├── .gitignore ├── CHANGELOG.md ├── README.md ├── composer.json ├── src ├── CleanClient.php ├── ClientBase.php ├── DadataClient.php ├── ProfileClient.php ├── Settings.php └── SuggestClient.php └── tests ├── BaseTest.php ├── CleanTest.php ├── ProfileTest.php └── SuggestTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the /vendor/ directory for people using composer 2 | /vendor/ 3 | 4 | # If the vendor directory isn't being commited the composer.lock file should also be ignored 5 | composer.lock -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 22.3.0 (2022-03-23) 2 | 3 | ### Features 4 | 5 | - Optional secret key in `SuggestClient` 6 | 7 | # 20.12.0 (2020-12-24) 8 | 9 | ### Features 10 | 11 | - Guzzle 7 support 12 | 13 | # 20.7.0 (2020-07-21) 14 | 15 | ### Features 16 | 17 | - Full Dadata API support as of July 2020 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dadata API Client 2 | 3 | > Data cleansing, enrichment and suggestions via [Dadata API](https://dadata.ru/api) 4 | 5 | [![Latest Stable Version][packagist-image]][packagist-url] 6 | [![Total Downloads][downloads-image]][packagist-url] 7 | [![License][license-image]][packagist-url] 8 | 9 | Thin PHP wrapper over Dadata API. 10 | 11 | ## Installation 12 | 13 | ```sh 14 | composer require hflabs/dadata 15 | ``` 16 | 17 | Requirements: 18 | 19 | - PHP 5.6+ 20 | - Guzzle 6 or 7 21 | 22 | ## Usage 23 | 24 | Create API client instance: 25 | 26 | ```php 27 | > $token = "Replace with Dadata API key"; 28 | > $secret = "Replace with Dadata secret key"; 29 | > $dadata = new \Dadata\DadataClient($token, $secret); 30 | ``` 31 | 32 | Then call API methods as specified below. 33 | 34 | ## Postal Address 35 | 36 | ### [Validate and cleanse address](https://dadata.ru/api/clean/address/) 37 | 38 | ```php 39 | > $response = $dadata->clean("address", "мск сухонская 11 89"); 40 | > var_dump($response); 41 | array(80) { 42 | ["source"]=> 43 | string(31) "мск сухонская 11 89" 44 | ["result"]=> 45 | string(56) "г Москва, ул Сухонская, д 11, кв 89" 46 | ["postal_code"]=> 47 | string(6) "127642" 48 | ["country"]=> 49 | string(12) "Россия" 50 | ["federal_district"]=> 51 | string(22) "Центральный" 52 | ["region"]=> 53 | string(12) "Москва" 54 | ["city_area"]=> 55 | string(31) "Северо-восточный" 56 | ["city_district"]=> 57 | string(37) "Северное Медведково" 58 | ["street"]=> 59 | string(18) "Сухонская" 60 | ["house"]=> 61 | string(2) "11" 62 | ["flat"]=> 63 | string(2) "89" 64 | ["flat_area"]=> 65 | string(4) "34.6" 66 | ["flat_price"]=> 67 | string(7) "6854710" 68 | ["fias_id"]=> 69 | string(36) "5ee84ac0-eb9a-4b42-b814-2f5f7c27c255" 70 | ["timezone"]=> 71 | string(5) "UTC+3" 72 | ["geo_lat"]=> 73 | string(10) "55.8782557" 74 | ["geo_lon"]=> 75 | string(8) "37.65372" 76 | ["qc_geo"]=> 77 | int(0) 78 | ["metro"]=> 79 | array(3) {...} 80 | } 81 | ``` 82 | 83 | ### [Geocode address](https://dadata.ru/api/geocode/) 84 | 85 | Same API method as "validate and cleanse": 86 | 87 | ```php 88 | > $response = $dadata->clean("address", "мск сухонская 11 89"); 89 | > var_dump($response); 90 | array(80) { 91 | ["source"]=> 92 | string(31) "мск сухонская 11 89" 93 | ["result"]=> 94 | string(56) "г Москва, ул Сухонская, д 11, кв 89" 95 | ... 96 | ["geo_lat"]=> 97 | string(10) "55.8782557" 98 | ["geo_lon"]=> 99 | string(8) "37.65372" 100 | ["beltway_hit"]=> 101 | string(7) "IN_MKAD" 102 | ["beltway_distance"]=> 103 | NULL 104 | ["qc_geo"]=> 105 | int(0) 106 | ... 107 | } 108 | ``` 109 | 110 | ### [Reverse geocode address](https://dadata.ru/api/geolocate/) 111 | 112 | ```php 113 | > $response = $dadata->geolocate("address", 55.878, 37.653); 114 | > var_dump($response); 115 | array(4) { 116 | [0]=> 117 | array(3) { 118 | ["value"]=> 119 | string(47) "г Москва, ул Сухонская, д 11" 120 | ... 121 | } 122 | [1]=> 123 | array(3) { 124 | ["value"]=> 125 | string(49) "г Москва, ул Сухонская, д 11А" 126 | ... 127 | } 128 | [2]=> 129 | array(3) { 130 | ["value"]=> 131 | string(47) "г Москва, ул Сухонская, д 13" 132 | ... 133 | } 134 | ... 135 | } 136 | ``` 137 | 138 | ### [GeoIP city](https://dadata.ru/api/iplocate/) 139 | 140 | ```php 141 | > $response = $dadata->iplocate("46.226.227.20"); 142 | > var_dump($response); 143 | array(3) { 144 | ["value"]=> 145 | string(21) "г Краснодар" 146 | ["unrestricted_value"]=> 147 | string(66) "350000, Краснодарский край, г Краснодар" 148 | ["data"]=> 149 | array(81) { 150 | ... 151 | } 152 | } 153 | ``` 154 | 155 | ### [Autocomplete (suggest) address](https://dadata.ru/api/suggest/address/) 156 | 157 | ```php 158 | > $response = $dadata->suggest("address", "самара метал"); 159 | > var_dump($response); 160 | array(5) { 161 | [0]=> 162 | array(3) { 163 | ["value"]=> 164 | string(49) "г Самара, пр-кт Металлургов" 165 | ... 166 | } 167 | [1]=> 168 | array(3) { 169 | ["value"]=> 170 | string(44) "г Самара, ул Металлистов" 171 | ... 172 | } 173 | [2]=> 174 | array(3) { 175 | ["value"]=> 176 | string(95) "г Самара, поселок Зубчаниновка, ул Металлургическая" 177 | ... 178 | } 179 | ... 180 | } 181 | ``` 182 | 183 | Show suggestions in English: 184 | 185 | ```php 186 | > $response = $dadata->suggest("address", "samara metal", 5, ["language" => "en"]); 187 | > var_dump($response); 188 | array(5) { 189 | [0]=> 190 | array(3) { 191 | ["value"]=> 192 | string(42) "Russia, gorod Samara, prospekt Metallurgov" 193 | ... 194 | } 195 | [1]=> 196 | array(3) { 197 | ["value"]=> 198 | string(39) "Russia, gorod Samara, ulitsa Metallistov" 199 | ... 200 | } 201 | [2]=> 202 | array(3) { 203 | ["value"]=> 204 | string(69) "Russia, gorod Samara, poselok Zubchaninovka, ulitsa Metallurgicheskaya" 205 | ... 206 | } 207 | ... 208 | } 209 | ``` 210 | 211 | Constrain by city (Yuzhno-Sakhalinsk): 212 | 213 | ```php 214 | > $locations = [[ "kladr_id" => "6500000100000" ]]; 215 | > $response = $dadata->suggest("address", "Ватутина", 5, ["locations" => $locations]); 216 | > var_dump($response); 217 | array(1) { 218 | [0]=> 219 | array(3) { 220 | ["value"]=> 221 | string(53) "г Южно-Сахалинск, ул Ватутина" 222 | ... 223 | } 224 | } 225 | ``` 226 | 227 | Constrain by specific geo point and radius (in Vologda city): 228 | 229 | ```php 230 | > $geo = [[ "lat" => 59.244634, "lon" => 39.913355, "radius_meters" => 200 ]]; 231 | > $response = $dadata->suggest("address", "сухонская", 5, ["locations_geo" => $geo]); 232 | > var_dump($response); 233 | array(1) { 234 | [0]=> 235 | array(3) { 236 | ["value"]=> 237 | string(42) "г Вологда, ул Сухонская" 238 | ... 239 | } 240 | } 241 | ``` 242 | 243 | Boost city to top (Toliatti): 244 | 245 | ```php 246 | > $boost = [[ "kladr_id" => "6300000700000" ]]; 247 | > $response = $dadata->suggest("address", "авто", 5, ["locations_boost" => $boost]); 248 | > var_dump($response); 249 | array(5) { 250 | [0]=> 251 | array(3) { 252 | ["value"]=> 253 | string(85) "Самарская обл, г Тольятти, Автозаводское шоссе" 254 | ... 255 | } 256 | [1]=> 257 | array(3) { 258 | ["value"]=> 259 | string(81) "Самарская обл, г Тольятти, ул Автомобилистов" 260 | ... 261 | } 262 | [2]=> 263 | array(3) { 264 | ["value"]=> 265 | string(81) "Самарская обл, г Тольятти, ул Автостроителей" 266 | ... 267 | } 268 | ... 269 | } 270 | ``` 271 | 272 | ### [Find address by FIAS ID](https://dadata.ru/api/find-address/) 273 | 274 | ```php 275 | > $response = $dadata->findById("address", "9120b43f-2fae-4838-a144-85e43c2bfb29"); 276 | > var_dump($response); 277 | array(1) { 278 | [0]=> 279 | array(3) { 280 | ["value"]=> 281 | string(36) "г Москва, ул Снежная" 282 | ... 283 | } 284 | } 285 | ``` 286 | 287 | Find by KLADR ID: 288 | 289 | ```php 290 | > $response = $dadata->findById("address", "77000000000268400"); 291 | ``` 292 | 293 | ### [Find postal office](https://dadata.ru/api/suggest/postal_unit/) 294 | 295 | Suggest postal office by address or code: 296 | 297 | ```php 298 | > $response = $dadata->suggest("postal_unit", "дежнева 2а"); 299 | > var_dump($response); 300 | array(1) { 301 | [0]=> 302 | array(3) { 303 | ["value"]=> 304 | string(6) "127642" 305 | ["unrestricted_value"]=> 306 | string(52) "г Москва, проезд Дежнёва, д 2А" 307 | ["data"]=> 308 | array(15) { 309 | ... 310 | } 311 | } 312 | } 313 | ``` 314 | 315 | Find postal office by code: 316 | 317 | ```php 318 | > $response = $dadata->findById("postal_unit", "127642"); 319 | > var_dump($response); 320 | array(1) { 321 | [0]=> 322 | array(3) { 323 | ["value"]=> 324 | string(6) "127642" 325 | ["unrestricted_value"]=> 326 | string(52) "г Москва, проезд Дежнёва, д 2А" 327 | ["data"]=> 328 | array(15) { 329 | ... 330 | } 331 | } 332 | } 333 | ``` 334 | 335 | Find nearest postal office: 336 | 337 | ```php 338 | > $response = $dadata->geolocate("postal_unit", 55.878, 37.653, 1000); 339 | > var_dump($response); 340 | array(2) { 341 | [0]=> 342 | array(3) { 343 | ["value"]=> 344 | string(6) "127642" 345 | ["unrestricted_value"]=> 346 | string(52) "г Москва, проезд Дежнёва, д 2А" 347 | ["data"]=> 348 | array(15) { 349 | ... 350 | } 351 | }, 352 | ... 353 | } 354 | ``` 355 | 356 | ### [Get City ID for delivery services](https://dadata.ru/api/delivery/) 357 | 358 | ```php 359 | > $response = $dadata->findById("delivery", "3100400100000"); 360 | > var_dump($response); 361 | array(1) { 362 | [0]=> 363 | array(3) { 364 | ["value"]=> 365 | string(13) "3100400100000" 366 | ["unrestricted_value"]=> 367 | string(36) "fe7eea4a-875a-4235-aa61-81c2a37a0440" 368 | ["data"]=> 369 | array(5) { 370 | ... 371 | ["boxberry_id"]=> 372 | string(5) "01929" 373 | ["cdek_id"]=> 374 | string(3) "344" 375 | ["dpd_id"]=> 376 | string(9) "196006461" 377 | } 378 | } 379 | } 380 | ``` 381 | 382 | ### [Get address strictly according to FIAS](https://dadata.ru/api/find-fias/) 383 | 384 | ```php 385 | > $response = $dadata->findById("fias", "9120b43f-2fae-4838-a144-85e43c2bfb29"); 386 | > var_dump($response); 387 | array(1) { 388 | [0]=> 389 | array(3) { 390 | ["value"]=> 391 | string(36) "г Москва, ул Снежная" 392 | ... 393 | } 394 | } 395 | ``` 396 | 397 | ### [Suggest country](https://dadata.ru/api/suggest/country/) 398 | 399 | ```php 400 | > $response = $dadata->suggest("country", "та"); 401 | > var_dump($response); 402 | array(4) { 403 | [0]=> 404 | array(3) { 405 | ["value"]=> 406 | string(22) "Таджикистан" 407 | ... 408 | }, 409 | [1]=> 410 | array(3) { 411 | ["value"]=> 412 | string(14) "Таиланд" 413 | ... 414 | } 415 | [2]=> 416 | array(3) { 417 | ["value"]=> 418 | string(14) "Тайвань" 419 | ... 420 | } 421 | ... 422 | } 423 | ``` 424 | 425 | ## Company or individual enterpreneur 426 | 427 | ### [Find company by INN](https://dadata.ru/api/find-party/) 428 | 429 | ```php 430 | > $response = $dadata->findById("party", "7707083893"); 431 | > var_dump($response); 432 | array(5) { 433 | [0]=> 434 | array(3) { 435 | ["value"]=> 436 | string(23) "ПАО СБЕРБАНК" 437 | ["unrestricted_value"]=> 438 | string(23) "ПАО СБЕРБАНК" 439 | ["data"]=> 440 | array(29) { 441 | ["kpp"]=> 442 | string(9) "773601001" 443 | ["inn"]=> 444 | string(10) "7707083893" 445 | ... 446 | } 447 | }, 448 | ... 449 | } 450 | ``` 451 | 452 | Find by INN and KPP: 453 | 454 | ```php 455 | > $response = $dadata->findById("party", "7707083893", 1, ["kpp" => "540602001"]); 456 | > var_dump($response); 457 | array(1) { 458 | [0]=> 459 | array(3) { 460 | ["value"]=> 461 | string(51) "СИБИРСКИЙ БАНК ПАО СБЕРБАНК" 462 | ["unrestricted_value"]=> 463 | string(51) "СИБИРСКИЙ БАНК ПАО СБЕРБАНК" 464 | ["data"]=> 465 | array(29) { 466 | ["kpp"]=> 467 | string(9) "540602001" 468 | ["inn"]=> 469 | string(10) "7707083893" 470 | ... 471 | } 472 | } 473 | } 474 | ``` 475 | 476 | ### [Suggest company](https://dadata.ru/api/suggest/party/) 477 | 478 | ```php 479 | > $response = $dadata->suggest("party", "сбер"); 480 | > var_dump($response); 481 | array(5) { 482 | [0]=> 483 | array(3) { 484 | ["value"]=> 485 | string(23) "ПАО СБЕРБАНК" 486 | ... 487 | } 488 | [1]=> 489 | array(3) { 490 | ["value"]=> 491 | string(48) "АО "СБЕРЭНЕРГОСЕРВИС-ЮГРА"" 492 | ... 493 | } 494 | [2]=> 495 | array(3) { 496 | ["value"]=> 497 | string(27) "АО "СБЕРБРОКЕР"" 498 | ... 499 | } 500 | ... 501 | } 502 | ``` 503 | 504 | Constrain by specific regions (Saint Petersburg and Leningradskaya oblast): 505 | 506 | ```php 507 | > $locations = [[ "kladr_id" => "7800000000000" ], [ "kladr_id" => "4700000000000"]]; 508 | > $response = $dadata->suggest("party", "сбер", 5, ["locations" => $locations]); 509 | ``` 510 | 511 | Constrain by active companies: 512 | 513 | ```php 514 | > $status = [ "ACTIVE" ]; 515 | > $response = $dadata->suggest("party", "сбер", 5, ["status" => $status]); 516 | ``` 517 | 518 | Constrain by individual entrepreneurs: 519 | 520 | ```php 521 | > $response = $dadata->suggest("party", "сбер", 5, ["type" => "INDIVIDUAL"]); 522 | ``` 523 | 524 | Constrain by head companies, no branches: 525 | 526 | ```php 527 | > $branch_type = [ "MAIN" ]; 528 | > $response = $dadata->suggest("party", "сбер", 5, ["branch_type" => $branch_type]); 529 | ``` 530 | 531 | ### [Find affiliated companies](https://dadata.ru/api/find-affiliated/) 532 | 533 | ```php 534 | > $response = $dadata->findAffiliated("7736207543"); 535 | > var_dump($response); 536 | array(5) { 537 | [0]=> 538 | array(3) { 539 | ["value"]=> 540 | string(36) "ООО "ДЗЕН.ПЛАТФОРМА"" 541 | ... 542 | } 543 | [1]=> 544 | array(3) { 545 | ["value"]=> 546 | string(21) "ООО "ЕДАДИЛ"" 547 | ... 548 | } 549 | [2]=> 550 | array(3) { 551 | ["value"]=> 552 | string(21) "ООО "ЗНАНИЕ"" 553 | ... 554 | } 555 | ... 556 | } 557 | ``` 558 | 559 | Search only by manager INN: 560 | 561 | ```php 562 | > $response = $dadata->findAffiliated("773006366201", 5, ["scope" => "MANAGERS"]); 563 | > var_dump($response); 564 | array(3) { 565 | [0]=> 566 | array(3) { 567 | ["value"]=> 568 | string(21) "ООО "ЯНДЕКС"" 569 | ... 570 | } 571 | [1]=> 572 | array(3) { 573 | ["value"]=> 574 | string(13) "МФ "ФОИ"" 575 | ... 576 | } 577 | [2]=> 578 | array(3) { 579 | ["value"]=> 580 | string(22) "АНО ДПО "ШАД"" 581 | ... 582 | } 583 | } 584 | ``` 585 | 586 | ## Bank 587 | 588 | ### [Find bank by BIC, SWIFT or INN](https://dadata.ru/api/find-bank/) 589 | 590 | ```php 591 | > $response = $dadata->findById("bank", "044525225"); 592 | > var_dump($response); 593 | array(1) { 594 | [0]=> 595 | array(3) { 596 | ["value"]=> 597 | string(23) "ПАО Сбербанк" 598 | ["unrestricted_value"]=> 599 | string(23) "ПАО Сбербанк" 600 | ["data"]=> 601 | array(14) { 602 | ["bic"]=> 603 | string(9) "044525225" 604 | ["swift"]=> 605 | string(8) "SABRRUMM" 606 | ["inn"]=> 607 | string(10) "7707083893" 608 | ... 609 | } 610 | } 611 | } 612 | ``` 613 | 614 | Find by SWIFT code: 615 | 616 | ```php 617 | > $response = $dadata->findById("bank", "SABRRUMM"); 618 | ``` 619 | 620 | Find by INN: 621 | 622 | ```php 623 | > $response = $dadata->findById("bank", "7728168971"); 624 | ``` 625 | 626 | Find by INN and KPP: 627 | 628 | ```php 629 | > $response = $dadata->findById("bank", "7728168971", 1, ["kpp" => "667102002"]); 630 | ``` 631 | 632 | Find by registration number: 633 | 634 | ```php 635 | > $response = $dadata->findById("bank", "1481"); 636 | ``` 637 | 638 | ### [Suggest bank](https://dadata.ru/api/suggest/bank/) 639 | 640 | ```php 641 | > $response = $dadata->suggest("bank", "ти"); 642 | > var_dump($response); 643 | array(5) { 644 | [0]=> 645 | array(3) { 646 | ["value"]=> 647 | string(28) "АО «Тимер Банк»" 648 | ... 649 | } 650 | [1]=> 651 | array(3) { 652 | ["value"]=> 653 | string(34) "АО «Тинькофф Банк»" 654 | ... 655 | } 656 | [2]=> 657 | array(3) { 658 | ["value"]=> 659 | string(65) "«Азиатско-Тихоокеанский Банк» (ПАО)" 660 | ... 661 | } 662 | ... 663 | } 664 | ``` 665 | 666 | ## Personal name 667 | 668 | ### [Validate and cleanse name](https://dadata.ru/api/clean/name/) 669 | 670 | ```php 671 | > $response = $dadata->clean("name", "Срегей владимерович иванов"); 672 | > var_dump($response); 673 | array(10) { 674 | ["source"]=> 675 | string(50) "Срегей владимерович иванов" 676 | ["result"]=> 677 | ... 678 | ["surname"]=> 679 | string(12) "Иванов" 680 | ["name"]=> 681 | string(12) "Сергей" 682 | ["patronymic"]=> 683 | string(24) "Владимирович" 684 | ["gender"]=> 685 | string(2) "М" 686 | ["qc"]=> 687 | int(1) 688 | } 689 | ``` 690 | 691 | ### [Suggest name](https://dadata.ru/api/suggest/name/) 692 | 693 | ```php 694 | > $response = $dadata->suggest("fio", "викт"); 695 | > var_dump($response); 696 | array(5) { 697 | [0]=> 698 | array(3) { 699 | ["value"]=> 700 | string(12) "Виктор" 701 | ... 702 | } 703 | [1]=> 704 | array(3) { 705 | ["value"]=> 706 | string(16) "Виктория" 707 | ... 708 | } 709 | [2]=> 710 | array(3) { 711 | ["value"]=> 712 | string(18) "Викторова" 713 | ... 714 | } 715 | ... 716 | } 717 | ``` 718 | 719 | Suggest female first name: 720 | 721 | ```php 722 | > $filter = ["parts" => ["NAME"], gender => "FEMALE"]; 723 | > $response = $dadata->suggest("fio", "викт", 5, $filter); 724 | > var_dump($response); 725 | array(2) { 726 | [0]=> 727 | array(3) { 728 | ["value"]=> 729 | string(16) "Виктория" 730 | ... 731 | } 732 | [1]=> 733 | array(3) { 734 | ["value"]=> 735 | string(18) "Викторина" 736 | ... 737 | } 738 | } 739 | 740 | ``` 741 | 742 | ## Phone 743 | 744 | ### [Validate and cleanse phone](https://dadata.ru/api/clean/phone/) 745 | 746 | ```php 747 | > $response = $dadata->clean("phone", "9168-233-454"); 748 | > var_dump($response); 749 | array(14) { 750 | ["source"]=> 751 | string(12) "9168-233-454" 752 | ["type"]=> 753 | string(18) "Мобильный" 754 | ["phone"]=> 755 | string(16) "+7 916 823-34-54" 756 | ... 757 | ["provider"]=> 758 | string(50) "ПАО "Мобильные ТелеСистемы"" 759 | ["country"]=> 760 | string(12) "Россия" 761 | ["region"]=> 762 | string(51) "Москва и Московская область" 763 | ["timezone"]=> 764 | string(5) "UTC+3" 765 | ["qc"]=> 766 | int(0) 767 | } 768 | ``` 769 | 770 | ## Passport 771 | 772 | ### [Validate passport](https://dadata.ru/api/clean/passport/) 773 | 774 | ```php 775 | > $response = $dadata->clean("passport", "4509 235857"); 776 | > var_dump($response); 777 | array(4) { 778 | ["source"]=> 779 | string(11) "4509 235857" 780 | ["series"]=> 781 | string(5) "45 09" 782 | ["number"]=> 783 | string(6) "235857" 784 | ["qc"]=> 785 | int(0) 786 | } 787 | ``` 788 | 789 | ### [Suggest issued by](https://dadata.ru/api/suggest/fms_unit/) 790 | 791 | ```php 792 | > $response = $dadata->suggest("fms_unit", "772 053"); 793 | > var_dump($response); 794 | array(5) { 795 | [0]=> 796 | array(3) { 797 | ["value"]=> 798 | string(36) "ОВД ЗЮЗИНО Г. МОСКВЫ" 799 | ... 800 | } 801 | [1]=> 802 | array(3) { 803 | ["value"]=> 804 | string(68) "ОВД ЗЮЗИНО Г. МОСКВЫ ПАСПОРТНЫЙ СТОЛ 1" 805 | ... 806 | } 807 | [2]=> 808 | array(3) { 809 | ["value"]=> 810 | string(57) "ОВД ЗЮЗИНО ПС УВД ЮЗАО Г. МОСКВЫ" 811 | ... 812 | } 813 | ... 814 | } 815 | ``` 816 | 817 | ## Email 818 | 819 | ### [Validate email](https://dadata.ru/api/clean/email/) 820 | 821 | ```php 822 | > $response = $dadata->clean("email", "serega@yandex/ru"); 823 | > var_dump($response); 824 | array(6) { 825 | ["source"]=> 826 | string(16) "serega@yandex/ru" 827 | ["email"]=> 828 | string(16) "serega@yandex.ru" 829 | ["local"]=> 830 | string(6) "serega" 831 | ["domain"]=> 832 | string(9) "yandex.ru" 833 | ["type"]=> 834 | string(8) "PERSONAL" 835 | ["qc"]=> 836 | int(4) 837 | } 838 | ``` 839 | 840 | ### [Suggest email](https://dadata.ru/api/suggest/email/) 841 | 842 | ```php 843 | > $response = $dadata->suggest("email", "maria@"); 844 | > var_dump($response); 845 | array(5) { 846 | [0]=> 847 | array(3) { 848 | ["value"]=> 849 | string(13) "maria@mail.ru" 850 | ... 851 | } 852 | [1]=> 853 | array(3) { 854 | ["value"]=> 855 | string(15) "maria@gmail.com" 856 | ... 857 | } 858 | [2]=> 859 | array(3) { 860 | ["value"]=> 861 | string(15) "maria@yandex.ru" 862 | ... 863 | } 864 | ... 865 | } 866 | ``` 867 | 868 | ## Other datasets 869 | 870 | ### [Tax office](https://dadata.ru/api/suggest/fns_unit/) 871 | 872 | ```php 873 | > $response = $dadata->findById("fns_unit", "5257"); 874 | > var_dump($response); 875 | array(1) { 876 | [0]=> 877 | array(3) { 878 | ["value"]=> 879 | string(118) "Инспекция ФНС России по Канавинскому району г.Нижнего Новгорода" 880 | ["unrestricted_value"]=> 881 | string(118) "Инспекция ФНС России по Канавинскому району г.Нижнего Новгорода" 882 | ["data"]=> 883 | array(18) { 884 | ["code"]=> 885 | string(4) "5257" 886 | ["oktmo"]=> 887 | string(8) "22701000" 888 | ["inn"]=> 889 | string(10) "5257046101" 890 | ["kpp"]=> 891 | string(9) "525701001" 892 | ... 893 | } 894 | } 895 | } 896 | 897 | ``` 898 | 899 | ### [Regional court](https://dadata.ru/api/suggest/region_court/) 900 | 901 | ```php 902 | > $response = $dadata->suggest("region_court", "таганско"); 903 | > var_dump($response); 904 | array(5) { 905 | [0]=> 906 | array(3) { 907 | ["value"]=> 908 | string(109) "Судебный участок № 371 Таганского судебного района г. Москвы" 909 | ... 910 | } 911 | [1]=> 912 | array(3) { 913 | ["value"]=> 914 | string(109) "Судебный участок № 372 Таганского судебного района г. Москвы" 915 | ... 916 | } 917 | [2]=> 918 | array(3) { 919 | ["value"]=> 920 | string(109) "Судебный участок № 373 Таганского судебного района г. Москвы" 921 | ... 922 | } 923 | ... 924 | } 925 | ``` 926 | 927 | ### [Metro station](https://dadata.ru/api/suggest/metro/) 928 | 929 | ```php 930 | > $response = $dadata->suggest("metro", "алекс"); 931 | > var_dump($response); 932 | array(4) { 933 | [0]=> 934 | array(3) { 935 | ["value"]=> 936 | string(37) "Александровский сад" 937 | ... 938 | } 939 | [1]=> 940 | array(3) { 941 | ["value"]=> 942 | string(24) "Алексеевская" 943 | ... 944 | } 945 | [2]=> 946 | array(3) { 947 | ["value"]=> 948 | string(54) "Площадь Александра Невского 1" 949 | ... 950 | } 951 | ... 952 | } 953 | ``` 954 | 955 | Constrain by city (Saint Petersburg): 956 | 957 | ```php 958 | > $filters = [[ "city" => "Санкт-Петербург" ]]; 959 | > $response = $dadata->suggest("metro", "алекс", 5, ["filters" => $filters]); 960 | > var_dump($response); 961 | array(2) { 962 | [0]=> 963 | array(3) { 964 | ["value"]=> 965 | string(54) "Площадь Александра Невского 1" 966 | ... 967 | } 968 | [1]=> 969 | array(3) { 970 | ["value"]=> 971 | string(54) "Площадь Александра Невского 2" 972 | ... 973 | } 974 | } 975 | ``` 976 | 977 | ### [Car brand](https://dadata.ru/api/suggest/car_brand/) 978 | 979 | ```php 980 | > $response = $dadata->suggest("car_brand", "фо"); 981 | > var_dump($response); 982 | array(3) { 983 | [0]=> 984 | array(3) { 985 | ["value"]=> 986 | string(10) "Volkswagen" 987 | ... 988 | } 989 | [1]=> 990 | array(3) { 991 | ["value"]=> 992 | string(4) "Ford" 993 | ... 994 | } 995 | [2]=> 996 | array(3) { 997 | ["value"]=> 998 | string(5) "Foton" 999 | ... 1000 | } 1001 | } 1002 | ``` 1003 | 1004 | ### [Currency](https://dadata.ru/api/suggest/currency/) 1005 | 1006 | ```php 1007 | > $response = $dadata->suggest("currency", "руб"); 1008 | > var_dump($response); 1009 | array(2) { 1010 | [0]=> 1011 | array(3) { 1012 | ["value"]=> 1013 | string(33) "Белорусский рубль" 1014 | ... 1015 | } 1016 | [1]=> 1017 | array(3) { 1018 | ["value"]=> 1019 | string(31) "Российский рубль" 1020 | ... 1021 | } 1022 | } 1023 | ``` 1024 | 1025 | ### [OKVED 2](https://dadata.ru/api/suggest/okved2/) 1026 | 1027 | ```php 1028 | > $response = $dadata->suggest("okved2", "космических"); 1029 | > var_dump($response); 1030 | array(5) { 1031 | [0]=> 1032 | array(3) { 1033 | ["value"]=> 1034 | string(139) "Производство космических аппаратов (в том числе спутников), ракет-носителей" 1035 | ... 1036 | } 1037 | [1]=> 1038 | array(3) { 1039 | ["value"]=> 1040 | string(139) "Производство частей и принадлежностей летательных и космических аппаратов" 1041 | ... 1042 | } 1043 | [2]=> 1044 | array(3) { 1045 | ["value"]=> 1046 | string(95) "Производство автоматических космических аппаратов" 1047 | ... 1048 | } 1049 | ... 1050 | } 1051 | ``` 1052 | 1053 | ### [OKPD 2](https://dadata.ru/api/suggest/okpd2/) 1054 | 1055 | ```php 1056 | > $response = $dadata->suggest("okpd2", "калоши"); 1057 | > var_dump($response); 1058 | array(1) { 1059 | [0]=> 1060 | array(3) { 1061 | ["value"]=> 1062 | string(91) "Услуги по обрезинованию валенок (рыбацкие калоши)" 1063 | ... 1064 | } 1065 | } 1066 | ``` 1067 | 1068 | ## Profile API 1069 | 1070 | Balance: 1071 | 1072 | ```php 1073 | > $response = $dadata->getBalance(); 1074 | > var_dump($response); 1075 | float(8238.20) 1076 | ``` 1077 | 1078 | Usage stats: 1079 | 1080 | ```php 1081 | > $response = $dadata->getDailyStats(); 1082 | > var_dump($response); 1083 | array(2) { 1084 | ["date"]=> 1085 | string(10) "2020-07-27" 1086 | ["services"]=> 1087 | array(3) { 1088 | ["merging"]=> 1089 | int(0) 1090 | ["suggestions"]=> 1091 | int(45521) 1092 | ["clean"]=> 1093 | int(1200) 1094 | } 1095 | } 1096 | 1097 | ``` 1098 | 1099 | Dataset versions: 1100 | 1101 | ```php 1102 | > $response = $dadata->getVersions(); 1103 | > var_dump($response); 1104 | array(3) { 1105 | ["dadata"]=> 1106 | array(1) { 1107 | ["version"]=> 1108 | string(26) "stable (9048:bf33b2acc8ba)" 1109 | } 1110 | ["suggestions"]=> 1111 | array(2) { 1112 | ["version"]=> 1113 | string(15) "20.5 (b55eb7c4)" 1114 | ["resources"]=> 1115 | array(4) { 1116 | ... 1117 | } 1118 | } 1119 | ["factor"]=> 1120 | array(2) { 1121 | ["version"]=> 1122 | string(16) "20.06 (eb70078e)" 1123 | ["resources"]=> 1124 | array(8) { 1125 | ... 1126 | } 1127 | } 1128 | } 1129 | 1130 | ``` 1131 | 1132 | ## Development setup 1133 | 1134 | ```sh 1135 | $ composer install 1136 | $ ./vendor/bin/phpunit tests 1137 | ``` 1138 | 1139 | ## Contributing 1140 | 1141 | This project only accepts bug fixes. 1142 | 1143 | ## [Changelog](CHANGELOG.md) 1144 | 1145 | This project uses [CalVer](https://calver.org/) with YY.MM.MICRO schema. See changelog for details specific to each release. 1146 | 1147 | ## License 1148 | 1149 | [MIT](https://choosealicense.com/licenses/mit/) 1150 | 1151 | 1152 | 1153 | [packagist-url]: https://packagist.org/packages/hflabs/dadata 1154 | [packagist-image]: https://poser.pugx.org/hflabs/dadata/v/stable.svg 1155 | [downloads-image]: https://poser.pugx.org/hflabs/dadata/downloads.svg 1156 | [license-image]: https://poser.pugx.org/hflabs/dadata/license.svg 1157 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hflabs/dadata", 3 | "type": "library", 4 | "description": "Data cleansing, enrichment and suggestions via Dadata API", 5 | "homepage": "https://github.com/nalgeon/dadata-php", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "HFLabs and contributors", 10 | "homepage": "https://github.com/hflabs/dadata-php/contributors" 11 | } 12 | ], 13 | "keywords": [ 14 | "dadata", 15 | "suggestions", 16 | "api", 17 | "php" 18 | ], 19 | "require": { 20 | "php": ">=5.6.0", 21 | "guzzlehttp/guzzle": "~6.0|^7.0" 22 | }, 23 | "require-dev": { 24 | "phpunit/phpunit": "^5.7" 25 | }, 26 | "autoload": { 27 | "psr-4": { 28 | "Dadata\\": "src/" 29 | } 30 | }, 31 | "autoload-dev": { 32 | "psr-4": { 33 | "Dadata\\": "tests/" 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/CleanClient.php: -------------------------------------------------------------------------------- 1 | post($url, $fields); 24 | return $response[0]; 25 | } 26 | 27 | /** 28 | * @throws GuzzleException 29 | */ 30 | public function cleanRecord($structure, $record) 31 | { 32 | $url = "clean"; 33 | $data = [ 34 | "structure" => $structure, 35 | "data" => [$record] 36 | ]; 37 | $response = $this->post($url, $data); 38 | return $response["data"][0]; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/ClientBase.php: -------------------------------------------------------------------------------- 1 | "application/json", 16 | "Accept" => "application/json", 17 | "Authorization" => "Token " . $token, 18 | ]; 19 | if ($secret) { 20 | $headers["X-Secret"] = $secret; 21 | } 22 | $this->client = new Client([ 23 | "base_uri" => $baseUrl, 24 | "headers" => $headers, 25 | "timeout" => Settings::TIMEOUT_SEC 26 | ]); 27 | } 28 | 29 | /** 30 | * @throws GuzzleException 31 | */ 32 | protected function get($url, $query = []) 33 | { 34 | $response = $this->client->get($url, ["query" => $query]); 35 | return json_decode($response->getBody(), true); 36 | } 37 | 38 | /** 39 | * @throws GuzzleException 40 | */ 41 | protected function post($url, $data) 42 | { 43 | $response = $this->client->post($url, [ 44 | "json" => $data 45 | ]); 46 | return json_decode($response->getBody(), true); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/DadataClient.php: -------------------------------------------------------------------------------- 1 | cleaner = new CleanClient($token, $secret); 16 | $this->profile = new ProfileClient($token, $secret); 17 | $this->suggestions = new SuggestClient($token, $secret); 18 | } 19 | 20 | /** 21 | * @throws GuzzleException 22 | */ 23 | public function clean($name, $value) 24 | { 25 | return $this->cleaner->clean($name, $value); 26 | } 27 | 28 | /** 29 | * @throws GuzzleException 30 | */ 31 | public function cleanRecord($structure, $record) 32 | { 33 | return $this->cleaner->cleanRecord($structure, $record); 34 | } 35 | 36 | /** 37 | * @throws GuzzleException 38 | */ 39 | public function findAffiliated($query, $count = Settings::SUGGESTION_COUNT, $kwargs = []) 40 | { 41 | return $this->suggestions->findAffiliated($query, $count, $kwargs); 42 | } 43 | 44 | /** 45 | * @throws GuzzleException 46 | */ 47 | public function findById($name, $query, $count = Settings::SUGGESTION_COUNT, $kwargs = []) 48 | { 49 | return $this->suggestions->findById($name, $query, $count, $kwargs); 50 | } 51 | 52 | /** 53 | * @throws GuzzleException 54 | */ 55 | public function geolocate($name, $lat, $lon, $radiusMeters = 100, $count = Settings::SUGGESTION_COUNT, $kwargs = []) 56 | { 57 | return $this->suggestions->geolocate($name, $lat, $lon, $radiusMeters, $count, $kwargs); 58 | } 59 | 60 | /** 61 | * @throws GuzzleException 62 | */ 63 | public function getBalance() 64 | { 65 | return $this->profile->getBalance(); 66 | } 67 | 68 | /** 69 | * @throws GuzzleException 70 | */ 71 | public function getDailyStats($date = null) 72 | { 73 | return $this->profile->getDailyStats($date); 74 | } 75 | 76 | /** 77 | * @throws GuzzleException 78 | */ 79 | public function getVersions() 80 | { 81 | return $this->profile->getVersions(); 82 | } 83 | 84 | /** 85 | * @throws GuzzleException 86 | */ 87 | public function iplocate($ip, $kwargs = []) 88 | { 89 | return $this->suggestions->iplocate($ip, $kwargs); 90 | } 91 | 92 | /** 93 | * @throws GuzzleException 94 | */ 95 | public function suggest($name, $query, $count = Settings::SUGGESTION_COUNT, $kwargs = []) 96 | { 97 | return $this->suggestions->suggest($name, $query, $count, $kwargs); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/ProfileClient.php: -------------------------------------------------------------------------------- 1 | get($url); 24 | return $response["balance"]; 25 | } 26 | 27 | /** 28 | * @throws GuzzleException 29 | */ 30 | public function getDailyStats($date = null) 31 | { 32 | $url = "stat/daily"; 33 | if (!$date) { 34 | $date = new DateTime(); 35 | } 36 | $query = ["date" => $date->format("Y-m-d")]; 37 | $response = $this->get($url, $query); 38 | return $response; 39 | } 40 | 41 | /** 42 | * @throws GuzzleException 43 | */ 44 | public function getVersions() 45 | { 46 | $url = "version"; 47 | $response = $this->get($url); 48 | return $response; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Settings.php: -------------------------------------------------------------------------------- 1 | $query, "count" => $count]; 23 | $data = $data + $kwargs; 24 | $response = $this->post($url, $data); 25 | return $response["suggestions"]; 26 | } 27 | 28 | /** 29 | * @throws GuzzleException 30 | */ 31 | public function findById($name, $query, $count = Settings::SUGGESTION_COUNT, $kwargs = []) 32 | { 33 | $url = "findById/$name"; 34 | $data = ["query" => $query, "count" => $count]; 35 | $data = $data + $kwargs; 36 | $response = $this->post($url, $data); 37 | return $response["suggestions"]; 38 | } 39 | 40 | /** 41 | * @throws GuzzleException 42 | */ 43 | public function geolocate($name, $lat, $lon, $radiusMeters = 100, $count = Settings::SUGGESTION_COUNT, $kwargs = []) 44 | { 45 | $url = "geolocate/$name"; 46 | $data = array( 47 | "lat" => $lat, 48 | "lon" => $lon, 49 | "radius_meters" => $radiusMeters, 50 | "count" => $count, 51 | ); 52 | $data = $data + $kwargs; 53 | $response = $this->post($url, $data); 54 | return $response["suggestions"]; 55 | } 56 | 57 | /** 58 | * @throws GuzzleException 59 | */ 60 | public function iplocate($ip, $kwargs = []) 61 | { 62 | $url = "iplocate/address"; 63 | $query = ["ip" => $ip]; 64 | $query = $query + $kwargs; 65 | $response = $this->get($url, $query); 66 | return $response["location"]; 67 | } 68 | 69 | /** 70 | * @throws GuzzleException 71 | */ 72 | public function suggest($name, $query, $count = Settings::SUGGESTION_COUNT, $kwargs = []) 73 | { 74 | $url = "suggest/$name"; 75 | $data = ["query" => $query, "count" => $count]; 76 | $data = $data + $kwargs; 77 | $response = $this->post($url, $data); 78 | return $response["suggestions"]; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/BaseTest.php: -------------------------------------------------------------------------------- 1 | mock = new MockHandler(); 21 | $this->handler = HandlerStack::create($this->mock); 22 | $this->history = []; 23 | $history = Middleware::history($this->history); 24 | $this->handler->push($history); 25 | } 26 | 27 | protected function mockResponse($data) 28 | { 29 | $body = Psr7\stream_for(json_encode($data)); 30 | $response = new Response(200, [], $body); 31 | $this->mock->append($response); 32 | } 33 | 34 | protected function getLastRequest() 35 | { 36 | $request = $this->history[count($this->history) - 1]["request"]; 37 | $body = $request->getBody(); 38 | $body->rewind(); 39 | return json_decode($body->getContents(), true); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/CleanTest.php: -------------------------------------------------------------------------------- 1 | api = new CleanClient("token", "secret"); 13 | $this->api->client = new Client(["handler" => $this->handler]); 14 | } 15 | 16 | public function testToken() 17 | { 18 | $api = new CleanClient("123", "456"); 19 | $headers = $api->client->getConfig("headers"); 20 | $this->assertEquals($headers["Authorization"], "Token 123"); 21 | } 22 | 23 | public function testSecret() 24 | { 25 | $api = new CleanClient("123", "456"); 26 | $headers = $api->client->getConfig("headers"); 27 | $this->assertEquals($headers["X-Secret"], "456"); 28 | } 29 | 30 | public function testClean() 31 | { 32 | $expected = [ 33 | "source" => "Сережа", 34 | "result" => "Сергей", 35 | "qc" => 1 36 | ]; 37 | $this->mockResponse([$expected]); 38 | $actual = $this->api->clean("name", "Сережа"); 39 | $this->assertEquals($actual, $expected); 40 | } 41 | 42 | public function testCleanRequest() 43 | { 44 | $this->mockResponse([ 45 | [ "source" => "москва"] 46 | ]); 47 | $this->api->clean("address", "москва"); 48 | $expected = ["москва"]; 49 | $actual = $this->getLastRequest(); 50 | $this->assertEquals($expected, $actual); 51 | } 52 | 53 | public function testCleanRecord() 54 | { 55 | $structure = ["AS_IS", "AS_IS", "AS_IS"]; 56 | $record = ["1", "2", "3"]; 57 | $expected = [ 58 | [ 59 | "source" => "1", 60 | ], 61 | [ 62 | "source" => "2", 63 | ], 64 | [ 65 | "source" => "3", 66 | ] 67 | ]; 68 | $response = [ 69 | "structure" => $structure, 70 | "data" => [$expected] 71 | ]; 72 | $this->mockResponse($response); 73 | $actual = $this->api->cleanRecord($structure, $record); 74 | $this->assertEquals($actual, $expected); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/ProfileTest.php: -------------------------------------------------------------------------------- 1 | api = new ProfileClient("token", "secret"); 14 | $this->api->client = new Client(["handler" => $this->handler]); 15 | } 16 | 17 | public function testToken() 18 | { 19 | $api = new ProfileClient("123", "456"); 20 | $headers = $api->client->getConfig("headers"); 21 | $this->assertEquals($headers["Authorization"], "Token 123"); 22 | } 23 | 24 | public function testSecret() 25 | { 26 | $api = new ProfileClient("123", "456"); 27 | $headers = $api->client->getConfig("headers"); 28 | $this->assertEquals($headers["X-Secret"], "456"); 29 | } 30 | 31 | public function testGetBalance() 32 | { 33 | $response = ["balance" => 9922.30]; 34 | $this->mockResponse($response); 35 | $actual = $this->api->getBalance(); 36 | $this->assertEquals($actual, 9922.30); 37 | } 38 | 39 | public function testGetDailyStats() 40 | { 41 | $today = new DateTime(); 42 | $todayStr = $today->format("Y-m-d"); 43 | $expected = ["date" => $todayStr, "services" => ["merging" => 0, "suggestions" => 11, "clean" => 1004]]; 44 | $this->mockResponse($expected); 45 | $actual = $this->api->getDailyStats(); 46 | $this->assertEquals($actual, $expected); 47 | } 48 | 49 | public function testVersions() 50 | { 51 | $expected = [ 52 | "dadata" => ["version" => "17.1 (5995:3d7b54a78838)"], 53 | "suggestions" => ["version" => "16.10 (5a2e47f29553)", "resources" => ["ЕГРЮЛ" => "13.01.2017"]], 54 | "factor" => ["version" => "8.0 (90780)", "resources" => ["ФИАС" => "30.01.2017"]], 55 | ]; 56 | $this->mockResponse($expected); 57 | $actual = $this->api->getVersions(); 58 | $this->assertEquals($actual, $expected); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/SuggestTest.php: -------------------------------------------------------------------------------- 1 | api = new SuggestClient("token"); 13 | $this->api->client = new Client(["handler" => $this->handler]); 14 | } 15 | 16 | public function testToken() 17 | { 18 | $api = new SuggestClient("123"); 19 | $headers = $api->client->getConfig("headers"); 20 | $this->assertEquals($headers["Authorization"], "Token 123"); 21 | } 22 | 23 | public function testFindAffiliated() 24 | { 25 | $expected = [ 26 | ["value" => "ООО ДЗЕН.ПЛАТФОРМА", "data" => ["inn" => "7704431373"]], 27 | ["value" => "ООО ЕДАДИЛ", "data" => ["inn" => "7728237907"]], 28 | ]; 29 | $response = [ 30 | "suggestions" => $expected 31 | ]; 32 | $this->mockResponse($response); 33 | $actual = $this->api->findAffiliated("7736207543"); 34 | $this->assertEquals($actual, $expected); 35 | } 36 | 37 | public function testFindAffiliatedRequest() 38 | { 39 | $this->mockResponse([ "suggestions" => [] ]); 40 | $this->api->findAffiliated("7736207543", 5); 41 | $expected = ["query" => "7736207543", "count" => 5]; 42 | $actual = $this->getLastRequest(); 43 | $this->assertEquals($expected, $actual); 44 | } 45 | 46 | public function testFindAffiliatedNotFound() 47 | { 48 | $expected = []; 49 | $response = [ 50 | "suggestions" => $expected 51 | ]; 52 | $this->mockResponse($response); 53 | $actual = $this->api->findAffiliated("1234567890"); 54 | $this->assertEquals($actual, $expected); 55 | } 56 | 57 | public function testFindById() 58 | { 59 | $expected = [ 60 | ["value" => "ООО МОТОРИКА", "data" => ["inn" => "7719402047"]], 61 | ]; 62 | $response = [ 63 | "suggestions" => $expected 64 | ]; 65 | $this->mockResponse($response); 66 | $actual = $this->api->findById("party", "7719402047"); 67 | $this->assertEquals($actual, $expected); 68 | } 69 | 70 | public function testFindByIdRequest() 71 | { 72 | $this->mockResponse([ "suggestions" => [] ]); 73 | $kwargs = [ 74 | "kpp" => "773101001" 75 | ]; 76 | $this->api->findById("party", "7719402047", 5, $kwargs); 77 | $expected = ["query" => "7719402047", "count" => 5, "kpp" => "773101001"]; 78 | $actual = $this->getLastRequest(); 79 | $this->assertEquals($expected, $actual); 80 | } 81 | 82 | public function testFindByIdNotFound() 83 | { 84 | $expected = []; 85 | $response = [ 86 | "suggestions" => $expected 87 | ]; 88 | $this->mockResponse($response); 89 | $actual = $this->api->findById("party", "1234567890"); 90 | $this->assertEquals($actual, $expected); 91 | } 92 | 93 | public function testGeolocate() 94 | { 95 | $expected = [ 96 | [ 97 | "value" => "г Москва, ул Сухонская, д 11", 98 | "data" => ["kladr_id" => "7700000000028360004"] 99 | ] 100 | ]; 101 | $response = [ 102 | "suggestions" => $expected 103 | ]; 104 | $this->mockResponse($response); 105 | $actual = $this->api->geolocate("address", 55.8782557, 37.65372); 106 | $this->assertEquals($actual, $expected); 107 | } 108 | 109 | public function testGeolocateRequest() 110 | { 111 | $this->mockResponse([ "suggestions" => [] ]); 112 | $this->api->geolocate("address", 55.8782557, 37.65372, 200, 5); 113 | $expected = ["lat" => 55.8782557, "lon" => 37.65372, "radius_meters" => 200, "count" => 5]; 114 | $actual = $this->getLastRequest(); 115 | $this->assertEquals($expected, $actual); 116 | } 117 | 118 | public function testGeolocateNotFound() 119 | { 120 | $expected = []; 121 | $response = [ 122 | "suggestions" => $expected 123 | ]; 124 | $this->mockResponse($response); 125 | $actual = $this->api->geolocate("address", 1, 1); 126 | $this->assertEquals($actual, $expected); 127 | } 128 | 129 | public function testIplocate() 130 | { 131 | $expected = [ 132 | "value" => "г Москва", 133 | "data" => ["kladr_id" => "7700000000000"] 134 | ]; 135 | $response = [ 136 | "location" => $expected 137 | ]; 138 | $this->mockResponse($response); 139 | $actual = $this->api->iplocate("212.45.30.108"); 140 | $this->assertEquals($actual, $expected); 141 | } 142 | 143 | public function testIplocateNotFound() 144 | { 145 | $response = [ 146 | "location" => null 147 | ]; 148 | $this->mockResponse($response); 149 | $actual = $this->api->iplocate("212.45.30.108"); 150 | $this->assertNull($actual); 151 | } 152 | 153 | public function testSuggest() 154 | { 155 | $expected = [ 156 | ["value" => "г Москва, ул Сухонская", "data" => ["kladr_id" => "77000000000283600"]], 157 | ["value" => "г Москва, ул Сухонская, д 1", "data" => ["kladr_id" => "7700000000028360009"]] 158 | ]; 159 | $response = [ 160 | "suggestions" => $expected 161 | ]; 162 | $this->mockResponse($response); 163 | $actual = $this->api->suggest("address", "мск сухонская"); 164 | $this->assertEquals($actual, $expected); 165 | } 166 | 167 | public function testSuggestRequest() 168 | { 169 | $this->mockResponse([ "suggestions" => [] ]); 170 | $kwargs = [ 171 | "to_bound" => ["value" => "city"] 172 | ]; 173 | $this->api->suggest("address", "samara", 10, $kwargs); 174 | $expected = ["query" => "samara", "count" => 10, "to_bound" => ["value" => "city"]]; 175 | $actual = $this->getLastRequest(); 176 | $this->assertEquals($expected, $actual); 177 | } 178 | 179 | public function testSuggestNotFound() 180 | { 181 | $expected = []; 182 | $response = [ 183 | "suggestions" => $expected 184 | ]; 185 | $this->mockResponse($response); 186 | $actual = $this->api->suggest("address", "whatever"); 187 | $this->assertEquals($actual, $expected); 188 | } 189 | } 190 | --------------------------------------------------------------------------------