├── .github └── workflows │ └── ant.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── bin └── cli.php ├── build.properties ├── build.xml ├── composer.json ├── composer.lock ├── data └── test.json ├── index.html ├── index.php ├── phpunit.xml.dist ├── src ├── ClassFactory.php ├── ClassFactoryInterface.php ├── ClassPrototype.php ├── ClassPrototypeInterface.php ├── PhpGenerator.php └── StringUtil.php └── tests ├── PhpGeneratorTest.php └── fixtures ├── sample-fluent-setters.txt ├── sample-typehinting-fluent-setters.txt ├── sample-typehinting.txt └── sample.txt /.github/workflows/ant.yml: -------------------------------------------------------------------------------- 1 | name: Apache Ant CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Set up JDK 1.8 13 | uses: actions/setup-java@v1 14 | with: 15 | java-version: 1.8 16 | - name: Build with Ant 17 | run: ant -noinput -buildfile build.xml 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | output* 3 | .idea/ 4 | .DS_Store 5 | bin/ 6 | build/ 7 | vendor/ 8 | phpunit.xml 9 | .phpunit.result.cache 10 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2020 Strikebit Productions 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 4 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 5 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 6 | persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 9 | Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 12 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 13 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 14 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JSON to PHP model classes 2 | A tool to generate PSR-2 compliant PHP model classes from JSON. This tool will 3 | recursively inspect JSON and generate corresponding classes complete with getters & 4 | setters. 5 | 6 | ## Installation 7 | If you're wanting this to be a part of your project: 8 | 9 | `composer require strikebit/json-to-php` 10 | 11 | If you're wanting this to be a standalone tool, clone this repository. Then install 12 | dependencies: 13 | 14 | `composer install` 15 | 16 | ## Usage 17 | 18 | [Online tool](https://json2php.strikebit.io/) 19 | 20 | ### Command Line 21 | Example: 22 | `php ./bin/cli.php ./input-file.json User 1 1 Acme\\Entity > output.txt` 23 | 24 | Arguments: 25 | 1. Location of your input JSON file. 26 | 2. Desired class name 27 | 3. Type hinting (0|1) 28 | 4. Fluent setters (0|1) 29 | 5. Desired namespace (optional) 30 | 31 | ## Contributing 32 | ### Testing 33 | [Apache Ant](https://ant.apache.org/) is required. 34 | 35 | `ant` 36 | 37 | Build errors will appear in build/results. 38 | -------------------------------------------------------------------------------- /bin/cli.php: -------------------------------------------------------------------------------- 1 | fromJson($className, $json); 34 | echo $generator->printClasses(); 35 | -------------------------------------------------------------------------------- /build.properties: -------------------------------------------------------------------------------- 1 | # PHP Code Sniffer 2 | phpcs.standard=PSR1,PSR2 3 | phpcs.dir=${basedir}/vendor/squizlabs/php_codesniffer 4 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "strikebit/json-to-php", 3 | "description": "Utility for creating PHP classes from JSON", 4 | "type": "library", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Aaron Benson", 9 | "email": "strikebit.io@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": "^7.1.3" 14 | }, 15 | "require-dev": { 16 | "escapestudios/symfony2-coding-standard": "^3.1", 17 | "phpmd/phpmd": "^2.6", 18 | "sebastian/phpcpd": "^4.0", 19 | "squizlabs/php_codesniffer": "^3.0", 20 | "symfony/phpunit-bridge": "^4.0" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Strikebit\\Util\\": "src/" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "Strikebit\\Util\\Tests\\": "tests/" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "82464515c8648c834ef399c76bd7549b", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "composer/xdebug-handler", 12 | "version": "1.4.1", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/composer/xdebug-handler.git", 16 | "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/1ab9842d69e64fb3a01be6b656501032d1b78cb7", 21 | "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": "^5.3.2 || ^7.0 || ^8.0", 26 | "psr/log": "^1.0" 27 | }, 28 | "require-dev": { 29 | "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" 30 | }, 31 | "type": "library", 32 | "autoload": { 33 | "psr-4": { 34 | "Composer\\XdebugHandler\\": "src" 35 | } 36 | }, 37 | "notification-url": "https://packagist.org/downloads/", 38 | "license": [ 39 | "MIT" 40 | ], 41 | "authors": [ 42 | { 43 | "name": "John Stevenson", 44 | "email": "john-stevenson@blueyonder.co.uk" 45 | } 46 | ], 47 | "description": "Restarts a process without Xdebug.", 48 | "keywords": [ 49 | "Xdebug", 50 | "performance" 51 | ], 52 | "time": "2020-03-01T12:26:26+00:00" 53 | }, 54 | { 55 | "name": "escapestudios/symfony2-coding-standard", 56 | "version": "3.11.0", 57 | "source": { 58 | "type": "git", 59 | "url": "https://github.com/djoos/Symfony-coding-standard.git", 60 | "reference": "78e3b0b6832c88cf7c0240b4abcd61430030d8c3" 61 | }, 62 | "dist": { 63 | "type": "zip", 64 | "url": "https://api.github.com/repos/djoos/Symfony-coding-standard/zipball/78e3b0b6832c88cf7c0240b4abcd61430030d8c3", 65 | "reference": "78e3b0b6832c88cf7c0240b4abcd61430030d8c3", 66 | "shasum": "" 67 | }, 68 | "require": { 69 | "squizlabs/php_codesniffer": "^3.3.1" 70 | }, 71 | "conflict": { 72 | "squizlabs/php_codesniffer": "<3 || >=4" 73 | }, 74 | "require-dev": { 75 | "phpunit/phpunit": "^5.0 || ^6.0 || ^7.0" 76 | }, 77 | "type": "phpcodesniffer-standard", 78 | "extra": { 79 | "branch-alias": { 80 | "dev-master": "3.x-dev" 81 | } 82 | }, 83 | "notification-url": "https://packagist.org/downloads/", 84 | "license": [ 85 | "MIT" 86 | ], 87 | "authors": [ 88 | { 89 | "name": "David Joos", 90 | "email": "iam@davidjoos.com" 91 | }, 92 | { 93 | "name": "Community contributors", 94 | "homepage": "https://github.com/djoos/Symfony-coding-standard/graphs/contributors" 95 | } 96 | ], 97 | "description": "CodeSniffer ruleset for the Symfony 2+ coding standard", 98 | "homepage": "https://github.com/djoos/Symfony-coding-standard", 99 | "keywords": [ 100 | "Coding Standard", 101 | "Symfony2", 102 | "phpcs", 103 | "symfony" 104 | ], 105 | "time": "2020-01-22T10:27:47+00:00" 106 | }, 107 | { 108 | "name": "pdepend/pdepend", 109 | "version": "2.7.1", 110 | "source": { 111 | "type": "git", 112 | "url": "https://github.com/pdepend/pdepend.git", 113 | "reference": "daba1cf0a6edaf172fa02a17807ae29f4c1c7471" 114 | }, 115 | "dist": { 116 | "type": "zip", 117 | "url": "https://api.github.com/repos/pdepend/pdepend/zipball/daba1cf0a6edaf172fa02a17807ae29f4c1c7471", 118 | "reference": "daba1cf0a6edaf172fa02a17807ae29f4c1c7471", 119 | "shasum": "" 120 | }, 121 | "require": { 122 | "php": ">=5.3.7", 123 | "symfony/config": "^2.3.0|^3|^4|^5", 124 | "symfony/dependency-injection": "^2.3.0|^3|^4|^5", 125 | "symfony/filesystem": "^2.3.0|^3|^4|^5" 126 | }, 127 | "require-dev": { 128 | "easy-doc/easy-doc": "0.0.0 || ^1.2.3", 129 | "gregwar/rst": "^1.0", 130 | "phpunit/phpunit": "^4.8.35|^5.7", 131 | "squizlabs/php_codesniffer": "^2.0.0" 132 | }, 133 | "bin": [ 134 | "src/bin/pdepend" 135 | ], 136 | "type": "library", 137 | "extra": { 138 | "branch-alias": { 139 | "dev-master": "2.x-dev" 140 | } 141 | }, 142 | "autoload": { 143 | "psr-4": { 144 | "PDepend\\": "src/main/php/PDepend" 145 | } 146 | }, 147 | "notification-url": "https://packagist.org/downloads/", 148 | "license": [ 149 | "BSD-3-Clause" 150 | ], 151 | "description": "Official version of pdepend to be handled with Composer", 152 | "time": "2020-02-08T12:06:13+00:00" 153 | }, 154 | { 155 | "name": "phpmd/phpmd", 156 | "version": "2.8.2", 157 | "source": { 158 | "type": "git", 159 | "url": "https://github.com/phpmd/phpmd.git", 160 | "reference": "714629ed782537f638fe23c4346637659b779a77" 161 | }, 162 | "dist": { 163 | "type": "zip", 164 | "url": "https://api.github.com/repos/phpmd/phpmd/zipball/714629ed782537f638fe23c4346637659b779a77", 165 | "reference": "714629ed782537f638fe23c4346637659b779a77", 166 | "shasum": "" 167 | }, 168 | "require": { 169 | "composer/xdebug-handler": "^1.0", 170 | "ext-xml": "*", 171 | "pdepend/pdepend": "^2.7.1", 172 | "php": ">=5.3.9" 173 | }, 174 | "require-dev": { 175 | "easy-doc/easy-doc": "0.0.0 || ^1.3.2", 176 | "gregwar/rst": "^1.0", 177 | "mikey179/vfsstream": "^1.6.4", 178 | "phpunit/phpunit": "^4.8.36 || ^5.7.27", 179 | "squizlabs/php_codesniffer": "^2.0" 180 | }, 181 | "bin": [ 182 | "src/bin/phpmd" 183 | ], 184 | "type": "library", 185 | "autoload": { 186 | "psr-0": { 187 | "PHPMD\\": "src/main/php" 188 | } 189 | }, 190 | "notification-url": "https://packagist.org/downloads/", 191 | "license": [ 192 | "BSD-3-Clause" 193 | ], 194 | "authors": [ 195 | { 196 | "name": "Manuel Pichler", 197 | "email": "github@manuel-pichler.de", 198 | "homepage": "https://github.com/manuelpichler", 199 | "role": "Project Founder" 200 | }, 201 | { 202 | "name": "Marc Würth", 203 | "email": "ravage@bluewin.ch", 204 | "homepage": "https://github.com/ravage84", 205 | "role": "Project Maintainer" 206 | }, 207 | { 208 | "name": "Other contributors", 209 | "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", 210 | "role": "Contributors" 211 | } 212 | ], 213 | "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", 214 | "homepage": "https://phpmd.org/", 215 | "keywords": [ 216 | "mess detection", 217 | "mess detector", 218 | "pdepend", 219 | "phpmd", 220 | "pmd" 221 | ], 222 | "time": "2020-02-16T20:15:50+00:00" 223 | }, 224 | { 225 | "name": "phpunit/php-timer", 226 | "version": "2.1.2", 227 | "source": { 228 | "type": "git", 229 | "url": "https://github.com/sebastianbergmann/php-timer.git", 230 | "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" 231 | }, 232 | "dist": { 233 | "type": "zip", 234 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", 235 | "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", 236 | "shasum": "" 237 | }, 238 | "require": { 239 | "php": "^7.1" 240 | }, 241 | "require-dev": { 242 | "phpunit/phpunit": "^7.0" 243 | }, 244 | "type": "library", 245 | "extra": { 246 | "branch-alias": { 247 | "dev-master": "2.1-dev" 248 | } 249 | }, 250 | "autoload": { 251 | "classmap": [ 252 | "src/" 253 | ] 254 | }, 255 | "notification-url": "https://packagist.org/downloads/", 256 | "license": [ 257 | "BSD-3-Clause" 258 | ], 259 | "authors": [ 260 | { 261 | "name": "Sebastian Bergmann", 262 | "email": "sebastian@phpunit.de", 263 | "role": "lead" 264 | } 265 | ], 266 | "description": "Utility class for timing", 267 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 268 | "keywords": [ 269 | "timer" 270 | ], 271 | "time": "2019-06-07T04:22:29+00:00" 272 | }, 273 | { 274 | "name": "psr/container", 275 | "version": "1.0.0", 276 | "source": { 277 | "type": "git", 278 | "url": "https://github.com/php-fig/container.git", 279 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" 280 | }, 281 | "dist": { 282 | "type": "zip", 283 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 284 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 285 | "shasum": "" 286 | }, 287 | "require": { 288 | "php": ">=5.3.0" 289 | }, 290 | "type": "library", 291 | "extra": { 292 | "branch-alias": { 293 | "dev-master": "1.0.x-dev" 294 | } 295 | }, 296 | "autoload": { 297 | "psr-4": { 298 | "Psr\\Container\\": "src/" 299 | } 300 | }, 301 | "notification-url": "https://packagist.org/downloads/", 302 | "license": [ 303 | "MIT" 304 | ], 305 | "authors": [ 306 | { 307 | "name": "PHP-FIG", 308 | "homepage": "http://www.php-fig.org/" 309 | } 310 | ], 311 | "description": "Common Container Interface (PHP FIG PSR-11)", 312 | "homepage": "https://github.com/php-fig/container", 313 | "keywords": [ 314 | "PSR-11", 315 | "container", 316 | "container-interface", 317 | "container-interop", 318 | "psr" 319 | ], 320 | "time": "2017-02-14T16:28:37+00:00" 321 | }, 322 | { 323 | "name": "psr/log", 324 | "version": "1.1.2", 325 | "source": { 326 | "type": "git", 327 | "url": "https://github.com/php-fig/log.git", 328 | "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" 329 | }, 330 | "dist": { 331 | "type": "zip", 332 | "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", 333 | "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", 334 | "shasum": "" 335 | }, 336 | "require": { 337 | "php": ">=5.3.0" 338 | }, 339 | "type": "library", 340 | "extra": { 341 | "branch-alias": { 342 | "dev-master": "1.1.x-dev" 343 | } 344 | }, 345 | "autoload": { 346 | "psr-4": { 347 | "Psr\\Log\\": "Psr/Log/" 348 | } 349 | }, 350 | "notification-url": "https://packagist.org/downloads/", 351 | "license": [ 352 | "MIT" 353 | ], 354 | "authors": [ 355 | { 356 | "name": "PHP-FIG", 357 | "homepage": "http://www.php-fig.org/" 358 | } 359 | ], 360 | "description": "Common interface for logging libraries", 361 | "homepage": "https://github.com/php-fig/log", 362 | "keywords": [ 363 | "log", 364 | "psr", 365 | "psr-3" 366 | ], 367 | "time": "2019-11-01T11:05:21+00:00" 368 | }, 369 | { 370 | "name": "sebastian/finder-facade", 371 | "version": "1.2.3", 372 | "source": { 373 | "type": "git", 374 | "url": "https://github.com/sebastianbergmann/finder-facade.git", 375 | "reference": "167c45d131f7fc3d159f56f191a0a22228765e16" 376 | }, 377 | "dist": { 378 | "type": "zip", 379 | "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/167c45d131f7fc3d159f56f191a0a22228765e16", 380 | "reference": "167c45d131f7fc3d159f56f191a0a22228765e16", 381 | "shasum": "" 382 | }, 383 | "require": { 384 | "php": "^7.1", 385 | "symfony/finder": "^2.3|^3.0|^4.0|^5.0", 386 | "theseer/fdomdocument": "^1.6" 387 | }, 388 | "type": "library", 389 | "extra": { 390 | "branch-alias": [] 391 | }, 392 | "autoload": { 393 | "classmap": [ 394 | "src/" 395 | ] 396 | }, 397 | "notification-url": "https://packagist.org/downloads/", 398 | "license": [ 399 | "BSD-3-Clause" 400 | ], 401 | "authors": [ 402 | { 403 | "name": "Sebastian Bergmann", 404 | "email": "sebastian@phpunit.de", 405 | "role": "lead" 406 | } 407 | ], 408 | "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", 409 | "homepage": "https://github.com/sebastianbergmann/finder-facade", 410 | "time": "2020-01-16T08:08:45+00:00" 411 | }, 412 | { 413 | "name": "sebastian/phpcpd", 414 | "version": "4.1.0", 415 | "source": { 416 | "type": "git", 417 | "url": "https://github.com/sebastianbergmann/phpcpd.git", 418 | "reference": "0d9afa762f2400de077b2192f4a9d127de0bb78e" 419 | }, 420 | "dist": { 421 | "type": "zip", 422 | "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/0d9afa762f2400de077b2192f4a9d127de0bb78e", 423 | "reference": "0d9afa762f2400de077b2192f4a9d127de0bb78e", 424 | "shasum": "" 425 | }, 426 | "require": { 427 | "ext-dom": "*", 428 | "php": "^7.1", 429 | "phpunit/php-timer": "^2.0", 430 | "sebastian/finder-facade": "^1.1", 431 | "sebastian/version": "^1.0|^2.0", 432 | "symfony/console": "^2.7|^3.0|^4.0" 433 | }, 434 | "bin": [ 435 | "phpcpd" 436 | ], 437 | "type": "library", 438 | "extra": { 439 | "branch-alias": { 440 | "dev-master": "4.0-dev" 441 | } 442 | }, 443 | "autoload": { 444 | "classmap": [ 445 | "src/" 446 | ] 447 | }, 448 | "notification-url": "https://packagist.org/downloads/", 449 | "license": [ 450 | "BSD-3-Clause" 451 | ], 452 | "authors": [ 453 | { 454 | "name": "Sebastian Bergmann", 455 | "email": "sebastian@phpunit.de", 456 | "role": "lead" 457 | } 458 | ], 459 | "description": "Copy/Paste Detector (CPD) for PHP code.", 460 | "homepage": "https://github.com/sebastianbergmann/phpcpd", 461 | "time": "2018-09-17T17:17:27+00:00" 462 | }, 463 | { 464 | "name": "sebastian/version", 465 | "version": "2.0.1", 466 | "source": { 467 | "type": "git", 468 | "url": "https://github.com/sebastianbergmann/version.git", 469 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 470 | }, 471 | "dist": { 472 | "type": "zip", 473 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 474 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 475 | "shasum": "" 476 | }, 477 | "require": { 478 | "php": ">=5.6" 479 | }, 480 | "type": "library", 481 | "extra": { 482 | "branch-alias": { 483 | "dev-master": "2.0.x-dev" 484 | } 485 | }, 486 | "autoload": { 487 | "classmap": [ 488 | "src/" 489 | ] 490 | }, 491 | "notification-url": "https://packagist.org/downloads/", 492 | "license": [ 493 | "BSD-3-Clause" 494 | ], 495 | "authors": [ 496 | { 497 | "name": "Sebastian Bergmann", 498 | "email": "sebastian@phpunit.de", 499 | "role": "lead" 500 | } 501 | ], 502 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 503 | "homepage": "https://github.com/sebastianbergmann/version", 504 | "time": "2016-10-03T07:35:21+00:00" 505 | }, 506 | { 507 | "name": "squizlabs/php_codesniffer", 508 | "version": "3.5.4", 509 | "source": { 510 | "type": "git", 511 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", 512 | "reference": "dceec07328401de6211037abbb18bda423677e26" 513 | }, 514 | "dist": { 515 | "type": "zip", 516 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dceec07328401de6211037abbb18bda423677e26", 517 | "reference": "dceec07328401de6211037abbb18bda423677e26", 518 | "shasum": "" 519 | }, 520 | "require": { 521 | "ext-simplexml": "*", 522 | "ext-tokenizer": "*", 523 | "ext-xmlwriter": "*", 524 | "php": ">=5.4.0" 525 | }, 526 | "require-dev": { 527 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" 528 | }, 529 | "bin": [ 530 | "bin/phpcs", 531 | "bin/phpcbf" 532 | ], 533 | "type": "library", 534 | "extra": { 535 | "branch-alias": { 536 | "dev-master": "3.x-dev" 537 | } 538 | }, 539 | "notification-url": "https://packagist.org/downloads/", 540 | "license": [ 541 | "BSD-3-Clause" 542 | ], 543 | "authors": [ 544 | { 545 | "name": "Greg Sherwood", 546 | "role": "lead" 547 | } 548 | ], 549 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 550 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", 551 | "keywords": [ 552 | "phpcs", 553 | "standards" 554 | ], 555 | "time": "2020-01-30T22:20:29+00:00" 556 | }, 557 | { 558 | "name": "symfony/config", 559 | "version": "v5.0.5", 560 | "source": { 561 | "type": "git", 562 | "url": "https://github.com/symfony/config.git", 563 | "reference": "938905f46df484b2aeae9016fd658aed577cdceb" 564 | }, 565 | "dist": { 566 | "type": "zip", 567 | "url": "https://api.github.com/repos/symfony/config/zipball/938905f46df484b2aeae9016fd658aed577cdceb", 568 | "reference": "938905f46df484b2aeae9016fd658aed577cdceb", 569 | "shasum": "" 570 | }, 571 | "require": { 572 | "php": "^7.2.5", 573 | "symfony/filesystem": "^4.4|^5.0", 574 | "symfony/polyfill-ctype": "~1.8" 575 | }, 576 | "conflict": { 577 | "symfony/finder": "<4.4" 578 | }, 579 | "require-dev": { 580 | "symfony/event-dispatcher": "^4.4|^5.0", 581 | "symfony/finder": "^4.4|^5.0", 582 | "symfony/messenger": "^4.4|^5.0", 583 | "symfony/service-contracts": "^1.1|^2", 584 | "symfony/yaml": "^4.4|^5.0" 585 | }, 586 | "suggest": { 587 | "symfony/yaml": "To use the yaml reference dumper" 588 | }, 589 | "type": "library", 590 | "extra": { 591 | "branch-alias": { 592 | "dev-master": "5.0-dev" 593 | } 594 | }, 595 | "autoload": { 596 | "psr-4": { 597 | "Symfony\\Component\\Config\\": "" 598 | }, 599 | "exclude-from-classmap": [ 600 | "/Tests/" 601 | ] 602 | }, 603 | "notification-url": "https://packagist.org/downloads/", 604 | "license": [ 605 | "MIT" 606 | ], 607 | "authors": [ 608 | { 609 | "name": "Fabien Potencier", 610 | "email": "fabien@symfony.com" 611 | }, 612 | { 613 | "name": "Symfony Community", 614 | "homepage": "https://symfony.com/contributors" 615 | } 616 | ], 617 | "description": "Symfony Config Component", 618 | "homepage": "https://symfony.com", 619 | "time": "2020-02-04T09:41:09+00:00" 620 | }, 621 | { 622 | "name": "symfony/console", 623 | "version": "v4.4.5", 624 | "source": { 625 | "type": "git", 626 | "url": "https://github.com/symfony/console.git", 627 | "reference": "4fa15ae7be74e53f6ec8c83ed403b97e23b665e9" 628 | }, 629 | "dist": { 630 | "type": "zip", 631 | "url": "https://api.github.com/repos/symfony/console/zipball/4fa15ae7be74e53f6ec8c83ed403b97e23b665e9", 632 | "reference": "4fa15ae7be74e53f6ec8c83ed403b97e23b665e9", 633 | "shasum": "" 634 | }, 635 | "require": { 636 | "php": "^7.1.3", 637 | "symfony/polyfill-mbstring": "~1.0", 638 | "symfony/polyfill-php73": "^1.8", 639 | "symfony/service-contracts": "^1.1|^2" 640 | }, 641 | "conflict": { 642 | "symfony/dependency-injection": "<3.4", 643 | "symfony/event-dispatcher": "<4.3|>=5", 644 | "symfony/lock": "<4.4", 645 | "symfony/process": "<3.3" 646 | }, 647 | "provide": { 648 | "psr/log-implementation": "1.0" 649 | }, 650 | "require-dev": { 651 | "psr/log": "~1.0", 652 | "symfony/config": "^3.4|^4.0|^5.0", 653 | "symfony/dependency-injection": "^3.4|^4.0|^5.0", 654 | "symfony/event-dispatcher": "^4.3", 655 | "symfony/lock": "^4.4|^5.0", 656 | "symfony/process": "^3.4|^4.0|^5.0", 657 | "symfony/var-dumper": "^4.3|^5.0" 658 | }, 659 | "suggest": { 660 | "psr/log": "For using the console logger", 661 | "symfony/event-dispatcher": "", 662 | "symfony/lock": "", 663 | "symfony/process": "" 664 | }, 665 | "type": "library", 666 | "extra": { 667 | "branch-alias": { 668 | "dev-master": "4.4-dev" 669 | } 670 | }, 671 | "autoload": { 672 | "psr-4": { 673 | "Symfony\\Component\\Console\\": "" 674 | }, 675 | "exclude-from-classmap": [ 676 | "/Tests/" 677 | ] 678 | }, 679 | "notification-url": "https://packagist.org/downloads/", 680 | "license": [ 681 | "MIT" 682 | ], 683 | "authors": [ 684 | { 685 | "name": "Fabien Potencier", 686 | "email": "fabien@symfony.com" 687 | }, 688 | { 689 | "name": "Symfony Community", 690 | "homepage": "https://symfony.com/contributors" 691 | } 692 | ], 693 | "description": "Symfony Console Component", 694 | "homepage": "https://symfony.com", 695 | "time": "2020-02-24T13:10:00+00:00" 696 | }, 697 | { 698 | "name": "symfony/dependency-injection", 699 | "version": "v5.0.5", 700 | "source": { 701 | "type": "git", 702 | "url": "https://github.com/symfony/dependency-injection.git", 703 | "reference": "3575004a9b0d51ead83473ec90121045b3a0b56f" 704 | }, 705 | "dist": { 706 | "type": "zip", 707 | "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/3575004a9b0d51ead83473ec90121045b3a0b56f", 708 | "reference": "3575004a9b0d51ead83473ec90121045b3a0b56f", 709 | "shasum": "" 710 | }, 711 | "require": { 712 | "php": "^7.2.5", 713 | "psr/container": "^1.0", 714 | "symfony/service-contracts": "^1.1.6|^2" 715 | }, 716 | "conflict": { 717 | "symfony/config": "<5.0", 718 | "symfony/finder": "<4.4", 719 | "symfony/proxy-manager-bridge": "<4.4", 720 | "symfony/yaml": "<4.4" 721 | }, 722 | "provide": { 723 | "psr/container-implementation": "1.0", 724 | "symfony/service-implementation": "1.0" 725 | }, 726 | "require-dev": { 727 | "symfony/config": "^5.0", 728 | "symfony/expression-language": "^4.4|^5.0", 729 | "symfony/yaml": "^4.4|^5.0" 730 | }, 731 | "suggest": { 732 | "symfony/config": "", 733 | "symfony/expression-language": "For using expressions in service container configuration", 734 | "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", 735 | "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", 736 | "symfony/yaml": "" 737 | }, 738 | "type": "library", 739 | "extra": { 740 | "branch-alias": { 741 | "dev-master": "5.0-dev" 742 | } 743 | }, 744 | "autoload": { 745 | "psr-4": { 746 | "Symfony\\Component\\DependencyInjection\\": "" 747 | }, 748 | "exclude-from-classmap": [ 749 | "/Tests/" 750 | ] 751 | }, 752 | "notification-url": "https://packagist.org/downloads/", 753 | "license": [ 754 | "MIT" 755 | ], 756 | "authors": [ 757 | { 758 | "name": "Fabien Potencier", 759 | "email": "fabien@symfony.com" 760 | }, 761 | { 762 | "name": "Symfony Community", 763 | "homepage": "https://symfony.com/contributors" 764 | } 765 | ], 766 | "description": "Symfony DependencyInjection Component", 767 | "homepage": "https://symfony.com", 768 | "time": "2020-02-24T15:05:31+00:00" 769 | }, 770 | { 771 | "name": "symfony/filesystem", 772 | "version": "v5.0.5", 773 | "source": { 774 | "type": "git", 775 | "url": "https://github.com/symfony/filesystem.git", 776 | "reference": "3afadc0f57cd74f86379d073e694b0f2cda2a88c" 777 | }, 778 | "dist": { 779 | "type": "zip", 780 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/3afadc0f57cd74f86379d073e694b0f2cda2a88c", 781 | "reference": "3afadc0f57cd74f86379d073e694b0f2cda2a88c", 782 | "shasum": "" 783 | }, 784 | "require": { 785 | "php": "^7.2.5", 786 | "symfony/polyfill-ctype": "~1.8" 787 | }, 788 | "type": "library", 789 | "extra": { 790 | "branch-alias": { 791 | "dev-master": "5.0-dev" 792 | } 793 | }, 794 | "autoload": { 795 | "psr-4": { 796 | "Symfony\\Component\\Filesystem\\": "" 797 | }, 798 | "exclude-from-classmap": [ 799 | "/Tests/" 800 | ] 801 | }, 802 | "notification-url": "https://packagist.org/downloads/", 803 | "license": [ 804 | "MIT" 805 | ], 806 | "authors": [ 807 | { 808 | "name": "Fabien Potencier", 809 | "email": "fabien@symfony.com" 810 | }, 811 | { 812 | "name": "Symfony Community", 813 | "homepage": "https://symfony.com/contributors" 814 | } 815 | ], 816 | "description": "Symfony Filesystem Component", 817 | "homepage": "https://symfony.com", 818 | "time": "2020-01-21T08:40:24+00:00" 819 | }, 820 | { 821 | "name": "symfony/finder", 822 | "version": "v5.0.5", 823 | "source": { 824 | "type": "git", 825 | "url": "https://github.com/symfony/finder.git", 826 | "reference": "6251f201187ca9d66f6b099d3de65d279e971138" 827 | }, 828 | "dist": { 829 | "type": "zip", 830 | "url": "https://api.github.com/repos/symfony/finder/zipball/6251f201187ca9d66f6b099d3de65d279e971138", 831 | "reference": "6251f201187ca9d66f6b099d3de65d279e971138", 832 | "shasum": "" 833 | }, 834 | "require": { 835 | "php": "^7.2.5" 836 | }, 837 | "type": "library", 838 | "extra": { 839 | "branch-alias": { 840 | "dev-master": "5.0-dev" 841 | } 842 | }, 843 | "autoload": { 844 | "psr-4": { 845 | "Symfony\\Component\\Finder\\": "" 846 | }, 847 | "exclude-from-classmap": [ 848 | "/Tests/" 849 | ] 850 | }, 851 | "notification-url": "https://packagist.org/downloads/", 852 | "license": [ 853 | "MIT" 854 | ], 855 | "authors": [ 856 | { 857 | "name": "Fabien Potencier", 858 | "email": "fabien@symfony.com" 859 | }, 860 | { 861 | "name": "Symfony Community", 862 | "homepage": "https://symfony.com/contributors" 863 | } 864 | ], 865 | "description": "Symfony Finder Component", 866 | "homepage": "https://symfony.com", 867 | "time": "2020-02-14T07:43:07+00:00" 868 | }, 869 | { 870 | "name": "symfony/phpunit-bridge", 871 | "version": "v4.4.5", 872 | "source": { 873 | "type": "git", 874 | "url": "https://github.com/symfony/phpunit-bridge.git", 875 | "reference": "a270dbfe54994138a8037937fd5934827b8605bf" 876 | }, 877 | "dist": { 878 | "type": "zip", 879 | "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/a270dbfe54994138a8037937fd5934827b8605bf", 880 | "reference": "a270dbfe54994138a8037937fd5934827b8605bf", 881 | "shasum": "" 882 | }, 883 | "require": { 884 | "php": ">=5.5.9" 885 | }, 886 | "conflict": { 887 | "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0" 888 | }, 889 | "suggest": { 890 | "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" 891 | }, 892 | "bin": [ 893 | "bin/simple-phpunit" 894 | ], 895 | "type": "symfony-bridge", 896 | "extra": { 897 | "branch-alias": { 898 | "dev-master": "4.4-dev" 899 | }, 900 | "thanks": { 901 | "name": "phpunit/phpunit", 902 | "url": "https://github.com/sebastianbergmann/phpunit" 903 | } 904 | }, 905 | "autoload": { 906 | "files": [ 907 | "bootstrap.php" 908 | ], 909 | "psr-4": { 910 | "Symfony\\Bridge\\PhpUnit\\": "" 911 | }, 912 | "exclude-from-classmap": [ 913 | "/Tests/" 914 | ] 915 | }, 916 | "notification-url": "https://packagist.org/downloads/", 917 | "license": [ 918 | "MIT" 919 | ], 920 | "authors": [ 921 | { 922 | "name": "Nicolas Grekas", 923 | "email": "p@tchwork.com" 924 | }, 925 | { 926 | "name": "Symfony Community", 927 | "homepage": "https://symfony.com/contributors" 928 | } 929 | ], 930 | "description": "Symfony PHPUnit Bridge", 931 | "homepage": "https://symfony.com", 932 | "time": "2020-02-24T14:58:55+00:00" 933 | }, 934 | { 935 | "name": "symfony/polyfill-ctype", 936 | "version": "v1.14.0", 937 | "source": { 938 | "type": "git", 939 | "url": "https://github.com/symfony/polyfill-ctype.git", 940 | "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38" 941 | }, 942 | "dist": { 943 | "type": "zip", 944 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/fbdeaec0df06cf3d51c93de80c7eb76e271f5a38", 945 | "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38", 946 | "shasum": "" 947 | }, 948 | "require": { 949 | "php": ">=5.3.3" 950 | }, 951 | "suggest": { 952 | "ext-ctype": "For best performance" 953 | }, 954 | "type": "library", 955 | "extra": { 956 | "branch-alias": { 957 | "dev-master": "1.14-dev" 958 | } 959 | }, 960 | "autoload": { 961 | "psr-4": { 962 | "Symfony\\Polyfill\\Ctype\\": "" 963 | }, 964 | "files": [ 965 | "bootstrap.php" 966 | ] 967 | }, 968 | "notification-url": "https://packagist.org/downloads/", 969 | "license": [ 970 | "MIT" 971 | ], 972 | "authors": [ 973 | { 974 | "name": "Gert de Pagter", 975 | "email": "BackEndTea@gmail.com" 976 | }, 977 | { 978 | "name": "Symfony Community", 979 | "homepage": "https://symfony.com/contributors" 980 | } 981 | ], 982 | "description": "Symfony polyfill for ctype functions", 983 | "homepage": "https://symfony.com", 984 | "keywords": [ 985 | "compatibility", 986 | "ctype", 987 | "polyfill", 988 | "portable" 989 | ], 990 | "time": "2020-01-13T11:15:53+00:00" 991 | }, 992 | { 993 | "name": "symfony/polyfill-mbstring", 994 | "version": "v1.14.0", 995 | "source": { 996 | "type": "git", 997 | "url": "https://github.com/symfony/polyfill-mbstring.git", 998 | "reference": "34094cfa9abe1f0f14f48f490772db7a775559f2" 999 | }, 1000 | "dist": { 1001 | "type": "zip", 1002 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/34094cfa9abe1f0f14f48f490772db7a775559f2", 1003 | "reference": "34094cfa9abe1f0f14f48f490772db7a775559f2", 1004 | "shasum": "" 1005 | }, 1006 | "require": { 1007 | "php": ">=5.3.3" 1008 | }, 1009 | "suggest": { 1010 | "ext-mbstring": "For best performance" 1011 | }, 1012 | "type": "library", 1013 | "extra": { 1014 | "branch-alias": { 1015 | "dev-master": "1.14-dev" 1016 | } 1017 | }, 1018 | "autoload": { 1019 | "psr-4": { 1020 | "Symfony\\Polyfill\\Mbstring\\": "" 1021 | }, 1022 | "files": [ 1023 | "bootstrap.php" 1024 | ] 1025 | }, 1026 | "notification-url": "https://packagist.org/downloads/", 1027 | "license": [ 1028 | "MIT" 1029 | ], 1030 | "authors": [ 1031 | { 1032 | "name": "Nicolas Grekas", 1033 | "email": "p@tchwork.com" 1034 | }, 1035 | { 1036 | "name": "Symfony Community", 1037 | "homepage": "https://symfony.com/contributors" 1038 | } 1039 | ], 1040 | "description": "Symfony polyfill for the Mbstring extension", 1041 | "homepage": "https://symfony.com", 1042 | "keywords": [ 1043 | "compatibility", 1044 | "mbstring", 1045 | "polyfill", 1046 | "portable", 1047 | "shim" 1048 | ], 1049 | "time": "2020-01-13T11:15:53+00:00" 1050 | }, 1051 | { 1052 | "name": "symfony/polyfill-php73", 1053 | "version": "v1.14.0", 1054 | "source": { 1055 | "type": "git", 1056 | "url": "https://github.com/symfony/polyfill-php73.git", 1057 | "reference": "5e66a0fa1070bf46bec4bea7962d285108edd675" 1058 | }, 1059 | "dist": { 1060 | "type": "zip", 1061 | "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/5e66a0fa1070bf46bec4bea7962d285108edd675", 1062 | "reference": "5e66a0fa1070bf46bec4bea7962d285108edd675", 1063 | "shasum": "" 1064 | }, 1065 | "require": { 1066 | "php": ">=5.3.3" 1067 | }, 1068 | "type": "library", 1069 | "extra": { 1070 | "branch-alias": { 1071 | "dev-master": "1.14-dev" 1072 | } 1073 | }, 1074 | "autoload": { 1075 | "psr-4": { 1076 | "Symfony\\Polyfill\\Php73\\": "" 1077 | }, 1078 | "files": [ 1079 | "bootstrap.php" 1080 | ], 1081 | "classmap": [ 1082 | "Resources/stubs" 1083 | ] 1084 | }, 1085 | "notification-url": "https://packagist.org/downloads/", 1086 | "license": [ 1087 | "MIT" 1088 | ], 1089 | "authors": [ 1090 | { 1091 | "name": "Nicolas Grekas", 1092 | "email": "p@tchwork.com" 1093 | }, 1094 | { 1095 | "name": "Symfony Community", 1096 | "homepage": "https://symfony.com/contributors" 1097 | } 1098 | ], 1099 | "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", 1100 | "homepage": "https://symfony.com", 1101 | "keywords": [ 1102 | "compatibility", 1103 | "polyfill", 1104 | "portable", 1105 | "shim" 1106 | ], 1107 | "time": "2020-01-13T11:15:53+00:00" 1108 | }, 1109 | { 1110 | "name": "symfony/service-contracts", 1111 | "version": "v2.0.1", 1112 | "source": { 1113 | "type": "git", 1114 | "url": "https://github.com/symfony/service-contracts.git", 1115 | "reference": "144c5e51266b281231e947b51223ba14acf1a749" 1116 | }, 1117 | "dist": { 1118 | "type": "zip", 1119 | "url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749", 1120 | "reference": "144c5e51266b281231e947b51223ba14acf1a749", 1121 | "shasum": "" 1122 | }, 1123 | "require": { 1124 | "php": "^7.2.5", 1125 | "psr/container": "^1.0" 1126 | }, 1127 | "suggest": { 1128 | "symfony/service-implementation": "" 1129 | }, 1130 | "type": "library", 1131 | "extra": { 1132 | "branch-alias": { 1133 | "dev-master": "2.0-dev" 1134 | } 1135 | }, 1136 | "autoload": { 1137 | "psr-4": { 1138 | "Symfony\\Contracts\\Service\\": "" 1139 | } 1140 | }, 1141 | "notification-url": "https://packagist.org/downloads/", 1142 | "license": [ 1143 | "MIT" 1144 | ], 1145 | "authors": [ 1146 | { 1147 | "name": "Nicolas Grekas", 1148 | "email": "p@tchwork.com" 1149 | }, 1150 | { 1151 | "name": "Symfony Community", 1152 | "homepage": "https://symfony.com/contributors" 1153 | } 1154 | ], 1155 | "description": "Generic abstractions related to writing services", 1156 | "homepage": "https://symfony.com", 1157 | "keywords": [ 1158 | "abstractions", 1159 | "contracts", 1160 | "decoupling", 1161 | "interfaces", 1162 | "interoperability", 1163 | "standards" 1164 | ], 1165 | "time": "2019-11-18T17:27:11+00:00" 1166 | }, 1167 | { 1168 | "name": "theseer/fdomdocument", 1169 | "version": "1.6.6", 1170 | "source": { 1171 | "type": "git", 1172 | "url": "https://github.com/theseer/fDOMDocument.git", 1173 | "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca" 1174 | }, 1175 | "dist": { 1176 | "type": "zip", 1177 | "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/6e8203e40a32a9c770bcb62fe37e68b948da6dca", 1178 | "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca", 1179 | "shasum": "" 1180 | }, 1181 | "require": { 1182 | "ext-dom": "*", 1183 | "lib-libxml": "*", 1184 | "php": ">=5.3.3" 1185 | }, 1186 | "type": "library", 1187 | "autoload": { 1188 | "classmap": [ 1189 | "src/" 1190 | ] 1191 | }, 1192 | "notification-url": "https://packagist.org/downloads/", 1193 | "license": [ 1194 | "BSD-3-Clause" 1195 | ], 1196 | "authors": [ 1197 | { 1198 | "name": "Arne Blankerts", 1199 | "email": "arne@blankerts.de", 1200 | "role": "lead" 1201 | } 1202 | ], 1203 | "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", 1204 | "homepage": "https://github.com/theseer/fDOMDocument", 1205 | "time": "2017-06-30T11:53:12+00:00" 1206 | } 1207 | ], 1208 | "aliases": [], 1209 | "minimum-stability": "stable", 1210 | "stability-flags": [], 1211 | "prefer-stable": false, 1212 | "prefer-lowest": false, 1213 | "platform": { 1214 | "php": "^7.1.3" 1215 | }, 1216 | "platform-dev": [] 1217 | } 1218 | -------------------------------------------------------------------------------- /data/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 150, 3 | "employer": null, 4 | "balance": 0.5001, 5 | "first_name": "John", 6 | "last_name": "Doe", 7 | "enabled": false, 8 | "address": { 9 | "street": "124 Baker St", 10 | "aptSuite": "100", 11 | "city": "Dallas", 12 | "state": "TX", 13 | "postalCode": "75204", 14 | "country": { 15 | "code": "US", 16 | "name": "United States", 17 | "planet": { 18 | "name": "Earth", 19 | "galaxy": "Milky Way" 20 | } 21 | } 22 | }, 23 | "income": { 24 | "netMonthly": 1000 25 | }, 26 | "pets": [ 27 | { 28 | "name": "Fido", 29 | "type": "Dog" 30 | }, { 31 | "name": "Winkles", 32 | "type": "Cat" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | JSON to PHP Class Models 7 | 83 | 133 | 134 | 135 | 136 |
137 |
138 |

JSON to PHP Class Converter

139 |

Generate PSR-2 compliant PHP model classes from JSON.

140 |
141 | 158 | 159 | 160 |
161 |
162 |
163 | 164 | 165 |
166 |
167 | 168 | 169 |
170 |
171 | 172 | 173 |
174 |
175 | 176 | 177 |
178 |
179 | 180 | 181 |
182 |
183 |
184 |

Output

185 | 186 |
187 | 188 | 189 |
190 |
191 |
192 |
193 | 194 | 195 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | fromJson($className, $json); 16 | 17 | if ($_POST['download']) { 18 | $zipArchive = new ZipArchive(); 19 | $filename = 'models.zip'; 20 | if (true !== $zipArchive->open('models.zip', ZipArchive::CREATE)) { 21 | // handle error 22 | return; 23 | } 24 | foreach ($classes as $key => $value) { 25 | $zipArchive->addFromString($key . '.php', $value); 26 | } 27 | 28 | $zipArchive->close(); 29 | 30 | header('Content-type: application/zip'); 31 | header("Content-Disposition: attachment; filename=$filename"); 32 | header('Content-length: ' . filesize('models.zip')); 33 | header('Pragma: no-cache'); 34 | header('Expires: 0'); 35 | readfile($filename); 36 | unlink($filename); 37 | exit; 38 | } 39 | 40 | $generatedPhp = $generator->printClasses(); 41 | } 42 | 43 | function validate() { 44 | if (empty($_POST['classname'])) { 45 | return 'Class name is required'; 46 | } 47 | $json = $_POST['json']; 48 | $jsonDecoded = json_decode($json); 49 | if (null === $jsonDecoded) { 50 | return 'Invalid JSON'; 51 | } 52 | 53 | return true; 54 | } 55 | 56 | ?> 57 | 58 | 59 | 60 | 61 | 67 | 68 | 69 | JSON to PHP Class Models 70 | 153 | 207 | 208 | 209 | 210 |
211 |
212 |

JSON to PHP Class Converter

213 |

Generate PSR-2 compliant PHP model classes from JSON.

214 |
215 | 216 | 233 | 234 | 237 | 238 | 239 | 240 |
241 |
242 |
243 | 244 | 245 | 246 | 247 | 248 | 249 |
250 |
251 | 252 | 253 | 254 | 255 | 256 | 257 |
258 |
259 | 260 | 261 | 262 | 263 | 264 | 265 |
266 |
267 | 268 | 269 | 270 | 271 | 272 | 273 |
274 |
275 | 276 | 277 | 278 | 279 | 280 | 281 |
282 |
283 | 284 |
285 |

Output

286 | 289 |
290 | 291 |
292 |
293 | 294 |
295 |
296 |

©

297 |
298 |
299 | 300 | 301 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | tests/ 16 | 17 | 18 | 19 | 20 | 21 | ./src/ 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/ClassFactory.php: -------------------------------------------------------------------------------- 1 | useTypeHinting = $useTypeHinting; 32 | $this->useFluentSetters = $useFluentSetters; 33 | $this->namespace = $namespace; 34 | } 35 | 36 | /** 37 | * @param string $className 38 | * @param \stdClass $obj 39 | * @param array $objects 40 | * 41 | * @return array 42 | */ 43 | public function create(string $className, \stdClass $obj, array $objects = []): array 44 | { 45 | $newClass = new ClassPrototype($className, $this->useTypeHinting, $this->useFluentSetters, $this->namespace); 46 | 47 | foreach ($obj as $key => $value) { 48 | if (is_object($value)) { 49 | $subClassName = StringUtil::snakeKebabToCamelCase($key); 50 | $newClass->addMethod($key, $subClassName); 51 | $objects = $this->create($subClassName, $value, $objects); 52 | } elseif (is_array($value)) { 53 | $newClass->addMethod($key, gettype($value)); 54 | if (!empty($value) && is_object($value[0])) { 55 | $subClassName = StringUtil::snakeKebabToCamelCase($key); 56 | $objects = $this->create($subClassName, $value[0], $objects); 57 | } 58 | } else { 59 | $newClass->addMethod($key, gettype($value)); 60 | } 61 | } 62 | 63 | $objects[$className] = $newClass; 64 | 65 | return $objects; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/ClassFactoryInterface.php: -------------------------------------------------------------------------------- 1 | className = $className; 47 | $this->useTypeHinting = $useTypeHinting; 48 | $this->useFluentSetters = $useFluentSetters; 49 | $this->namespace = $namespace; 50 | } 51 | 52 | /** 53 | * {@inheritDoc} 54 | */ 55 | public function getClassName(): string 56 | { 57 | return $this->className; 58 | } 59 | 60 | /** 61 | * {@inheritDoc} 62 | */ 63 | public function addMethod(string $methodName, string $dataType): void 64 | { 65 | if (!$this->hasMethod($methodName)) { 66 | $this->methods[] = [ 67 | 'methodName' => $methodName, 68 | 'dataType' => $dataType 69 | ]; 70 | } 71 | } 72 | 73 | /** 74 | * {@inheritDoc} 75 | */ 76 | public function hasMethod(string $methodName): bool 77 | { 78 | foreach ($this->methods as $method) { 79 | if ($method['methodName'] === $methodName) { 80 | return true; 81 | } 82 | } 83 | 84 | return false; 85 | } 86 | 87 | /** 88 | * {@inheritDoc} 89 | */ 90 | public function printProperty(array $method): string 91 | { 92 | $propertyName = lcfirst(StringUtil::snakeKebabToCamelCase($method['methodName'])); 93 | $dataType = $this->getDataType($method['dataType']); 94 | return <<getDataType($method['dataType']); 112 | $getterPrefix = $this->getGetterPrefix($method['dataType']); 113 | 114 | if ($this->useTypeHinting && $this->useFluentSetters) { 115 | return $this->printPhp7FluentSettersMethod($dataType, $getterPrefix, $methodName, $propertyName); 116 | } elseif ($this->useTypeHinting && !$this->useFluentSetters) { 117 | return $this->printPhp7Method($dataType, $getterPrefix, $methodName, $propertyName); 118 | } elseif (!$this->useTypeHinting && $this->useFluentSetters) { 119 | return $this->printPhp5FluentSettersMethod($dataType, $getterPrefix, $methodName, $propertyName); 120 | } else { 121 | return $this->printPhp5Method($dataType, $getterPrefix, $methodName, $propertyName); 122 | } 123 | } 124 | 125 | /** 126 | * @param string $dataType 127 | * @param string $getterPrefix 128 | * @param string $methodName 129 | * @param string $propertyName 130 | * 131 | * @return string 132 | */ 133 | protected function printPhp7Method( 134 | string $dataType, 135 | string $getterPrefix, 136 | string $methodName, 137 | string $propertyName 138 | ): string { 139 | return <<$propertyName; 147 | } 148 | 149 | /** 150 | * @param $dataType|null \$$propertyName 151 | */ 152 | public function set$methodName(?$dataType \$$propertyName): void 153 | { 154 | \$this->$propertyName = \$$propertyName; 155 | } 156 | 157 | EOL; 158 | } 159 | 160 | /** 161 | * @param string $dataType 162 | * @param string $getterPrefix 163 | * @param string $methodName 164 | * @param string $propertyName 165 | * 166 | * @return string 167 | */ 168 | protected function printPhp7FluentSettersMethod( 169 | string $dataType, 170 | string $getterPrefix, 171 | string $methodName, 172 | string $propertyName 173 | ): string { 174 | return <<$propertyName; 182 | } 183 | 184 | /** 185 | * @param $dataType|null \$$propertyName 186 | * 187 | * @return $this->className 188 | */ 189 | public function set$methodName(?$dataType \$$propertyName): $this->className 190 | { 191 | \$this->$propertyName = \$$propertyName; 192 | 193 | return \$this; 194 | } 195 | 196 | EOL; 197 | } 198 | 199 | /** 200 | * @param string $dataType 201 | * @param string $getterPrefix 202 | * @param string $methodName 203 | * @param string $propertyName 204 | * 205 | * @return string 206 | */ 207 | protected function printPhp5Method( 208 | string $dataType, 209 | string $getterPrefix, 210 | string $methodName, 211 | string $propertyName 212 | ): string { 213 | return <<$propertyName; 221 | } 222 | 223 | /** 224 | * @param $dataType|null \$$propertyName 225 | */ 226 | public function set$methodName(\$$propertyName) 227 | { 228 | \$this->$propertyName = \$$propertyName; 229 | } 230 | 231 | EOL; 232 | } 233 | 234 | /** 235 | * @param string $dataType 236 | * @param string $getterPrefix 237 | * @param string $methodName 238 | * @param string $propertyName 239 | * 240 | * @return string 241 | */ 242 | protected function printPhp5FluentSettersMethod( 243 | string $dataType, 244 | string $getterPrefix, 245 | string $methodName, 246 | string $propertyName 247 | ): string { 248 | return <<$propertyName; 256 | } 257 | 258 | /** 259 | * @param $dataType|null \$$propertyName 260 | * 261 | * @return $this->className 262 | */ 263 | public function set$methodName(\$$propertyName) 264 | { 265 | \$this->$propertyName = \$$propertyName; 266 | 267 | return \$this; 268 | } 269 | 270 | EOL; 271 | } 272 | 273 | /** 274 | * {@inheritDoc} 275 | */ 276 | private function getDataType(string $dataType): string 277 | { 278 | switch ($dataType) { 279 | case 'integer': 280 | return 'int'; 281 | case 'boolean': 282 | return 'bool'; 283 | case 'double': 284 | return 'float'; 285 | case 'NULL': 286 | return 'string'; 287 | case 'Array': 288 | return 'array'; 289 | } 290 | 291 | return $dataType; 292 | } 293 | 294 | /** 295 | * Get getter prefix 296 | * 297 | * @param string $dataType 298 | * 299 | * @return string 300 | */ 301 | private function getGetterPrefix(string $dataType): string 302 | { 303 | return 'boolean' === $dataType ? 'is' : 'get'; 304 | } 305 | 306 | public function __toString() 307 | { 308 | $str = <<namespace) { 315 | $str .= <<namespace; 317 | 318 | 319 | EOL; 320 | } 321 | 322 | $str .= <<className 324 | { 325 | 326 | EOL 327 | ; 328 | foreach ($this->methods as $method) { 329 | $str .= $this->printProperty($method); 330 | } 331 | 332 | foreach ($this->methods as $method) { 333 | $str .= $this->printMethod($method); 334 | } 335 | 336 | $str .= << 14 | */ 15 | private $classes = []; 16 | 17 | /** 18 | * PhpGenerator constructor. 19 | * 20 | * @param bool $useTypeHinting 21 | * @param bool $useFluentSetters 22 | * @param string|null $namespace 23 | */ 24 | public function __construct( 25 | bool $useTypeHinting = true, 26 | bool $useFluentSetters = false, 27 | ?string $namespace = null 28 | ) { 29 | $this->factory = new ClassFactory($useTypeHinting, $useFluentSetters, $namespace); 30 | } 31 | 32 | /** 33 | * @param string $className 34 | * @param string $jsonStr 35 | * 36 | * @return array 37 | */ 38 | public function fromJson(string $className, string $jsonStr): array 39 | { 40 | $obj = json_decode($jsonStr, false); 41 | $this->classes = $this->factory->create($className, $obj); 42 | 43 | return $this->classes; 44 | } 45 | 46 | /** 47 | * Print output of classes into string 48 | * 49 | * @return string 50 | */ 51 | public function printClasses(): string 52 | { 53 | $str = ''; 54 | 55 | /** @var ClassPrototypeInterface $value */ 56 | foreach ($this->classes as $value) { 57 | $str .= $value; 58 | } 59 | 60 | return $str; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/StringUtil.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(PhpGenerator::class, $generator); 18 | 19 | /** @var array $classes */ 20 | $classes = $generator->fromJson($className, $jsonStr); 21 | $this->assertIsArray($classes); 22 | $count = count($classes); 23 | $this->assertEquals(6, $count); 24 | /** @var ClassPrototypeInterface $class */ 25 | foreach ($classes as $class) { 26 | switch ($class->getClassName()) { 27 | case 'Country': 28 | $this->assertTrue($class->hasMethod('code')); 29 | $this->assertTrue($class->hasMethod('name')); 30 | $this->assertTrue($class->hasMethod('planet')); 31 | break; 32 | case 'Planet': 33 | $this->assertTrue($class->hasMethod('name')); 34 | $this->assertTrue($class->hasMethod('galaxy')); 35 | break; 36 | case 'Income': 37 | $this->assertTrue($class->hasMethod('netMonthly')); 38 | break; 39 | case 'Pets': 40 | $this->assertTrue($class->hasMethod('name')); 41 | $this->assertTrue($class->hasMethod('type')); 42 | break; 43 | case 'Address': 44 | $this->assertTrue($class->hasMethod('street')); 45 | $this->assertTrue($class->hasMethod('aptSuite')); 46 | $this->assertTrue($class->hasMethod('city')); 47 | $this->assertTrue($class->hasMethod('state')); 48 | $this->assertTrue($class->hasMethod('postalCode')); 49 | $this->assertTrue($class->hasMethod('country')); 50 | break; 51 | case 'User': 52 | $this->assertTrue($class->hasMethod('id')); 53 | $this->assertTrue($class->hasMethod('employer')); 54 | $this->assertTrue($class->hasMethod('balance')); 55 | $this->assertTrue($class->hasMethod('first_name')); 56 | $this->assertTrue($class->hasMethod('last_name')); 57 | $this->assertTrue($class->hasMethod('enabled')); 58 | $this->assertTrue($class->hasMethod('address')); 59 | $this->assertTrue($class->hasMethod('income')); 60 | $this->assertTrue($class->hasMethod('pets')); 61 | break; 62 | } 63 | } 64 | } 65 | 66 | public function testPhp7TypeHintingFluentSettersOutput() 67 | { 68 | $jsonStr = file_get_contents(__DIR__ . '/../data/test.json'); 69 | $namespace = 'Acme\Demo'; 70 | $className = 'Test'; 71 | $generator = new PhpGenerator(true, true, $namespace); 72 | $generator->fromJson($className, $jsonStr); 73 | $output = $generator->printClasses(); 74 | $matchOutput = file_get_contents(__DIR__ . '/fixtures/sample-typehinting-fluent-setters.txt'); 75 | 76 | $this->assertSame($output, $matchOutput); 77 | } 78 | 79 | public function testPhp7TypeHintingOutput() 80 | { 81 | $jsonStr = file_get_contents(__DIR__ . '/../data/test.json'); 82 | $namespace = 'Acme\Demo'; 83 | $className = 'Test'; 84 | $generator = new PhpGenerator(true, false, $namespace); 85 | $generator->fromJson($className, $jsonStr); 86 | $output = $generator->printClasses(); 87 | $matchOutput = file_get_contents(__DIR__ . '/fixtures/sample-typehinting.txt'); 88 | 89 | $this->assertSame($output, $matchOutput); 90 | } 91 | 92 | public function testPhp5Output() 93 | { 94 | $jsonStr = file_get_contents(__DIR__ . '/../data/test.json'); 95 | $namespace = 'Acme\Demo'; 96 | $className = 'Test'; 97 | $generator = new PhpGenerator(false, false, $namespace); 98 | $generator->fromJson($className, $jsonStr); 99 | $output = $generator->printClasses(); 100 | $matchOutput = file_get_contents(__DIR__ . '/fixtures/sample.txt'); 101 | 102 | $this->assertSame($output, $matchOutput); 103 | } 104 | 105 | public function testPhp5FluentSettersOutput() 106 | { 107 | $jsonStr = file_get_contents(__DIR__ . '/../data/test.json'); 108 | $namespace = 'Acme\Demo'; 109 | $className = 'Test'; 110 | $generator = new PhpGenerator(false, true, $namespace); 111 | $generator->fromJson($className, $jsonStr); 112 | $output = $generator->printClasses(); 113 | $matchOutput = file_get_contents(__DIR__ . '/fixtures/sample-fluent-setters.txt'); 114 | 115 | $this->assertSame($output, $matchOutput); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/fixtures/sample-fluent-setters.txt: -------------------------------------------------------------------------------- 1 | name; 24 | } 25 | 26 | /** 27 | * @param string|null $name 28 | * 29 | * @return Planet 30 | */ 31 | public function setName($name) 32 | { 33 | $this->name = $name; 34 | 35 | return $this; 36 | } 37 | 38 | /** 39 | * @return string|null 40 | */ 41 | public function getGalaxy() 42 | { 43 | return $this->galaxy; 44 | } 45 | 46 | /** 47 | * @param string|null $galaxy 48 | * 49 | * @return Planet 50 | */ 51 | public function setGalaxy($galaxy) 52 | { 53 | $this->galaxy = $galaxy; 54 | 55 | return $this; 56 | } 57 | } 58 | 59 | code; 87 | } 88 | 89 | /** 90 | * @param string|null $code 91 | * 92 | * @return Country 93 | */ 94 | public function setCode($code) 95 | { 96 | $this->code = $code; 97 | 98 | return $this; 99 | } 100 | 101 | /** 102 | * @return string|null 103 | */ 104 | public function getName() 105 | { 106 | return $this->name; 107 | } 108 | 109 | /** 110 | * @param string|null $name 111 | * 112 | * @return Country 113 | */ 114 | public function setName($name) 115 | { 116 | $this->name = $name; 117 | 118 | return $this; 119 | } 120 | 121 | /** 122 | * @return Planet|null 123 | */ 124 | public function getPlanet() 125 | { 126 | return $this->planet; 127 | } 128 | 129 | /** 130 | * @param Planet|null $planet 131 | * 132 | * @return Country 133 | */ 134 | public function setPlanet($planet) 135 | { 136 | $this->planet = $planet; 137 | 138 | return $this; 139 | } 140 | } 141 | 142 | street; 185 | } 186 | 187 | /** 188 | * @param string|null $street 189 | * 190 | * @return Address 191 | */ 192 | public function setStreet($street) 193 | { 194 | $this->street = $street; 195 | 196 | return $this; 197 | } 198 | 199 | /** 200 | * @return string|null 201 | */ 202 | public function getAptSuite() 203 | { 204 | return $this->aptSuite; 205 | } 206 | 207 | /** 208 | * @param string|null $aptSuite 209 | * 210 | * @return Address 211 | */ 212 | public function setAptSuite($aptSuite) 213 | { 214 | $this->aptSuite = $aptSuite; 215 | 216 | return $this; 217 | } 218 | 219 | /** 220 | * @return string|null 221 | */ 222 | public function getCity() 223 | { 224 | return $this->city; 225 | } 226 | 227 | /** 228 | * @param string|null $city 229 | * 230 | * @return Address 231 | */ 232 | public function setCity($city) 233 | { 234 | $this->city = $city; 235 | 236 | return $this; 237 | } 238 | 239 | /** 240 | * @return string|null 241 | */ 242 | public function getState() 243 | { 244 | return $this->state; 245 | } 246 | 247 | /** 248 | * @param string|null $state 249 | * 250 | * @return Address 251 | */ 252 | public function setState($state) 253 | { 254 | $this->state = $state; 255 | 256 | return $this; 257 | } 258 | 259 | /** 260 | * @return string|null 261 | */ 262 | public function getPostalCode() 263 | { 264 | return $this->postalCode; 265 | } 266 | 267 | /** 268 | * @param string|null $postalCode 269 | * 270 | * @return Address 271 | */ 272 | public function setPostalCode($postalCode) 273 | { 274 | $this->postalCode = $postalCode; 275 | 276 | return $this; 277 | } 278 | 279 | /** 280 | * @return Country|null 281 | */ 282 | public function getCountry() 283 | { 284 | return $this->country; 285 | } 286 | 287 | /** 288 | * @param Country|null $country 289 | * 290 | * @return Address 291 | */ 292 | public function setCountry($country) 293 | { 294 | $this->country = $country; 295 | 296 | return $this; 297 | } 298 | } 299 | 300 | netMonthly; 318 | } 319 | 320 | /** 321 | * @param int|null $netMonthly 322 | * 323 | * @return Income 324 | */ 325 | public function setNetMonthly($netMonthly) 326 | { 327 | $this->netMonthly = $netMonthly; 328 | 329 | return $this; 330 | } 331 | } 332 | 333 | name; 356 | } 357 | 358 | /** 359 | * @param string|null $name 360 | * 361 | * @return Pets 362 | */ 363 | public function setName($name) 364 | { 365 | $this->name = $name; 366 | 367 | return $this; 368 | } 369 | 370 | /** 371 | * @return string|null 372 | */ 373 | public function getType() 374 | { 375 | return $this->type; 376 | } 377 | 378 | /** 379 | * @param string|null $type 380 | * 381 | * @return Pets 382 | */ 383 | public function setType($type) 384 | { 385 | $this->type = $type; 386 | 387 | return $this; 388 | } 389 | } 390 | 391 | id; 449 | } 450 | 451 | /** 452 | * @param int|null $id 453 | * 454 | * @return Test 455 | */ 456 | public function setId($id) 457 | { 458 | $this->id = $id; 459 | 460 | return $this; 461 | } 462 | 463 | /** 464 | * @return string|null 465 | */ 466 | public function getEmployer() 467 | { 468 | return $this->employer; 469 | } 470 | 471 | /** 472 | * @param string|null $employer 473 | * 474 | * @return Test 475 | */ 476 | public function setEmployer($employer) 477 | { 478 | $this->employer = $employer; 479 | 480 | return $this; 481 | } 482 | 483 | /** 484 | * @return float|null 485 | */ 486 | public function getBalance() 487 | { 488 | return $this->balance; 489 | } 490 | 491 | /** 492 | * @param float|null $balance 493 | * 494 | * @return Test 495 | */ 496 | public function setBalance($balance) 497 | { 498 | $this->balance = $balance; 499 | 500 | return $this; 501 | } 502 | 503 | /** 504 | * @return string|null 505 | */ 506 | public function getFirstName() 507 | { 508 | return $this->firstName; 509 | } 510 | 511 | /** 512 | * @param string|null $firstName 513 | * 514 | * @return Test 515 | */ 516 | public function setFirstName($firstName) 517 | { 518 | $this->firstName = $firstName; 519 | 520 | return $this; 521 | } 522 | 523 | /** 524 | * @return string|null 525 | */ 526 | public function getLastName() 527 | { 528 | return $this->lastName; 529 | } 530 | 531 | /** 532 | * @param string|null $lastName 533 | * 534 | * @return Test 535 | */ 536 | public function setLastName($lastName) 537 | { 538 | $this->lastName = $lastName; 539 | 540 | return $this; 541 | } 542 | 543 | /** 544 | * @return bool|null 545 | */ 546 | public function isEnabled() 547 | { 548 | return $this->enabled; 549 | } 550 | 551 | /** 552 | * @param bool|null $enabled 553 | * 554 | * @return Test 555 | */ 556 | public function setEnabled($enabled) 557 | { 558 | $this->enabled = $enabled; 559 | 560 | return $this; 561 | } 562 | 563 | /** 564 | * @return Address|null 565 | */ 566 | public function getAddress() 567 | { 568 | return $this->address; 569 | } 570 | 571 | /** 572 | * @param Address|null $address 573 | * 574 | * @return Test 575 | */ 576 | public function setAddress($address) 577 | { 578 | $this->address = $address; 579 | 580 | return $this; 581 | } 582 | 583 | /** 584 | * @return Income|null 585 | */ 586 | public function getIncome() 587 | { 588 | return $this->income; 589 | } 590 | 591 | /** 592 | * @param Income|null $income 593 | * 594 | * @return Test 595 | */ 596 | public function setIncome($income) 597 | { 598 | $this->income = $income; 599 | 600 | return $this; 601 | } 602 | 603 | /** 604 | * @return array|null 605 | */ 606 | public function getPets() 607 | { 608 | return $this->pets; 609 | } 610 | 611 | /** 612 | * @param array|null $pets 613 | * 614 | * @return Test 615 | */ 616 | public function setPets($pets) 617 | { 618 | $this->pets = $pets; 619 | 620 | return $this; 621 | } 622 | } 623 | 624 | -------------------------------------------------------------------------------- /tests/fixtures/sample-typehinting-fluent-setters.txt: -------------------------------------------------------------------------------- 1 | name; 24 | } 25 | 26 | /** 27 | * @param string|null $name 28 | * 29 | * @return Planet 30 | */ 31 | public function setName(?string $name): Planet 32 | { 33 | $this->name = $name; 34 | 35 | return $this; 36 | } 37 | 38 | /** 39 | * @return string|null 40 | */ 41 | public function getGalaxy(): ?string 42 | { 43 | return $this->galaxy; 44 | } 45 | 46 | /** 47 | * @param string|null $galaxy 48 | * 49 | * @return Planet 50 | */ 51 | public function setGalaxy(?string $galaxy): Planet 52 | { 53 | $this->galaxy = $galaxy; 54 | 55 | return $this; 56 | } 57 | } 58 | 59 | code; 87 | } 88 | 89 | /** 90 | * @param string|null $code 91 | * 92 | * @return Country 93 | */ 94 | public function setCode(?string $code): Country 95 | { 96 | $this->code = $code; 97 | 98 | return $this; 99 | } 100 | 101 | /** 102 | * @return string|null 103 | */ 104 | public function getName(): ?string 105 | { 106 | return $this->name; 107 | } 108 | 109 | /** 110 | * @param string|null $name 111 | * 112 | * @return Country 113 | */ 114 | public function setName(?string $name): Country 115 | { 116 | $this->name = $name; 117 | 118 | return $this; 119 | } 120 | 121 | /** 122 | * @return Planet|null 123 | */ 124 | public function getPlanet(): ?Planet 125 | { 126 | return $this->planet; 127 | } 128 | 129 | /** 130 | * @param Planet|null $planet 131 | * 132 | * @return Country 133 | */ 134 | public function setPlanet(?Planet $planet): Country 135 | { 136 | $this->planet = $planet; 137 | 138 | return $this; 139 | } 140 | } 141 | 142 | street; 185 | } 186 | 187 | /** 188 | * @param string|null $street 189 | * 190 | * @return Address 191 | */ 192 | public function setStreet(?string $street): Address 193 | { 194 | $this->street = $street; 195 | 196 | return $this; 197 | } 198 | 199 | /** 200 | * @return string|null 201 | */ 202 | public function getAptSuite(): ?string 203 | { 204 | return $this->aptSuite; 205 | } 206 | 207 | /** 208 | * @param string|null $aptSuite 209 | * 210 | * @return Address 211 | */ 212 | public function setAptSuite(?string $aptSuite): Address 213 | { 214 | $this->aptSuite = $aptSuite; 215 | 216 | return $this; 217 | } 218 | 219 | /** 220 | * @return string|null 221 | */ 222 | public function getCity(): ?string 223 | { 224 | return $this->city; 225 | } 226 | 227 | /** 228 | * @param string|null $city 229 | * 230 | * @return Address 231 | */ 232 | public function setCity(?string $city): Address 233 | { 234 | $this->city = $city; 235 | 236 | return $this; 237 | } 238 | 239 | /** 240 | * @return string|null 241 | */ 242 | public function getState(): ?string 243 | { 244 | return $this->state; 245 | } 246 | 247 | /** 248 | * @param string|null $state 249 | * 250 | * @return Address 251 | */ 252 | public function setState(?string $state): Address 253 | { 254 | $this->state = $state; 255 | 256 | return $this; 257 | } 258 | 259 | /** 260 | * @return string|null 261 | */ 262 | public function getPostalCode(): ?string 263 | { 264 | return $this->postalCode; 265 | } 266 | 267 | /** 268 | * @param string|null $postalCode 269 | * 270 | * @return Address 271 | */ 272 | public function setPostalCode(?string $postalCode): Address 273 | { 274 | $this->postalCode = $postalCode; 275 | 276 | return $this; 277 | } 278 | 279 | /** 280 | * @return Country|null 281 | */ 282 | public function getCountry(): ?Country 283 | { 284 | return $this->country; 285 | } 286 | 287 | /** 288 | * @param Country|null $country 289 | * 290 | * @return Address 291 | */ 292 | public function setCountry(?Country $country): Address 293 | { 294 | $this->country = $country; 295 | 296 | return $this; 297 | } 298 | } 299 | 300 | netMonthly; 318 | } 319 | 320 | /** 321 | * @param int|null $netMonthly 322 | * 323 | * @return Income 324 | */ 325 | public function setNetMonthly(?int $netMonthly): Income 326 | { 327 | $this->netMonthly = $netMonthly; 328 | 329 | return $this; 330 | } 331 | } 332 | 333 | name; 356 | } 357 | 358 | /** 359 | * @param string|null $name 360 | * 361 | * @return Pets 362 | */ 363 | public function setName(?string $name): Pets 364 | { 365 | $this->name = $name; 366 | 367 | return $this; 368 | } 369 | 370 | /** 371 | * @return string|null 372 | */ 373 | public function getType(): ?string 374 | { 375 | return $this->type; 376 | } 377 | 378 | /** 379 | * @param string|null $type 380 | * 381 | * @return Pets 382 | */ 383 | public function setType(?string $type): Pets 384 | { 385 | $this->type = $type; 386 | 387 | return $this; 388 | } 389 | } 390 | 391 | id; 449 | } 450 | 451 | /** 452 | * @param int|null $id 453 | * 454 | * @return Test 455 | */ 456 | public function setId(?int $id): Test 457 | { 458 | $this->id = $id; 459 | 460 | return $this; 461 | } 462 | 463 | /** 464 | * @return string|null 465 | */ 466 | public function getEmployer(): ?string 467 | { 468 | return $this->employer; 469 | } 470 | 471 | /** 472 | * @param string|null $employer 473 | * 474 | * @return Test 475 | */ 476 | public function setEmployer(?string $employer): Test 477 | { 478 | $this->employer = $employer; 479 | 480 | return $this; 481 | } 482 | 483 | /** 484 | * @return float|null 485 | */ 486 | public function getBalance(): ?float 487 | { 488 | return $this->balance; 489 | } 490 | 491 | /** 492 | * @param float|null $balance 493 | * 494 | * @return Test 495 | */ 496 | public function setBalance(?float $balance): Test 497 | { 498 | $this->balance = $balance; 499 | 500 | return $this; 501 | } 502 | 503 | /** 504 | * @return string|null 505 | */ 506 | public function getFirstName(): ?string 507 | { 508 | return $this->firstName; 509 | } 510 | 511 | /** 512 | * @param string|null $firstName 513 | * 514 | * @return Test 515 | */ 516 | public function setFirstName(?string $firstName): Test 517 | { 518 | $this->firstName = $firstName; 519 | 520 | return $this; 521 | } 522 | 523 | /** 524 | * @return string|null 525 | */ 526 | public function getLastName(): ?string 527 | { 528 | return $this->lastName; 529 | } 530 | 531 | /** 532 | * @param string|null $lastName 533 | * 534 | * @return Test 535 | */ 536 | public function setLastName(?string $lastName): Test 537 | { 538 | $this->lastName = $lastName; 539 | 540 | return $this; 541 | } 542 | 543 | /** 544 | * @return bool|null 545 | */ 546 | public function isEnabled(): ?bool 547 | { 548 | return $this->enabled; 549 | } 550 | 551 | /** 552 | * @param bool|null $enabled 553 | * 554 | * @return Test 555 | */ 556 | public function setEnabled(?bool $enabled): Test 557 | { 558 | $this->enabled = $enabled; 559 | 560 | return $this; 561 | } 562 | 563 | /** 564 | * @return Address|null 565 | */ 566 | public function getAddress(): ?Address 567 | { 568 | return $this->address; 569 | } 570 | 571 | /** 572 | * @param Address|null $address 573 | * 574 | * @return Test 575 | */ 576 | public function setAddress(?Address $address): Test 577 | { 578 | $this->address = $address; 579 | 580 | return $this; 581 | } 582 | 583 | /** 584 | * @return Income|null 585 | */ 586 | public function getIncome(): ?Income 587 | { 588 | return $this->income; 589 | } 590 | 591 | /** 592 | * @param Income|null $income 593 | * 594 | * @return Test 595 | */ 596 | public function setIncome(?Income $income): Test 597 | { 598 | $this->income = $income; 599 | 600 | return $this; 601 | } 602 | 603 | /** 604 | * @return array|null 605 | */ 606 | public function getPets(): ?array 607 | { 608 | return $this->pets; 609 | } 610 | 611 | /** 612 | * @param array|null $pets 613 | * 614 | * @return Test 615 | */ 616 | public function setPets(?array $pets): Test 617 | { 618 | $this->pets = $pets; 619 | 620 | return $this; 621 | } 622 | } 623 | 624 | -------------------------------------------------------------------------------- /tests/fixtures/sample-typehinting.txt: -------------------------------------------------------------------------------- 1 | name; 24 | } 25 | 26 | /** 27 | * @param string|null $name 28 | */ 29 | public function setName(?string $name): void 30 | { 31 | $this->name = $name; 32 | } 33 | 34 | /** 35 | * @return string|null 36 | */ 37 | public function getGalaxy(): ?string 38 | { 39 | return $this->galaxy; 40 | } 41 | 42 | /** 43 | * @param string|null $galaxy 44 | */ 45 | public function setGalaxy(?string $galaxy): void 46 | { 47 | $this->galaxy = $galaxy; 48 | } 49 | } 50 | 51 | code; 79 | } 80 | 81 | /** 82 | * @param string|null $code 83 | */ 84 | public function setCode(?string $code): void 85 | { 86 | $this->code = $code; 87 | } 88 | 89 | /** 90 | * @return string|null 91 | */ 92 | public function getName(): ?string 93 | { 94 | return $this->name; 95 | } 96 | 97 | /** 98 | * @param string|null $name 99 | */ 100 | public function setName(?string $name): void 101 | { 102 | $this->name = $name; 103 | } 104 | 105 | /** 106 | * @return Planet|null 107 | */ 108 | public function getPlanet(): ?Planet 109 | { 110 | return $this->planet; 111 | } 112 | 113 | /** 114 | * @param Planet|null $planet 115 | */ 116 | public function setPlanet(?Planet $planet): void 117 | { 118 | $this->planet = $planet; 119 | } 120 | } 121 | 122 | street; 165 | } 166 | 167 | /** 168 | * @param string|null $street 169 | */ 170 | public function setStreet(?string $street): void 171 | { 172 | $this->street = $street; 173 | } 174 | 175 | /** 176 | * @return string|null 177 | */ 178 | public function getAptSuite(): ?string 179 | { 180 | return $this->aptSuite; 181 | } 182 | 183 | /** 184 | * @param string|null $aptSuite 185 | */ 186 | public function setAptSuite(?string $aptSuite): void 187 | { 188 | $this->aptSuite = $aptSuite; 189 | } 190 | 191 | /** 192 | * @return string|null 193 | */ 194 | public function getCity(): ?string 195 | { 196 | return $this->city; 197 | } 198 | 199 | /** 200 | * @param string|null $city 201 | */ 202 | public function setCity(?string $city): void 203 | { 204 | $this->city = $city; 205 | } 206 | 207 | /** 208 | * @return string|null 209 | */ 210 | public function getState(): ?string 211 | { 212 | return $this->state; 213 | } 214 | 215 | /** 216 | * @param string|null $state 217 | */ 218 | public function setState(?string $state): void 219 | { 220 | $this->state = $state; 221 | } 222 | 223 | /** 224 | * @return string|null 225 | */ 226 | public function getPostalCode(): ?string 227 | { 228 | return $this->postalCode; 229 | } 230 | 231 | /** 232 | * @param string|null $postalCode 233 | */ 234 | public function setPostalCode(?string $postalCode): void 235 | { 236 | $this->postalCode = $postalCode; 237 | } 238 | 239 | /** 240 | * @return Country|null 241 | */ 242 | public function getCountry(): ?Country 243 | { 244 | return $this->country; 245 | } 246 | 247 | /** 248 | * @param Country|null $country 249 | */ 250 | public function setCountry(?Country $country): void 251 | { 252 | $this->country = $country; 253 | } 254 | } 255 | 256 | netMonthly; 274 | } 275 | 276 | /** 277 | * @param int|null $netMonthly 278 | */ 279 | public function setNetMonthly(?int $netMonthly): void 280 | { 281 | $this->netMonthly = $netMonthly; 282 | } 283 | } 284 | 285 | name; 308 | } 309 | 310 | /** 311 | * @param string|null $name 312 | */ 313 | public function setName(?string $name): void 314 | { 315 | $this->name = $name; 316 | } 317 | 318 | /** 319 | * @return string|null 320 | */ 321 | public function getType(): ?string 322 | { 323 | return $this->type; 324 | } 325 | 326 | /** 327 | * @param string|null $type 328 | */ 329 | public function setType(?string $type): void 330 | { 331 | $this->type = $type; 332 | } 333 | } 334 | 335 | id; 393 | } 394 | 395 | /** 396 | * @param int|null $id 397 | */ 398 | public function setId(?int $id): void 399 | { 400 | $this->id = $id; 401 | } 402 | 403 | /** 404 | * @return string|null 405 | */ 406 | public function getEmployer(): ?string 407 | { 408 | return $this->employer; 409 | } 410 | 411 | /** 412 | * @param string|null $employer 413 | */ 414 | public function setEmployer(?string $employer): void 415 | { 416 | $this->employer = $employer; 417 | } 418 | 419 | /** 420 | * @return float|null 421 | */ 422 | public function getBalance(): ?float 423 | { 424 | return $this->balance; 425 | } 426 | 427 | /** 428 | * @param float|null $balance 429 | */ 430 | public function setBalance(?float $balance): void 431 | { 432 | $this->balance = $balance; 433 | } 434 | 435 | /** 436 | * @return string|null 437 | */ 438 | public function getFirstName(): ?string 439 | { 440 | return $this->firstName; 441 | } 442 | 443 | /** 444 | * @param string|null $firstName 445 | */ 446 | public function setFirstName(?string $firstName): void 447 | { 448 | $this->firstName = $firstName; 449 | } 450 | 451 | /** 452 | * @return string|null 453 | */ 454 | public function getLastName(): ?string 455 | { 456 | return $this->lastName; 457 | } 458 | 459 | /** 460 | * @param string|null $lastName 461 | */ 462 | public function setLastName(?string $lastName): void 463 | { 464 | $this->lastName = $lastName; 465 | } 466 | 467 | /** 468 | * @return bool|null 469 | */ 470 | public function isEnabled(): ?bool 471 | { 472 | return $this->enabled; 473 | } 474 | 475 | /** 476 | * @param bool|null $enabled 477 | */ 478 | public function setEnabled(?bool $enabled): void 479 | { 480 | $this->enabled = $enabled; 481 | } 482 | 483 | /** 484 | * @return Address|null 485 | */ 486 | public function getAddress(): ?Address 487 | { 488 | return $this->address; 489 | } 490 | 491 | /** 492 | * @param Address|null $address 493 | */ 494 | public function setAddress(?Address $address): void 495 | { 496 | $this->address = $address; 497 | } 498 | 499 | /** 500 | * @return Income|null 501 | */ 502 | public function getIncome(): ?Income 503 | { 504 | return $this->income; 505 | } 506 | 507 | /** 508 | * @param Income|null $income 509 | */ 510 | public function setIncome(?Income $income): void 511 | { 512 | $this->income = $income; 513 | } 514 | 515 | /** 516 | * @return array|null 517 | */ 518 | public function getPets(): ?array 519 | { 520 | return $this->pets; 521 | } 522 | 523 | /** 524 | * @param array|null $pets 525 | */ 526 | public function setPets(?array $pets): void 527 | { 528 | $this->pets = $pets; 529 | } 530 | } 531 | 532 | -------------------------------------------------------------------------------- /tests/fixtures/sample.txt: -------------------------------------------------------------------------------- 1 | name; 24 | } 25 | 26 | /** 27 | * @param string|null $name 28 | */ 29 | public function setName($name) 30 | { 31 | $this->name = $name; 32 | } 33 | 34 | /** 35 | * @return string|null 36 | */ 37 | public function getGalaxy() 38 | { 39 | return $this->galaxy; 40 | } 41 | 42 | /** 43 | * @param string|null $galaxy 44 | */ 45 | public function setGalaxy($galaxy) 46 | { 47 | $this->galaxy = $galaxy; 48 | } 49 | } 50 | 51 | code; 79 | } 80 | 81 | /** 82 | * @param string|null $code 83 | */ 84 | public function setCode($code) 85 | { 86 | $this->code = $code; 87 | } 88 | 89 | /** 90 | * @return string|null 91 | */ 92 | public function getName() 93 | { 94 | return $this->name; 95 | } 96 | 97 | /** 98 | * @param string|null $name 99 | */ 100 | public function setName($name) 101 | { 102 | $this->name = $name; 103 | } 104 | 105 | /** 106 | * @return Planet|null 107 | */ 108 | public function getPlanet() 109 | { 110 | return $this->planet; 111 | } 112 | 113 | /** 114 | * @param Planet|null $planet 115 | */ 116 | public function setPlanet($planet) 117 | { 118 | $this->planet = $planet; 119 | } 120 | } 121 | 122 | street; 165 | } 166 | 167 | /** 168 | * @param string|null $street 169 | */ 170 | public function setStreet($street) 171 | { 172 | $this->street = $street; 173 | } 174 | 175 | /** 176 | * @return string|null 177 | */ 178 | public function getAptSuite() 179 | { 180 | return $this->aptSuite; 181 | } 182 | 183 | /** 184 | * @param string|null $aptSuite 185 | */ 186 | public function setAptSuite($aptSuite) 187 | { 188 | $this->aptSuite = $aptSuite; 189 | } 190 | 191 | /** 192 | * @return string|null 193 | */ 194 | public function getCity() 195 | { 196 | return $this->city; 197 | } 198 | 199 | /** 200 | * @param string|null $city 201 | */ 202 | public function setCity($city) 203 | { 204 | $this->city = $city; 205 | } 206 | 207 | /** 208 | * @return string|null 209 | */ 210 | public function getState() 211 | { 212 | return $this->state; 213 | } 214 | 215 | /** 216 | * @param string|null $state 217 | */ 218 | public function setState($state) 219 | { 220 | $this->state = $state; 221 | } 222 | 223 | /** 224 | * @return string|null 225 | */ 226 | public function getPostalCode() 227 | { 228 | return $this->postalCode; 229 | } 230 | 231 | /** 232 | * @param string|null $postalCode 233 | */ 234 | public function setPostalCode($postalCode) 235 | { 236 | $this->postalCode = $postalCode; 237 | } 238 | 239 | /** 240 | * @return Country|null 241 | */ 242 | public function getCountry() 243 | { 244 | return $this->country; 245 | } 246 | 247 | /** 248 | * @param Country|null $country 249 | */ 250 | public function setCountry($country) 251 | { 252 | $this->country = $country; 253 | } 254 | } 255 | 256 | netMonthly; 274 | } 275 | 276 | /** 277 | * @param int|null $netMonthly 278 | */ 279 | public function setNetMonthly($netMonthly) 280 | { 281 | $this->netMonthly = $netMonthly; 282 | } 283 | } 284 | 285 | name; 308 | } 309 | 310 | /** 311 | * @param string|null $name 312 | */ 313 | public function setName($name) 314 | { 315 | $this->name = $name; 316 | } 317 | 318 | /** 319 | * @return string|null 320 | */ 321 | public function getType() 322 | { 323 | return $this->type; 324 | } 325 | 326 | /** 327 | * @param string|null $type 328 | */ 329 | public function setType($type) 330 | { 331 | $this->type = $type; 332 | } 333 | } 334 | 335 | id; 393 | } 394 | 395 | /** 396 | * @param int|null $id 397 | */ 398 | public function setId($id) 399 | { 400 | $this->id = $id; 401 | } 402 | 403 | /** 404 | * @return string|null 405 | */ 406 | public function getEmployer() 407 | { 408 | return $this->employer; 409 | } 410 | 411 | /** 412 | * @param string|null $employer 413 | */ 414 | public function setEmployer($employer) 415 | { 416 | $this->employer = $employer; 417 | } 418 | 419 | /** 420 | * @return float|null 421 | */ 422 | public function getBalance() 423 | { 424 | return $this->balance; 425 | } 426 | 427 | /** 428 | * @param float|null $balance 429 | */ 430 | public function setBalance($balance) 431 | { 432 | $this->balance = $balance; 433 | } 434 | 435 | /** 436 | * @return string|null 437 | */ 438 | public function getFirstName() 439 | { 440 | return $this->firstName; 441 | } 442 | 443 | /** 444 | * @param string|null $firstName 445 | */ 446 | public function setFirstName($firstName) 447 | { 448 | $this->firstName = $firstName; 449 | } 450 | 451 | /** 452 | * @return string|null 453 | */ 454 | public function getLastName() 455 | { 456 | return $this->lastName; 457 | } 458 | 459 | /** 460 | * @param string|null $lastName 461 | */ 462 | public function setLastName($lastName) 463 | { 464 | $this->lastName = $lastName; 465 | } 466 | 467 | /** 468 | * @return bool|null 469 | */ 470 | public function isEnabled() 471 | { 472 | return $this->enabled; 473 | } 474 | 475 | /** 476 | * @param bool|null $enabled 477 | */ 478 | public function setEnabled($enabled) 479 | { 480 | $this->enabled = $enabled; 481 | } 482 | 483 | /** 484 | * @return Address|null 485 | */ 486 | public function getAddress() 487 | { 488 | return $this->address; 489 | } 490 | 491 | /** 492 | * @param Address|null $address 493 | */ 494 | public function setAddress($address) 495 | { 496 | $this->address = $address; 497 | } 498 | 499 | /** 500 | * @return Income|null 501 | */ 502 | public function getIncome() 503 | { 504 | return $this->income; 505 | } 506 | 507 | /** 508 | * @param Income|null $income 509 | */ 510 | public function setIncome($income) 511 | { 512 | $this->income = $income; 513 | } 514 | 515 | /** 516 | * @return array|null 517 | */ 518 | public function getPets() 519 | { 520 | return $this->pets; 521 | } 522 | 523 | /** 524 | * @param array|null $pets 525 | */ 526 | public function setPets($pets) 527 | { 528 | $this->pets = $pets; 529 | } 530 | } 531 | 532 | --------------------------------------------------------------------------------