├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── CHANGES.txt
├── Dockerfile
├── LICENSE
├── README.md
├── SECURITY.md
├── Vagrantfile
├── composer.json
├── composer.lock
├── demo
└── geocode.php
├── opencage_logo_300_150.png
├── phpcs.xml
├── phpunit.xml
├── src
├── AbstractGeocoder.php
└── Geocoder.php
└── tests
├── GeocoderTest.php
└── bootstrap.php
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 |
3 | on:
4 | push:
5 | pull_request:
6 | schedule:
7 | - cron: '15 22 2 * *'
8 |
9 | env:
10 | OPENCAGE_API_KEY: ${{ secrets.GEO_CODER_OPENCAGE_API_KEY }}
11 |
12 | jobs:
13 | test:
14 | strategy:
15 | matrix:
16 | # https://www.php.net/supported-versions.php
17 | php-version: ['8.2', '8.3', '8.4']
18 |
19 | name: PHP OpenCage Geocode
20 |
21 | runs-on: ubuntu-latest
22 |
23 | steps:
24 | - name: Checkout repository
25 | uses: actions/checkout@v4
26 |
27 | - name: Set up PHP ${{ matrix.php-version }}
28 | uses: shivammathur/setup-php@v2
29 | with:
30 | php-version: ${{ matrix.php-version }}
31 | coverage: none
32 |
33 | - name: Install dependencies
34 | run: composer install --no-progress --no-suggest --no-interaction
35 |
36 | - name: Run tests
37 | run: |
38 | composer validate
39 | ./vendor/bin/phpunit
40 | SKIP_CURL=1 ./vendor/bin/phpunit
41 |
42 | - name: Run proxy tests
43 | run: |
44 | docker run -d --name=tinyproxy -p 8888:8888 monokal/tinyproxy:latest ANY
45 | PROXY=http://0.0.0.0:8888 ./vendor/bin/phpunit
46 | docker rm -f tinyproxy
47 |
48 | - name: Run Linter
49 | run: ./vendor/bin/phpcs .
50 |
51 | - name: Run PHPStan
52 | run: ./vendor/bin/phpstan analyse --level 5 src tests demo
53 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vagrant
2 | vendor
3 | .phpunit.*
--------------------------------------------------------------------------------
/CHANGES.txt:
--------------------------------------------------------------------------------
1 | 3.3.1 -- Thu Nov 21 2024
2 | =====================================================
3 | - add testing against PHP 8.4
4 |
5 | 3.3.0 -- Mon Mar 11 2024
6 | =====================================================
7 | - add an HTTP header: User-Agent
8 |
9 | 3.2.2 -- Mon Feb 26 2024
10 | =====================================================
11 | - add setProxy method
12 |
13 | 3.2.1 -- Fri Jan 26 2024
14 | =====================================================
15 | - add testing against PHP 8.3
16 | - add PHPStan linting
17 |
18 | 3.2.0 -- Wed Jul 26 2023
19 | =====================================================
20 | - requires PHP >= 8.0, PHP 7.4 no longer supported
21 | - add testing against PHP 8.2
22 |
23 | 3.1.1 -- Wed Dec 22 2021
24 | =====================================================
25 | - add testing against PHP 8.1
26 |
27 | 3.1.0 -- Wed Sep 15 2021
28 | =====================================================
29 | - Error response when curl encounters a network issue (e.g. DNS, old TLS cipher). Before it
30 | would silently fail.
31 | - Use test API keys in test suite for HTTP 200 and 402 responses
32 |
33 | 3.0.0 -- Thu Jan 28 2021
34 | =====================================================
35 | - deprecate PHP 5.6, added PHP 8
36 |
37 | 2.1.0 -- Thu May 9 2019
38 | =====================================================
39 | - file_get_contents printed errors and returned false. Instead those are
40 | caughed now and an empty valid JSON document with the error code is
41 | returned. file_get_contents is only used when the curl fetching doesn't
42 | work (rare)
43 |
44 | 2.0.3 -- Sat Apr 27 2019
45 | =====================================================
46 | - API returns HTTP 401 for invalid key
47 | - add Vagrant setup for testing
48 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Using docker
2 | #
3 | # ```bash
4 | # docker build -t local/opencage-php .
5 | #
6 | # docker run -ti -v `pwd`:/usr/src/myapp local/opencage-php
7 | #
8 | # app@ee88ad785ca2:/usr/src/myapp$ composer install
9 | # app@ee88ad785ca2:/usr/src/myapp$ ./vendor/bin/phpunit
10 | # app@ee88ad785ca2:/usr/src/myapp$ SKIP_CURL=1 ./vendor/bin/phpunit
11 | # app@ee88ad785ca2:/usr/src/myapp$ ./vendor/bin/phpcs .
12 | # app@ee88ad785ca2:/usr/src/myapp$ ./vendor/bin/phpstan analyse --level 5 src tests demo
13 | # ```
14 |
15 | FROM ubuntu:22.04
16 |
17 | ENV TZ=Europe/London
18 |
19 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
20 |
21 | RUN apt-get update -qq && \
22 | apt-get install -y -qq curl vim php-cli php-curl php-xml php-mbstring unzip
23 |
24 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
25 |
26 | RUN useradd --user-group --system --create-home --no-log-init app
27 |
28 | COPY . /usr/src/myapp
29 | WORKDIR /usr/src/myapp
30 |
31 | RUN chown -R app:app /usr/src/myapp
32 |
33 | USER app
34 |
35 | VOLUME [ "/usr/src/myapp" ]
36 |
37 | CMD ["/bin/bash"]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2019 OpenCage GmbH (https://opencagedata.com)
2 | Copyright (c) 2015 OpenCageData (https://opencagedata.com)
3 | Copyright (c) 2014 Lokku Limited (http://lokku.com/)
4 | Copyright (c) 2014 Gary Gale (http://www/garygale.com/)
5 |
6 | All rights reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without modification,
9 | are permitted provided that the following conditions are met:
10 |
11 | 1. Redistributions of source code must retain the above copyright notice, this
12 | list of conditions and the following disclaimer.
13 |
14 | 2. Redistributions in binary form must reproduce the above copyright notice, this
15 | list of conditions and the following disclaimer in the documentation and/or other
16 | materials provided with the distribution.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 | OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenCage Geocoding API Library for PHP
2 |
3 | A [PHP](http://php.net/) library to use the [OpenCage geocoding API](https://opencagedata.com/api).
4 |
5 | ## Build Status / Code Quality
6 |
7 | [](https://github.com/OpenCageData/php-opencage-geocode/actions/workflows/ci.yml)
8 | [](https://badge.fury.io/ph/opencage%2Fgeocode)
9 | 
10 |
11 | ## Overview
12 | This library attempts to use the [CURL](http://www.php.net/manual/en/book.curl.php)
13 | extension to access the OpenCage Geocoding API. If CURL support is not available, the
14 | library falls back to using [fopen wrappers](http://uk3.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen).
15 |
16 | To use the library you must either have the CURL extension compiled into your version
17 | of PHP. Alternatively configure the use of fopen wrappers via the `allow_url_fopen`
18 | directive in your `php.ini`.
19 |
20 | ### Authentication
21 |
22 | You need an API key, which you can sign up for [here](https://opencagedata.com).
23 |
24 | ### Tutorial
25 |
26 | You can find [a comprehensive tutorial for using this module on the OpenCage site](https://opencagedata.com/tutorials/geocode-in-php).
27 |
28 | ## Installation
29 |
30 | ### With Composer
31 |
32 | The recommended - and easiest way - to install is via [Composer](https://getcomposer.org/).
33 | Require the library in your project's `composer.json` file.
34 |
35 | ```php
36 | $ composer require opencage/geocode
37 | ```
38 |
39 | Import the Geocoder class.
40 |
41 | ```php
42 | require "vendor/autoload.php";
43 | ```
44 |
45 | ### The old fashioned way
46 |
47 | See the file `demo/geocode.php`
48 |
49 |
50 | ## Geocoding
51 |
52 | ```php
53 | $geocoder = new \OpenCage\Geocoder\Geocoder('YOUR-API-KEY');
54 | $result = $geocoder->geocode('82 Clerkenwell Road, London');
55 | print_r($result);
56 | ```
57 |
58 | ### Reverse geocoding
59 |
60 | ```php
61 | $geocoder = new \OpenCage\Geocoder\Geocoder('YOUR-API-KEY');
62 | $result = $geocoder->geocode('43.831,4.360'); # latitude,longitude (y,x)
63 | print $result['results'][0]['formatted'];
64 | // 3 Rue de Rivarol, 30020 Nîmes, France
65 | ```
66 |
67 | ### Set optional parameters
68 |
69 | See the full list at:
70 | [https://opencagedata.com/api#optional-params](https://opencagedata.com/api#optional-params)
71 |
72 | ```php
73 | $result = $geocoder->geocode('6 Rue Massillon, 30020 Nîmes, France', [
74 | 'language' => 'fr',
75 | 'countrycode' => 'fr'
76 | ]);
77 | if ($result && $result['total_results'] > 0) {
78 | $first = $result['results'][0];
79 | print $first['geometry']['lng'] . ';' . $first['geometry']['lat'] . ';' . $first['formatted'] . "\n";
80 | // 4.360081;43.8316276;6 Rue Massillon, 30020 Nîmes, Frankreich
81 | }
82 | ```
83 |
84 | ### Set a proxy URL
85 |
86 | ```php
87 | $geocoder->setProxy('http://proxy.example.com:1234');
88 | $result = $geocoder->geocode("Brandenburger Tor, Berlin");
89 | print_r($result['results'][0]['formatted']);
90 | // Brandenburger Tor, Unter den Linden, 10117 Berlin, Germany
91 | print_r($result['results'][0]['geometry']);
92 | // Array
93 | // (
94 | // [lat] => 52.5166047
95 | // [lng] => 13.3809897
96 | // )
97 | ```
98 |
99 | ## Example results
100 |
101 |
102 | ```php
103 | Array
104 | (
105 | [total_results] => 2
106 | [status] => Array
107 | (
108 | [message] => OK
109 | [code] => 200
110 | )
111 | [results] => Array
112 | (
113 | [0] => Array
114 | (
115 | [annotations] => Array
116 | (
117 | [DMS] => Array
118 | (
119 | [lat] => 51° 31' 21.60894'' N
120 | [lng] => 0° 6' 8.95198'' E
121 | )
122 |
123 | [MGRS] => 30UYC0100511930
124 | [Maidenhead] => IO91wm75qk
125 | [Mercator] => Array
126 | (
127 | [x] => -11408.763
128 | [y] => 6680801.955
129 | )
130 |
131 | [OSGB] => Array
132 | (
133 | [easting] => 531628.199
134 | [gridref] => TQ 316 821
135 | [northing] => 182177.015
136 | )
137 |
138 | [OSM] => Array
139 | (
140 | [url] => http://www.openstreetmap.org/?mlat=51.52267&mlon=-0.10249#map=17/51.52267/-0.10249
141 | )
142 |
143 | [callingcode] => 44
144 | [geohash] => gcpvjemm7csmhczg9cvt
145 | [sun] => Array
146 | (
147 | [rise] => Array
148 | (
149 | [apparent] => 1452931140
150 | [astronomical] => 1452923940
151 | [civil] => 1452928800
152 | [nautical] => 1452926280
153 | )
154 |
155 | [set] => Array
156 | (
157 | [apparent] => 1452961320
158 | [astronomical] => 1452968520
159 | [civil] => 1452963660
160 | [nautical] => 1452966120
161 | )
162 |
163 | )
164 |
165 | [timezone] => Array
166 | (
167 | [name] => Europe/London
168 | [now_in_dst] => 0
169 | [offset_sec] => 0
170 | [offset_string] => 0
171 | [short_name] => GMT
172 | )
173 |
174 | [what3words] => Array
175 | (
176 | [words] => gallons.trim.tips
177 | )
178 |
179 | )
180 |
181 | [bounds] => Array
182 | (
183 | [northeast] => Array
184 | (
185 | [lat] => 51.5227563
186 | [lng] => -0.1023801
187 | )
188 |
189 | [southwest] => Array
190 | (
191 | [lat] => 51.5226042
192 | [lng] => -0.1025907
193 | )
194 |
195 | )
196 |
197 | [components] => Array
198 | (
199 | [city] => London
200 | [country] => United Kingdom
201 | [country_code] => gb
202 | [house_number] => 82
203 | [postcode] => EC1M 5RF
204 | [road] => Clerkenwell Road
205 | [state] => England
206 | [state_district] => Greater London
207 | [suburb] => Clerkenwell
208 | )
209 |
210 | [confidence] => 10
211 | [formatted] => 82 Clerkenwell Road, London EC1M 5RF, United Kingdom
212 | [geometry] => Array
213 | (
214 | [lat] => 51.52266915
215 | [lng] => -0.10248666188363
216 | )
217 |
218 | )
219 |
220 | [1] => Array
221 | (
222 | [annotations] => Array
223 | (
224 | [DMS] => Array
225 | (
226 | [lat] => 51° 30' 30.70800'' N
227 | [lng] => 0° 7' 32.66400'' E
228 | )
229 |
230 | [MGRS] => 30UXC9945410295
231 | [Maidenhead] => IO91wm42vb
232 | [Mercator] => Array
233 | (
234 | [x] => -13997.313
235 | [y] => 6678279.278
236 | )
237 |
238 | [OSGB] => Array
239 | (
240 | [easting] => 530055.544
241 | [gridref] => TQ 300 805
242 | [northing] => 180563.298
243 | )
244 |
245 | [OSM] => Array
246 | (
247 | [url] => http://www.openstreetmap.org/?mlat=51.50853&mlon=-0.12574#map=17/51.50853/-0.12574
248 | )
249 |
250 | [geohash] => gcpvj0u6yjcmwxz8bn43
251 | [sun] => Array
252 | (
253 | [rise] => Array
254 | (
255 | [apparent] => 1452931140
256 | [astronomical] => 1452923940
257 | [civil] => 1452928800
258 | [nautical] => 1452926340
259 | )
260 |
261 | [set] => Array
262 | (
263 | [apparent] => 1452961320
264 | [astronomical] => 1452968520
265 | [civil] => 1452963660
266 | [nautical] => 1452966120
267 | )
268 |
269 | )
270 |
271 | [timezone] => Array
272 | (
273 | [name] => Europe/London
274 | [now_in_dst] => 0
275 | [offset_sec] => 0
276 | [offset_string] => 0
277 | [short_name] => GMT
278 | )
279 |
280 | [what3words] => Array
281 | (
282 | [words] => thing.then.link
283 | )
284 |
285 | )
286 |
287 | [bounds] => Array
288 | (
289 | [northeast] => Array
290 | (
291 | [lat] => 51.7202301025
292 | [lng] => 0.336111992598
293 | )
294 |
295 | [southwest] => Array
296 | (
297 | [lat] => 51.2786598206
298 | [lng] => -0.523222982883
299 | )
300 |
301 | )
302 |
303 | [components] => Array
304 | (
305 | [country] => United Kingdom
306 | [county] => Greater London
307 | [state] => England
308 | [town] => London
309 | )
310 |
311 | [confidence] => 1
312 | [formatted] => London, Greater London, United Kingdom
313 | [geometry] => Array
314 | (
315 | [lat] => 51.50853
316 | [lng] => -0.12574
317 | )
318 |
319 | )
320 |
321 | )
322 | )
323 | ```
324 |
325 | ## Copyright
326 |
327 | Copyright (c) OpenCage GmbH. See LICENSE for details.
328 |
329 | ## Who is OpenCage GmbH?
330 |
331 |
332 |
333 | We run a worldwide [geocoding API](https://opencagedata.com/api) and [geosearch](https://opencagedata.com/geosearch) service based on open data.
334 | Learn more [about us](https://opencagedata.com/about).
335 |
336 | We also run [Geomob](https://thegeomob.com), a series of regular meetups for location based service creators, where we do our best to highlight geoinnovation. If you like geo stuff, you will probably enjoy [the Geomob podcast](https://thegeomob.com/podcast/).
337 |
338 | -- end --
339 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Vulnerability
4 |
5 | Please see the [OpenCage security bounty page](https://opencagedata.com/security-bounty)
6 |
--------------------------------------------------------------------------------
/Vagrantfile:
--------------------------------------------------------------------------------
1 | # -*- mode: ruby -*-
2 | # vi: set ft=ruby :
3 |
4 | Vagrant.configure("2") do |config|
5 | # The most common configuration options are documented and commented below.
6 | # For a complete reference, please see the online documentation at
7 | # https://docs.vagrantup.com.
8 |
9 | # Every Vagrant development environment requires a box. You can search for
10 | # boxes at https://vagrantcloud.com/search.
11 | config.vm.box = "bento/ubuntu-24.04"
12 | if RUBY_PLATFORM.include?('darwin') && RUBY_PLATFORM.include?('arm64')
13 | # Apple Silicon/M processor
14 | config.vm.box = 'gutehall/ubuntu24-04'
15 | end
16 |
17 | config.vm.synced_folder ".", "/home/vagrant/php-opencage-geocode"
18 |
19 | # Enable provisioning with a shell script. Additional provisioners such as
20 | # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
21 | # documentation for more information about their specific syntax and use.
22 | config.vm.provision "shell", inline: <<-SHELL
23 | apt-get update -qq
24 | apt-get install -y -qq php-cli php-curl php-xml php-mbstring unzip
25 | curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
26 | cd /home/vagrant/php-opencage-geocode
27 | composer install
28 | # run tests:
29 | ./vendor/bin/phpunit
30 | ./vendor/bin/phpcs .
31 | SHELL
32 | end
33 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "opencage/geocode",
3 | "description": "A PHP library for geocoding via the OpenCage Geocoder API",
4 | "license": "BSD-2-Clause",
5 | "authors": [
6 | {
7 | "name": "OpenCage GmbH",
8 | "email": "support@opencagedata.com",
9 | "homepage": "https://opencagedata.com"
10 | }
11 | ],
12 | "autoload": {
13 | "psr-4": {
14 | "OpenCage\\Geocoder\\": "src"
15 | }
16 | },
17 | "require": {
18 | "php": ">=8.0"
19 | },
20 | "require-dev": {
21 | "phpunit/phpunit": "~11.0",
22 | "squizlabs/php_codesniffer": "^3.7",
23 | "phpstan/phpstan": "^2.0.0"
24 | },
25 | "archive": {
26 | "exclude": ["vendor", ".DS_Store"]
27 | },
28 | "keywords": [
29 | "geocode",
30 | "addresses",
31 | "geocoding",
32 | "opencagedata"
33 | ],
34 | "support": {
35 | "issues": "https://github.com/OpenCageData/php-opencage-geocode/issues",
36 | "source": "https://github.com/OpenCageData/php-opencage-geocode",
37 | "docs": "https://opencagedata.com/api"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "a01464c881c41a49ed2eca71ef038ad4",
8 | "packages": [],
9 | "packages-dev": [
10 | {
11 | "name": "myclabs/deep-copy",
12 | "version": "1.12.1",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/myclabs/DeepCopy.git",
16 | "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
21 | "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "php": "^7.1 || ^8.0"
26 | },
27 | "conflict": {
28 | "doctrine/collections": "<1.6.8",
29 | "doctrine/common": "<2.13.3 || >=3 <3.2.2"
30 | },
31 | "require-dev": {
32 | "doctrine/collections": "^1.6.8",
33 | "doctrine/common": "^2.13.3 || ^3.2.2",
34 | "phpspec/prophecy": "^1.10",
35 | "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
36 | },
37 | "type": "library",
38 | "autoload": {
39 | "files": [
40 | "src/DeepCopy/deep_copy.php"
41 | ],
42 | "psr-4": {
43 | "DeepCopy\\": "src/DeepCopy/"
44 | }
45 | },
46 | "notification-url": "https://packagist.org/downloads/",
47 | "license": [
48 | "MIT"
49 | ],
50 | "description": "Create deep copies (clones) of your objects",
51 | "keywords": [
52 | "clone",
53 | "copy",
54 | "duplicate",
55 | "object",
56 | "object graph"
57 | ],
58 | "support": {
59 | "issues": "https://github.com/myclabs/DeepCopy/issues",
60 | "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1"
61 | },
62 | "funding": [
63 | {
64 | "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
65 | "type": "tidelift"
66 | }
67 | ],
68 | "time": "2024-11-08T17:47:46+00:00"
69 | },
70 | {
71 | "name": "nikic/php-parser",
72 | "version": "v5.3.1",
73 | "source": {
74 | "type": "git",
75 | "url": "https://github.com/nikic/PHP-Parser.git",
76 | "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b"
77 | },
78 | "dist": {
79 | "type": "zip",
80 | "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b",
81 | "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b",
82 | "shasum": ""
83 | },
84 | "require": {
85 | "ext-ctype": "*",
86 | "ext-json": "*",
87 | "ext-tokenizer": "*",
88 | "php": ">=7.4"
89 | },
90 | "require-dev": {
91 | "ircmaxell/php-yacc": "^0.0.7",
92 | "phpunit/phpunit": "^9.0"
93 | },
94 | "bin": [
95 | "bin/php-parse"
96 | ],
97 | "type": "library",
98 | "extra": {
99 | "branch-alias": {
100 | "dev-master": "5.0-dev"
101 | }
102 | },
103 | "autoload": {
104 | "psr-4": {
105 | "PhpParser\\": "lib/PhpParser"
106 | }
107 | },
108 | "notification-url": "https://packagist.org/downloads/",
109 | "license": [
110 | "BSD-3-Clause"
111 | ],
112 | "authors": [
113 | {
114 | "name": "Nikita Popov"
115 | }
116 | ],
117 | "description": "A PHP parser written in PHP",
118 | "keywords": [
119 | "parser",
120 | "php"
121 | ],
122 | "support": {
123 | "issues": "https://github.com/nikic/PHP-Parser/issues",
124 | "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1"
125 | },
126 | "time": "2024-10-08T18:51:32+00:00"
127 | },
128 | {
129 | "name": "phar-io/manifest",
130 | "version": "2.0.4",
131 | "source": {
132 | "type": "git",
133 | "url": "https://github.com/phar-io/manifest.git",
134 | "reference": "54750ef60c58e43759730615a392c31c80e23176"
135 | },
136 | "dist": {
137 | "type": "zip",
138 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
139 | "reference": "54750ef60c58e43759730615a392c31c80e23176",
140 | "shasum": ""
141 | },
142 | "require": {
143 | "ext-dom": "*",
144 | "ext-libxml": "*",
145 | "ext-phar": "*",
146 | "ext-xmlwriter": "*",
147 | "phar-io/version": "^3.0.1",
148 | "php": "^7.2 || ^8.0"
149 | },
150 | "type": "library",
151 | "extra": {
152 | "branch-alias": {
153 | "dev-master": "2.0.x-dev"
154 | }
155 | },
156 | "autoload": {
157 | "classmap": [
158 | "src/"
159 | ]
160 | },
161 | "notification-url": "https://packagist.org/downloads/",
162 | "license": [
163 | "BSD-3-Clause"
164 | ],
165 | "authors": [
166 | {
167 | "name": "Arne Blankerts",
168 | "email": "arne@blankerts.de",
169 | "role": "Developer"
170 | },
171 | {
172 | "name": "Sebastian Heuer",
173 | "email": "sebastian@phpeople.de",
174 | "role": "Developer"
175 | },
176 | {
177 | "name": "Sebastian Bergmann",
178 | "email": "sebastian@phpunit.de",
179 | "role": "Developer"
180 | }
181 | ],
182 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
183 | "support": {
184 | "issues": "https://github.com/phar-io/manifest/issues",
185 | "source": "https://github.com/phar-io/manifest/tree/2.0.4"
186 | },
187 | "funding": [
188 | {
189 | "url": "https://github.com/theseer",
190 | "type": "github"
191 | }
192 | ],
193 | "time": "2024-03-03T12:33:53+00:00"
194 | },
195 | {
196 | "name": "phar-io/version",
197 | "version": "3.2.1",
198 | "source": {
199 | "type": "git",
200 | "url": "https://github.com/phar-io/version.git",
201 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
202 | },
203 | "dist": {
204 | "type": "zip",
205 | "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
206 | "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
207 | "shasum": ""
208 | },
209 | "require": {
210 | "php": "^7.2 || ^8.0"
211 | },
212 | "type": "library",
213 | "autoload": {
214 | "classmap": [
215 | "src/"
216 | ]
217 | },
218 | "notification-url": "https://packagist.org/downloads/",
219 | "license": [
220 | "BSD-3-Clause"
221 | ],
222 | "authors": [
223 | {
224 | "name": "Arne Blankerts",
225 | "email": "arne@blankerts.de",
226 | "role": "Developer"
227 | },
228 | {
229 | "name": "Sebastian Heuer",
230 | "email": "sebastian@phpeople.de",
231 | "role": "Developer"
232 | },
233 | {
234 | "name": "Sebastian Bergmann",
235 | "email": "sebastian@phpunit.de",
236 | "role": "Developer"
237 | }
238 | ],
239 | "description": "Library for handling version information and constraints",
240 | "support": {
241 | "issues": "https://github.com/phar-io/version/issues",
242 | "source": "https://github.com/phar-io/version/tree/3.2.1"
243 | },
244 | "time": "2022-02-21T01:04:05+00:00"
245 | },
246 | {
247 | "name": "phpstan/phpstan",
248 | "version": "2.0.2",
249 | "source": {
250 | "type": "git",
251 | "url": "https://github.com/phpstan/phpstan.git",
252 | "reference": "6c98c7600fc717b2c78c11ef60040d5b1e359c82"
253 | },
254 | "dist": {
255 | "type": "zip",
256 | "url": "https://api.github.com/repos/phpstan/phpstan/zipball/6c98c7600fc717b2c78c11ef60040d5b1e359c82",
257 | "reference": "6c98c7600fc717b2c78c11ef60040d5b1e359c82",
258 | "shasum": ""
259 | },
260 | "require": {
261 | "php": "^7.4|^8.0"
262 | },
263 | "conflict": {
264 | "phpstan/phpstan-shim": "*"
265 | },
266 | "bin": [
267 | "phpstan",
268 | "phpstan.phar"
269 | ],
270 | "type": "library",
271 | "autoload": {
272 | "files": [
273 | "bootstrap.php"
274 | ]
275 | },
276 | "notification-url": "https://packagist.org/downloads/",
277 | "license": [
278 | "MIT"
279 | ],
280 | "description": "PHPStan - PHP Static Analysis Tool",
281 | "keywords": [
282 | "dev",
283 | "static analysis"
284 | ],
285 | "support": {
286 | "docs": "https://phpstan.org/user-guide/getting-started",
287 | "forum": "https://github.com/phpstan/phpstan/discussions",
288 | "issues": "https://github.com/phpstan/phpstan/issues",
289 | "security": "https://github.com/phpstan/phpstan/security/policy",
290 | "source": "https://github.com/phpstan/phpstan-src"
291 | },
292 | "funding": [
293 | {
294 | "url": "https://github.com/ondrejmirtes",
295 | "type": "github"
296 | },
297 | {
298 | "url": "https://github.com/phpstan",
299 | "type": "github"
300 | }
301 | ],
302 | "time": "2024-11-17T14:17:00+00:00"
303 | },
304 | {
305 | "name": "phpunit/php-code-coverage",
306 | "version": "11.0.7",
307 | "source": {
308 | "type": "git",
309 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
310 | "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca"
311 | },
312 | "dist": {
313 | "type": "zip",
314 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f7f08030e8811582cc459871d28d6f5a1a4d35ca",
315 | "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca",
316 | "shasum": ""
317 | },
318 | "require": {
319 | "ext-dom": "*",
320 | "ext-libxml": "*",
321 | "ext-xmlwriter": "*",
322 | "nikic/php-parser": "^5.3.1",
323 | "php": ">=8.2",
324 | "phpunit/php-file-iterator": "^5.1.0",
325 | "phpunit/php-text-template": "^4.0.1",
326 | "sebastian/code-unit-reverse-lookup": "^4.0.1",
327 | "sebastian/complexity": "^4.0.1",
328 | "sebastian/environment": "^7.2.0",
329 | "sebastian/lines-of-code": "^3.0.1",
330 | "sebastian/version": "^5.0.2",
331 | "theseer/tokenizer": "^1.2.3"
332 | },
333 | "require-dev": {
334 | "phpunit/phpunit": "^11.4.1"
335 | },
336 | "suggest": {
337 | "ext-pcov": "PHP extension that provides line coverage",
338 | "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
339 | },
340 | "type": "library",
341 | "extra": {
342 | "branch-alias": {
343 | "dev-main": "11.0.x-dev"
344 | }
345 | },
346 | "autoload": {
347 | "classmap": [
348 | "src/"
349 | ]
350 | },
351 | "notification-url": "https://packagist.org/downloads/",
352 | "license": [
353 | "BSD-3-Clause"
354 | ],
355 | "authors": [
356 | {
357 | "name": "Sebastian Bergmann",
358 | "email": "sebastian@phpunit.de",
359 | "role": "lead"
360 | }
361 | ],
362 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
363 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
364 | "keywords": [
365 | "coverage",
366 | "testing",
367 | "xunit"
368 | ],
369 | "support": {
370 | "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
371 | "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
372 | "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.7"
373 | },
374 | "funding": [
375 | {
376 | "url": "https://github.com/sebastianbergmann",
377 | "type": "github"
378 | }
379 | ],
380 | "time": "2024-10-09T06:21:38+00:00"
381 | },
382 | {
383 | "name": "phpunit/php-file-iterator",
384 | "version": "5.1.0",
385 | "source": {
386 | "type": "git",
387 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
388 | "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6"
389 | },
390 | "dist": {
391 | "type": "zip",
392 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6",
393 | "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6",
394 | "shasum": ""
395 | },
396 | "require": {
397 | "php": ">=8.2"
398 | },
399 | "require-dev": {
400 | "phpunit/phpunit": "^11.0"
401 | },
402 | "type": "library",
403 | "extra": {
404 | "branch-alias": {
405 | "dev-main": "5.0-dev"
406 | }
407 | },
408 | "autoload": {
409 | "classmap": [
410 | "src/"
411 | ]
412 | },
413 | "notification-url": "https://packagist.org/downloads/",
414 | "license": [
415 | "BSD-3-Clause"
416 | ],
417 | "authors": [
418 | {
419 | "name": "Sebastian Bergmann",
420 | "email": "sebastian@phpunit.de",
421 | "role": "lead"
422 | }
423 | ],
424 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
425 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
426 | "keywords": [
427 | "filesystem",
428 | "iterator"
429 | ],
430 | "support": {
431 | "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
432 | "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
433 | "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0"
434 | },
435 | "funding": [
436 | {
437 | "url": "https://github.com/sebastianbergmann",
438 | "type": "github"
439 | }
440 | ],
441 | "time": "2024-08-27T05:02:59+00:00"
442 | },
443 | {
444 | "name": "phpunit/php-invoker",
445 | "version": "5.0.1",
446 | "source": {
447 | "type": "git",
448 | "url": "https://github.com/sebastianbergmann/php-invoker.git",
449 | "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2"
450 | },
451 | "dist": {
452 | "type": "zip",
453 | "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2",
454 | "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2",
455 | "shasum": ""
456 | },
457 | "require": {
458 | "php": ">=8.2"
459 | },
460 | "require-dev": {
461 | "ext-pcntl": "*",
462 | "phpunit/phpunit": "^11.0"
463 | },
464 | "suggest": {
465 | "ext-pcntl": "*"
466 | },
467 | "type": "library",
468 | "extra": {
469 | "branch-alias": {
470 | "dev-main": "5.0-dev"
471 | }
472 | },
473 | "autoload": {
474 | "classmap": [
475 | "src/"
476 | ]
477 | },
478 | "notification-url": "https://packagist.org/downloads/",
479 | "license": [
480 | "BSD-3-Clause"
481 | ],
482 | "authors": [
483 | {
484 | "name": "Sebastian Bergmann",
485 | "email": "sebastian@phpunit.de",
486 | "role": "lead"
487 | }
488 | ],
489 | "description": "Invoke callables with a timeout",
490 | "homepage": "https://github.com/sebastianbergmann/php-invoker/",
491 | "keywords": [
492 | "process"
493 | ],
494 | "support": {
495 | "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
496 | "security": "https://github.com/sebastianbergmann/php-invoker/security/policy",
497 | "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1"
498 | },
499 | "funding": [
500 | {
501 | "url": "https://github.com/sebastianbergmann",
502 | "type": "github"
503 | }
504 | ],
505 | "time": "2024-07-03T05:07:44+00:00"
506 | },
507 | {
508 | "name": "phpunit/php-text-template",
509 | "version": "4.0.1",
510 | "source": {
511 | "type": "git",
512 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
513 | "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964"
514 | },
515 | "dist": {
516 | "type": "zip",
517 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964",
518 | "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964",
519 | "shasum": ""
520 | },
521 | "require": {
522 | "php": ">=8.2"
523 | },
524 | "require-dev": {
525 | "phpunit/phpunit": "^11.0"
526 | },
527 | "type": "library",
528 | "extra": {
529 | "branch-alias": {
530 | "dev-main": "4.0-dev"
531 | }
532 | },
533 | "autoload": {
534 | "classmap": [
535 | "src/"
536 | ]
537 | },
538 | "notification-url": "https://packagist.org/downloads/",
539 | "license": [
540 | "BSD-3-Clause"
541 | ],
542 | "authors": [
543 | {
544 | "name": "Sebastian Bergmann",
545 | "email": "sebastian@phpunit.de",
546 | "role": "lead"
547 | }
548 | ],
549 | "description": "Simple template engine.",
550 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
551 | "keywords": [
552 | "template"
553 | ],
554 | "support": {
555 | "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
556 | "security": "https://github.com/sebastianbergmann/php-text-template/security/policy",
557 | "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1"
558 | },
559 | "funding": [
560 | {
561 | "url": "https://github.com/sebastianbergmann",
562 | "type": "github"
563 | }
564 | ],
565 | "time": "2024-07-03T05:08:43+00:00"
566 | },
567 | {
568 | "name": "phpunit/php-timer",
569 | "version": "7.0.1",
570 | "source": {
571 | "type": "git",
572 | "url": "https://github.com/sebastianbergmann/php-timer.git",
573 | "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3"
574 | },
575 | "dist": {
576 | "type": "zip",
577 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3",
578 | "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3",
579 | "shasum": ""
580 | },
581 | "require": {
582 | "php": ">=8.2"
583 | },
584 | "require-dev": {
585 | "phpunit/phpunit": "^11.0"
586 | },
587 | "type": "library",
588 | "extra": {
589 | "branch-alias": {
590 | "dev-main": "7.0-dev"
591 | }
592 | },
593 | "autoload": {
594 | "classmap": [
595 | "src/"
596 | ]
597 | },
598 | "notification-url": "https://packagist.org/downloads/",
599 | "license": [
600 | "BSD-3-Clause"
601 | ],
602 | "authors": [
603 | {
604 | "name": "Sebastian Bergmann",
605 | "email": "sebastian@phpunit.de",
606 | "role": "lead"
607 | }
608 | ],
609 | "description": "Utility class for timing",
610 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
611 | "keywords": [
612 | "timer"
613 | ],
614 | "support": {
615 | "issues": "https://github.com/sebastianbergmann/php-timer/issues",
616 | "security": "https://github.com/sebastianbergmann/php-timer/security/policy",
617 | "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1"
618 | },
619 | "funding": [
620 | {
621 | "url": "https://github.com/sebastianbergmann",
622 | "type": "github"
623 | }
624 | ],
625 | "time": "2024-07-03T05:09:35+00:00"
626 | },
627 | {
628 | "name": "phpunit/phpunit",
629 | "version": "11.4.3",
630 | "source": {
631 | "type": "git",
632 | "url": "https://github.com/sebastianbergmann/phpunit.git",
633 | "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76"
634 | },
635 | "dist": {
636 | "type": "zip",
637 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e8e8ed1854de5d36c088ec1833beae40d2dedd76",
638 | "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76",
639 | "shasum": ""
640 | },
641 | "require": {
642 | "ext-dom": "*",
643 | "ext-json": "*",
644 | "ext-libxml": "*",
645 | "ext-mbstring": "*",
646 | "ext-xml": "*",
647 | "ext-xmlwriter": "*",
648 | "myclabs/deep-copy": "^1.12.0",
649 | "phar-io/manifest": "^2.0.4",
650 | "phar-io/version": "^3.2.1",
651 | "php": ">=8.2",
652 | "phpunit/php-code-coverage": "^11.0.7",
653 | "phpunit/php-file-iterator": "^5.1.0",
654 | "phpunit/php-invoker": "^5.0.1",
655 | "phpunit/php-text-template": "^4.0.1",
656 | "phpunit/php-timer": "^7.0.1",
657 | "sebastian/cli-parser": "^3.0.2",
658 | "sebastian/code-unit": "^3.0.1",
659 | "sebastian/comparator": "^6.1.1",
660 | "sebastian/diff": "^6.0.2",
661 | "sebastian/environment": "^7.2.0",
662 | "sebastian/exporter": "^6.1.3",
663 | "sebastian/global-state": "^7.0.2",
664 | "sebastian/object-enumerator": "^6.0.1",
665 | "sebastian/type": "^5.1.0",
666 | "sebastian/version": "^5.0.2"
667 | },
668 | "suggest": {
669 | "ext-soap": "To be able to generate mocks based on WSDL files"
670 | },
671 | "bin": [
672 | "phpunit"
673 | ],
674 | "type": "library",
675 | "extra": {
676 | "branch-alias": {
677 | "dev-main": "11.4-dev"
678 | }
679 | },
680 | "autoload": {
681 | "files": [
682 | "src/Framework/Assert/Functions.php"
683 | ],
684 | "classmap": [
685 | "src/"
686 | ]
687 | },
688 | "notification-url": "https://packagist.org/downloads/",
689 | "license": [
690 | "BSD-3-Clause"
691 | ],
692 | "authors": [
693 | {
694 | "name": "Sebastian Bergmann",
695 | "email": "sebastian@phpunit.de",
696 | "role": "lead"
697 | }
698 | ],
699 | "description": "The PHP Unit Testing framework.",
700 | "homepage": "https://phpunit.de/",
701 | "keywords": [
702 | "phpunit",
703 | "testing",
704 | "xunit"
705 | ],
706 | "support": {
707 | "issues": "https://github.com/sebastianbergmann/phpunit/issues",
708 | "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
709 | "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.3"
710 | },
711 | "funding": [
712 | {
713 | "url": "https://phpunit.de/sponsors.html",
714 | "type": "custom"
715 | },
716 | {
717 | "url": "https://github.com/sebastianbergmann",
718 | "type": "github"
719 | },
720 | {
721 | "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
722 | "type": "tidelift"
723 | }
724 | ],
725 | "time": "2024-10-28T13:07:50+00:00"
726 | },
727 | {
728 | "name": "sebastian/cli-parser",
729 | "version": "3.0.2",
730 | "source": {
731 | "type": "git",
732 | "url": "https://github.com/sebastianbergmann/cli-parser.git",
733 | "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180"
734 | },
735 | "dist": {
736 | "type": "zip",
737 | "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180",
738 | "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180",
739 | "shasum": ""
740 | },
741 | "require": {
742 | "php": ">=8.2"
743 | },
744 | "require-dev": {
745 | "phpunit/phpunit": "^11.0"
746 | },
747 | "type": "library",
748 | "extra": {
749 | "branch-alias": {
750 | "dev-main": "3.0-dev"
751 | }
752 | },
753 | "autoload": {
754 | "classmap": [
755 | "src/"
756 | ]
757 | },
758 | "notification-url": "https://packagist.org/downloads/",
759 | "license": [
760 | "BSD-3-Clause"
761 | ],
762 | "authors": [
763 | {
764 | "name": "Sebastian Bergmann",
765 | "email": "sebastian@phpunit.de",
766 | "role": "lead"
767 | }
768 | ],
769 | "description": "Library for parsing CLI options",
770 | "homepage": "https://github.com/sebastianbergmann/cli-parser",
771 | "support": {
772 | "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
773 | "security": "https://github.com/sebastianbergmann/cli-parser/security/policy",
774 | "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2"
775 | },
776 | "funding": [
777 | {
778 | "url": "https://github.com/sebastianbergmann",
779 | "type": "github"
780 | }
781 | ],
782 | "time": "2024-07-03T04:41:36+00:00"
783 | },
784 | {
785 | "name": "sebastian/code-unit",
786 | "version": "3.0.1",
787 | "source": {
788 | "type": "git",
789 | "url": "https://github.com/sebastianbergmann/code-unit.git",
790 | "reference": "6bb7d09d6623567178cf54126afa9c2310114268"
791 | },
792 | "dist": {
793 | "type": "zip",
794 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268",
795 | "reference": "6bb7d09d6623567178cf54126afa9c2310114268",
796 | "shasum": ""
797 | },
798 | "require": {
799 | "php": ">=8.2"
800 | },
801 | "require-dev": {
802 | "phpunit/phpunit": "^11.0"
803 | },
804 | "type": "library",
805 | "extra": {
806 | "branch-alias": {
807 | "dev-main": "3.0-dev"
808 | }
809 | },
810 | "autoload": {
811 | "classmap": [
812 | "src/"
813 | ]
814 | },
815 | "notification-url": "https://packagist.org/downloads/",
816 | "license": [
817 | "BSD-3-Clause"
818 | ],
819 | "authors": [
820 | {
821 | "name": "Sebastian Bergmann",
822 | "email": "sebastian@phpunit.de",
823 | "role": "lead"
824 | }
825 | ],
826 | "description": "Collection of value objects that represent the PHP code units",
827 | "homepage": "https://github.com/sebastianbergmann/code-unit",
828 | "support": {
829 | "issues": "https://github.com/sebastianbergmann/code-unit/issues",
830 | "security": "https://github.com/sebastianbergmann/code-unit/security/policy",
831 | "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.1"
832 | },
833 | "funding": [
834 | {
835 | "url": "https://github.com/sebastianbergmann",
836 | "type": "github"
837 | }
838 | ],
839 | "time": "2024-07-03T04:44:28+00:00"
840 | },
841 | {
842 | "name": "sebastian/code-unit-reverse-lookup",
843 | "version": "4.0.1",
844 | "source": {
845 | "type": "git",
846 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
847 | "reference": "183a9b2632194febd219bb9246eee421dad8d45e"
848 | },
849 | "dist": {
850 | "type": "zip",
851 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e",
852 | "reference": "183a9b2632194febd219bb9246eee421dad8d45e",
853 | "shasum": ""
854 | },
855 | "require": {
856 | "php": ">=8.2"
857 | },
858 | "require-dev": {
859 | "phpunit/phpunit": "^11.0"
860 | },
861 | "type": "library",
862 | "extra": {
863 | "branch-alias": {
864 | "dev-main": "4.0-dev"
865 | }
866 | },
867 | "autoload": {
868 | "classmap": [
869 | "src/"
870 | ]
871 | },
872 | "notification-url": "https://packagist.org/downloads/",
873 | "license": [
874 | "BSD-3-Clause"
875 | ],
876 | "authors": [
877 | {
878 | "name": "Sebastian Bergmann",
879 | "email": "sebastian@phpunit.de"
880 | }
881 | ],
882 | "description": "Looks up which function or method a line of code belongs to",
883 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
884 | "support": {
885 | "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
886 | "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy",
887 | "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1"
888 | },
889 | "funding": [
890 | {
891 | "url": "https://github.com/sebastianbergmann",
892 | "type": "github"
893 | }
894 | ],
895 | "time": "2024-07-03T04:45:54+00:00"
896 | },
897 | {
898 | "name": "sebastian/comparator",
899 | "version": "6.2.1",
900 | "source": {
901 | "type": "git",
902 | "url": "https://github.com/sebastianbergmann/comparator.git",
903 | "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739"
904 | },
905 | "dist": {
906 | "type": "zip",
907 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739",
908 | "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739",
909 | "shasum": ""
910 | },
911 | "require": {
912 | "ext-dom": "*",
913 | "ext-mbstring": "*",
914 | "php": ">=8.2",
915 | "sebastian/diff": "^6.0",
916 | "sebastian/exporter": "^6.0"
917 | },
918 | "require-dev": {
919 | "phpunit/phpunit": "^11.4"
920 | },
921 | "type": "library",
922 | "extra": {
923 | "branch-alias": {
924 | "dev-main": "6.2-dev"
925 | }
926 | },
927 | "autoload": {
928 | "classmap": [
929 | "src/"
930 | ]
931 | },
932 | "notification-url": "https://packagist.org/downloads/",
933 | "license": [
934 | "BSD-3-Clause"
935 | ],
936 | "authors": [
937 | {
938 | "name": "Sebastian Bergmann",
939 | "email": "sebastian@phpunit.de"
940 | },
941 | {
942 | "name": "Jeff Welch",
943 | "email": "whatthejeff@gmail.com"
944 | },
945 | {
946 | "name": "Volker Dusch",
947 | "email": "github@wallbash.com"
948 | },
949 | {
950 | "name": "Bernhard Schussek",
951 | "email": "bschussek@2bepublished.at"
952 | }
953 | ],
954 | "description": "Provides the functionality to compare PHP values for equality",
955 | "homepage": "https://github.com/sebastianbergmann/comparator",
956 | "keywords": [
957 | "comparator",
958 | "compare",
959 | "equality"
960 | ],
961 | "support": {
962 | "issues": "https://github.com/sebastianbergmann/comparator/issues",
963 | "security": "https://github.com/sebastianbergmann/comparator/security/policy",
964 | "source": "https://github.com/sebastianbergmann/comparator/tree/6.2.1"
965 | },
966 | "funding": [
967 | {
968 | "url": "https://github.com/sebastianbergmann",
969 | "type": "github"
970 | }
971 | ],
972 | "time": "2024-10-31T05:30:08+00:00"
973 | },
974 | {
975 | "name": "sebastian/complexity",
976 | "version": "4.0.1",
977 | "source": {
978 | "type": "git",
979 | "url": "https://github.com/sebastianbergmann/complexity.git",
980 | "reference": "ee41d384ab1906c68852636b6de493846e13e5a0"
981 | },
982 | "dist": {
983 | "type": "zip",
984 | "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0",
985 | "reference": "ee41d384ab1906c68852636b6de493846e13e5a0",
986 | "shasum": ""
987 | },
988 | "require": {
989 | "nikic/php-parser": "^5.0",
990 | "php": ">=8.2"
991 | },
992 | "require-dev": {
993 | "phpunit/phpunit": "^11.0"
994 | },
995 | "type": "library",
996 | "extra": {
997 | "branch-alias": {
998 | "dev-main": "4.0-dev"
999 | }
1000 | },
1001 | "autoload": {
1002 | "classmap": [
1003 | "src/"
1004 | ]
1005 | },
1006 | "notification-url": "https://packagist.org/downloads/",
1007 | "license": [
1008 | "BSD-3-Clause"
1009 | ],
1010 | "authors": [
1011 | {
1012 | "name": "Sebastian Bergmann",
1013 | "email": "sebastian@phpunit.de",
1014 | "role": "lead"
1015 | }
1016 | ],
1017 | "description": "Library for calculating the complexity of PHP code units",
1018 | "homepage": "https://github.com/sebastianbergmann/complexity",
1019 | "support": {
1020 | "issues": "https://github.com/sebastianbergmann/complexity/issues",
1021 | "security": "https://github.com/sebastianbergmann/complexity/security/policy",
1022 | "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1"
1023 | },
1024 | "funding": [
1025 | {
1026 | "url": "https://github.com/sebastianbergmann",
1027 | "type": "github"
1028 | }
1029 | ],
1030 | "time": "2024-07-03T04:49:50+00:00"
1031 | },
1032 | {
1033 | "name": "sebastian/diff",
1034 | "version": "6.0.2",
1035 | "source": {
1036 | "type": "git",
1037 | "url": "https://github.com/sebastianbergmann/diff.git",
1038 | "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544"
1039 | },
1040 | "dist": {
1041 | "type": "zip",
1042 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544",
1043 | "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544",
1044 | "shasum": ""
1045 | },
1046 | "require": {
1047 | "php": ">=8.2"
1048 | },
1049 | "require-dev": {
1050 | "phpunit/phpunit": "^11.0",
1051 | "symfony/process": "^4.2 || ^5"
1052 | },
1053 | "type": "library",
1054 | "extra": {
1055 | "branch-alias": {
1056 | "dev-main": "6.0-dev"
1057 | }
1058 | },
1059 | "autoload": {
1060 | "classmap": [
1061 | "src/"
1062 | ]
1063 | },
1064 | "notification-url": "https://packagist.org/downloads/",
1065 | "license": [
1066 | "BSD-3-Clause"
1067 | ],
1068 | "authors": [
1069 | {
1070 | "name": "Sebastian Bergmann",
1071 | "email": "sebastian@phpunit.de"
1072 | },
1073 | {
1074 | "name": "Kore Nordmann",
1075 | "email": "mail@kore-nordmann.de"
1076 | }
1077 | ],
1078 | "description": "Diff implementation",
1079 | "homepage": "https://github.com/sebastianbergmann/diff",
1080 | "keywords": [
1081 | "diff",
1082 | "udiff",
1083 | "unidiff",
1084 | "unified diff"
1085 | ],
1086 | "support": {
1087 | "issues": "https://github.com/sebastianbergmann/diff/issues",
1088 | "security": "https://github.com/sebastianbergmann/diff/security/policy",
1089 | "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2"
1090 | },
1091 | "funding": [
1092 | {
1093 | "url": "https://github.com/sebastianbergmann",
1094 | "type": "github"
1095 | }
1096 | ],
1097 | "time": "2024-07-03T04:53:05+00:00"
1098 | },
1099 | {
1100 | "name": "sebastian/environment",
1101 | "version": "7.2.0",
1102 | "source": {
1103 | "type": "git",
1104 | "url": "https://github.com/sebastianbergmann/environment.git",
1105 | "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5"
1106 | },
1107 | "dist": {
1108 | "type": "zip",
1109 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5",
1110 | "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5",
1111 | "shasum": ""
1112 | },
1113 | "require": {
1114 | "php": ">=8.2"
1115 | },
1116 | "require-dev": {
1117 | "phpunit/phpunit": "^11.0"
1118 | },
1119 | "suggest": {
1120 | "ext-posix": "*"
1121 | },
1122 | "type": "library",
1123 | "extra": {
1124 | "branch-alias": {
1125 | "dev-main": "7.2-dev"
1126 | }
1127 | },
1128 | "autoload": {
1129 | "classmap": [
1130 | "src/"
1131 | ]
1132 | },
1133 | "notification-url": "https://packagist.org/downloads/",
1134 | "license": [
1135 | "BSD-3-Clause"
1136 | ],
1137 | "authors": [
1138 | {
1139 | "name": "Sebastian Bergmann",
1140 | "email": "sebastian@phpunit.de"
1141 | }
1142 | ],
1143 | "description": "Provides functionality to handle HHVM/PHP environments",
1144 | "homepage": "https://github.com/sebastianbergmann/environment",
1145 | "keywords": [
1146 | "Xdebug",
1147 | "environment",
1148 | "hhvm"
1149 | ],
1150 | "support": {
1151 | "issues": "https://github.com/sebastianbergmann/environment/issues",
1152 | "security": "https://github.com/sebastianbergmann/environment/security/policy",
1153 | "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0"
1154 | },
1155 | "funding": [
1156 | {
1157 | "url": "https://github.com/sebastianbergmann",
1158 | "type": "github"
1159 | }
1160 | ],
1161 | "time": "2024-07-03T04:54:44+00:00"
1162 | },
1163 | {
1164 | "name": "sebastian/exporter",
1165 | "version": "6.1.3",
1166 | "source": {
1167 | "type": "git",
1168 | "url": "https://github.com/sebastianbergmann/exporter.git",
1169 | "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e"
1170 | },
1171 | "dist": {
1172 | "type": "zip",
1173 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e",
1174 | "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e",
1175 | "shasum": ""
1176 | },
1177 | "require": {
1178 | "ext-mbstring": "*",
1179 | "php": ">=8.2",
1180 | "sebastian/recursion-context": "^6.0"
1181 | },
1182 | "require-dev": {
1183 | "phpunit/phpunit": "^11.2"
1184 | },
1185 | "type": "library",
1186 | "extra": {
1187 | "branch-alias": {
1188 | "dev-main": "6.1-dev"
1189 | }
1190 | },
1191 | "autoload": {
1192 | "classmap": [
1193 | "src/"
1194 | ]
1195 | },
1196 | "notification-url": "https://packagist.org/downloads/",
1197 | "license": [
1198 | "BSD-3-Clause"
1199 | ],
1200 | "authors": [
1201 | {
1202 | "name": "Sebastian Bergmann",
1203 | "email": "sebastian@phpunit.de"
1204 | },
1205 | {
1206 | "name": "Jeff Welch",
1207 | "email": "whatthejeff@gmail.com"
1208 | },
1209 | {
1210 | "name": "Volker Dusch",
1211 | "email": "github@wallbash.com"
1212 | },
1213 | {
1214 | "name": "Adam Harvey",
1215 | "email": "aharvey@php.net"
1216 | },
1217 | {
1218 | "name": "Bernhard Schussek",
1219 | "email": "bschussek@gmail.com"
1220 | }
1221 | ],
1222 | "description": "Provides the functionality to export PHP variables for visualization",
1223 | "homepage": "https://www.github.com/sebastianbergmann/exporter",
1224 | "keywords": [
1225 | "export",
1226 | "exporter"
1227 | ],
1228 | "support": {
1229 | "issues": "https://github.com/sebastianbergmann/exporter/issues",
1230 | "security": "https://github.com/sebastianbergmann/exporter/security/policy",
1231 | "source": "https://github.com/sebastianbergmann/exporter/tree/6.1.3"
1232 | },
1233 | "funding": [
1234 | {
1235 | "url": "https://github.com/sebastianbergmann",
1236 | "type": "github"
1237 | }
1238 | ],
1239 | "time": "2024-07-03T04:56:19+00:00"
1240 | },
1241 | {
1242 | "name": "sebastian/global-state",
1243 | "version": "7.0.2",
1244 | "source": {
1245 | "type": "git",
1246 | "url": "https://github.com/sebastianbergmann/global-state.git",
1247 | "reference": "3be331570a721f9a4b5917f4209773de17f747d7"
1248 | },
1249 | "dist": {
1250 | "type": "zip",
1251 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7",
1252 | "reference": "3be331570a721f9a4b5917f4209773de17f747d7",
1253 | "shasum": ""
1254 | },
1255 | "require": {
1256 | "php": ">=8.2",
1257 | "sebastian/object-reflector": "^4.0",
1258 | "sebastian/recursion-context": "^6.0"
1259 | },
1260 | "require-dev": {
1261 | "ext-dom": "*",
1262 | "phpunit/phpunit": "^11.0"
1263 | },
1264 | "type": "library",
1265 | "extra": {
1266 | "branch-alias": {
1267 | "dev-main": "7.0-dev"
1268 | }
1269 | },
1270 | "autoload": {
1271 | "classmap": [
1272 | "src/"
1273 | ]
1274 | },
1275 | "notification-url": "https://packagist.org/downloads/",
1276 | "license": [
1277 | "BSD-3-Clause"
1278 | ],
1279 | "authors": [
1280 | {
1281 | "name": "Sebastian Bergmann",
1282 | "email": "sebastian@phpunit.de"
1283 | }
1284 | ],
1285 | "description": "Snapshotting of global state",
1286 | "homepage": "https://www.github.com/sebastianbergmann/global-state",
1287 | "keywords": [
1288 | "global state"
1289 | ],
1290 | "support": {
1291 | "issues": "https://github.com/sebastianbergmann/global-state/issues",
1292 | "security": "https://github.com/sebastianbergmann/global-state/security/policy",
1293 | "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2"
1294 | },
1295 | "funding": [
1296 | {
1297 | "url": "https://github.com/sebastianbergmann",
1298 | "type": "github"
1299 | }
1300 | ],
1301 | "time": "2024-07-03T04:57:36+00:00"
1302 | },
1303 | {
1304 | "name": "sebastian/lines-of-code",
1305 | "version": "3.0.1",
1306 | "source": {
1307 | "type": "git",
1308 | "url": "https://github.com/sebastianbergmann/lines-of-code.git",
1309 | "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a"
1310 | },
1311 | "dist": {
1312 | "type": "zip",
1313 | "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a",
1314 | "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a",
1315 | "shasum": ""
1316 | },
1317 | "require": {
1318 | "nikic/php-parser": "^5.0",
1319 | "php": ">=8.2"
1320 | },
1321 | "require-dev": {
1322 | "phpunit/phpunit": "^11.0"
1323 | },
1324 | "type": "library",
1325 | "extra": {
1326 | "branch-alias": {
1327 | "dev-main": "3.0-dev"
1328 | }
1329 | },
1330 | "autoload": {
1331 | "classmap": [
1332 | "src/"
1333 | ]
1334 | },
1335 | "notification-url": "https://packagist.org/downloads/",
1336 | "license": [
1337 | "BSD-3-Clause"
1338 | ],
1339 | "authors": [
1340 | {
1341 | "name": "Sebastian Bergmann",
1342 | "email": "sebastian@phpunit.de",
1343 | "role": "lead"
1344 | }
1345 | ],
1346 | "description": "Library for counting the lines of code in PHP source code",
1347 | "homepage": "https://github.com/sebastianbergmann/lines-of-code",
1348 | "support": {
1349 | "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
1350 | "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
1351 | "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1"
1352 | },
1353 | "funding": [
1354 | {
1355 | "url": "https://github.com/sebastianbergmann",
1356 | "type": "github"
1357 | }
1358 | ],
1359 | "time": "2024-07-03T04:58:38+00:00"
1360 | },
1361 | {
1362 | "name": "sebastian/object-enumerator",
1363 | "version": "6.0.1",
1364 | "source": {
1365 | "type": "git",
1366 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1367 | "reference": "f5b498e631a74204185071eb41f33f38d64608aa"
1368 | },
1369 | "dist": {
1370 | "type": "zip",
1371 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa",
1372 | "reference": "f5b498e631a74204185071eb41f33f38d64608aa",
1373 | "shasum": ""
1374 | },
1375 | "require": {
1376 | "php": ">=8.2",
1377 | "sebastian/object-reflector": "^4.0",
1378 | "sebastian/recursion-context": "^6.0"
1379 | },
1380 | "require-dev": {
1381 | "phpunit/phpunit": "^11.0"
1382 | },
1383 | "type": "library",
1384 | "extra": {
1385 | "branch-alias": {
1386 | "dev-main": "6.0-dev"
1387 | }
1388 | },
1389 | "autoload": {
1390 | "classmap": [
1391 | "src/"
1392 | ]
1393 | },
1394 | "notification-url": "https://packagist.org/downloads/",
1395 | "license": [
1396 | "BSD-3-Clause"
1397 | ],
1398 | "authors": [
1399 | {
1400 | "name": "Sebastian Bergmann",
1401 | "email": "sebastian@phpunit.de"
1402 | }
1403 | ],
1404 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1405 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1406 | "support": {
1407 | "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
1408 | "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy",
1409 | "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1"
1410 | },
1411 | "funding": [
1412 | {
1413 | "url": "https://github.com/sebastianbergmann",
1414 | "type": "github"
1415 | }
1416 | ],
1417 | "time": "2024-07-03T05:00:13+00:00"
1418 | },
1419 | {
1420 | "name": "sebastian/object-reflector",
1421 | "version": "4.0.1",
1422 | "source": {
1423 | "type": "git",
1424 | "url": "https://github.com/sebastianbergmann/object-reflector.git",
1425 | "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9"
1426 | },
1427 | "dist": {
1428 | "type": "zip",
1429 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9",
1430 | "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9",
1431 | "shasum": ""
1432 | },
1433 | "require": {
1434 | "php": ">=8.2"
1435 | },
1436 | "require-dev": {
1437 | "phpunit/phpunit": "^11.0"
1438 | },
1439 | "type": "library",
1440 | "extra": {
1441 | "branch-alias": {
1442 | "dev-main": "4.0-dev"
1443 | }
1444 | },
1445 | "autoload": {
1446 | "classmap": [
1447 | "src/"
1448 | ]
1449 | },
1450 | "notification-url": "https://packagist.org/downloads/",
1451 | "license": [
1452 | "BSD-3-Clause"
1453 | ],
1454 | "authors": [
1455 | {
1456 | "name": "Sebastian Bergmann",
1457 | "email": "sebastian@phpunit.de"
1458 | }
1459 | ],
1460 | "description": "Allows reflection of object attributes, including inherited and non-public ones",
1461 | "homepage": "https://github.com/sebastianbergmann/object-reflector/",
1462 | "support": {
1463 | "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
1464 | "security": "https://github.com/sebastianbergmann/object-reflector/security/policy",
1465 | "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1"
1466 | },
1467 | "funding": [
1468 | {
1469 | "url": "https://github.com/sebastianbergmann",
1470 | "type": "github"
1471 | }
1472 | ],
1473 | "time": "2024-07-03T05:01:32+00:00"
1474 | },
1475 | {
1476 | "name": "sebastian/recursion-context",
1477 | "version": "6.0.2",
1478 | "source": {
1479 | "type": "git",
1480 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
1481 | "reference": "694d156164372abbd149a4b85ccda2e4670c0e16"
1482 | },
1483 | "dist": {
1484 | "type": "zip",
1485 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16",
1486 | "reference": "694d156164372abbd149a4b85ccda2e4670c0e16",
1487 | "shasum": ""
1488 | },
1489 | "require": {
1490 | "php": ">=8.2"
1491 | },
1492 | "require-dev": {
1493 | "phpunit/phpunit": "^11.0"
1494 | },
1495 | "type": "library",
1496 | "extra": {
1497 | "branch-alias": {
1498 | "dev-main": "6.0-dev"
1499 | }
1500 | },
1501 | "autoload": {
1502 | "classmap": [
1503 | "src/"
1504 | ]
1505 | },
1506 | "notification-url": "https://packagist.org/downloads/",
1507 | "license": [
1508 | "BSD-3-Clause"
1509 | ],
1510 | "authors": [
1511 | {
1512 | "name": "Sebastian Bergmann",
1513 | "email": "sebastian@phpunit.de"
1514 | },
1515 | {
1516 | "name": "Jeff Welch",
1517 | "email": "whatthejeff@gmail.com"
1518 | },
1519 | {
1520 | "name": "Adam Harvey",
1521 | "email": "aharvey@php.net"
1522 | }
1523 | ],
1524 | "description": "Provides functionality to recursively process PHP variables",
1525 | "homepage": "https://github.com/sebastianbergmann/recursion-context",
1526 | "support": {
1527 | "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
1528 | "security": "https://github.com/sebastianbergmann/recursion-context/security/policy",
1529 | "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2"
1530 | },
1531 | "funding": [
1532 | {
1533 | "url": "https://github.com/sebastianbergmann",
1534 | "type": "github"
1535 | }
1536 | ],
1537 | "time": "2024-07-03T05:10:34+00:00"
1538 | },
1539 | {
1540 | "name": "sebastian/type",
1541 | "version": "5.1.0",
1542 | "source": {
1543 | "type": "git",
1544 | "url": "https://github.com/sebastianbergmann/type.git",
1545 | "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac"
1546 | },
1547 | "dist": {
1548 | "type": "zip",
1549 | "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac",
1550 | "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac",
1551 | "shasum": ""
1552 | },
1553 | "require": {
1554 | "php": ">=8.2"
1555 | },
1556 | "require-dev": {
1557 | "phpunit/phpunit": "^11.3"
1558 | },
1559 | "type": "library",
1560 | "extra": {
1561 | "branch-alias": {
1562 | "dev-main": "5.1-dev"
1563 | }
1564 | },
1565 | "autoload": {
1566 | "classmap": [
1567 | "src/"
1568 | ]
1569 | },
1570 | "notification-url": "https://packagist.org/downloads/",
1571 | "license": [
1572 | "BSD-3-Clause"
1573 | ],
1574 | "authors": [
1575 | {
1576 | "name": "Sebastian Bergmann",
1577 | "email": "sebastian@phpunit.de",
1578 | "role": "lead"
1579 | }
1580 | ],
1581 | "description": "Collection of value objects that represent the types of the PHP type system",
1582 | "homepage": "https://github.com/sebastianbergmann/type",
1583 | "support": {
1584 | "issues": "https://github.com/sebastianbergmann/type/issues",
1585 | "security": "https://github.com/sebastianbergmann/type/security/policy",
1586 | "source": "https://github.com/sebastianbergmann/type/tree/5.1.0"
1587 | },
1588 | "funding": [
1589 | {
1590 | "url": "https://github.com/sebastianbergmann",
1591 | "type": "github"
1592 | }
1593 | ],
1594 | "time": "2024-09-17T13:12:04+00:00"
1595 | },
1596 | {
1597 | "name": "sebastian/version",
1598 | "version": "5.0.2",
1599 | "source": {
1600 | "type": "git",
1601 | "url": "https://github.com/sebastianbergmann/version.git",
1602 | "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874"
1603 | },
1604 | "dist": {
1605 | "type": "zip",
1606 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874",
1607 | "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874",
1608 | "shasum": ""
1609 | },
1610 | "require": {
1611 | "php": ">=8.2"
1612 | },
1613 | "type": "library",
1614 | "extra": {
1615 | "branch-alias": {
1616 | "dev-main": "5.0-dev"
1617 | }
1618 | },
1619 | "autoload": {
1620 | "classmap": [
1621 | "src/"
1622 | ]
1623 | },
1624 | "notification-url": "https://packagist.org/downloads/",
1625 | "license": [
1626 | "BSD-3-Clause"
1627 | ],
1628 | "authors": [
1629 | {
1630 | "name": "Sebastian Bergmann",
1631 | "email": "sebastian@phpunit.de",
1632 | "role": "lead"
1633 | }
1634 | ],
1635 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1636 | "homepage": "https://github.com/sebastianbergmann/version",
1637 | "support": {
1638 | "issues": "https://github.com/sebastianbergmann/version/issues",
1639 | "security": "https://github.com/sebastianbergmann/version/security/policy",
1640 | "source": "https://github.com/sebastianbergmann/version/tree/5.0.2"
1641 | },
1642 | "funding": [
1643 | {
1644 | "url": "https://github.com/sebastianbergmann",
1645 | "type": "github"
1646 | }
1647 | ],
1648 | "time": "2024-10-09T05:16:32+00:00"
1649 | },
1650 | {
1651 | "name": "squizlabs/php_codesniffer",
1652 | "version": "3.11.1",
1653 | "source": {
1654 | "type": "git",
1655 | "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
1656 | "reference": "19473c30efe4f7b3cd42522d0b2e6e7f243c6f87"
1657 | },
1658 | "dist": {
1659 | "type": "zip",
1660 | "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/19473c30efe4f7b3cd42522d0b2e6e7f243c6f87",
1661 | "reference": "19473c30efe4f7b3cd42522d0b2e6e7f243c6f87",
1662 | "shasum": ""
1663 | },
1664 | "require": {
1665 | "ext-simplexml": "*",
1666 | "ext-tokenizer": "*",
1667 | "ext-xmlwriter": "*",
1668 | "php": ">=5.4.0"
1669 | },
1670 | "require-dev": {
1671 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4"
1672 | },
1673 | "bin": [
1674 | "bin/phpcbf",
1675 | "bin/phpcs"
1676 | ],
1677 | "type": "library",
1678 | "extra": {
1679 | "branch-alias": {
1680 | "dev-master": "3.x-dev"
1681 | }
1682 | },
1683 | "notification-url": "https://packagist.org/downloads/",
1684 | "license": [
1685 | "BSD-3-Clause"
1686 | ],
1687 | "authors": [
1688 | {
1689 | "name": "Greg Sherwood",
1690 | "role": "Former lead"
1691 | },
1692 | {
1693 | "name": "Juliette Reinders Folmer",
1694 | "role": "Current lead"
1695 | },
1696 | {
1697 | "name": "Contributors",
1698 | "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors"
1699 | }
1700 | ],
1701 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
1702 | "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
1703 | "keywords": [
1704 | "phpcs",
1705 | "standards",
1706 | "static analysis"
1707 | ],
1708 | "support": {
1709 | "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues",
1710 | "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy",
1711 | "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer",
1712 | "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki"
1713 | },
1714 | "funding": [
1715 | {
1716 | "url": "https://github.com/PHPCSStandards",
1717 | "type": "github"
1718 | },
1719 | {
1720 | "url": "https://github.com/jrfnl",
1721 | "type": "github"
1722 | },
1723 | {
1724 | "url": "https://opencollective.com/php_codesniffer",
1725 | "type": "open_collective"
1726 | }
1727 | ],
1728 | "time": "2024-11-16T12:02:36+00:00"
1729 | },
1730 | {
1731 | "name": "theseer/tokenizer",
1732 | "version": "1.2.3",
1733 | "source": {
1734 | "type": "git",
1735 | "url": "https://github.com/theseer/tokenizer.git",
1736 | "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
1737 | },
1738 | "dist": {
1739 | "type": "zip",
1740 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
1741 | "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
1742 | "shasum": ""
1743 | },
1744 | "require": {
1745 | "ext-dom": "*",
1746 | "ext-tokenizer": "*",
1747 | "ext-xmlwriter": "*",
1748 | "php": "^7.2 || ^8.0"
1749 | },
1750 | "type": "library",
1751 | "autoload": {
1752 | "classmap": [
1753 | "src/"
1754 | ]
1755 | },
1756 | "notification-url": "https://packagist.org/downloads/",
1757 | "license": [
1758 | "BSD-3-Clause"
1759 | ],
1760 | "authors": [
1761 | {
1762 | "name": "Arne Blankerts",
1763 | "email": "arne@blankerts.de",
1764 | "role": "Developer"
1765 | }
1766 | ],
1767 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
1768 | "support": {
1769 | "issues": "https://github.com/theseer/tokenizer/issues",
1770 | "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
1771 | },
1772 | "funding": [
1773 | {
1774 | "url": "https://github.com/theseer",
1775 | "type": "github"
1776 | }
1777 | ],
1778 | "time": "2024-03-03T12:36:25+00:00"
1779 | }
1780 | ],
1781 | "aliases": [],
1782 | "minimum-stability": "stable",
1783 | "stability-flags": {},
1784 | "prefer-stable": false,
1785 | "prefer-lowest": false,
1786 | "platform": {
1787 | "php": ">=8.0"
1788 | },
1789 | "platform-dev": {},
1790 | "plugin-api-version": "2.6.0"
1791 | }
1792 |
--------------------------------------------------------------------------------
/demo/geocode.php:
--------------------------------------------------------------------------------
1 | geocode($query);
12 | print_r($result);
13 |
--------------------------------------------------------------------------------
/opencage_logo_300_150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenCageData/php-opencage-geocode/3e6f38a08d3f42476667689267fe7b1fceedb1dd/opencage_logo_300_150.png
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | opencage geocode standard
5 |
6 |
7 |
8 |
9 |
10 |
11 | ./vendor/
12 | ./tests/bootstrap.php
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 | ./tests/
18 | tests/bootstrap.php
19 |
20 |
21 |
22 |
23 | ./src/
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/AbstractGeocoder.php:
--------------------------------------------------------------------------------
1 | remember to match everything with the git tag
8 |
9 | const TIMEOUT = 10;
10 | const URL = 'https://api.opencagedata.com/geocode/v1/json/?';
11 | const PROXY = null;
12 |
13 | protected $key;
14 | protected $timeout;
15 | protected $url;
16 | protected $proxy;
17 | protected $user_agent;
18 |
19 | public function __construct($key = null)
20 | {
21 | if (isset($key) && !empty($key)) {
22 | $this->setKey($key);
23 | }
24 | $this->setTimeout(self::TIMEOUT);
25 | $this->user_agent = 'opencage-php/' . self::VERSION . ' (PHP ' . phpversion() . '; ' . php_uname('s') . ' ' . php_uname('r') . ')';
26 | }
27 |
28 | public function setKey($key)
29 | {
30 | $this->key = $key;
31 | }
32 |
33 | public function setTimeout($timeout)
34 | {
35 | $this->timeout = $timeout;
36 | }
37 |
38 | public function setProxy($proxy)
39 | {
40 | $this->proxy = $proxy;
41 | }
42 |
43 | protected function getJSON($query)
44 | {
45 | if (function_exists('curl_version') && !getenv('SKIP_CURL')) {
46 | $ret = $this->getJSONByCurl($query);
47 | return $ret;
48 | } elseif (ini_get('allow_url_fopen')) {
49 | $ret = $this->getJSONByFopen($query);
50 | return $ret;
51 | } else {
52 | throw new \Exception('PHP is not compiled with CURL support and allow_url_fopen is disabled; giving up');
53 | }
54 | }
55 |
56 | protected function getJSONByFopen($query)
57 | {
58 | $context = stream_context_create(
59 | [
60 | 'http' => [
61 | 'user_agent' => $this->user_agent,
62 | 'timeout' => $this->timeout
63 | ]
64 | ]
65 | );
66 |
67 | error_clear_last();
68 |
69 | $ret = @file_get_contents($query);
70 |
71 | if ($ret === false) {
72 | /** NOTE: https://github.com/phpstan/phpstan/issues/3213 */
73 | /** @phpstan-ignore-next-line */
74 | if (isset($http_response_header) && is_array($http_response_header)) {
75 | $error_message = $http_response_header[0];
76 | if ($error = error_get_last()) {
77 | $error_message = $error['message'];
78 | }
79 |
80 | // print "got an eror: $error\n";
81 | if (preg_match('/ 401 /', $error_message)) {
82 | // failed to open stream: HTTP request failed! HTTP/1.1 401 Unauthorized
83 | return $this->generateErrorJSON(401, 'invalid API key');
84 | } elseif (preg_match('/ 402 /', $error_message)) {
85 | // failed to open stream: HTTP request failed! HTTP/1.1 402 Payment Required
86 | return $this->generateErrorJSON(402, 'quota exceeded');
87 | }
88 | } else {
89 | // failed to open stream: php_network_getaddresses: getaddrinfo failed: No address associated with hostname
90 | return $this->generateErrorJSON(498, "network issue accessing $query");
91 | }
92 | }
93 |
94 | return $ret;
95 | }
96 |
97 | protected function generateErrorJSON($code, $message)
98 | {
99 | $response = [
100 | 'results' => [],
101 | 'total_results' => 0,
102 | 'status' => [
103 | 'code' => $code,
104 | 'message' => $message
105 | ]
106 | ];
107 | return json_encode($response);
108 | }
109 |
110 | protected function getJSONByCurl($query)
111 | {
112 | $ch = curl_init();
113 | $options = [
114 | CURLOPT_TIMEOUT => $this->timeout,
115 | CURLOPT_URL => $query,
116 | CURLOPT_RETURNTRANSFER => 1
117 | ];
118 | if ($this->proxy) {
119 | $options[CURLOPT_PROXY] = $this->proxy;
120 | }
121 | curl_setopt_array($ch, $options);
122 |
123 | $headers = [
124 | 'User-Agent: ' . $this->user_agent
125 | ];
126 |
127 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
128 |
129 | $ret = curl_exec($ch);
130 | if ($ret === false) {
131 | return $this->generateErrorJSON(498, 'network issue '.curl_error($ch));
132 | }
133 | return $ret;
134 | }
135 |
136 | abstract public function geocode($query);
137 | }
138 |
--------------------------------------------------------------------------------
/src/Geocoder.php:
--------------------------------------------------------------------------------
1 | $paramValue) {
27 | $url .= '&'.$param.'=' . urlencode($paramValue);
28 | }
29 | }
30 |
31 | if (empty($this->key)) {
32 | throw new \Exception('Missing API key');
33 | }
34 | $url .= '&key=' . $this->key;
35 |
36 | $ret = json_decode($this->getJSON($url), true);
37 | return $ret;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/GeocoderTest.php:
--------------------------------------------------------------------------------
1 | geocode('Johannesburg');
15 | } catch (\Exception $e) {
16 | $this->assertEquals('Missing API key', $e->getMessage());
17 | return;
18 | }
19 | $this->fail();
20 | }
21 |
22 | public function testInvalidKey()
23 | {
24 | $geocoder = new Geocoder('invalid-APIKEY');
25 | $result = $geocoder->geocode('Johannesburg');
26 | // print_r($result);
27 | $this->assertEquals(401, $result['status']['code']);
28 | $this->assertEquals('invalid API key', $result['status']['message']);
29 | }
30 |
31 | public function testNetworkRequestError()
32 | {
33 | // https://opencagedata.com/api#testingkeys
34 | $geocoder = new Geocoder('6d0e711d72d74daeb2b0bfd2a5cdfdba');
35 | $result = $geocoder->geocode('London', ['host' => 'doesnotexist.opencagedata.com']);
36 | // print_r($result);
37 |
38 | $this->assertEquals(498, $result['status']['code']);
39 | $this->assertStringContainsString('network issue', $result['status']['message']);
40 | $this->assertStringContainsString('doesnotexist.opencagedata.com', $result['status']['message']);
41 | }
42 |
43 | public function testOverQuota()
44 | {
45 | // https://opencagedata.com/api#testingkeys
46 | $geocoder = new Geocoder('4372eff77b8343cebfc843eb4da4ddc4');
47 | $result = $geocoder->geocode('Johannesburg');
48 | $this->assertEquals(402, $result['status']['code']);
49 | $this->assertEquals('quota exceeded', $result['status']['message']);
50 | }
51 |
52 | public function testLondon()
53 | {
54 | // https://opencagedata.com/api#testingkeys
55 | $geocoder = new Geocoder('6d0e711d72d74daeb2b0bfd2a5cdfdba');
56 | $query = "82 Clerkenwell Road, London";
57 | $result = $geocoder->geocode($query);
58 |
59 | // print_r($result);
60 |
61 | $this->assertEquals(200, $result['status']['code']);
62 | $this->assertEquals('OK', $result['status']['message']);
63 | }
64 |
65 | public function testProxy()
66 | {
67 | $proxy = getenv('PROXY');
68 | if (!$proxy) {
69 | $this->markTestSkipped('PROXY environment variable not set');
70 | }
71 | // https://opencagedata.com/api#testingkeys
72 | $geocoder = new Geocoder('6d0e711d72d74daeb2b0bfd2a5cdfdba');
73 | $geocoder->setProxy($proxy);
74 | $query = "82 Clerkenwell Road, London";
75 | $result = $geocoder->geocode($query);
76 |
77 | // print_r($result);
78 |
79 | $this->assertEquals(200, $result['status']['code']);
80 | $this->assertEquals('OK', $result['status']['message']);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 |