diff --git a/.gitattributes b/.gitattributes
index 289761dafa2..2a4681cce94 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,5 +1,35 @@
# Improve diff output for PHP files.
-*.php diff=php
+*.php diff=php
+
+/.github export-ignore
+/bin export-ignore
+/tests export-ignore
+/.browserslistrc export-ignore
+/.devlib export-ignore
+/.editorconfig export-ignore
+/.eslintignore export-ignore
+/.eslintrc export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
+/.gitmodules export-ignore
+/.npmrc export-ignore
+/.nvmrc export-ignore
+/.phpcs.xml.dist export-ignore
+/.phpstorm.meta.php export-ignore
+/.rtlcssrc export-ignore
+/.stylelintignore export-ignore
+/.stylelintrc.json export-ignore
+/babel.config.js export-ignore
+/codecov.yml export-ignore
+/Gruntfile.js export-ignore
+/package.json export-ignore
+/package-lock.json export-ignore
+/phpstan.neon.dist export-ignore
+/phpunit.xml.dist export-ignore
+/postcss.config.js export-ignore
+/scoper.inc.php export-ignore
+/sizereport.config.js export-ignore
+/webpack.config.js export-ignore
# Mark generated files so diffs are hidden by default.
*.snap linguist-generated=true
diff --git a/.github/workflows/build-test-measure.yml b/.github/workflows/build-test-measure.yml
index 1ee847a32f5..b81030c5390 100644
--- a/.github/workflows/build-test-measure.yml
+++ b/.github/workflows/build-test-measure.yml
@@ -387,14 +387,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php }}
- extensions: curl, date, dom, gd, iconv, json, libxml, mysql, spl
- coverage: ${{ matrix.coverage && 'pcov' || 'none' }}
- ini-values: pcov.directory=.
-
- name: Shutdown default MySQL service
run: sudo service mysql stop
@@ -425,8 +417,31 @@ jobs:
restore-keys: |
${{ runner.os }}-composer-
+ # PHP-Scoper only works on PHP 7.3+ but is still a necessary tool to generate the scoped dependencies. To work
+ # around this, a compatible PHP version is temporarily installed and then used to install the dependencies.
+ # Once that is done, the PHP version is replaced with the one meant to be used and the vendor directory is
+ # removed so that the appropriate dependencies can then be later installed.
+
+ - name: Setup PHP 7.4 (to run PHP Scoper)
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 7.4
+
+ - name: Install Composer dependencies (and scope necessary dependencies)
+ run: |
+ composer install --prefer-dist --no-suggest --no-progress --no-interaction
+ rm -rf vendor
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: curl, date, dom, gd, iconv, json, libxml, mysql, spl
+ coverage: ${{ matrix.coverage && 'pcov' || 'none' }}
+ ini-values: pcov.directory=.
+
- name: Install Composer dependencies
- run: composer install --prefer-dist --ignore-platform-reqs --no-progress --no-interaction
+ run: composer install --prefer-dist --ignore-platform-reqs --no-progress --no-interaction --no-scripts
- name: Get npm cache directory
id: npm-cache
@@ -670,7 +685,7 @@ jobs:
git-sha-8: ${{ steps.retrieve-git-sha-8.outputs.sha8 }}
strategy:
matrix:
- build: ['dev', 'prod']
+ build: ['dev', 'prod', 'composer']
steps:
- name: Check out source files
@@ -755,18 +770,16 @@ jobs:
runs-on: ubuntu-latest
needs:
- build-zip
- steps:
- - name: Download dev build
- uses: actions/download-artifact@v2
- with:
- name: amp-${{ needs.build-zip.outputs.branch-name }}-${{ needs.build-zip.outputs.git-sha-8 }}-dev
- path: builds/dev
+ strategy:
+ matrix:
+ build: [ 'dev', 'prod', 'composer' ]
- - name: Download prod build
+ steps:
+ - name: Download ${{ matrix.build }} build
uses: actions/download-artifact@v2
with:
- name: amp-${{ needs.build-zip.outputs.branch-name }}-${{ needs.build-zip.outputs.git-sha-8 }}-prod
- path: builds/prod
+ name: amp-${{ needs.build-zip.outputs.branch-name }}-${{ needs.build-zip.outputs.git-sha-8 }}-${{ matrix.build }}
+ path: builds/${{ matrix.build }}
- name: Setup Google Cloud SDK
uses: google-github-actions/setup-gcloud@master
@@ -774,11 +787,8 @@ jobs:
project_id: ${{ secrets.GCS_PROJECT_ID }}
service_account_key: ${{ secrets.GCS_APPLICATION_CREDENTIALS }}
- - name: Upload dev build to bucket
- run: gsutil cp -r builds/dev/amp.zip gs://ampwp_github_artifacts/${{ github.ref }}/dev/amp.zip
-
- - name: Upload prod build to bucket
- run: gsutil cp -r builds/prod/amp.zip gs://ampwp_github_artifacts/${{ github.ref }}/prod/amp.zip
+ - name: Upload ${{ matrix.build }} build to bucket
+ run: gsutil cp -r builds/${{ matrix.build }}/amp.zip gs://ampwp_github_artifacts/${{ github.ref }}/${{ matrix.build }}/amp.zip
#-----------------------------------------------------------------------------------------------------------------------
@@ -807,7 +817,8 @@ jobs:
run: |
body="Plugin builds for ${{ github.event.pull_request.head.sha }} are ready :bellhop_bell:!
- Download [development build](https://storage.googleapis.com/ampwp_github_artifacts/${{ github.ref }}/dev/amp.zip)
- - Download [production build](https://storage.googleapis.com/ampwp_github_artifacts/${{ github.ref }}/prod/amp.zip)"
+ - Download [production build](https://storage.googleapis.com/ampwp_github_artifacts/${{ github.ref }}/prod/amp.zip)
+ - Download [composer build](https://storage.googleapis.com/ampwp_github_artifacts/${{ github.ref }}/composer/amp.zip)"
body="${body//$'\n'/'%0A'}"
echo "::set-output name=body::$body"
diff --git a/.gitignore b/.gitignore
index 1044d8cf962..a02048459e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,7 @@ built
/phpcs.xml
/phpunit.xml
/*.sql
+/third-party
# Generated via bin/transform-readme.php
/readme.txt
diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist
index 8bad0b81e96..90417f09b61 100644
--- a/.phpcs.xml.dist
+++ b/.phpcs.xml.dist
@@ -131,6 +131,10 @@
+
+ scoper.inc.php
+
+
.
@@ -146,4 +150,5 @@
^build/*
includes/sanitizers/class-amp-allowed-tags-generated.php
assets/js/*.asset.php
+ third-party/*
diff --git a/Gruntfile.js b/Gruntfile.js
index 32385a415c1..1d1e71855af 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -3,7 +3,7 @@
module.exports = function( grunt ) {
'use strict';
- // Root paths to include in the plugin build ZIP when running `npm run build:prod`.
+ // Root paths to include in the plugin build ZIP.
const productionIncludedRootFiles = [
'LICENSE',
'amp.php',
@@ -12,7 +12,6 @@ module.exports = function( grunt ) {
'includes',
'src',
'templates',
- 'vendor',
];
// These patterns paths will be excluded from among the above directory.
@@ -43,6 +42,17 @@ module.exports = function( grunt ) {
'vendor/ampproject/amp-toolbox/conceptual-diagram.svg',
'vendor/ampproject/amp-toolbox/phpstan.neon.dist',
'vendor/bin',
+ 'third-party/composer.json',
+ 'scoper.inc.php',
+ ];
+
+ // These will be removed from the Composer build of the plugin prior to creating a ZIP.
+ // ⚠️ Warning: These paths are passed straight to rm command in the shell, without any escaping.
+ const productionComposerExcludedFilePatterns = [
+ 'vendor',
+ 'composer.lock',
+ 'third-party/composer.json',
+ 'scoper.inc.php',
];
grunt.initConfig( {
@@ -81,10 +91,12 @@ module.exports = function( grunt ) {
composer_install: {
command: [
'if [ ! -e build ]; then echo "Run grunt build first."; exit 1; fi',
+ 'mkdir -p build/vendor/bin',
+ 'cp vendor/bin/php-scoper build/vendor/bin/',
'cd build',
'composer install --no-dev -o',
- 'composer remove cweagans/composer-patches --update-no-dev -o',
- 'rm -rf ' + productionVendorExcludedFilePatterns.join( ' ' ),
+ 'COMPOSER_DISCARD_CHANGES=true composer remove --no-interaction --no-scripts --update-no-dev -o cweagans/composer-patches sabberworm/php-css-parser',
+ 'rm -rf ' + ( 'composer' === process.env.BUILD_TYPE ? productionComposerExcludedFilePatterns : productionVendorExcludedFilePatterns ).join( ' ' ),
].join( ' && ' ),
},
create_build_zip: {
@@ -155,6 +167,9 @@ module.exports = function( grunt ) {
paths.push( 'readme.txt' );
paths.push( 'composer.*' ); // Copy in order to be able to do run composer_install.
+ paths.push( 'scoper.inc.php' ); // Copy in order generate scoped Composer dependencies.
+
+ // Also copy recently built assets.
paths.push( 'assets/js/**/*.js' );
paths.push( 'assets/js/**/*.asset.php' );
paths.push( 'assets/css/*.css' );
@@ -164,30 +179,44 @@ module.exports = function( grunt ) {
paths.push( 'assets/css/*.css.map' );
}
+ // Get build version from amp.php.
+ const versionRegex = /(\*\s+Version:\s+)(?\d+(\.\d+)+)(?-\w+)?/;
+ const { groups: matches } = grunt.file.read( 'amp.php' ).match( versionRegex );
+
+ if ( ! matches || ! matches.version ) {
+ throw new Error( 'Plugin version could not be retrieved from amp.php' );
+ }
+
+ const version = matches.version;
+
grunt.config.set( 'copy', {
build: {
src: paths,
dest: 'build',
expand: true,
options: {
- noProcess: [ '*/**', 'LICENSE' ], // That is, only process amp.php and README.md.
+ noProcess: [ '**/*', '!amp.php', '!composer.json' ],
process( content, srcpath ) {
- let matches, version, versionRegex;
- if ( /amp\.php$/.test( srcpath ) ) {
- versionRegex = /(\*\s+Version:\s+)(\d+(\.\d+)+-\w+)/;
-
+ if ( /^amp\.php$/.test( srcpath ) ) {
// If not a stable build (e.g. 0.7.0-beta), amend the version with the git commit and current timestamp.
- matches = content.match( versionRegex );
- if ( matches ) {
- version = matches[ 2 ] + '-' + versionAppend;
- console.log( 'Updating version in amp.php to ' + version ); // eslint-disable-line no-console
- content = content.replace( versionRegex, '$1' + version );
- content = content.replace( /(define\(\s*'AMP__VERSION',\s*')(.+?)(?=')/, '$1' + version );
+ if ( matches.identifier ) {
+ const pluginVersion = version + matches.identifier + '-' + versionAppend;
+ console.log( 'Updating version in amp.php to ' + pluginVersion ); // eslint-disable-line no-console
+ content = content.replace( versionRegex, '$1' + pluginVersion );
+ content = content.replace( /(define\(\s*'AMP__VERSION',\s*')(.+?)(?=')/, '$1' + pluginVersion );
}
// Remove dev mode code blocks.
content = content.replace( /\n\/\/\s*DEV_CODE.+?\n}\n/s, '' );
+
+ if ( 'composer' === process.env.BUILD_TYPE ) {
+ content = content.replace( "require_once AMP__DIR__ . '/vendor/autoload.php';", '' );
+ }
+ } else if ( /^composer\.json$/.test( srcpath ) && 'composer' === process.env.BUILD_TYPE ) {
+ console.log( 'Setting version in composer.json to ' + version ); // eslint-disable-line no-console
+ content = content.replace( /"name": "ampproject\/amp-wp",/, '$&\n "version": "' + version + '",' );
}
+
return content;
},
},
diff --git a/amp.php b/amp.php
index fba64bd65a9..49f61942fe6 100644
--- a/amp.php
+++ b/amp.php
@@ -157,7 +157,7 @@
unset( $_amp_required_extensions, $_amp_missing_extensions, $_amp_required_constructs, $_amp_missing_classes, $_amp_missing_functions, $_amp_required_extension, $_amp_construct_type, $_amp_construct, $_amp_constructs );
// DEV_CODE. This block of code is removed during the build process.
-if ( ! file_exists( AMP__DIR__ . '/vendor/autoload.php' ) || ! file_exists( AMP__DIR__ . '/vendor/sabberworm/php-css-parser' ) || ! file_exists( AMP__DIR__ . '/assets/js/amp-block-editor.js' ) ) {
+if ( ! file_exists( AMP__DIR__ . '/vendor/autoload.php' ) || ! file_exists( AMP__DIR__ . '/third-party/vendor/scoper-autoload.php' ) || ! file_exists( AMP__DIR__ . '/assets/js/amp-block-editor.js' ) ) {
$_amp_load_errors->add(
'build_required',
sprintf(
@@ -251,6 +251,7 @@ function _amp_incorrect_plugin_slug_admin_notice() {
}
require_once AMP__DIR__ . '/vendor/autoload.php';
+require_once AMP__DIR__ . '/third-party/vendor/scoper-autoload.php';
register_activation_hook( __FILE__, 'amp_activate' );
diff --git a/codecov.yml b/codecov.yml
index 34dc93a6d6f..7ba02126fb7 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -42,6 +42,8 @@ comment:
ignore:
- "/bin"
- "/back-compat"
+ - "/third-party"
- "/docs/**/*"
- ".phpstorm.meta.php"
- "/qa-tester/**"
+ - "scoper.inc.php"
diff --git a/composer.json b/composer.json
index 0eb084af1d1..9fde39137af 100644
--- a/composer.json
+++ b/composer.json
@@ -50,6 +50,11 @@
},
"extra": {
"downloads": {
+ "php-scoper": {
+ "path": "vendor/bin/php-scoper",
+ "type": "phar",
+ "url": "https://github.com/humbug/php-scoper/releases/download/0.14.0/php-scoper.phar"
+ },
"phpstan": {
"path": "vendor/bin/phpstan",
"type": "phar",
@@ -91,10 +96,22 @@
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
+ "post-install-cmd": [
+ "@scope-dependencies"
+ ],
+ "post-update-cmd": [
+ "@scope-dependencies"
+ ],
"analyze": "if [ -z $TEST_SKIP_PHPSTAN ]; then phpstan --version; phpstan analyze --ansi; fi",
"pre-commit": [
"npm run lint:staged"
],
- "prepare-tests": "install-package-tests"
+ "prepare-tests": "install-package-tests",
+ "scope-dependencies": [
+ "php-scoper add-prefix --output-dir=third-party --force --quiet",
+ "echo '{ \"autoload\": { \"classmap\": [\"\"] } }' > third-party/composer.json",
+ "composer dump-autoload --working-dir third-party --no-dev --no-plugins --classmap-authoritative",
+ "sed -i'.bak' -e 's/Composer\\\\Autoload/AmpProject\\\\AmpWP\\\\Composer\\\\Autoload/' third-party/vendor/composer/*.php && rm -rf third-party/vendor/composer/*.php.bak"
+ ]
}
}
diff --git a/composer.lock b/composer.lock
index 548fc78c249..bd4d94a86da 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "a6058fda10827da7ccfc7041bdd0c33c",
+ "content-hash": "f73a29684d97e6b2474f5d742dd8e6cc",
"packages": [
{
"name": "ampproject/amp-toolbox",
@@ -12,12 +12,12 @@
"source": {
"type": "git",
"url": "https://github.com/ampproject/amp-toolbox-php.git",
- "reference": "8e1dfacf4f4df8835c6a9ed1d3be8b4a7bf7b92e"
+ "reference": "3c52c66a3e0665d22111d4552e23d61d033ba1d0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ampproject/amp-toolbox-php/zipball/8e1dfacf4f4df8835c6a9ed1d3be8b4a7bf7b92e",
- "reference": "8e1dfacf4f4df8835c6a9ed1d3be8b4a7bf7b92e",
+ "url": "https://api.github.com/repos/ampproject/amp-toolbox-php/zipball/3c52c66a3e0665d22111d4552e23d61d033ba1d0",
+ "reference": "3c52c66a3e0665d22111d4552e23d61d033ba1d0",
"shasum": ""
},
"require": {
@@ -72,7 +72,7 @@
"issues": "https://github.com/ampproject/amp-toolbox-php/issues",
"source": "https://github.com/ampproject/amp-toolbox-php/tree/main"
},
- "time": "2021-04-25T07:16:15+00:00"
+ "time": "2021-04-28T01:26:05+00:00"
},
{
"name": "cweagans/composer-patches",
@@ -229,7 +229,7 @@
"issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues",
"source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/master"
},
- "time": "2021-04-23T05:58:34+00:00"
+ "time": "2021-04-26T15:40:51+00:00"
},
{
"name": "willwashburn/stream",
@@ -286,16 +286,16 @@
"packages-dev": [
{
"name": "automattic/vipwpcs",
- "version": "2.3.1",
+ "version": "2.3.2",
"source": {
"type": "git",
"url": "https://github.com/Automattic/VIP-Coding-Standards.git",
- "reference": "90173cec6f4df2af9a31627f4880874d788459ab"
+ "reference": "efacebef421334d54b99afa92fb8fa645336a8a7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Automattic/VIP-Coding-Standards/zipball/90173cec6f4df2af9a31627f4880874d788459ab",
- "reference": "90173cec6f4df2af9a31627f4880874d788459ab",
+ "url": "https://api.github.com/repos/Automattic/VIP-Coding-Standards/zipball/efacebef421334d54b99afa92fb8fa645336a8a7",
+ "reference": "efacebef421334d54b99afa92fb8fa645336a8a7",
"shasum": ""
},
"require": {
@@ -334,7 +334,7 @@
"source": "https://github.com/Automattic/VIP-Coding-Standards",
"wiki": "https://github.com/Automattic/VIP-Coding-Standards/wiki"
},
- "time": "2021-04-23T14:52:17+00:00"
+ "time": "2021-04-28T16:41:50+00:00"
},
{
"name": "behat/behat",
@@ -1199,16 +1199,16 @@
},
{
"name": "guzzlehttp/psr7",
- "version": "1.8.1",
+ "version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1"
+ "reference": "dc960a912984efb74d0a90222870c72c87f10c91"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1",
- "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91",
+ "reference": "dc960a912984efb74d0a90222870c72c87f10c91",
"shasum": ""
},
"require": {
@@ -1268,9 +1268,9 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/1.8.1"
+ "source": "https://github.com/guzzle/psr7/tree/1.8.2"
},
- "time": "2021-03-21T16:25:00+00:00"
+ "time": "2021-04-26T09:17:50+00:00"
},
{
"name": "mikey179/vfsstream",
@@ -2931,23 +2931,30 @@
},
{
"name": "rmccue/requests",
- "version": "v1.7.0",
+ "version": "v1.8.0",
"source": {
"type": "git",
- "url": "https://github.com/rmccue/Requests.git",
- "reference": "87932f52ffad70504d93f04f15690cf16a089546"
+ "url": "https://github.com/WordPress/Requests.git",
+ "reference": "afbe4790e4def03581c4a0963a1e8aa01f6030f1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/rmccue/Requests/zipball/87932f52ffad70504d93f04f15690cf16a089546",
- "reference": "87932f52ffad70504d93f04f15690cf16a089546",
+ "url": "https://api.github.com/repos/WordPress/Requests/zipball/afbe4790e4def03581c4a0963a1e8aa01f6030f1",
+ "reference": "afbe4790e4def03581c4a0963a1e8aa01f6030f1",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"require-dev": {
- "requests/test-server": "dev-master"
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7",
+ "php-parallel-lint/php-console-highlighter": "^0.5.0",
+ "php-parallel-lint/php-parallel-lint": "^1.3",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5",
+ "requests/test-server": "dev-master",
+ "squizlabs/php_codesniffer": "^3.5",
+ "wp-coding-standards/wpcs": "^2.0"
},
"type": "library",
"autoload": {
@@ -2966,7 +2973,7 @@
}
],
"description": "A HTTP library written in PHP, for human beings.",
- "homepage": "http://github.com/rmccue/Requests",
+ "homepage": "http://github.com/WordPress/Requests",
"keywords": [
"curl",
"fsockopen",
@@ -2977,10 +2984,10 @@
"sockets"
],
"support": {
- "issues": "https://github.com/rmccue/Requests/issues",
- "source": "https://github.com/rmccue/Requests/tree/master"
+ "issues": "https://github.com/WordPress/Requests/issues",
+ "source": "https://github.com/WordPress/Requests/tree/v1.8.0"
},
- "time": "2016-10-13T00:11:37+00:00"
+ "time": "2021-04-27T11:05:25+00:00"
},
{
"name": "roave/security-advisories",
@@ -2988,12 +2995,12 @@
"source": {
"type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git",
- "reference": "3c97c13698c448fdbbda20acb871884a2d8f45b1"
+ "reference": "a9d356baedee32afbb2179a2a61a45b215f8c95e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3c97c13698c448fdbbda20acb871884a2d8f45b1",
- "reference": "3c97c13698c448fdbbda20acb871884a2d8f45b1",
+ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/a9d356baedee32afbb2179a2a61a45b215f8c95e",
+ "reference": "a9d356baedee32afbb2179a2a61a45b215f8c95e",
"shasum": ""
},
"conflict": {
@@ -3021,7 +3028,7 @@
"centreon/centreon": "<18.10.8|>=19,<19.4.5",
"cesnet/simplesamlphp-module-proxystatistics": "<3.1",
"codeigniter/framework": "<=3.0.6",
- "composer/composer": "<=1-alpha.11",
+ "composer/composer": "<1.10.22|>=2-alpha.1,<2.0.13",
"contao-components/mediaelement": ">=2.14.2,<2.21.1",
"contao/core": ">=2,<3.5.39",
"contao/core-bundle": ">=4,<4.4.52|>=4.5,<4.9.6|= 4.10.0",
@@ -3133,7 +3140,7 @@
"paragonie/random_compat": "<2",
"passbolt/passbolt_api": "<2.11",
"paypal/merchant-sdk-php": "<3.12",
- "pear/archive_tar": "<1.4.13",
+ "pear/archive_tar": "<1.4.12",
"personnummer/personnummer": "<3.0.2",
"phpfastcache/phpfastcache": ">=5,<5.0.13",
"phpmailer/phpmailer": "<6.1.6",
@@ -3161,6 +3168,7 @@
"pusher/pusher-php-server": "<2.2.1",
"pwweb/laravel-core": "<=0.3.6-beta",
"rainlab/debugbar-plugin": "<3.1",
+ "rmccue/requests": ">=1.6,<1.8",
"robrichards/xmlseclibs": "<3.0.4",
"sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1",
"sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9",
@@ -3326,7 +3334,7 @@
"type": "tidelift"
}
],
- "time": "2021-04-22T17:19:04+00:00"
+ "time": "2021-04-28T18:10:37+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
diff --git a/includes/options/class-amp-options-manager.php b/includes/options/class-amp-options-manager.php
index 21bd8eb7a40..1698fb07dee 100644
--- a/includes/options/class-amp-options-manager.php
+++ b/includes/options/class-amp-options-manager.php
@@ -43,7 +43,6 @@ class AMP_Options_Manager {
* Sets up hooks.
*/
public static function init() {
- add_action( 'admin_notices', [ __CLASS__, 'render_php_css_parser_conflict_notice' ] );
add_action( 'admin_notices', [ __CLASS__, 'insecure_connection_notice' ] );
add_action( 'admin_notices', [ __CLASS__, 'reader_theme_fallback_notice' ] );
}
@@ -421,48 +420,6 @@ public static function update_options( $options ) {
return update_option( self::OPTION_NAME, $amp_options, false );
}
- /**
- * Render PHP-CSS-Parser conflict notice.
- *
- * @return void
- */
- public static function render_php_css_parser_conflict_notice() {
- $current_screen = get_current_screen();
- if ( ! ( $current_screen instanceof WP_Screen ) || 'toplevel_page_' . self::OPTION_NAME !== $current_screen->id ) {
- return;
- }
-
- if ( AMP_Style_Sanitizer::has_required_php_css_parser() ) {
- return;
- }
-
- try {
- $reflection = new ReflectionClass( 'Sabberworm\CSS\CSSList\CSSList' );
- $source_dir = str_replace(
- trailingslashit( WP_CONTENT_DIR ),
- '',
- preg_replace( '#/vendor/sabberworm/.+#', '', $reflection->getFileName() )
- );
-
- printf(
- '',
- wp_kses(
- sprintf(
- /* translators: %s: path to the conflicting library */
- __( 'A conflicting version of PHP-CSS-Parser appears to be installed by another plugin or theme (located in %s). Because of this, CSS processing will be limited, and tree shaking will not be available.', 'amp' ),
- '' . esc_html( $source_dir ) . '
'
- ),
- [ 'code' => [] ]
- )
- );
- } catch ( ReflectionException $e ) {
- printf(
- '',
- esc_html__( 'PHP-CSS-Parser is not available so CSS processing will not be available.', 'amp' )
- );
- }
- }
-
/**
* Outputs an admin notice if the site is not served over HTTPS.
*
diff --git a/includes/sanitizers/class-amp-style-sanitizer.php b/includes/sanitizers/class-amp-style-sanitizer.php
index 28658d89112..d005fbbced6 100644
--- a/includes/sanitizers/class-amp-style-sanitizer.php
+++ b/includes/sanitizers/class-amp-style-sanitizer.php
@@ -13,21 +13,24 @@
use AmpProject\Dom\Document;
use AmpProject\Exception\FailedToGetFromRemoteUrl;
use AmpProject\RemoteGetRequest;
-use Sabberworm\CSS\RuleSet\DeclarationBlock;
-use Sabberworm\CSS\CSSList\CSSList;
-use Sabberworm\CSS\Property\Selector;
-use Sabberworm\CSS\RuleSet\RuleSet;
-use Sabberworm\CSS\Property\AtRule;
-use Sabberworm\CSS\Rule\Rule;
-use Sabberworm\CSS\CSSList\KeyFrame;
-use Sabberworm\CSS\RuleSet\AtRuleSet;
-use Sabberworm\CSS\OutputFormat;
-use Sabberworm\CSS\Property\Import;
-use Sabberworm\CSS\CSSList\AtRuleBlockList;
-use Sabberworm\CSS\Value\RuleValueList;
-use Sabberworm\CSS\Value\URL;
-use Sabberworm\CSS\Value\Value;
-use Sabberworm\CSS\CSSList\Document as CSSDocument;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\RuleSet\DeclarationBlock;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\CSSList\CSSList;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\Property\Selector;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\RuleSet\RuleSet;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\Property\AtRule;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\Rule\Rule;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\CSSList\KeyFrame;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\RuleSet\AtRuleSet;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\OutputFormat;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\Property\Import;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\CSSList\AtRuleBlockList;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\Value\RuleValueList;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\Value\URL;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\Value\Value;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\CSSList\Document as CSSDocument;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\Settings as CSSSettings;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\Parser as CSSParser;
+use AmpProject\AmpWP\ScopedDependencies\Sabberworm\CSS\OutputFormat as CSSOutputFormat;
/**
* Class AMP_Style_Sanitizer
@@ -376,6 +379,8 @@ public static function get_css_parser_validation_error_codes() {
/**
* Determine whether the version of PHP-CSS-Parser loaded has all required features for tree shaking and CSS processing.
*
+ * @codeCoverageIgnore
+ * @deprecated As of v2.1 a patched version of PHP-CSS-Parser is now bundled with the plugin.
* @since 1.0.2
*
* @return bool Returns true if the plugin's forked version of PHP-CSS-Parser is loaded by Composer.
@@ -1803,8 +1808,8 @@ private function create_validated_css_document( $stylesheet_string, $options ) {
// Remove spaces from data URLs, which cause errors and PHP-CSS-Parser can't handle them.
$stylesheet_string = $this->remove_spaces_from_url_values( $stylesheet_string );
- $parser_settings = Sabberworm\CSS\Settings::create();
- $css_parser = new Sabberworm\CSS\Parser( $stylesheet_string, $parser_settings );
+ $parser_settings = CSSSettings::create();
+ $css_parser = new CSSParser( $stylesheet_string, $parser_settings );
$css_document = $css_parser->parse(); // @todo If 'utf-8' is not $css_parser->getCharset() then issue warning?
if ( ! empty( $options['stylesheet_url'] ) ) {
@@ -1904,7 +1909,7 @@ private function parse_stylesheet( $stylesheet_string, $options = [] ) {
if ( ! empty( $parsed_stylesheet['css_document'] ) ) {
$css_document = $parsed_stylesheet['css_document'];
- $output_format = Sabberworm\CSS\OutputFormat::createCompact();
+ $output_format = CSSOutputFormat::createCompact();
$output_format->setSemicolonAfterLastRule( false );
$before_declaration_block = sprintf( '/*%s*/', chr( 1 ) );
@@ -1915,15 +1920,12 @@ private function parse_stylesheet( $stylesheet_string, $options = [] ) {
$before_at_rule = sprintf( '/*%s*/', chr( 6 ) );
$after_at_rule = sprintf( '/*%s*/', chr( 7 ) );
- // Add comments to stylesheet if PHP-CSS-Parser has the required extensions for tree shaking.
- if ( self::has_required_php_css_parser() ) {
- $output_format->set( 'BeforeDeclarationBlock', $before_declaration_block );
- $output_format->set( 'SpaceBeforeSelectorSeparator', $between_selectors );
- $output_format->set( 'AfterDeclarationBlockSelectors', $after_declaration_block_selectors );
- $output_format->set( 'AfterDeclarationBlock', $after_declaration_block );
- $output_format->set( 'BeforeAtRuleBlock', $before_at_rule );
- $output_format->set( 'AfterAtRuleBlock', $after_at_rule );
- }
+ $output_format->set( 'BeforeDeclarationBlock', $before_declaration_block );
+ $output_format->set( 'SpaceBeforeSelectorSeparator', $between_selectors );
+ $output_format->set( 'AfterDeclarationBlockSelectors', $after_declaration_block_selectors );
+ $output_format->set( 'AfterDeclarationBlock', $after_declaration_block );
+ $output_format->set( 'BeforeAtRuleBlock', $before_at_rule );
+ $output_format->set( 'AfterAtRuleBlock', $after_at_rule );
$output_format->set( 'SpaceBetweenRules', $between_properties );
$stylesheet_string = $css_document->render( $output_format );
diff --git a/includes/validation/class-amp-validated-url-post-type.php b/includes/validation/class-amp-validated-url-post-type.php
index 9284334d7eb..fc076295564 100644
--- a/includes/validation/class-amp-validated-url-post-type.php
+++ b/includes/validation/class-amp-validated-url-post-type.php
@@ -2341,14 +2341,6 @@ static function ( $a, $b ) use ( $stylesheets ) {
?>
-
-
-
-
diff --git a/package.json b/package.json
index 7b7d9a95f18..3c98ca8eb7d 100644
--- a/package.json
+++ b/package.json
@@ -94,8 +94,9 @@
"webpackbar": "4.0.0"
},
"scripts": {
- "build:dev": "cross-env NODE_ENV=development npm-run-all 'build:!(dev|prod)'",
- "build:prod": "cross-env NODE_ENV=production npm-run-all 'build:!(dev|prod)'",
+ "build:dev": "cross-env NODE_ENV=development npm-run-all 'build:!(dev|prod|composer)'",
+ "build:prod": "cross-env NODE_ENV=production npm-run-all 'build:!(dev|prod|composer)'",
+ "build:composer": "cross-env NODE_ENV=production BUILD_TYPE=composer npm-run-all 'build:!(dev|prod|composer)'",
"build:prepare": "grunt clean",
"build:js": "wp-scripts build",
"build:run": "grunt build",
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 210521e26d4..7977834706e 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -26,6 +26,7 @@ parameters:
- %currentWorkingDirectory%/tests/php/static-analysis-stubs/twentyseventeen.php
- %currentWorkingDirectory%/tests/php/static-analysis-stubs/legacy-i18n.php
- %currentWorkingDirectory%/vendor/autoload.php
+ - %currentWorkingDirectory%/third-party/vendor/scoper-autoload.php
- %currentWorkingDirectory%/amp.php
- %currentWorkingDirectory%/includes/amp-frontend-actions.php
- %currentWorkingDirectory%/includes/amp-post-template-functions.php
diff --git a/scoper.inc.php b/scoper.inc.php
new file mode 100644
index 00000000000..b49fc4dfd4c
--- /dev/null
+++ b/scoper.inc.php
@@ -0,0 +1,73 @@
+ 'AmpProject\\AmpWP\\ScopedDependencies',
+
+ // By default when running php-scoper add-prefix, it will prefix all relevant code found in the current working
+ // directory. You can however define which files should be scoped by defining a collection of Finders in the
+ // following configuration key.
+ //
+ // For more see: https://github.com/humbug/php-scoper#finders-and-paths.
+ 'finders' => [
+ Finder::create()
+ ->files()
+ ->ignoreVCS( true )
+ ->ignoreDotFiles( true )
+ ->name( '*.php' )
+ ->exclude( [ 'tests' ] )
+ ->in( 'vendor/sabberworm/php-css-parser' )
+ ->append( [ 'vendor/sabberworm/php-css-parser/composer.json' ] ),
+
+ // Main composer.json file so that we can build a classmap.
+ Finder::create()
+ ->append( [ 'composer.json' ] ),
+ ],
+
+ // Whitelists a list of files. Unlike the other whitelist related features, this one is about completely leaving
+ // a file untouched.
+ // Paths are relative to the configuration file unless if they are already absolute.
+ 'files-whitelist' => [],
+
+ // When scoping PHP files, there will be scenarios where some of the code being scoped indirectly references the
+ // original namespace. These will include, for example, strings or string manipulations. PHP-Scoper has limited
+ // support for prefixing such strings. To circumvent that, you can define patchers to manipulate the file to your
+ // heart contents.
+ //
+ // For more see: https://github.com/humbug/php-scoper#patchers.
+ 'patchers' => [
+ function ( $filePath, $prefix, $contents ) { //phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
+ // Change the contents here.
+
+ return $contents;
+ },
+ ],
+
+ // PHP-Scoper's goal is to make sure that all code for a project lies in a distinct PHP namespace. However, you
+ // may want to share a common API between the bundled code of your PHAR and the consumer code. For example if
+ // you have a PHPUnit PHAR with isolated code, you still want the PHAR to be able to understand the
+ // PHPUnit\Framework\TestCase class.
+ //
+ // A way to achieve this is by specifying a list of classes to not prefix with the following configuration key. Note
+ // that this does not work with functions or constants neither with classes belonging to the global namespace.
+ //
+ // Fore more see https://github.com/humbug/php-scoper#whitelist.
+ 'whitelist' => [],
+
+ // If `true` then the user defined constants belonging to the global namespace will not be prefixed.
+ //
+ // For more see https://github.com/humbug/php-scoper#constants--constants--functions-from-the-global-namespace.
+ 'whitelist-global-constants' => false,
+
+ // If `true` then the user defined classes belonging to the global namespace will not be prefixed.
+ //
+ // For more see https://github.com/humbug/php-scoper#constants--constants--functions-from-the-global-namespace.
+ 'whitelist-global-classes' => false,
+
+ // If `true` then the user defined functions belonging to the global namespace will not be prefixed.
+ //
+ // For more see https://github.com/humbug/php-scoper#constants--constants--functions-from-the-global-namespace.
+ 'whitelist-global-functions' => false,
+];
diff --git a/tests/php/test-class-amp-options-manager.php b/tests/php/test-class-amp-options-manager.php
index 49ec10fe91c..7a46e2f7fbf 100644
--- a/tests/php/test-class-amp-options-manager.php
+++ b/tests/php/test-class-amp-options-manager.php
@@ -73,7 +73,6 @@ public function test_constants() {
*/
public function test_init() {
AMP_Options_Manager::init();
- $this->assertEquals( 10, has_action( 'admin_notices', [ AMP_Options_Manager::class, 'render_php_css_parser_conflict_notice' ] ) );
$this->assertEquals( 10, has_action( 'admin_notices', [ AMP_Options_Manager::class, 'insecure_connection_notice' ] ) );
$this->assertEquals( 10, has_action( 'admin_notices', [ AMP_Options_Manager::class, 'reader_theme_fallback_notice' ] ) );
}
@@ -711,17 +710,6 @@ public function test_get_options_theme_support_defaults( $args, $expected_mode,
$this->assertEquals( $expected_mode, AMP_Options_Manager::get_option( Option::THEME_SUPPORT ) );
}
- /** @covers AMP_Options_Manager::render_php_css_parser_conflict_notice() */
- public function test_render_php_css_parser_conflict_notice() {
- $this->assertEmpty( get_echo( [ 'AMP_Options_Manager', 'render_php_css_parser_conflict_notice' ] ) );
-
- set_current_screen( 'themes' );
- $this->assertEmpty( get_echo( [ 'AMP_Options_Manager', 'render_php_css_parser_conflict_notice' ] ) );
-
- set_current_screen( 'toplevel_page_' . AMP_Options_Manager::OPTION_NAME );
- $this->assertEmpty( get_echo( [ 'AMP_Options_Manager', 'render_php_css_parser_conflict_notice' ] ) );
- }
-
/** @covers AMP_Options_Manager::insecure_connection_notice() */
public function test_insecure_connection_notice() {
$_SERVER['HTTPS'] = false;
|