diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 36dbb9c..385ddf9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,6 +33,20 @@ Combinations of these tools can be built into the `RoboFile.php`, e.g. spinning ## Release Process +### Automated +1. Merge all production-ready code into `main`. +2. Run `composer release:pre`. This will prompt for the release number, bump all the versions to that version, and push a new `release-major.minor.patch` version branch. +3. Create a PR against the `build` branch. +4. After all tests and code reviews pass (including resolving any merge conflicts) and automation makes the commit containing the build files, merge the PR into `build`. +5. Navigate to the [Releases](https://github.com/pantheon-systems/pantheon-wordpress-edge-integrations/releases) page and click the "Draft a New Release" button. +7. Under "Choose a Tag", enter the release version (`major.minor.patch`) and select "Create a new tag: `major.minor.patch` on publish". +8. Set the target branch to `build`. +9. Enter the version number as the release title. +10. Click the "Auto-generate release notes" button to add the changelog to the release. +11. Publish the release! +12. Run `composer release:post`. This will prompt for the current stable release and the next version number and bump the readme to the current stable, and all other versions to the next version. This is intended to be pushed to `main` after the release is published. + +### Manual 1. Merge all production-ready code into `main`. 2. On your local machine, checkout `main` and pull the latest. 3. Checkout a new release branch: `git checkout -b release-major.minor.patch` and bump the version number in [pantheon-wordpress-edge-integrations.php](https://github.com/pantheon-systems/pantheon-wordpress-edge-integrations/blob/main/pantheon-wordpress-edge-integrations.php#L7), and [package.json](https://github.com/pantheon-systems/pantheon-wordpress-edge-integrations/blob/main/package.json#L3) diff --git a/composer.json b/composer.json index c85a114..b459ea8 100644 --- a/composer.json +++ b/composer.json @@ -6,22 +6,22 @@ "minimum-stability": "dev", "prefer-stable": true, "repositories": [ - { - "type": "composer", - "url": "https://packagist.org" - }, { "type": "path", "url": "packages/*", "symlink": true }, + { + "type": "composer", + "url": "https://packagist.org" + }, { "type": "git", "url": "https://github.com/wordpress/wordpress-develop.git" } ], "require": { - "pantheon-systems/pantheon-edge-integrations": "^v1.0" + "pantheon-systems/pantheon-edge-integrations": "^v1.1.0-alpha1" }, "require-dev": { "consolidation/robo": "^3.0", @@ -40,14 +40,15 @@ ] }, "scripts": { - "bump:patch": "npm run bump:patch", - "bump:minor": "npm run bump:minor", - "bump:major": "npm run bump:major", + "release:pre": "bash scripts/pre-release", + "release:post": "bash scripts/post-release", "lint:php": "find ./pantheon-wordpress-edge-integrations.php ./inc ./tests -name '*.php' -exec php -l {} \\;", "lint:phpcs": "vendor/bin/phpcs -s --standard=phpcs.ruleset.xml .", "lint:phpcbf": "vendor/bin/phpcbf -s --standard=phpcs.ruleset.xml .", "lint": "composer lint:php && composer lint:phpcs", "test:unit": "vendor/bin/phpunit -c phpunit.xml", + "test:geo": "vendor/bin/phpunit -c phpunit.xml --group wp-geo", + "test:interest": "vendor/bin/phpunit -c phpunit.xml --group wp-interest", "test": "composer test:unit" }, "config": { diff --git a/composer.lock b/composer.lock index 10b541d..3492343 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ab09a1cb9d1f507bd3bd9f56f10706e3", + "content-hash": "a0e61fa9c3d547fdfa6e9c657d826f45", "packages": [ { "name": "pantheon-systems/pantheon-edge-integrations", - "version": "1.0.1", + "version": "v1.1.0-alpha1", "source": { "type": "git", "url": "https://github.com/pantheon-systems/pantheon-edge-integrations.git", - "reference": "4a6447a6d009ca8f6410390f4f0971ee7cd0de19" + "reference": "529b95b0759efe3dc80532d005ccc87a7c41abd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pantheon-systems/pantheon-edge-integrations/zipball/4a6447a6d009ca8f6410390f4f0971ee7cd0de19", - "reference": "4a6447a6d009ca8f6410390f4f0971ee7cd0de19", + "url": "https://api.github.com/repos/pantheon-systems/pantheon-edge-integrations/zipball/529b95b0759efe3dc80532d005ccc87a7c41abd1", + "reference": "529b95b0759efe3dc80532d005ccc87a7c41abd1", "shasum": "" }, "require-dev": { @@ -40,9 +40,9 @@ "description": "Helper class for content personalization.", "support": { "issues": "https://github.com/pantheon-systems/pantheon-edge-integrations/issues", - "source": "https://github.com/pantheon-systems/pantheon-edge-integrations/tree/1.0.1" + "source": "https://github.com/pantheon-systems/pantheon-edge-integrations/tree/v1.1.0-alpha1" }, - "time": "2022-02-24T17:14:59+00:00" + "time": "2022-06-01T21:29:18+00:00" } ], "packages-dev": [ @@ -180,16 +180,16 @@ }, { "name": "consolidation/annotated-command", - "version": "4.5.4", + "version": "4.5.5", "source": { "type": "git", "url": "https://github.com/consolidation/annotated-command.git", - "reference": "93398c3166d9026ab93219ce23b2092b4d7b7904" + "reference": "67cea8e8e7656b74da651ea6f49321853996c0fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/93398c3166d9026ab93219ce23b2092b4d7b7904", - "reference": "93398c3166d9026ab93219ce23b2092b4d7b7904", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/67cea8e8e7656b74da651ea6f49321853996c0fd", + "reference": "67cea8e8e7656b74da651ea6f49321853996c0fd", "shasum": "" }, "require": { @@ -230,9 +230,9 @@ "description": "Initialize Symfony Console commands from annotated command class methods.", "support": { "issues": "https://github.com/consolidation/annotated-command/issues", - "source": "https://github.com/consolidation/annotated-command/tree/4.5.4" + "source": "https://github.com/consolidation/annotated-command/tree/4.5.5" }, - "time": "2022-04-05T17:58:10+00:00" + "time": "2022-04-26T16:18:25+00:00" }, { "name": "consolidation/config", @@ -831,26 +831,25 @@ }, { "name": "grasmash/expander", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/grasmash/expander.git", - "reference": "f4df21d01d1fbda38269cca89e3dbb6ba223da7f" + "reference": "b7cbc1f2fdf9a9c0e253a424c2a4058316b7cb6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/grasmash/expander/zipball/f4df21d01d1fbda38269cca89e3dbb6ba223da7f", - "reference": "f4df21d01d1fbda38269cca89e3dbb6ba223da7f", + "url": "https://api.github.com/repos/grasmash/expander/zipball/b7cbc1f2fdf9a9c0e253a424c2a4058316b7cb6e", + "reference": "b7cbc1f2fdf9a9c0e253a424c2a4058316b7cb6e", "shasum": "" }, "require": { "dflydev/dot-access-data": "^3.0.0", - "php": ">=5.6", - "psr/log": "^1 | ^2" + "php": ">=7.1", + "psr/log": "^1 | ^2 | ^3" }, "require-dev": { "greg-1-anderson/composer-test-scenarios": "^1", - "php-coveralls/php-coveralls": "^2.0", "phpunit/phpunit": "^6.0 || ^8.0 || ^9", "squizlabs/php_codesniffer": "^2.7 || ^3.3" }, @@ -877,9 +876,9 @@ "description": "Expands internal property references in PHP arrays file.", "support": { "issues": "https://github.com/grasmash/expander/issues", - "source": "https://github.com/grasmash/expander/tree/2.0.2" + "source": "https://github.com/grasmash/expander/tree/2.0.3" }, - "time": "2022-02-24T03:58:20+00:00" + "time": "2022-04-25T22:17:46+00:00" }, { "name": "humanmade/coding-standards", @@ -1062,16 +1061,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.2", + "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", "shasum": "" }, "require": { @@ -1112,9 +1111,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" }, - "time": "2021-11-30T19:35:32+00:00" + "time": "2022-05-31T20:59:12+00:00" }, { "name": "phar-io/manifest", @@ -3222,16 +3221,16 @@ }, { "name": "symfony/console", - "version": "v6.0.7", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e" + "reference": "9b190bc7a19d19add1dbb3382721973836e59b50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", - "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", + "url": "https://api.github.com/repos/symfony/console/zipball/9b190bc7a19d19add1dbb3382721973836e59b50", + "reference": "9b190bc7a19d19add1dbb3382721973836e59b50", "shasum": "" }, "require": { @@ -3297,7 +3296,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.0.7" + "source": "https://github.com/symfony/console/tree/v6.0.9" }, "funding": [ { @@ -3313,20 +3312,20 @@ "type": "tidelift" } ], - "time": "2022-03-31T17:18:25+00:00" + "time": "2022-05-27T06:40:13+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.0.3", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934" + "reference": "5c85b58422865d42c6eb46f7693339056db098a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6472ea2dd415e925b90ca82be64b8bc6157f3934", - "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/5c85b58422865d42c6eb46f7693339056db098a8", + "reference": "5c85b58422865d42c6eb46f7693339056db098a8", "shasum": "" }, "require": { @@ -3380,7 +3379,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.9" }, "funding": [ { @@ -3396,7 +3395,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-05-05T16:45:52+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -3479,16 +3478,16 @@ }, { "name": "symfony/filesystem", - "version": "v6.0.7", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff" + "reference": "bf7b9d2ee692b6df2a41017d6023a2fe732d240c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", - "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/bf7b9d2ee692b6df2a41017d6023a2fe732d240c", + "reference": "bf7b9d2ee692b6df2a41017d6023a2fe732d240c", "shasum": "" }, "require": { @@ -3522,7 +3521,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.0.7" + "source": "https://github.com/symfony/filesystem/tree/v6.0.9" }, "funding": [ { @@ -3538,20 +3537,20 @@ "type": "tidelift" } ], - "time": "2022-04-01T12:54:51+00:00" + "time": "2022-05-21T13:33:31+00:00" }, { "name": "symfony/finder", - "version": "v6.0.3", + "version": "v6.0.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430" + "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8661b74dbabc23223f38c9b99d3f8ade71170430", - "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430", + "url": "https://api.github.com/repos/symfony/finder/zipball/af7edab28d17caecd1f40a9219fc646ae751c21f", + "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f", "shasum": "" }, "require": { @@ -3583,7 +3582,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.0.3" + "source": "https://github.com/symfony/finder/tree/v6.0.8" }, "funding": [ { @@ -3599,20 +3598,20 @@ "type": "tidelift" } ], - "time": "2022-01-26T17:23:29+00:00" + "time": "2022-04-15T08:07:58+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", "shasum": "" }, "require": { @@ -3627,7 +3626,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3665,7 +3664,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" }, "funding": [ { @@ -3681,20 +3680,20 @@ "type": "tidelift" } ], - "time": "2021-10-20T20:35:02+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + "reference": "433d05519ce6990bf3530fba6957499d327395c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference": "433d05519ce6990bf3530fba6957499d327395c2", "shasum": "" }, "require": { @@ -3706,7 +3705,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3746,7 +3745,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" }, "funding": [ { @@ -3762,20 +3761,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T21:10:46+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "219aa369ceff116e673852dce47c3a41794c14bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd", "shasum": "" }, "require": { @@ -3787,7 +3786,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3830,7 +3829,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" }, "funding": [ { @@ -3846,20 +3845,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", "shasum": "" }, "require": { @@ -3874,7 +3873,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3913,7 +3912,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" }, "funding": [ { @@ -3929,20 +3928,20 @@ "type": "tidelift" } ], - "time": "2021-11-30T18:21:41+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/process", - "version": "v6.0.7", + "version": "v6.0.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4" + "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/e13f6757e267d687e20ec5b26ccfcbbe511cd8f4", - "reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4", + "url": "https://api.github.com/repos/symfony/process/zipball/d074154ea8b1443a96391f6e39f9e547b2dd01b9", + "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9", "shasum": "" }, "require": { @@ -3974,7 +3973,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.0.7" + "source": "https://github.com/symfony/process/tree/v6.0.8" }, "funding": [ { @@ -3990,7 +3989,7 @@ "type": "tidelift" } ], - "time": "2022-03-18T16:21:55+00:00" + "time": "2022-04-12T16:11:42+00:00" }, { "name": "symfony/service-contracts", @@ -4076,16 +4075,16 @@ }, { "name": "symfony/string", - "version": "v6.0.3", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2" + "reference": "df9f03d595aa2d446498ba92fe803a519b2c43cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2", - "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2", + "url": "https://api.github.com/repos/symfony/string/zipball/df9f03d595aa2d446498ba92fe803a519b2c43cc", + "reference": "df9f03d595aa2d446498ba92fe803a519b2c43cc", "shasum": "" }, "require": { @@ -4141,7 +4140,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.0.3" + "source": "https://github.com/symfony/string/tree/v6.0.9" }, "funding": [ { @@ -4157,7 +4156,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-04-22T08:18:02+00:00" }, { "name": "symfony/yaml", diff --git a/inc/geo.php b/inc/geo.php index 79ec1f0..f1aa6b9 100644 --- a/inc/geo.php +++ b/inc/geo.php @@ -12,77 +12,64 @@ /** * Return geolocation data for the current user. * - * @param string $data_type The type of geo data to return. Allowed values: 'country', 'region', 'city', 'continent', 'conn-speed', 'conn-type' or an empty string. All other values will return an empty string. Defaults to ''. + * @param string $data_type The type of geo data to return. Allowed values: 'country-code', 'country-name', 'region', 'city', 'continent-code', 'conn-speed', 'conn-type' or an empty string. All other values will return an empty string. Defaults to ''. * * If an empty string is passed, get_geo() will return all Audience data encoded in JSON format. * * @param mixed $data Data to pass to the HeaderData class. By default, this is pulled from $_SERVER data. * - * @param string $header The header to use for geolocation data. Defaults to 'Audience-Set'. - * * @return string The requested geo data. */ -function get_geo( string $data_type = '', $data = null, string $header = 'Audience-Set' ) : string { +function get_geo( string $data_type = '', $data = null ) : string { + // Backwards compatibility for old data types. + $data_type = $data_type === 'country' ? 'country-code' : $data_type; + $data_type = $data_type === 'continent' ? 'continent-code' : $data_type; + // If the passed data type is not allowed, return an empty string. + $data_type = strtolower( $data_type ); if ( ! in_array( $data_type, get_geo_allowed_values(), true ) ) { return ''; } - /** - * Filter the header to use for geolocation. - * - * @param array $allowed_geo_headers Array of allowed geo headers. Defaults to ['Audience-Set', 'Audience']. - */ - $allowed_geo_headers = apply_filters( 'pantheon.ei.allowed_geo_headers', [ 'Audience-Set', 'Audience' ] ); - - // Make sure the header we're pulling from is an allowed geo header. - if ( ! in_array( $header, $allowed_geo_headers, true ) ) { + // Set the header and make sure it is a valid header. + $header = 'P13n-Geo-' . ucwords( $data_type, '-' ); + if ( ! empty( $data_type ) && ! in_array( $header, get_geo_allowed_headers(), true ) ) { return ''; } - /** - * Get the geo data from the HeaderData class and allow it to be filtered. - * - * For filtering purposes, the data passed is an array of key/value pairs of geo data. Because this filter fires after the data types are checked, it's possible (but not recommended) to provide data that would otherwise be filtered out. - * - * @hook pantheon.ei.geo_data - * @param array The full, parsed Audience geo data as an array. - */ - $parsed_geo = apply_filters( 'pantheon.ei.parsed_geo_data', EI\HeaderData::parse( $header, $data ) ); - // If no geo data type was passed, return all Audience data. + // If no geo data type was passed, return all geo data. if ( empty( $data_type ) ) { - return ! empty( $parsed_geo ) ? json_encode( $parsed_geo ) : ''; - } + $geo_data = EI\HeaderData::personalizationObject( $data ); + $all_geo = []; - // If no data exists for the data type, return an empty string. - if ( ! isset( $parsed_geo[ $data_type ] ) ) { - return ''; - } + // Loop through the geo headers and load up the all geo data with data from the personalization object. + foreach ( get_geo_allowed_headers() as $header ) { + $key = strtolower( str_replace( 'P13n-Geo-', '', $header ) ); + $all_geo[ $key ] = isset( $geo_data[ $header ] ) ? $geo_data[ $header ] : ''; + } - // If 'latlon' was requested, return the latitude and longitude. - if ( $data_type === 'latlon' ) { - $parsed_geo['latlon'] = $parsed_geo['lat'] . ',' . $parsed_geo['lon']; - } + /** + * Allow developers to filter the data that is returned when no data type is passed. + * + * Normally, if no data type is passed, all geo data is fetched and returned. This filter allows the developer to specify the data that comes back. + * + * This gets passed through json_encode before being returned. + * + * @hook pantheon.ei.get_all_geo + * @param array $data The full, parsed geo data as an array. + */ + $all_geo = apply_filters( 'pantheon.ei.get_all_geo', $all_geo ); - /** - * Fires after the geo data is retrieved but before it is returned. - * - * Allows developers to hook into the geo data retrieval process and access the geo value and the type of data requested and the full passed data, if it exists. - * - * @hook pantheon.ei.get_geo - * @param string The geo data value. - * @param string The type of geo data requested. - * @param mixed Data passed to the HeaderData class. By default, this is pulled from $_SERVER data. - */ - do_action( 'pantheon.ei.before_get_geo', $parsed_geo[ $data_type ], $data_type, $data ); + return json_encode( $all_geo ); + } /** * Allow developers to modify the requested geo data. This filter fires after the data is parsed and before it is returned making this the last stop before data is output. * - * @hook pantheon.ei.geo_data - * @param string The requested geo data. + * @hook pantheon.ei.get_geo_{$data_type} + * @param array The requested geo header data. */ - return apply_filters( 'pantheon.ei.get_geo', $parsed_geo[ $data_type ] ); + return apply_filters( "pantheon.ei.get_geo_$data_type", EI\HeaderData::parse( $header, $data ) ); } /** @@ -97,5 +84,40 @@ function get_geo_allowed_values() : array { * @hook pantheon.ei.geo_data_types * @param array The allowed geo data types. */ - return apply_filters( 'pantheon.ei.geo_allowed_values', [ '', 'country', 'region', 'city', 'continent', 'conn-speed', 'conn-type', 'lat', 'lon', 'latlon' ] ); + return apply_filters( 'pantheon.ei.geo_allowed_values', [ + '', + 'country-code', + 'country-name', + 'city', + 'region', + 'continent-code', + 'conn-speed', + 'conn-type', + ] ); +} + +/** + * Returns the array of allowed headers. + * + * @return array + */ +function get_geo_allowed_headers() : array { + $values = get_geo_allowed_values(); + $headers = []; + + foreach ( $values as $value ) { + if ( empty( $value ) ) { + continue; + } + + $headers[] = ucwords( "p13n-geo-$value", '-' ); + } + + /** + * Allow developers to modify the allowed geo headers. + * + * @hook pantheon.ei.geo_headers + * @param array The allowed geo headers. + */ + return apply_filters( 'pantheon.ei.geo_allowed_headers', $headers ); } diff --git a/inc/interest.php b/inc/interest.php index 6309462..c2b40f2 100644 --- a/inc/interest.php +++ b/inc/interest.php @@ -22,6 +22,22 @@ function bootstrap() { add_action( 'pantheon.ei.after_enqueue_script', $n( 'localize_script' ) ); } +/** + * Return the Interest header key. + * + * @return string The Interest header key. + */ +function get_interest_header_key() : string { + /** + * Allow the Interest header key to be customized. + * + * @hook pantheon.ei.interest_header_key + * + * @param string $key The Interest header key. + */ + return apply_filters( 'pantheon.ei.interest_header_key', 'P13n-Interest' ); +} + /** * Pass interest data to the script. * @@ -59,7 +75,7 @@ function localize_script() { * @return void */ function set_interest_header() { - $cookie_key = 'interest'; + $cookie_key = get_interest_header_key(); if ( ! array_key_exists( $cookie_key, $_COOKIE ) ) { return; } @@ -69,7 +85,9 @@ function set_interest_header() { return; } - set_interest( [ 'HTTP_INTEREST' => $interest ] ); + // Get the Interest header key. Allows the Interest header key to be customized. + $http_interest = strtoupper( 'HTTP_' . str_replace( '-', '_', get_interest_header_key() ) ); + set_interest( [ $http_interest => $interest ] ); } /** @@ -86,7 +104,7 @@ function set_interest( array $data = null ) : array { * @hook pantheon.ei.applied_interest_data * @param array The full, parsed Interest data as an array. */ - $applied_interest = apply_filters( 'pantheon.ei.applied_interest_data', EI\HeaderData::parse( 'Interest', $data ) ); + $applied_interest = apply_filters( 'pantheon.ei.applied_interest_data', EI\HeaderData::parse( get_interest_header_key(), $data ) ); return $applied_interest; } @@ -102,8 +120,7 @@ function get_interest() : array { * * @hook pantheon.ei.parsed_interest_data */ - $parsed_interest = apply_filters( 'pantheon.ei.parsed_interest_data', EI\HeaderData::parse( 'Interest' ) ); - + $parsed_interest = apply_filters( 'pantheon.ei.parsed_interest_data', EI\HeaderData::parse( get_interest_header_key() ) ); return $parsed_interest; } diff --git a/inc/namespace.php b/inc/namespace.php index 80f81a0..1831abd 100644 --- a/inc/namespace.php +++ b/inc/namespace.php @@ -118,9 +118,14 @@ function get_supported_vary_headers() : array { * @param array $defaults Array of vary headers supported by the plugin. */ $defaults = apply_filters( 'pantheon.ei.supported_vary_headers', [ - 'Audience-Set' => true, - 'Audience' => false, - 'Interest' => true, + 'P13n-Geo-Country-Code' => true, + 'P13n-Geo-Country-Name' => false, + 'P13n-Geo-Region' => false, + 'P13n-Geo-City' => false, + 'P13n-Geo-Continent-Code' => false, + 'P13n-Geo-Conn-Type' => false, + 'P13n-Geo-Conn-Speed' => false, + 'P13n-Interest' => true, ] ); // Omit headers that are not supported. diff --git a/package-lock.json b/package-lock.json index 6ecf600..0e070e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "pantheon-wordpress-edge-integrations", - "version": "0.2.16", + "version": "0.2.17", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3d430e7..41d70c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pantheon-wordpress-edge-integrations", - "version": "0.2.16", + "version": "0.2.17", "description": "WordPress plugin to support Pantheon Edge Integrations and personalization features", "scripts": { "bump:patch": "bump patch --commit 'Version %s.' pantheon-wordpress-edge-integrations.php README.md", diff --git a/pantheon-wordpress-edge-integrations.php b/pantheon-wordpress-edge-integrations.php index 9252169..273d029 100644 --- a/pantheon-wordpress-edge-integrations.php +++ b/pantheon-wordpress-edge-integrations.php @@ -4,7 +4,7 @@ * Description: WordPress plugin to support Pantheon Edge Integrations and personalization features. * Author: Pantheon * Author URI: https://pantheon.io - * Version: 0.2.16 + * Version: 0.3.0-alpha1 * * @package Pantheon/EdgeIntegrations */ diff --git a/scripts/post-release b/scripts/post-release new file mode 100644 index 0000000..82e8ebd --- /dev/null +++ b/scripts/post-release @@ -0,0 +1,28 @@ +#!/bin/bash +# Announce the script so we know we're in the right place. +echo "Welcome to the post-release script! +In this script, we will bump the version number in the plugin file, package.json and the stable version readme." + +echo "Enter the current stable release version: " +read CURRENT_VERSION + +echo "Enter the next release version: " +read NEXT_VERSION + +# Check out the main branch and pull the latest changes. +git checkout main && git pull + +# Bump the version in the plugin file. +sed -i '' "s/Version: .*-dev/Version: $NEXT_VERSION-dev/" pantheon-wordpress-edge-integrations.php + +# Bump the version in the readme to the current stable. +sed -i '' "s/Stable tag: .*/Stable tag: $CURRENT_VERSION /" README.md + +# Bump the versions in the package.json and package-lock.json files. +node_modules/.bin/bump $NEXT_VERSION package.json package-lock.json + +# Commit the changes but don't push. +git add pantheon-wordpress-edge-integrations.php README.md package.json package-lock.json +git commit -m "Bump versions to $NEXT_VERSION and current stable $CURRENT_VERSION" + +echo "Bumped versions to $NEXT_VERSION and current stable $CURRENT_VERSION. Make sure to push to the main branch." \ No newline at end of file diff --git a/scripts/pre-release b/scripts/pre-release new file mode 100644 index 0000000..039021b --- /dev/null +++ b/scripts/pre-release @@ -0,0 +1,56 @@ +#!/bin/bash +# Announce the script so we know we're in the right place. +echo "Welcome to the release prep script!" + +# Check if this is a pre-release or a regular release. +echo "Are you creating a pre-release? (y/n)" +read PRE_RELEASE + +if [ "$PRE_RELEASE" == "y" ]; then + echo "Got it. Preparing for pre-release." + # Get the branch to merge into. + echo "What's the main branch that the pre-release will be merged into? (e.g. branches/0.3.x)?" + read BRANCH + + # Get the release version. + echo "Enter the pre-release version (e.g. 0.3.0-alpha1): " + read VERSION + + # Make sure we're on the latest version of that branch and checkout a new pre-release branch. + git checkout $BRANCH && git pull + git checkout -b release-$VERSION + + # Drop the -dev in the plugin file. We won't change the stable version in the readme for a pre-release. + sed -i '' "s/Version: .*-dev/Version: $VERSION/" pantheon-wordpress-edge-integrations.php + + # Commit the changes. + git add pantheon-wordpress-edge-integrations.php + git commit -m "Bump version to $VERSION" + git push --set-upstream origin release-$VERSION + + echo "Created new release branch for $VERSION. Make sure to set the parent branch to 'build'." + return 0; +else + echo "Got it. Preparing for release." + # Get the release version. + echo "Enter the release version: " + read VERSION + + # Make sure we're on the latest version of the working tree and checkout a new release branch. + git checkout main && git pull + git checkout -b release-$VERSION + + # Drop the -dev in the plugin file. + sed -i '' "s/Version: .*-dev/Version: $VERSION/" pantheon-wordpress-edge-integrations.php + + # Bump the version in the readme. + sed -i '' "s/Stable tag: .*/Stable tag: $VERSION /" README.md + + # Commit the changes. + git add pantheon-wordpress-edge-integrations.php README.md + git commit -m "Bump version to $VERSION" + git push --set-upstream origin release-$VERSION + + echo "Created new release branch for $VERSION. Make sure to set the parent branch to 'build'." + return 0; +fi diff --git a/tests/Test.php b/tests/Test.php index 537cc65..adb548e 100644 --- a/tests/Test.php +++ b/tests/Test.php @@ -35,7 +35,7 @@ public function testGlobalsAreDefined() { * Test the supported vary headers. */ public function testSupportedVaryHeaders() { - $this->assertEquals( [ 'Audience-Set', 'Interest' ], + $this->assertEquals( [ 'P13n-Geo-Country-Code', 'P13n-Interest' ], get_supported_vary_headers(), 'The vary headers supported do not match.' ); @@ -70,6 +70,8 @@ public function testAddHeaderData() { * Test the edge_integrations_enabled function. */ public function testEIEnabled() { + $_SERVER['HTTP_P13N_INTEREST'] = 'foo'; + $_SERVER['HTTP_P13N_GEO_COUNTRY_CODE'] = 'bar'; remove_all_filters( 'pantheon.ei.parsed_geo_data' ); remove_all_filters( 'pantheon.ei.parsed_interest_data' ); $headers = get_supported_vary_headers(); @@ -103,9 +105,10 @@ public function testEIEnabled() { $dummy_data = [ 'city' => 'City', 'region' => 'State', - 'country' => 'US', + 'country-code' => 'US', ]; add_filter( 'pantheon.ei.parsed_geo_data', function( $data ) use ( $dummy_data ) { + $data = empty( $data ) ? [] : $data; $data['city'] = $dummy_data['city']; $data['region'] = $dummy_data['region']; $data['country'] = $dummy_data['country']; diff --git a/tests/geoTest.php b/tests/geoTest.php index b1f3500..e67c284 100644 --- a/tests/geoTest.php +++ b/tests/geoTest.php @@ -32,112 +32,53 @@ function_exists( '\\Pantheon\\EI\\WP\\Geo\\get_geo' ), */ public function testGetGeo( array $audience_data ) { remove_all_filters( 'pantheon.ei.parsed_geo_data' ); - // Get the actual data in a format that's easier to read. - $parsed_data = EI\HeaderData::parse( 'Audience-Set', $audience_data ); - // Get the geo country. - $country = Geo\get_geo( 'country', $audience_data ); - $parsed_country = $parsed_data['country']; - // Test the country. - $this->assertIsString( $country ); - $this->assertNotEmpty( - $country, - 'Country data is empty' - ); - $this->assertEquals( - $country, - $parsed_country, - 'Country data does not match' - ); - - // Get the geo region. - $region = Geo\get_geo( 'region', $audience_data ); - $parsed_region = $parsed_data['region']; - - // Test the region. - $this->assertIsString( $region ); - $this->assertNotEmpty( - $region, - 'Region data is empty' - ); - $this->assertEquals( - $region, - $parsed_region, - 'Region data does not match' - ); - - // Get the geo city. - $city = Geo\get_geo( 'city', $audience_data ); - $parsed_city = $parsed_data['city']; - - // Test the city. - $this->assertIsString( $city ); - $this->assertNotEmpty( - $city, - 'City data is empty' - ); - $this->assertEquals( - $city, - $parsed_city, - 'City data does not match' - ); - - // Get the geo continent. - $continent = Geo\get_geo( 'continent', $audience_data ); - $parsed_continent = $parsed_data['continent']; - - // Test the continent. - $this->assertIsString( $continent ); - $this->assertNotEmpty( - $continent, - 'Continent data is empty' - ); - $this->assertEquals( - $continent, - $parsed_continent, - 'Continent data does not match' - ); - - // Get the connection type. - $conn_type = Geo\get_geo( 'conn-type', $audience_data ); - $parsed_conn_type = $parsed_data['conn-type']; + foreach ( $audience_data as $header => $value ) { + $data = [ + 'HTTP_' . strtoupper( str_replace( '-', '_', $header ) ) => $value, + ]; + $region = $audience_data['P13n-Geo-Country-Code']; + $data_type = str_replace( 'p13n-geo-', '', strtolower( $header ) ); + // Get the geo data. + $value_to_test = Geo\get_geo( $data_type, $data ); + // Make sure the data matches. + $this->assertIsString( $value_to_test ); - // Test the connection type. - $this->assertIsString( $conn_type ); - $this->assertNotEmpty( - $conn_type, - 'Connection type data is empty' - ); - $this->assertEquals( - $conn_type, - $parsed_conn_type, - 'Connection type data does not match' - ); + // We left the UK conn-type empty, so check for empty. + if ( $region === 'UK' && $data_type === 'conn-type' ) { + $this->assertEquals( + '', + $value_to_test, + 'UK conn-type should be empty' + ); + } else { + $this->assertNotEmpty( + $value_to_test, + "Data is empty for $region $data_type" + ); + } - // Get the connection speed. - $conn_speed = Geo\get_geo( 'conn-speed', $audience_data ); - $parsed_conn_speed = $parsed_data['conn-speed']; + $this->assertEquals( + $value_to_test, + $value, + "Data does not match for $region $data_type" + ); - // Test the connection speed. - $this->assertIsString( $conn_speed ); - $this->assertNotEmpty( - $conn_speed, - 'Connection speed data is empty' - ); - $this->assertEquals( - $conn_speed, - $parsed_conn_speed, - 'Connection speed data does not match' - ); + // Build the parsed data for testing later. + $parsed_data[ $data_type ] = $value; + } // Test that some other string returns empty. $this->assertEmpty( - Geo\get_geo( 'some-other-string', $audience_data ), + Geo\get_geo( 'some-other-string' ), 'Disallowed strings should return empty' ); + // Massage the data so we get actual results. + $all_geo_data = $this->format_mock_header_data( $audience_data ); + // Test the get_geo function with no data type passed. - $empty_geo = Geo\get_geo( '', $audience_data ); + $empty_geo = Geo\get_geo( '', $all_geo_data ); $this->assertNotEmpty( $empty_geo, 'Empty data type should not return empty' @@ -152,6 +93,29 @@ public function testGetGeo( array $audience_data ) { $parsed_data, 'Empty data type should return parsed data' ); + + // Ensure the json-encoded string matches what's expected. + $this->assertEquals( + $empty_geo, + json_encode( $parsed_data ), + ); + } + + /** + * Format mock data to emulate actual headers. + * Used to pass into returnPersonalizationObject which expects actual header data. + * + * @see EI\HeaderData::personalizationObject + * @param array $data The data to format. + * + * @return array The formatted data. + */ + private function format_mock_header_data( array $data ) : array { + $new_data = []; + foreach ( $data as $header => $value ) { + $new_data[ strtoupper( str_replace( '-', '_', 'HTTP_' . $header ) ) ] = $value; + } + return $new_data; } /** @@ -161,20 +125,40 @@ public function testGetGeo( array $audience_data ) { */ public function mockAudienceData() : array { return [ - [ - 'US' => [ 'HTTP_AUDIENCE_SET' => 'country:US|city:Salt Lake City|region:UT|continent:NA|conn-speed:broadband|conn-type:wired' ] - ], - [ - 'CA' => [ 'HTTP_AUDIENCE_SET' => 'country:CA|city:Vancouver|region:BC|continent:NA|conn-speed:cable|conn-type:wifi' ] - ], - [ - 'UK' => [ 'HTTP_AUDIENCE_SET' => 'country:UK|city:London|region:LND|continent:EU|conn-speed:xdsl|conn-type:?' ] - ], + 'us' => [ [ + 'P13n-Geo-Country-Code' => 'US', + 'P13n-Geo-Country-Name' => 'united states', + 'P13n-Geo-City' => 'salt lake city', + 'P13n-Geo-Region' => 'UT', + 'P13n-Geo-Continent-Code' => 'NA', + 'P13n-Geo-Conn-Speed' => 'broadband', + 'P13n-Geo-Conn-Type' => 'wired', + ] ], + 'ca' => [ [ + 'P13n-Geo-Country-Code' => 'CA', + 'P13n-Geo-Country-Name' => 'canada', + 'P13n-Geo-City' => 'vancouver', + 'P13n-Geo-Region' => 'BC', + 'P13n-Geo-Continent-Code' => 'NA', + 'P13n-Geo-Conn-Speed' => 'cable', + 'P13n-Geo-Conn-Type' => 'wifi', + ] ], + 'uk' => [ [ + 'P13n-Geo-Country-Code' => 'UK', + 'P13n-Geo-Country-Name' => 'united kingdom', + 'P13n-Geo-City' => 'london', + 'P13n-Geo-Region' => 'LND', + 'P13n-Geo-Continent-Code' => 'EU', + 'P13n-Geo-Conn-Speed' => 'xdsl', + 'P13n-Geo-Conn-Type' => '', + ] ], ]; } /** * Test the pantheon.ei.geo_allowed_values filter and get_geo_allowed_values function. + * + * @group wp-geo */ public function testGeoAllowedValues() { $allowed_values = Geo\get_geo_allowed_values(); @@ -184,15 +168,13 @@ public function testGeoAllowedValues() { $allowed_values, [ '', - 'country', - 'region', + 'country-code', + 'country-name', 'city', - 'continent', + 'region', + 'continent-code', 'conn-speed', 'conn-type', - 'lat', - 'lon', - 'latlon', ], 'Allowed values do not match' ); @@ -205,14 +187,76 @@ public function testGeoAllowedValues() { // Validate that the new value is in the allowed values. $this->assertContains( 'some-other-value', Geo\get_geo_allowed_values() ); + + // Reset the data back to the original. + add_filter( 'pantheon.ei.geo_allowed_values', function() { + return [ + '', + 'country-code', + 'country-name', + 'city', + 'region', + 'continent-code', + 'conn-speed', + 'conn-type', + ]; + }, 10, 1 ); + } + + /** + * Test the pantheon.ei.geo_allowed_values filter and get_geo_allowed_values function. + * + * @group wp-geo + */ + public function testGeoAllowedHeaders() { + $allowed_headers = Geo\get_geo_allowed_headers(); + $this->assertIsArray( $allowed_headers ); + $this->assertNotEmpty( $allowed_headers ); + $this->assertEquals( + $allowed_headers, + [ + 'P13n-Geo-Country-Code', + 'P13n-Geo-Country-Name', + 'P13n-Geo-City', + 'P13n-Geo-Region', + 'P13n-Geo-Continent-Code', + 'P13n-Geo-Conn-Speed', + 'P13n-Geo-Conn-Type', + ], + 'Allowed headers do not match' + ); + + // Add a new header value to the allowed headers. + add_filter( 'pantheon.ei.geo_allowed_headers', function( $values ) { + $values[] = 'some-other-header'; + return $values; + }, 10, 1 ); + + // Validate that the new header value is in the allowed headers. + $this->assertContains( 'some-other-header', Geo\get_geo_allowed_headers() ); + + // Reset the data back to the original. + add_filter( 'pantheon.ei.geo_allowed_headers', function() { + return [ + 'P13n-Geo-Country-Code', + 'P13n-Geo-Country-Name', + 'P13n-Geo-City', + 'P13n-Geo-Region', + 'P13n-Geo-Continent-Code', + 'P13n-Geo-Conn-Speed', + 'P13n-Geo-Conn-Type', + ]; + }, 10, 1 ); } /** * Test the pantheon.ei.parsed_geo_data filter. + * + * @group wp-geo */ public function testParsedGeoData() { // Filter the parsed geo data. - add_filter( 'pantheon.ei.parsed_geo_data', function( $geo_data ) { + add_filter( 'pantheon.ei.get_all_geo', function( $geo_data ) { return [ 'name' => 'Chris Reynolds', 'role' => 'Software Engineer', @@ -234,32 +278,21 @@ public function testParsedGeoData() { ] ), 'Parsed data does not match' ); - - // Reset the geo data to something resembling real data. This is a hack because data is retained across tests. - add_filter( 'pantheon.ei.parsed_geo_data', function() { - return EI\HeaderData::parse( 'Audience-Set', $this->mockAudienceData()[0]['US'] ); - }, 10 ); - } - - /** - * Test that the pantheon.ei.get_geo action hook fires. - */ - public function testGetGeoAction() { - Geo\get_geo(); - $this->assertGreaterThan( 0, did_action( 'pantheon.ei.before_get_geo' ) ); } /** * Test the pantheon.ei.get_geo filter. + * + * @group wp-geo */ public function testGetGeoFilter() { // Filter the geo data. - add_filter( 'pantheon.ei.get_geo', function( $value ) { + add_filter( 'pantheon.ei.get_geo_country-name', function( $value ) { return 'Antarctica'; }, 10, 1 ); $this->assertEquals( - Geo\get_geo( 'country' ), + Geo\get_geo( 'country-name' ), 'Antarctica', 'Filtered geo data does not match' ); @@ -267,18 +300,15 @@ public function testGetGeoFilter() { /** * Test that we dn't get an undefined array key error when calling a geo value that doesn't exist. + * + * @group wp-geo */ public function testUndefinedArrayKey() { // Reset the geo data to nothing. - add_filter( 'pantheon.ei.parsed_geo_data', function() { + add_filter( 'pantheon.ei.get_all_geo', function() { return []; }, 10 ); - $this->assertEmpty( Geo\get_geo( 'country' ) ); - - // Reset the geo back to something resembling real data. - add_filter( 'pantheon.ei.parsed_geo_data', function() { - return EI\HeaderData::parse( 'Audience-Set', $this->mockAudienceData()[0]['US'] ); - }, 10 ); + $this->assertEmpty( Geo\get_geo( 'conn-speed' ) ); } } diff --git a/tests/interestTest.php b/tests/interestTest.php index 975652d..f3e8542 100644 --- a/tests/interestTest.php +++ b/tests/interestTest.php @@ -24,6 +24,23 @@ function_exists( '\\Pantheon\\EI\\WP\\Interest\\bootstrap' ), ); } + /** + * Test that we can get the expected Interest header key. + */ + public function testGetInterestHeaderKey() { + $this->assertEquals( + 'P13n-Interest', + Interest\get_interest_header_key() + ); + + // This tests code in set_interest. This assertion ensures that the headers we set are correct. + $http_interest = strtoupper( 'HTTP_' . str_replace( '-', '_', Interest\get_interest_header_key() ) ); + $this->assertEquals( + 'HTTP_P13N_INTEREST', + $http_interest + ); + } + /** * Test Interest post types. */ @@ -158,7 +175,7 @@ function_exists( '\\Pantheon\\EI\\WP\\Interest\\set_interest' ), */ public function testSetInterest( array $interest_data ) { // Get the actual data in a format that's easier to read. - $parsed_data = EI\HeaderData::parse( 'Interest', $interest_data ); + $parsed_data = EI\HeaderData::parse( Interest\get_interest_header_key(), $interest_data ); $interest = Interest\set_interest( $interest_data ); $this->assertIsArray( $interest ); @@ -180,10 +197,10 @@ public function testSetInterest( array $interest_data ) { */ public function testParsedInterestData() { remove_all_filters( 'pantheon.ei.parsed_interest_data' ); - $input = [ 'HTTP_INTEREST' =>'Carl Sagan|Richard Feynman|Albert Einstein' ]; + $input = [ 'HTTP_P13N_INTEREST' =>'Carl Sagan|Richard Feynman|Albert Einstein' ]; // Filter the parsed interest data. add_filter( 'pantheon.ei.parsed_interest_data', function( $interest_data ) { - return [ 'HTTP_INTEREST' =>'Carl Sagan|Richard Feynman|Albert Einstein' ]; + return [ 'HTTP_P13N_INTEREST' =>'Carl Sagan|Richard Feynman|Albert Einstein' ]; }, 10, 1 ); $data = Interest\get_interest( $input ); @@ -202,7 +219,7 @@ public function testParsedInterestData() { public function mockGetInterestData() : array { return [ [ - 'mockInterestData' => [ 'HTTP_INTEREST' => 'Carl Sagan|Richard Feynman|Neil deGrasse Tyson' ] + 'mockInterestData' => [ 'HTTP_P13N_INTEREST' => 'Carl Sagan|Richard Feynman|Neil deGrasse Tyson' ] ] ]; } diff --git a/vendor/autoload.php b/vendor/autoload.php index c459488..8d86366 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -2,6 +2,11 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + exit(1); +} + require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInite51040fef24b8d6bfedf0c89db7f35c6::getLoader(); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 1a27fd0..b95b408 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -27,7 +27,7 @@ public static function getLoader() spl_autoload_unregister(array('ComposerAutoloaderInite51040fef24b8d6bfedf0c89db7f35c6', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - \Composer\Autoload\ComposerStaticInite51040fef24b8d6bfedf0c89db7f35c6::getInitializer($loader)(); + call_user_func(\Composer\Autoload\ComposerStaticInite51040fef24b8d6bfedf0c89db7f35c6::getInitializer($loader)); $loader->register(true); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 50e7d39..bccdc24 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,24 +2,24 @@ "packages": [ { "name": "pantheon-systems/pantheon-edge-integrations", - "version": "1.0.1", - "version_normalized": "1.0.1.0", + "version": "v1.1.0-alpha1", + "version_normalized": "1.1.0.0-alpha1", "source": { "type": "git", "url": "https://github.com/pantheon-systems/pantheon-edge-integrations.git", - "reference": "4a6447a6d009ca8f6410390f4f0971ee7cd0de19" + "reference": "529b95b0759efe3dc80532d005ccc87a7c41abd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pantheon-systems/pantheon-edge-integrations/zipball/4a6447a6d009ca8f6410390f4f0971ee7cd0de19", - "reference": "4a6447a6d009ca8f6410390f4f0971ee7cd0de19", + "url": "https://api.github.com/repos/pantheon-systems/pantheon-edge-integrations/zipball/529b95b0759efe3dc80532d005ccc87a7c41abd1", + "reference": "529b95b0759efe3dc80532d005ccc87a7c41abd1", "shasum": "" }, "require-dev": { "phpunit/phpunit": "^9.5", "squizlabs/php_codesniffer": "^3.6" }, - "time": "2022-02-24T17:14:59+00:00", + "time": "2022-06-01T21:29:18+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -37,7 +37,7 @@ "description": "Helper class for content personalization.", "support": { "issues": "https://github.com/pantheon-systems/pantheon-edge-integrations/issues", - "source": "https://github.com/pantheon-systems/pantheon-edge-integrations/tree/1.0.1" + "source": "https://github.com/pantheon-systems/pantheon-edge-integrations/tree/v1.1.0-alpha1" }, "install-path": "../pantheon-systems/pantheon-edge-integrations" } diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index fec063a..673fbd2 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -5,18 +5,18 @@ 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '00a95e0381a92a394f5a8865ea86b5bed1e10706', + 'reference' => 'a4cb7a0ad9407a43962610eaf6597fbb16e1b6a4', 'name' => 'pantheon-systems/pantheon-wordpress-edge-integrations', 'dev' => false, ), 'versions' => array( 'pantheon-systems/pantheon-edge-integrations' => array( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', + 'pretty_version' => 'v1.1.0-alpha1', + 'version' => '1.1.0.0-alpha1', 'type' => 'library', 'install_path' => __DIR__ . '/../pantheon-systems/pantheon-edge-integrations', 'aliases' => array(), - 'reference' => '4a6447a6d009ca8f6410390f4f0971ee7cd0de19', + 'reference' => '529b95b0759efe3dc80532d005ccc87a7c41abd1', 'dev_requirement' => false, ), 'pantheon-systems/pantheon-wordpress-edge-integrations' => array( @@ -25,7 +25,7 @@ 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => '00a95e0381a92a394f5a8865ea86b5bed1e10706', + 'reference' => 'a4cb7a0ad9407a43962610eaf6597fbb16e1b6a4', 'dev_requirement' => false, ), ), diff --git a/vendor/pantheon-systems/pantheon-edge-integrations/CODEOWNERS b/vendor/pantheon-systems/pantheon-edge-integrations/CODEOWNERS new file mode 100644 index 0000000..380098e --- /dev/null +++ b/vendor/pantheon-systems/pantheon-edge-integrations/CODEOWNERS @@ -0,0 +1,4 @@ +# Code owners. See: +# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners + +* @pantheon-systems/edge-integrations diff --git a/vendor/pantheon-systems/pantheon-edge-integrations/README.md b/vendor/pantheon-systems/pantheon-edge-integrations/README.md index 44419ab..613f4e4 100644 --- a/vendor/pantheon-systems/pantheon-edge-integrations/README.md +++ b/vendor/pantheon-systems/pantheon-edge-integrations/README.md @@ -1,22 +1,123 @@ # Pantheon Edge Integrations -[![Unsupported](https://img.shields.io/badge/pantheon-unsupported-yellow?logo=pantheon&color=FFDC28&style=for-the-badge)](https://github.com/topics/unsupported?q=org%3Apantheon-systems "Unsupported, e.g. a tool we are actively using internally and are making available, but do not promise to support") ![Build Status](https://github.com/pantheon-systems/pantheon-edge-integrations/actions/workflows/main.yml/badge.svg) +[![Unsupported](https://img.shields.io/badge/pantheon-unsupported-yellow?logo=pantheon&color=FFDC28)](https://pantheon.io/docs/oss-support-levels#unsupported) ![Packagist Release Version](https://img.shields.io/packagist/v/pantheon-systems/pantheon-edge-integrations)![Build Status](https://github.com/pantheon-systems/pantheon-edge-integrations/actions/workflows/main.yml/badge.svg) -Pantheon Edge Integrations uses header data to provide a personalization object, to be used for personalizing content for each user. +Pantheon Edge Integrations is a PHP library which uses header data to provide a personalization object, to be used for personalizing content for each user. + +## Installation + +Pantheon Edge Integrations can be installed via Composer from [Packagist](https://packagist.org/packages/pantheon-systems/pantheon-edge-integrations)... + +``` sh +composer require pantheon-systems/pantheon-edge-integrations +``` + +## Usage + +To make use of the PHP library, ensure PHP can use the class. After which, it's possible to etiher call the library through instanced methods, or through the global methods. + +``` php +use Pantheon\EI\HeaderData; +``` + +### Instanced Methods + +Once the class is available, `headerData` objects can be instantiated to make use of the API and methods can be called on it. + +``` php +$headerData = new HeaderData(); +``` + +#### getHeader($key) -## Methods -### getHeader(key) Uses header key to return raw header data. -### parseHeader(key) +``` php +$headerData->getHeader('Audience'); +// => "geo:US" + +$headerData->getHeader('Interest'); +// => "27" + +$headerData->getHeader('Role'); +// => "subscriber" +``` + +#### parseHeader($key) + Uses header key to return parsed header data array. -### returnPersonalizationObject() +``` php +$headerData->getHeader('Audience'); +// => [geo => US] + +$headerData->getHeader('Interest'); +// => [0 => 27] + +$headerData->getHeader('Role'); +// => "subscriber" +``` + +#### returnPersonalizationObject() + Returns an array with personalization data. -### returnVaryHeader($key) +``` php +$headerData->returnPersonalizedObject(); +// => [ +// Audience => [ geo => US ] +// Interest => [ 0 => 27 ] +// Role => subscriber +// ] +``` + +#### returnVaryHeader($key) + Returns vary header array, based on header data. +### Global Methods + +There are also static methods defined within the class to help assist in retrieving data without having to instantiate the object yourself. + +#### HeaderData::personalizationObject() + +Gets the global personalizaition object. + +``` php +Pantheon\EI\HeaderData::personalizationObject(); +// => [ +// Audience => [ geo => US ] +// Interest => [ 0 => 27 ] +// Role => subscriber +// ] +``` + +#### HeaderData::parse($key) + +Parses a global header by key using a specified regex. + +``` php +Pantheon\EI\HeaderData::parse('Audience'); +// => [geo => US] +``` + +#### HeaderData::header($key) + +Gets the global header data based on the given key. + +``` php +Pantheon\EI\HeaderData::header('Audience'); +// => geo:US +``` + +#### HeaderData::varyHeader() + +Returns vary header array based on the global data. + +``` php +Pantheon\EI\HeaderData::varyHeader('geo'); +``` + ## Development [PHPUnit](https://phpunit.de/) is used to run the [tests](tests). @@ -25,14 +126,3 @@ Returns vary header array, based on header data. composer install composer test ``` - -## Default branch name - -The default branch name is `main`. This has changed since the project was created. If your local environment is still using `master` as the default branch name, you may update by running the following commands: - -```bash -git branch -m master -git fetch origin -git branch -u origin/ -git remote set-head origin -a -``` diff --git a/vendor/pantheon-systems/pantheon-edge-integrations/src/HeaderData.php b/vendor/pantheon-systems/pantheon-edge-integrations/src/HeaderData.php index bf31f9a..b33a3df 100644 --- a/vendor/pantheon-systems/pantheon-edge-integrations/src/HeaderData.php +++ b/vendor/pantheon-systems/pantheon-edge-integrations/src/HeaderData.php @@ -1,4 +1,11 @@ getHeader($key); + $parsed_header = in_array($key, [ 'Interest', 'P13n-Interest' ], true)? [] : ''; - if (!empty($header)) { - $parsed_header = []; - switch ($key) { - // Parse Audience header. - case 'Audience': - case 'Audience-Set': - // Separate different pairs in header string. - $header_parts = explode('|', $header); - - foreach ($header_parts as $header_part) { - // Skip if empty. - if (empty($header_part)) { - continue; - } - - // Separate the pair string into key and value. - $header_pair = explode(':', $header_part); - if (count($header_pair) >= 2) { - $parsed_header[$header_pair[0]] = $header_pair[1]; - } else { - // If string isn't formatted as a pair, just set string. - $parsed_header[$key][] = $header_part; - } - } - break; - - // Parse Interest header. - case 'Interest': - // Decode special characters. - $header_decoded = urldecode($header); - - // Split header value into an array. - $parsed_header = explode('|', $header_decoded); - break; - - // By default, just return header. - default: - $parsed_header = $header; - break; - } + // If the header is empty, bail early. + if (empty($header)) { + return $parsed_header; + } + + // Decode the header. + $header_decoded = urldecode($header); + // Backwards compatibility with Audience and Audience-Set. + if (in_array($key, ['Audience','Audience-Set'], true)) { + $parsed_header = $this->__deprecatedAudienceHandling($key, $header_decoded); return $parsed_header; } - return []; + // If the header is an interest, or if the value has multiple entries, + // allow those entries to be split into an array. + if (in_array($key, [ 'Interest', 'P13n-Interest' ], true) || + stripos($header_decoded, '|') + ) { + $parsed_header = explode('|', $header_decoded); + // Trim white space out of values. + $parsed_header = array_map('trim', $parsed_header); + } + + // If the header is not an interest (e.g. Geo or custom), set the value to the decoded header. + if (empty($parsed_header)) { + $parsed_header = $header_decoded; + } + + return $parsed_header; + } + + /** + * Handles deprecated Audience and Audience-Set headers. + * @param string $key The header key. Either 'Audience' or 'Audience-Set'. + * @param string $header The header value. + * @return array + * Returns an array of audience data. + * @deprecated + * This function is deprecated and will be removed in a future release. + */ + public function __deprecatedAudienceHandling(string $key, string $header) : array { + $parsed_header = []; + + // If we're dealing with an Audience header, we need to add it to an array. + if ($key === 'Audience') { + $_headers = [$header]; + } + + // Split the header data at the | character. + $_headers = explode('|', $header); + + // Loop through each header. + foreach ($_headers as $i => $header_part) { + // If the header is empty, bail early. + if (empty($header_part)) { + continue; + } + + // Split at the : character. + $header_pair = explode(':', $header_part); + // If we actually have a header pair, map the key and value. + // Otherwise, just return the value for the passed key. + if (count($header_pair) >= 2) { + $parsed_header[$header_pair[0]] = $header_pair[1]; + } else { + $parsed_header[$key] = $header_part; + } + } + + return $parsed_header; } /** @@ -135,10 +169,18 @@ public function returnPersonalizationObject(): array { $p_obj = []; $header_keys = [ - 'Audience', - 'Audience-Set', - 'Interest', - 'Role', + 'P13n-Geo-Region', + 'P13n-Geo-Country-Code', + 'P13n-Geo-Country-Name', + 'P13n-Geo-Continent-Code', + 'P13n-Geo-City', + 'P13n-Geo-Conn-Type', + 'P13n-Geo-Conn-Speed', + 'P13n-Interest', + 'Audience', // Deprecated. + 'Audience-Set', // Deprecated. + 'Interest', // Deprecated. + 'Role', // Not implemented. ]; foreach ($header_keys as $key) { diff --git a/vendor/pantheon-systems/pantheon-edge-integrations/tests/HeaderDataTest.php b/vendor/pantheon-systems/pantheon-edge-integrations/tests/HeaderDataTest.php index 70991c9..a683b8e 100644 --- a/vendor/pantheon-systems/pantheon-edge-integrations/tests/HeaderDataTest.php +++ b/vendor/pantheon-systems/pantheon-edge-integrations/tests/HeaderDataTest.php @@ -18,6 +18,25 @@ */ final class HeaderDataTest extends TestCase { + + private $p13n_input = [ + 'HTTP_P13N_GEO_COUNTRY_CODE' => 'US', + 'HTTP_P13N_GEO_COUNTRY_NAME' => 'united states', + 'HTTP_P13N_GEO_CITY' => 'salt lake city', + 'HTTP_P13N_GEO_REGION' => 'UT', + 'HTTP_P13N_GEO_CONTINENT_CODE' => 'NA', + 'HTTP_P13N_GEO_CONN_TYPE' => 'wifi', + 'HTTP_P13N_GEO_CONN_SPEED' => 'broadband', + 'HTTP_P13N_Interest' => 'Marie Curie|Jane Goodall|Edith Clark||For Science!|With A Percent%20', + 'HTTP_USER_AGENT' => 'Should just return the value', + 'HTTP_ROLE' => 'Administrator', + 'HTTP_INTEREST' => 'Carl Sagan|Richard Feynman||For Science!|With A Percent%20', + 'HTTP_AUDIENCE' => 'geo:us', + 'HTTP_AUDIENCE_SET' => 'country:us|city:salt lake city|region:UT|continent:NA|conn_type:wifi|conn_speed:broadband', + 'HTTP_IGNORED' => 'HTTP Ignored Entry', + 'IGNORED_ENTRY' => 'Completely ignored entry' + ]; + /** * Tests the HeaderData constructor. * @@ -66,37 +85,35 @@ public function testGetHeader(): void { * @group headerdata */ public function testParseHeader(): void { - // The Audience and Interest entries are parsed into arrays. - $input = [ - 'HTTP_AUDIENCE' => 'Parents|Children||Age:47|Name:RobLoach|Name:StevePersch|Name:AnnaMykhailova', - 'HTTP_AUDIENCE_SET' => 'country:US|city:Salt Lake City|region:UT|continent:NA|conn-speed:broadband|conn-type:wired', - 'HTTP_USER_AGENT' => 'Should just return the value', - 'IGNORED TEST' => 'Should return an empty array', - 'HTTP_INTEREST' => 'Carl Sagan|Richard Feynman||For Science!|With%20A Percent20', - ]; - $headerData = new HeaderData($input); + $headerData = new HeaderData($this->p13n_input); // When a header doesn't exist. $keyNotFound = $headerData->parseHeader('header key not found'); - $this->assertEmpty($keyNotFound, 'Expected to return an empty array'); - $this->assertIsArray($keyNotFound, 'Should be an array'); + $this->assertEmpty($keyNotFound, 'Expected to return an empty string'); + $this->assertIsString($keyNotFound, 'Should be a string'); - // Audience - $audience = $headerData->parseHeader('Audience'); - $this->assertIsArray($audience['Audience']); - $this->assertEquals($audience['Audience'][1], 'Children'); - $this->assertEquals($audience['Name'], 'AnnaMykhailova'); // Take the last entry. - $this->assertEquals($audience['Age'], 47); - - // Audience Set - $audienceSet = $headerData->parseHeader('Audience-Set'); - $this->assertIsArray($audienceSet); - $this->assertEquals($audienceSet['country'], 'US'); - $this->assertEquals($audienceSet['city'], 'Salt Lake City'); - $this->assertEquals($audienceSet['region'], 'UT'); - $this->assertEquals($audienceSet['continent'], 'NA'); - $this->assertEquals($audienceSet['conn-speed'], 'broadband'); - $this->assertEquals($audienceSet['conn-type'], 'wired'); + // Geolocation. + $country_code = $headerData->parseHeader('P13n-Geo-Country-Code'); + $this->assertIsString($country_code, 'Should be a string'); + $this->assertEquals($country_code, 'US'); + $country_name = $headerData->parseHeader('P13n-Geo-Country-Name'); + $this->assertIsString($country_name, 'Should be a string'); + $this->assertEquals($country_name, 'united states'); + $city = $headerData->parseHeader('P13n-Geo-City'); + $this->assertIsString($city, 'Should be a string'); + $this->assertEquals($city, 'salt lake city'); + $region = $headerData->parseHeader('P13n-Geo-Region'); + $this->assertIsString($region, 'Should be a string'); + $this->assertEquals($region, 'UT'); + $continent_code = $headerData->parseHeader('P13n-Geo-Continent-Code'); + $this->assertIsString($continent_code, 'Should be a string'); + $this->assertEquals($continent_code, 'NA'); + $conn_type = $headerData->parseHeader('P13n-Geo-Conn-Type'); + $this->assertIsString($conn_type, 'Should be a string'); + $this->assertEquals($conn_type, 'wifi'); + $conn_speed = $headerData->parseHeader('P13n-Geo-Conn-Speed'); + $this->assertIsString($conn_speed, 'Should be a string'); + $this->assertEquals($conn_speed, 'broadband'); // Interest $interest = $headerData->parseHeader('Interest'); @@ -105,12 +122,33 @@ public function testParseHeader(): void { 'Richard Feynman', '', 'For Science!', - 'With A Percent20' + 'With A Percent' ]; $this->assertEquals($interest, $expected); + $p13n_interest = $headerData->parseHeader('P13n-Interest'); + $this->assertEquals($p13n_interest, [ + 'Marie Curie', + 'Jane Goodall', + 'Edith Clark', + '', + 'For Science!', + 'With A Percent' + ]); // User Agent $this->assertEquals($headerData->parseHeader('User-Agent'), 'Should just return the value'); + + // Backcompat. + $audience = $headerData->parseHeader('Audience'); + $this->assertEquals($audience['geo'], 'us'); + + $audience_set = $headerData->parseHeader('Audience-Set'); + $this->assertEquals($audience_set['country'], 'us'); + $this->assertEquals($audience_set['city'], 'salt lake city'); + $this->assertEquals($audience_set['region'], 'UT'); + $this->assertEquals($audience_set['continent'], 'NA'); + $this->assertEquals($audience_set['conn_type'], 'wifi'); + $this->assertEquals($audience_set['conn_speed'], 'broadband'); } /** @@ -119,23 +157,19 @@ public function testParseHeader(): void { * @group headerdata */ public function testReturnPersonalizationObject(): void { - $input = [ - 'HTTP_AUDIENCE' => 'geo:US', - 'HTTP_AUDIENCE_SET' => 'country:US|city:Salt Lake City|region:UT|continent:NA|conn-speed:broadband|conn-type:wired', - 'HTTP_ROLE' => 'Administrator', - 'HTTP_INTEREST' => 'Carl Sagan|Richard Feynman', - 'HTTP_IGNORED' => 'HTTP Ignored Entry', - 'IGNORED_ENTRY' => 'Completely ignored entry' - ]; - $headerData = new HeaderData($input); + $headerData = new HeaderData($this->p13n_input); $result = $headerData->returnPersonalizationObject(); - - $this->assertEquals($result['Audience']['geo'], 'US'); + $this->assertEquals($result['P13n-Geo-Country-Code'], 'US'); + $this->assertEquals($result['P13n-Geo-Country-Name'], 'united states'); + $this->assertEquals($result['P13n-Geo-City'], 'salt lake city'); + $this->assertEquals($result['P13n-Geo-Region'], 'UT'); + $this->assertEquals($result['P13n-Geo-Continent-Code'], 'NA'); + $this->assertEquals($result['P13n-Geo-Conn-Type'], 'wifi'); + $this->assertEquals($result['P13n-Geo-Conn-Speed'], 'broadband'); + $this->assertIsArray($result['P13n-Interest']); + $this->assertContains('Edith Clark',$result['P13n-Interest']); $this->assertEquals($result['Role'], 'Administrator'); $this->assertArrayNotHasKey('Ignored', $result); - // Test the first and last things in the Audience Set array. If we have both, we can assume everything in the middle matches as well. - $this->assertEquals($result['Audience-Set']['country'], 'US'); - $this->assertEquals($result['Audience-Set']['conn-type'], 'wired'); } /** @@ -193,19 +227,16 @@ public function testGlobalHeader() { */ public function testGlobalParse() { // Initialize both the global and an instance as the same input. - $input = [ - 'HTTP_AUDIENCE' => 'Parents|Children||Age:47|Name:RobLoach|Name:StevePersch|Name:AnnaMykhailova', - 'HTTP_AUDIENCE_SET' => 'country:US|city:Salt Lake City|region:UT|continent:NA|conn-speed:broadband|conn-type:wired', - 'HTTP_IGNORED' => 'HTTP Ignored Entry', - 'IGNORED_ENTRY' => 'Completely ignored entry', - ]; + $input = $this->p13n_input; - $audience = HeaderData::parse('Audience', $input); - $audienceSet = HeaderData::parse('Audience-Set', $input); - $this->assertArrayHasKey('Age', $audience); - $this->assertEquals(47, $audience['Age']); - $this->assertArrayHasKey( 'region', $audienceSet ); - $this->assertEquals( 'UT', $audienceSet['region'] ); + $country_code = HeaderData::parse('P13n-Geo-Country-Code', $input); + $city = HeaderData::parse('P13n-Geo-City', $input); + $region = HeaderData::parse('P13n-Geo-Region', $input); + $interest = HeaderData::parse('P13n-Interest', $input); + $this->assertEquals('US', $country_code); + $this->assertEquals('salt lake city', $city); + $this->assertEquals( 'UT', $region ); + $this->assertContains( 'Jane Goodall', $interest ); } /**