diff --git a/composer.json b/composer.json index 7386ed02..91d5e7d7 100644 --- a/composer.json +++ b/composer.json @@ -22,15 +22,16 @@ }, "license": "MIT", "require": { - "php": "^7.4", + "php": "^7.4 | ^8.0", "guzzlehttp/guzzle": "^6.3|^7.0", "nesbot/carbon": "^2.0", "spatie/data-transfer-object": "^2.0" }, "require-dev": { "anteris-dev/autotask-client-generator": "^1.0", - "brianium/paratest": "^5.0", + "brianium/paratest": "^6.0", "phpunit/phpunit": "^9.3", + "spatie/ray": "^1.21", "vlucas/phpdotenv": "^4.0|^5.0" }, "scripts": { diff --git a/composer.lock b/composer.lock index f464d096..5de3f5e8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,37 +4,36 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a29324e369c84792ffe4aacc01e01df4", + "content-hash": "1197ea5d5e7a9ea31c7c3bb1632b416c", "packages": [ { "name": "guzzlehttp/guzzle", - "version": "7.0.1", + "version": "7.2.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "2d9d3c186a6637a43193e66b097c50e4451eaab2" + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/2d9d3c186a6637a43193e66b097c50e4451eaab2", - "reference": "2d9d3c186a6637a43193e66b097c50e4451eaab2", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0aa74dfb41ae110835923ef10a9d803a22d50e79", + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.6.1", - "php": "^7.2.5", + "guzzlehttp/promises": "^1.4", + "guzzlehttp/psr7": "^1.7", + "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0" }, "provide": { "psr/http-client-implementation": "1.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.0", "ext-curl": "*", - "php-http/client-integration-tests": "dev-phpunit8", - "phpunit/phpunit": "^8.5.5", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", "psr/log": "^1.1" }, "suggest": { @@ -45,7 +44,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.0-dev" + "dev-master": "7.1-dev" } }, "autoload": { @@ -85,27 +84,49 @@ "rest", "web service" ], - "time": "2020-06-27T10:33:25+00:00" + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.2.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://github.com/alexeyshockov", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], + "time": "2020-10-10T11:47:56+00:00" }, { "name": "guzzlehttp/promises", - "version": "v1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + "reference": "60d379c243457e073cff02bc323a2a86cb355631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "url": "https://api.github.com/repos/guzzle/promises/zipball/60d379c243457e073cff02bc323a2a86cb355631", + "reference": "60d379c243457e073cff02bc323a2a86cb355631", "shasum": "" }, "require": { - "php": ">=5.5.0" + "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.0" + "symfony/phpunit-bridge": "^4.4 || ^5.1" }, "type": "library", "extra": { @@ -136,20 +157,24 @@ "keywords": [ "promise" ], - "time": "2016-12-20T10:07:11+00:00" + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.0" + }, + "time": "2020-09-30T07:37:28+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.6.1", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", "shasum": "" }, "require": { @@ -162,15 +187,15 @@ }, "require-dev": { "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" }, "suggest": { - "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.7-dev" } }, "autoload": { @@ -207,20 +232,24 @@ "uri", "url" ], - "time": "2019-07-01T23:21:34+00:00" + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.7.0" + }, + "time": "2020-09-30T07:37:11+00:00" }, { "name": "nesbot/carbon", - "version": "2.39.1", + "version": "2.45.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "7af467873250583cc967a59ee9df29fabab193c1" + "reference": "528783b188bdb853eb21239b1722831e0f000a8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7af467873250583cc967a59ee9df29fabab193c1", - "reference": "7af467873250583cc967a59ee9df29fabab193c1", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/528783b188bdb853eb21239b1722831e0f000a8d", + "reference": "528783b188bdb853eb21239b1722831e0f000a8d", "shasum": "" }, "require": { @@ -235,8 +264,8 @@ "kylekatarnls/multi-tester": "^2.0", "phpmd/phpmd": "^2.9", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12.35", - "phpunit/phpunit": "^7.5 || ^8.0", + "phpstan/phpstan": "^0.12.54", + "phpunit/phpunit": "^7.5.20 || ^8.5.14", "squizlabs/php_codesniffer": "^3.4" }, "bin": [ @@ -286,7 +315,21 @@ "datetime", "time" ], - "time": "2020-09-04T13:11:37+00:00" + "support": { + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2021-02-11T18:30:17+00:00" }, { "name": "psr/http-client", @@ -335,6 +378,9 @@ "psr", "psr-18" ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, "time": "2020-06-29T06:28:15+00:00" }, { @@ -385,6 +431,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { @@ -425,29 +474,31 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { "name": "spatie/data-transfer-object", - "version": "2.5.0", + "version": "2.8.3", "source": { "type": "git", "url": "https://github.com/spatie/data-transfer-object.git", - "reference": "e326e10c8fd694db9b0c584c4986370beb9fd3ce" + "reference": "2625a59566804ec63f01947d85947336237cbda6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/e326e10c8fd694db9b0c584c4986370beb9fd3ce", - "reference": "e326e10c8fd694db9b0c584c4986370beb9fd3ce", + "url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/2625a59566804ec63f01947d85947336237cbda6", + "reference": "2625a59566804ec63f01947d85947336237cbda6", "shasum": "" }, "require": { - "php": "^7.4" + "php": "^7.4|^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "larapack/dd": "^1.0", - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.0" }, "suggest": { "phpstan/phpstan": "Take advantage of checkUninitializedProperties with \\Spatie\\DataTransferObject\\PHPstan\\PropertiesAreAlwaysInitializedExtension" @@ -476,24 +527,34 @@ "data-transfer-object", "spatie" ], - "time": "2020-08-28T09:26:20+00:00" + "support": { + "issues": "https://github.com/spatie/data-transfer-object/issues", + "source": "https://github.com/spatie/data-transfer-object/tree/2.8.3" + }, + "funding": [ + { + "url": "https://www.patreon.com/spatie", + "type": "patreon" + } + ], + "time": "2021-02-12T08:46:52+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.18.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a" + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a6977d63bf9a0ad4c65cd352709e230876f9904a", - "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" @@ -501,7 +562,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -539,29 +600,46 @@ "portable", "shim" ], - "time": "2020-07-14T12:35:20+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.18.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981" + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/d87d5766cbf48d72388a9f6b85f280c8ad51f981", - "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", "shasum": "" }, "require": { - "php": ">=7.0.8" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -605,27 +683,44 @@ "portable", "shim" ], - "time": "2020-07-14T12:35:20+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/translation", - "version": "v5.1.5", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "917b02cdc5f33e0309b8e9d33ee1480b20687413" + "reference": "74b0353ab34ff4cca827a2cf909e325d96815e60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/917b02cdc5f33e0309b8e9d33ee1480b20687413", - "reference": "917b02cdc5f33e0309b8e9d33ee1480b20687413", + "url": "https://api.github.com/repos/symfony/translation/zipball/74b0353ab34ff4cca827a2cf909e325d96815e60", + "reference": "74b0353ab34ff4cca827a2cf909e325d96815e60", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "^1.15", - "symfony/translation-contracts": "^2" + "symfony/translation-contracts": "^2.3" }, "conflict": { "symfony/config": "<4.4", @@ -635,7 +730,7 @@ "symfony/yaml": "<4.4" }, "provide": { - "symfony/translation-implementation": "2.0" + "symfony/translation-implementation": "2.3" }, "require-dev": { "psr/log": "~1.0", @@ -654,12 +749,10 @@ "symfony/yaml": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { + "files": [ + "Resources/functions.php" + ], "psr-4": { "Symfony\\Component\\Translation\\": "" }, @@ -681,22 +774,39 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Translation Component", + "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", - "time": "2020-08-17T10:01:29+00:00" + "support": { + "source": "https://github.com/symfony/translation/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-04T15:41:09+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.2.0", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "77ce1c3627c9f39643acd9af086631f842c50c4d" + "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/77ce1c3627c9f39643acd9af086631f842c50c4d", - "reference": "77ce1c3627c9f39643acd9af086631f842c50c4d", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/e2eaa60b558f26a4b0354e1bbb25636efaaad105", + "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105", "shasum": "" }, "require": { @@ -708,7 +818,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -744,7 +854,24 @@ "interoperability", "standards" ], - "time": "2020-09-07T11:33:47+00:00" + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-28T13:05:58+00:00" } ], "packages-dev": [ @@ -788,49 +915,54 @@ } ], "description": "This package is the brains behind the Autotask API client. It generates each service class using the Autotask API as its guide.", + "support": { + "issues": "https://github.com/Anteris-Dev/autotask-client-generator/issues", + "source": "https://github.com/Anteris-Dev/autotask-client-generator/tree/master" + }, "time": "2020-09-08T16:16:50+00:00" }, { "name": "brianium/paratest", - "version": "5.0.4", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "e54bea90b784b289a7ee17f2319210338c2d7d6d" + "reference": "9a94366983ce32c7724fc92e3b544327d4adb9be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/e54bea90b784b289a7ee17f2319210338c2d7d6d", - "reference": "e54bea90b784b289a7ee17f2319210338c2d7d6d", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/9a94366983ce32c7724fc92e3b544327d4adb9be", + "reference": "9a94366983ce32c7724fc92e3b544327d4adb9be", "shasum": "" }, "require": { "ext-dom": "*", "ext-pcre": "*", - "ext-pdo": "*", "ext-reflection": "*", "ext-simplexml": "*", - "php": "^7.3", - "phpunit/php-code-coverage": "^9.1.2", - "phpunit/php-file-iterator": "^3.0", - "phpunit/php-timer": "^5.0", - "phpunit/phpunit": "^9.3.5", - "sebastian/environment": "^5.1", - "symfony/console": "^4.4 || ^5.1", - "symfony/process": "^4.4 || ^5.1" + "php": "^7.3 || ^8.0", + "phpunit/php-code-coverage": "^9.2.5", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-timer": "^5.0.3", + "phpunit/phpunit": "^9.5.1", + "sebastian/environment": "^5.1.3", + "symfony/console": "^4.4 || ^5.2", + "symfony/process": "^4.4 || ^5.2" }, "require-dev": { - "doctrine/coding-standard": "^8.1.0", + "doctrine/coding-standard": "^8.2.0", "ekino/phpstan-banned-code": "^0.3.1", - "ergebnis/phpstan-rules": "^0.15.1", - "phpstan/phpstan": "^0.12.37", - "phpstan/phpstan-deprecation-rules": "^0.12.5", - "phpstan/phpstan-phpunit": "^0.12.16", - "phpstan/phpstan-strict-rules": "^0.12.4", - "squizlabs/php_codesniffer": "^3.5.6", - "symfony/filesystem": "^5.1.3", - "thecodingmachine/phpstan-strict-rules": "^0.12.0", - "vimeo/psalm": "^3.12.2" + "ergebnis/phpstan-rules": "^0.15.3", + "ext-posix": "*", + "infection/infection": "^0.20.2", + "phpstan/phpstan": "^0.12.70", + "phpstan/phpstan-deprecation-rules": "^0.12.6", + "phpstan/phpstan-phpunit": "^0.12.17", + "phpstan/phpstan-strict-rules": "^0.12.9", + "squizlabs/php_codesniffer": "^3.5.8", + "symfony/filesystem": "^5.2.2", + "thecodingmachine/phpstan-strict-rules": "^0.12.1", + "vimeo/psalm": "^4.4.1" }, "bin": [ "bin/paratest" @@ -863,7 +995,67 @@ "phpunit", "testing" ], - "time": "2020-08-26T13:44:25+00:00" + "support": { + "issues": "https://github.com/paratestphp/paratest/issues", + "source": "https://github.com/paratestphp/paratest/tree/v6.2.0" + }, + "time": "2021-01-29T15:25:31+00:00" + }, + { + "name": "brick/math", + "version": "0.9.2", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "vimeo/psalm": "4.3.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.9.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/brick/math", + "type": "tidelift" + } + ], + "time": "2021-01-20T22:51:39+00:00" }, { "name": "doctrine/inflector", @@ -940,40 +1132,53 @@ "uppercase", "words" ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.x" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], "time": "2020-05-29T15:13:26+00:00" }, { "name": "doctrine/instantiator", - "version": "1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -987,7 +1192,7 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", @@ -996,7 +1201,25 @@ "constructor", "instantiate" ], - "time": "2020-05-29T17:27:14+00:00" + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-11-10T18:47:58+00:00" }, { "name": "graham-campbell/result-type", @@ -1048,26 +1271,43 @@ "Result-Type", "result" ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], "time": "2020-04-13T13:17:36+00:00" }, { "name": "illuminate/collections", - "version": "v8.0.0", + "version": "v8.31.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "446310d53bf58905bf2fb0152d9df9a169fc3aa9" + "reference": "ecc881c6dce66e22f2c236374f342d41c7ebeb67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/446310d53bf58905bf2fb0152d9df9a169fc3aa9", - "reference": "446310d53bf58905bf2fb0152d9df9a169fc3aa9", + "url": "https://api.github.com/repos/illuminate/collections/zipball/ecc881c6dce66e22f2c236374f342d41c7ebeb67", + "reference": "ecc881c6dce66e22f2c236374f342d41c7ebeb67", "shasum": "" }, "require": { "illuminate/contracts": "^8.0", "illuminate/macroable": "^8.0", - "php": "^7.3" + "php": "^7.3|^8.0" + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump method (^5.1.4)." }, "type": "library", "extra": { @@ -1095,24 +1335,28 @@ ], "description": "The Illuminate Collections package.", "homepage": "https://laravel.com", - "time": "2020-09-08T12:37:36+00:00" + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2021-03-02T13:34:56+00:00" }, { "name": "illuminate/contracts", - "version": "v8.0.0", + "version": "v8.31.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "8420ad4a55c85a106d560408239fd72a64057df6" + "reference": "9c7a9868d7485a82663d67109429094c8e4ed56d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/8420ad4a55c85a106d560408239fd72a64057df6", - "reference": "8420ad4a55c85a106d560408239fd72a64057df6", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/9c7a9868d7485a82663d67109429094c8e4ed56d", + "reference": "9c7a9868d7485a82663d67109429094c8e4ed56d", "shasum": "" }, "require": { - "php": "^7.3", + "php": "^7.3|^8.0", "psr/container": "^1.0", "psr/simple-cache": "^1.0" }, @@ -1139,24 +1383,28 @@ ], "description": "The Illuminate Contracts package.", "homepage": "https://laravel.com", - "time": "2020-09-08T11:21:59+00:00" + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2021-02-26T13:17:03+00:00" }, { "name": "illuminate/macroable", - "version": "v8.0.0", + "version": "v8.31.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", - "reference": "561442f134eaf4d3f710bf523ecfe1537fa53f64" + "reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/macroable/zipball/561442f134eaf4d3f710bf523ecfe1537fa53f64", - "reference": "561442f134eaf4d3f710bf523ecfe1537fa53f64", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/300aa13c086f25116b5f3cde3ca54ff5c822fb05", + "reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05", "shasum": "" }, "require": { - "php": "^7.3" + "php": "^7.3|^8.0" }, "type": "library", "extra": { @@ -1181,20 +1429,24 @@ ], "description": "The Illuminate Macroable package.", "homepage": "https://laravel.com", - "time": "2020-06-08T14:13:16+00:00" + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2020-10-27T15:20:30+00:00" }, { "name": "illuminate/support", - "version": "v8.0.0", + "version": "v8.31.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "bf22e29a15c773719f3aa036075ed0498321d454" + "reference": "978e64ffb68189b70fea77e4d401f43e88fa54ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/bf22e29a15c773719f3aa036075ed0498321d454", - "reference": "bf22e29a15c773719f3aa036075ed0498321d454", + "url": "https://api.github.com/repos/illuminate/support/zipball/978e64ffb68189b70fea77e4d401f43e88fa54ca", + "reference": "978e64ffb68189b70fea77e4d401f43e88fa54ca", "shasum": "" }, "require": { @@ -1204,8 +1456,8 @@ "illuminate/collections": "^8.0", "illuminate/contracts": "^8.0", "illuminate/macroable": "^8.0", - "nesbot/carbon": "^2.17", - "php": "^7.3", + "nesbot/carbon": "^2.31", + "php": "^7.3|^8.0", "voku/portable-ascii": "^1.4.8" }, "conflict": { @@ -1213,10 +1465,11 @@ }, "suggest": { "illuminate/filesystem": "Required to use the composer class (^8.0).", + "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^1.3).", "ramsey/uuid": "Required to use Str::uuid() (^4.0).", - "symfony/process": "Required to use the composer class (^5.1).", - "symfony/var-dumper": "Required to use the dd function (^5.1).", - "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.0)." + "symfony/process": "Required to use the composer class (^5.1.4).", + "symfony/var-dumper": "Required to use the dd function (^5.1.4).", + "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.2)." }, "type": "library", "extra": { @@ -1244,20 +1497,24 @@ ], "description": "The Illuminate Support package.", "homepage": "https://laravel.com", - "time": "2020-09-07T12:54:55+00:00" + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2021-03-04T14:09:31+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.10.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", "shasum": "" }, "require": { @@ -1292,20 +1549,30 @@ "object", "object graph" ], - "time": "2020-06-29T13:22:24+00:00" + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-11-13T09:40:50+00:00" }, { "name": "nikic/php-parser", - "version": "v4.9.1", + "version": "v4.10.4", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28" + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/88e519766fc58bd46b8265561fb79b54e2e00b28", - "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", "shasum": "" }, "require": { @@ -1344,7 +1611,11 @@ "parser", "php" ], - "time": "2020-08-30T16:15:20+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4" + }, + "time": "2020-12-20T10:01:03+00:00" }, { "name": "phar-io/manifest", @@ -1400,20 +1671,24 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/master" + }, "time": "2020-06-27T14:33:11+00:00" }, { "name": "phar-io/version", - "version": "3.0.2", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0" + "reference": "bae7c545bef187884426f042434e561ab1ddb182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/c6bb6825def89e0a32220f88337f8ceaf1975fa0", - "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0", + "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", + "reference": "bae7c545bef187884426f042434e561ab1ddb182", "shasum": "" }, "require": { @@ -1447,7 +1722,11 @@ } ], "description": "Library for handling version information and constraints", - "time": "2020-06-27T14:39:04+00:00" + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.1.0" + }, + "time": "2021-02-23T14:00:09+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -1496,20 +1775,24 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.1", + "version": "5.2.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44" + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d870572532cd70bc3fab58f2e23ad423c8404c44", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", "shasum": "" }, "require": { @@ -1548,20 +1831,24 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-08-15T11:14:08+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + }, + "time": "2020-09-03T19:13:55+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", "shasum": "" }, "require": { @@ -1593,7 +1880,11 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-06-27T10:12:23+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + }, + "time": "2020-09-17T18:55:26+00:00" }, { "name": "phpoption/phpoption", @@ -1648,32 +1939,46 @@ "php", "type" ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.7.5" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], "time": "2020-07-20T17:29:33+00:00" }, { "name": "phpspec/prophecy", - "version": "1.11.1", + "version": "1.12.2", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" + "reference": "245710e971a030f42e08f4912863805570f23d39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", + "reference": "245710e971a030f42e08f4912863805570f23d39", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2", - "phpdocumentor/reflection-docblock": "^5.0", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0" + "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { @@ -1711,34 +2016,38 @@ "spy", "stub" ], - "time": "2020-07-08T12:44:21+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/1.12.2" + }, + "time": "2020-12-19T10:15:11+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.1.8", + "version": "9.2.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f98f8466126d83b55b924a94d2244c53c216b8fb" + "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f98f8466126d83b55b924a94d2244c53c216b8fb", - "reference": "f98f8466126d83b55b924a94d2244c53c216b8fb", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1", + "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.8", - "php": "^7.3 || ^8.0", + "nikic/php-parser": "^4.10.2", + "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", "sebastian/code-unit-reverse-lookup": "^2.0.2", "sebastian/complexity": "^2.0", "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0", + "sebastian/lines-of-code": "^1.0.3", "sebastian/version": "^3.0.1", "theseer/tokenizer": "^1.2.0" }, @@ -1752,7 +2061,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.1-dev" + "dev-master": "9.2-dev" } }, "autoload": { @@ -1778,27 +2087,37 @@ "testing", "xunit" ], - "time": "2020-09-07T08:07:10+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:44:49+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.4", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e" + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/25fefc5b19835ca653877fe081644a3f8c1d915e", - "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -1828,28 +2147,38 @@ "filesystem", "iterator" ], - "time": "2020-07-11T05:18:21+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:57:25+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "7a85b66acc48cacffdf87dadd3694e7123674298" + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/7a85b66acc48cacffdf87dadd3694e7123674298", - "reference": "7a85b66acc48cacffdf87dadd3694e7123674298", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-pcntl": "*" @@ -1881,27 +2210,37 @@ "keywords": [ "process" ], - "time": "2020-08-06T07:04:15+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324" + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", - "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -1930,27 +2269,37 @@ "keywords": [ "template" ], - "time": "2020-06-26T11:55:37+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.1", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7" + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/cc49734779cbb302bf51a44297dab8c4bbf941e7", - "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -1979,20 +2328,30 @@ "keywords": [ "timer" ], - "time": "2020-06-26T11:58:13+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" }, { "name": "phpunit/phpunit", - "version": "9.3.8", + "version": "9.5.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "93d78d8e2a06393a0d0c1ead6fe9984f1af1f88c" + "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/93d78d8e2a06393a0d0c1ead6fe9984f1af1f88c", - "reference": "93d78d8e2a06393a0d0c1ead6fe9984f1af1f88c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f661659747f2f87f9e72095bb207bceb0f151cb4", + "reference": "f661659747f2f87f9e72095bb207bceb0f151cb4", "shasum": "" }, "require": { @@ -2006,24 +2365,24 @@ "myclabs/deep-copy": "^1.10.1", "phar-io/manifest": "^2.0.1", "phar-io/version": "^3.0.2", - "php": "^7.3 || ^8.0", - "phpspec/prophecy": "^1.11.1", - "phpunit/php-code-coverage": "^9.1.5", - "phpunit/php-file-iterator": "^3.0.4", - "phpunit/php-invoker": "^3.1", - "phpunit/php-text-template": "^2.0.2", - "phpunit/php-timer": "^5.0.1", - "sebastian/cli-parser": "^1.0", - "sebastian/code-unit": "^1.0.5", - "sebastian/comparator": "^4.0.3", - "sebastian/diff": "^4.0.2", - "sebastian/environment": "^5.1.2", - "sebastian/exporter": "^4.0.2", - "sebastian/global-state": "^5.0", - "sebastian/object-enumerator": "^4.0.2", - "sebastian/resource-operations": "^3.0.2", - "sebastian/type": "^2.2.1", - "sebastian/version": "^3.0.1" + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^2.3", + "sebastian/version": "^3.0.2" }, "require-dev": { "ext-pdo": "*", @@ -2039,7 +2398,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.3-dev" + "dev-master": "9.5-dev" } }, "autoload": { @@ -2068,31 +2427,40 @@ "testing", "xunit" ], - "time": "2020-08-27T06:30:58+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.2" + }, + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-02-02T14:45:58+00:00" }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -2105,7 +2473,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -2117,7 +2485,11 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.1" + }, + "time": "2021-03-05T17:36:06+00:00" }, { "name": "psr/simple-cache", @@ -2165,119 +2537,311 @@ "psr-16", "simple-cache" ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, "time": "2017-10-23T01:57:42+00:00" }, { - "name": "sebastian/cli-parser", - "version": "1.0.0", + "name": "ramsey/collection", + "version": "1.1.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "2a4a38c56e62f7295bedb8b1b7439ad523d4ea82" + "url": "https://github.com/ramsey/collection.git", + "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2a4a38c56e62f7295bedb8b1b7439ad523d4ea82", - "reference": "2a4a38c56e62f7295bedb8b1b7439ad523d4ea82", + "url": "https://api.github.com/repos/ramsey/collection/zipball/28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", + "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": "^7.2 || ^8" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "captainhook/captainhook": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "ergebnis/composer-normalize": "^2.6", + "fakerphp/faker": "^1.5", + "hamcrest/hamcrest-php": "^2", + "jangregor/phpstan-prophecy": "^0.8", + "mockery/mockery": "^1.3", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^0.12.32", + "phpstan/phpstan-mockery": "^0.12.5", + "phpstan/phpstan-phpunit": "^0.12.11", + "phpunit/phpunit": "^8.5 || ^9", + "psy/psysh": "^0.10.4", + "slevomat/coding-standard": "^6.3", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.4" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Ramsey\\Collection\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" } ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "time": "2020-08-12T10:49:21+00:00" + "description": "A PHP 7.2+ library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.1.3" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2021-01-21T17:40:04+00:00" }, { - "name": "sebastian/code-unit", - "version": "1.0.5", + "name": "ramsey/uuid", + "version": "4.1.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "c1e2df332c905079980b119c4db103117e5e5c90" + "url": "https://github.com/ramsey/uuid.git", + "reference": "cd4032040a750077205918c86049aa0f43d22947" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/c1e2df332c905079980b119c4db103117e5e5c90", - "reference": "c1e2df332c905079980b119c4db103117e5e5c90", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/cd4032040a750077205918c86049aa0f43d22947", + "reference": "cd4032040a750077205918c86049aa0f43d22947", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "brick/math": "^0.8 || ^0.9", + "ext-json": "*", + "php": "^7.2 || ^8", + "ramsey/collection": "^1.0", + "symfony/polyfill-ctype": "^1.8" + }, + "replace": { + "rhumsaa/uuid": "self.version" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "codeception/aspect-mock": "^3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", + "doctrine/annotations": "^1.8", + "goaop/framework": "^2", + "mockery/mockery": "^1.3", + "moontoast/math": "^1.1", + "paragonie/random-lib": "^2", + "php-mock/php-mock-mockery": "^1.3", + "php-mock/php-mock-phpunit": "^2.5", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^0.17.1", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-mockery": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^8.5", + "psy/psysh": "^0.10.0", + "slevomat/coding-standard": "^6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "3.9.4" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-ctype": "Enables faster processing of character classification using ctype functions.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "4.x-dev" } }, "autoload": { - "classmap": [ - "src/" + "psr-4": { + "Ramsey\\Uuid\\": "src/" + }, + "files": [ + "src/functions.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "homepage": "https://github.com/ramsey/uuid", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "rss": "https://github.com/ramsey/uuid/releases.atom", + "source": "https://github.com/ramsey/uuid" + }, + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "url": "https://github.com/ramsey", + "type": "github" } ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "time": "2020-06-26T12:50:45+00:00" + "time": "2020-08-18T17:17:46+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "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": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "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": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819" + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ee51f9bb0c6d8a43337055db3120829fa14da819", - "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2302,29 +2866,39 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2020-06-26T12:04:00+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.3", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f" + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", - "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0", + "php": ">=7.3", "sebastian/diff": "^4.0", "sebastian/exporter": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2366,28 +2940,38 @@ "compare", "equality" ], - "time": "2020-06-26T12:05:46+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:49:45+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.0", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "33fcd6a26656c6546f70871244ecba4b4dced097" + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/33fcd6a26656c6546f70871244ecba4b4dced097", - "reference": "33fcd6a26656c6546f70871244ecba4b4dced097", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", "shasum": "" }, "require": { "nikic/php-parser": "^4.7", - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2413,27 +2997,37 @@ ], "description": "Library for calculating the complexity of PHP code units", "homepage": "https://github.com/sebastianbergmann/complexity", - "time": "2020-07-25T14:01:34+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" }, { "name": "sebastian/diff", - "version": "4.0.2", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113" + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", - "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0", + "phpunit/phpunit": "^9.3", "symfony/process": "^4.2 || ^5" }, "type": "library", @@ -2469,27 +3063,37 @@ "unidiff", "unified diff" ], - "time": "2020-06-30T04:46:02+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" }, { "name": "sebastian/environment", - "version": "5.1.2", + "version": "5.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2" + "reference": "388b6ced16caa751030f6a69e588299fa09200ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", - "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-posix": "*" @@ -2497,7 +3101,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -2522,29 +3126,39 @@ "environment", "hhvm" ], - "time": "2020-06-26T12:07:24+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:52:38+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.2", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "571d721db4aec847a0e59690b954af33ebf9f023" + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/571d721db4aec847a0e59690b954af33ebf9f023", - "reference": "571d721db4aec847a0e59690b954af33ebf9f023", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0", + "php": ">=7.3", "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2589,24 +3203,34 @@ "export", "exporter" ], - "time": "2020-06-26T12:08:55+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:24:23+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.0", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "22ae663c951bdc39da96603edc3239ed3a299097" + "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/22ae663c951bdc39da96603edc3239ed3a299097", - "reference": "22ae663c951bdc39da96603edc3239ed3a299097", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", + "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0", + "php": ">=7.3", "sebastian/object-reflector": "^2.0", "sebastian/recursion-context": "^4.0" }, @@ -2643,28 +3267,38 @@ "keywords": [ "global state" ], - "time": "2020-08-07T04:09:03+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:55:19+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.0", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5" + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e02bf626f404b5daec382a7b8a6a4456e49017e5", - "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", "shasum": "" }, "require": { "nikic/php-parser": "^4.6", - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2690,29 +3324,39 @@ ], "description": "Library for counting the lines of code in PHP source code", "homepage": "https://github.com/sebastianbergmann/lines-of-code", - "time": "2020-07-22T18:33:42+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.2", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8" + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/074fed2d0a6d08e1677dd8ce9d32aecb384917b8", - "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0", + "php": ">=7.3", "sebastian/object-reflector": "^2.0", "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2737,27 +3381,37 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2020-06-26T12:11:32+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "127a46f6b057441b201253526f81d5406d6c7840" + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/127a46f6b057441b201253526f81d5406d6c7840", - "reference": "127a46f6b057441b201253526f81d5406d6c7840", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2782,27 +3436,37 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2020-06-26T12:12:55+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.2", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63" + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/062231bf61d2b9448c4fa5a7643b5e1829c11d63", - "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -2835,24 +3499,34 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2020-06-26T12:14:17+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" }, { "name": "sebastian/resource-operations", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0653718a5a629b065e91f774595267f8dc32e213" + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0653718a5a629b065e91f774595267f8dc32e213", - "reference": "0653718a5a629b065e91f774595267f8dc32e213", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -2880,32 +3554,42 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2020-06-26T12:16:22+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" }, { "name": "sebastian/type", - "version": "2.2.1", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a" + "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/86991e2b33446cd96e648c18bcdb1e95afb2c05a", - "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2", + "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-master": "2.3-dev" } }, "autoload": { @@ -2926,24 +3610,34 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", - "time": "2020-07-05T08:31:53+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/2.3.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:18:59+00:00" }, { "name": "sebastian/version", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "626586115d0ed31cb71483be55beb759b5af5a3c" + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/626586115d0ed31cb71483be55beb759b5af5a3c", - "reference": "626586115d0ed31cb71483be55beb759b5af5a3c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "php": "^7.3 || ^8.0" + "php": ">=7.3" }, "type": "library", "extra": { @@ -2969,20 +3663,217 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2020-06-26T12:18:43+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "spatie/backtrace", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "3440fe023a7d5b4497090fb6b2dcdc747daf7873" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/3440fe023a7d5b4497090fb6b2dcdc747daf7873", + "reference": "3440fe023a7d5b4497090fb6b2dcdc747daf7873", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "phpunit/phpunit": "^9.3", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/backtrace/issues", + "source": "https://github.com/spatie/backtrace/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2021-01-29T09:20:43+00:00" + }, + { + "name": "spatie/macroable", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/macroable.git", + "reference": "7a99549fc001c925714b329220dea680c04bfa48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/macroable/zipball/7a99549fc001c925714b329220dea680c04bfa48", + "reference": "7a99549fc001c925714b329220dea680c04bfa48", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Macroable\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A trait to dynamically add methods to a class", + "homepage": "https://github.com/spatie/macroable", + "keywords": [ + "macroable", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/macroable/issues", + "source": "https://github.com/spatie/macroable/tree/1.0.1" + }, + "time": "2020-11-03T10:15:05+00:00" + }, + { + "name": "spatie/ray", + "version": "1.21.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/ray.git", + "reference": "829676b1b6791aba6660fcca6f553d72c894a0ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ray/zipball/829676b1b6791aba6660fcca6f553d72c894a0ae", + "reference": "829676b1b6791aba6660fcca6f553d72c894a0ae", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "php": "^7.3|^8.0", + "ramsey/uuid": "^3.0|^4.1", + "spatie/backtrace": "^1.1", + "spatie/macroable": "^1.0", + "symfony/stopwatch": "^4.0|^5.1", + "symfony/var-dumper": "^4.2|^5.1" + }, + "require-dev": { + "illuminate/support": "6.x|^8.18", + "nesbot/carbon": "^2.43", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.9.16", + "spatie/phpunit-snapshot-assertions": "^4.2", + "spatie/test-time": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Ray\\": "src" + }, + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Debug with Ray to fix problems faster", + "homepage": "https://github.com/spatie/ray", + "keywords": [ + "ray", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/ray/issues", + "source": "https://github.com/spatie/ray/tree/1.21.2" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2021-03-04T11:06:19+00:00" }, { "name": "symfony/console", - "version": "v5.1.5", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "186f395b256065ba9b890c0a4e48a91d598fa2cf" + "reference": "d6d0cc30d8c0fda4e7b213c20509b0159a8f4556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/186f395b256065ba9b890c0a4e48a91d598fa2cf", - "reference": "186f395b256065ba9b890c0a4e48a91d598fa2cf", + "url": "https://api.github.com/repos/symfony/console/zipball/d6d0cc30d8c0fda4e7b213c20509b0159a8f4556", + "reference": "d6d0cc30d8c0fda4e7b213c20509b0159a8f4556", "shasum": "" }, "require": { @@ -3019,11 +3910,6 @@ "symfony/process": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" @@ -3046,26 +3932,49 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", - "time": "2020-09-02T07:07:40+00:00" + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-23T10:08:49+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.18.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" @@ -3073,7 +3982,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3110,24 +4019,41 @@ "polyfill", "portable" ], - "time": "2020-07-14T12:35:20+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.18.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "b740103edbdcc39602239ee8860f0f45a8eb9aa5" + "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b740103edbdcc39602239ee8860f0f45a8eb9aa5", - "reference": "b740103edbdcc39602239ee8860f0f45a8eb9aa5", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170", + "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" @@ -3135,7 +4061,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3174,24 +4100,41 @@ "portable", "shim" ], - "time": "2020-07-14T12:35:20+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.18.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e" + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", - "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" @@ -3199,7 +4142,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3241,29 +4184,46 @@ "portable", "shim" ], - "time": "2020-07-14T12:35:20+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.18.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca" + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fffa1a52a023e782cdcc221d781fe1ec8f87fcca", - "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3303,20 +4263,37 @@ "portable", "shim" ], - "time": "2020-07-14T12:35:20+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/process", - "version": "v5.1.5", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "1864216226af21eb76d9477f691e7cbf198e0402" + "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/1864216226af21eb76d9477f691e7cbf198e0402", - "reference": "1864216226af21eb76d9477f691e7cbf198e0402", + "url": "https://api.github.com/repos/symfony/process/zipball/313a38f09c77fbcdc1d223e57d368cea76a2fd2f", + "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f", "shasum": "" }, "require": { @@ -3324,11 +4301,6 @@ "symfony/polyfill-php80": "^1.15" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" @@ -3351,9 +4323,26 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Process Component", + "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", - "time": "2020-07-23T08:36:24+00:00" + "support": { + "source": "https://github.com/symfony/process/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:15:41+00:00" }, { "name": "symfony/service-contracts", @@ -3415,20 +4404,99 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/master" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-09-07T11:33:47+00:00" }, + { + "name": "symfony/stopwatch", + "version": "v5.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b12274acfab9d9850c52583d136a24398cdf1a0c", + "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/service-contracts": "^1.0|^2" + }, + "type": "library", + "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": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:15:41+00:00" + }, { "name": "symfony/string", - "version": "v5.1.5", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "0de4cc1e18bb596226c06a82e2e7e9bc6001a63a" + "reference": "4e78d7d47061fa183639927ec40d607973699609" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/0de4cc1e18bb596226c06a82e2e7e9bc6001a63a", - "reference": "0de4cc1e18bb596226c06a82e2e7e9bc6001a63a", + "url": "https://api.github.com/repos/symfony/string/zipball/4e78d7d47061fa183639927ec40d607973699609", + "reference": "4e78d7d47061fa183639927ec40d607973699609", "shasum": "" }, "require": { @@ -3446,11 +4514,6 @@ "symfony/var-exporter": "^4.4|^5.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.1-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\String\\": "" @@ -3476,7 +4539,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony String component", + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", "homepage": "https://symfony.com", "keywords": [ "grapheme", @@ -3486,7 +4549,112 @@ "utf-8", "utf8" ], - "time": "2020-08-17T07:48:54+00:00" + "support": { + "source": "https://github.com/symfony/string/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-16T10:20:28+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v5.2.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "002ab5a36702adf0c9a11e6d8836623253e9045e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/002ab5a36702adf0c9a11e6d8836623253e9045e", + "reference": "002ab5a36702adf0c9a11e6d8836623253e9045e", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<4.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "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": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v5.2.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-06T07:59:01+00:00" }, { "name": "theseer/tokenizer", @@ -3526,20 +4694,30 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/master" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], "time": "2020-07-12T23:59:07+00:00" }, { "name": "twig/twig", - "version": "v3.0.5", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "9b76b1535483cdf4edf01bb787b0217b62bd68a5" + "reference": "1f3b7e2c06cc05d42936a8ad508ff1db7975cdc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/9b76b1535483cdf4edf01bb787b0217b62bd68a5", - "reference": "9b76b1535483cdf4edf01bb787b0217b62bd68a5", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/1f3b7e2c06cc05d42936a8ad508ff1db7975cdc5", + "reference": "1f3b7e2c06cc05d42936a8ad508ff1db7975cdc5", "shasum": "" }, "require": { @@ -3554,7 +4732,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.3-dev" } }, "autoload": { @@ -3588,20 +4766,34 @@ "keywords": [ "templating" ], - "time": "2020-08-05T15:13:19+00:00" + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2021-02-08T09:54:36+00:00" }, { "name": "vlucas/phpdotenv", - "version": "v5.1.0", + "version": "v5.3.0", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "448c76d7a9e30c341ff5bc367a923af74ae18467" + "reference": "b3eac5c7ac896e52deab4a99068e3f4ab12d9e56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/448c76d7a9e30c341ff5bc367a923af74ae18467", - "reference": "448c76d7a9e30c341ff5bc367a923af74ae18467", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/b3eac5c7ac896e52deab4a99068e3f4ab12d9e56", + "reference": "b3eac5c7ac896e52deab4a99068e3f4ab12d9e56", "shasum": "" }, "require": { @@ -3616,7 +4808,7 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.4.1", "ext-filter": "*", - "phpunit/phpunit": "^7.5.20 || ^8.5.2 || ^9.0" + "phpunit/phpunit": "^7.5.20 || ^8.5.14 || ^9.5.1" }, "suggest": { "ext-filter": "Required to use the boolean validator." @@ -3624,7 +4816,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-master": "5.3-dev" } }, "autoload": { @@ -3654,27 +4846,41 @@ "env", "environment" ], - "time": "2020-07-14T19:26:25+00:00" + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.3.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2021-01-20T15:23:13+00:00" }, { "name": "voku/portable-ascii", - "version": "1.5.3", + "version": "1.5.6", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "25bcbf01678930251fd572891447d9e318a6e2b8" + "reference": "80953678b19901e5165c56752d087fc11526017c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/25bcbf01678930251fd572891447d9e318a6e2b8", - "reference": "25bcbf01678930251fd572891447d9e318a6e2b8", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/80953678b19901e5165c56752d087fc11526017c", + "reference": "80953678b19901e5165c56752d087fc11526017c", "shasum": "" }, "require": { "php": ">=7.0.0" }, "require-dev": { - "phpunit/phpunit": "~6.0 || ~7.0" + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" }, "suggest": { "ext-intl": "Use Intl for transliterator_transliterate() support" @@ -3702,19 +4908,45 @@ "clean", "php" ], - "time": "2020-07-22T23:32:04+00:00" + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/1.5.6" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2020-11-12T00:07:28+00:00" }, { "name": "webmozart/assert", "version": "1.9.1", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", + "url": "https://github.com/webmozarts/assert.git", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", "shasum": "" }, @@ -3751,6 +4983,10 @@ "check", "validate" ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.9.1" + }, "time": "2020-07-08T17:02:28+00:00" } ], @@ -3760,7 +4996,8 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.4" + "php": "^7.4 | ^8.0" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.0.0" } diff --git a/src/API/AttachmentInfo/AttachmentInfoService.php b/src/API/AttachmentInfo/AttachmentInfoService.php index e9f8a02e..83e3ceaa 100644 --- a/src/API/AttachmentInfo/AttachmentInfoService.php +++ b/src/API/AttachmentInfo/AttachmentInfoService.php @@ -5,6 +5,7 @@ use Anteris\Autotask\HttpClient; use Anteris\Autotask\Support\EntityFields\EntityFieldCollection; use Anteris\Autotask\Support\EntityInformation\EntityInformationEntity; +use GuzzleHttp\Psr7\Response; /** * Handles all interaction with Autotask AttachmentInfo. @@ -27,6 +28,30 @@ public function __construct(HttpClient $client) $this->client = $client; } + /** + * Creates a new attachmentinfo. + * + * @param AttachmentInfoEntity $resource The attachmentinfo entity to be written. + * + * @author Aidan Casey + */ + public function create(AttachmentInfoEntity $resource): Response + { + return $this->client->post("AttachmentInfo", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the AttachmentInfo to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("AttachmentInfo/$id"); + } + /** * Finds the AttachmentInfo based on its ID. * diff --git a/src/API/AttachmentNestedAttachments/AttachmentNestedAttachmentService.php b/src/API/AttachmentNestedAttachments/AttachmentNestedAttachmentService.php index 8656a94d..db124036 100644 --- a/src/API/AttachmentNestedAttachments/AttachmentNestedAttachmentService.php +++ b/src/API/AttachmentNestedAttachments/AttachmentNestedAttachmentService.php @@ -37,19 +37,21 @@ public function __construct(HttpClient $client) */ public function create(AttachmentNestedAttachmentEntity $resource): Response { - return $this->client->post("AttachmentNestedAttachments", $resource->toArray()); + $parentID = $resource->parentID; + return $this->client->post("Attachments/$parentID/NestedAttachments", $resource->toArray()); } /** * Deletes an entity by its ID. * + * @param int $parentID ID of the AttachmentNestedAttachment parent resource. * @param int $id ID of the AttachmentNestedAttachment to be deleted. * * @author Aidan Casey */ - public function deleteById(int $id): void + public function deleteById(int $parentID,int $id): void { - $this->client->delete("AttachmentNestedAttachments/$id"); + $this->client->delete("Attachments/$parentID/NestedAttachments/$id"); } /** diff --git a/src/API/Companies/CompanyEntity.php b/src/API/Companies/CompanyEntity.php index 2887609e..2df5e0ce 100644 --- a/src/API/Companies/CompanyEntity.php +++ b/src/API/Companies/CompanyEntity.php @@ -57,6 +57,7 @@ class CompanyEntity extends DataTransferObject public ?int $parentCompanyID; public string $phone; public ?string $postalCode; + public ?int $purchaseOrderTemplateID; public ?int $quoteEmailMessageID; public ?int $quoteTemplateID; public ?string $sicCode; diff --git a/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordCollection.php b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordCollection.php new file mode 100644 index 00000000..8acf7427 --- /dev/null +++ b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): ConfigurationItemDnsRecordCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + ConfigurationItemDnsRecordEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordEntity.php b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordEntity.php new file mode 100644 index 00000000..72979ed9 --- /dev/null +++ b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordEntity.php @@ -0,0 +1,55 @@ + + */ + public function __construct(array $array) + { + if (isset($array['createDateTime'])) { + $array['createDateTime'] = new Carbon($array['createDateTime']); + } + + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordPaginator.php b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordPaginator.php new file mode 100644 index 00000000..140d6657 --- /dev/null +++ b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = ConfigurationItemDnsRecordCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): ConfigurationItemDnsRecordPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): ConfigurationItemDnsRecordPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordQueryBuilder.php b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordQueryBuilder.php new file mode 100644 index 00000000..29301b55 --- /dev/null +++ b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("ConfigurationItemDnsRecords/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): ConfigurationItemDnsRecordCollection + { + $response = $this->client->get("ConfigurationItemDnsRecords/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return ConfigurationItemDnsRecordCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): ConfigurationItemDnsRecordPaginator + { + $response = $this->client->get("ConfigurationItemDnsRecords/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new ConfigurationItemDnsRecordPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('ConfigurationItemDnsRecords/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordService.php b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordService.php new file mode 100644 index 00000000..da7a7242 --- /dev/null +++ b/src/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordService.php @@ -0,0 +1,95 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the ConfigurationItemDnsRecord to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("ConfigurationItemDnsRecords/$id"); + } + + /** + * Finds the ConfigurationItemDnsRecord based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): ConfigurationItemDnsRecordEntity + { + return ConfigurationItemDnsRecordEntity::fromResponse( + $this->client->get("ConfigurationItemDnsRecords/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("ConfigurationItemDnsRecords/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("ConfigurationItemDnsRecords/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see ConfigurationItemDnsRecordQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): ConfigurationItemDnsRecordQueryBuilder + { + return new ConfigurationItemDnsRecordQueryBuilder($this->client); + } +} diff --git a/src/API/ConfigurationItemExts/ConfigurationItemExtEntity.php b/src/API/ConfigurationItemExts/ConfigurationItemExtEntity.php index ca072740..049045d4 100644 --- a/src/API/ConfigurationItemExts/ConfigurationItemExtEntity.php +++ b/src/API/ConfigurationItemExts/ConfigurationItemExtEntity.php @@ -44,6 +44,11 @@ class ConfigurationItemExtEntity extends DataTransferObject public $dattoUsedKilobytes; public ?string $dattoZFSVersionID; public ?string $deviceNetworkingID; + public ?string $domain; + public ?Carbon $domainExpirationDateTime; + public ?Carbon $domainLastUpdatedDateTime; + public ?int $domainRegistrarID; + public ?Carbon $domainRegistrationDateTime; public ?float $hourlyCost; public $id; public ?int $impersonatorCreatorResourceID; @@ -102,6 +107,16 @@ class ConfigurationItemExtEntity extends DataTransferObject public ?float $setupFee; public ?int $sourceChargeID; public ?int $sourceChargeType; + public ?string $sslCommonName; + public ?string $sslIssuedBy; + public ?string $sslLocation; + public ?string $sslOrganization; + public ?string $sslOrganizationUnit; + public ?string $sslSerialNumber; + public ?string $sslSignatureAlgorithm; + public ?string $sslSource; + public ?Carbon $sslValidFromDateTime; + public ?Carbon $sslValidUntilDateTime; public ?int $vendorID; public ?Carbon $warrantyExpirationDate; /** @var \Anteris\Autotask\Support\UserDefinedFields\UserDefinedFieldEntity[]|null */ @@ -123,6 +138,18 @@ public function __construct(array $array) $array['dattoLastCheckInDateTime'] = new Carbon($array['dattoLastCheckInDateTime']); } + if (isset($array['domainExpirationDateTime'])) { + $array['domainExpirationDateTime'] = new Carbon($array['domainExpirationDateTime']); + } + + if (isset($array['domainLastUpdatedDateTime'])) { + $array['domainLastUpdatedDateTime'] = new Carbon($array['domainLastUpdatedDateTime']); + } + + if (isset($array['domainRegistrationDateTime'])) { + $array['domainRegistrationDateTime'] = new Carbon($array['domainRegistrationDateTime']); + } + if (isset($array['installDate'])) { $array['installDate'] = new Carbon($array['installDate']); } @@ -131,6 +158,14 @@ public function __construct(array $array) $array['lastModifiedTime'] = new Carbon($array['lastModifiedTime']); } + if (isset($array['sslValidFromDateTime'])) { + $array['sslValidFromDateTime'] = new Carbon($array['sslValidFromDateTime']); + } + + if (isset($array['sslValidUntilDateTime'])) { + $array['sslValidUntilDateTime'] = new Carbon($array['sslValidUntilDateTime']); + } + if (isset($array['warrantyExpirationDate'])) { $array['warrantyExpirationDate'] = new Carbon($array['warrantyExpirationDate']); } diff --git a/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameCollection.php b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameCollection.php new file mode 100644 index 00000000..f103c6a5 --- /dev/null +++ b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): ConfigurationItemSslSubjectAlternativeNameCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + ConfigurationItemSslSubjectAlternativeNameEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameEntity.php b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameEntity.php new file mode 100644 index 00000000..f5931829 --- /dev/null +++ b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNamePaginator.php b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNamePaginator.php new file mode 100644 index 00000000..d774c29c --- /dev/null +++ b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNamePaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = ConfigurationItemSslSubjectAlternativeNameCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): ConfigurationItemSslSubjectAlternativeNamePaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): ConfigurationItemSslSubjectAlternativeNamePaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameQueryBuilder.php b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameQueryBuilder.php new file mode 100644 index 00000000..adbc610f --- /dev/null +++ b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("ConfigurationItemSslSubjectAlternativeNames/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): ConfigurationItemSslSubjectAlternativeNameCollection + { + $response = $this->client->get("ConfigurationItemSslSubjectAlternativeNames/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return ConfigurationItemSslSubjectAlternativeNameCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): ConfigurationItemSslSubjectAlternativeNamePaginator + { + $response = $this->client->get("ConfigurationItemSslSubjectAlternativeNames/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new ConfigurationItemSslSubjectAlternativeNamePaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('ConfigurationItemSslSubjectAlternativeNames/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameService.php b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameService.php new file mode 100644 index 00000000..1dd94c3d --- /dev/null +++ b/src/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameService.php @@ -0,0 +1,95 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the ConfigurationItemSslSubjectAlternativeName to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("ConfigurationItemSslSubjectAlternativeNames/$id"); + } + + /** + * Finds the ConfigurationItemSslSubjectAlternativeName based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): ConfigurationItemSslSubjectAlternativeNameEntity + { + return ConfigurationItemSslSubjectAlternativeNameEntity::fromResponse( + $this->client->get("ConfigurationItemSslSubjectAlternativeNames/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("ConfigurationItemSslSubjectAlternativeNames/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("ConfigurationItemSslSubjectAlternativeNames/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see ConfigurationItemSslSubjectAlternativeNameQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): ConfigurationItemSslSubjectAlternativeNameQueryBuilder + { + return new ConfigurationItemSslSubjectAlternativeNameQueryBuilder($this->client); + } +} diff --git a/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceCollection.php b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceCollection.php new file mode 100644 index 00000000..d756aecd --- /dev/null +++ b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): ConfigurationItemWebhookExcludedResourceCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + ConfigurationItemWebhookExcludedResourceEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceEntity.php b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceEntity.php new file mode 100644 index 00000000..303cef5b --- /dev/null +++ b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourcePaginator.php b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourcePaginator.php new file mode 100644 index 00000000..aba7c4a0 --- /dev/null +++ b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourcePaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = ConfigurationItemWebhookExcludedResourceCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): ConfigurationItemWebhookExcludedResourcePaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): ConfigurationItemWebhookExcludedResourcePaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceQueryBuilder.php b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceQueryBuilder.php new file mode 100644 index 00000000..7be75a56 --- /dev/null +++ b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("ConfigurationItemWebhookExcludedResources/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): ConfigurationItemWebhookExcludedResourceCollection + { + $response = $this->client->get("ConfigurationItemWebhookExcludedResources/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return ConfigurationItemWebhookExcludedResourceCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): ConfigurationItemWebhookExcludedResourcePaginator + { + $response = $this->client->get("ConfigurationItemWebhookExcludedResources/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new ConfigurationItemWebhookExcludedResourcePaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('ConfigurationItemWebhookExcludedResources/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceService.php b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceService.php new file mode 100644 index 00000000..d5bd418d --- /dev/null +++ b/src/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new configurationitemwebhookexcludedresource. + * + * @param ConfigurationItemWebhookExcludedResourceEntity $resource The configurationitemwebhookexcludedresource entity to be written. + * + * @author Aidan Casey + */ + public function create(ConfigurationItemWebhookExcludedResourceEntity $resource): Response + { + return $this->client->post("ConfigurationItemWebhookExcludedResources", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the ConfigurationItemWebhookExcludedResource to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("ConfigurationItemWebhookExcludedResources/$id"); + } + + /** + * Finds the ConfigurationItemWebhookExcludedResource based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): ConfigurationItemWebhookExcludedResourceEntity + { + return ConfigurationItemWebhookExcludedResourceEntity::fromResponse( + $this->client->get("ConfigurationItemWebhookExcludedResources/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("ConfigurationItemWebhookExcludedResources/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("ConfigurationItemWebhookExcludedResources/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see ConfigurationItemWebhookExcludedResourceQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): ConfigurationItemWebhookExcludedResourceQueryBuilder + { + return new ConfigurationItemWebhookExcludedResourceQueryBuilder($this->client); + } +} diff --git a/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldCollection.php b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldCollection.php new file mode 100644 index 00000000..fdc26ccb --- /dev/null +++ b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): ConfigurationItemWebhookFieldCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + ConfigurationItemWebhookFieldEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldEntity.php b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldEntity.php new file mode 100644 index 00000000..04d4938c --- /dev/null +++ b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldEntity.php @@ -0,0 +1,49 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldPaginator.php b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldPaginator.php new file mode 100644 index 00000000..660b553e --- /dev/null +++ b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = ConfigurationItemWebhookFieldCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): ConfigurationItemWebhookFieldPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): ConfigurationItemWebhookFieldPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldQueryBuilder.php b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldQueryBuilder.php new file mode 100644 index 00000000..47006545 --- /dev/null +++ b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("ConfigurationItemWebhookFields/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): ConfigurationItemWebhookFieldCollection + { + $response = $this->client->get("ConfigurationItemWebhookFields/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return ConfigurationItemWebhookFieldCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): ConfigurationItemWebhookFieldPaginator + { + $response = $this->client->get("ConfigurationItemWebhookFields/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new ConfigurationItemWebhookFieldPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('ConfigurationItemWebhookFields/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldService.php b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldService.php new file mode 100644 index 00000000..86fa6e9b --- /dev/null +++ b/src/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new configurationitemwebhookfield. + * + * @param ConfigurationItemWebhookFieldEntity $resource The configurationitemwebhookfield entity to be written. + * + * @author Aidan Casey + */ + public function create(ConfigurationItemWebhookFieldEntity $resource): Response + { + return $this->client->post("ConfigurationItemWebhookFields", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the ConfigurationItemWebhookField to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("ConfigurationItemWebhookFields/$id"); + } + + /** + * Finds the ConfigurationItemWebhookField based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): ConfigurationItemWebhookFieldEntity + { + return ConfigurationItemWebhookFieldEntity::fromResponse( + $this->client->get("ConfigurationItemWebhookFields/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("ConfigurationItemWebhookFields/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("ConfigurationItemWebhookFields/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see ConfigurationItemWebhookFieldQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): ConfigurationItemWebhookFieldQueryBuilder + { + return new ConfigurationItemWebhookFieldQueryBuilder($this->client); + } + + /** + * Updates the configurationitemwebhookfield. + * + * @param ConfigurationItemWebhookFieldEntity $resource The configurationitemwebhookfield entity to be updated. + * + * @author Aidan Casey + */ + public function update(ConfigurationItemWebhookFieldEntity $resource): Response + { + return $this->client->put("ConfigurationItemWebhookFields", $resource->toArray()); + } +} diff --git a/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldCollection.php b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldCollection.php new file mode 100644 index 00000000..03e6451e --- /dev/null +++ b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): ConfigurationItemWebhookUdfFieldCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + ConfigurationItemWebhookUdfFieldEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldEntity.php b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldEntity.php new file mode 100644 index 00000000..2ed6b4ae --- /dev/null +++ b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldEntity.php @@ -0,0 +1,49 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldPaginator.php b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldPaginator.php new file mode 100644 index 00000000..a5a521f0 --- /dev/null +++ b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = ConfigurationItemWebhookUdfFieldCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): ConfigurationItemWebhookUdfFieldPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): ConfigurationItemWebhookUdfFieldPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldQueryBuilder.php b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldQueryBuilder.php new file mode 100644 index 00000000..8baf3e79 --- /dev/null +++ b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("ConfigurationItemWebhookUdfFields/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): ConfigurationItemWebhookUdfFieldCollection + { + $response = $this->client->get("ConfigurationItemWebhookUdfFields/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return ConfigurationItemWebhookUdfFieldCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): ConfigurationItemWebhookUdfFieldPaginator + { + $response = $this->client->get("ConfigurationItemWebhookUdfFields/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new ConfigurationItemWebhookUdfFieldPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('ConfigurationItemWebhookUdfFields/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldService.php b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldService.php new file mode 100644 index 00000000..a75aff77 --- /dev/null +++ b/src/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new configurationitemwebhookudffield. + * + * @param ConfigurationItemWebhookUdfFieldEntity $resource The configurationitemwebhookudffield entity to be written. + * + * @author Aidan Casey + */ + public function create(ConfigurationItemWebhookUdfFieldEntity $resource): Response + { + return $this->client->post("ConfigurationItemWebhookUdfFields", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the ConfigurationItemWebhookUdfField to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("ConfigurationItemWebhookUdfFields/$id"); + } + + /** + * Finds the ConfigurationItemWebhookUdfField based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): ConfigurationItemWebhookUdfFieldEntity + { + return ConfigurationItemWebhookUdfFieldEntity::fromResponse( + $this->client->get("ConfigurationItemWebhookUdfFields/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("ConfigurationItemWebhookUdfFields/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("ConfigurationItemWebhookUdfFields/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see ConfigurationItemWebhookUdfFieldQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): ConfigurationItemWebhookUdfFieldQueryBuilder + { + return new ConfigurationItemWebhookUdfFieldQueryBuilder($this->client); + } + + /** + * Updates the configurationitemwebhookudffield. + * + * @param ConfigurationItemWebhookUdfFieldEntity $resource The configurationitemwebhookudffield entity to be updated. + * + * @author Aidan Casey + */ + public function update(ConfigurationItemWebhookUdfFieldEntity $resource): Response + { + return $this->client->put("ConfigurationItemWebhookUdfFields", $resource->toArray()); + } +} diff --git a/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookCollection.php b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookCollection.php new file mode 100644 index 00000000..824684f6 --- /dev/null +++ b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): ConfigurationItemWebhookCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + ConfigurationItemWebhookEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookEntity.php b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookEntity.php new file mode 100644 index 00000000..5032fa44 --- /dev/null +++ b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookEntity.php @@ -0,0 +1,58 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookPaginator.php b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookPaginator.php new file mode 100644 index 00000000..454686c4 --- /dev/null +++ b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = ConfigurationItemWebhookCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): ConfigurationItemWebhookPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): ConfigurationItemWebhookPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookQueryBuilder.php b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookQueryBuilder.php new file mode 100644 index 00000000..da53fc6d --- /dev/null +++ b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("ConfigurationItemWebhooks/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): ConfigurationItemWebhookCollection + { + $response = $this->client->get("ConfigurationItemWebhooks/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return ConfigurationItemWebhookCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): ConfigurationItemWebhookPaginator + { + $response = $this->client->get("ConfigurationItemWebhooks/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new ConfigurationItemWebhookPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('ConfigurationItemWebhooks/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookService.php b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookService.php new file mode 100644 index 00000000..6b8d804e --- /dev/null +++ b/src/API/ConfigurationItemWebhooks/ConfigurationItemWebhookService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new configurationitemwebhook. + * + * @param ConfigurationItemWebhookEntity $resource The configurationitemwebhook entity to be written. + * + * @author Aidan Casey + */ + public function create(ConfigurationItemWebhookEntity $resource): Response + { + return $this->client->post("ConfigurationItemWebhooks", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the ConfigurationItemWebhook to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("ConfigurationItemWebhooks/$id"); + } + + /** + * Finds the ConfigurationItemWebhook based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): ConfigurationItemWebhookEntity + { + return ConfigurationItemWebhookEntity::fromResponse( + $this->client->get("ConfigurationItemWebhooks/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("ConfigurationItemWebhooks/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("ConfigurationItemWebhooks/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see ConfigurationItemWebhookQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): ConfigurationItemWebhookQueryBuilder + { + return new ConfigurationItemWebhookQueryBuilder($this->client); + } + + /** + * Updates the configurationitemwebhook. + * + * @param ConfigurationItemWebhookEntity $resource The configurationitemwebhook entity to be updated. + * + * @author Aidan Casey + */ + public function update(ConfigurationItemWebhookEntity $resource): Response + { + return $this->client->put("ConfigurationItemWebhooks", $resource->toArray()); + } +} diff --git a/src/API/ConfigurationItems/ConfigurationItemEntity.php b/src/API/ConfigurationItems/ConfigurationItemEntity.php index ecda6597..b1c26c67 100644 --- a/src/API/ConfigurationItems/ConfigurationItemEntity.php +++ b/src/API/ConfigurationItems/ConfigurationItemEntity.php @@ -44,6 +44,11 @@ class ConfigurationItemEntity extends DataTransferObject public $dattoUsedKilobytes; public ?int $dattoZFSVersionID; public ?string $deviceNetworkingID; + public ?string $domain; + public ?Carbon $domainExpirationDateTime; + public ?Carbon $domainLastUpdatedDateTime; + public ?int $domainRegistrarID; + public ?Carbon $domainRegistrationDateTime; public ?float $hourlyCost; public $id; public ?int $impersonatorCreatorResourceID; @@ -101,6 +106,16 @@ class ConfigurationItemEntity extends DataTransferObject public ?float $setupFee; public ?int $sourceChargeID; public ?int $sourceChargeType; + public ?string $sslCommonName; + public ?string $sslIssuedBy; + public ?string $sslLocation; + public ?string $sslOrganization; + public ?string $sslOrganizationUnit; + public ?string $sslSerialNumber; + public ?string $sslSignatureAlgorithm; + public ?string $sslSource; + public ?Carbon $sslValidFromDateTime; + public ?Carbon $sslValidUntilDateTime; public ?int $vendorID; public ?Carbon $warrantyExpirationDate; /** @var \Anteris\Autotask\Support\UserDefinedFields\UserDefinedFieldEntity[]|null */ @@ -122,6 +137,18 @@ public function __construct(array $array) $array['dattoLastCheckInDateTime'] = new Carbon($array['dattoLastCheckInDateTime']); } + if (isset($array['domainExpirationDateTime'])) { + $array['domainExpirationDateTime'] = new Carbon($array['domainExpirationDateTime']); + } + + if (isset($array['domainLastUpdatedDateTime'])) { + $array['domainLastUpdatedDateTime'] = new Carbon($array['domainLastUpdatedDateTime']); + } + + if (isset($array['domainRegistrationDateTime'])) { + $array['domainRegistrationDateTime'] = new Carbon($array['domainRegistrationDateTime']); + } + if (isset($array['installDate'])) { $array['installDate'] = new Carbon($array['installDate']); } @@ -130,6 +157,14 @@ public function __construct(array $array) $array['lastModifiedTime'] = new Carbon($array['lastModifiedTime']); } + if (isset($array['sslValidFromDateTime'])) { + $array['sslValidFromDateTime'] = new Carbon($array['sslValidFromDateTime']); + } + + if (isset($array['sslValidUntilDateTime'])) { + $array['sslValidUntilDateTime'] = new Carbon($array['sslValidUntilDateTime']); + } + if (isset($array['warrantyExpirationDate'])) { $array['warrantyExpirationDate'] = new Carbon($array['warrantyExpirationDate']); } diff --git a/src/API/Countries/CountryEntity.php b/src/API/Countries/CountryEntity.php index 75ac1884..167de95b 100644 --- a/src/API/Countries/CountryEntity.php +++ b/src/API/Countries/CountryEntity.php @@ -18,6 +18,7 @@ class CountryEntity extends DataTransferObject public ?bool $isActive; public ?bool $isDefaultCountry; public ?string $name; + public ?int $purchaseOrderTemplateID; public ?int $quoteTemplateID; /** @var \Anteris\Autotask\Support\UserDefinedFields\UserDefinedFieldEntity[]|null */ public ?array $userDefinedFields; diff --git a/src/API/DocumentAttachments/DocumentAttachmentCollection.php b/src/API/DocumentAttachments/DocumentAttachmentCollection.php new file mode 100644 index 00000000..0d514442 --- /dev/null +++ b/src/API/DocumentAttachments/DocumentAttachmentCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentAttachmentCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentAttachmentEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentAttachments/DocumentAttachmentEntity.php b/src/API/DocumentAttachments/DocumentAttachmentEntity.php new file mode 100644 index 00000000..da2b7ed8 --- /dev/null +++ b/src/API/DocumentAttachments/DocumentAttachmentEntity.php @@ -0,0 +1,63 @@ + + */ + public function __construct(array $array) + { + if (isset($array['attachDate'])) { + $array['attachDate'] = new Carbon($array['attachDate']); + } + + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentAttachments/DocumentAttachmentPaginator.php b/src/API/DocumentAttachments/DocumentAttachmentPaginator.php new file mode 100644 index 00000000..13bc909d --- /dev/null +++ b/src/API/DocumentAttachments/DocumentAttachmentPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentAttachmentCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentAttachmentPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentAttachmentPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentAttachments/DocumentAttachmentQueryBuilder.php b/src/API/DocumentAttachments/DocumentAttachmentQueryBuilder.php new file mode 100644 index 00000000..62a25f56 --- /dev/null +++ b/src/API/DocumentAttachments/DocumentAttachmentQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentAttachments/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentAttachmentCollection + { + $response = $this->client->get("DocumentAttachments/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentAttachmentCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentAttachmentPaginator + { + $response = $this->client->get("DocumentAttachments/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentAttachmentPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentAttachments/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentAttachments/DocumentAttachmentService.php b/src/API/DocumentAttachments/DocumentAttachmentService.php new file mode 100644 index 00000000..34f58fa9 --- /dev/null +++ b/src/API/DocumentAttachments/DocumentAttachmentService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documentattachment. + * + * @param DocumentAttachmentEntity $resource The documentattachment entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentAttachmentEntity $resource): Response + { + return $this->client->post("DocumentAttachments", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the DocumentAttachment to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("DocumentAttachments/$id"); + } + + /** + * Finds the DocumentAttachment based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentAttachmentEntity + { + return DocumentAttachmentEntity::fromResponse( + $this->client->get("DocumentAttachments/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentAttachments/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentAttachments/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentAttachmentQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentAttachmentQueryBuilder + { + return new DocumentAttachmentQueryBuilder($this->client); + } +} diff --git a/src/API/DocumentCategories/DocumentCategoryCollection.php b/src/API/DocumentCategories/DocumentCategoryCollection.php new file mode 100644 index 00000000..1878f953 --- /dev/null +++ b/src/API/DocumentCategories/DocumentCategoryCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentCategoryCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentCategoryEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentCategories/DocumentCategoryEntity.php b/src/API/DocumentCategories/DocumentCategoryEntity.php new file mode 100644 index 00000000..8b0b2508 --- /dev/null +++ b/src/API/DocumentCategories/DocumentCategoryEntity.php @@ -0,0 +1,48 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentCategories/DocumentCategoryPaginator.php b/src/API/DocumentCategories/DocumentCategoryPaginator.php new file mode 100644 index 00000000..3a5ae332 --- /dev/null +++ b/src/API/DocumentCategories/DocumentCategoryPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentCategoryCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentCategoryPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentCategoryPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentCategories/DocumentCategoryQueryBuilder.php b/src/API/DocumentCategories/DocumentCategoryQueryBuilder.php new file mode 100644 index 00000000..4e93d460 --- /dev/null +++ b/src/API/DocumentCategories/DocumentCategoryQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentCategories/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentCategoryCollection + { + $response = $this->client->get("DocumentCategories/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentCategoryCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentCategoryPaginator + { + $response = $this->client->get("DocumentCategories/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentCategoryPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentCategories/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentCategories/DocumentCategoryService.php b/src/API/DocumentCategories/DocumentCategoryService.php new file mode 100644 index 00000000..66db6199 --- /dev/null +++ b/src/API/DocumentCategories/DocumentCategoryService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documentcategory. + * + * @param DocumentCategoryEntity $resource The documentcategory entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentCategoryEntity $resource): Response + { + return $this->client->post("DocumentCategories", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the DocumentCategory to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("DocumentCategories/$id"); + } + + /** + * Finds the DocumentCategory based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentCategoryEntity + { + return DocumentCategoryEntity::fromResponse( + $this->client->get("DocumentCategories/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentCategories/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentCategories/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentCategoryQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentCategoryQueryBuilder + { + return new DocumentCategoryQueryBuilder($this->client); + } + + /** + * Updates the documentcategory. + * + * @param DocumentCategoryEntity $resource The documentcategory entity to be updated. + * + * @author Aidan Casey + */ + public function update(DocumentCategoryEntity $resource): Response + { + return $this->client->put("DocumentCategories", $resource->toArray()); + } +} diff --git a/src/API/DocumentChecklistItems/DocumentChecklistItemCollection.php b/src/API/DocumentChecklistItems/DocumentChecklistItemCollection.php new file mode 100644 index 00000000..f44b8d0b --- /dev/null +++ b/src/API/DocumentChecklistItems/DocumentChecklistItemCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentChecklistItemCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentChecklistItemEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentChecklistItems/DocumentChecklistItemEntity.php b/src/API/DocumentChecklistItems/DocumentChecklistItemEntity.php new file mode 100644 index 00000000..83fd42fb --- /dev/null +++ b/src/API/DocumentChecklistItems/DocumentChecklistItemEntity.php @@ -0,0 +1,49 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentChecklistItems/DocumentChecklistItemPaginator.php b/src/API/DocumentChecklistItems/DocumentChecklistItemPaginator.php new file mode 100644 index 00000000..f018d2f5 --- /dev/null +++ b/src/API/DocumentChecklistItems/DocumentChecklistItemPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentChecklistItemCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentChecklistItemPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentChecklistItemPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentChecklistItems/DocumentChecklistItemQueryBuilder.php b/src/API/DocumentChecklistItems/DocumentChecklistItemQueryBuilder.php new file mode 100644 index 00000000..3e3a6abc --- /dev/null +++ b/src/API/DocumentChecklistItems/DocumentChecklistItemQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentChecklistItems/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentChecklistItemCollection + { + $response = $this->client->get("DocumentChecklistItems/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentChecklistItemCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentChecklistItemPaginator + { + $response = $this->client->get("DocumentChecklistItems/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentChecklistItemPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentChecklistItems/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentChecklistItems/DocumentChecklistItemService.php b/src/API/DocumentChecklistItems/DocumentChecklistItemService.php new file mode 100644 index 00000000..fe4e0477 --- /dev/null +++ b/src/API/DocumentChecklistItems/DocumentChecklistItemService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documentchecklistitem. + * + * @param DocumentChecklistItemEntity $resource The documentchecklistitem entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentChecklistItemEntity $resource): Response + { + return $this->client->post("DocumentChecklistItems", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the DocumentChecklistItem to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("DocumentChecklistItems/$id"); + } + + /** + * Finds the DocumentChecklistItem based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentChecklistItemEntity + { + return DocumentChecklistItemEntity::fromResponse( + $this->client->get("DocumentChecklistItems/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentChecklistItems/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentChecklistItems/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentChecklistItemQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentChecklistItemQueryBuilder + { + return new DocumentChecklistItemQueryBuilder($this->client); + } + + /** + * Updates the documentchecklistitem. + * + * @param DocumentChecklistItemEntity $resource The documentchecklistitem entity to be updated. + * + * @author Aidan Casey + */ + public function update(DocumentChecklistItemEntity $resource): Response + { + return $this->client->put("DocumentChecklistItems", $resource->toArray()); + } +} diff --git a/src/API/DocumentChecklistLibraries/DocumentChecklistLibraryCollection.php b/src/API/DocumentChecklistLibraries/DocumentChecklistLibraryCollection.php new file mode 100644 index 00000000..af8bae26 --- /dev/null +++ b/src/API/DocumentChecklistLibraries/DocumentChecklistLibraryCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentChecklistLibraryCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentChecklistLibraryEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentChecklistLibraries/DocumentChecklistLibraryEntity.php b/src/API/DocumentChecklistLibraries/DocumentChecklistLibraryEntity.php new file mode 100644 index 00000000..3035255d --- /dev/null +++ b/src/API/DocumentChecklistLibraries/DocumentChecklistLibraryEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentChecklistLibraries/DocumentChecklistLibraryService.php b/src/API/DocumentChecklistLibraries/DocumentChecklistLibraryService.php new file mode 100644 index 00000000..318dcb57 --- /dev/null +++ b/src/API/DocumentChecklistLibraries/DocumentChecklistLibraryService.php @@ -0,0 +1,70 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documentchecklistlibrary. + * + * @param DocumentChecklistLibraryEntity $resource The documentchecklistlibrary entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentChecklistLibraryEntity $resource): Response + { + return $this->client->post("DocumentChecklistLibraries", $resource->toArray()); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentChecklistLibraries/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentChecklistLibraries/entityInformation") + ); + } +} diff --git a/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationCollection.php b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationCollection.php new file mode 100644 index 00000000..9da8d074 --- /dev/null +++ b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentConfigurationItemAssociationCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentConfigurationItemAssociationEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationEntity.php b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationEntity.php new file mode 100644 index 00000000..09a2f0bf --- /dev/null +++ b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationPaginator.php b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationPaginator.php new file mode 100644 index 00000000..55f7a718 --- /dev/null +++ b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentConfigurationItemAssociationCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentConfigurationItemAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentConfigurationItemAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationQueryBuilder.php b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationQueryBuilder.php new file mode 100644 index 00000000..2f80d77e --- /dev/null +++ b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentConfigurationItemAssociations/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentConfigurationItemAssociationCollection + { + $response = $this->client->get("DocumentConfigurationItemAssociations/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentConfigurationItemAssociationCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentConfigurationItemAssociationPaginator + { + $response = $this->client->get("DocumentConfigurationItemAssociations/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentConfigurationItemAssociationPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentConfigurationItemAssociations/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationService.php b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationService.php new file mode 100644 index 00000000..642b5abb --- /dev/null +++ b/src/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documentconfigurationitemassociation. + * + * @param DocumentConfigurationItemAssociationEntity $resource The documentconfigurationitemassociation entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentConfigurationItemAssociationEntity $resource): Response + { + return $this->client->post("DocumentConfigurationItemAssociations", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the DocumentConfigurationItemAssociation to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("DocumentConfigurationItemAssociations/$id"); + } + + /** + * Finds the DocumentConfigurationItemAssociation based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentConfigurationItemAssociationEntity + { + return DocumentConfigurationItemAssociationEntity::fromResponse( + $this->client->get("DocumentConfigurationItemAssociations/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentConfigurationItemAssociations/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentConfigurationItemAssociations/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentConfigurationItemAssociationQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentConfigurationItemAssociationQueryBuilder + { + return new DocumentConfigurationItemAssociationQueryBuilder($this->client); + } +} diff --git a/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationCollection.php b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationCollection.php new file mode 100644 index 00000000..d7669aee --- /dev/null +++ b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentConfigurationItemCategoryAssociationCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentConfigurationItemCategoryAssociationEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationEntity.php b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationEntity.php new file mode 100644 index 00000000..747a25bd --- /dev/null +++ b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationPaginator.php b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationPaginator.php new file mode 100644 index 00000000..7dc65ffc --- /dev/null +++ b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentConfigurationItemCategoryAssociationCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentConfigurationItemCategoryAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentConfigurationItemCategoryAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationQueryBuilder.php b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationQueryBuilder.php new file mode 100644 index 00000000..d7c722c2 --- /dev/null +++ b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentConfigurationItemCategoryAssociations/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentConfigurationItemCategoryAssociationCollection + { + $response = $this->client->get("DocumentConfigurationItemCategoryAssociations/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentConfigurationItemCategoryAssociationCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentConfigurationItemCategoryAssociationPaginator + { + $response = $this->client->get("DocumentConfigurationItemCategoryAssociations/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentConfigurationItemCategoryAssociationPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentConfigurationItemCategoryAssociations/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationService.php b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationService.php new file mode 100644 index 00000000..00015627 --- /dev/null +++ b/src/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documentconfigurationitemcategoryassociation. + * + * @param DocumentConfigurationItemCategoryAssociationEntity $resource The documentconfigurationitemcategoryassociation entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentConfigurationItemCategoryAssociationEntity $resource): Response + { + return $this->client->post("DocumentConfigurationItemCategoryAssociations", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the DocumentConfigurationItemCategoryAssociation to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("DocumentConfigurationItemCategoryAssociations/$id"); + } + + /** + * Finds the DocumentConfigurationItemCategoryAssociation based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentConfigurationItemCategoryAssociationEntity + { + return DocumentConfigurationItemCategoryAssociationEntity::fromResponse( + $this->client->get("DocumentConfigurationItemCategoryAssociations/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentConfigurationItemCategoryAssociations/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentConfigurationItemCategoryAssociations/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentConfigurationItemCategoryAssociationQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentConfigurationItemCategoryAssociationQueryBuilder + { + return new DocumentConfigurationItemCategoryAssociationQueryBuilder($this->client); + } +} diff --git a/src/API/DocumentNotes/DocumentNoteCollection.php b/src/API/DocumentNotes/DocumentNoteCollection.php new file mode 100644 index 00000000..ceafcf39 --- /dev/null +++ b/src/API/DocumentNotes/DocumentNoteCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentNoteCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentNoteEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentNotes/DocumentNoteEntity.php b/src/API/DocumentNotes/DocumentNoteEntity.php new file mode 100644 index 00000000..574b019c --- /dev/null +++ b/src/API/DocumentNotes/DocumentNoteEntity.php @@ -0,0 +1,61 @@ + + */ + public function __construct(array $array) + { + if (isset($array['createdDateTime'])) { + $array['createdDateTime'] = new Carbon($array['createdDateTime']); + } + + if (isset($array['lastModifiedDateTime'])) { + $array['lastModifiedDateTime'] = new Carbon($array['lastModifiedDateTime']); + } + + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentNotes/DocumentNotePaginator.php b/src/API/DocumentNotes/DocumentNotePaginator.php new file mode 100644 index 00000000..57068188 --- /dev/null +++ b/src/API/DocumentNotes/DocumentNotePaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentNoteCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentNotePaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentNotePaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentNotes/DocumentNoteQueryBuilder.php b/src/API/DocumentNotes/DocumentNoteQueryBuilder.php new file mode 100644 index 00000000..f2c00595 --- /dev/null +++ b/src/API/DocumentNotes/DocumentNoteQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentNotes/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentNoteCollection + { + $response = $this->client->get("DocumentNotes/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentNoteCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentNotePaginator + { + $response = $this->client->get("DocumentNotes/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentNotePaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentNotes/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentNotes/DocumentNoteService.php b/src/API/DocumentNotes/DocumentNoteService.php new file mode 100644 index 00000000..d77719a3 --- /dev/null +++ b/src/API/DocumentNotes/DocumentNoteService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documentnote. + * + * @param DocumentNoteEntity $resource The documentnote entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentNoteEntity $resource): Response + { + return $this->client->post("DocumentNotes", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the DocumentNote to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("DocumentNotes/$id"); + } + + /** + * Finds the DocumentNote based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentNoteEntity + { + return DocumentNoteEntity::fromResponse( + $this->client->get("DocumentNotes/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentNotes/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentNotes/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentNoteQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentNoteQueryBuilder + { + return new DocumentNoteQueryBuilder($this->client); + } + + /** + * Updates the documentnote. + * + * @param DocumentNoteEntity $resource The documentnote entity to be updated. + * + * @author Aidan Casey + */ + public function update(DocumentNoteEntity $resource): Response + { + return $this->client->put("DocumentNotes", $resource->toArray()); + } +} diff --git a/src/API/DocumentPlainTextContent/DocumentPlainTextContentCollection.php b/src/API/DocumentPlainTextContent/DocumentPlainTextContentCollection.php new file mode 100644 index 00000000..e72d0785 --- /dev/null +++ b/src/API/DocumentPlainTextContent/DocumentPlainTextContentCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentPlainTextContentCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentPlainTextContentEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentPlainTextContent/DocumentPlainTextContentEntity.php b/src/API/DocumentPlainTextContent/DocumentPlainTextContentEntity.php new file mode 100644 index 00000000..8de7e931 --- /dev/null +++ b/src/API/DocumentPlainTextContent/DocumentPlainTextContentEntity.php @@ -0,0 +1,46 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentPlainTextContent/DocumentPlainTextContentPaginator.php b/src/API/DocumentPlainTextContent/DocumentPlainTextContentPaginator.php new file mode 100644 index 00000000..30638844 --- /dev/null +++ b/src/API/DocumentPlainTextContent/DocumentPlainTextContentPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentPlainTextContentCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentPlainTextContentPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentPlainTextContentPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentPlainTextContent/DocumentPlainTextContentQueryBuilder.php b/src/API/DocumentPlainTextContent/DocumentPlainTextContentQueryBuilder.php new file mode 100644 index 00000000..e0108f81 --- /dev/null +++ b/src/API/DocumentPlainTextContent/DocumentPlainTextContentQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentPlainTextContent/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentPlainTextContentCollection + { + $response = $this->client->get("DocumentPlainTextContent/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentPlainTextContentCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentPlainTextContentPaginator + { + $response = $this->client->get("DocumentPlainTextContent/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentPlainTextContentPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentPlainTextContent/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentPlainTextContent/DocumentPlainTextContentService.php b/src/API/DocumentPlainTextContent/DocumentPlainTextContentService.php new file mode 100644 index 00000000..854d2344 --- /dev/null +++ b/src/API/DocumentPlainTextContent/DocumentPlainTextContentService.php @@ -0,0 +1,96 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Finds the DocumentPlainTextContent based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentPlainTextContentEntity + { + return DocumentPlainTextContentEntity::fromResponse( + $this->client->get("DocumentPlainTextContent/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentPlainTextContent/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentPlainTextContent/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentPlainTextContentQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentPlainTextContentQueryBuilder + { + return new DocumentPlainTextContentQueryBuilder($this->client); + } + + /** + * Updates the documentplaintextcontent. + * + * @param DocumentPlainTextContentEntity $resource The documentplaintextcontent entity to be updated. + * + * @author Aidan Casey + */ + public function update(DocumentPlainTextContentEntity $resource): Response + { + return $this->client->put("DocumentPlainTextContent", $resource->toArray()); + } +} diff --git a/src/API/DocumentTagAssociations/DocumentTagAssociationCollection.php b/src/API/DocumentTagAssociations/DocumentTagAssociationCollection.php new file mode 100644 index 00000000..d5a194df --- /dev/null +++ b/src/API/DocumentTagAssociations/DocumentTagAssociationCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentTagAssociationCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentTagAssociationEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentTagAssociations/DocumentTagAssociationEntity.php b/src/API/DocumentTagAssociations/DocumentTagAssociationEntity.php new file mode 100644 index 00000000..ab1a42dd --- /dev/null +++ b/src/API/DocumentTagAssociations/DocumentTagAssociationEntity.php @@ -0,0 +1,54 @@ + + */ + public function __construct(array $array) + { + if (isset($array['createDateTime'])) { + $array['createDateTime'] = new Carbon($array['createDateTime']); + } + + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentTagAssociations/DocumentTagAssociationPaginator.php b/src/API/DocumentTagAssociations/DocumentTagAssociationPaginator.php new file mode 100644 index 00000000..a8304e0b --- /dev/null +++ b/src/API/DocumentTagAssociations/DocumentTagAssociationPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentTagAssociationCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentTagAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentTagAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentTagAssociations/DocumentTagAssociationQueryBuilder.php b/src/API/DocumentTagAssociations/DocumentTagAssociationQueryBuilder.php new file mode 100644 index 00000000..2a55b736 --- /dev/null +++ b/src/API/DocumentTagAssociations/DocumentTagAssociationQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentTagAssociations/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentTagAssociationCollection + { + $response = $this->client->get("DocumentTagAssociations/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentTagAssociationCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentTagAssociationPaginator + { + $response = $this->client->get("DocumentTagAssociations/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentTagAssociationPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentTagAssociations/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentTagAssociations/DocumentTagAssociationService.php b/src/API/DocumentTagAssociations/DocumentTagAssociationService.php new file mode 100644 index 00000000..c5b538f1 --- /dev/null +++ b/src/API/DocumentTagAssociations/DocumentTagAssociationService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documenttagassociation. + * + * @param DocumentTagAssociationEntity $resource The documenttagassociation entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentTagAssociationEntity $resource): Response + { + return $this->client->post("DocumentTagAssociations", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the DocumentTagAssociation to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("DocumentTagAssociations/$id"); + } + + /** + * Finds the DocumentTagAssociation based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentTagAssociationEntity + { + return DocumentTagAssociationEntity::fromResponse( + $this->client->get("DocumentTagAssociations/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentTagAssociations/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentTagAssociations/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentTagAssociationQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentTagAssociationQueryBuilder + { + return new DocumentTagAssociationQueryBuilder($this->client); + } +} diff --git a/src/API/DocumentTicketAssociations/DocumentTicketAssociationCollection.php b/src/API/DocumentTicketAssociations/DocumentTicketAssociationCollection.php new file mode 100644 index 00000000..6a437e86 --- /dev/null +++ b/src/API/DocumentTicketAssociations/DocumentTicketAssociationCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentTicketAssociationCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentTicketAssociationEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentTicketAssociations/DocumentTicketAssociationEntity.php b/src/API/DocumentTicketAssociations/DocumentTicketAssociationEntity.php new file mode 100644 index 00000000..fc002b2d --- /dev/null +++ b/src/API/DocumentTicketAssociations/DocumentTicketAssociationEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentTicketAssociations/DocumentTicketAssociationPaginator.php b/src/API/DocumentTicketAssociations/DocumentTicketAssociationPaginator.php new file mode 100644 index 00000000..69ef0848 --- /dev/null +++ b/src/API/DocumentTicketAssociations/DocumentTicketAssociationPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentTicketAssociationCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentTicketAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentTicketAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentTicketAssociations/DocumentTicketAssociationQueryBuilder.php b/src/API/DocumentTicketAssociations/DocumentTicketAssociationQueryBuilder.php new file mode 100644 index 00000000..3b67bd84 --- /dev/null +++ b/src/API/DocumentTicketAssociations/DocumentTicketAssociationQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentTicketAssociations/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentTicketAssociationCollection + { + $response = $this->client->get("DocumentTicketAssociations/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentTicketAssociationCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentTicketAssociationPaginator + { + $response = $this->client->get("DocumentTicketAssociations/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentTicketAssociationPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentTicketAssociations/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentTicketAssociations/DocumentTicketAssociationService.php b/src/API/DocumentTicketAssociations/DocumentTicketAssociationService.php new file mode 100644 index 00000000..f46aa670 --- /dev/null +++ b/src/API/DocumentTicketAssociations/DocumentTicketAssociationService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documentticketassociation. + * + * @param DocumentTicketAssociationEntity $resource The documentticketassociation entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentTicketAssociationEntity $resource): Response + { + return $this->client->post("DocumentTicketAssociations", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the DocumentTicketAssociation to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("DocumentTicketAssociations/$id"); + } + + /** + * Finds the DocumentTicketAssociation based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentTicketAssociationEntity + { + return DocumentTicketAssociationEntity::fromResponse( + $this->client->get("DocumentTicketAssociations/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentTicketAssociations/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentTicketAssociations/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentTicketAssociationQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentTicketAssociationQueryBuilder + { + return new DocumentTicketAssociationQueryBuilder($this->client); + } +} diff --git a/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationCollection.php b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationCollection.php new file mode 100644 index 00000000..1dee4746 --- /dev/null +++ b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentToDocumentAssociationCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentToDocumentAssociationEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationEntity.php b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationEntity.php new file mode 100644 index 00000000..ae3c3564 --- /dev/null +++ b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationPaginator.php b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationPaginator.php new file mode 100644 index 00000000..d1704dbe --- /dev/null +++ b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentToDocumentAssociationCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentToDocumentAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentToDocumentAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationQueryBuilder.php b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationQueryBuilder.php new file mode 100644 index 00000000..0053af6a --- /dev/null +++ b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DocumentToDocumentAssociations/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentToDocumentAssociationCollection + { + $response = $this->client->get("DocumentToDocumentAssociations/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentToDocumentAssociationCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentToDocumentAssociationPaginator + { + $response = $this->client->get("DocumentToDocumentAssociations/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentToDocumentAssociationPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DocumentToDocumentAssociations/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationService.php b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationService.php new file mode 100644 index 00000000..0d50cad3 --- /dev/null +++ b/src/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new documenttodocumentassociation. + * + * @param DocumentToDocumentAssociationEntity $resource The documenttodocumentassociation entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentToDocumentAssociationEntity $resource): Response + { + return $this->client->post("DocumentToDocumentAssociations", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the DocumentToDocumentAssociation to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("DocumentToDocumentAssociations/$id"); + } + + /** + * Finds the DocumentToDocumentAssociation based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentToDocumentAssociationEntity + { + return DocumentToDocumentAssociationEntity::fromResponse( + $this->client->get("DocumentToDocumentAssociations/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DocumentToDocumentAssociations/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DocumentToDocumentAssociations/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentToDocumentAssociationQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentToDocumentAssociationQueryBuilder + { + return new DocumentToDocumentAssociationQueryBuilder($this->client); + } +} diff --git a/src/API/Documents/DocumentCollection.php b/src/API/Documents/DocumentCollection.php new file mode 100644 index 00000000..c961d9cd --- /dev/null +++ b/src/API/Documents/DocumentCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DocumentCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DocumentEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/Documents/DocumentEntity.php b/src/API/Documents/DocumentEntity.php new file mode 100644 index 00000000..ce924371 --- /dev/null +++ b/src/API/Documents/DocumentEntity.php @@ -0,0 +1,66 @@ + + */ + public function __construct(array $array) + { + if (isset($array['createdDateTime'])) { + $array['createdDateTime'] = new Carbon($array['createdDateTime']); + } + + if (isset($array['lastModifiedDateTime'])) { + $array['lastModifiedDateTime'] = new Carbon($array['lastModifiedDateTime']); + } + + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/Documents/DocumentPaginator.php b/src/API/Documents/DocumentPaginator.php new file mode 100644 index 00000000..e5a04325 --- /dev/null +++ b/src/API/Documents/DocumentPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DocumentCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DocumentPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DocumentPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/Documents/DocumentQueryBuilder.php b/src/API/Documents/DocumentQueryBuilder.php new file mode 100644 index 00000000..46530983 --- /dev/null +++ b/src/API/Documents/DocumentQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("Documents/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DocumentCollection + { + $response = $this->client->get("Documents/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DocumentCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DocumentPaginator + { + $response = $this->client->get("Documents/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DocumentPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('Documents/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/Documents/DocumentService.php b/src/API/Documents/DocumentService.php new file mode 100644 index 00000000..b2247a0f --- /dev/null +++ b/src/API/Documents/DocumentService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new document. + * + * @param DocumentEntity $resource The document entity to be written. + * + * @author Aidan Casey + */ + public function create(DocumentEntity $resource): Response + { + return $this->client->post("Documents", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the Document to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("Documents/$id"); + } + + /** + * Finds the Document based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DocumentEntity + { + return DocumentEntity::fromResponse( + $this->client->get("Documents/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("Documents/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("Documents/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DocumentQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DocumentQueryBuilder + { + return new DocumentQueryBuilder($this->client); + } + + /** + * Updates the document. + * + * @param DocumentEntity $resource The document entity to be updated. + * + * @author Aidan Casey + */ + public function update(DocumentEntity $resource): Response + { + return $this->client->put("Documents", $resource->toArray()); + } +} diff --git a/src/API/DomainRegistrars/DomainRegistrarCollection.php b/src/API/DomainRegistrars/DomainRegistrarCollection.php new file mode 100644 index 00000000..92c6a168 --- /dev/null +++ b/src/API/DomainRegistrars/DomainRegistrarCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): DomainRegistrarCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + DomainRegistrarEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/DomainRegistrars/DomainRegistrarEntity.php b/src/API/DomainRegistrars/DomainRegistrarEntity.php new file mode 100644 index 00000000..d2996e35 --- /dev/null +++ b/src/API/DomainRegistrars/DomainRegistrarEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/DomainRegistrars/DomainRegistrarPaginator.php b/src/API/DomainRegistrars/DomainRegistrarPaginator.php new file mode 100644 index 00000000..7783eb83 --- /dev/null +++ b/src/API/DomainRegistrars/DomainRegistrarPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = DomainRegistrarCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): DomainRegistrarPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): DomainRegistrarPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/DomainRegistrars/DomainRegistrarQueryBuilder.php b/src/API/DomainRegistrars/DomainRegistrarQueryBuilder.php new file mode 100644 index 00000000..26ae7b0b --- /dev/null +++ b/src/API/DomainRegistrars/DomainRegistrarQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("DomainRegistrars/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): DomainRegistrarCollection + { + $response = $this->client->get("DomainRegistrars/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return DomainRegistrarCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): DomainRegistrarPaginator + { + $response = $this->client->get("DomainRegistrars/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new DomainRegistrarPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('DomainRegistrars/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/DomainRegistrars/DomainRegistrarService.php b/src/API/DomainRegistrars/DomainRegistrarService.php new file mode 100644 index 00000000..a9fafa62 --- /dev/null +++ b/src/API/DomainRegistrars/DomainRegistrarService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new domainregistrar. + * + * @param DomainRegistrarEntity $resource The domainregistrar entity to be written. + * + * @author Aidan Casey + */ + public function create(DomainRegistrarEntity $resource): Response + { + return $this->client->post("DomainRegistrars", $resource->toArray()); + } + + /** + * Finds the DomainRegistrar based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): DomainRegistrarEntity + { + return DomainRegistrarEntity::fromResponse( + $this->client->get("DomainRegistrars/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("DomainRegistrars/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("DomainRegistrars/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see DomainRegistrarQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): DomainRegistrarQueryBuilder + { + return new DomainRegistrarQueryBuilder($this->client); + } + + /** + * Updates the domainregistrar. + * + * @param DomainRegistrarEntity $resource The domainregistrar entity to be updated. + * + * @author Aidan Casey + */ + public function update(DomainRegistrarEntity $resource): Response + { + return $this->client->put("DomainRegistrars", $resource->toArray()); + } +} diff --git a/src/API/ExpenseItems/ExpenseItemEntity.php b/src/API/ExpenseItems/ExpenseItemEntity.php index afb70e5f..d40d06c5 100644 --- a/src/API/ExpenseItems/ExpenseItemEntity.php +++ b/src/API/ExpenseItems/ExpenseItemEntity.php @@ -20,7 +20,7 @@ class ExpenseItemEntity extends DataTransferObject public ?int $expenseCurrencyID; public Carbon $expenseDate; public int $expenseReportID; - public ?string $glCode; + public ?string $gLCode; public bool $haveReceipt; public $id; public ?float $internalCurrencyExpenseAmount; diff --git a/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetCollection.php b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetCollection.php new file mode 100644 index 00000000..0da0b15f --- /dev/null +++ b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): IntegrationVendorWidgetCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + IntegrationVendorWidgetEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetEntity.php b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetEntity.php new file mode 100644 index 00000000..3a9c9eb7 --- /dev/null +++ b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetEntity.php @@ -0,0 +1,64 @@ + + */ + public function __construct(array $array) + { + if (isset($array['createDateTime'])) { + $array['createDateTime'] = new Carbon($array['createDateTime']); + } + + if (isset($array['lastModifiedDateTime'])) { + $array['lastModifiedDateTime'] = new Carbon($array['lastModifiedDateTime']); + } + + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetPaginator.php b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetPaginator.php new file mode 100644 index 00000000..5ae4327a --- /dev/null +++ b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = IntegrationVendorWidgetCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): IntegrationVendorWidgetPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): IntegrationVendorWidgetPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetQueryBuilder.php b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetQueryBuilder.php new file mode 100644 index 00000000..b8d8bb83 --- /dev/null +++ b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("IntegrationVendorWidgets/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): IntegrationVendorWidgetCollection + { + $response = $this->client->get("IntegrationVendorWidgets/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return IntegrationVendorWidgetCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): IntegrationVendorWidgetPaginator + { + $response = $this->client->get("IntegrationVendorWidgets/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new IntegrationVendorWidgetPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('IntegrationVendorWidgets/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetService.php b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetService.php new file mode 100644 index 00000000..c12baa2e --- /dev/null +++ b/src/API/IntegrationVendorWidgets/IntegrationVendorWidgetService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new integrationvendorwidget. + * + * @param IntegrationVendorWidgetEntity $resource The integrationvendorwidget entity to be written. + * + * @author Aidan Casey + */ + public function create(IntegrationVendorWidgetEntity $resource): Response + { + return $this->client->post("IntegrationVendorWidgets", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the IntegrationVendorWidget to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("IntegrationVendorWidgets/$id"); + } + + /** + * Finds the IntegrationVendorWidget based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): IntegrationVendorWidgetEntity + { + return IntegrationVendorWidgetEntity::fromResponse( + $this->client->get("IntegrationVendorWidgets/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("IntegrationVendorWidgets/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("IntegrationVendorWidgets/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see IntegrationVendorWidgetQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): IntegrationVendorWidgetQueryBuilder + { + return new IntegrationVendorWidgetQueryBuilder($this->client); + } + + /** + * Updates the integrationvendorwidget. + * + * @param IntegrationVendorWidgetEntity $resource The integrationvendorwidget entity to be updated. + * + * @author Aidan Casey + */ + public function update(IntegrationVendorWidgetEntity $resource): Response + { + return $this->client->put("IntegrationVendorWidgets", $resource->toArray()); + } +} diff --git a/src/API/Opportunities/OpportunityEntity.php b/src/API/Opportunities/OpportunityEntity.php index 32ce34e3..5543c1e3 100644 --- a/src/API/Opportunities/OpportunityEntity.php +++ b/src/API/Opportunities/OpportunityEntity.php @@ -56,7 +56,7 @@ class OpportunityEntity extends DataTransferObject public ?int $revenueSpread; public ?string $revenueSpreadUnit; public ?int $salesOrderID; - public ?int $salesProcessPercentComplete; + public ?float $salesProcessPercentComplete; public ?float $semiannualCost; public ?float $semiannualRevenue; public int $stage; diff --git a/src/API/PurchaseOrders/PurchaseOrderEntity.php b/src/API/PurchaseOrders/PurchaseOrderEntity.php index 564d2291..966cc1c9 100644 --- a/src/API/PurchaseOrders/PurchaseOrderEntity.php +++ b/src/API/PurchaseOrders/PurchaseOrderEntity.php @@ -25,6 +25,8 @@ class PurchaseOrderEntity extends DataTransferObject public ?int $paymentTerm; public ?string $phone; public ?int $purchaseForCompanyID; + public ?string $purchaseOrderNumber; + public ?int $purchaseOrderTemplateID; public ?Carbon $shippingDate; public ?int $shippingType; public string $shipToAddress1; diff --git a/src/API/TagAliases/TagAliasCollection.php b/src/API/TagAliases/TagAliasCollection.php new file mode 100644 index 00000000..fb62451f --- /dev/null +++ b/src/API/TagAliases/TagAliasCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): TagAliasCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + TagAliasEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/TagAliases/TagAliasEntity.php b/src/API/TagAliases/TagAliasEntity.php new file mode 100644 index 00000000..d162c2c6 --- /dev/null +++ b/src/API/TagAliases/TagAliasEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/TagAliases/TagAliasPaginator.php b/src/API/TagAliases/TagAliasPaginator.php new file mode 100644 index 00000000..de1bef93 --- /dev/null +++ b/src/API/TagAliases/TagAliasPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = TagAliasCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): TagAliasPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): TagAliasPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/TagAliases/TagAliasQueryBuilder.php b/src/API/TagAliases/TagAliasQueryBuilder.php new file mode 100644 index 00000000..a6012dda --- /dev/null +++ b/src/API/TagAliases/TagAliasQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("TagAliases/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): TagAliasCollection + { + $response = $this->client->get("TagAliases/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return TagAliasCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): TagAliasPaginator + { + $response = $this->client->get("TagAliases/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new TagAliasPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('TagAliases/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/TagAliases/TagAliasService.php b/src/API/TagAliases/TagAliasService.php new file mode 100644 index 00000000..fa8c1e68 --- /dev/null +++ b/src/API/TagAliases/TagAliasService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new tagalias. + * + * @param TagAliasEntity $resource The tagalias entity to be written. + * + * @author Aidan Casey + */ + public function create(TagAliasEntity $resource): Response + { + return $this->client->post("TagAliases", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the TagAlias to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("TagAliases/$id"); + } + + /** + * Finds the TagAlias based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): TagAliasEntity + { + return TagAliasEntity::fromResponse( + $this->client->get("TagAliases/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("TagAliases/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("TagAliases/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see TagAliasQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): TagAliasQueryBuilder + { + return new TagAliasQueryBuilder($this->client); + } +} diff --git a/src/API/TagGroups/TagGroupCollection.php b/src/API/TagGroups/TagGroupCollection.php new file mode 100644 index 00000000..44846ba1 --- /dev/null +++ b/src/API/TagGroups/TagGroupCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): TagGroupCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + TagGroupEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/TagGroups/TagGroupEntity.php b/src/API/TagGroups/TagGroupEntity.php new file mode 100644 index 00000000..24c137a5 --- /dev/null +++ b/src/API/TagGroups/TagGroupEntity.php @@ -0,0 +1,49 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/TagGroups/TagGroupPaginator.php b/src/API/TagGroups/TagGroupPaginator.php new file mode 100644 index 00000000..225a23b1 --- /dev/null +++ b/src/API/TagGroups/TagGroupPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = TagGroupCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): TagGroupPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): TagGroupPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/TagGroups/TagGroupQueryBuilder.php b/src/API/TagGroups/TagGroupQueryBuilder.php new file mode 100644 index 00000000..69427a8e --- /dev/null +++ b/src/API/TagGroups/TagGroupQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("TagGroups/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): TagGroupCollection + { + $response = $this->client->get("TagGroups/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return TagGroupCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): TagGroupPaginator + { + $response = $this->client->get("TagGroups/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new TagGroupPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('TagGroups/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/TagGroups/TagGroupService.php b/src/API/TagGroups/TagGroupService.php new file mode 100644 index 00000000..16167caa --- /dev/null +++ b/src/API/TagGroups/TagGroupService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new taggroup. + * + * @param TagGroupEntity $resource The taggroup entity to be written. + * + * @author Aidan Casey + */ + public function create(TagGroupEntity $resource): Response + { + return $this->client->post("TagGroups", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the TagGroup to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("TagGroups/$id"); + } + + /** + * Finds the TagGroup based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): TagGroupEntity + { + return TagGroupEntity::fromResponse( + $this->client->get("TagGroups/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("TagGroups/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("TagGroups/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see TagGroupQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): TagGroupQueryBuilder + { + return new TagGroupQueryBuilder($this->client); + } + + /** + * Updates the taggroup. + * + * @param TagGroupEntity $resource The taggroup entity to be updated. + * + * @author Aidan Casey + */ + public function update(TagGroupEntity $resource): Response + { + return $this->client->put("TagGroups", $resource->toArray()); + } +} diff --git a/src/API/Tags/TagCollection.php b/src/API/Tags/TagCollection.php new file mode 100644 index 00000000..baa8b7a5 --- /dev/null +++ b/src/API/Tags/TagCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): TagCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + TagEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/Tags/TagEntity.php b/src/API/Tags/TagEntity.php new file mode 100644 index 00000000..29fcaa97 --- /dev/null +++ b/src/API/Tags/TagEntity.php @@ -0,0 +1,61 @@ + + */ + public function __construct(array $array) + { + if (isset($array['createDateTime'])) { + $array['createDateTime'] = new Carbon($array['createDateTime']); + } + + if (isset($array['lastModifiedDateTime'])) { + $array['lastModifiedDateTime'] = new Carbon($array['lastModifiedDateTime']); + } + + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/Tags/TagPaginator.php b/src/API/Tags/TagPaginator.php new file mode 100644 index 00000000..5de230f6 --- /dev/null +++ b/src/API/Tags/TagPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = TagCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): TagPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): TagPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/Tags/TagQueryBuilder.php b/src/API/Tags/TagQueryBuilder.php new file mode 100644 index 00000000..dff478ab --- /dev/null +++ b/src/API/Tags/TagQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("Tags/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): TagCollection + { + $response = $this->client->get("Tags/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return TagCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): TagPaginator + { + $response = $this->client->get("Tags/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new TagPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('Tags/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/Tags/TagService.php b/src/API/Tags/TagService.php new file mode 100644 index 00000000..7a68dd2d --- /dev/null +++ b/src/API/Tags/TagService.php @@ -0,0 +1,120 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new tag. + * + * @param TagEntity $resource The tag entity to be written. + * + * @author Aidan Casey + */ + public function create(TagEntity $resource): Response + { + return $this->client->post("Tags", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the Tag to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("Tags/$id"); + } + + /** + * Finds the Tag based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): TagEntity + { + return TagEntity::fromResponse( + $this->client->get("Tags/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("Tags/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("Tags/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see TagQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): TagQueryBuilder + { + return new TagQueryBuilder($this->client); + } + + /** + * Updates the tag. + * + * @param TagEntity $resource The tag entity to be updated. + * + * @author Aidan Casey + */ + public function update(TagEntity $resource): Response + { + return $this->client->put("Tags", $resource->toArray()); + } +} diff --git a/src/API/TaskNotes/TaskNoteEntity.php b/src/API/TaskNotes/TaskNoteEntity.php index 8026524c..6fd032ad 100644 --- a/src/API/TaskNotes/TaskNoteEntity.php +++ b/src/API/TaskNotes/TaskNoteEntity.php @@ -22,7 +22,7 @@ class TaskNoteEntity extends DataTransferObject public int $noteType; public int $publish; public int $taskID; - public string $title; + public ?string $title; /** @var \Anteris\Autotask\Support\UserDefinedFields\UserDefinedFieldEntity[]|null */ public ?array $userDefinedFields; diff --git a/src/API/TicketNoteAttachments/TicketNoteAttachmentService.php b/src/API/TicketNoteAttachments/TicketNoteAttachmentService.php index 9697d742..9ac115e3 100644 --- a/src/API/TicketNoteAttachments/TicketNoteAttachmentService.php +++ b/src/API/TicketNoteAttachments/TicketNoteAttachmentService.php @@ -37,19 +37,21 @@ public function __construct(HttpClient $client) */ public function create(TicketNoteAttachmentEntity $resource): Response { - return $this->client->post("TicketNoteAttachments", $resource->toArray()); + $parentID = $resource->parentID; + return $this->client->post("TicketNotes/$parentID/Attachments", $resource->toArray()); } /** * Deletes an entity by its ID. * + * @param int $parentID ID of the TicketNoteAttachment parent resource. * @param int $id ID of the TicketNoteAttachment to be deleted. * * @author Aidan Casey */ - public function deleteById(int $id): void + public function deleteById(int $parentID,int $id): void { - $this->client->delete("TicketNoteAttachments/$id"); + $this->client->delete("TicketNotes/$parentID/Attachments/$id"); } /** diff --git a/src/API/TicketNotes/TicketNoteEntity.php b/src/API/TicketNotes/TicketNoteEntity.php index ea4a5c4a..59dca340 100644 --- a/src/API/TicketNotes/TicketNoteEntity.php +++ b/src/API/TicketNotes/TicketNoteEntity.php @@ -22,7 +22,7 @@ class TicketNoteEntity extends DataTransferObject public int $noteType; public int $publish; public int $ticketID; - public string $title; + public ?string $title; /** @var \Anteris\Autotask\Support\UserDefinedFields\UserDefinedFieldEntity[]|null */ public ?array $userDefinedFields; diff --git a/src/API/TicketTagAssociations/TicketTagAssociationCollection.php b/src/API/TicketTagAssociations/TicketTagAssociationCollection.php new file mode 100644 index 00000000..b936370e --- /dev/null +++ b/src/API/TicketTagAssociations/TicketTagAssociationCollection.php @@ -0,0 +1,49 @@ + + */ + public static function fromResponse(Response $response): TicketTagAssociationCollection + { + $array = json_decode($response->getBody(), true); + + if (isset($array['items']) === false) { + throw new \Exception('Missing items key in response.'); + } + + return new static( + TicketTagAssociationEntity::arrayOf($array['items']) + ); + } +} diff --git a/src/API/TicketTagAssociations/TicketTagAssociationEntity.php b/src/API/TicketTagAssociations/TicketTagAssociationEntity.php new file mode 100644 index 00000000..5c735689 --- /dev/null +++ b/src/API/TicketTagAssociations/TicketTagAssociationEntity.php @@ -0,0 +1,47 @@ + + */ + public function __construct(array $array) + { + parent::__construct($array); + } + + /** + * Creates an instance of this class from an Http response. + * + * @param Response $response Http response. + * + * @author Aidan Casey + */ + public static function fromResponse(Response $response) + { + $responseArray = json_decode($response->getBody(), true); + + if (isset($responseArray['item']) === false) { + throw new \Exception('Missing item key in response.'); + } + + return new self($responseArray['item']); + } +} diff --git a/src/API/TicketTagAssociations/TicketTagAssociationPaginator.php b/src/API/TicketTagAssociations/TicketTagAssociationPaginator.php new file mode 100644 index 00000000..3f67c93a --- /dev/null +++ b/src/API/TicketTagAssociations/TicketTagAssociationPaginator.php @@ -0,0 +1,87 @@ + + */ + public function __construct(HttpClient $client, $response) + { + $this->client = $client; + $this->collection = TicketTagAssociationCollection::fromResponse($response); + $this->page = PageEntity::fromResponse($response); + } + + /** + * If a next page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasNextPage(): bool + { + if(! $this->page->nextPageUrl) { + return false; + } + + return true; + } + + /** + * If a previous page exists, returns true. Otherwise returns false. + * + * @author Aidan Casey + */ + public function hasPrevPage(): bool + { + if (!$this->page->prevPageUrl) { + return false; + } + + return true; + } + + /** + * Retrieves and returns the next page. + * + * @author Aidan Casey + */ + public function nextPage(): TicketTagAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->nextPageUrl); + return new static($this->client, $response); + } + + /** + * Retrieves and returns the previous page. + * + * @author Aidan Casey + */ + public function prevPage (): TicketTagAssociationPaginator + { + $response = $this->client->getClient()->get($this->page->prevPageUrl); + return new static($this->client, $response); + } +} diff --git a/src/API/TicketTagAssociations/TicketTagAssociationQueryBuilder.php b/src/API/TicketTagAssociations/TicketTagAssociationQueryBuilder.php new file mode 100644 index 00000000..df12d496 --- /dev/null +++ b/src/API/TicketTagAssociations/TicketTagAssociationQueryBuilder.php @@ -0,0 +1,304 @@ + + */ + public function __construct( + HttpClient $client + ) + { + $this->client = $client; + } + + /** + * Runs the query but returns an integer specifying the number of records + * that would be returned if executed. + */ + public function count(): int + { + $response = $this->client->get("TicketTagAssociations/query/count", [ + 'search' => json_encode( $this->toArray() ) + ]); + + $responseArray = json_decode($response->getBody(), true); + + if (! isset($responseArray['queryCount'])) { + throw new Exception('Missing queryCount key in response!'); + } + + return $responseArray['queryCount']; + } + + /** + * Pages through all the records, executing the callback for each record. + * + * @param callable $callback The callback to be executed for each record. + * + * @author Aidan Casey + */ + public function loop(callable $callback) + { + $currentPage = $this->paginate(); + + while(True) { + foreach ($currentPage->collection as $collectionItem) { + $callback($collectionItem); + } + + if (! $currentPage->hasNextPage()) { + break; + } + + $currentPage = $currentPage->nextPage(); + } + } + + /** + * Runs the query. + */ + public function get(): TicketTagAssociationCollection + { + $response = $this->client->get("TicketTagAssociations/query", [ + 'search' => json_encode( $this->toArray() ) + ]); + + return TicketTagAssociationCollection::fromResponse($response); + } + + /** + * Runs the query and returns a paginator object. + */ + public function paginate(): TicketTagAssociationPaginator + { + $response = $this->client->get("TicketTagAssociations/query", [ + 'search' => json_encode($this->toArray()) + ]); + + return new TicketTagAssociationPaginator($this->client, $response); + } + + /** + * Returns the filters in this class. + */ + public function getFilters(): array + { + return $this->filter; + } + + /** + * Sets the max number of records to be returned. + */ + public function records(int $records) + { + if ($records < 1 || $records > 500) { + throw new Exception("Cannot set records to $records, must be between 1 and 500!"); + } + + $this->records = $records; + return $this; + } + + /** + * Adds a where statement to the query. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * @param string $conjunction The conjunction to filter with ('AND' or 'OR'). + * + * @author Aidan Casey + */ + public function where( + $field, + $operator = null, + $value = null, + $udf = false, + $conjuction = 'AND' + ) + { + // First scenario, field and non-value operator are set. + if ( + isset($field) && + in_array(strtolower($operator), ['exist', 'notexist']) + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Second scenario, everything is set and legit. + if ( + isset($field) && + $operator !== null && + $value !== null + ) { + $this->validateOperator($operator); + + $query = [ + 'field' => $field, + 'op' => $operator, + 'value' => $value, + ]; + + if ($udf) { + $query['udf'] = true; + } + + $this->filter[] = $query; + return $this; + } + + // Third scenario, "$field" is a callback + if (is_callable($field)) { + $this->validateConjunction($conjuction); + + $this->filter[] = $this->nestedWhere($conjuction, $field); + return $this; + } + } + + /** + * Adds a where statement with an 'OR' conjunction. + * + * @param string|callable $field A field name or callback query function. + * @param string $operator The operator to filter with. + * @param string $value The value the field should be compared to. + * @param bool $udf Specifies whether or not the field being queried is a UDF. + * + * @author Aidan Casey + */ + public function orWhere($field, $operator = null, $value = null, $udf = false) + { + return $this->where($field, $operator, $value, $udf, 'OR'); + } + + /** + * Returns the query as an array. + */ + public function toArray(): array + { + $array = [ + 'filter' => $this->filter, + ]; + + if (isset($this->records)) { + $array['MaxRecords'] = $this->records; + } + + return $array; + } + + /** + * Converts a callback where statement into a nested query. + * + * @param string $conjuction The conjunction to join these items with (AND or OR). + * @param callable $callback The callback query to be executed. + * + * @author Aidan Casey + */ + protected function nestedWhere(string $conjunction, callable $callback) + { + return [ + 'op' => $conjunction, + 'items' => $callback( new static($this->client) )->getFilters() + ]; + } + + /** + * Ensures the conjunction being used is valid. + * + * @param string $conjuction The conjunction to validate. + * + * @author Aidan Casey + */ + protected function validateConjunction(string $conjunction) + { + if (strtoupper($conjunction) != 'AND' && strtoupper($conjunction) != 'OR') { + throw new Exception("Invalid query conjunction: $conjunction"); + } + } + + /** + * Ensures the operator being used is valid. + * + * @param string $operator The operator to validate. + * + * @author Aidan Casey + */ + protected function validateOperator(string $operator) + { + if ( + !in_array($operator, [ + 'eq', + 'noteq', + 'gt', + 'gte', + 'lt', + 'lte', + 'in', + 'notIn', + 'exist', + 'notExist', + 'beginsWith', + 'endsWith', + 'contains', + ]) + ) { + throw new Exception("Invalid query operator: $operator"); + } + } + + /** + * Converts the built query into a string and returns. + * + * @author Aidan Casey + */ + public function __toString() + { + $uri = UriResolver::resolve( + $this->client->getClient()->getConfig()['base_uri'], + new Uri('TicketTagAssociations/query') + ); + + return (string) Uri::withQueryValues($uri, [ + 'search' => json_encode($this->toArray()) + ]); + } +} diff --git a/src/API/TicketTagAssociations/TicketTagAssociationService.php b/src/API/TicketTagAssociations/TicketTagAssociationService.php new file mode 100644 index 00000000..eca04442 --- /dev/null +++ b/src/API/TicketTagAssociations/TicketTagAssociationService.php @@ -0,0 +1,108 @@ + + */ + public function __construct(HttpClient $client) + { + $this->client = $client; + } + + /** + * Creates a new tickettagassociation. + * + * @param TicketTagAssociationEntity $resource The tickettagassociation entity to be written. + * + * @author Aidan Casey + */ + public function create(TicketTagAssociationEntity $resource): Response + { + return $this->client->post("TicketTagAssociations", $resource->toArray()); + } + + /** + * Deletes an entity by its ID. + * + * @param int $id ID of the TicketTagAssociation to be deleted. + * + * @author Aidan Casey + */ + public function deleteById(int $id): void + { + $this->client->delete("TicketTagAssociations/$id"); + } + + /** + * Finds the TicketTagAssociation based on its ID. + * + * @param string $id ID of the entity to be retrieved. + * + * @author Aidan Casey + */ + public function findById(int $id): TicketTagAssociationEntity + { + return TicketTagAssociationEntity::fromResponse( + $this->client->get("TicketTagAssociations/$id") + ); + } + + /** + * Returns information about what fields an entity has. + * + * @see EntityFieldCollection + * + * @author Aidan Casey + */ + public function getEntityFields(): EntityFieldCollection + { + return EntityFieldCollection::fromResponse( + $this->client->get("TicketTagAssociations/entityInformation/fields") + ); + } + + /** + * Returns information about what actions can be made against an entity. + * + * @see EntityInformationEntity + * + * @author Aidan Casey + */ + public function getEntityInformation(): EntityInformationEntity + { + return EntityInformationEntity::fromResponse( + $this->client->get("TicketTagAssociations/entityInformation") + ); + } + + /** + * Returns an instance of the query builder for this entity. + * + * @see TicketTagAssociationQueryBuilder The query builder class. + * + * @author Aidan Casey + */ + public function query(): TicketTagAssociationQueryBuilder + { + return new TicketTagAssociationQueryBuilder($this->client); + } +} diff --git a/src/API/TimeEntries/TimeEntryEntity.php b/src/API/TimeEntries/TimeEntryEntity.php index 287be81b..a85d3219 100644 --- a/src/API/TimeEntries/TimeEntryEntity.php +++ b/src/API/TimeEntries/TimeEntryEntity.php @@ -20,7 +20,7 @@ class TimeEntryEntity extends DataTransferObject public $contractServiceID; public ?Carbon $createDateTime; public ?int $creatorUserID; - public Carbon $dateWorked; + public ?Carbon $dateWorked; public ?Carbon $endDateTime; public ?float $hoursToBill; public ?float $hoursWorked; diff --git a/src/API/UserDefinedFieldListItems/UserDefinedFieldListItemEntity.php b/src/API/UserDefinedFieldListItems/UserDefinedFieldListItemEntity.php index 4af1c323..ee4eb263 100644 --- a/src/API/UserDefinedFieldListItems/UserDefinedFieldListItemEntity.php +++ b/src/API/UserDefinedFieldListItems/UserDefinedFieldListItemEntity.php @@ -13,6 +13,7 @@ class UserDefinedFieldListItemEntity extends DataTransferObject { public ?Carbon $createDate; public $id; + public ?bool $isActive; public $udfFieldId; public string $valueForDisplay; public string $valueForExport; diff --git a/src/Client.php b/src/Client.php index 70cd2e47..70157f93 100644 --- a/src/Client.php +++ b/src/Client.php @@ -34,10 +34,16 @@ use Anteris\Autotask\API\ConfigurationItemBillingProductAssociations\ConfigurationItemBillingProductAssociationService; use Anteris\Autotask\API\ConfigurationItemCategories\ConfigurationItemCategoryService; use Anteris\Autotask\API\ConfigurationItemCategoryUdfAssociations\ConfigurationItemCategoryUdfAssociationService; +use Anteris\Autotask\API\ConfigurationItemDnsRecords\ConfigurationItemDnsRecordService; use Anteris\Autotask\API\ConfigurationItemExts\ConfigurationItemExtService; use Anteris\Autotask\API\ConfigurationItemNoteAttachments\ConfigurationItemNoteAttachmentService; use Anteris\Autotask\API\ConfigurationItemNotes\ConfigurationItemNoteService; +use Anteris\Autotask\API\ConfigurationItemSslSubjectAlternativeNames\ConfigurationItemSslSubjectAlternativeNameService; use Anteris\Autotask\API\ConfigurationItemTypes\ConfigurationItemTypeService; +use Anteris\Autotask\API\ConfigurationItemWebhookExcludedResources\ConfigurationItemWebhookExcludedResourceService; +use Anteris\Autotask\API\ConfigurationItemWebhookFields\ConfigurationItemWebhookFieldService; +use Anteris\Autotask\API\ConfigurationItemWebhookUdfFields\ConfigurationItemWebhookUdfFieldService; +use Anteris\Autotask\API\ConfigurationItemWebhooks\ConfigurationItemWebhookService; use Anteris\Autotask\API\ConfigurationItems\ConfigurationItemService; use Anteris\Autotask\API\ContactBillingProductAssociations\ContactBillingProductAssociationService; use Anteris\Autotask\API\ContactGroupContacts\ContactGroupContactService; @@ -76,11 +82,25 @@ use Anteris\Autotask\API\DeletedTicketActivityLogs\DeletedTicketActivityLogService; use Anteris\Autotask\API\DeletedTicketLogs\DeletedTicketLogService; use Anteris\Autotask\API\Departments\DepartmentService; +use Anteris\Autotask\API\DocumentAttachments\DocumentAttachmentService; +use Anteris\Autotask\API\DocumentCategories\DocumentCategoryService; +use Anteris\Autotask\API\DocumentChecklistItems\DocumentChecklistItemService; +use Anteris\Autotask\API\DocumentChecklistLibraries\DocumentChecklistLibraryService; +use Anteris\Autotask\API\DocumentConfigurationItemAssociations\DocumentConfigurationItemAssociationService; +use Anteris\Autotask\API\DocumentConfigurationItemCategoryAssociations\DocumentConfigurationItemCategoryAssociationService; +use Anteris\Autotask\API\DocumentNotes\DocumentNoteService; +use Anteris\Autotask\API\DocumentPlainTextContent\DocumentPlainTextContentService; +use Anteris\Autotask\API\DocumentTagAssociations\DocumentTagAssociationService; +use Anteris\Autotask\API\DocumentTicketAssociations\DocumentTicketAssociationService; +use Anteris\Autotask\API\DocumentToDocumentAssociations\DocumentToDocumentAssociationService; +use Anteris\Autotask\API\Documents\DocumentService; +use Anteris\Autotask\API\DomainRegistrars\DomainRegistrarService; use Anteris\Autotask\API\ExpenseItems\ExpenseItemService; use Anteris\Autotask\API\ExpenseReportAttachments\ExpenseReportAttachmentService; use Anteris\Autotask\API\ExpenseReports\ExpenseReportService; use Anteris\Autotask\API\HolidaySets\HolidaySetService; use Anteris\Autotask\API\Holidays\HolidayService; +use Anteris\Autotask\API\IntegrationVendorWidgets\IntegrationVendorWidgetService; use Anteris\Autotask\API\InternalLocationWithBusinessHours\InternalLocationWithBusinessHourService; use Anteris\Autotask\API\InternalLocations\InternalLocationService; use Anteris\Autotask\API\InventoryItemSerialNumbers\InventoryItemSerialNumberService; @@ -147,6 +167,9 @@ use Anteris\Autotask\API\Subscriptions\SubscriptionService; use Anteris\Autotask\API\SurveyResults\SurveyResultService; use Anteris\Autotask\API\Surveys\SurveyService; +use Anteris\Autotask\API\TagAliases\TagAliasService; +use Anteris\Autotask\API\TagGroups\TagGroupService; +use Anteris\Autotask\API\Tags\TagService; use Anteris\Autotask\API\TaskAttachments\TaskAttachmentService; use Anteris\Autotask\API\TaskNoteAttachments\TaskNoteAttachmentService; use Anteris\Autotask\API\TaskNotes\TaskNoteService; @@ -170,6 +193,7 @@ use Anteris\Autotask\API\TicketNotes\TicketNoteService; use Anteris\Autotask\API\TicketRmaCredits\TicketRmaCreditService; use Anteris\Autotask\API\TicketSecondaryResources\TicketSecondaryResourceService; +use Anteris\Autotask\API\TicketTagAssociations\TicketTagAssociationService; use Anteris\Autotask\API\Tickets\TicketService; use Anteris\Autotask\API\TimeEntries\TimeEntryService; use Anteris\Autotask\API\TimeEntryAttachments\TimeEntryAttachmentService; @@ -588,6 +612,18 @@ public function configurationItemCategoryUdfAssociations(): ConfigurationItemCat return $this->classCache['ConfigurationItemCategoryUdfAssociations']; } + /** + * Handles any interaction with the ConfigurationItemDnsRecords endpoint. + */ + public function configurationItemDnsRecords(): ConfigurationItemDnsRecordService + { + if (! isset($this->classCache['ConfigurationItemDnsRecords'])) { + $this->classCache['ConfigurationItemDnsRecords'] = new ConfigurationItemDnsRecordService($this->client); + } + + return $this->classCache['ConfigurationItemDnsRecords']; + } + /** * Handles any interaction with the ConfigurationItemExts endpoint. */ @@ -624,6 +660,18 @@ public function configurationItemNotes(): ConfigurationItemNoteService return $this->classCache['ConfigurationItemNotes']; } + /** + * Handles any interaction with the ConfigurationItemSslSubjectAlternativeNames endpoint. + */ + public function configurationItemSslSubjectAlternativeNames(): ConfigurationItemSslSubjectAlternativeNameService + { + if (! isset($this->classCache['ConfigurationItemSslSubjectAlternativeNames'])) { + $this->classCache['ConfigurationItemSslSubjectAlternativeNames'] = new ConfigurationItemSslSubjectAlternativeNameService($this->client); + } + + return $this->classCache['ConfigurationItemSslSubjectAlternativeNames']; + } + /** * Handles any interaction with the ConfigurationItemTypes endpoint. */ @@ -636,6 +684,54 @@ public function configurationItemTypes(): ConfigurationItemTypeService return $this->classCache['ConfigurationItemTypes']; } + /** + * Handles any interaction with the ConfigurationItemWebhookExcludedResources endpoint. + */ + public function configurationItemWebhookExcludedResources(): ConfigurationItemWebhookExcludedResourceService + { + if (! isset($this->classCache['ConfigurationItemWebhookExcludedResources'])) { + $this->classCache['ConfigurationItemWebhookExcludedResources'] = new ConfigurationItemWebhookExcludedResourceService($this->client); + } + + return $this->classCache['ConfigurationItemWebhookExcludedResources']; + } + + /** + * Handles any interaction with the ConfigurationItemWebhookFields endpoint. + */ + public function configurationItemWebhookFields(): ConfigurationItemWebhookFieldService + { + if (! isset($this->classCache['ConfigurationItemWebhookFields'])) { + $this->classCache['ConfigurationItemWebhookFields'] = new ConfigurationItemWebhookFieldService($this->client); + } + + return $this->classCache['ConfigurationItemWebhookFields']; + } + + /** + * Handles any interaction with the ConfigurationItemWebhookUdfFields endpoint. + */ + public function configurationItemWebhookUdfFields(): ConfigurationItemWebhookUdfFieldService + { + if (! isset($this->classCache['ConfigurationItemWebhookUdfFields'])) { + $this->classCache['ConfigurationItemWebhookUdfFields'] = new ConfigurationItemWebhookUdfFieldService($this->client); + } + + return $this->classCache['ConfigurationItemWebhookUdfFields']; + } + + /** + * Handles any interaction with the ConfigurationItemWebhooks endpoint. + */ + public function configurationItemWebhooks(): ConfigurationItemWebhookService + { + if (! isset($this->classCache['ConfigurationItemWebhooks'])) { + $this->classCache['ConfigurationItemWebhooks'] = new ConfigurationItemWebhookService($this->client); + } + + return $this->classCache['ConfigurationItemWebhooks']; + } + /** * Handles any interaction with the ConfigurationItems endpoint. */ @@ -1092,6 +1188,162 @@ public function departments(): DepartmentService return $this->classCache['Departments']; } + /** + * Handles any interaction with the DocumentAttachments endpoint. + */ + public function documentAttachments(): DocumentAttachmentService + { + if (! isset($this->classCache['DocumentAttachments'])) { + $this->classCache['DocumentAttachments'] = new DocumentAttachmentService($this->client); + } + + return $this->classCache['DocumentAttachments']; + } + + /** + * Handles any interaction with the DocumentCategories endpoint. + */ + public function documentCategories(): DocumentCategoryService + { + if (! isset($this->classCache['DocumentCategories'])) { + $this->classCache['DocumentCategories'] = new DocumentCategoryService($this->client); + } + + return $this->classCache['DocumentCategories']; + } + + /** + * Handles any interaction with the DocumentChecklistItems endpoint. + */ + public function documentChecklistItems(): DocumentChecklistItemService + { + if (! isset($this->classCache['DocumentChecklistItems'])) { + $this->classCache['DocumentChecklistItems'] = new DocumentChecklistItemService($this->client); + } + + return $this->classCache['DocumentChecklistItems']; + } + + /** + * Handles any interaction with the DocumentChecklistLibraries endpoint. + */ + public function documentChecklistLibraries(): DocumentChecklistLibraryService + { + if (! isset($this->classCache['DocumentChecklistLibraries'])) { + $this->classCache['DocumentChecklistLibraries'] = new DocumentChecklistLibraryService($this->client); + } + + return $this->classCache['DocumentChecklistLibraries']; + } + + /** + * Handles any interaction with the DocumentConfigurationItemAssociations endpoint. + */ + public function documentConfigurationItemAssociations(): DocumentConfigurationItemAssociationService + { + if (! isset($this->classCache['DocumentConfigurationItemAssociations'])) { + $this->classCache['DocumentConfigurationItemAssociations'] = new DocumentConfigurationItemAssociationService($this->client); + } + + return $this->classCache['DocumentConfigurationItemAssociations']; + } + + /** + * Handles any interaction with the DocumentConfigurationItemCategoryAssociations endpoint. + */ + public function documentConfigurationItemCategoryAssociations(): DocumentConfigurationItemCategoryAssociationService + { + if (! isset($this->classCache['DocumentConfigurationItemCategoryAssociations'])) { + $this->classCache['DocumentConfigurationItemCategoryAssociations'] = new DocumentConfigurationItemCategoryAssociationService($this->client); + } + + return $this->classCache['DocumentConfigurationItemCategoryAssociations']; + } + + /** + * Handles any interaction with the DocumentNotes endpoint. + */ + public function documentNotes(): DocumentNoteService + { + if (! isset($this->classCache['DocumentNotes'])) { + $this->classCache['DocumentNotes'] = new DocumentNoteService($this->client); + } + + return $this->classCache['DocumentNotes']; + } + + /** + * Handles any interaction with the DocumentPlainTextContent endpoint. + */ + public function documentPlainTextContent(): DocumentPlainTextContentService + { + if (! isset($this->classCache['DocumentPlainTextContent'])) { + $this->classCache['DocumentPlainTextContent'] = new DocumentPlainTextContentService($this->client); + } + + return $this->classCache['DocumentPlainTextContent']; + } + + /** + * Handles any interaction with the DocumentTagAssociations endpoint. + */ + public function documentTagAssociations(): DocumentTagAssociationService + { + if (! isset($this->classCache['DocumentTagAssociations'])) { + $this->classCache['DocumentTagAssociations'] = new DocumentTagAssociationService($this->client); + } + + return $this->classCache['DocumentTagAssociations']; + } + + /** + * Handles any interaction with the DocumentTicketAssociations endpoint. + */ + public function documentTicketAssociations(): DocumentTicketAssociationService + { + if (! isset($this->classCache['DocumentTicketAssociations'])) { + $this->classCache['DocumentTicketAssociations'] = new DocumentTicketAssociationService($this->client); + } + + return $this->classCache['DocumentTicketAssociations']; + } + + /** + * Handles any interaction with the DocumentToDocumentAssociations endpoint. + */ + public function documentToDocumentAssociations(): DocumentToDocumentAssociationService + { + if (! isset($this->classCache['DocumentToDocumentAssociations'])) { + $this->classCache['DocumentToDocumentAssociations'] = new DocumentToDocumentAssociationService($this->client); + } + + return $this->classCache['DocumentToDocumentAssociations']; + } + + /** + * Handles any interaction with the Documents endpoint. + */ + public function documents(): DocumentService + { + if (! isset($this->classCache['Documents'])) { + $this->classCache['Documents'] = new DocumentService($this->client); + } + + return $this->classCache['Documents']; + } + + /** + * Handles any interaction with the DomainRegistrars endpoint. + */ + public function domainRegistrars(): DomainRegistrarService + { + if (! isset($this->classCache['DomainRegistrars'])) { + $this->classCache['DomainRegistrars'] = new DomainRegistrarService($this->client); + } + + return $this->classCache['DomainRegistrars']; + } + /** * Handles any interaction with the ExpenseItems endpoint. */ @@ -1152,6 +1404,18 @@ public function holidays(): HolidayService return $this->classCache['Holidays']; } + /** + * Handles any interaction with the IntegrationVendorWidgets endpoint. + */ + public function integrationVendorWidgets(): IntegrationVendorWidgetService + { + if (! isset($this->classCache['IntegrationVendorWidgets'])) { + $this->classCache['IntegrationVendorWidgets'] = new IntegrationVendorWidgetService($this->client); + } + + return $this->classCache['IntegrationVendorWidgets']; + } + /** * Handles any interaction with the InternalLocationWithBusinessHours endpoint. */ @@ -1944,6 +2208,42 @@ public function surveys(): SurveyService return $this->classCache['Surveys']; } + /** + * Handles any interaction with the TagAliases endpoint. + */ + public function tagAliases(): TagAliasService + { + if (! isset($this->classCache['TagAliases'])) { + $this->classCache['TagAliases'] = new TagAliasService($this->client); + } + + return $this->classCache['TagAliases']; + } + + /** + * Handles any interaction with the TagGroups endpoint. + */ + public function tagGroups(): TagGroupService + { + if (! isset($this->classCache['TagGroups'])) { + $this->classCache['TagGroups'] = new TagGroupService($this->client); + } + + return $this->classCache['TagGroups']; + } + + /** + * Handles any interaction with the Tags endpoint. + */ + public function tags(): TagService + { + if (! isset($this->classCache['Tags'])) { + $this->classCache['Tags'] = new TagService($this->client); + } + + return $this->classCache['Tags']; + } + /** * Handles any interaction with the TaskAttachments endpoint. */ @@ -2220,6 +2520,18 @@ public function ticketSecondaryResources(): TicketSecondaryResourceService return $this->classCache['TicketSecondaryResources']; } + /** + * Handles any interaction with the TicketTagAssociations endpoint. + */ + public function ticketTagAssociations(): TicketTagAssociationService + { + if (! isset($this->classCache['TicketTagAssociations'])) { + $this->classCache['TicketTagAssociations'] = new TicketTagAssociationService($this->client); + } + + return $this->classCache['TicketTagAssociations']; + } + /** * Handles any interaction with the Tickets endpoint. */ diff --git a/tests/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordServiceTest.php b/tests/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordServiceTest.php new file mode 100644 index 00000000..9776a999 --- /dev/null +++ b/tests/API/ConfigurationItemDnsRecords/ConfigurationItemDnsRecordServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + ConfigurationItemDnsRecordService::class, + $this->client->configurationItemDnsRecords() + ); + } + + /** + * @covers ConfigurationItemDnsRecordService + */ + public function test_query_returns_collection() + { + $result = $this->client->configurationItemDnsRecords()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + ConfigurationItemDnsRecordCollection::class, + $result + ); + } + + /** + * @covers ConfigurationItemDnsRecordCollection + */ + public function test_collection_contains_configuration_item_dns_record_entities() + { + $result = $this->client->configurationItemDnsRecords()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + ConfigurationItemDnsRecordEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers ConfigurationItemDnsRecordService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + ConfigurationItemDnsRecordQueryBuilder::class, + $this->client->configurationItemDnsRecords()->query() + ); + } +} diff --git a/tests/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameServiceTest.php b/tests/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameServiceTest.php new file mode 100644 index 00000000..a9f196cd --- /dev/null +++ b/tests/API/ConfigurationItemSslSubjectAlternativeNames/ConfigurationItemSslSubjectAlternativeNameServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + ConfigurationItemSslSubjectAlternativeNameService::class, + $this->client->configurationItemSslSubjectAlternativeNames() + ); + } + + /** + * @covers ConfigurationItemSslSubjectAlternativeNameService + */ + public function test_query_returns_collection() + { + $result = $this->client->configurationItemSslSubjectAlternativeNames()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + ConfigurationItemSslSubjectAlternativeNameCollection::class, + $result + ); + } + + /** + * @covers ConfigurationItemSslSubjectAlternativeNameCollection + */ + public function test_collection_contains_configuration_item_ssl_subject_alternative_name_entities() + { + $result = $this->client->configurationItemSslSubjectAlternativeNames()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + ConfigurationItemSslSubjectAlternativeNameEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers ConfigurationItemSslSubjectAlternativeNameService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + ConfigurationItemSslSubjectAlternativeNameQueryBuilder::class, + $this->client->configurationItemSslSubjectAlternativeNames()->query() + ); + } +} diff --git a/tests/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceServiceTest.php b/tests/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceServiceTest.php new file mode 100644 index 00000000..6e3f9c1d --- /dev/null +++ b/tests/API/ConfigurationItemWebhookExcludedResources/ConfigurationItemWebhookExcludedResourceServiceTest.php @@ -0,0 +1,24 @@ +assertInstanceOf( + ConfigurationItemWebhookExcludedResourceService::class, + $this->client->configurationItemWebhookExcludedResources() + ); + } +} diff --git a/tests/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldServiceTest.php b/tests/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldServiceTest.php new file mode 100644 index 00000000..4d3ce251 --- /dev/null +++ b/tests/API/ConfigurationItemWebhookFields/ConfigurationItemWebhookFieldServiceTest.php @@ -0,0 +1,24 @@ +assertInstanceOf( + ConfigurationItemWebhookFieldService::class, + $this->client->configurationItemWebhookFields() + ); + } +} diff --git a/tests/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldServiceTest.php b/tests/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldServiceTest.php new file mode 100644 index 00000000..e2d300f3 --- /dev/null +++ b/tests/API/ConfigurationItemWebhookUdfFields/ConfigurationItemWebhookUdfFieldServiceTest.php @@ -0,0 +1,24 @@ +assertInstanceOf( + ConfigurationItemWebhookUdfFieldService::class, + $this->client->configurationItemWebhookUdfFields() + ); + } +} diff --git a/tests/API/ConfigurationItemWebhooks/ConfigurationItemWebhookServiceTest.php b/tests/API/ConfigurationItemWebhooks/ConfigurationItemWebhookServiceTest.php new file mode 100644 index 00000000..f82682ba --- /dev/null +++ b/tests/API/ConfigurationItemWebhooks/ConfigurationItemWebhookServiceTest.php @@ -0,0 +1,24 @@ +assertInstanceOf( + ConfigurationItemWebhookService::class, + $this->client->configurationItemWebhooks() + ); + } +} diff --git a/tests/API/Currencies/CurrencyServiceTest.php b/tests/API/Currencies/CurrencyServiceTest.php new file mode 100644 index 00000000..fcb66e94 --- /dev/null +++ b/tests/API/Currencies/CurrencyServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + CurrencyService::class, + $this->client->currencies() + ); + } + + /** + * @covers CurrencyService + */ + public function test_query_returns_collection() + { + $result = $this->client->currencies()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + CurrencyCollection::class, + $result + ); + } + + /** + * @covers CurrencyCollection + */ + public function test_collection_contains_currency_entities() + { + $result = $this->client->currencies()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + CurrencyEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers CurrencyService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + CurrencyQueryBuilder::class, + $this->client->currencies()->query() + ); + } +} diff --git a/tests/API/DocumentAttachments/DocumentAttachmentServiceTest.php b/tests/API/DocumentAttachments/DocumentAttachmentServiceTest.php new file mode 100644 index 00000000..0c8871dd --- /dev/null +++ b/tests/API/DocumentAttachments/DocumentAttachmentServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentAttachmentService::class, + $this->client->documentAttachments() + ); + } + + /** + * @covers DocumentAttachmentService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentAttachments()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentAttachmentCollection::class, + $result + ); + } + + /** + * @covers DocumentAttachmentCollection + */ + public function test_collection_contains_document_attachment_entities() + { + $result = $this->client->documentAttachments()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentAttachmentEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentAttachmentService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentAttachmentQueryBuilder::class, + $this->client->documentAttachments()->query() + ); + } +} diff --git a/tests/API/DocumentCategories/DocumentCategoryServiceTest.php b/tests/API/DocumentCategories/DocumentCategoryServiceTest.php new file mode 100644 index 00000000..dfed5b78 --- /dev/null +++ b/tests/API/DocumentCategories/DocumentCategoryServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentCategoryService::class, + $this->client->documentCategories() + ); + } + + /** + * @covers DocumentCategoryService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentCategories()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentCategoryCollection::class, + $result + ); + } + + /** + * @covers DocumentCategoryCollection + */ + public function test_collection_contains_document_category_entities() + { + $result = $this->client->documentCategories()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentCategoryEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentCategoryService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentCategoryQueryBuilder::class, + $this->client->documentCategories()->query() + ); + } +} diff --git a/tests/API/DocumentChecklistItems/DocumentChecklistItemServiceTest.php b/tests/API/DocumentChecklistItems/DocumentChecklistItemServiceTest.php new file mode 100644 index 00000000..63173f17 --- /dev/null +++ b/tests/API/DocumentChecklistItems/DocumentChecklistItemServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentChecklistItemService::class, + $this->client->documentChecklistItems() + ); + } + + /** + * @covers DocumentChecklistItemService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentChecklistItems()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentChecklistItemCollection::class, + $result + ); + } + + /** + * @covers DocumentChecklistItemCollection + */ + public function test_collection_contains_document_checklist_item_entities() + { + $result = $this->client->documentChecklistItems()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentChecklistItemEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentChecklistItemService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentChecklistItemQueryBuilder::class, + $this->client->documentChecklistItems()->query() + ); + } +} diff --git a/tests/API/DocumentChecklistLibraries/DocumentChecklistLibraryServiceTest.php b/tests/API/DocumentChecklistLibraries/DocumentChecklistLibraryServiceTest.php new file mode 100644 index 00000000..4b74f6d8 --- /dev/null +++ b/tests/API/DocumentChecklistLibraries/DocumentChecklistLibraryServiceTest.php @@ -0,0 +1,19 @@ +assertInstanceOf( + DocumentChecklistLibraryService::class, + $this->client->documentChecklistLibraries() + ); + } +} diff --git a/tests/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationServiceTest.php b/tests/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationServiceTest.php new file mode 100644 index 00000000..8bfcc882 --- /dev/null +++ b/tests/API/DocumentConfigurationItemAssociations/DocumentConfigurationItemAssociationServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentConfigurationItemAssociationService::class, + $this->client->documentConfigurationItemAssociations() + ); + } + + /** + * @covers DocumentConfigurationItemAssociationService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentConfigurationItemAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentConfigurationItemAssociationCollection::class, + $result + ); + } + + /** + * @covers DocumentConfigurationItemAssociationCollection + */ + public function test_collection_contains_document_configuration_item_association_entities() + { + $result = $this->client->documentConfigurationItemAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentConfigurationItemAssociationEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentConfigurationItemAssociationService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentConfigurationItemAssociationQueryBuilder::class, + $this->client->documentConfigurationItemAssociations()->query() + ); + } +} diff --git a/tests/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationServiceTest.php b/tests/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationServiceTest.php new file mode 100644 index 00000000..91d0c464 --- /dev/null +++ b/tests/API/DocumentConfigurationItemCategoryAssociations/DocumentConfigurationItemCategoryAssociationServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentConfigurationItemCategoryAssociationService::class, + $this->client->documentConfigurationItemCategoryAssociations() + ); + } + + /** + * @covers DocumentConfigurationItemCategoryAssociationService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentConfigurationItemCategoryAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentConfigurationItemCategoryAssociationCollection::class, + $result + ); + } + + /** + * @covers DocumentConfigurationItemCategoryAssociationCollection + */ + public function test_collection_contains_document_configuration_item_category_association_entities() + { + $result = $this->client->documentConfigurationItemCategoryAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentConfigurationItemCategoryAssociationEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentConfigurationItemCategoryAssociationService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentConfigurationItemCategoryAssociationQueryBuilder::class, + $this->client->documentConfigurationItemCategoryAssociations()->query() + ); + } +} diff --git a/tests/API/DocumentNotes/DocumentNoteServiceTest.php b/tests/API/DocumentNotes/DocumentNoteServiceTest.php new file mode 100644 index 00000000..1cb2dc4c --- /dev/null +++ b/tests/API/DocumentNotes/DocumentNoteServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentNoteService::class, + $this->client->documentNotes() + ); + } + + /** + * @covers DocumentNoteService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentNotes()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentNoteCollection::class, + $result + ); + } + + /** + * @covers DocumentNoteCollection + */ + public function test_collection_contains_document_note_entities() + { + $result = $this->client->documentNotes()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentNoteEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentNoteService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentNoteQueryBuilder::class, + $this->client->documentNotes()->query() + ); + } +} diff --git a/tests/API/DocumentPlainTextContent/DocumentPlainTextContentServiceTest.php b/tests/API/DocumentPlainTextContent/DocumentPlainTextContentServiceTest.php new file mode 100644 index 00000000..cc93b658 --- /dev/null +++ b/tests/API/DocumentPlainTextContent/DocumentPlainTextContentServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentPlainTextContentService::class, + $this->client->documentPlainTextContent() + ); + } + + /** + * @covers DocumentPlainTextContentService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentPlainTextContent()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentPlainTextContentCollection::class, + $result + ); + } + + /** + * @covers DocumentPlainTextContentCollection + */ + public function test_collection_contains_document_plain_text_content_entities() + { + $result = $this->client->documentPlainTextContent()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentPlainTextContentEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentPlainTextContentService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentPlainTextContentQueryBuilder::class, + $this->client->documentPlainTextContent()->query() + ); + } +} diff --git a/tests/API/DocumentTagAssociations/DocumentTagAssociationServiceTest.php b/tests/API/DocumentTagAssociations/DocumentTagAssociationServiceTest.php new file mode 100644 index 00000000..e7fd42ce --- /dev/null +++ b/tests/API/DocumentTagAssociations/DocumentTagAssociationServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentTagAssociationService::class, + $this->client->documentTagAssociations() + ); + } + + /** + * @covers DocumentTagAssociationService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentTagAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentTagAssociationCollection::class, + $result + ); + } + + /** + * @covers DocumentTagAssociationCollection + */ + public function test_collection_contains_document_tag_association_entities() + { + $result = $this->client->documentTagAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentTagAssociationEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentTagAssociationService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentTagAssociationQueryBuilder::class, + $this->client->documentTagAssociations()->query() + ); + } +} diff --git a/tests/API/DocumentTicketAssociations/DocumentTicketAssociationServiceTest.php b/tests/API/DocumentTicketAssociations/DocumentTicketAssociationServiceTest.php new file mode 100644 index 00000000..9f8a58b1 --- /dev/null +++ b/tests/API/DocumentTicketAssociations/DocumentTicketAssociationServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentTicketAssociationService::class, + $this->client->documentTicketAssociations() + ); + } + + /** + * @covers DocumentTicketAssociationService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentTicketAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentTicketAssociationCollection::class, + $result + ); + } + + /** + * @covers DocumentTicketAssociationCollection + */ + public function test_collection_contains_document_ticket_association_entities() + { + $result = $this->client->documentTicketAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentTicketAssociationEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentTicketAssociationService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentTicketAssociationQueryBuilder::class, + $this->client->documentTicketAssociations()->query() + ); + } +} diff --git a/tests/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationServiceTest.php b/tests/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationServiceTest.php new file mode 100644 index 00000000..4d91b642 --- /dev/null +++ b/tests/API/DocumentToDocumentAssociations/DocumentToDocumentAssociationServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentToDocumentAssociationService::class, + $this->client->documentToDocumentAssociations() + ); + } + + /** + * @covers DocumentToDocumentAssociationService + */ + public function test_query_returns_collection() + { + $result = $this->client->documentToDocumentAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentToDocumentAssociationCollection::class, + $result + ); + } + + /** + * @covers DocumentToDocumentAssociationCollection + */ + public function test_collection_contains_document_to_document_association_entities() + { + $result = $this->client->documentToDocumentAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentToDocumentAssociationEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentToDocumentAssociationService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentToDocumentAssociationQueryBuilder::class, + $this->client->documentToDocumentAssociations()->query() + ); + } +} diff --git a/tests/API/Documents/DocumentServiceTest.php b/tests/API/Documents/DocumentServiceTest.php new file mode 100644 index 00000000..a5cb3aa2 --- /dev/null +++ b/tests/API/Documents/DocumentServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DocumentService::class, + $this->client->documents() + ); + } + + /** + * @covers DocumentService + */ + public function test_query_returns_collection() + { + $result = $this->client->documents()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DocumentCollection::class, + $result + ); + } + + /** + * @covers DocumentCollection + */ + public function test_collection_contains_document_entities() + { + $result = $this->client->documents()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DocumentEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DocumentService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DocumentQueryBuilder::class, + $this->client->documents()->query() + ); + } +} diff --git a/tests/API/DomainRegistrars/DomainRegistrarServiceTest.php b/tests/API/DomainRegistrars/DomainRegistrarServiceTest.php new file mode 100644 index 00000000..7a055f46 --- /dev/null +++ b/tests/API/DomainRegistrars/DomainRegistrarServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + DomainRegistrarService::class, + $this->client->domainRegistrars() + ); + } + + /** + * @covers DomainRegistrarService + */ + public function test_query_returns_collection() + { + $result = $this->client->domainRegistrars()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + DomainRegistrarCollection::class, + $result + ); + } + + /** + * @covers DomainRegistrarCollection + */ + public function test_collection_contains_domain_registrar_entities() + { + $result = $this->client->domainRegistrars()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + DomainRegistrarEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers DomainRegistrarService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + DomainRegistrarQueryBuilder::class, + $this->client->domainRegistrars()->query() + ); + } +} diff --git a/tests/API/IntegrationVendorWidgets/IntegrationVendorWidgetServiceTest.php b/tests/API/IntegrationVendorWidgets/IntegrationVendorWidgetServiceTest.php new file mode 100644 index 00000000..b345bd84 --- /dev/null +++ b/tests/API/IntegrationVendorWidgets/IntegrationVendorWidgetServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + IntegrationVendorWidgetService::class, + $this->client->integrationVendorWidgets() + ); + } + + /** + * @covers IntegrationVendorWidgetService + */ + public function test_query_returns_collection() + { + $result = $this->client->integrationVendorWidgets()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + IntegrationVendorWidgetCollection::class, + $result + ); + } + + /** + * @covers IntegrationVendorWidgetCollection + */ + public function test_collection_contains_integration_vendor_widget_entities() + { + $result = $this->client->integrationVendorWidgets()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + IntegrationVendorWidgetEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers IntegrationVendorWidgetService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + IntegrationVendorWidgetQueryBuilder::class, + $this->client->integrationVendorWidgets()->query() + ); + } +} diff --git a/tests/API/PriceListMaterialCodes/PriceListMaterialCodeServiceTest.php b/tests/API/PriceListMaterialCodes/PriceListMaterialCodeServiceTest.php new file mode 100644 index 00000000..00d44d7d --- /dev/null +++ b/tests/API/PriceListMaterialCodes/PriceListMaterialCodeServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + PriceListMaterialCodeService::class, + $this->client->priceListMaterialCodes() + ); + } + + /** + * @covers PriceListMaterialCodeService + */ + public function test_query_returns_collection() + { + $result = $this->client->priceListMaterialCodes()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + PriceListMaterialCodeCollection::class, + $result + ); + } + + /** + * @covers PriceListMaterialCodeCollection + */ + public function test_collection_contains_price_list_material_code_entities() + { + $result = $this->client->priceListMaterialCodes()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + PriceListMaterialCodeEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers PriceListMaterialCodeService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + PriceListMaterialCodeQueryBuilder::class, + $this->client->priceListMaterialCodes()->query() + ); + } +} diff --git a/tests/API/PriceListProductTiers/PriceListProductTierServiceTest.php b/tests/API/PriceListProductTiers/PriceListProductTierServiceTest.php new file mode 100644 index 00000000..f5681ef5 --- /dev/null +++ b/tests/API/PriceListProductTiers/PriceListProductTierServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + PriceListProductTierService::class, + $this->client->priceListProductTiers() + ); + } + + /** + * @covers PriceListProductTierService + */ + public function test_query_returns_collection() + { + $result = $this->client->priceListProductTiers()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + PriceListProductTierCollection::class, + $result + ); + } + + /** + * @covers PriceListProductTierCollection + */ + public function test_collection_contains_price_list_product_tier_entities() + { + $result = $this->client->priceListProductTiers()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + PriceListProductTierEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers PriceListProductTierService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + PriceListProductTierQueryBuilder::class, + $this->client->priceListProductTiers()->query() + ); + } +} diff --git a/tests/API/PriceListProducts/PriceListProductServiceTest.php b/tests/API/PriceListProducts/PriceListProductServiceTest.php new file mode 100644 index 00000000..b65b7220 --- /dev/null +++ b/tests/API/PriceListProducts/PriceListProductServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + PriceListProductService::class, + $this->client->priceListProducts() + ); + } + + /** + * @covers PriceListProductService + */ + public function test_query_returns_collection() + { + $result = $this->client->priceListProducts()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + PriceListProductCollection::class, + $result + ); + } + + /** + * @covers PriceListProductCollection + */ + public function test_collection_contains_price_list_product_entities() + { + $result = $this->client->priceListProducts()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + PriceListProductEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers PriceListProductService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + PriceListProductQueryBuilder::class, + $this->client->priceListProducts()->query() + ); + } +} diff --git a/tests/API/PriceListRoles/PriceListRoleServiceTest.php b/tests/API/PriceListRoles/PriceListRoleServiceTest.php new file mode 100644 index 00000000..942271d7 --- /dev/null +++ b/tests/API/PriceListRoles/PriceListRoleServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + PriceListRoleService::class, + $this->client->priceListRoles() + ); + } + + /** + * @covers PriceListRoleService + */ + public function test_query_returns_collection() + { + $result = $this->client->priceListRoles()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + PriceListRoleCollection::class, + $result + ); + } + + /** + * @covers PriceListRoleCollection + */ + public function test_collection_contains_price_list_role_entities() + { + $result = $this->client->priceListRoles()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + PriceListRoleEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers PriceListRoleService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + PriceListRoleQueryBuilder::class, + $this->client->priceListRoles()->query() + ); + } +} diff --git a/tests/API/PriceListServiceBundles/PriceListServiceBundleServiceTest.php b/tests/API/PriceListServiceBundles/PriceListServiceBundleServiceTest.php new file mode 100644 index 00000000..5c42e839 --- /dev/null +++ b/tests/API/PriceListServiceBundles/PriceListServiceBundleServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + PriceListServiceBundleService::class, + $this->client->priceListServiceBundles() + ); + } + + /** + * @covers PriceListServiceBundleService + */ + public function test_query_returns_collection() + { + $result = $this->client->priceListServiceBundles()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + PriceListServiceBundleCollection::class, + $result + ); + } + + /** + * @covers PriceListServiceBundleCollection + */ + public function test_collection_contains_price_list_service_bundle_entities() + { + $result = $this->client->priceListServiceBundles()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + PriceListServiceBundleEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers PriceListServiceBundleService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + PriceListServiceBundleQueryBuilder::class, + $this->client->priceListServiceBundles()->query() + ); + } +} diff --git a/tests/API/PriceListServices/PriceListServiceServiceTest.php b/tests/API/PriceListServices/PriceListServiceServiceTest.php new file mode 100644 index 00000000..c55abcca --- /dev/null +++ b/tests/API/PriceListServices/PriceListServiceServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + PriceListServiceService::class, + $this->client->priceListServices() + ); + } + + /** + * @covers PriceListServiceService + */ + public function test_query_returns_collection() + { + $result = $this->client->priceListServices()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + PriceListServiceCollection::class, + $result + ); + } + + /** + * @covers PriceListServiceCollection + */ + public function test_collection_contains_price_list_service_entities() + { + $result = $this->client->priceListServices()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + PriceListServiceEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers PriceListServiceService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + PriceListServiceQueryBuilder::class, + $this->client->priceListServices()->query() + ); + } +} diff --git a/tests/API/PriceListWorkTypeModifiers/PriceListWorkTypeModifierServiceTest.php b/tests/API/PriceListWorkTypeModifiers/PriceListWorkTypeModifierServiceTest.php new file mode 100644 index 00000000..fff8e00c --- /dev/null +++ b/tests/API/PriceListWorkTypeModifiers/PriceListWorkTypeModifierServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + PriceListWorkTypeModifierService::class, + $this->client->priceListWorkTypeModifiers() + ); + } + + /** + * @covers PriceListWorkTypeModifierService + */ + public function test_query_returns_collection() + { + $result = $this->client->priceListWorkTypeModifiers()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + PriceListWorkTypeModifierCollection::class, + $result + ); + } + + /** + * @covers PriceListWorkTypeModifierCollection + */ + public function test_collection_contains_price_list_work_type_modifier_entities() + { + $result = $this->client->priceListWorkTypeModifiers()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + PriceListWorkTypeModifierEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers PriceListWorkTypeModifierService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + PriceListWorkTypeModifierQueryBuilder::class, + $this->client->priceListWorkTypeModifiers()->query() + ); + } +} diff --git a/tests/API/TagAliases/TagAliasServiceTest.php b/tests/API/TagAliases/TagAliasServiceTest.php new file mode 100644 index 00000000..ce3b655d --- /dev/null +++ b/tests/API/TagAliases/TagAliasServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + TagAliasService::class, + $this->client->tagAliases() + ); + } + + /** + * @covers TagAliasService + */ + public function test_query_returns_collection() + { + $result = $this->client->tagAliases()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + TagAliasCollection::class, + $result + ); + } + + /** + * @covers TagAliasCollection + */ + public function test_collection_contains_tag_alias_entities() + { + $result = $this->client->tagAliases()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + TagAliasEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers TagAliasService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + TagAliasQueryBuilder::class, + $this->client->tagAliases()->query() + ); + } +} diff --git a/tests/API/TagGroups/TagGroupServiceTest.php b/tests/API/TagGroups/TagGroupServiceTest.php new file mode 100644 index 00000000..6eff6235 --- /dev/null +++ b/tests/API/TagGroups/TagGroupServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + TagGroupService::class, + $this->client->tagGroups() + ); + } + + /** + * @covers TagGroupService + */ + public function test_query_returns_collection() + { + $result = $this->client->tagGroups()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + TagGroupCollection::class, + $result + ); + } + + /** + * @covers TagGroupCollection + */ + public function test_collection_contains_tag_group_entities() + { + $result = $this->client->tagGroups()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + TagGroupEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers TagGroupService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + TagGroupQueryBuilder::class, + $this->client->tagGroups()->query() + ); + } +} diff --git a/tests/API/Tags/TagServiceTest.php b/tests/API/Tags/TagServiceTest.php new file mode 100644 index 00000000..c04af7d3 --- /dev/null +++ b/tests/API/Tags/TagServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + TagService::class, + $this->client->tags() + ); + } + + /** + * @covers TagService + */ + public function test_query_returns_collection() + { + $result = $this->client->tags()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + TagCollection::class, + $result + ); + } + + /** + * @covers TagCollection + */ + public function test_collection_contains_tag_entities() + { + $result = $this->client->tags()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + TagEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers TagService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + TagQueryBuilder::class, + $this->client->tags()->query() + ); + } +} diff --git a/tests/API/TicketHistory/TicketHistoryServiceTest.php b/tests/API/TicketHistory/TicketHistoryServiceTest.php new file mode 100644 index 00000000..09905bdd --- /dev/null +++ b/tests/API/TicketHistory/TicketHistoryServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + TicketHistoryService::class, + $this->client->ticketHistory() + ); + } + + /** + * @covers TicketHistoryService + */ + public function test_query_returns_collection() + { + $result = $this->client->ticketHistory()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + TicketHistoryCollection::class, + $result + ); + } + + /** + * @covers TicketHistoryCollection + */ + public function test_collection_contains_ticket_history_entities() + { + $result = $this->client->ticketHistory()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + TicketHistoryEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers TicketHistoryService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + TicketHistoryQueryBuilder::class, + $this->client->ticketHistory()->query() + ); + } +} diff --git a/tests/API/TicketTagAssociations/TicketTagAssociationServiceTest.php b/tests/API/TicketTagAssociations/TicketTagAssociationServiceTest.php new file mode 100644 index 00000000..f0b2e734 --- /dev/null +++ b/tests/API/TicketTagAssociations/TicketTagAssociationServiceTest.php @@ -0,0 +1,67 @@ +assertInstanceOf( + TicketTagAssociationService::class, + $this->client->ticketTagAssociations() + ); + } + + /** + * @covers TicketTagAssociationService + */ + public function test_query_returns_collection() + { + $result = $this->client->ticketTagAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure its a collection + $this->assertInstanceOf( + TicketTagAssociationCollection::class, + $result + ); + } + + /** + * @covers TicketTagAssociationCollection + */ + public function test_collection_contains_ticket_tag_association_entities() + { + $result = $this->client->ticketTagAssociations()->query()->where('id', 'exist')->records(1)->get(); + + // Make sure the collection has entities + if (count($result) > 0) { + $this->assertInstanceOf( + TicketTagAssociationEntity::class, + $result->offsetGet(0) + ); + } else { + $this->assertCount(0, $result); + } + } + + /** + * @covers TicketTagAssociationService + */ + public function test_query_method_returns_query_builder() + { + $this->assertInstanceOf( + TicketTagAssociationQueryBuilder::class, + $this->client->ticketTagAssociations()->query() + ); + } +} diff --git a/tests/AbstractTest.php b/tests/AbstractTest.php index c5eec658..a15b679c 100644 --- a/tests/AbstractTest.php +++ b/tests/AbstractTest.php @@ -20,46 +20,36 @@ abstract class AbstractTest extends TestCase public function setUp(): void { // Start by trying to load environment variables - if (file_exists(__DIR__ . '/../.env')) { - // We have to create an unsafe immutable in v5 given that CI will require - // use to use getenv() - if (method_exists(Dotenv::class, 'createUnsafeImmutable')) { - $dotenv = Dotenv::createUnsafeImmutable(__DIR__ . '/../'); - } else { - $dotenv = Dotenv::createImmutable(__DIR__ . '/../'); - } - + if (file_exists( __DIR__ . '/../.env')) { + $dotenv = Dotenv::createImmutable(__DIR__ . '/../'); $dotenv->load(); + } else { + throw new Exception('Unable to find environment file!'); } // Next check each individual one - $username = getenv('AUTOTASK_API_USERNAME'); - $secret = getenv('AUTOTASK_API_SECRET'); - $ic = getenv('AUTOTASK_API_INTEGRATION_CODE'); - $baseUri = getenv('AUTOTASK_API_BASE_URI'); - - if (!$username) { + if (! isset($_ENV['AUTOTASK_API_USERNAME'])) { throw new Exception('Unable to find find AUTOTASK_API_USERNAME env variable!'); } - if (!$secret) { + if (! isset($_ENV['AUTOTASK_API_SECRET'])) { throw new Exception('Unable to find find AUTOTASK_API_SECRET env variable!'); } - if (!$ic) { + if (! isset($_ENV['AUTOTASK_API_INTEGRATION_CODE'])) { throw new Exception('Unable to find find AUTOTASK_API_INTEGRATION_CODE env variable!'); } - if (!$baseUri) { + if (! isset($_ENV['AUTOTASK_API_BASE_URI'])) { throw new Exception('Unable to find find AUTOTASK_API_BASE_URI env variable!'); } // Now try creating the client $this->client = new Client( - $username, - $secret, - $ic, - $baseUri + $_ENV['AUTOTASK_API_USERNAME'], + $_ENV['AUTOTASK_API_SECRET'], + $_ENV['AUTOTASK_API_INTEGRATION_CODE'], + $_ENV['AUTOTASK_API_BASE_URI'] ); } }