diff --git a/composer.json b/composer.json
index 0a51aa054..2288f29bc 100644
--- a/composer.json
+++ b/composer.json
@@ -4,6 +4,12 @@
"homepage": "https://wordpress.org/plugins/stream/",
"type": "wordpress-plugin",
"license": "GPL-2.0-or-later",
+ "repositories": [
+ {
+ "type":"composer",
+ "url":"https://wpackagist.org"
+ }
+ ],
"require": {
"composer/installers": "~1.0"
},
@@ -15,7 +21,8 @@
"wp-cli/wp-cli-bundle": "^2.2",
"wp-coding-standards/wpcs": "^2.2",
"wp-phpunit/wp-phpunit": "^5.4",
- "wpsh/local": "^0.2.3"
+ "wpsh/local": "^0.2.3",
+ "wpackagist-plugin/advanced-custom-fields": "5.8.12"
},
"config": {
"process-timeout": 600,
@@ -25,7 +32,10 @@
}
},
"extra": {
- "wordpress-install-dir": "local/public"
+ "wordpress-install-dir": "local/public",
+ "installer-paths": {
+ "local/public/wp-content/plugins/{$name}/": ["type:wordpress-plugin"]
+ }
},
"scripts": {
"release": [
diff --git a/composer.lock b/composer.lock
index 58d193226..23dea658e 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": "74043f691d06bd00f61066eec761aa80",
+ "content-hash": "028b548fadf428b765cbcfc049cc00b2",
"packages": [
{
"name": "composer/installers",
@@ -137,30 +137,30 @@
"packages-dev": [
{
"name": "automattic/vipwpcs",
- "version": "2.0.0",
+ "version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/Automattic/VIP-Coding-Standards.git",
- "reference": "fc02f491dc9f51da7c32941ac579f70b9ed300c5"
+ "reference": "03e75ddd0261b675dece60fb67fc2e9c6af4ad35"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Automattic/VIP-Coding-Standards/zipball/fc02f491dc9f51da7c32941ac579f70b9ed300c5",
- "reference": "fc02f491dc9f51da7c32941ac579f70b9ed300c5",
+ "url": "https://api.github.com/repos/Automattic/VIP-Coding-Standards/zipball/03e75ddd0261b675dece60fb67fc2e9c6af4ad35",
+ "reference": "03e75ddd0261b675dece60fb67fc2e9c6af4ad35",
"shasum": ""
},
"require": {
- "php": ">=5.6",
- "squizlabs/php_codesniffer": "^3.3.1",
- "wp-coding-standards/wpcs": "^2.1"
+ "php": ">=5.4",
+ "squizlabs/php_codesniffer": "^3.5.5",
+ "wp-coding-standards/wpcs": "^2.3"
},
"require-dev": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5",
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7",
"phpcompatibility/php-compatibility": "^9",
- "phpunit/phpunit": "^5 || ^6 || ^7"
+ "phpunit/phpunit": "^4 || ^5 || ^6 || ^7"
},
"suggest": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically."
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will manage the PHPCS 'installed_paths' automatically."
},
"type": "phpcodesniffer-standard",
"notification-url": "https://packagist.org/downloads/",
@@ -179,7 +179,7 @@
"standards",
"wordpress"
],
- "time": "2019-07-12T08:47:36+00:00"
+ "time": "2020-07-07T07:48:04+00:00"
},
{
"name": "composer/ca-bundle",
@@ -239,16 +239,16 @@
},
{
"name": "composer/composer",
- "version": "1.10.8",
+ "version": "1.10.10",
"source": {
"type": "git",
"url": "https://github.com/composer/composer.git",
- "reference": "56e0e094478f30935e9128552188355fa9712291"
+ "reference": "32966a3b1d48bc01472a8321fd6472b44fad033a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/composer/zipball/56e0e094478f30935e9128552188355fa9712291",
- "reference": "56e0e094478f30935e9128552188355fa9712291",
+ "url": "https://api.github.com/repos/composer/composer/zipball/32966a3b1d48bc01472a8321fd6472b44fad033a",
+ "reference": "32966a3b1d48bc01472a8321fd6472b44fad033a",
"shasum": ""
},
"require": {
@@ -315,7 +315,21 @@
"dependency",
"package"
],
- "time": "2020-06-24T19:23:30+00:00"
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-08-03T09:35:19+00:00"
},
{
"name": "composer/semver",
@@ -380,16 +394,16 @@
},
{
"name": "composer/spdx-licenses",
- "version": "1.5.3",
+ "version": "1.5.4",
"source": {
"type": "git",
"url": "https://github.com/composer/spdx-licenses.git",
- "reference": "0c3e51e1880ca149682332770e25977c70cf9dae"
+ "reference": "6946f785871e2314c60b4524851f3702ea4f2223"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/0c3e51e1880ca149682332770e25977c70cf9dae",
- "reference": "0c3e51e1880ca149682332770e25977c70cf9dae",
+ "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/6946f785871e2314c60b4524851f3702ea4f2223",
+ "reference": "6946f785871e2314c60b4524851f3702ea4f2223",
"shasum": ""
},
"require": {
@@ -436,7 +450,21 @@
"spdx",
"validator"
],
- "time": "2020-02-14T07:44:31+00:00"
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-15T15:35:07+00:00"
},
{
"name": "composer/xdebug-handler",
@@ -1265,6 +1293,55 @@
],
"time": "2013-02-24T15:01:54+00:00"
},
+ {
+ "name": "paragonie/random_compat",
+ "version": "v2.0.18",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "0a58ef6e3146256cc3dc7cc393927bcc7d1b72db"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/0a58ef6e3146256cc3dc7cc393927bcc7d1b72db",
+ "reference": "0a58ef6e3146256cc3dc7cc393927bcc7d1b72db",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "lib/random.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "polyfill",
+ "pseudorandom",
+ "random"
+ ],
+ "time": "2019-01-03T20:59:08+00:00"
+ },
{
"name": "php-coveralls/php-coveralls",
"version": "v2.2.0",
@@ -2698,16 +2775,16 @@
},
{
"name": "seld/phar-utils",
- "version": "1.1.0",
+ "version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/phar-utils.git",
- "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0"
+ "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8800503d56b9867d43d9c303b9cbcc26016e82f0",
- "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0",
+ "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8674b1d84ffb47cc59a101f5d5a3b61e87d23796",
+ "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796",
"shasum": ""
},
"require": {
@@ -2738,7 +2815,7 @@
"keywords": [
"phar"
],
- "time": "2020-02-14T15:25:33+00:00"
+ "time": "2020-07-07T18:42:57+00:00"
},
{
"name": "squizlabs/php_codesniffer",
@@ -2793,16 +2870,16 @@
},
{
"name": "symfony/config",
- "version": "v3.4.42",
+ "version": "v3.4.43",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "cd61db31cbd19cbe4ba9f6968f13c9076e1372ab"
+ "reference": "9e2aa97f0d51f114983666f5aa362426d53e004a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/cd61db31cbd19cbe4ba9f6968f13c9076e1372ab",
- "reference": "cd61db31cbd19cbe4ba9f6968f13c9076e1372ab",
+ "url": "https://api.github.com/repos/symfony/config/zipball/9e2aa97f0d51f114983666f5aa362426d53e004a",
+ "reference": "9e2aa97f0d51f114983666f5aa362426d53e004a",
"shasum": ""
},
"require": {
@@ -2853,20 +2930,34 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2020-05-22T10:56:48+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-23T09:37:51+00:00"
},
{
"name": "symfony/console",
- "version": "v3.4.42",
+ "version": "v3.4.43",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "bfe29ead7e7b1cc9ce74c6a40d06ad1f96fced13"
+ "reference": "afc7189694d2c59546cf24ea606a236fa46a966e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/bfe29ead7e7b1cc9ce74c6a40d06ad1f96fced13",
- "reference": "bfe29ead7e7b1cc9ce74c6a40d06ad1f96fced13",
+ "url": "https://api.github.com/repos/symfony/console/zipball/afc7189694d2c59546cf24ea606a236fa46a966e",
+ "reference": "afc7189694d2c59546cf24ea606a236fa46a966e",
"shasum": ""
},
"require": {
@@ -2925,20 +3016,34 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2020-05-30T18:58:05+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-06T08:57:31+00:00"
},
{
"name": "symfony/debug",
- "version": "v3.4.42",
+ "version": "v3.4.43",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "518c6a00d0872da30bd06aee3ea59a0a5cf54d6d"
+ "reference": "7ce874f4432d8b11cc45a80cc5130a6e2609728d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/518c6a00d0872da30bd06aee3ea59a0a5cf54d6d",
- "reference": "518c6a00d0872da30bd06aee3ea59a0a5cf54d6d",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/7ce874f4432d8b11cc45a80cc5130a6e2609728d",
+ "reference": "7ce874f4432d8b11cc45a80cc5130a6e2609728d",
"shasum": ""
},
"require": {
@@ -2981,11 +3086,25 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2020-05-22T18:25:20+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-16T09:41:49+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v3.4.42",
+ "version": "v3.4.43",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
@@ -3031,11 +3150,25 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
"time": "2020-05-30T17:48:24+00:00"
},
{
"name": "symfony/finder",
- "version": "v3.4.42",
+ "version": "v3.4.43",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
@@ -3080,20 +3213,34 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
"time": "2020-02-14T07:34:21+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.17.1",
+ "version": "v1.18.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d"
+ "reference": "1c302646f6efc070cd46856e600e5e0684d6b454"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d",
- "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454",
+ "reference": "1c302646f6efc070cd46856e600e5e0684d6b454",
"shasum": ""
},
"require": {
@@ -3105,7 +3252,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.17-dev"
+ "dev-master": "1.18-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -3142,25 +3289,40 @@
"polyfill",
"portable"
],
- "time": "2020-06-06T08:46:27+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-14T12:35:20+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
- "version": "v1.17.1",
+ "version": "v1.18.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
- "reference": "a57f8161502549a742a63c09f0a604997bf47027"
+ "reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a57f8161502549a742a63c09f0a604997bf47027",
- "reference": "a57f8161502549a742a63c09f0a604997bf47027",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/5dcab1bc7146cf8c1beaa4502a3d9be344334251",
+ "reference": "5dcab1bc7146cf8c1beaa4502a3d9be344334251",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
- "symfony/polyfill-mbstring": "^1.3",
+ "symfony/polyfill-intl-normalizer": "^1.10",
+ "symfony/polyfill-php70": "^1.10",
"symfony/polyfill-php72": "^1.10"
},
"suggest": {
@@ -3169,7 +3331,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.17-dev"
+ "dev-master": "1.18-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -3193,6 +3355,10 @@
"name": "Laurent Bassin",
"email": "laurent@bassin.info"
},
+ {
+ "name": "Trevor Rowbotham",
+ "email": "trevor.rowbotham@pm.me"
+ },
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
@@ -3208,20 +3374,115 @@
"portable",
"shim"
],
- "time": "2020-06-06T08:46:27+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-08-04T06:02:08+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.18.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e",
+ "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.18-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-14T12:35:20+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.17.1",
+ "version": "v1.18.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "7110338d81ce1cbc3e273136e4574663627037a7"
+ "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7110338d81ce1cbc3e273136e4574663627037a7",
- "reference": "7110338d81ce1cbc3e273136e4574663627037a7",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a6977d63bf9a0ad4c65cd352709e230876f9904a",
+ "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a",
"shasum": ""
},
"require": {
@@ -3233,7 +3494,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.17-dev"
+ "dev-master": "1.18-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -3271,20 +3532,111 @@
"portable",
"shim"
],
- "time": "2020-06-06T08:46:27+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-14T12:35:20+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php70",
+ "version": "v1.18.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php70.git",
+ "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0dd93f2c578bdc9c72697eaa5f1dd25644e618d3",
+ "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3",
+ "shasum": ""
+ },
+ "require": {
+ "paragonie/random_compat": "~1.0|~2.0|~9.99",
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.18-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Php70\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ],
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-14T12:35:20+00:00"
},
{
"name": "symfony/polyfill-php72",
- "version": "v1.17.0",
+ "version": "v1.18.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
- "reference": "f048e612a3905f34931127360bdd2def19a5e582"
+ "reference": "639447d008615574653fb3bc60d1986d7172eaae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582",
- "reference": "f048e612a3905f34931127360bdd2def19a5e582",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/639447d008615574653fb3bc60d1986d7172eaae",
+ "reference": "639447d008615574653fb3bc60d1986d7172eaae",
"shasum": ""
},
"require": {
@@ -3293,7 +3645,11 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.17-dev"
+ "dev-master": "1.18-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
@@ -3326,20 +3682,34 @@
"portable",
"shim"
],
- "time": "2020-05-12T16:47:27+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-14T12:35:20+00:00"
},
{
"name": "symfony/process",
- "version": "v3.4.42",
+ "version": "v3.4.43",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "8a895f0c92a7c4b10db95139bcff71bdf66d4d21"
+ "reference": "af8d812d75fcdf2eae30928b42396fe17df137e4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/8a895f0c92a7c4b10db95139bcff71bdf66d4d21",
- "reference": "8a895f0c92a7c4b10db95139bcff71bdf66d4d21",
+ "url": "https://api.github.com/repos/symfony/process/zipball/af8d812d75fcdf2eae30928b42396fe17df137e4",
+ "reference": "af8d812d75fcdf2eae30928b42396fe17df137e4",
"shasum": ""
},
"require": {
@@ -3375,11 +3745,25 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2020-05-23T17:05:51+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-16T09:41:49+00:00"
},
{
"name": "symfony/stopwatch",
- "version": "v3.4.42",
+ "version": "v3.4.43",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
@@ -3424,20 +3808,34 @@
],
"description": "Symfony Stopwatch Component",
"homepage": "https://symfony.com",
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
"time": "2020-03-15T09:38:08+00:00"
},
{
"name": "symfony/yaml",
- "version": "v3.4.42",
+ "version": "v3.4.43",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "7233ac2bfdde24d672f5305f2b3f6b5d741ef8eb"
+ "reference": "e7fa05917ae931332a42d65b577ece4d497aad81"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/7233ac2bfdde24d672f5305f2b3f6b5d741ef8eb",
- "reference": "7233ac2bfdde24d672f5305f2b3f6b5d741ef8eb",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/e7fa05917ae931332a42d65b577ece4d497aad81",
+ "reference": "e7fa05917ae931332a42d65b577ece4d497aad81",
"shasum": ""
},
"require": {
@@ -3483,24 +3881,38 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2020-05-11T07:51:54+00:00"
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-07-23T09:37:51+00:00"
},
{
"name": "webmozart/assert",
- "version": "1.9.0",
+ "version": "1.9.1",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
- "reference": "9dc4f203e36f2b486149058bade43c851dd97451"
+ "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/9dc4f203e36f2b486149058bade43c851dd97451",
- "reference": "9dc4f203e36f2b486149058bade43c851dd97451",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
+ "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0",
+ "php": "^5.3.3 || ^7.0 || ^8.0",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
@@ -3532,7 +3944,7 @@
"check",
"validate"
],
- "time": "2020-06-16T10:16:42+00:00"
+ "time": "2020-07-08T17:02:28+00:00"
},
{
"name": "wp-cli/cache-command",
@@ -4402,16 +4814,16 @@
},
{
"name": "wp-cli/i18n-command",
- "version": "v2.2.4",
+ "version": "v2.2.5",
"source": {
"type": "git",
"url": "https://github.com/wp-cli/i18n-command.git",
- "reference": "9784ff2c074d1765442b618e6d3a43fee2093a05"
+ "reference": "b02ecdc9a57f9633740c254d19749118b7411f0f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/wp-cli/i18n-command/zipball/9784ff2c074d1765442b618e6d3a43fee2093a05",
- "reference": "9784ff2c074d1765442b618e6d3a43fee2093a05",
+ "url": "https://api.github.com/repos/wp-cli/i18n-command/zipball/b02ecdc9a57f9633740c254d19749118b7411f0f",
+ "reference": "b02ecdc9a57f9633740c254d19749118b7411f0f",
"shasum": ""
},
"require": {
@@ -4455,7 +4867,7 @@
],
"description": "Provides internationalization tools for WordPress projects.",
"homepage": "https://github.com/wp-cli/i18n-command",
- "time": "2020-06-12T00:17:09+00:00"
+ "time": "2020-07-08T15:20:38+00:00"
},
{
"name": "wp-cli/import-command",
@@ -5589,6 +6001,24 @@
],
"time": "2020-04-01T14:35:27+00:00"
},
+ {
+ "name": "wpackagist-plugin/advanced-custom-fields",
+ "version": "5.8.12",
+ "source": {
+ "type": "svn",
+ "url": "https://plugins.svn.wordpress.org/advanced-custom-fields/",
+ "reference": "tags/5.8.12"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://downloads.wordpress.org/plugin/advanced-custom-fields.5.8.12.zip"
+ },
+ "require": {
+ "composer/installers": "~1.0"
+ },
+ "type": "wordpress-plugin",
+ "homepage": "https://wordpress.org/plugins/advanced-custom-fields/"
+ },
{
"name": "wpsh/local",
"version": "0.2.3",
diff --git a/connectors/class-connector-acf.php b/connectors/class-connector-acf.php
index 7a9f4302a..431d5d965 100644
--- a/connectors/class-connector-acf.php
+++ b/connectors/class-connector-acf.php
@@ -31,6 +31,8 @@ class Connector_ACF extends Connector {
* @var array
*/
public $actions = array(
+ 'save_post',
+ 'post_updated',
'added_post_meta',
'updated_post_meta',
'delete_post_meta',
@@ -147,13 +149,210 @@ public function action_links( $links, $record ) {
return $links;
}
+ /**
+ * Tracks the creation of custom field group fields and settings (ACF v5+ only)
+ *
+ * @action save_post
+ *
+ * @param int $post_id Post ID.
+ * @param WP_Post $post Post object.
+ * @param bool $update Whether this is an existing post being updated or not.
+ */
+ public function callback_save_post( $post_id, $post, $update ) {
+ // Bail if updating existing post.
+ if ( false !== $update ) {
+ return;
+ }
+
+ // Log new ACF field additions to field groups.
+ if ( 'acf-field' === $post->post_type ) {
+ $parent = get_post( $post->post_parent );
+ if ( $parent ) {
+ $this->log_prop( 'added', $post_id, $post, 'parent', $parent );
+ }
+ } elseif ( 'acf-field-group' === $post->post_type ) {
+ $props = maybe_unserialize( $post->post_content );
+
+ if ( ! empty( $props ) && is_array( $props ) ) {
+ foreach ( $props as $prop => $value ) {
+ $this->log_prop( 'added', $post_id, $post, $prop, $value );
+ }
+ }
+ }
+ }
+
+ /**
+ * Tracks changes to custom field groups settings.
+ *
+ * @action post_updated
+ *
+ * @param int $post_id Post ID.
+ * @param \WP_Post $posts_after Newly saved post object.
+ * @param \WP_Post $posts_before Old post object.
+ * @return void
+ */
+ public function callback_post_updated( $post_id, $posts_after, $posts_before ) {
+ if ( 'acf-field-group' !== $posts_after->post_type ) {
+ return;
+ }
+
+ $_new = ! empty( $posts_after->post_content ) ? maybe_unserialize( $posts_after->post_content ) : array();
+ $_old = ! empty( $posts_before->post_content ) ? maybe_unserialize( $posts_before->post_content ) : array();
+
+ // Get updated settings.
+ $updated_keys = $this->get_changed_keys( $_new, $_old );
+ $updated_keys = empty( $updated_keys ) ? array_keys( $_new ) : $updated_keys;
+
+ // Process updated properties.
+ foreach ( $updated_keys as $prop ) {
+ $old_value = null;
+ $value = $_new[ $prop ];
+ if ( empty( $value ) && is_array( $_old ) && ! empty( $_old[ $prop ] ) ) {
+ $action = 'deleted';
+ $old_value = $_old[ $prop ];
+ } else {
+ $action = 'updated';
+ }
+
+ $this->log_prop( $action, $post_id, $posts_after, $prop, $value, $old_value );
+ }
+ }
+
+
+ /**
+ * Logs field/field group property changes (ACF v5 only).
+ *
+ * @param string $action Added, updated, deleted.
+ * @param int $post_id Post ID.
+ * @param WP_Post $post Post object.
+ * @param string $property ACF property.
+ * @param mixed|null $value Value assigned to property.
+ * @param mixed|null $old_value Old value previously assigned to property.
+ * @return void
+ */
+ public function log_prop( $action, $post_id, $post, $property, $value = null, $old_value = null ) {
+ $action_labels = $this->get_action_labels();
+
+ // Fields.
+ if ( 'parent' === $property ) {
+ if ( 'deleted' === $action ) {
+ $meta_value = $old_value;
+ }
+
+ $this->log(
+ /* translators: %1$s: field label, %2$s: form title, %3$s: action (e.g. "Message", "Contact", "Created") */
+ esc_html_x( '"%1$s" field in "%2$s" %3$s', 'acf', 'stream' ),
+ array(
+ 'label' => $post->post_title,
+ 'title' => $value->post_title,
+ 'action' => strtolower( $action_labels[ $action ] ),
+ 'key' => $post->post_name,
+ 'name' => $post->post_excerpt,
+ ),
+ $value->ID,
+ 'fields',
+ $action
+ );
+ } elseif ( 'position' === $property ) {
+ if ( 'deleted' === $action ) {
+ return;
+ }
+
+ $options = array(
+ 'acf_after_title' => esc_html_x( 'High (after title)', 'acf', 'stream' ),
+ 'normal' => esc_html_x( 'Normal (after content)', 'acf', 'stream' ),
+ 'side' => esc_html_x( 'Side', 'acf', 'stream' ),
+ );
+
+ $this->log(
+ /* translators: %1$s: form title, %2$s a position (e.g. "Contact", "Side") */
+ esc_html_x( 'Position of "%1$s" updated to "%2$s"', 'acf', 'stream' ),
+ array(
+ 'title' => $post->post_title,
+ 'option_label' => $options[ $value ],
+ 'option' => $property,
+ 'option_value' => $value,
+ ),
+ $post_id,
+ 'options',
+ 'updated'
+ );
+ } elseif ( 'layout' === $property ) {
+ if ( 'deleted' === $action ) {
+ return;
+ }
+
+ $options = array(
+ 'no_box' => esc_html_x( 'Seamless (no metabox)', 'acf', 'stream' ),
+ 'default' => esc_html_x( 'Standard (WP metabox)', 'acf', 'stream' ),
+ );
+
+ $this->log(
+ /* translators: %1$s: form title, %2$s a layout (e.g. "Contact", "Seamless") */
+ esc_html_x( 'Style of "%1$s" updated to "%2$s"', 'acf', 'stream' ),
+ array(
+ 'title' => $post->post_title,
+ 'option_label' => $options[ $value ],
+ 'option' => $property,
+ 'option_value' => $value,
+ ),
+ $post_id,
+ 'options',
+ 'updated'
+ );
+ } elseif ( 'hide_on_screen' === $property ) {
+ if ( 'deleted' === $action ) {
+ return;
+ }
+
+ $options = array(
+ 'permalink' => esc_html_x( 'Permalink', 'acf', 'stream' ),
+ 'the_content' => esc_html_x( 'Content Editor', 'acf', 'stream' ),
+ 'excerpt' => esc_html_x( 'Excerpt', 'acf', 'stream' ),
+ 'custom_fields' => esc_html_x( 'Custom Fields', 'acf', 'stream' ),
+ 'discussion' => esc_html_x( 'Discussion', 'acf', 'stream' ),
+ 'comments' => esc_html_x( 'Comments', 'acf', 'stream' ),
+ 'revisions' => esc_html_x( 'Revisions', 'acf', 'stream' ),
+ 'slug' => esc_html_x( 'Slug', 'acf', 'stream' ),
+ 'author' => esc_html_x( 'Author', 'acf', 'stream' ),
+ 'format' => esc_html_x( 'Format', 'acf', 'stream' ),
+ 'featured_image' => esc_html_x( 'Featured Image', 'acf', 'stream' ),
+ 'categories' => esc_html_x( 'Categories', 'acf', 'stream' ),
+ 'tags' => esc_html_x( 'Tags', 'acf', 'stream' ),
+ 'send-trackbacks' => esc_html_x( 'Send Trackbacks', 'acf', 'stream' ),
+ );
+
+ if ( is_array( $value ) && count( $options ) === count( $value ) ) {
+ $options_label = esc_html_x( 'All screens', 'acf', 'stream' );
+ } elseif ( empty( $value ) ) {
+ $options_label = esc_html_x( 'No screens', 'acf', 'stream' );
+ } else {
+ $options_label = implode( ', ', array_intersect_key( $options, array_flip( $value ) ) );
+ }
+
+ $this->log(
+ /* translators: %1$s: a form title, %2$s: a display option (e.g. "Contact", "All screens") */
+ esc_html_x( '"%1$s" set to display on "%2$s"', 'acf', 'stream' ),
+ array(
+ 'title' => $post->post_title,
+ 'option_label' => $options_label,
+ 'option' => $property,
+ 'option_value' => $value,
+ ),
+ $post_id,
+ 'options',
+ 'updated'
+ );
+ }
+ }
+
/**
* Track addition of post meta
*
* @action added_post_meta
*/
public function callback_added_post_meta() {
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'post', 'added' ), func_get_args() ) );
+ $this->check_meta( 'post', 'added', ...func_get_args() );
}
/**
@@ -162,7 +361,7 @@ public function callback_added_post_meta() {
* @action updated_post_meta
*/
public function callback_updated_post_meta() {
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'post', 'updated' ), func_get_args() ) );
+ $this->check_meta( 'post', 'updated', ...func_get_args() );
}
/**
@@ -174,7 +373,7 @@ public function callback_updated_post_meta() {
* @action delete_post_meta
*/
public function callback_delete_post_meta() {
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'post', 'deleted' ), func_get_args() ) );
+ $this->check_meta( 'post', 'deleted', ...func_get_args() );
}
/**
@@ -183,7 +382,7 @@ public function callback_delete_post_meta() {
* @action added_user_meta
*/
public function callback_added_user_meta() {
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'user', 'added' ), func_get_args() ) );
+ $this->check_meta( 'user', 'added', ...func_get_args() );
}
/**
@@ -192,7 +391,7 @@ public function callback_added_user_meta() {
* @action updated_user_meta
*/
public function callback_updated_user_meta() {
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'user', 'updated' ), func_get_args() ) );
+ $this->check_meta( 'user', 'updated', ...func_get_args() );
}
/**
@@ -204,7 +403,7 @@ public function callback_updated_user_meta() {
* @action delete_user_meta
*/
public function callback_delete_user_meta() {
- call_user_func_array( array( $this, 'check_meta' ), array_merge( array( 'user', 'deleted' ), func_get_args() ) );
+ $this->check_meta( 'user', 'deleted', ...func_get_args() );
}
/**
@@ -219,7 +418,7 @@ public function callback_delete_user_meta() {
*/
public function check_meta( $type, $action, $meta_id, $object_id, $meta_key, $meta_value = null ) {
$post = get_post( $object_id );
- if ( 'post' !== $type || ! $post || 'acf' !== $post->post_type ) {
+ if ( 'post' !== $type || ! $post || ! in_array( $post->post_type, array( 'acf', 'acf-field-group' ), true ) ) {
$this->check_meta_values( $type, $action, $meta_id, $object_id, $meta_key, $meta_value );
return;
}
@@ -274,7 +473,7 @@ public function check_meta( $type, $action, $meta_id, $object_id, $meta_key, $me
),
$object_id,
'options',
- 'updated'
+ $action
);
} elseif ( 'layout' === $meta_key ) {
if ( 'deleted' === $action ) {
@@ -479,10 +678,29 @@ public function log_override( $data ) {
return $data;
}
- if ( 'posts' === $data['connector'] && 'acf' === $data['context'] ) {
- $data['context'] = 'field_groups';
- $data['connector'] = $this->name;
- $data['args']['singular_name'] = esc_html__( 'field group', 'stream' );
+ $is_acf_context = in_array( $data['context'], array( 'acf', 'acf-field-group', 'acf-field' ), true );
+
+ if ( 'posts' === $data['connector'] && $is_acf_context ) {
+ // If ACF field group CPT being logged.
+ if ( 'acf' === $data['context'] || 'acf-field-group' === $data['context'] ) {
+ $data['context'] = 'field_groups';
+ $data['connector'] = $this->name;
+ $data['args']['singular_name'] = esc_html__( 'field group', 'stream' );
+
+ // elseif ACF field CPT being logged (ACF v5+ only).
+ } elseif ( 'acf-field' === $data['context'] ) {
+ $field_group = get_post( wp_get_post_parent_id( $data['object_id'] ) );
+
+ $data['context'] = 'fields';
+ $data['connector'] = $this->name;
+ $data['args']['singular_name'] = ! empty( $field_group )
+ ? sprintf(
+ /* translators: %s: field group name */
+ esc_html__( 'field in the "%s" field group', 'stream' ),
+ $field_group->post_title
+ )
+ : esc_html__( 'field', 'stream' );
+ }
}
return $data;
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 52817036d..f6d9740cd 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -17,16 +17,12 @@
-
- */local/*
-
-
*.ruleset
*/tests/*
*/includes/lib/*
*/ui/lib/*
*/vendor/*
*/build/*
- */local/public/*
+ */local/*
*/node_modules/*
diff --git a/phpunit.xml b/phpunit.xml
index 4b301981e..47e6e7211 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -7,6 +7,12 @@
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
+
+
+
tests
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 63002091c..f3e85b0e6 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -14,6 +14,31 @@
// @see https://core.trac.wordpress.org/browser/trunk/tests/phpunit/includes/functions.php
require_once $_tests_dir . '/includes/functions.php';
+/**
+ * Force plugins defined in a constant (supplied by phpunit.xml) to be active at runtime.
+ *
+ * @filter site_option_active_sitewide_plugins
+ * @filter option_active_plugins
+ *
+ * @param array $active_plugins
+ * @return array
+ */
+function xwp_filter_active_plugins_for_phpunit( $active_plugins ) {
+ $forced_active_plugins = array();
+ if ( defined( 'WP_TEST_ACTIVATED_PLUGINS' ) ) {
+ $forced_active_plugins = preg_split( '/\s*,\s*/', WP_TEST_ACTIVATED_PLUGINS );
+ }
+
+ if ( ! empty( $forced_active_plugins ) ) {
+ foreach ( $forced_active_plugins as $forced_active_plugin ) {
+ $active_plugins[] = $forced_active_plugin;
+ }
+ }
+ return $active_plugins;
+}
+tests_add_filter( 'site_option_active_sitewide_plugins', 'xwp_filter_active_plugins_for_phpunit' );
+tests_add_filter( 'option_active_plugins', 'xwp_filter_active_plugins_for_phpunit' );
+
tests_add_filter(
'muplugins_loaded',
function() {
diff --git a/tests/tests/connectors/test-class-connector-acf.php b/tests/tests/connectors/test-class-connector-acf.php
new file mode 100644
index 000000000..8259544ef
--- /dev/null
+++ b/tests/tests/connectors/test-class-connector-acf.php
@@ -0,0 +1,295 @@
+plugin->connectors->unload_connectors();
+
+ // Make partial of Connector_ACF class, with mocked "log" function.
+ $this->mock = $this->getMockBuilder( Connector_ACF::class )
+ ->setMethods( array( 'log' ) )
+ ->getMock();
+
+ // Register connector.
+ $this->mock->register();
+ }
+
+ /**
+ * Runs after each test
+ */
+ public function tearDown() {
+ parent::tearDown();
+ }
+
+ /**
+ * Create/Update ACF field group
+ *
+ * @param array $config ACF field group configuration.
+ */
+ private function update_acf_field_group( $config = array() ) {
+ $defaults = array(
+ 'key' => $this->group_key,
+ 'title' => 'Test Group',
+ 'fields' => array(),
+ 'location' => array(
+ array(
+ array(
+ 'param' => 'post_type',
+ 'operator' => '==',
+ 'value' => 'post',
+ ),
+ ),
+ ),
+ 'menu_order' => 0,
+ 'position' => 'normal',
+ 'style' => 'default',
+ 'label_placement' => 'top',
+ 'instruction_placement' => 'label',
+ 'hide_on_screen' => '',
+ 'active' => true,
+ 'description' => '',
+ );
+
+ return \acf_update_field_group( array_merge( $defaults, $config ) );
+ }
+
+ /**
+ * Create/Update ACF field.
+ *
+ * @param array $config ACF field configuration.
+ */
+ private function update_acf_field( $config = array() ) {
+ $defaults = [
+ 'parent' => $this->group_key,
+ 'key' => uniqid(),
+ 'label' => 'Test Field',
+ 'name' => 'test_field',
+ 'type' => 'text',
+ 'instructions' => '',
+ 'required' => 0,
+ 'conditional_logic' => 0,
+ 'wrapper' => array(
+ 'width' => '',
+ 'class' => '',
+ 'id' => '',
+ ),
+ 'default_value' => 'Yes sir!',
+ 'placeholder' => '',
+ 'prepend' => '',
+ 'append' => '',
+ 'maxlength' => '',
+ ];
+
+ return \acf_update_field( array_merge( $defaults, $config ) );
+ }
+
+ /**
+ * Confirm that ACF is installed and active.
+ */
+ public function test_acf_installed_and_activated() {
+ $this->assertTrue( is_callable( 'acf' ) );
+ }
+
+ /**
+ * Tests the "callback_save_post" callback.
+ */
+ public function test_callback_save_post() {
+ $this->mock->expects( $this->exactly( 2 ) )
+ ->method( 'log' )
+ ->withConsecutive(
+ array(
+ $this->equalTo( esc_html_x( 'Position of "%1$s" updated to "%2$s"', 'acf', 'stream' ) ),
+ $this->equalTo(
+ array(
+ 'title' => 'Test Group',
+ 'option_label' => esc_html_x( 'Normal (after content)', 'acf', 'stream' ),
+ 'option' => 'position',
+ 'option_value' => 'normal',
+ )
+ ),
+ $this->greaterThan( 0 ),
+ $this->equalTo( 'options' ),
+ $this->equalTo( 'updated' ),
+ ),
+ array(
+ $this->equalTo( esc_html_x( '"%1$s" set to display on "%2$s"', 'acf', 'stream' ) ),
+ $this->equalTo(
+ array(
+ 'title' => 'Test Group',
+ 'option_label' => esc_html_x( 'No screens', 'acf', 'stream' ),
+ 'option' => 'hide_on_screen',
+ 'option_value' => null,
+ )
+ ),
+ $this->greaterThan( 0 ),
+ $this->equalTo( 'options' ),
+ $this->equalTo( 'updated' ),
+ )
+ );
+
+ // Register test ACF field group and field to trigger callback.
+ $this->update_acf_field_group();
+ $this->update_acf_field();
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( 'wp_stream_test_callback_save_post' ) );
+
+ // 'acf/update_field_group' is called at the end of "acf_update_field()".
+ $this->assertSame( 1, did_action( 'acf/update_field_group' ) );
+ }
+
+ /**
+ * Tests the "callback_post_updated" callback.
+ */
+ public function test_callback_post_updated() {
+ // Register test ACF field group and field for later use.
+ $field_group = $this->update_acf_field_group();
+ $field = $this->update_acf_field();
+
+ $this->mock->expects( $this->exactly( 1 ) )
+ ->method( 'log' )
+ ->with(
+ $this->equalTo( esc_html_x( 'Position of "%1$s" updated to "%2$s"', 'acf', 'stream' ) ),
+ $this->equalTo(
+ array(
+ 'title' => $field_group['title'],
+ 'option_label' => esc_html_x( 'High (after title)', 'acf', 'stream' ),
+ 'option' => 'position',
+ 'option_value' => 'acf_after_title',
+ )
+ ),
+ $this->equalTo( $field_group['ID'] ),
+ $this->equalTo( 'options' ),
+ $this->equalTo( 'updated' )
+ );
+
+ // Update field group.
+ $field_group['position'] = 'acf_after_title';
+ $this->update_acf_field_group( $field_group );
+
+ // Check callback test action.
+ $this->assertGreaterThan( 0, did_action( 'wp_stream_test_callback_post_updated' ) );
+
+ // 'acf/update_field_group' is called at the end of "acf_update_field()".
+ $this->assertSame( 2, did_action( 'acf/update_field_group' ) );
+ }
+
+ /**
+ * Tests the "check_meta_values" function and some of the connected callbacks.
+ */
+ public function test_check_meta_values() {
+ // Register test ACF field group and field for later use.
+ $field_group = $this->update_acf_field_group(
+ array(
+ 'location' => array(
+ array(
+ array(
+ 'param' => 'post_type',
+ 'operator' => '==',
+ 'value' => 'post',
+ ),
+ ),
+ array(
+ array(
+ 'param' => 'current_user',
+ 'operator' => '==',
+ 'value' => 'logged_in',
+ ),
+ ),
+ ),
+ )
+ );
+ $field = $this->update_acf_field();
+
+ // Create post for later use.
+ $post_id = self::factory()->post->create( array( 'post_title' => 'Test post' ) );
+ $user_id = self::factory()->user->create(
+ array(
+ 'username' => 'testuser',
+ 'display_name' => 'testuser',
+ )
+ );
+
+ // Expected log() calls.
+ $this->mock->expects( $this->exactly( 3 ) )
+ ->method( 'log' )
+ ->withConsecutive(
+ array(
+ $this->equalTo( esc_html_x( '"%1$s" of "%2$s" %3$s updated', 'acf', 'stream' ) ),
+ $this->equalTo(
+ array(
+ 'field_label' => $field['label'],
+ 'title' => 'Test post',
+ 'singular_name' => 'post',
+ 'meta_value' => 'Yes sir!',
+ 'meta_key' => 'test_field',
+ 'meta_type' => 'post',
+ )
+ ),
+ $this->equalTo( $post_id ),
+ $this->equalTo( 'values' ),
+ $this->equalTo( 'updated' )
+ ),
+ array(
+ $this->equalTo( esc_html_x( '"%1$s" of "%2$s" %3$s updated', 'acf', 'stream' ) ),
+ $this->equalTo(
+ array(
+ 'field_label' => $field['label'],
+ 'title' => 'Test post',
+ 'singular_name' => 'post',
+ 'meta_value' => '',
+ 'meta_key' => 'test_field',
+ 'meta_type' => 'post',
+ )
+ ),
+ $this->equalTo( $post_id ),
+ $this->equalTo( 'values' ),
+ $this->equalTo( 'updated' )
+ ),
+ array(
+ $this->equalTo( esc_html_x( '"%1$s" of "%2$s" %3$s updated', 'acf', 'stream' ) ),
+ $this->equalTo(
+ array(
+ 'field_label' => $field['label'],
+ 'title' => 'testuser',
+ 'singular_name' => 'user',
+ 'meta_value' => 'Yes sir!',
+ 'meta_key' => 'test_field',
+ 'meta_type' => 'user',
+ )
+ ),
+ $this->equalTo( $user_id ),
+ $this->equalTo( 'values' ),
+ $this->equalTo( 'updated' )
+ )
+ );
+
+ // Update custom fields to trigger callback.
+ update_field( 'test_field', 'Yes sir!', $post_id );
+ update_field( 'test_field', '', $post_id );
+
+ \wp_set_current_user( $user_id );
+ update_field( 'test_field', 'Yes sir!', "user_{$user_id}" );
+
+ // Check callback test actions.
+ $this->assertGreaterThan( 0, did_action( 'wp_stream_test_callback_added_post_meta' ) );
+ $this->assertGreaterThan( 0, did_action( 'wp_stream_test_callback_updated_post_meta' ) );
+ }
+}