├── .envrc ├── .gitattributes ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ ├── CD.yml │ └── CI.yml ├── .gitignore ├── .php-cs-fixer.dist.php ├── .pre-commit-config.yaml ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── composer.json ├── docs ├── addressesValidateExample.md ├── createLabelFromRate.md ├── createLabelFromShipmentDetailsExample.md ├── getRatesWithShipmentDetailsExample.md ├── listCarriersExample.md ├── shipengine-php-docs │ ├── classes │ │ ├── ShipEngine-Message-AccountStatusException.html │ │ ├── ShipEngine-Message-BusinessRuleException.html │ │ ├── ShipEngine-Message-Events-RequestSentEvent.html │ │ ├── ShipEngine-Message-Events-ResponseReceivedEvent.html │ │ ├── ShipEngine-Message-Events-ShipEngineEvent.html │ │ ├── ShipEngine-Message-Events-ShipEngineEventListener.html │ │ ├── ShipEngine-Message-InvalidFieldValueException.html │ │ ├── ShipEngine-Message-RateLimitExceededException.html │ │ ├── ShipEngine-Message-SecurityException.html │ │ ├── ShipEngine-Message-ShipEngineException.html │ │ ├── ShipEngine-Message-SystemException.html │ │ ├── ShipEngine-Message-ValidationException.html │ │ ├── ShipEngine-Model-Address-Address.html │ │ ├── ShipEngine-Model-Address-AddressValidateResult.html │ │ ├── ShipEngine-Model-Carriers-Carrier.html │ │ ├── ShipEngine-Model-Carriers-CarrierAccount.html │ │ ├── ShipEngine-Model-Package-Location.html │ │ ├── ShipEngine-Model-Package-Package.html │ │ ├── ShipEngine-Model-Package-Shipment.html │ │ ├── ShipEngine-Model-Package-TrackPackageResult.html │ │ ├── ShipEngine-Model-Package-TrackingEvent.html │ │ ├── ShipEngine-Model-Package-TrackingQuery.html │ │ ├── ShipEngine-Service-Address-AddressService.html │ │ ├── ShipEngine-Service-Carriers-CarrierAccountService.html │ │ ├── ShipEngine-Service-Package-TrackPackageService.html │ │ ├── ShipEngine-Service-ShipEngineConfig.html │ │ ├── ShipEngine-ShipEngine.html │ │ ├── ShipEngine-ShipEngineClient.html │ │ ├── ShipEngine-ShipEngineConfig.html │ │ ├── ShipEngine-Util-Arr.html │ │ ├── ShipEngine-Util-Assert.html │ │ ├── ShipEngine-Util-Constants-CarrierNames.html │ │ ├── ShipEngine-Util-Constants-Carriers.html │ │ ├── ShipEngine-Util-Constants-Endpoints.html │ │ ├── ShipEngine-Util-Constants-ErrorCode.html │ │ ├── ShipEngine-Util-Constants-ErrorSource.html │ │ ├── ShipEngine-Util-Constants-ErrorType.html │ │ ├── ShipEngine-Util-Constants-RPCMethods.html │ │ ├── ShipEngine-Util-Constants-TrackingStatus.html │ │ ├── ShipEngine-Util-Getters.html │ │ ├── ShipEngine-Util-InvalidFieldValueException.html │ │ ├── ShipEngine-Util-IsoString.html │ │ ├── ShipEngine-Util-Json.html │ │ ├── ShipEngine-Util-ShipEngineLogger.html │ │ ├── ShipEngine-Util-ShipEngineSerializer.html │ │ └── ShipEngine-Util-VersionInfo.html │ ├── css │ │ ├── base.css │ │ ├── normalize.css │ │ └── template.css │ ├── files │ │ ├── src-message-accountstatusexception.html │ │ ├── src-message-businessruleexception.html │ │ ├── src-message-events-requestsentevent.html │ │ ├── src-message-events-responsereceivedevent.html │ │ ├── src-message-events-shipengineevent.html │ │ ├── src-message-events-shipengineeventlistener.html │ │ ├── src-message-invalidfieldvalueexception.html │ │ ├── src-message-ratelimitexceededexception.html │ │ ├── src-message-securityexception.html │ │ ├── src-message-shipengineexception.html │ │ ├── src-message-systemexception.html │ │ ├── src-message-validationexception.html │ │ ├── src-model-address-address.html │ │ ├── src-model-address-addressvalidateresult.html │ │ ├── src-model-carriers-carrier.html │ │ ├── src-model-carriers-carrieraccount.html │ │ ├── src-model-package-location.html │ │ ├── src-model-package-package.html │ │ ├── src-model-package-shipment.html │ │ ├── src-model-package-trackingevent.html │ │ ├── src-model-package-trackingquery.html │ │ ├── src-model-package-trackpackageresult.html │ │ ├── src-service-address-addressservice.html │ │ ├── src-service-carriers-carrieraccountservice.html │ │ ├── src-service-package-trackpackageservice.html │ │ ├── src-service-shipengineconfig.html │ │ ├── src-shipengine.html │ │ ├── src-shipengineclient.html │ │ ├── src-shipengineconfig.html │ │ ├── src-util-arr.html │ │ ├── src-util-assert.html │ │ ├── src-util-constants-carriernames.html │ │ ├── src-util-constants-carriers.html │ │ ├── src-util-constants-endpoints.html │ │ ├── src-util-constants-errorcode.html │ │ ├── src-util-constants-errorsource.html │ │ ├── src-util-constants-errortype.html │ │ ├── src-util-constants-rpcmethods.html │ │ ├── src-util-constants-trackingstatus.html │ │ ├── src-util-getters.html │ │ ├── src-util-isostring.html │ │ ├── src-util-json.html │ │ ├── src-util-shipenginelogger.html │ │ ├── src-util-shipengineserializer.html │ │ └── src-util-versioninfo.html │ ├── graphs │ │ └── classes.html │ ├── index.html │ ├── indices │ │ └── files.html │ ├── js │ │ ├── search.js │ │ └── searchIndex.js │ ├── namespaces │ │ ├── default.html │ │ ├── shipengine-message-events.html │ │ ├── shipengine-message.html │ │ ├── shipengine-model-address.html │ │ ├── shipengine-model-carriers.html │ │ ├── shipengine-model-package.html │ │ ├── shipengine-model.html │ │ ├── shipengine-service-address.html │ │ ├── shipengine-service-carriers.html │ │ ├── shipengine-service-package.html │ │ ├── shipengine-service.html │ │ ├── shipengine-util-constants.html │ │ ├── shipengine-util.html │ │ └── shipengine.html │ └── packages │ │ ├── ShipEngine-Message-Events.html │ │ ├── ShipEngine-Message.html │ │ ├── ShipEngine-Model-Address.html │ │ ├── ShipEngine-Model-Carriers.html │ │ ├── ShipEngine-Model-Package.html │ │ ├── ShipEngine-Model.html │ │ ├── ShipEngine-Service-Address.html │ │ ├── ShipEngine-Service-Carriers.html │ │ ├── ShipEngine-Service-Package.html │ │ ├── ShipEngine-Service.html │ │ ├── ShipEngine-Util-Constants.html │ │ ├── ShipEngine-Util.html │ │ ├── ShipEngine.html │ │ └── default.html ├── trackUsingCarrierCodeAndTrackingNumberExample.md ├── trackUsingLabelIdExample.md └── voidLabelExample.md ├── phpunit.xml ├── ruleset.xml ├── shell.nix ├── src ├── Message │ ├── AccountStatusException.php │ ├── BusinessRuleException.php │ ├── InvalidFieldValueException.php │ ├── RateLimitExceededException.php │ ├── SecurityException.php │ ├── ShipEngineException.php │ ├── SystemException.php │ ├── TimeoutException.php │ └── ValidationException.php ├── ShipEngine.php ├── ShipEngineClient.php ├── ShipEngineConfig.php └── Util │ ├── Arr.php │ ├── Assert.php │ ├── Constants │ └── Endpoints.php │ ├── Getters.php │ ├── IsoString.php │ ├── Json.php │ ├── ShipEngineLogger.php │ └── ShipEngineSerializer.php ├── tests ├── ShipEngineClientTest.php ├── ShipEngineConfigTest.php ├── ShipEngineTest.php └── Util │ ├── ArrTest.php │ ├── Foo.php │ ├── GettersTest.php │ ├── IsoStringTest.php │ ├── JsonTest.php │ ├── ShipEngineLoggerTest.php │ └── ShipEngineSerializerTest.php └── version.txt /.envrc: -------------------------------------------------------------------------------- 1 | use nix 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Git attributes 2 | # https://git-scm.com/docs/gitattributes 3 | # https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes 4 | 5 | # Normalize line endings for all files that git determines to be text. 6 | # https://git-scm.com/docs/gitattributes#gitattributes-Settostringvalueauto 7 | * text=auto 8 | 9 | # Normalize line endings to LF on checkin, and do NOT convert to CRLF when checking-out on Windows. 10 | # https://git-scm.com/docs/gitattributes#gitattributes-Settostringvaluelf 11 | *.txt text eol=lf 12 | *.html text eol=lf 13 | *.md text eol=lf 14 | *.css text eol=lf 15 | *.scss text eol=lf 16 | *.map text eol=lf 17 | *.js text eol=lf 18 | *.jsx text eol=lf 19 | *.ts text eol=lf 20 | *.tsx text eol=lf 21 | *.json text eol=lf 22 | *.yml text eol=lf 23 | *.yaml text eol=lf 24 | *.xml text eol=lf 25 | *.svg text eol=lf -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, religion, or sexual identity 11 | and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the 27 | overall community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or 32 | advances of any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email 36 | address, without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | anthony.shull@autane.com or james.messinger@auctane.com. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series 87 | of actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or 94 | permanent ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within 114 | the community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.0, available at 120 | [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available 127 | at [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | 135 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to ShipEngine PHP 2 | 3 | #### Table of Contents 4 | 5 | [Code of Conduct](#code-of-conduct) 6 | 7 | ## Code of Conduct 8 | 9 | This project and everyone participating in it is governed by the [ShipEngine Code of Conduct](CODE_OF_CONDUCT.md). 10 | By participating, you are expected to uphold this code. 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/workflows/CD.yml: -------------------------------------------------------------------------------- 1 | name: CD 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | release-please: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: GoogleCloudPlatform/release-please-action@v2 13 | id: release 14 | with: 15 | release-type: simple 16 | package-name: shipengine/shipengine 17 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | name: shipengine-php 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | 11 | env: 12 | COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} 13 | ACTIONS_ALLOW_UNSECURE_COMMANDS: true 14 | 15 | jobs: 16 | ci: 17 | name: shipengine-php test suite 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v2 21 | with: 22 | submodules: true 23 | token: ${{ secrets.GITHUB_TOKEN }} 24 | - uses: technote-space/toc-generator@v4 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | - uses: shivammathur/setup-php@v2 28 | with: 29 | php-version: "7.4" 30 | tools: phpcs, phpstan, phpunit, php-cs-fixer 31 | extensions: xdebug 32 | runner_github_workspace_path: ${{ github.workspace }} 33 | - run: composer install 34 | - run: php-cs-fixer fix -vvv --config=.php-cs-fixer.dist.php 35 | # - run: phpcs --standard=./ruleset.xml PSR2 src 36 | - run: phpstan analyse src --level 5 37 | - run: phpunit 38 | - run: ./vendor/bin/php-coveralls --coverage_clover=build/logs/clover.xml -v 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### VisualStudioCode 2 | .vscode/* 3 | !.vscode/settings.json 4 | !.vscode/tasks.json 5 | !.vscode/launch.json 6 | !.vscode/extensions.json 7 | *.code-workspace 8 | 9 | # Local History for Visual Studio Code 10 | .history/ 11 | 12 | ### JetBrains 13 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 14 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 15 | 16 | # User-specific stuff 17 | .idea/**/workspace.xml 18 | .idea/**/tasks.xml 19 | .idea/**/usage.statistics.xml 20 | .idea/**/dictionaries 21 | .idea/**/shelf 22 | 23 | # Generated files 24 | .idea/**/contentModel.xml 25 | 26 | # Sensitive or high-churn files 27 | .idea/**/dataSources/ 28 | .idea/**/dataSources.ids 29 | .idea/**/dataSources.local.xml 30 | .idea/**/sqlDataSources.xml 31 | .idea/**/dynamic.xml 32 | .idea/**/uiDesigner.xml 33 | .idea/**/dbnavigator.xml 34 | 35 | # Gradle 36 | .idea/**/gradle.xml 37 | .idea/**/libraries 38 | 39 | # Gradle and Maven with auto-import 40 | # When using Gradle or Maven with auto-import, you should exclude module files, 41 | # since they will be recreated, and may cause churn. Uncomment if using 42 | # auto-import. 43 | # .idea/artifacts 44 | # .idea/compiler.xml 45 | # .idea/jarRepositories.xml 46 | # .idea/modules.xml 47 | # .idea/*.iml 48 | # .idea/modules 49 | # *.iml 50 | # *.ipr 51 | 52 | # CMake 53 | cmake-build-*/ 54 | 55 | # Mongo Explorer plugin 56 | .idea/**/mongoSettings.xml 57 | 58 | # File-based project format 59 | *.iws 60 | 61 | # IntelliJ 62 | out/ 63 | .idea/ 64 | 65 | # mpeltonen/sbt-idea plugin 66 | .idea_modules/ 67 | 68 | # JIRA plugin 69 | atlassian-ide-plugin.xml 70 | 71 | # Cursive Clojure plugin 72 | .idea/replstate.xml 73 | 74 | # Crashlytics plugin (for Android Studio and IntelliJ) 75 | com_crashlytics_export_strings.xml 76 | crashlytics.properties 77 | crashlytics-build.properties 78 | fabric.properties 79 | 80 | # Editor-based Rest Client 81 | .idea/httpRequests 82 | 83 | # Android studio 3.1+ serialized cache file 84 | .idea/caches/build_file_checksums.ser 85 | 86 | # Micellaneous Locals 87 | *~ 88 | .DS_Store 89 | vendor 90 | composer.lock 91 | config.yaml 92 | .phpdoc 93 | reports 94 | build 95 | .gitmodules 96 | 97 | # Simengine 98 | ./sim 99 | 100 | # Nix Config 101 | ./shell.nix 102 | 103 | # Docker 104 | Dockerfile 105 | docker-compose.yml 106 | docker-compose.yaml 107 | 108 | # PHP CS Fixer 109 | .php_cs 110 | .php_cs.cache 111 | 112 | # PHP Unit 113 | .phpunit.* 114 | 115 | # Locals 116 | foo.php 117 | baz.php 118 | 119 | logs 120 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | exclude('vendor') 5 | ->exclude('.github') 6 | ->ignoreDotFiles(true) 7 | ->ignoreVCS(true) 8 | ->in(__DIR__ . '/src') 9 | ->in(__DIR__ . '/tests'); 10 | 11 | $config = new PhpCsFixer\Config(); 12 | return $config->setRules([ 13 | '@PSR2' => true, 14 | 'strict_param' => true 15 | ]) 16 | ->setRiskyAllowed(true) 17 | ->setFinder($finder); 18 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v2.3.0 4 | hooks: 5 | - id: check-yaml 6 | - id: end-of-file-fixer 7 | - id: trailing-whitespace 8 | - id: forbid-new-submodules 9 | - repo: https://github.com/digitalpulp/pre-commit-php.git 10 | rev: 1.4.0 11 | hooks: 12 | - id: php-unit 13 | - id: php-cs 14 | files: \.(php)$ 15 | args: [ --standard=PSR2 src ] 16 | - id: php-stan 17 | files: \.(php)$ 18 | args: [ analyse src --level 5 ] 19 | - id: php-cs-fixer 20 | files: \.(php)$ 21 | args: [ -vv --config=.php-cs-fixer.dist.php ] 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 1.0.0 (2021-08-04) 4 | 5 | ### Bug Fixes 6 | 7 | - bump version number ([2eb5d71](https://www.github.com/ShipEngine/shipengine-php/commit/2eb5d710f82ccefd2110a720394234e47e38040e)) 8 | - implement CD w/ release please ([5325e40](https://www.github.com/ShipEngine/shipengine-php/commit/5325e40f0bff35f8cda1fc5f67ce5f461345a905)) 9 | 10 | ## 1.0.1 11 | 12 | ### Changes 13 | 14 | - increase default timeout from 15s to 60s 15 | 16 | ## 1.0.2 17 | 18 | ### Changes 19 | 20 | - Added error code FundingSourceMissingConfiguration 21 | - Added error code FundingSourceError 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/bash 2 | .DEFAULT_GOAL := help 3 | 4 | .PHONY: help check-tag tag release full_release 5 | 6 | help: 7 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 8 | 9 | check-tag: ## Ensures that the TAG variable was passed to the make command. 10 | $(if $(TAG),,$(error TAG is not defined. Pass via "TAG=X.Y.Z make tag - where X, Y, and Z are major, minor, and patch version numbers")) 11 | 12 | # Creates a release but does not push it. This task updates the changelog with the TAG environment variable, 13 | #replaces the VERSION constant in src/ShipEngine.php, and ensures that the source is still valid after updating, 14 | # commits the changelog and updated VERSION constant, creates an annotated git tag using 15 | # chag (https://github.com/mtdowling/chag), and prints out a diff of the last commit. 16 | tag: check-tag ## Creates a packagist release but does not push it. 17 | TAG=$(TAG) bash ./scripts/bumpVersion.sh 18 | @echo "Tagging repository $(TAG) for release" 19 | chag update $(TAG) 20 | git commit -a -m '$(TAG) packagist release' 21 | chag tag 22 | @echo "A Packagist release has been created. Push using 'make release' to publish to Packagist." 23 | @echo "Changes made in the release commit:" 24 | git diff HEAD~1 HEAD 25 | 26 | # Creates a release based on the master branch and latest tag. This task 27 | # pushes the latest tag, pushes master. Use "TAG=X.Y.Z make tag" to create a release, 28 | # and use "make release" to push a release. 29 | release: check-tag ## Publish release to Packagist. 30 | git push origin master 31 | git push origin $(TAG) 32 | 33 | full-release: tag release ## Tags the repo, pushes the tag, and publishes a release to Packagist. 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![ShipEngine](https://shipengine.github.io/img/shipengine-logo-wide.png)](https://shipengine.com) 2 | 3 | ShipEngine PHP 4 | ============== 5 | 6 | [![Build Status](https://github.com/ShipEngine/shipengine-php/workflows/shipengine-php/badge.svg)](https://github.com/ShipEngine/shipengine-php/actions) 7 | [![Coverage Status](https://coveralls.io/repos/github/ShipEngine/shipengine-php/badge.svg?branch=main&t=SkXqIE)](https://coveralls.io/github/ShipEngine/shipengine-php?branch=main) 8 | [![Latest Version](https://poser.pugx.org/shipengine/shipengine/v)](//packagist.org/packages/shipengine/shipengine) 9 | [![License](https://poser.pugx.org/shipengine/shipengine/license)](//packagist.org/packages/shipengine/shipengine) 10 | ![OS Compatibility](https://shipengine.github.io/img/badges/os-badges.svg) 11 | 12 | A PHP library built on the [ShipEngine API](https://shipengine.com) offering low-level access as well as convenience methods. 13 | 14 | 15 | 16 | 17 | 18 | **Table of Contents** 19 | 20 | - [Quick Start](#quick-start) 21 | - [Examples](#examples) 22 | - [Methods](#methods) 23 | - [Class Objects](#class-objects) 24 | - [Instantiate ShipEngine Class](#instantiate-shipengine-class) 25 | - [Testing](#testing) 26 | - [Linting](#linting) 27 | - [Contributing](#contributing) 28 | 29 | 30 | 31 | Quick Start 32 | =========== 33 | Install ShipEngine via [Composer](https://getcomposer.org/): 34 | ```bash 35 | composer require shipengine/shipengine 36 | ``` 37 | - The only configuration requirement is an [API Key](https://www.shipengine.com/docs/auth/#api-keys). 38 | 39 | > The following example assumes that you have already set the `SHIPENGINE_API_KEY` environment variable with your Api Key using `putenv()`. 40 | 41 | Examples 42 | ======== 43 | 44 | Methods 45 | ------- 46 | - [validateAddress](./docs/addressValidateExample.md "Validate Address method documentation") - Indicates whether the provided address is valid. If the 47 | address is valid, the method returns a normalized version of the address based on the standards of the country in 48 | which the address resides. 49 | - [normalizeAddress](./docs/normalizeAddressExample.md "Normalize Address method documentation") - Returns a normalized, or standardized, version of the 50 | address. If the address cannot be normalized, an error is returned. 51 | - [trackPackage](./docs/trackPackageExample.md "Track Package method documentation") - Track a package by `packageId` or by `carrierCode` and `trackingNumber`. This method returns 52 | the all tracking events for a given shipment. 53 | 54 | Class Objects 55 | ------------- 56 | - [ShipEngine]() - A configurable entry point to the ShipEngine API SDK, this class provides convenience methods 57 | for various ShipEngine API Services. 58 | 59 | Instantiate ShipEngine Class 60 | ---------------------------- 61 | ```php 62 | $apiKey, 84 | 'pageSize' => 75, 85 | 'retries' => 3, 86 | 'timeout' => \DateInterval('PT60S') 87 | ); 88 | 89 | $shipengine = new ShipEngine($config); 90 | ``` 91 | 92 | Testing 93 | ======= 94 | - You can now run all tests using [PHPUnit](https://phpunit.de/): 95 | _phpunit_ 96 | ```bash 97 | composer test 98 | ``` 99 | 100 | Linting 101 | ======= 102 | You can utilize the `composer` script that runs **phpcs**, **phpstan**, and **php-cs-fixer**. 103 | ```bash 104 | composer lint 105 | ``` 106 | 107 | Contributing 108 | ============ 109 | Contributions, enhancements, and bug-fixes are welcome! [Open an issue](https://github.com/ShipEngine/shipengine-php/issues) 110 | on GitHub and [submit a pull request](https://github.com/ShipEngine/shipengine-php/pulls). 111 | 112 | We are managing `php environment` with [Nix](https://nixos.org/download.html "Nix Website") 113 | and [Direnv](https://direnv.net/docs/installation.html "Direnv Install page"), and we recommend downloading 114 | them before contributing to this project. 115 | 116 | - The quickest way to install Nix is to open a terminal and run the following command, make sure to follow the 117 | instructions output by the installation script: 118 | ```bash 119 | curl -L https://nixos.org/nix/install | sh 120 | ``` 121 | 122 | - Next, install `Direnv` using one of th methods outlined on their install page here: 123 | [Direnv Installation](https://direnv.net/docs/installation.html "Direnv Install page") 124 | 125 | - Lastly, you will need open your terminal and while this repository the current working directory and run `direnv allow`, 126 | this will allow `direnv` to auto-load every time you navigate to the repo. This will automatically load the `Nix` 127 | environment which is running the proper version of `PHP and Xdebug (PHP 7.4)` this repository supports/requires. 128 | ```bash 129 | direnv allow 130 | ``` 131 | - You will need to `cd` out of the project directory after you first install `direnv` and run `direnv allow` from within 132 | the project directory, and then `cd` back into the project directory for `direnv` to auto-load the `Nix` environment properly. 133 | 134 | This project also makes use of `pre-commit hooks` to help run lint and tests at time of commit, to leverage this you will 135 | need to install [pre-commit](https://pre-commit.com/#installation) and run the following command while in this repo: 136 | 137 | ```bash 138 | pre-commit install 139 | ``` 140 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shipengine/shipengine", 3 | "type": "library", 4 | "description": "PHP library for the ShipEngine API.", 5 | "keywords": [ 6 | "shipengine", 7 | "api", 8 | "shipping" 9 | ], 10 | "homepage": "https://github.com/ShipEngine/shipengine-php", 11 | "license": "Apache-2.0", 12 | "authors": [ 13 | { 14 | "name": "shipengine/shipengine contributors", 15 | "homepage": "https://github.com/ShipEngine/shipengine-php/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=7.4", 20 | "cbschuld/php-uuid-base58": "^1.0", 21 | "guzzlehttp/guzzle": "^7.0", 22 | "php-http/client-common": "^2.3.0", 23 | "php-http/discovery": "^1.12.0", 24 | "php-http/httplug": "^2.2.0", 25 | "php-http/message": "^1.10.0", 26 | "php-http/message-factory": "^1.0.2", 27 | "psr/http-client": "^1.0.1", 28 | "psr/http-message": "^1.0", 29 | "symfony/event-dispatcher": "^5.2", 30 | "symfony/property-access": "^5.2", 31 | "symfony/serializer": "^5.2" 32 | }, 33 | "require-dev": { 34 | "friendsofphp/php-cs-fixer": "^2.18", 35 | "guzzlehttp/psr7": "^1.7.0", 36 | "mockery/mockery": "^1.4", 37 | "php-coveralls/php-coveralls": "^2.4", 38 | "php-http/guzzle7-adapter": "^0.1.1", 39 | "phpdocumentor/phpdocumentor": "^3.0.0", 40 | "phpstan/phpstan": "^0.12.53", 41 | "phpunit/php-code-coverage": "^9.2", 42 | "phpunit/phpunit": "^9", 43 | "squizlabs/php_codesniffer": "3.*" 44 | }, 45 | "autoload": { 46 | "psr-4": { 47 | "ShipEngine\\": "src/" 48 | } 49 | }, 50 | "config": { 51 | "sort-packages": true, 52 | "allow-plugins": { 53 | "symfony/flex": true 54 | } 55 | }, 56 | "scripts": { 57 | "lint": "composer phpcs-fixer && composer phpcs && composer phpstan", 58 | "test": "./vendor/bin/phpunit", 59 | "phpstan": "./vendor/bin/phpstan analyse src --level 5", 60 | "phpcs": "./vendor/bin/phpcs --standard=PSR2 src", 61 | "phpcs-fixer": "./vendor/bin/php-cs-fixer fix -vv --config=.php-cs-fixer.dist.php", 62 | "gen:docs": "./vendor/bin/phpdoc -d src -t docs/shipengine-php-docs" 63 | }, 64 | "minimum-stability": "dev", 65 | "prefer-stable": true 66 | } 67 | -------------------------------------------------------------------------------- /docs/addressesValidateExample.md: -------------------------------------------------------------------------------- 1 | Validate Addresses 2 | ================================ 3 | [ShipEngine](www.shipengine.com) allows you to validate an array of addresses before using it to create a shipment to ensure 4 | accurate delivery of your packages. Please see [our docs](https://www.shipengine.com/docs/addresses/validation/) to learn more about validating addresses. 5 | 6 | Input Parameters 7 | ------------------------------------ 8 | The `validateAddresses` method accepts an array of addresses as seen in the documentation above. 9 | 10 | Output 11 | -------------------------------- 12 | The `validateAddresses` method returns an array of address validation result objects. 13 | 14 | Example 15 | ============================== 16 | ```php 17 | use ShipEngine\ShipEngine; 18 | use ShipEngine\Message\ShipEngineException; 19 | 20 | function validateAddressesDemoFunction() { 21 | $client = new ShipEngine('API-Key'); 22 | 23 | $address = [ 24 | [ 25 | "name" => "John Smith", 26 | "company_name" => "ShipStation", 27 | "address_line1" => "3800 N Lamar Blvd", 28 | "address_line2" => "#220", 29 | "postal_code" => '78756', 30 | "country_code" => "US", 31 | "address_residential_indicator" => 'no', 32 | ], [ 33 | "name" => "John Smith", 34 | "company" => "ShipMate", 35 | "city_locality" => "Toronto", 36 | "state_province" => "On", 37 | "postal_code" => "M6K 3C3", 38 | "country_code" => "CA", 39 | "address_line1" => "123 Foo", 40 | ] 41 | ]; 42 | 43 | try { 44 | print_r($client->validateAddresses($address)); 45 | } catch (ShipEngineException $e) { 46 | print_r($e -> getMessage()); 47 | } 48 | } 49 | 50 | validateAddressesDemoFunction(); 51 | 52 | ``` 53 | 54 | Example Output 55 | ----------------------------------------------------- 56 | 57 | ### Array of connected carrier accounts 58 | ```php 59 | Array 60 | ( 61 | [0] => Array 62 | ( 63 | [status] => verified 64 | [original_address] => Array 65 | ( 66 | [name] => John Smith 67 | [phone] => 68 | [company_name] => ShipStation 69 | [address_line1] => 3800 N Lamar Blvd 70 | [address_line2] => #220 71 | [address_line3] => 72 | [city_locality] => 73 | [state_province] => 74 | [postal_code] => 78756 75 | [country_code] => US 76 | [address_residential_indicator] => no 77 | ) 78 | 79 | [matched_address] => Array 80 | ( 81 | [name] => JOHN SMITH 82 | [phone] => 83 | [company_name] => SHIPSTATION 84 | [address_line1] => 3800 N LAMAR BLVD STE 220 85 | [address_line2] => 86 | [address_line3] => 87 | [city_locality] => AUSTIN 88 | [state_province] => TX 89 | [postal_code] => 78756-0003 90 | [country_code] => US 91 | [address_residential_indicator] => no 92 | ) 93 | 94 | [messages] => Array 95 | ( 96 | ) 97 | 98 | ) 99 | 100 | [1] => Array 101 | ( 102 | [status] => error 103 | [original_address] => Array 104 | ( 105 | [name] => John Smith 106 | [phone] => 107 | [company_name] => 108 | [address_line1] => 123 Foo 109 | [address_line2] => 110 | [address_line3] => 111 | [city_locality] => Toronto 112 | [state_province] => On 113 | [postal_code] => M6K 3C3 114 | [country_code] => CA 115 | [address_residential_indicator] => unknown 116 | ) 117 | 118 | [matched_address] => 119 | [messages] => Array 120 | ( 121 | [0] => Array 122 | ( 123 | [code] => a1002 124 | [message] => Could not match the inputted street name to a unique street name. No matches or too many matches were found. 125 | [type] => error 126 | [detail_code] => street_does_not_match_unique_street_name 127 | ) 128 | 129 | [1] => Array 130 | ( 131 | [code] => a1004 132 | [message] => This address has been partially verified down to the city level. This is NOT the highest level possible with the data provided. 133 | [type] => error 134 | [detail_code] => partially_verified_to_city_level 135 | ) 136 | 137 | ) 138 | 139 | ) 140 | 141 | ) 142 | ``` -------------------------------------------------------------------------------- /docs/createLabelFromRate.md: -------------------------------------------------------------------------------- 1 | Create Label From Rate 2 | ====================================== 3 | When retrieving rates for shipments using the `getRatesWithShipmentDetails` method, the returned information contains a `rateId` property that can be used to purchase a label without having to refill in the shipment information repeatedly. Please see [our docs](https://www.shipengine.com/docs/labels/create-from-rate/) to learn more about creating shipping labels from rates. 4 | 5 | Input Parameters 6 | ------------------------------------- 7 | 8 | The `createLabelFromRate` method requires a `rateId` and label params as seen in the documentation above. 9 | 10 | Output 11 | -------------------------------- 12 | The `createLabelFromRate` method returns the label that was created. 13 | 14 | Example 15 | ============================== 16 | ```php 17 | use ShipEngine\ShipEngine; 18 | use ShipEngine\Message\ShipEngineException; 19 | 20 | function createLabelFromRateDemoFunction() { 21 | $client = new ShipEngine('API-Key'); 22 | 23 | $params = [ 24 | "validate_address" => "no_validation", 25 | "label_layout" => "4x6", 26 | "label_format" => "pdf", 27 | "label_download_type" => "url", 28 | "display_scheme" => "label" 29 | ]; 30 | 31 | try { 32 | print_r($client-> createLabelFromRate('se-797094871', $params)); 33 | } catch (ShipEngineException $e) { 34 | print_r($e -> getMessage()); 35 | } 36 | } 37 | 38 | createLabelFromRateDemoFunction(); 39 | 40 | ``` 41 | 42 | Example Output 43 | ----------------------------------------------------- 44 | 45 | ### Successful Create Label From Rate Result 46 | ```php 47 | Array 48 | ( 49 | [label_id] => se-75484277 50 | [status] => completed 51 | [shipment_id] => se-144316600 52 | [ship_date] => 2021-08-04T00:00:00Z 53 | [created_at] => 2021-08-04T17:29:10.3686928Z 54 | [shipment_cost] => Array 55 | ( 56 | [currency] => usd 57 | [amount] => 11.63 58 | ) 59 | 60 | [insurance_cost] => Array 61 | ( 62 | [currency] => usd 63 | [amount] => 0 64 | ) 65 | 66 | [tracking_number] => 9405511899560334465315 67 | [is_return_label] => 68 | [rma_number] => 69 | [is_international] => 70 | [batch_id] => 71 | [carrier_id] => se-423887 72 | [service_code] => usps_priority_mail 73 | [package_code] => regional_rate_box_a 74 | [voided] => 75 | [voided_at] => 76 | [label_format] => pdf 77 | [display_scheme] => label 78 | [label_layout] => 4x6 79 | [trackable] => 1 80 | [label_image_id] => 81 | [carrier_code] => stamps_com 82 | [tracking_status] => in_transit 83 | [label_download] => Array 84 | ( 85 | [pdf] => https://api.shipengine.com/v1/downloads/10/I_F8RgnVBEGvt7ycgHHIGg/label-75484277.pdf 86 | [png] => https://api.shipengine.com/v1/downloads/10/I_F8RgnVBEGvt7ycgHHIGg/label-75484277.png 87 | [zpl] => https://api.shipengine.com/v1/downloads/10/I_F8RgnVBEGvt7ycgHHIGg/label-75484277.zpl 88 | [href] => https://api.shipengine.com/v1/downloads/10/I_F8RgnVBEGvt7ycgHHIGg/label-75484277.pdf 89 | ) 90 | 91 | [form_download] => 92 | [insurance_claim] => 93 | [packages] => Array 94 | ( 95 | [0] => Array 96 | ( 97 | [package_id] => 80105682 98 | [package_code] => regional_rate_box_a 99 | [weight] => Array 100 | ( 101 | [value] => 1 102 | [unit] => ounce 103 | ) 104 | 105 | [dimensions] => Array 106 | ( 107 | [unit] => inch 108 | [length] => 0 109 | [width] => 0 110 | [height] => 0 111 | ) 112 | 113 | [insured_value] => Array 114 | ( 115 | [currency] => usd 116 | [amount] => 0 117 | ) 118 | 119 | [tracking_number] => 9405511899560334465315 120 | [label_messages] => Array 121 | ( 122 | [reference1] => 123 | [reference2] => 124 | [reference3] => 125 | ) 126 | 127 | [external_package_id] => 128 | [sequence] => 1 129 | ) 130 | 131 | ) 132 | 133 | [charge_event] => carrier_default 134 | ) 135 | ``` -------------------------------------------------------------------------------- /docs/createLabelFromShipmentDetailsExample.md: -------------------------------------------------------------------------------- 1 | Create Label From Shipment Details 2 | ====================================== 3 | [ShipEngine](www.shipengine.com) allows you programmatically create shipping labels. Please see [our docs](https://www.shipengine.com/docs/labels/create-a-label/) to learn more about creating shipping labels. 4 | 5 | Input Parameters 6 | ------------------------------------- 7 | The `createLabelFromShipmentDetails` method accepts shipment related params as seen in the documentation above. 8 | 9 | Output 10 | -------------------------------- 11 | The `createLabelFromShipmentDetails` method returns the label that was created. 12 | 13 | Example 14 | ============================== 15 | ```php 16 | use ShipEngine\ShipEngine; 17 | use ShipEngine\Message\ShipEngineException; 18 | 19 | function createLabelFromShipmentDetailsDemoFunction() { 20 | $client = new ShipEngine('API-Key'); 21 | 22 | $details = [ 23 | "shipment" => [ 24 | "service_code" => "ups_ground", 25 | "ship_to" => [ 26 | "name" => "Jane Doe", 27 | "address_line1" => "525 S Winchester Blvd", 28 | "city_locality" => "San Jose", 29 | "state_province" => "CA", 30 | "postal_code" => "95128", 31 | "country_code" => "US", 32 | "address_residential_indicator" => "yes" 33 | ], 34 | "ship_from" => [ 35 | "name" => "John Doe", 36 | "company_name" => "Example Corp", 37 | "phone" => "555-555-5555", 38 | "address_line1" => "4009 Marathon Blvd", 39 | "city_locality" => "Austin", 40 | "state_province" => "TX", 41 | "postal_code" => "78756", 42 | "country_code" => "US", 43 | "address_residential_indicator" => "no" 44 | ], 45 | "packages" => [ 46 | [ 47 | "weight" => [ 48 | "value" => 20, 49 | "unit" => "ounce" 50 | ], 51 | "dimensions" => [ 52 | "height" => 6, 53 | "width" => 12, 54 | "length" => 24, 55 | "unit" => "inch" 56 | ] 57 | ] 58 | ] 59 | ] 60 | ]; 61 | 62 | try { 63 | print_r($client->createLabelFromShipmentDetails($details)); 64 | } catch (ShipEngineException $e) { 65 | print_r($e -> getMessage()); 66 | } 67 | } 68 | 69 | createLabelFromShipmentDetailsDemoFunction(); 70 | 71 | ``` 72 | 73 | Example Output 74 | ----------------------------------------------------- 75 | 76 | ### Successful Create Label From Shipment Details 77 | ```php 78 | Array 79 | ( 80 | [label_id] => se-75449505 81 | [status] => completed 82 | [shipment_id] => se-144329069 83 | [ship_date] => 2021-08-04T00:00:00Z 84 | [created_at] => 2021-08-04T15:40:26.7329234Z 85 | [shipment_cost] => Array 86 | ( 87 | [currency] => usd 88 | [amount] => 27.98 89 | ) 90 | 91 | [insurance_cost] => Array 92 | ( 93 | [currency] => usd 94 | [amount] => 0 95 | ) 96 | 97 | [tracking_number] => 1Z63R0960328699118 98 | [is_return_label] => 99 | [rma_number] => 100 | [is_international] => 101 | [batch_id] => 102 | [carrier_id] => se-423888 103 | [service_code] => ups_ground 104 | [package_code] => package 105 | [voided] => 106 | [voided_at] => 107 | [label_format] => pdf 108 | [display_scheme] => label 109 | [label_layout] => 4x6 110 | [trackable] => 1 111 | [label_image_id] => 112 | [carrier_code] => ups 113 | [tracking_status] => in_transit 114 | [label_download] => Array 115 | ( 116 | [pdf] => https://api.shipengine.com/v1/downloads/10/VF_Xyq2J002-GxtKSn_Plw/label-75449505.pdf 117 | [png] => https://api.shipengine.com/v1/downloads/10/VF_Xyq2J002-GxtKSn_Plw/label-75449505.png 118 | [zpl] => https://api.shipengine.com/v1/downloads/10/VF_Xyq2J002-GxtKSn_Plw/label-75449505.zpl 119 | [href] => https://api.shipengine.com/v1/downloads/10/VF_Xyq2J002-GxtKSn_Plw/label-75449505.pdf 120 | ) 121 | 122 | [form_download] => 123 | [insurance_claim] => 124 | [packages] => Array 125 | ( 126 | [0] => Array 127 | ( 128 | [package_id] => 80068779 129 | [package_code] => package 130 | [weight] => Array 131 | ( 132 | [value] => 20 133 | [unit] => ounce 134 | ) 135 | 136 | [dimensions] => Array 137 | ( 138 | [unit] => inch 139 | [length] => 24 140 | [width] => 12 141 | [height] => 6 142 | ) 143 | 144 | [insured_value] => Array 145 | ( 146 | [currency] => usd 147 | [amount] => 0 148 | ) 149 | 150 | [tracking_number] => 1Z63R0960328699118 151 | [label_messages] => Array 152 | ( 153 | [reference1] => 154 | [reference2] => 155 | [reference3] => 156 | ) 157 | 158 | [external_package_id] => 159 | [sequence] => 1 160 | ) 161 | 162 | ) 163 | 164 | [charge_event] => carrier_default 165 | ) 166 | ``` -------------------------------------------------------------------------------- /docs/shipengine-php-docs/css/template.css: -------------------------------------------------------------------------------- 1 | .phpdocumentor-summary { 2 | font-style: italic; 3 | } 4 | .phpdocumentor-description { 5 | margin-bottom: var(--spacing-md); 6 | } 7 | .phpdocumentor-element { 8 | position: relative; 9 | } 10 | 11 | .phpdocumentor .phpdocumentor-element__name { 12 | line-height: 1; 13 | } 14 | 15 | .phpdocumentor-element__package, 16 | .phpdocumentor-element__extends, 17 | .phpdocumentor-element__implements { 18 | display: block; 19 | font-size: var(--text-xxs); 20 | font-weight: normal; 21 | opacity: .7; 22 | } 23 | 24 | .phpdocumentor-element__package .phpdocumentor-breadcrumbs { 25 | display: inline; 26 | } 27 | 28 | .phpdocumentor-element:not(:last-child) { 29 | border-bottom: 1px solid var(--primary-color-lighten); 30 | padding-bottom: var(--spacing-lg); 31 | } 32 | 33 | .phpdocumentor-element.-deprecated .phpdocumentor-element__name { 34 | text-decoration: line-through; 35 | } 36 | 37 | .phpdocumentor-element__modifier { 38 | font-size: var(--text-xxs); 39 | padding: calc(var(--spacing-base-size) / 4) calc(var(--spacing-base-size) / 2); 40 | color: var(--text-color); 41 | background-color: var(--light-gray); 42 | border-radius: 3px; 43 | text-transform: uppercase; 44 | } 45 | .phpdocumentor-signature { 46 | display: inline-block; 47 | font-size: var(--text-sm); 48 | margin-bottom: var(--spacing-md); 49 | } 50 | 51 | .phpdocumentor-signature.-deprecated .phpdocumentor-signature__name { 52 | text-decoration: line-through; 53 | } 54 | .phpdocumentor-table-of-contents { 55 | } 56 | 57 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry { 58 | padding-top: var(--spacing-xs); 59 | margin-left: 2rem; 60 | display: flex; 61 | } 62 | 63 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry > a { 64 | flex: 0 1 auto; 65 | } 66 | 67 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry > span { 68 | flex: 1; 69 | white-space: nowrap; 70 | text-overflow: ellipsis; 71 | overflow: hidden; 72 | } 73 | 74 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry:after { 75 | content: ''; 76 | height: 12px; 77 | width: 12px; 78 | left: 16px; 79 | position: absolute; 80 | } 81 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-private:after { 82 | background: url('data:image/svg+xml;utf8,') no-repeat; 83 | } 84 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-protected:after { 85 | left: 13px; 86 | background: url('data:image/svg+xml;utf8,') no-repeat; 87 | } 88 | 89 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry:before { 90 | width: 1.25rem; 91 | height: 1.25rem; 92 | line-height: 1.25rem; 93 | background: transparent url('data:image/svg+xml;utf8,') no-repeat center center; 94 | content: ''; 95 | position: absolute; 96 | left: 0; 97 | border-radius: 50%; 98 | font-weight: 600; 99 | color: white; 100 | text-align: center; 101 | font-size: .75rem; 102 | margin-top: .2rem; 103 | } 104 | 105 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-method:before { 106 | content: 'M'; 107 | background-image: url('data:image/svg+xml;utf8,'); 108 | } 109 | 110 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-function:before { 111 | content: 'M'; 112 | background-image: url('data:image/svg+xml;utf8,'); 113 | } 114 | 115 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-property:before { 116 | content: 'P' 117 | } 118 | 119 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-constant:before { 120 | content: 'C'; 121 | background-color: transparent; 122 | background-image: url('data:image/svg+xml;utf8,'); 123 | } 124 | 125 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-class:before { 126 | content: 'C' 127 | } 128 | 129 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-interface:before { 130 | content: 'I' 131 | } 132 | 133 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-trait:before { 134 | content: 'T' 135 | } 136 | 137 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-namespace:before { 138 | content: 'N' 139 | } 140 | 141 | .phpdocumentor-table-of-contents .phpdocumentor-table-of-contents__entry.-package:before { 142 | content: 'P' 143 | } 144 | 145 | .phpdocumentor-table-of-contents dd { 146 | font-style: italic; 147 | margin-left: 2rem; 148 | } 149 | .phpdocumentor-element-found-in { 150 | position: absolute; 151 | top: 0; 152 | right: 0; 153 | font-size: var(--text-sm); 154 | color: gray; 155 | } 156 | .phpdocumentor-class-graph { 157 | width: 100%; height: 600px; border:1px solid black; overflow: hidden 158 | } 159 | 160 | .phpdocumentor-class-graph__graph { 161 | width: 100%; 162 | } 163 | .phpdocumentor-tag-list__definition { 164 | display: flex; 165 | } 166 | 167 | .phpdocumentor-tag-link { 168 | margin-right: var(--spacing-sm); 169 | } 170 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-model-carriers-carrier.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |

Documentation

23 | 24 | 27 | 37 | 38 | 42 |
43 | 44 |
45 |
46 | 47 | 50 | 87 | 88 |
89 |
    90 |
91 | 92 |
93 |

Carrier.php

94 | 95 | 96 | 97 |

98 | Interfaces, Classes and Traits 99 | 100 |

101 | 102 |
103 | 104 |
Carrier
105 |
Class Carrier - Immutable carrier object.
106 | 107 |
108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
116 |
117 |
118 |
119 |

Search results

120 | 121 |
122 |
123 |
    124 |
    125 |
    126 |
    127 |
    128 |
    129 | 130 | 131 |
    132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-model-package-package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
    22 |

    Documentation

    23 | 24 | 27 | 37 | 38 | 42 |
    43 | 44 |
    45 |
    46 | 47 | 50 | 87 | 88 |
    89 |
      90 |
    91 | 92 |
    93 |

    Package.php

    94 | 95 | 96 | 97 |

    98 | Interfaces, Classes and Traits 99 | 100 |

    101 | 102 |
    103 | 104 |
    Package
    105 |
    Class Package
    106 | 107 |
    108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
    116 |
    117 |
    118 |
    119 |

    Search results

    120 | 121 |
    122 |
    123 |
      124 |
      125 |
      126 |
      127 |
      128 |
      129 | 130 | 131 |
      132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-model-package-shipment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
      22 |

      Documentation

      23 | 24 | 27 | 37 | 38 | 42 |
      43 | 44 |
      45 |
      46 | 47 | 50 | 87 | 88 |
      89 |
        90 |
      91 | 92 |
      93 |

      Shipment.php

      94 | 95 | 96 | 97 |

      98 | Interfaces, Classes and Traits 99 | 100 |

      101 | 102 |
      103 | 104 |
      Shipment
      105 |
      Class Shipment
      106 | 107 |
      108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
      116 |
      117 |
      118 |
      119 |

      Search results

      120 | 121 |
      122 |
      123 |
        124 |
        125 |
        126 |
        127 |
        128 |
        129 | 130 | 131 |
        132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-service-shipengineconfig.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
        22 |

        Documentation

        23 | 24 | 27 | 37 | 38 | 42 |
        43 | 44 |
        45 |
        46 | 47 | 50 | 87 | 88 |
        89 |
          90 |
        91 | 92 |
        93 |

        ShipEngineConfig.php

        94 | 95 | 96 | 97 |

        98 | Interfaces, Classes and Traits 99 | 100 |

        101 | 102 |
        103 | 104 |
        ShipEngineConfig
        105 |
        106 | 107 |
        108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
        116 |
        117 |
        118 |
        119 |

        Search results

        120 | 121 |
        122 |
        123 |
          124 |
          125 |
          126 |
          127 |
          128 |
          129 | 130 | 131 |
          132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-shipengine.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
          22 |

          Documentation

          23 | 24 | 27 | 37 | 38 | 42 |
          43 | 44 |
          45 |
          46 | 47 | 50 | 87 | 88 |
          89 |
            90 |
          91 | 92 |
          93 |

          ShipEngine.php

          94 | 95 | 96 | 97 |

          98 | Interfaces, Classes and Traits 99 | 100 |

          101 | 102 |
          103 | 104 |
          ShipEngine
          105 |
          Exposes the functionality of the ShipEngine API.
          106 | 107 |
          108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
          116 |
          117 |
          118 |
          119 |

          Search results

          120 | 121 |
          122 |
          123 |
            124 |
            125 |
            126 |
            127 |
            128 |
            129 | 130 | 131 |
            132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-shipengineconfig.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
            22 |

            Documentation

            23 | 24 | 27 | 37 | 38 | 42 |
            43 | 44 |
            45 |
            46 | 47 | 50 | 87 | 88 |
            89 |
              90 |
            91 | 92 |
            93 |

            ShipEngineConfig.php

            94 | 95 | 96 | 97 |

            98 | Interfaces, Classes and Traits 99 | 100 |

            101 | 102 |
            103 | 104 |
            ShipEngineConfig
            105 |
            106 | 107 |
            108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
            116 |
            117 |
            118 |
            119 |

            Search results

            120 | 121 |
            122 |
            123 |
              124 |
              125 |
              126 |
              127 |
              128 |
              129 | 130 | 131 |
              132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-util-arr.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
              22 |

              Documentation

              23 | 24 | 27 | 37 | 38 | 42 |
              43 | 44 |
              45 |
              46 | 47 | 50 | 87 | 88 |
              89 |
                90 |
              91 | 92 |
              93 |

              Arr.php

              94 | 95 | 96 | 97 |

              98 | Interfaces, Classes and Traits 99 | 100 |

              101 | 102 |
              103 | 104 |
              Arr
              105 |
              Collects helper functions for Array presenting them as static methods.
              106 | 107 |
              108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
              116 |
              117 |
              118 |
              119 |

              Search results

              120 | 121 |
              122 |
              123 |
                124 |
                125 |
                126 |
                127 |
                128 |
                129 | 130 | 131 |
                132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-util-assert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
                22 |

                Documentation

                23 | 24 | 27 | 37 | 38 | 42 |
                43 | 44 |
                45 |
                46 | 47 | 50 | 87 | 88 |
                89 |
                  90 |
                91 | 92 |
                93 |

                Assert.php

                94 | 95 | 96 | 97 |

                98 | Interfaces, Classes and Traits 99 | 100 |

                101 | 102 |
                103 | 104 |
                Assert
                105 |
                Class Assert
                106 | 107 |
                108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
                116 |
                117 |
                118 |
                119 |

                Search results

                120 | 121 |
                122 |
                123 |
                  124 |
                  125 |
                  126 |
                  127 |
                  128 |
                  129 | 130 | 131 |
                  132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-util-constants-endpoints.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
                  22 |

                  Documentation

                  23 | 24 | 27 | 37 | 38 | 42 |
                  43 | 44 |
                  45 |
                  46 | 47 | 50 | 87 | 88 |
                  89 |
                    90 |
                  91 | 92 |
                  93 |

                  Endpoints.php

                  94 | 95 | 96 | 97 |

                  98 | Interfaces, Classes and Traits 99 | 100 |

                  101 | 102 |
                  103 | 104 |
                  Endpoints
                  105 |
                  106 | 107 |
                  108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
                  116 |
                  117 |
                  118 |
                  119 |

                  Search results

                  120 | 121 |
                  122 |
                  123 |
                    124 |
                    125 |
                    126 |
                    127 |
                    128 |
                    129 | 130 | 131 |
                    132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-util-getters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
                    22 |

                    Documentation

                    23 | 24 | 27 | 37 | 38 | 42 |
                    43 | 44 |
                    45 |
                    46 | 47 | 50 | 87 | 88 |
                    89 |
                      90 |
                    91 | 92 |
                    93 |

                    Getters.php

                    94 | 95 | 96 | 97 |

                    98 | Interfaces, Classes and Traits 99 | 100 |

                    101 | 102 |
                    103 | 104 | 105 |
                    Getters
                    106 |
                    Expose getters for private properties.
                    107 |
                    108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
                    116 |
                    117 |
                    118 |
                    119 |

                    Search results

                    120 | 121 |
                    122 |
                    123 |
                      124 |
                      125 |
                      126 |
                      127 |
                      128 |
                      129 | 130 | 131 |
                      132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-util-isostring.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
                      22 |

                      Documentation

                      23 | 24 | 27 | 37 | 38 | 42 |
                      43 | 44 |
                      45 |
                      46 | 47 | 50 | 87 | 88 |
                      89 |
                        90 |
                      91 | 92 |
                      93 |

                      IsoString.php

                      94 | 95 | 96 | 97 |

                      98 | Interfaces, Classes and Traits 99 | 100 |

                      101 | 102 |
                      103 | 104 |
                      IsoString
                      105 |
                      A string representing a Date, DateTime, or DateTime with Timezone.
                      106 | 107 |
                      108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
                      116 |
                      117 |
                      118 |
                      119 |

                      Search results

                      120 | 121 |
                      122 |
                      123 |
                        124 |
                        125 |
                        126 |
                        127 |
                        128 |
                        129 | 130 | 131 |
                        132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-util-json.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
                        22 |

                        Documentation

                        23 | 24 | 27 | 37 | 38 | 42 |
                        43 | 44 |
                        45 |
                        46 | 47 | 50 | 87 | 88 |
                        89 |
                          90 |
                        91 | 92 |
                        93 |

                        Json.php

                        94 | 95 | 96 | 97 |

                        98 | Interfaces, Classes and Traits 99 | 100 |

                        101 | 102 |
                        103 | 104 |
                        Json
                        105 |
                        Helper functions for JSON processing.
                        106 | 107 |
                        108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
                        116 |
                        117 |
                        118 |
                        119 |

                        Search results

                        120 | 121 |
                        122 |
                        123 |
                          124 |
                          125 |
                          126 |
                          127 |
                          128 |
                          129 | 130 | 131 |
                          132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/files/src-util-shipenginelogger.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
                          22 |

                          Documentation

                          23 | 24 | 27 | 37 | 38 | 42 |
                          43 | 44 |
                          45 |
                          46 | 47 | 50 | 87 | 88 |
                          89 |
                            90 |
                          91 | 92 |
                          93 |

                          ShipEngineLogger.php

                          94 | 95 | 96 | 97 |

                          98 | Interfaces, Classes and Traits 99 | 100 |

                          101 | 102 |
                          103 | 104 |
                          ShipEngineLogger
                          105 |
                          Class ShipEngineLogger
                          106 | 107 |
                          108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
                          116 |
                          117 |
                          118 |
                          119 |

                          Search results

                          120 | 121 |
                          122 |
                          123 |
                            124 |
                            125 |
                            126 |
                            127 |
                            128 |
                            129 | 130 | 131 |
                            132 | 133 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/graphs/classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
                            15 |

                            Documentation

                            16 | 17 | 20 | 30 | 31 | 35 |
                            36 | 37 |
                            38 |
                            39 | 40 | 43 | 80 | 81 |
                            82 |
                            83 | 84 |
                            85 | 93 |
                            94 |
                            95 |
                            96 |

                            Search results

                            97 | 98 |
                            99 |
                            100 |
                              101 |
                              102 |
                              103 |
                              104 |
                              105 |
                              106 | 107 | 108 |
                              109 | 110 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/js/search.js: -------------------------------------------------------------------------------- 1 | // Search module for phpDocumentor 2 | // 3 | // This module is a wrapper around fuse.js that will use a given index and attach itself to a 4 | // search form and to a search results pane identified by the following data attributes: 5 | // 6 | // 1. data-search-form 7 | // 2. data-search-results 8 | // 9 | // The data-search-form is expected to have a single input element of type 'search' that will trigger searching for 10 | // a series of results, were the data-search-results pane is expected to have a direct UL child that will be populated 11 | // with rendered results. 12 | // 13 | // The search has various stages, upon loading this stage the data-search-form receives the CSS class 14 | // 'phpdocumentor-search--enabled'; this indicates that JS is allowed and indices are being loaded. It is recommended 15 | // to hide the form by default and show it when it receives this class to achieve progressive enhancement for this 16 | // feature. 17 | // 18 | // After loading this module, it is expected to load a search index asynchronously, for example: 19 | // 20 | // 21 | // 22 | // In this script the generated index should attach itself to the search module using the `appendIndex` function. By 23 | // doing it like this the page will continue loading, unhindered by the loading of the search. 24 | // 25 | // After the page has fully loaded, and all these deferred indexes loaded, the initialization of the search module will 26 | // be called and the form will receive the class 'phpdocumentor-search--active', indicating search is ready. At this 27 | // point, the input field will also have it's 'disabled' attribute removed. 28 | var Search = (function () { 29 | var fuse; 30 | var index = []; 31 | var options = { 32 | shouldSort: true, 33 | threshold: 0.6, 34 | location: 0, 35 | distance: 100, 36 | maxPatternLength: 32, 37 | minMatchCharLength: 1, 38 | keys: [ 39 | "fqsen", 40 | "name", 41 | "summary", 42 | "url" 43 | ] 44 | }; 45 | 46 | // Credit David Walsh (https://davidwalsh.name/javascript-debounce-function) 47 | // Returns a function, that, as long as it continues to be invoked, will not 48 | // be triggered. The function will be called after it stops being called for 49 | // N milliseconds. If `immediate` is passed, trigger the function on the 50 | // leading edge, instead of the trailing. 51 | function debounce(func, wait, immediate) { 52 | var timeout; 53 | 54 | return function executedFunction() { 55 | var context = this; 56 | var args = arguments; 57 | 58 | var later = function () { 59 | timeout = null; 60 | if (!immediate) func.apply(context, args); 61 | }; 62 | 63 | var callNow = immediate && !timeout; 64 | clearTimeout(timeout); 65 | timeout = setTimeout(later, wait); 66 | if (callNow) func.apply(context, args); 67 | }; 68 | } 69 | 70 | function close() { 71 | // Start scroll prevention: https://css-tricks.com/prevent-page-scrolling-when-a-modal-is-open/ 72 | const scrollY = document.body.style.top; 73 | document.body.style.position = ''; 74 | document.body.style.top = ''; 75 | window.scrollTo(0, parseInt(scrollY || '0') * -1); 76 | // End scroll prevention 77 | 78 | var form = document.querySelector('[data-search-form]'); 79 | var searchResults = document.querySelector('[data-search-results]'); 80 | 81 | form.classList.toggle('phpdocumentor-search--has-results', false); 82 | searchResults.classList.add('phpdocumentor-search-results--hidden'); 83 | var searchField = document.querySelector('[data-search-form] input[type="search"]'); 84 | searchField.blur(); 85 | } 86 | 87 | function search(event) { 88 | // Start scroll prevention: https://css-tricks.com/prevent-page-scrolling-when-a-modal-is-open/ 89 | document.body.style.position = 'fixed'; 90 | document.body.style.top = `-${window.scrollY}px`; 91 | // End scroll prevention 92 | 93 | // prevent enter's from autosubmitting 94 | event.stopPropagation(); 95 | 96 | var form = document.querySelector('[data-search-form]'); 97 | var searchResults = document.querySelector('[data-search-results]'); 98 | var searchResultEntries = document.querySelector('[data-search-results] .phpdocumentor-search-results__entries'); 99 | 100 | searchResultEntries.innerHTML = ''; 101 | 102 | if (!event.target.value) { 103 | close(); 104 | return; 105 | } 106 | 107 | form.classList.toggle('phpdocumentor-search--has-results', true); 108 | searchResults.classList.remove('phpdocumentor-search-results--hidden'); 109 | var results = fuse.search(event.target.value, {limit: 25}); 110 | 111 | results.forEach(function (result) { 112 | var entry = document.createElement("li"); 113 | entry.classList.add("phpdocumentor-search-results__entry"); 114 | entry.innerHTML += '

                              ' + result.name + "

                              \n"; 115 | entry.innerHTML += '' + result.fqsen + "\n"; 116 | entry.innerHTML += '
                              ' + result.summary + '
                              '; 117 | searchResultEntries.appendChild(entry) 118 | }); 119 | } 120 | 121 | function appendIndex(added) { 122 | index = index.concat(added); 123 | 124 | // re-initialize search engine when appending an index after initialisation 125 | if (typeof fuse !== 'undefined') { 126 | fuse = new Fuse(index, options); 127 | } 128 | } 129 | 130 | function init() { 131 | fuse = new Fuse(index, options); 132 | 133 | var form = document.querySelector('[data-search-form]'); 134 | var searchField = document.querySelector('[data-search-form] input[type="search"]'); 135 | 136 | var closeButton = document.querySelector('.phpdocumentor-search-results__close'); 137 | closeButton.addEventListener('click', function() { close() }.bind(this)); 138 | 139 | var searchResults = document.querySelector('[data-search-results]'); 140 | searchResults.addEventListener('click', function() { close() }.bind(this)); 141 | 142 | form.classList.add('phpdocumentor-search--active'); 143 | 144 | searchField.setAttribute('placeholder', 'Search (Press "/" to focus)'); 145 | searchField.removeAttribute('disabled'); 146 | searchField.addEventListener('keyup', debounce(search, 300)); 147 | 148 | window.addEventListener('keyup', function (event) { 149 | if (event.key === '/') { 150 | searchField.focus(); 151 | } 152 | if (event.code === 'Escape') { 153 | close(); 154 | } 155 | }.bind(this)); 156 | } 157 | 158 | return { 159 | appendIndex, 160 | init 161 | } 162 | })(); 163 | 164 | window.addEventListener('DOMContentLoaded', function () { 165 | var form = document.querySelector('[data-search-form]'); 166 | 167 | // When JS is supported; show search box. Must be before including the search for it to take effect immediately 168 | form.classList.add('phpdocumentor-search--enabled'); 169 | }); 170 | 171 | window.addEventListener('load', function () { 172 | Search.init(); 173 | }); 174 | -------------------------------------------------------------------------------- /docs/shipengine-php-docs/namespaces/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
                              22 |

                              Documentation

                              23 | 24 | 27 | 37 | 38 | 42 |
                              43 | 44 |
                              45 |
                              46 | 47 | 50 | 87 | 88 |
                              89 |
                                90 |
                              91 | 92 |
                              93 |

                              API Documentation

                              94 | 95 | 96 |

                              97 | Namespaces 98 | 99 |

                              100 | 101 |
                              102 |
                              ShipEngine
                              103 |
                              104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 |
                              112 |
                              113 |
                              114 |
                              115 |

                              Search results

                              116 | 117 |
                              118 |
                              119 |
                                120 |
                                121 |
                                122 |
                                123 |
                                124 |
                                125 | 126 | 127 |
                                128 | 129 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /docs/trackUsingCarrierCodeAndTrackingNumberExample.md: -------------------------------------------------------------------------------- 1 | Track Using Carrier Code and Tracking Number 2 | ====================================== 3 | [ShipEngine](www.shipengine.com) allows you to track a package for a given carrier and tracking number. Please see [our docs](https://www.shipengine.com/docs/tracking/) to learn more about tracking shipments. 4 | 5 | Input Parameters 6 | ------------------------------------- 7 | 8 | The `trackUsingCarrierCodeAndTrackingNumber` method requires the carrier code and tracking number of the shipment being tracked. 9 | 10 | Output 11 | -------------------------------- 12 | The `trackUsingCarrierCodeAndTrackingNumber` method returns tracking information associated with the shipment for the carrier code and tracking number. 13 | 14 | Example 15 | ============================== 16 | ```php 17 | use ShipEngine\ShipEngine; 18 | use ShipEngine\Message\ShipEngineException; 19 | 20 | function trackUsingCarrierCodeAndTrackingNumberDemoFunction() { 21 | $client = new ShipEngine('API-Key'); 22 | try { 23 | print_r($client->trackUsingCarrierCodeAndTrackingNumber('stamps_com', '9405511899223197428490')); 24 | } catch (ShipEngineException $e) { 25 | print_r($e -> getMessage()); 26 | } 27 | } 28 | 29 | trackUsingCarrierCodeAndTrackingNumberDemoFunction(); 30 | ``` 31 | 32 | Example Output 33 | ----------------------------------------------------- 34 | 35 | ### Tracking Result 36 | ```php 37 | Array 38 | ( 39 | [tracking_number] => 9405511899223197428490 40 | [tracking_url] => https://tools.usps.com/go/TrackConfirmAction.action?tLabels=9405511899223197428490 41 | [status_code] => NY 42 | [carrier_code] => stamps_com 43 | [carrier_id] => 1 44 | [carrier_detail_code] => 45 | [status_description] => Not Yet In System 46 | [carrier_status_code] => -2147219283 47 | [carrier_status_description] => A status update is not yet available for this tracking number. More information will become available when USPS receives the tracking information, or when the package is received by USPS. 48 | [ship_date] => 49 | [estimated_delivery_date] => 50 | [actual_delivery_date] => 51 | [exception_description] => 52 | [events] => Array 53 | ( 54 | ) 55 | 56 | ) 57 | ``` -------------------------------------------------------------------------------- /docs/trackUsingLabelIdExample.md: -------------------------------------------------------------------------------- 1 | Track By Label ID 2 | ====================================== 3 | [ShipEngine](www.shipengine.com) allows you to track a package by its ShipEngine label ID. Please see [our docs](https://www.shipengine.com/docs/tracking/track-by-label-id/) to learn more about tracking shipments. 4 | 5 | Input Parameters 6 | ------------------------------------- 7 | 8 | The `trackUsingLabelId` method requires the ID of the label associated with the shipment you are trying to track. 9 | 10 | Output 11 | -------------------------------- 12 | The `trackUsingLabelId` method returns tracking information associated with the shipment for the given label ID. 13 | 14 | Example 15 | ============================== 16 | ```php 17 | use ShipEngine\ShipEngine; 18 | use ShipEngine\Message\ShipEngineException; 19 | 20 | function trackLabelWithLabelIdDemoFunction() { 21 | $client = new ShipEngine('API-Key'); 22 | try { 23 | print_r($client->trackUsingLabelId('se-75492762')); 24 | } catch (ShipEngineException $e) { 25 | print_r($e -> getMessage()); 26 | } 27 | } 28 | 29 | trackLabelWithLabelIdDemoFunction(); 30 | ``` 31 | 32 | Example Output 33 | ----------------------------------------------------- 34 | 35 | ### Tracking Result 36 | ```php 37 | Array 38 | ( 39 | [tracking_number] => 1Z63R0960322853130 40 | [tracking_url] => http://wwwapps.ups.com/WebTracking/processRequest?HTMLVersion=5.0&Requester=NES&AgreeToTermsAndConditions=yes&loc=en_US&tracknum=1Z63R0960322853130 41 | [status_code] => UN 42 | [carrier_code] => ups 43 | [carrier_id] => 3 44 | [carrier_detail_code] => 45 | [status_description] => Unknown 46 | [carrier_status_code] => 47 | [carrier_status_description] => No tracking information available 48 | [ship_date] => 49 | [estimated_delivery_date] => 50 | [actual_delivery_date] => 51 | [exception_description] => 52 | [events] => Array 53 | ( 54 | ) 55 | 56 | ) 57 | ``` -------------------------------------------------------------------------------- /docs/voidLabelExample.md: -------------------------------------------------------------------------------- 1 | Void Label With Label Id 2 | ================================ 3 | [ShipEngine](www.shipengine.com) allows you to attempt to void a previously purchased label. Please see [our docs](https://www.shipengine.com/docs/labels/voiding/) to learn more about voiding a label. 4 | 5 | Input Parameters 6 | ------------------------------------- 7 | 8 | The `voidLabelWithLabelId` method accepts a string that contains the label Id that is being voided. 9 | 10 | Output 11 | -------------------------------- 12 | The `voidLabelWithLabelId` method returns an object that indicates the status of the void label request. 13 | 14 | Example 15 | ============================== 16 | ```php 17 | use ShipEngine\ShipEngine; 18 | use ShipEngine\Message\ShipEngineException; 19 | 20 | function voidLabelWithLabelIdDemoFunction() { 21 | $client = new ShipEngine('API-Key'); 22 | try { 23 | print_r($client->voidLabelWithLabelId('se-75449505')); 24 | } catch (ShipEngineException $e) { 25 | print_r($e -> getMessage()); 26 | } 27 | } 28 | 29 | voidLabelWithLabelIdDemoFunction(); 30 | ``` 31 | 32 | Example Output 33 | ----------------------------------------------------- 34 | 35 | ### Successful Void Label 36 | ```php 37 | Array 38 | ( 39 | [approved] => 40 | [message] => No shipment found within the allowed void period 41 | ) 42 | ``` -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | tests 17 | 18 | 19 | 21 | 22 | src 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /ruleset.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | This standard changes the line length 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | buildInputs = [ 5 | (pkgs.php74.withExtensions ({ enabled, all }: enabled ++ [ all.xdebug ])) 6 | pkgs.php74Packages.composer 7 | pkgs.php74Packages.phpcs 8 | pkgs.php74Packages.phpstan 9 | ]; 10 | 11 | COMPOSER_MEMORY_LIMIT=-1; 12 | } 13 | -------------------------------------------------------------------------------- /src/Message/AccountStatusException.php: -------------------------------------------------------------------------------- 1 | field_name = $field_name; 44 | $this->field_value = $field_value; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Message/RateLimitExceededException.php: -------------------------------------------------------------------------------- 1 | retryAfter = $retryAfter; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Message/SecurityException.php: -------------------------------------------------------------------------------- 1 | requestId = $requestId; 85 | $this->source = $source ?? 'shipengine'; 86 | $this->type = $type; 87 | $this->errorCode = $errorCode; 88 | $this->url = $url ?? 'https://www.shipengine.com/docs/errors/codes/'; 89 | } 90 | 91 | /** 92 | * @return array 93 | */ 94 | public function jsonSerialize() 95 | { 96 | return [ 97 | 'requestId' => $this->requestId, 98 | 'source' => $this->source, 99 | 'type' => $this->type, 100 | 'errorCode' => $this->errorCode, 101 | 'message' => $this->message, 102 | 'url' => $this->url 103 | ]; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Message/SystemException.php: -------------------------------------------------------------------------------- 1 | sendRequestWithRetries('GET', $path, null, $config); 38 | } 39 | 40 | /** 41 | * Implement a POST request and return output 42 | * 43 | * @param string $path 44 | * @param ShipEngineConfig $config 45 | * @param array $params 46 | * 47 | * @return array 48 | */ 49 | public function post($path, ShipEngineConfig $config, array $params = null) 50 | { 51 | return $this->sendRequestWithRetries('POST', $path, $params, $config); 52 | } 53 | 54 | /** 55 | * Implement a PUT request and return output 56 | * 57 | * @param string $path 58 | * @param ShipEngineConfig $config 59 | * @param array $params 60 | * 61 | * @return array 62 | */ 63 | public function put($path, ShipEngineConfig $config, array $params = null) 64 | { 65 | return $this->sendRequestWithRetries('PUT', $path, $params, $config); 66 | } 67 | 68 | /** 69 | * Implement a DELETE request and return output 70 | * 71 | * @param string $path 72 | * @param ShipEngineConfig $config 73 | * 74 | * @return array 75 | */ 76 | public function delete($path, ShipEngineConfig $config) 77 | { 78 | return $this->sendRequestWithRetries('DELETE', $path, null, $config); 79 | } 80 | 81 | /** 82 | * Send a `REST` request via *ShipEngineClient*. 83 | * 84 | * @param string $method 85 | * @param string $path 86 | * @param array|null $params 87 | * @param ShipEngineConfig $config 88 | * @return array 89 | * @throws GuzzleException 90 | */ 91 | private function sendRequestWithRetries( 92 | string $method, 93 | string $path, 94 | ?array $params, 95 | ShipEngineConfig $config 96 | ): array 97 | { 98 | $apiResponse = null; 99 | for ($retry = 0; $retry <= $config->retries; $retry++) { 100 | try { 101 | $apiResponse = $this->sendRequest($method, $path, $params, $retry, $config); 102 | break; 103 | } catch (\RuntimeException $err) { 104 | if (($retry < $config->retries) && 105 | $err instanceof RateLimitExceededException && 106 | ($err->retryAfter->s < $config->timeout->s) 107 | ) { 108 | // The request was blocked due to exceeding the rate limit. 109 | // So wait the specified amount of time and then retry. 110 | sleep($err->retryAfter->s); 111 | } else { 112 | throw $err; 113 | } 114 | } 115 | } 116 | return $apiResponse; 117 | } 118 | 119 | /** 120 | * Send a `REST` request via HTTP Messages to ShipEngine API. If the response 121 | * is successful, the result is returned. Otherwise, an error is thrown. 122 | * 123 | * @param string $method 124 | * @param string $path 125 | * @param array|null $params 126 | * @param int $retry 127 | * @param ShipEngineConfig $config 128 | * @return array 129 | * @throws GuzzleException 130 | */ 131 | private function sendRequest( 132 | string $method, 133 | string $path, 134 | ?array $params, 135 | int $retry, 136 | ShipEngineConfig $config 137 | ): array { 138 | $requestHeaders = array( 139 | 'api-key' => $config->apiKey, 140 | 'User-Agent' => $this->deriveUserAgent(), 141 | 'Content-Type' => 'application/json', 142 | 'Accept' => 'application/json' 143 | ); 144 | 145 | $client = new Client( 146 | [ 147 | 'base_uri' => $config->baseUrl, 148 | 'timeout' => $config->timeout, 149 | 'max_retry_attempts' => $config->retries 150 | ] 151 | ); 152 | 153 | $jsonData = json_encode($params, JSON_UNESCAPED_SLASHES); 154 | 155 | $request = new Request($method, $path, $requestHeaders, $jsonData); 156 | 157 | try { 158 | $response = $client->send( 159 | $request, 160 | ['timeout' => $config->timeout->s, 'http_errors' => false] 161 | ); 162 | } catch (ClientException $err) { 163 | throw new ShipEngineException( 164 | "An unknown error occurred while calling the ShipEngine $method API:\n" . 165 | $err->getMessage(), 166 | null, 167 | 'ShipEngine', 168 | 'System', 169 | 'Unspecified' 170 | ); 171 | } 172 | 173 | $responseBody = (string)$response->getBody(); 174 | 175 | $parsedResponse = json_decode($responseBody, true); 176 | $statusCode = $response->getStatusCode(); 177 | 178 | // $assert->isResponse404($statusCode, $parsedResponse); 179 | // $assert->isResponse429($statusCode, $parsedResponse, $config); 180 | // $assert->isResponse500($statusCode, $parsedResponse); 181 | 182 | return $this->handleResponse($parsedResponse); 183 | } 184 | 185 | 186 | /** 187 | * Handles the response from ShipEngine API. 188 | * 189 | * @param array $response 190 | * @return array 191 | */ 192 | private function handleResponse(array $response): array 193 | { 194 | if (!isset($response['errors']) || (count($response['errors']) == 0)) { 195 | return $response; 196 | } 197 | 198 | $error = $response['errors'][0]; 199 | 200 | throw new ShipEngineException( 201 | $error['message'], 202 | $response['request_id'], 203 | $error['error_source'], 204 | $error['error_type'], 205 | $error['error_code'] 206 | ); 207 | } 208 | 209 | /** 210 | * Derive a User-Agent header from the environment. This is the user-agent that will be set on every request 211 | * via the ShipEngine Client. 212 | * 213 | * @returns string 214 | */ 215 | private function deriveUserAgent(): string 216 | { 217 | $sdk_version = 'shipengine-php/' . ShipEngine::VERSION; 218 | 219 | $os = explode(' ', php_uname()); 220 | $os_kernel = $os[0] . '/' . $os[2]; 221 | 222 | $php_version = 'PHP/' . phpversion(); 223 | 224 | return $sdk_version . ' ' . $os_kernel . ' ' . $php_version; 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /src/ShipEngineConfig.php: -------------------------------------------------------------------------------- 1 | isApiKeyValid($config); 84 | $this->apiKey = $config['apiKey']; 85 | 86 | 87 | if (isset($config['retries']) === true && $config['retries'] >= 0) { 88 | $this->retries = $config['retries']; 89 | } elseif (isset($config['retries']) === false) { 90 | $this->retries = self::DEFAULT_RETRIES; 91 | } elseif ($config['retries'] < 0) { 92 | throw new ValidationException( 93 | 'Retries must be zero or greater.', 94 | null, 95 | 'shipengine', 96 | 'validation', 97 | 'invalid_field_value' 98 | ); 99 | } 100 | 101 | $timeout = $config['timeout']; 102 | if ($timeout instanceof DateInterval) { 103 | $assert->isTimeoutValid($timeout); 104 | $this->timeout = $timeout; 105 | } elseif (isset($config['timeout']) === false) { 106 | $this->timeout = new DateInterval(self::DEFAULT_TIMEOUT); 107 | } else { 108 | throw new ValidationException( 109 | 'Timeout is not a DateInterval.', 110 | null, 111 | 'shipengine', 112 | 'validation', 113 | 'invalid_field_value' 114 | ); 115 | } 116 | 117 | $this->baseUrl = $config['baseUrl'] ?? self::DEFAULT_BASE_URI; 118 | $this->pageSize = $config['pageSize'] ?? self::DEFAULT_PAGE_SIZE; 119 | } 120 | 121 | /** 122 | * Merge in method level config into the global config used by the **ShipEngine** object. 123 | * 124 | * @param array|null $newConfig 125 | * @return $this 126 | */ 127 | public function merge(?array $newConfig = null): ShipEngineConfig 128 | { 129 | if (!isset($newConfig)) { 130 | return $this; 131 | } 132 | 133 | $config = array(); 134 | 135 | isset($newConfig['apiKey']) ? 136 | ($config['apiKey'] = $newConfig['apiKey']) : 137 | ($config['apiKey'] = $this->apiKey); 138 | 139 | isset($newConfig['baseUrl']) ? 140 | ($config['baseUrl'] = $newConfig['baseUrl']) : 141 | ($config['baseUrl'] = $this->baseUrl); 142 | 143 | isset($newConfig['pageSize']) ? 144 | ($config['pageSize'] = $newConfig['pageSize']) : 145 | ($config['pageSize'] = $this->pageSize); 146 | 147 | isset($newConfig['retries']) ? 148 | ($config['retries'] = $newConfig['retries']) : 149 | ($config['retries'] = $this->retries); 150 | 151 | isset($newConfig['timeout']) ? 152 | ($config['timeout'] = $newConfig['timeout']) : 153 | ($config['timeout'] = $this->timeout); 154 | 155 | return new ShipEngineConfig($config); 156 | } 157 | 158 | /** 159 | * Specify data which should be serialized to JSON 160 | * @link http://php.net/manual/en/jsonserializable.jsonserialize.php 161 | */ 162 | public function jsonSerialize() 163 | { 164 | return [ 165 | 'apiKey' => $this->apiKey, 166 | 'baseUrl' => $this->baseUrl, 167 | 'pageSize' => $this->pageSize, 168 | 'retries' => $this->retries, 169 | 'timeout' => $this->timeout->s 170 | ]; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/Util/Arr.php: -------------------------------------------------------------------------------- 1 | $value) { 34 | if (is_array($value)) { 35 | $result = array_merge($result, self::flatten($value)); 36 | } else { 37 | $result = array_merge($result, array($key => $value)); 38 | } 39 | } 40 | 41 | return $result; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Util/Assert.php: -------------------------------------------------------------------------------- 1 | invert === 1 || $timeout->s === 0) { 46 | throw new ValidationException( 47 | 'Timeout must be greater than zero.', 48 | null, 49 | 'shipengine', 50 | 'validation', 51 | 'invalid_field_value' 52 | ); 53 | } 54 | } 55 | 56 | // /** 57 | // * Asserts that the status code is 500, and if it is a `SystemException` is thrown. 58 | // * 59 | // * @param int $statusCode 60 | // * @param array $parsedResponse 61 | // */ 62 | // public function isResponse500(int $statusCode, array $parsedResponse): void 63 | // { 64 | // if ($statusCode === 500) { 65 | // $error = $parsedResponse['error']; 66 | // throw new SystemException( 67 | // $error['message'], 68 | // $parsedResponse['id'], 69 | // $error['data']['source'], 70 | // $error['data']['type'], 71 | // $error['data']['code'], 72 | // $error['data']['url'] ?? null 73 | // ); 74 | // } 75 | // } 76 | 77 | // public function isResponse404(int $statusCode, $parsedResponse): void 78 | // { 79 | // var_dump($parsedResponse); 80 | // if (array_key_exists('error', $parsedResponse)) { 81 | // $error = $parsedResponse['error']; 82 | // $errorData = $parsedResponse['error']['data']; 83 | // if ($statusCode === 404) { 84 | // throw new SystemException( 85 | // $error['message'], 86 | // $parsedResponse['id'], 87 | // $errorData['source'], 88 | // $errorData['type'], 89 | // $errorData['code'], 90 | // null 91 | // ); 92 | // } 93 | // } 94 | // } 95 | 96 | // public function isResponse429(int $statusCode, array $response, ShipEngineConfig $config): void 97 | // { 98 | // if (array_key_exists('error', $response)) { 99 | // $error = $response['error']; 100 | // $retryAfter = isset($error['data']['retryAfter']) ? $error['data']['retryAfter'] : null; 101 | 102 | // if ($retryAfter > $config->timeout->s) { 103 | // throw new TimeoutException( 104 | // $config->timeout->s, 105 | // ErrorSource::SHIPENGINE, 106 | // $response['id'] 107 | // ); 108 | // } 109 | 110 | // if ($statusCode === 429) { 111 | // throw new RateLimitExceededException( 112 | // new \DateInterval("PT{$retryAfter}S"), 113 | // ErrorSource::SHIPENGINE, 114 | // $response['id'] 115 | // ); 116 | // } 117 | // } 118 | // } 119 | } 120 | -------------------------------------------------------------------------------- /src/Util/Constants/Endpoints.php: -------------------------------------------------------------------------------- 1 | $property; 14 | } 15 | 16 | throw new \RuntimeException("Retrieving the field/member $property is not valid for this entity."); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Util/IsoString.php: -------------------------------------------------------------------------------- 1 | value = $value; 15 | } 16 | 17 | public function __toString(): string 18 | { 19 | return $this->value; 20 | } 21 | 22 | /** 23 | * Returns whether or not the `IsoString` includes a time element. 24 | */ 25 | public function hasTime(): bool 26 | { 27 | return preg_match('/[0-9]*T[0-9]*/', $this->value) == 1; 28 | } 29 | 30 | /** 31 | * Returns whether or not the `IsoString` includes a timezone element. 32 | */ 33 | public function hasTimezone(): bool 34 | { 35 | return $this->hasTime() && preg_match('/(?<=T).*[+-][0-9]|Z$/', $this->value) == 1; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Util/Json.php: -------------------------------------------------------------------------------- 1 | jsonSerialize(); 16 | 17 | foreach ($keys as $key) { 18 | $old = $key[0]; 19 | $new = $key[1]; 20 | $json[$new] = $json[$old]; 21 | unset($json[$old]); 22 | } 23 | 24 | return $json; 25 | } 26 | 27 | /** 28 | * Encode a JsonSerializable object, swapping out the $keys in process. 29 | */ 30 | public static function encode(\JsonSerializable $obj, array ...$keys): string 31 | { 32 | $json = self::jsonize($obj, $keys); 33 | return json_encode($json); 34 | } 35 | 36 | /** 37 | * Encode an array of JsonSerializable objects, swapping out the $keys in the process. 38 | */ 39 | public static function encodeArray(array $objs, array ...$keys): string 40 | { 41 | $new = array(); 42 | 43 | foreach ($objs as $obj) { 44 | $new[] = self::jsonize($obj, $keys); 45 | } 46 | 47 | return json_encode($new); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Util/ShipEngineLogger.php: -------------------------------------------------------------------------------- 1 | emergency($message, $context); 25 | break; 26 | case LogLevel::ALERT: 27 | $this->alert($message, $context); 28 | break; 29 | case LogLevel::CRITICAL: 30 | $this->critical($message, $context); 31 | break; 32 | case LogLevel::ERROR: 33 | $this->error($message, $context); 34 | break; 35 | case LogLevel::WARNING: 36 | $this->warning($message, $context); 37 | break; 38 | case LogLevel::NOTICE: 39 | $this->notice($message, $context); 40 | break; 41 | case LogLevel::INFO: 42 | $this->info($message, $context); 43 | break; 44 | case LogLevel::DEBUG: 45 | $this->debug($message, $context); 46 | break; 47 | default: 48 | throw new \Psr\Log\InvalidArgumentException( 49 | 'Severity level not recognized - must be emergency, alert, critical, 50 | error, warning, notice, info, or debug.' 51 | ); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Util/ShipEngineSerializer.php: -------------------------------------------------------------------------------- 1 | serializer = new Serializer($normalizer, $encoder); 33 | } 34 | 35 | /** 36 | * Deserialize a JSON string into a PHP Type object. 37 | * 38 | * @param string $json_data 39 | * @param string $target_class 40 | * @return mixed 41 | * @throws NotEncodableValueException 42 | */ 43 | public function deserializeJsonToType(string $json_data, string $target_class) 44 | { 45 | return $this->serializer->deserialize($json_data, $target_class, 'json'); 46 | } 47 | 48 | /** 49 | * Serialize a PHP object into a specific PHP Object/Type. 50 | * 51 | * @param mixed $php_object 52 | * @param string $target_class 53 | * @return mixed 54 | * @throws NotEncodableValueException 55 | */ 56 | public function serializeDataToType($php_object, string $target_class) 57 | { 58 | $json = $this->serializeDataToJson($php_object); 59 | return $this->deserializeJsonToType($json, $target_class); 60 | } 61 | 62 | /** 63 | * Serialize arbitrary PHP data objects (e.g. an array or explicit object) into JSON strings. 64 | * 65 | * @param mixed $data 66 | * @return string 67 | * @throws NotEncodableValueException 68 | */ 69 | public function serializeDataToJson($data): string 70 | { 71 | return $this->serializer->serialize($data, 'json'); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /tests/ShipEngineClientTest.php: -------------------------------------------------------------------------------- 1 | getMethod($method_name); 32 | // $method->setAccessible(true); 33 | // return $method->invokeArgs($obj, $args); 34 | // } 35 | 36 | // /** 37 | // * Tests the private `wrapRequest` method on the ShipEngineClient. 38 | // */ 39 | // public function testWrapRequest(): void 40 | // { 41 | // $wrap_request = $this->callPrivateMethod( 42 | // self::$shipengine_client, 43 | // 'wrapRequest', 44 | // [ 45 | // RPCMethods::ADDRESS_VALIDATE, 46 | // array( 47 | // 'street' => array( 48 | // '4 Jersey St', 49 | // 'validate-isResidential-address', 50 | // ), 51 | // 'cityLocality' => 'Boston', 52 | // 'stateProvince' => 'MA', 53 | // 'postalCode' => '02215', 54 | // 'countryCode' => 'US', 55 | // ) 56 | // ] 57 | // ); 58 | 59 | // $params = $wrap_request['params']; 60 | // $this->assertIsArray($wrap_request); 61 | // $this->assertArrayHasKey('id', $wrap_request); 62 | // $this->assertArrayHasKey('jsonrpc', $wrap_request); 63 | // $this->assertArrayHasKey('method', $wrap_request); 64 | // $this->assertArrayHasKey('params', $wrap_request); 65 | // $this->assertIsArray($params); 66 | // $this->assertArrayHasKey('street', $params); 67 | // $this->assertIsArray($params['street']); 68 | // $this->assertArrayHasKey('cityLocality', $params); 69 | // $this->assertArrayHasKey('stateProvince', $params); 70 | // $this->assertArrayHasKey('postalCode', $params); 71 | // $this->assertArrayHasKey('countryCode', $params); 72 | // } 73 | 74 | // public function testWrapRequestWithNullParams(): void 75 | // { 76 | // $wrap_request = $this->callPrivateMethod( 77 | // self::$shipengine_client, 78 | // 'wrapRequest', 79 | // [ 80 | // RPCMethods::ADDRESS_VALIDATE, 81 | // null 82 | // ] 83 | // ); 84 | 85 | // $this->assertArrayNotHasKey('params', $wrap_request); 86 | // $this->assertArrayHasKey('id', $wrap_request); 87 | // $this->assertArrayHasKey('jsonrpc', $wrap_request); 88 | // $this->assertArrayHasKey('method', $wrap_request); 89 | // } 90 | // } 91 | -------------------------------------------------------------------------------- /tests/ShipEngineTest.php: -------------------------------------------------------------------------------- 1 | 'TEST_ycvJAgX6tLB1Awm9WGJmD8mpZ8wXiQ20WhqFowCk32s', 33 | 'baseUrl' => 'https://api.shipengine.com', 34 | 'pageSize' => 75, 35 | 'retries' => 7, 36 | 'timeout' => new \DateInterval('PT60S'), 37 | ) 38 | ); 39 | } 40 | 41 | public function testInstantiation(): void 42 | { 43 | $shipengineInit = new ShipEngine( 44 | array( 45 | 'apiKey' => 'TEST_ycvJAgX6tLB1Awm9WGJmD8mpZ8wXiQ20WhqFowCk32s', 46 | 'baseUrl' => 'https://api.shipengine.com', 47 | 'pageSize' => 75, 48 | 'retries' => 7, 49 | 'timeout' => new \DateInterval('PT60S'), 50 | ) 51 | ); 52 | $this->assertInstanceOf(ShipEngine::class, $shipengineInit); 53 | } 54 | 55 | // public function testFetchCarrierAccountsReturnValue(): void 56 | // { 57 | // $carriers = self::$shipengine->listCarriers(); 58 | 59 | // foreach ($carriers['carriers'] as $carrier) { 60 | // $this->assertEquals($carrier['supports_label_messages'], true); 61 | // } 62 | // } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Util/ArrTest.php: -------------------------------------------------------------------------------- 1 | assertCount(3, $new); 26 | $this->assertContainsOnly('int', $new); 27 | } 28 | 29 | public function testSubArray(): void 30 | { 31 | $old = array( 32 | 'one' => 1, 33 | 'two' => 2, 34 | 'three' => 3 35 | ); 36 | 37 | $new = Arr::subArray($old, 'one', 'two'); 38 | 39 | $this->assertArrayHasKey('one', $new); 40 | $this->assertArrayHasKey('two', $new); 41 | $this->assertArrayNotHasKey('three', $new); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Util/Foo.php: -------------------------------------------------------------------------------- 1 | 0, '1' => 1); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/Util/GettersTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('baz', $foo->bar); 18 | } 19 | 20 | public function testUnfoundGetter(): void 21 | { 22 | $this->expectException(\RuntimeException::class); 23 | $foo = new Foo(); 24 | $foo->baz; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Util/IsoStringTest.php: -------------------------------------------------------------------------------- 1 | assertCount(2, $strs); 20 | } 21 | 22 | public function testHasTime(): void 23 | { 24 | $str = new IsoString('2020-01-01T00:00:00Z'); 25 | $this->assertTrue($str->hasTime()); 26 | 27 | $str = new IsoString('2020-01-01'); 28 | $this->assertFalse($str->hasTime()); 29 | } 30 | 31 | public function testHasTimezone(): void 32 | { 33 | $str = new IsoString('2020-01-01T00:00:00Z'); 34 | $this->assertTrue($str->hasTimezone()); 35 | 36 | $str = new IsoString('2020-01-01T00:00:00+00:00'); 37 | $this->assertTrue($str->hasTimezone()); 38 | 39 | $str = new IsoString('2020-01-01T00:00:00-00:00'); 40 | $this->assertTrue($str->hasTimezone()); 41 | 42 | $str = new IsoString('2020-01-01'); 43 | $this->assertFalse($str->hasTimezone()); 44 | 45 | $str = new IsoString('2020-01-01T00:00:00'); 46 | $this->assertFalse($str->hasTimezone()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/Util/JsonTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('{"0":0,"one":1}', $json_string); 24 | } 25 | 26 | public function testEncodeArray(): void 27 | { 28 | $foos = array(new Foo(), new Foo()); 29 | 30 | $json_string = Json::encodeArray($foos, ['0', 'zero']); 31 | 32 | $this->assertEquals('[{"1":1,"zero":0},{"1":1,"zero":0}]', $json_string); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/Util/ShipEngineLoggerTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(LoggerInterface::class, $logger); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Util/ShipEngineSerializerTest.php: -------------------------------------------------------------------------------- 1 | array('4 Jersey St', 'Ste 200', '2nd Floor'), 28 | 'cityLocality' => 'Boston', 29 | 'stateProvince' => 'MA', 30 | 'postalCode' => '02215', 31 | 'countryCode' => 'US', 32 | ); 33 | 34 | $json = $serializer->serializeDataToJson($arr); 35 | $this->assertJson($json); 36 | } 37 | 38 | // public function testDeserializeJsonToType() 39 | // { 40 | // $serializer = new ShipEngineSerializer(); 41 | // $json_string = '{"address": { 42 | // "street": [ 43 | // "4 Jersey St", 44 | // "multiple-error-messages" 45 | // ], 46 | // "cityLocality": "Boston", 47 | // "stateProvince": "MA", 48 | // "postalCode": "02215", 49 | // "countryCode": "US" 50 | // }}'; 51 | 52 | 53 | // $this->assertInstanceOf( 54 | // Address::class, 55 | // $serializer->deserializeJsonToType($json_string, Address::class) 56 | // ); 57 | // } 58 | 59 | // public function testSerializeDataToType() 60 | // { 61 | // $serializer = new ShipEngineSerializer(); 62 | // $address = array( 63 | // 'address' => array( 64 | // 'street' => array('4 Jersey St', 'Ste 200', '2nd Floor'), 65 | // 'cityLocality' => 'Boston', 66 | // 'stateProvince' => 'MA', 67 | // 'postalCode' => '02215', 68 | // 'countryCode' => 'US' 69 | // ) 70 | // ); 71 | 72 | // $this->assertInstanceOf( 73 | // Address::class, 74 | // $serializer->serializeDataToType($address, Address::class) 75 | // ); 76 | // } 77 | 78 | public function testInstantiation(): void 79 | { 80 | $serializer = new ShipEngineSerializer(); 81 | 82 | $this->assertInstanceOf(ShipEngineSerializer::class, $serializer); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 1.0.2 2 | --------------------------------------------------------------------------------