From b912085a58cfba9ba2bbb5bbecf28e0fe0c7341b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 17:43:22 +0000 Subject: [PATCH 01/10] Initial plan From d8895a0c1934a1f4189b23255bb7d87d2c8fad68 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 17:47:33 +0000 Subject: [PATCH 02/10] Initial exploration complete Co-authored-by: ozh <223647+ozh@users.noreply.github.com> --- .phpunit.result.cache | 1 + composer.json | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 .phpunit.result.cache diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 0000000..dfacdef --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +{"version":2,"defects":{"HttpBuildUrlTest::testTrailingSlash":8,"HttpBuildUrlTest::testJoinQuery":8,"HttpBuildUrlTest::testJoinPath":8,"HttpBuildUrlTest::testBitmasks":8},"times":{"HttpBuildUrlTest::testExampleOne":0,"HttpBuildUrlTest::testTrailingSlash":0.002,"HttpBuildUrlTest::testUrlQueryArrayIsIgnored":0,"HttpBuildUrlTest::testPartsQueryArrayIsIgnored":0,"HttpBuildUrlTest::testAcceptStrings":0,"HttpBuildUrlTest::testAcceptArrays":0,"HttpBuildUrlTest::testDefaults":0,"HttpBuildUrlTest::testNewUrl":0,"HttpBuildUrlTest::testJoinQuery":0,"HttpBuildUrlTest::testJoinPath":0,"HttpBuildUrlTest::testJoinPathTwo":0,"HttpBuildUrlTest::testBitmasks":0}} \ No newline at end of file diff --git a/composer.json b/composer.json index a5d83de..e06b667 100644 --- a/composer.json +++ b/composer.json @@ -14,5 +14,8 @@ }, "autoload": { "files": ["src/http_build_url.php"] + }, + "require-dev": { + "phpunit/phpunit": "^12.4" } } From 90518680ea8a5e78e1e20e377fe1833104936648 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 17:52:38 +0000 Subject: [PATCH 03/10] Migrate from Travis CI to GitHub Actions, update tests for PHP 5.6-8.4 Co-authored-by: ozh <223647+ozh@users.noreply.github.com> --- .github/workflows/test.yml | 53 ++++++++++++++++++++++++++++++++++++++ .gitignore | 3 ++- .phpunit.result.cache | 2 +- .travis.yml | 13 ---------- composer.json | 2 +- phpunit.xml.dist | 14 +++------- tests/HttpBuildUrlTest.php | 17 ++++++++---- tests/bootstrap.php | 18 ++++++++----- 8 files changed, 84 insertions(+), 38 deletions(-) create mode 100644 .github/workflows/test.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..2a3ac85 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,53 @@ +name: Tests + +on: + push: + branches: [ master, main ] + pull_request: + branches: [ master, main ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-version: + - '5.6' + - '7.0' + - '7.1' + - '7.2' + - '7.3' + - '7.4' + - '8.0' + - '8.1' + - '8.2' + - '8.3' + - '8.4' + + name: PHP ${{ matrix.php-version }} + + steps: + - uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + coverage: none + + - name: Install dependencies + run: | + if [ "${{ matrix.php-version }}" = "5.6" ] || [ "${{ matrix.php-version }}" = "7.0" ] || [ "${{ matrix.php-version }}" = "7.1" ]; then + composer require --dev phpunit/phpunit:^5.7 --no-interaction --no-update + elif [ "${{ matrix.php-version }}" = "7.2" ] || [ "${{ matrix.php-version }}" = "7.3" ] || [ "${{ matrix.php-version }}" = "7.4" ]; then + composer require --dev phpunit/phpunit:^8.5 --no-interaction --no-update + elif [ "${{ matrix.php-version }}" = "8.0" ] || [ "${{ matrix.php-version }}" = "8.1" ]; then + composer require --dev phpunit/phpunit:^9.5 --no-interaction --no-update + else + composer require --dev phpunit/phpunit:^10.0 --no-interaction --no-update + fi + composer install --no-interaction --prefer-dist + + - name: Run tests + run: vendor/bin/phpunit --coverage-text diff --git a/.gitignore b/.gitignore index 245ce84..ee08617 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ .idea build composer.lock -vendor \ No newline at end of file +vendor/ +.phpunit.cache diff --git a/.phpunit.result.cache b/.phpunit.result.cache index dfacdef..e1a59c5 100644 --- a/.phpunit.result.cache +++ b/.phpunit.result.cache @@ -1 +1 @@ -{"version":2,"defects":{"HttpBuildUrlTest::testTrailingSlash":8,"HttpBuildUrlTest::testJoinQuery":8,"HttpBuildUrlTest::testJoinPath":8,"HttpBuildUrlTest::testBitmasks":8},"times":{"HttpBuildUrlTest::testExampleOne":0,"HttpBuildUrlTest::testTrailingSlash":0.002,"HttpBuildUrlTest::testUrlQueryArrayIsIgnored":0,"HttpBuildUrlTest::testPartsQueryArrayIsIgnored":0,"HttpBuildUrlTest::testAcceptStrings":0,"HttpBuildUrlTest::testAcceptArrays":0,"HttpBuildUrlTest::testDefaults":0,"HttpBuildUrlTest::testNewUrl":0,"HttpBuildUrlTest::testJoinQuery":0,"HttpBuildUrlTest::testJoinPath":0,"HttpBuildUrlTest::testJoinPathTwo":0,"HttpBuildUrlTest::testBitmasks":0}} \ No newline at end of file +{"version":2,"defects":{"HttpBuildUrlTest::testTrailingSlash":8,"HttpBuildUrlTest::testJoinQuery":8,"HttpBuildUrlTest::testJoinPath":8,"HttpBuildUrlTest::testBitmasks":8},"times":{"HttpBuildUrlTest::testExampleOne":0.001,"HttpBuildUrlTest::testTrailingSlash":0.002,"HttpBuildUrlTest::testUrlQueryArrayIsIgnored":0,"HttpBuildUrlTest::testPartsQueryArrayIsIgnored":0,"HttpBuildUrlTest::testAcceptStrings":0,"HttpBuildUrlTest::testAcceptArrays":0,"HttpBuildUrlTest::testDefaults":0,"HttpBuildUrlTest::testNewUrl":0,"HttpBuildUrlTest::testJoinQuery":0,"HttpBuildUrlTest::testJoinPath":0,"HttpBuildUrlTest::testJoinPathTwo":0,"HttpBuildUrlTest::testBitmasks":0,"HttpBuildUrlTest::testTrailingSlash#0":0,"HttpBuildUrlTest::testTrailingSlash#1":0,"HttpBuildUrlTest::testTrailingSlash#2":0,"HttpBuildUrlTest::testTrailingSlash#3":0,"HttpBuildUrlTest::testTrailingSlash#4":0,"HttpBuildUrlTest::testTrailingSlash#5":0,"HttpBuildUrlTest::testJoinQuery#0":0,"HttpBuildUrlTest::testJoinQuery#1":0,"HttpBuildUrlTest::testJoinPath#0":0,"HttpBuildUrlTest::testJoinPath#1":0,"HttpBuildUrlTest::testJoinPath#2":0,"HttpBuildUrlTest::testBitmasks#0":0,"HttpBuildUrlTest::testBitmasks#1":0,"HttpBuildUrlTest::testBitmasks#2":0,"HttpBuildUrlTest::testBitmasks#3":0,"HttpBuildUrlTest::testBitmasks#4":0,"HttpBuildUrlTest::testBitmasks#5":0,"HttpBuildUrlTest::testBitmasks#6":0,"HttpBuildUrlTest::testBitmasks#7":0,"HttpBuildUrlTest::testBitmasks#8":0,"HttpBuildUrlTest::testBitmasks#9":0,"HttpBuildUrlTest::testBitmasks#10":0}} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index dea4bf1..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -sudo: false - -language: php -php: - - 5.3 - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - 7.1 - - hhvm - -script: phpunit --coverage-text diff --git a/composer.json b/composer.json index e06b667..639a06a 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,6 @@ "files": ["src/http_build_url.php"] }, "require-dev": { - "phpunit/phpunit": "^12.4" + "phpunit/phpunit": "^5.7 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0" } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 62dfd81..0804712 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,9 @@ - + - + ./tests @@ -10,12 +12,4 @@ ./src - - - - - \ No newline at end of file diff --git a/tests/HttpBuildUrlTest.php b/tests/HttpBuildUrlTest.php index 40a3f15..bd2fbfa 100644 --- a/tests/HttpBuildUrlTest.php +++ b/tests/HttpBuildUrlTest.php @@ -1,6 +1,13 @@ assertSame($expected, $actual); } - public function trailingSlashProvider() + public static function trailingSlashProvider() { return array( array( @@ -180,7 +187,7 @@ public function testBitmasks($constant, $expected) $this->assertSame($expected, $actual); } - public function pathProvider() + public static function pathProvider() { return array( array('/donuts/brownies', 'http://user:pass@www.example.com:8080/donuts/brownies?a=b#files'), @@ -189,7 +196,7 @@ public function pathProvider() ); } - public function queryProvider() + public static function queryProvider() { return array( array('a=c', 'http://user:pass@www.example.com:8080/pub/index.php?a=c#files'), @@ -197,7 +204,7 @@ public function queryProvider() ); } - public function bitmaskProvider() + public static function bitmaskProvider() { return array( array('HTTP_URL_REPLACE', 'http://user:pass@www.example.com:8080/pub/index.php?a=b#files'), diff --git a/tests/bootstrap.php b/tests/bootstrap.php index cf8b03e..827bb4a 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,13 +1,17 @@ =' ) ) { - class_alias( 'PHPUnit\Framework\Assert', 'PHPUnit_Framework_Assert' ); - class_alias( 'PHPUnit\Framework\TestCase', 'PHPUnit_Framework_TestCase' ); - class_alias( 'PHPUnit\Framework\Error\Error', 'PHPUnit_Framework_Error' ); - class_alias( 'PHPUnit\Framework\Error\Notice', 'PHPUnit_Framework_Error_Notice' ); - class_alias( 'PHPUnit\Framework\Error\Warning', 'PHPUnit_Framework_Error_Warning' ); +// PHPUnit 6+ uses namespaced classes, create aliases for older PHPUnit versions compatibility +if ( class_exists( 'PHPUnit\Runner\Version' ) ) { + // PHPUnit 6+ + if ( ! class_exists( 'PHPUnit_Framework_TestCase' ) ) { + class_alias( 'PHPUnit\Framework\TestCase', 'PHPUnit_Framework_TestCase' ); + } +} else { + // PHPUnit 4-5 - ensure forward compatibility classes exist + if ( ! class_exists( 'PHPUnit\Framework\TestCase' ) && class_exists( 'PHPUnit_Framework_TestCase' ) ) { + class_alias( 'PHPUnit_Framework_TestCase', 'PHPUnit\Framework\TestCase' ); + } } // Past this point, tests will start From 19d1a5cb70434cb91405694fd0c96483d03b6041 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 17:53:56 +0000 Subject: [PATCH 04/10] Remove coverage flag from workflow (requires xdebug) Co-authored-by: ozh <223647+ozh@users.noreply.github.com> --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a3ac85..3408156 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -50,4 +50,4 @@ jobs: composer install --no-interaction --prefer-dist - name: Run tests - run: vendor/bin/phpunit --coverage-text + run: vendor/bin/phpunit From f7401fb4719ea5bf90df569d334983a37c2d64a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 8 Nov 2025 17:55:19 +0000 Subject: [PATCH 05/10] Add explicit permissions to GitHub Actions workflow Co-authored-by: ozh <223647+ozh@users.noreply.github.com> --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3408156..b55bf15 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,6 +9,8 @@ on: jobs: test: runs-on: ubuntu-latest + permissions: + contents: read strategy: fail-fast: false matrix: From bd9cf786b742a46ae49f5237caa33a4479c7beff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=BE=85=E0=BC=BB=20=C7=AC=C9=80=C4=A7=20=E0=BC=84?= =?UTF-8?q?=E0=BC=86=E0=BD=89?= Date: Sun, 9 Nov 2025 00:22:13 +0100 Subject: [PATCH 06/10] Add .phpunit.result.cache to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ee08617..b9220cd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ build composer.lock vendor/ .phpunit.cache +.phpunit.result.cache From 4575bdab376c4c9c1e0c24a5e35dcc0537ba9b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=BE=85=E0=BC=BB=20=C7=AC=C9=80=C4=A7=20=E0=BC=84?= =?UTF-8?q?=E0=BC=86=E0=BD=89?= Date: Sun, 9 Nov 2025 00:23:36 +0100 Subject: [PATCH 07/10] Delete .phpunit.result.cache --- .phpunit.result.cache | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .phpunit.result.cache diff --git a/.phpunit.result.cache b/.phpunit.result.cache deleted file mode 100644 index e1a59c5..0000000 --- a/.phpunit.result.cache +++ /dev/null @@ -1 +0,0 @@ -{"version":2,"defects":{"HttpBuildUrlTest::testTrailingSlash":8,"HttpBuildUrlTest::testJoinQuery":8,"HttpBuildUrlTest::testJoinPath":8,"HttpBuildUrlTest::testBitmasks":8},"times":{"HttpBuildUrlTest::testExampleOne":0.001,"HttpBuildUrlTest::testTrailingSlash":0.002,"HttpBuildUrlTest::testUrlQueryArrayIsIgnored":0,"HttpBuildUrlTest::testPartsQueryArrayIsIgnored":0,"HttpBuildUrlTest::testAcceptStrings":0,"HttpBuildUrlTest::testAcceptArrays":0,"HttpBuildUrlTest::testDefaults":0,"HttpBuildUrlTest::testNewUrl":0,"HttpBuildUrlTest::testJoinQuery":0,"HttpBuildUrlTest::testJoinPath":0,"HttpBuildUrlTest::testJoinPathTwo":0,"HttpBuildUrlTest::testBitmasks":0,"HttpBuildUrlTest::testTrailingSlash#0":0,"HttpBuildUrlTest::testTrailingSlash#1":0,"HttpBuildUrlTest::testTrailingSlash#2":0,"HttpBuildUrlTest::testTrailingSlash#3":0,"HttpBuildUrlTest::testTrailingSlash#4":0,"HttpBuildUrlTest::testTrailingSlash#5":0,"HttpBuildUrlTest::testJoinQuery#0":0,"HttpBuildUrlTest::testJoinQuery#1":0,"HttpBuildUrlTest::testJoinPath#0":0,"HttpBuildUrlTest::testJoinPath#1":0,"HttpBuildUrlTest::testJoinPath#2":0,"HttpBuildUrlTest::testBitmasks#0":0,"HttpBuildUrlTest::testBitmasks#1":0,"HttpBuildUrlTest::testBitmasks#2":0,"HttpBuildUrlTest::testBitmasks#3":0,"HttpBuildUrlTest::testBitmasks#4":0,"HttpBuildUrlTest::testBitmasks#5":0,"HttpBuildUrlTest::testBitmasks#6":0,"HttpBuildUrlTest::testBitmasks#7":0,"HttpBuildUrlTest::testBitmasks#8":0,"HttpBuildUrlTest::testBitmasks#9":0,"HttpBuildUrlTest::testBitmasks#10":0}} \ No newline at end of file From c396476cb675c4804c173a6cef7ca4f8a7316681 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 9 Nov 2025 08:29:28 +0000 Subject: [PATCH 08/10] Initial plan From bcc4681ae1245128ecb819aa2b0b712bf4213c12 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 9 Nov 2025 08:36:25 +0000 Subject: [PATCH 09/10] Update README with GitHub Actions badge and comprehensive usage examples Co-authored-by: ozh <223647+ozh@users.noreply.github.com> --- readme.md | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index cdf10f4..33a4ae4 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # http_build_url() for PHP -[![Build Status](https://travis-ci.org/jakeasmith/http_build_url.png)](https://travis-ci.org/jakeasmith/http_build_url) +[![Tests](https://github.com/ozh/http_build_url/actions/workflows/test.yml/badge.svg)](https://github.com/ozh/http_build_url/actions/workflows/test.yml) [![Code Climate](https://codeclimate.com/github/jakeasmith/http_build_url/badges/gpa.svg)](https://codeclimate.com/github/jakeasmith/http_build_url) [![Latest Stable Version](https://poser.pugx.org/jakeasmith/http_build_url/v/stable.png)](https://packagist.org/packages/jakeasmith/http_build_url) [![Total Downloads](https://poser.pugx.org/jakeasmith/http_build_url/downloads.png)](https://packagist.org/packages/jakeasmith/http_build_url) @@ -15,6 +15,136 @@ The easiest way to install this library is to use [Composer](https://getcomposer $ composer require jakeasmith/http_build_url ^1 ``` +## Usage + +The `http_build_url()` function builds a URL from an array of parts or merges two URLs together according to specified flags. + +### Basic Examples + +#### Building a URL from parts + +```php + 'https', + 'host' => 'www.example.com', + 'path' => '/path/to/page', + 'query' => 'foo=bar' +]); + +echo $url; // https://www.example.com/path/to/page?foo=bar +``` + +#### Merging URL parts + +```php + 'https', + 'host' => 'secure.example.com', + 'path' => '/new/path.php' +]); + +echo $new_url; // https://user:pass@secure.example.com:8080/new/path.php?a=b#files +``` + +### Advanced Examples with Flags + +The function accepts various flags to control how URLs are merged and manipulated: + +#### Joining paths + +```php + 'baz/qux'], + HTTP_URL_JOIN_PATH +); + +echo $url; // http://example.com/foo/bar/baz/qux +``` + +#### Joining query strings + +```php + 'foo=new&extra=param'], + HTTP_URL_JOIN_QUERY +); + +echo $url; // http://example.com/page?foo=new&old=value&extra=param +``` + +#### Stripping URL components + +```php + 'ftp', + 'host' => 'ftp.example.com', + 'path' => 'files/current/', + 'query' => 'a=c' + ], + HTTP_URL_STRIP_AUTH | HTTP_URL_JOIN_PATH | HTTP_URL_JOIN_QUERY | HTTP_URL_STRIP_FRAGMENT +); + +echo $url; // ftp://ftp.example.com/pub/files/current/?a=c +``` + +### Available Flags + +- `HTTP_URL_REPLACE` (default) - Replace parts of the first URL with parts from the second +- `HTTP_URL_JOIN_PATH` - Join relative paths instead of replacing +- `HTTP_URL_JOIN_QUERY` - Merge query parameters instead of replacing +- `HTTP_URL_STRIP_USER` - Remove username from URL +- `HTTP_URL_STRIP_PASS` - Remove password from URL +- `HTTP_URL_STRIP_AUTH` - Remove both username and password +- `HTTP_URL_STRIP_PORT` - Remove port from URL +- `HTTP_URL_STRIP_PATH` - Remove path from URL +- `HTTP_URL_STRIP_QUERY` - Remove query string from URL +- `HTTP_URL_STRIP_FRAGMENT` - Remove fragment (hash) from URL +- `HTTP_URL_STRIP_ALL` - Remove all components except scheme and host + +Flags can be combined using the bitwise OR operator (`|`). + ## License This project is licensed under the MIT License - see the LICENSE file for details. From 94acd2624e46dbb2660d898c0d5bce5a5b643703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=BE=85=E0=BC=BB=20=C7=AC=C9=80=C4=A7=20=E0=BC=84?= =?UTF-8?q?=E0=BC=86=E0=BD=89?= Date: Sun, 9 Nov 2025 10:11:54 +0100 Subject: [PATCH 10/10] Update GitHub Actions badge link in README --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 33a4ae4..bd089cf 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ # http_build_url() for PHP -[![Tests](https://github.com/ozh/http_build_url/actions/workflows/test.yml/badge.svg)](https://github.com/ozh/http_build_url/actions/workflows/test.yml) +[![Tests](https://github.com/jakeasmith/http_build_url/actions/workflows/test.yml/badge.svg)](https://github.com/ozh/http_build_url/actions/workflows/test.yml) [![Code Climate](https://codeclimate.com/github/jakeasmith/http_build_url/badges/gpa.svg)](https://codeclimate.com/github/jakeasmith/http_build_url) [![Latest Stable Version](https://poser.pugx.org/jakeasmith/http_build_url/v/stable.png)](https://packagist.org/packages/jakeasmith/http_build_url) [![Total Downloads](https://poser.pugx.org/jakeasmith/http_build_url/downloads.png)](https://packagist.org/packages/jakeasmith/http_build_url)