Version Description
- 2021-06-18 =
- Changed ownership!
Download this release
Release Info
Developer | tautvidas |
Plugin | WP Mail Logging |
Version | 1.9.8 |
Comparing to | |
See all releases |
Code changes from version 1.9.7 to 1.9.8
- CONTRIBUTING.md +61 -0
- Gruntfile.js +1 -1
- README.md +28 -0
- bin/install-wp-tests.sh +152 -0
- bin/release.sh +211 -0
- bin/run-wp-tests.sh +10 -0
- composer.json +40 -0
- composer.lock +186 -0
- languages/wp-mail-logging-de_DE.mo +0 -0
- languages/wp-mail-logging-zh_CN.mo +0 -0
- languages/wp-mail-logging.pot +26 -38
- package.json +3 -3
- phpunit.xml +37 -0
- readme.txt +7 -6
- src/WPML_OptionsManager.php +0 -91
- src/inc/redux/WPML_Redux_Framework_config.php +1 -1
- tests/helper/WPML_IntegrationTestCase.php +37 -0
- tests/helper/WPMailArrayBuilder.php +107 -0
- tests/phpunit/includes/bootstrap.php +47 -0
- tests/phpunit/integration/WPML_Hook_Remover_Test.php +39 -0
- tests/phpunit/integration/WPML_IntegrationTestCase_Test.php +14 -0
- tests/phpunit/integration/WPML_LogRotation_Test.php +149 -0
- tests/phpunit/integration/WPML_MailRenderer_AJAX_Handler_Test.php +162 -0
- tests/phpunit/integration/WPML_Plugin_Test.php +58 -0
- tests/phpunit/integration/test-core-settings.php +22 -0
- tests/phpunit/unit/WPML_Attachment_Test.php +110 -0
- tests/phpunit/unit/WPML_ColumnManager_Test.php +101 -0
- tests/phpunit/unit/WPML_Email_Log_List_Test.php +38 -0
- tests/phpunit/unit/WPML_Email_Resender_Test.php +107 -0
- tests/phpunit/unit/WPML_MailExtractor_Test.php +187 -0
- tests/phpunit/unit/WPML_MailRenderer_Test.php +228 -0
- tests/phpunit/unit/WPML_MessageSanitizer_Test.php +60 -0
- tests/phpunit/unit/WPML_Plugin_Test.php +36 -0
- tests/phpunit/unit/WPML_PrivacyController_Test.php +123 -0
- tests/phpunit/unit/WPML_Utils_Test.php +80 -0
- vendor/autoload.php +7 -0
- vendor/composer/ClassLoader.php +481 -0
- vendor/composer/InstalledVersions.php +337 -0
- vendor/composer/LICENSE +21 -0
- vendor/composer/autoload_classmap.php +10 -0
- vendor/composer/autoload_namespaces.php +9 -0
- vendor/composer/autoload_psr4.php +11 -0
- vendor/composer/autoload_real.php +57 -0
- vendor/composer/autoload_static.php +41 -0
- vendor/composer/installed.json +5 -0
- vendor/composer/installed.php +23 -0
- vendor/composer/platform_check.php +26 -0
- wp-mail-logging.php +5 -5
CONTRIBUTING.md
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#Contribute To wp-mail-logging
|
2 |
+
|
3 |
+
Community made patches, localisations, bug reports and contributions are always welcome and are crucial to ensure the quality of wp-mail-logging.
|
4 |
+
|
5 |
+
When contributing please ensure you follow the guidelines below.
|
6 |
+
|
7 |
+
## Environment
|
8 |
+
All dependencies are managed via [composer](http://getcomposer.org).
|
9 |
+
To install the plugin with development dependencies run:
|
10 |
+
|
11 |
+
```composer install```
|
12 |
+
|
13 |
+
To get a working plugin installation run:
|
14 |
+
|
15 |
+
```composer install --no-dev --no-scripts --prefer-dist``` (perfect for making a release by zipping the resulting environment)
|
16 |
+
|
17 |
+
To execute unit tests use the phpunit version downloaded by composer:
|
18 |
+
|
19 |
+
```
|
20 |
+
cd /srv/www/wordpress-develop/public_html/src/wp-content/plugins/wp-mail-logging
|
21 |
+
vendor/phpunit/phpunit/phpunit
|
22 |
+
```
|
23 |
+
If you use VVV make sure to be in the `/srv` directory instead of `/vagrant/www`. Otherwise there are errors like:
|
24 |
+
```
|
25 |
+
PHP Fatal error: Cannot redeclare composerRequire553f4f88fd2d0873cede8d164ece3593() (previously declared in /vagrant/www/wordpress-develop/public_html/src/wp-content/plugins/wp-mail-logging/vendor/composer/autoload_real.php:63) in /srv/www/wordpress-develop/public_html/src/wp-content/plugins/wp-mail-logging/vendor/composer/autoload_real.php on line 70
|
26 |
+
```
|
27 |
+
## IDE
|
28 |
+
|
29 |
+
Please insure to be conform with the development guidelines.
|
30 |
+
* use tabs and not spaces. The tab indent size should be 4 for all wp-mail-logging code.
|
31 |
+
|
32 |
+
## Getting Started
|
33 |
+
|
34 |
+
* Submit a ticket for your issue, assuming one does not already exist or fix an issue
|
35 |
+
* Raise it on our [Issue Tracker](https://github.com/kgjerstad/wp-mail-logging/issues)
|
36 |
+
* Clearly describe the issue including steps to reproduce the bug.
|
37 |
+
* Make sure you fill in the earliest version that you know has the issue as well as the version of WordPress you're using.
|
38 |
+
|
39 |
+
## Making Changes
|
40 |
+
|
41 |
+
* Fork the repository on GitHub.
|
42 |
+
* Create a new branch like 'feature1'.
|
43 |
+
* Make the changes to your branch.
|
44 |
+
* Ensure you stick to the [WordPress Coding Standards](http://codex.wordpress.org/WordPress_Coding_Standards).
|
45 |
+
* Always leave the code cleaner than you found it. (The Boy Scouts Rule)
|
46 |
+
* Reference your issue (if present) and include a note about the fix in the commit message.
|
47 |
+
* If possible, and if applicable, please also add/update unit tests for your changes.
|
48 |
+
* Finally submit a pull request to the 'master' branch of the wp-mail-logging repository.
|
49 |
+
|
50 |
+
## Code Documentation
|
51 |
+
|
52 |
+
* We ensure that every wp-mail-logging function is documented well and follows the standards set by phpDoc.
|
53 |
+
* Please make sure that every function is documented so that when we update our API Documentation things don't go awry!
|
54 |
+
* If you're adding/editing a function in a class, make sure to add `@access {private|public|protected}`.
|
55 |
+
|
56 |
+
At this point you're waiting on us to merge your pull request. We'll review all pull requests, and make suggestions and changes if necessary.
|
57 |
+
|
58 |
+
# Additional Resources
|
59 |
+
* [General GitHub Documentation](http://help.github.com/)
|
60 |
+
* [GitHub Pull Request documentation](http://help.github.com/send-pull-requests/)
|
61 |
+
* [PHPUnit Tests Guide](http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html)
|
Gruntfile.js
CHANGED
@@ -125,7 +125,7 @@ module.exports = function (grunt) {
|
|
125 |
},
|
126 |
'github-release': {
|
127 |
options: {
|
128 |
-
repository: '
|
129 |
auth: grunt.file.readJSON('credentials.json'),
|
130 |
release: {
|
131 |
tag_name: 'release/<%= pkg.version %>',
|
125 |
},
|
126 |
'github-release': {
|
127 |
options: {
|
128 |
+
repository: 'kgjerstad/wp-mail-logging', // Path to repository
|
129 |
auth: grunt.file.readJSON('credentials.json'),
|
130 |
release: {
|
131 |
tag_name: 'release/<%= pkg.version %>',
|
README.md
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# :envelope: wp-mail-logging [![Build Status](https://travis-ci.org/kgjerstad/wp-mail-logging.png?branch=master)](https://travis-ci.org/kgjerstad/wp-mail-logging) [![codecov](https://codecov.io/gh/kgjerstad/wp-mail-logging/branch/master/graph/badge.svg)](https://codecov.io/gh/kgjerstad/wp-mail-logging) [![Join the chat at https://gitter.im/kgjerstad/wp-mail-logging](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/kgjerstad/wp-mail-logging?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
2 |
+
## Welcome ##
|
3 |
+
wp-mail-logging is a WordPress plugin that logs each mail sent by WordPress.
|
4 |
+
|
5 |
+
## Installation ##
|
6 |
+
|
7 |
+
Install the plugin from the official [Wordpress Plugin Repository](https://wordpress.org/plugins/wp-mail-logging/).
|
8 |
+
|
9 |
+
## Bugs ##
|
10 |
+
If you find an issue, let us know in the [Tracker](https://github.com/kgjerstad/wp-mail-logging/issues?state=open)!
|
11 |
+
|
12 |
+
## Contributions ##
|
13 |
+
Anyone is welcome to contribute to wp-mail-logging. Please create an pull request for each change you want to contribute.
|
14 |
+
|
15 |
+
There are various ways you can contribute:
|
16 |
+
|
17 |
+
### As Developer ###
|
18 |
+
1. You can clone the git repository: 'https://github.com/kgjerstad/wp-mail-logging.git'
|
19 |
+
2. Or download it directly as a ZIP file: 'https://github.com/kgjerstad/wp-mail-logging/archive/master.zip'
|
20 |
+
|
21 |
+
This will download the latest developer copy of wp-mail-logging.
|
22 |
+
|
23 |
+
Please read [Contributing](https://github.com/kgjerstad/wp-mail-logging/blob/master/CONTRIBUTING.md) if you plan to contribute.
|
24 |
+
|
25 |
+
### As Assistant ###
|
26 |
+
1. Raise an [Issue](https://github.com/kgjerstad/wp-mail-logging/issues?state=open)
|
27 |
+
3. Translate wp-mail-logging into different languages
|
28 |
+
4. Provide feedback and suggestions on [enhancements](https://github.com/kgjerstad/wp-mail-logging/issues?direction=desc&labels=Enhancement%2Cenhancement&page=1&sort=created&state=open)
|
bin/install-wp-tests.sh
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env bash
|
2 |
+
|
3 |
+
if [ $# -lt 3 ]; then
|
4 |
+
echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]"
|
5 |
+
exit 1
|
6 |
+
fi
|
7 |
+
|
8 |
+
DB_NAME=$1
|
9 |
+
DB_USER=$2
|
10 |
+
DB_PASS=$3
|
11 |
+
DB_HOST=${4-localhost}
|
12 |
+
WP_VERSION=${5-latest}
|
13 |
+
SKIP_DB_CREATE=${6-false}
|
14 |
+
|
15 |
+
TMPDIR=${TMPDIR-/tmp}
|
16 |
+
TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
|
17 |
+
WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
|
18 |
+
WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress/}
|
19 |
+
|
20 |
+
download() {
|
21 |
+
if [ `which curl` ]; then
|
22 |
+
curl -s "$1" > "$2";
|
23 |
+
elif [ `which wget` ]; then
|
24 |
+
wget -nv -O "$2" "$1"
|
25 |
+
fi
|
26 |
+
}
|
27 |
+
|
28 |
+
if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then
|
29 |
+
WP_TESTS_TAG="branches/$WP_VERSION"
|
30 |
+
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
|
31 |
+
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
|
32 |
+
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
|
33 |
+
WP_TESTS_TAG="tags/${WP_VERSION%??}"
|
34 |
+
else
|
35 |
+
WP_TESTS_TAG="tags/$WP_VERSION"
|
36 |
+
fi
|
37 |
+
elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
|
38 |
+
WP_TESTS_TAG="trunk"
|
39 |
+
else
|
40 |
+
# http serves a single offer, whereas https serves multiple. we only want one
|
41 |
+
download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
|
42 |
+
grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
|
43 |
+
LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
|
44 |
+
if [[ -z "$LATEST_VERSION" ]]; then
|
45 |
+
echo "Latest WordPress version could not be found"
|
46 |
+
exit 1
|
47 |
+
fi
|
48 |
+
WP_TESTS_TAG="tags/$LATEST_VERSION"
|
49 |
+
fi
|
50 |
+
|
51 |
+
set -ex
|
52 |
+
|
53 |
+
install_wp() {
|
54 |
+
|
55 |
+
if [ -d $WP_CORE_DIR ]; then
|
56 |
+
return;
|
57 |
+
fi
|
58 |
+
|
59 |
+
mkdir -p $WP_CORE_DIR
|
60 |
+
|
61 |
+
if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
|
62 |
+
mkdir -p $TMPDIR/wordpress-nightly
|
63 |
+
download https://wordpress.org/nightly-builds/wordpress-latest.zip $TMPDIR/wordpress-nightly/wordpress-nightly.zip
|
64 |
+
unzip -q $TMPDIR/wordpress-nightly/wordpress-nightly.zip -d $TMPDIR/wordpress-nightly/
|
65 |
+
mv $TMPDIR/wordpress-nightly/wordpress/* $WP_CORE_DIR
|
66 |
+
else
|
67 |
+
if [ $WP_VERSION == 'latest' ]; then
|
68 |
+
local ARCHIVE_NAME='latest'
|
69 |
+
elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then
|
70 |
+
# https serves multiple offers, whereas http serves single.
|
71 |
+
download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json
|
72 |
+
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
|
73 |
+
# version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
|
74 |
+
LATEST_VERSION=${WP_VERSION%??}
|
75 |
+
else
|
76 |
+
# otherwise, scan the releases and get the most up to date minor version of the major release
|
77 |
+
local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'`
|
78 |
+
LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1)
|
79 |
+
fi
|
80 |
+
if [[ -z "$LATEST_VERSION" ]]; then
|
81 |
+
local ARCHIVE_NAME="wordpress-$WP_VERSION"
|
82 |
+
else
|
83 |
+
local ARCHIVE_NAME="wordpress-$LATEST_VERSION"
|
84 |
+
fi
|
85 |
+
else
|
86 |
+
local ARCHIVE_NAME="wordpress-$WP_VERSION"
|
87 |
+
fi
|
88 |
+
download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz
|
89 |
+
tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR
|
90 |
+
fi
|
91 |
+
|
92 |
+
download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
|
93 |
+
}
|
94 |
+
|
95 |
+
install_test_suite() {
|
96 |
+
# portable in-place argument for both GNU sed and Mac OSX sed
|
97 |
+
if [[ $(uname -s) == 'Darwin' ]]; then
|
98 |
+
local ioption='-i .bak'
|
99 |
+
else
|
100 |
+
local ioption='-i'
|
101 |
+
fi
|
102 |
+
|
103 |
+
# set up testing suite if it doesn't yet exist
|
104 |
+
if [ ! -d $WP_TESTS_DIR ]; then
|
105 |
+
# set up testing suite
|
106 |
+
mkdir -p $WP_TESTS_DIR
|
107 |
+
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
|
108 |
+
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
|
109 |
+
fi
|
110 |
+
|
111 |
+
if [ ! -f wp-tests-config.php ]; then
|
112 |
+
download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
|
113 |
+
# remove all forward slashes in the end
|
114 |
+
WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
|
115 |
+
sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
|
116 |
+
sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
|
117 |
+
sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
|
118 |
+
sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
|
119 |
+
sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
|
120 |
+
fi
|
121 |
+
|
122 |
+
}
|
123 |
+
|
124 |
+
install_db() {
|
125 |
+
|
126 |
+
if [ ${SKIP_DB_CREATE} = "true" ]; then
|
127 |
+
return 0
|
128 |
+
fi
|
129 |
+
|
130 |
+
# parse DB_HOST for port or socket references
|
131 |
+
local PARTS=(${DB_HOST//\:/ })
|
132 |
+
local DB_HOSTNAME=${PARTS[0]};
|
133 |
+
local DB_SOCK_OR_PORT=${PARTS[1]};
|
134 |
+
local EXTRA=""
|
135 |
+
|
136 |
+
if ! [ -z $DB_HOSTNAME ] ; then
|
137 |
+
if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
|
138 |
+
EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
|
139 |
+
elif ! [ -z $DB_SOCK_OR_PORT ] ; then
|
140 |
+
EXTRA=" --socket=$DB_SOCK_OR_PORT"
|
141 |
+
elif ! [ -z $DB_HOSTNAME ] ; then
|
142 |
+
EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
|
143 |
+
fi
|
144 |
+
fi
|
145 |
+
|
146 |
+
# create database
|
147 |
+
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
|
148 |
+
}
|
149 |
+
|
150 |
+
install_wp
|
151 |
+
install_test_suite
|
152 |
+
install_db
|
bin/release.sh
ADDED
@@ -0,0 +1,211 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#! /bin/bash
|
2 |
+
# See https://github.com/GaryJones/wordpress-plugin-git-flow-svn-deploy for instructions and credits.
|
3 |
+
|
4 |
+
echo
|
5 |
+
echo "WordPress Plugin Git-Flow SVN Deploy v1.0.0-dev2"
|
6 |
+
echo
|
7 |
+
echo "Step 1. Let's collect some information first."
|
8 |
+
echo
|
9 |
+
echo "Default values are in brackets - just hit enter to accept them."
|
10 |
+
echo
|
11 |
+
|
12 |
+
# Get some user input
|
13 |
+
# Can't use the -i flag for read, since that doesn't work for bash 3
|
14 |
+
#printf "1a) WordPress Repo Plugin Slug e.g. my-awesome-plugin: "
|
15 |
+
#read -e PLUGINSLUG
|
16 |
+
#echo
|
17 |
+
|
18 |
+
# Set up some default values. Feel free to change these in your own script
|
19 |
+
CURRENTDIR=`pwd`
|
20 |
+
PLUGINSLUG="wp-mail-logging"
|
21 |
+
default_svnpath="/tmp/$PLUGINSLUG-release"
|
22 |
+
default_svnurl="http://plugins.svn.wordpress.org/$PLUGINSLUG"
|
23 |
+
default_svnuser="wysija"
|
24 |
+
default_plugindir="$CURRENTDIR/../../$PLUGINSLUG"
|
25 |
+
default_mainfile="$PLUGINSLUG.php"
|
26 |
+
|
27 |
+
echo "1b) Path to a local directory where a temporary SVN checkout can be made."
|
28 |
+
printf "No trailing slash and don't add trunk ($default_svnpath): "
|
29 |
+
read -e input
|
30 |
+
input="${input%/}" # Strip trailing slash
|
31 |
+
SVNPATH="${input:-$default_svnpath}" # Populate with default if empty
|
32 |
+
echo
|
33 |
+
|
34 |
+
echo "1c) Remote SVN repo on WordPress.org. No trailing slash."
|
35 |
+
printf "($default_svnurl): "
|
36 |
+
read -e input
|
37 |
+
input="${input%/}" # Strip trailing slash
|
38 |
+
SVNURL="${input:-$default_svnurl}" # Populate with default if empty
|
39 |
+
echo
|
40 |
+
|
41 |
+
printf "1d) Your WordPress repo SVN username ($default_svnuser): "
|
42 |
+
read -e input
|
43 |
+
SVNUSER="${input:-$default_svnuser}" # Populate with default if empty
|
44 |
+
echo
|
45 |
+
|
46 |
+
echo "1e) Your local plugin root directory, the Git repo. No trailing slash."
|
47 |
+
printf "($default_plugindir): "
|
48 |
+
read -e input
|
49 |
+
input="${input%/}" # Strip trailing slash
|
50 |
+
PLUGINDIR="${input:-$default_plugindir}" # Populate with default if empty
|
51 |
+
echo
|
52 |
+
|
53 |
+
printf "1f) Name of the main plugin file ($default_mainfile): "
|
54 |
+
read -e input
|
55 |
+
MAINFILE="${input:-$default_mainfile}" # Populate with default if empty
|
56 |
+
echo
|
57 |
+
|
58 |
+
echo "That's all of the data collected."
|
59 |
+
echo
|
60 |
+
echo "Slug: $PLUGINSLUG"
|
61 |
+
echo "Temp checkout path: $SVNPATH"
|
62 |
+
echo "Remote SVN repo: $SVNURL"
|
63 |
+
echo "SVN username: $SVNUSER"
|
64 |
+
echo "Plugin directory: $PLUGINDIR"
|
65 |
+
echo "Main file: $MAINFILE"
|
66 |
+
echo
|
67 |
+
|
68 |
+
printf "OK to proceed (y|n)? "
|
69 |
+
read -e input
|
70 |
+
PROCEED="${input:-y}"
|
71 |
+
echo
|
72 |
+
|
73 |
+
# Allow user cancellation
|
74 |
+
if [ "$PROCEED" != "y" ]; then echo "Aborting..."; exit 1; fi
|
75 |
+
|
76 |
+
# git config
|
77 |
+
GITPATH="$PLUGINDIR/" # this file should be in the base of your git repository
|
78 |
+
|
79 |
+
# Let's begin...
|
80 |
+
echo ".........................................."
|
81 |
+
echo
|
82 |
+
echo "Preparing to deploy WordPress plugin"
|
83 |
+
echo
|
84 |
+
echo ".........................................."
|
85 |
+
echo
|
86 |
+
|
87 |
+
# Check version in readme.txt is the same as plugin file after translating both to unix line breaks to work around grep's failure to identify mac line breaks
|
88 |
+
NEWVERSION1=`grep "^Stable tag:" $GITPATH/readme.txt | awk -F' ' '{print $NF}' | tr -d '\r'`
|
89 |
+
echo "readme.txt version: $NEWVERSION1"
|
90 |
+
NEWVERSION2=`grep "Version:" $GITPATH/$MAINFILE | awk -F' ' '{print $NF}' | tr -d '\r'`
|
91 |
+
echo "$MAINFILE version: $NEWVERSION2"
|
92 |
+
|
93 |
+
if [ "$NEWVERSION1" != "$NEWVERSION2" ]; then echo "Version in readme.txt & $MAINFILE don't match. Exiting...."; exit 1; fi
|
94 |
+
|
95 |
+
echo "Versions match in readme.txt and $MAINFILE. Let's proceed..."
|
96 |
+
|
97 |
+
# GaryJ: Ignore check for git tag, as git flow release finish creates this.
|
98 |
+
#if git show-ref --tags --quiet --verify -- "refs/tags/$NEWVERSION1"
|
99 |
+
# then
|
100 |
+
# echo "Version $NEWVERSION1 already exists as git tag. Exiting....";
|
101 |
+
# exit 1;
|
102 |
+
# else
|
103 |
+
# echo "Git version does not exist. Let's proceed..."
|
104 |
+
#fi
|
105 |
+
|
106 |
+
echo "Changing to $GITPATH"
|
107 |
+
cd $GITPATH
|
108 |
+
# GaryJ: Commit message variable not needed . Hard coded for SVN trunk commit for consistency.
|
109 |
+
echo -e "Enter a commit message for this new version: \c"
|
110 |
+
read COMMITMSG
|
111 |
+
# GaryJ: git flow release finish already covers this commit.
|
112 |
+
git commit -am "$COMMITMSG"
|
113 |
+
|
114 |
+
# GaryJ: git flow release finish already covers this tag creation.
|
115 |
+
echo "Tagging new version in git"
|
116 |
+
git tag -a "release/$NEWVERSION1" -m "Tagging version $NEWVERSION1"
|
117 |
+
|
118 |
+
echo "Pushing git master to origin, with tags"
|
119 |
+
git push origin master
|
120 |
+
git push origin master --tags
|
121 |
+
|
122 |
+
echo
|
123 |
+
echo "Creating local copy of SVN repo trunk ..."
|
124 |
+
svn checkout $SVNURL $SVNPATH --depth immediates
|
125 |
+
svn update --quiet $SVNPATH/trunk --set-depth infinity
|
126 |
+
|
127 |
+
echo "Ignoring GitHub specific files"
|
128 |
+
svn propset svn:ignore "README.md
|
129 |
+
CONTRIBUTING.md
|
130 |
+
README.md
|
131 |
+
phpunit.xml
|
132 |
+
Thumbs.db
|
133 |
+
.travis.yml
|
134 |
+
.git
|
135 |
+
.gitignore
|
136 |
+
tests
|
137 |
+
bin
|
138 |
+
composer.json
|
139 |
+
composer.lock" "$SVNPATH/trunk/"
|
140 |
+
|
141 |
+
echo "Exporting the HEAD of master from git to the trunk of SVN"
|
142 |
+
git checkout-index -a -f --prefix=$SVNPATH/trunk/
|
143 |
+
|
144 |
+
# If submodule exist, recursively check out their indexes
|
145 |
+
if [ -f ".gitmodules" ]
|
146 |
+
then
|
147 |
+
echo "Exporting the HEAD of each submodule from git to the trunk of SVN"
|
148 |
+
git submodule init
|
149 |
+
git submodule update
|
150 |
+
git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
|
151 |
+
while read path_key path
|
152 |
+
do
|
153 |
+
#url_key=$(echo $path_key | sed 's/\.path/.url/')
|
154 |
+
#url=$(git config -f .gitmodules --get "$url_key")
|
155 |
+
#git submodule add $url $path
|
156 |
+
echo "This is the submodule path: $path"
|
157 |
+
echo "The following line is the command to checkout the submodule."
|
158 |
+
echo "git submodule foreach --recursive 'git checkout-index -a -f --prefix=$SVNPATH/trunk/$path/'"
|
159 |
+
git submodule foreach --recursive 'git checkout-index -a -f --prefix=$SVNPATH/trunk/$path/'
|
160 |
+
done
|
161 |
+
fi
|
162 |
+
|
163 |
+
# Support for the /assets folder on the .org repo.
|
164 |
+
echo "Moving assets"
|
165 |
+
# Make the directory if it doesn't already exist
|
166 |
+
mkdir -p $SVNPATH/assets/
|
167 |
+
mv $SVNPATH/trunk/assets/* $SVNPATH/assets/
|
168 |
+
svn add --force $SVNPATH/assets/
|
169 |
+
svn delete --force $SVNPATH/trunk/assets
|
170 |
+
|
171 |
+
printf "OK to proceed? This will actually release $PLUGINSLUG $NEWVERSION1 (y|n)? "
|
172 |
+
read -e input
|
173 |
+
PROCEED="${input:-y}"
|
174 |
+
echo
|
175 |
+
|
176 |
+
# Allow user cancellation
|
177 |
+
if [ "$PROCEED" != "y" ]; then echo "Aborting..."; exit 1; fi
|
178 |
+
|
179 |
+
echo "Changing directory to SVN and committing to trunk"
|
180 |
+
cd $SVNPATH/trunk/
|
181 |
+
# Delete all files that should not now be added.
|
182 |
+
svn status | grep -v "^.[ \t]*\..*" | grep "^\!" | awk '{print $2}' | xargs svn del
|
183 |
+
# Add all new files that are not set to be ignored
|
184 |
+
svn status | grep -v "^.[ \t]*\..*" | grep "^?" | awk '{print $2}' | xargs svn add
|
185 |
+
svn commit --username=$SVNUSER -m "Preparing for $NEWVERSION1 release"
|
186 |
+
|
187 |
+
echo "Updating WordPress plugin repo assets and committing"
|
188 |
+
cd $SVNPATH/assets/
|
189 |
+
# Delete all new files that are not set to be ignored
|
190 |
+
svn status | grep -v "^.[ \t]*\..*" | grep "^\!" | awk '{print $2}' | xargs svn del
|
191 |
+
# Add all new files that are not set to be ignored
|
192 |
+
svn status | grep -v "^.[ \t]*\..*" | grep "^?" | awk '{print $2}' | xargs svn add
|
193 |
+
svn update --accept mine-full $SVNPATH/assets/*
|
194 |
+
svn commit --username=$SVNUSER -m "Updating assets"
|
195 |
+
|
196 |
+
echo "Creating new SVN tag and committing it"
|
197 |
+
cd $SVNPATH
|
198 |
+
svn update --quiet $SVNPATH/tags/$NEWVERSION1
|
199 |
+
svn copy --quiet trunk/ tags/$NEWVERSION1/
|
200 |
+
# Remove assets and trunk directories from tag directory
|
201 |
+
svn delete --force --quiet $SVNPATH/tags/$NEWVERSION1/assets
|
202 |
+
svn delete --force --quiet $SVNPATH/tags/$NEWVERSION1/trunk
|
203 |
+
cd $SVNPATH/tags/$NEWVERSION1
|
204 |
+
svn commit --username=$SVNUSER -m "Tagging version $NEWVERSION1"
|
205 |
+
|
206 |
+
echo "Removing temporary directory $SVNPATH"
|
207 |
+
cd $SVNPATH
|
208 |
+
cd ..
|
209 |
+
rm -fr $SVNPATH/
|
210 |
+
|
211 |
+
echo "*** FIN ***"
|
bin/run-wp-tests.sh
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#! /bin/sh
|
2 |
+
|
3 |
+
# Simpler test script for running tests iteratively.
|
4 |
+
# You must have executd first install-wp-tests.
|
5 |
+
|
6 |
+
export WP_TESTS_DIR=/tmp/wordpress-testing
|
7 |
+
export WP_DIR=/tmp/wordpress
|
8 |
+
SCRIPTS_DIR=`dirname $0`
|
9 |
+
|
10 |
+
bash $SCRIPTS_DIR/install-wp-tests.sh wordpress_test wp 'wp' localhost
|
composer.json
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "no3x/wp-mail-logging",
|
3 |
+
"description": "WordPress plugin that logs each email sent by WordPress.",
|
4 |
+
"type": "wordpress-plugin",
|
5 |
+
"keywords": ["mail", "email", "log", "logging", "debug", "list", "store", "collect", "view"],
|
6 |
+
"homepage": "https://github.com/kgjerstad/wp-mail-logging",
|
7 |
+
"require": {
|
8 |
+
"php": ">=5.4"
|
9 |
+
},
|
10 |
+
"require-dev": {
|
11 |
+
"bocharsky-bw/arrayzy": "v0.1.1",
|
12 |
+
"mockery/mockery": "^0.9.9"
|
13 |
+
},
|
14 |
+
"license": "GPL-2.0",
|
15 |
+
"authors": [
|
16 |
+
{
|
17 |
+
"name": "No3x",
|
18 |
+
"email": "no3x@no3x.de",
|
19 |
+
"homepage": "http://no3x.de",
|
20 |
+
"role": "Developer"
|
21 |
+
}
|
22 |
+
],
|
23 |
+
"support": {
|
24 |
+
"issues": "https://github.com/kgjerstad/wp-mail-logging/issues",
|
25 |
+
"source": "https://github.com/kgjerstad/wp-mail-logging/releases"
|
26 |
+
|
27 |
+
},
|
28 |
+
"extra": {
|
29 |
+
"installer-paths": {
|
30 |
+
"vendor/redux-framework/redux-framework": ["redux-framework/redux-framework"]
|
31 |
+
}
|
32 |
+
},
|
33 |
+
"minimum-stability": "dev",
|
34 |
+
"autoload": {
|
35 |
+
"psr-4": {
|
36 |
+
"No3x\\WPML\\Tests\\": "tests/phpunit/tests",
|
37 |
+
"No3x\\WPML\\Tests\\Helper\\": "tests/helper"
|
38 |
+
}
|
39 |
+
}
|
40 |
+
}
|
composer.lock
ADDED
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"_readme": [
|
3 |
+
"This file locks the dependencies of your project to a known state",
|
4 |
+
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
5 |
+
"This file is @generated automatically"
|
6 |
+
],
|
7 |
+
"content-hash": "5112a4988dade121d66ea3f9730fb3d9",
|
8 |
+
"packages": [],
|
9 |
+
"packages-dev": [
|
10 |
+
{
|
11 |
+
"name": "bocharsky-bw/arrayzy",
|
12 |
+
"version": "v0.1.1",
|
13 |
+
"source": {
|
14 |
+
"type": "git",
|
15 |
+
"url": "https://github.com/bocharsky-bw/Arrayzy.git",
|
16 |
+
"reference": "364cda2180574868c37ed84fb5734fcf4fb6853a"
|
17 |
+
},
|
18 |
+
"dist": {
|
19 |
+
"type": "zip",
|
20 |
+
"url": "https://api.github.com/repos/bocharsky-bw/Arrayzy/zipball/364cda2180574868c37ed84fb5734fcf4fb6853a",
|
21 |
+
"reference": "364cda2180574868c37ed84fb5734fcf4fb6853a",
|
22 |
+
"shasum": ""
|
23 |
+
},
|
24 |
+
"require": {
|
25 |
+
"ext-json": "*",
|
26 |
+
"php": ">=5.4"
|
27 |
+
},
|
28 |
+
"require-dev": {
|
29 |
+
"phpunit/phpunit": "~4.5"
|
30 |
+
},
|
31 |
+
"type": "library",
|
32 |
+
"autoload": {
|
33 |
+
"psr-4": {
|
34 |
+
"Arrayzy\\": "src/"
|
35 |
+
}
|
36 |
+
},
|
37 |
+
"notification-url": "https://packagist.org/downloads/",
|
38 |
+
"license": [
|
39 |
+
"MIT"
|
40 |
+
],
|
41 |
+
"authors": [
|
42 |
+
{
|
43 |
+
"name": "Bocharsky Victor",
|
44 |
+
"email": "bocharsky.bw@gmail.com"
|
45 |
+
}
|
46 |
+
],
|
47 |
+
"description": "A PHP array easy manipulation library in OOP way",
|
48 |
+
"homepage": "https://github.com/bocharsky-bw/Arrayzy",
|
49 |
+
"keywords": [
|
50 |
+
"OOP",
|
51 |
+
"array",
|
52 |
+
"arrayzy",
|
53 |
+
"helper",
|
54 |
+
"manipulation",
|
55 |
+
"utility",
|
56 |
+
"wrapper"
|
57 |
+
],
|
58 |
+
"time": "2015-07-12T19:31:25+00:00"
|
59 |
+
},
|
60 |
+
{
|
61 |
+
"name": "hamcrest/hamcrest-php",
|
62 |
+
"version": "1.2.x-dev",
|
63 |
+
"source": {
|
64 |
+
"type": "git",
|
65 |
+
"url": "https://github.com/hamcrest/hamcrest-php.git",
|
66 |
+
"reference": "26968e9810ff0d1aa48f6d67a862559d92a51884"
|
67 |
+
},
|
68 |
+
"dist": {
|
69 |
+
"type": "zip",
|
70 |
+
"url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/26968e9810ff0d1aa48f6d67a862559d92a51884",
|
71 |
+
"reference": "26968e9810ff0d1aa48f6d67a862559d92a51884",
|
72 |
+
"shasum": ""
|
73 |
+
},
|
74 |
+
"require": {
|
75 |
+
"php": "^5.3|^7.0"
|
76 |
+
},
|
77 |
+
"replace": {
|
78 |
+
"cordoval/hamcrest-php": "*",
|
79 |
+
"davedevelopment/hamcrest-php": "*",
|
80 |
+
"kodova/hamcrest-php": "*"
|
81 |
+
},
|
82 |
+
"require-dev": {
|
83 |
+
"phpunit/php-file-iterator": "1.3.3",
|
84 |
+
"phpunit/phpunit": "~4.0",
|
85 |
+
"satooshi/php-coveralls": "^1.0"
|
86 |
+
},
|
87 |
+
"type": "library",
|
88 |
+
"extra": {
|
89 |
+
"branch-alias": {
|
90 |
+
"dev-master": "1.2-dev"
|
91 |
+
}
|
92 |
+
},
|
93 |
+
"autoload": {
|
94 |
+
"classmap": [
|
95 |
+
"hamcrest"
|
96 |
+
],
|
97 |
+
"files": [
|
98 |
+
"hamcrest/Hamcrest.php"
|
99 |
+
]
|
100 |
+
},
|
101 |
+
"notification-url": "https://packagist.org/downloads/",
|
102 |
+
"license": [
|
103 |
+
"BSD-3-Clause"
|
104 |
+
],
|
105 |
+
"description": "This is the PHP port of Hamcrest Matchers",
|
106 |
+
"keywords": [
|
107 |
+
"test"
|
108 |
+
],
|
109 |
+
"time": "2018-02-19T09:04:07+00:00"
|
110 |
+
},
|
111 |
+
{
|
112 |
+
"name": "mockery/mockery",
|
113 |
+
"version": "0.9.x-dev",
|
114 |
+
"source": {
|
115 |
+
"type": "git",
|
116 |
+
"url": "https://github.com/mockery/mockery.git",
|
117 |
+
"reference": "e206aa48a851b95a91eeb61bfcce536d51b7cd96"
|
118 |
+
},
|
119 |
+
"dist": {
|
120 |
+
"type": "zip",
|
121 |
+
"url": "https://api.github.com/repos/mockery/mockery/zipball/e206aa48a851b95a91eeb61bfcce536d51b7cd96",
|
122 |
+
"reference": "e206aa48a851b95a91eeb61bfcce536d51b7cd96",
|
123 |
+
"shasum": ""
|
124 |
+
},
|
125 |
+
"require": {
|
126 |
+
"hamcrest/hamcrest-php": "~1.1",
|
127 |
+
"lib-pcre": ">=7.0",
|
128 |
+
"php": ">=5.3.2"
|
129 |
+
},
|
130 |
+
"require-dev": {
|
131 |
+
"phpunit/phpunit": "~4.0"
|
132 |
+
},
|
133 |
+
"type": "library",
|
134 |
+
"extra": {
|
135 |
+
"branch-alias": {
|
136 |
+
"dev-master": "0.9.x-dev"
|
137 |
+
}
|
138 |
+
},
|
139 |
+
"autoload": {
|
140 |
+
"psr-0": {
|
141 |
+
"Mockery": "library/"
|
142 |
+
}
|
143 |
+
},
|
144 |
+
"notification-url": "https://packagist.org/downloads/",
|
145 |
+
"license": [
|
146 |
+
"BSD-3-Clause"
|
147 |
+
],
|
148 |
+
"authors": [
|
149 |
+
{
|
150 |
+
"name": "Pádraic Brady",
|
151 |
+
"email": "padraic.brady@gmail.com",
|
152 |
+
"homepage": "http://blog.astrumfutura.com"
|
153 |
+
},
|
154 |
+
{
|
155 |
+
"name": "Dave Marshall",
|
156 |
+
"email": "dave.marshall@atstsolutions.co.uk",
|
157 |
+
"homepage": "http://davedevelopment.co.uk"
|
158 |
+
}
|
159 |
+
],
|
160 |
+
"description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.",
|
161 |
+
"homepage": "http://github.com/padraic/mockery",
|
162 |
+
"keywords": [
|
163 |
+
"BDD",
|
164 |
+
"TDD",
|
165 |
+
"library",
|
166 |
+
"mock",
|
167 |
+
"mock objects",
|
168 |
+
"mockery",
|
169 |
+
"stub",
|
170 |
+
"test",
|
171 |
+
"test double",
|
172 |
+
"testing"
|
173 |
+
],
|
174 |
+
"time": "2018-02-02T16:28:49+00:00"
|
175 |
+
}
|
176 |
+
],
|
177 |
+
"aliases": [],
|
178 |
+
"minimum-stability": "dev",
|
179 |
+
"stability-flags": [],
|
180 |
+
"prefer-stable": false,
|
181 |
+
"prefer-lowest": false,
|
182 |
+
"platform": {
|
183 |
+
"php": ">=5.4"
|
184 |
+
},
|
185 |
+
"platform-dev": []
|
186 |
+
}
|
languages/wp-mail-logging-de_DE.mo
CHANGED
Binary file
|
languages/wp-mail-logging-zh_CN.mo
CHANGED
Binary file
|
languages/wp-mail-logging.pot
CHANGED
@@ -1,14 +1,14 @@
|
|
1 |
-
# Copyright (C)
|
2 |
# This file is distributed under the GPLv3.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: WP Mail Logging 1.9.
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-mail-logging\n"
|
7 |
-
"POT-Creation-Date:
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=utf-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
-
"PO-Revision-Date:
|
12 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
13 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
14 |
"X-Generator: grunt-wp-i18n 0.5.4\n"
|
@@ -40,7 +40,7 @@ msgstr ""
|
|
40 |
msgid "Subject"
|
41 |
msgstr ""
|
42 |
|
43 |
-
#: src/Renderer/WPML_ColumnManager.php:36 src/WPML_OptionsManager.php:
|
44 |
msgid "Message"
|
45 |
msgstr ""
|
46 |
|
@@ -68,7 +68,7 @@ msgstr ""
|
|
68 |
msgid "No email found."
|
69 |
msgstr ""
|
70 |
|
71 |
-
#: src/WPML_LifeCycle.php:205
|
72 |
msgid "Settings"
|
73 |
msgstr ""
|
74 |
|
@@ -76,76 +76,64 @@ msgstr ""
|
|
76 |
msgid "WP Mail Log"
|
77 |
msgstr ""
|
78 |
|
79 |
-
#: src/WPML_OptionsManager.php:
|
80 |
-
#: src/WPML_OptionsManager.php:
|
81 |
msgid "About"
|
82 |
msgstr ""
|
83 |
|
84 |
-
#: src/WPML_OptionsManager.php:
|
85 |
-
msgid "About Plugin"
|
86 |
-
msgstr ""
|
87 |
-
|
88 |
-
#: src/WPML_OptionsManager.php:438
|
89 |
-
msgid "More information"
|
90 |
-
msgstr ""
|
91 |
-
|
92 |
-
#: src/WPML_OptionsManager.php:439
|
93 |
-
msgid "Plugin Homepage/support"
|
94 |
-
msgstr ""
|
95 |
-
|
96 |
-
#: src/WPML_OptionsManager.php:440
|
97 |
-
msgid "Plugin author's blog"
|
98 |
-
msgstr ""
|
99 |
-
|
100 |
-
#: src/WPML_OptionsManager.php:447
|
101 |
msgid "Entries per page"
|
102 |
msgstr ""
|
103 |
|
104 |
-
#: src/WPML_OptionsManager.php:
|
105 |
msgid "You do not have sufficient permissions to access this page."
|
106 |
msgstr ""
|
107 |
|
108 |
-
#: src/WPML_OptionsManager.php:
|
109 |
msgid "Log"
|
110 |
msgstr ""
|
111 |
|
112 |
-
#: src/WPML_OptionsManager.php:
|
|
|
|
|
|
|
|
|
113 |
msgid "Close"
|
114 |
msgstr ""
|
115 |
|
116 |
-
#: src/WPML_OptionsManager.php:
|
117 |
msgid "Search"
|
118 |
msgstr ""
|
119 |
|
120 |
-
#: src/WPML_OptionsManager.php:
|
121 |
msgid "true"
|
122 |
msgstr ""
|
123 |
|
124 |
-
#: src/WPML_OptionsManager.php:
|
125 |
msgid "false"
|
126 |
msgstr ""
|
127 |
|
128 |
-
#: src/WPML_OptionsManager.php:
|
129 |
msgid "Administrator"
|
130 |
msgstr ""
|
131 |
|
132 |
-
#: src/WPML_OptionsManager.php:
|
133 |
msgid "Editor"
|
134 |
msgstr ""
|
135 |
|
136 |
-
#: src/WPML_OptionsManager.php:
|
137 |
msgid "Author"
|
138 |
msgstr ""
|
139 |
|
140 |
-
#: src/WPML_OptionsManager.php:
|
141 |
msgid "Contributor"
|
142 |
msgstr ""
|
143 |
|
144 |
-
#: src/WPML_OptionsManager.php:
|
145 |
msgid "Subscriber"
|
146 |
msgstr ""
|
147 |
|
148 |
-
#: src/WPML_OptionsManager.php:
|
149 |
msgid "Anyone"
|
150 |
msgstr ""
|
151 |
|
@@ -346,4 +334,4 @@ msgstr ""
|
|
346 |
#: src/inc/class-wp-list-table.php:573
|
347 |
msgctxt "paging"
|
348 |
msgid "%1$s of %2$s"
|
349 |
-
msgstr ""
|
1 |
+
# Copyright (C) 2021 Wysija
|
2 |
# This file is distributed under the GPLv3.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: WP Mail Logging 1.9.8\n"
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-mail-logging\n"
|
7 |
+
"POT-Creation-Date: 2021-07-03 13:37:23+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=utf-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2021-MO-DA HO:MI+ZONE\n"
|
12 |
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
13 |
"Language-Team: LANGUAGE <LL@li.org>\n"
|
14 |
"X-Generator: grunt-wp-i18n 0.5.4\n"
|
40 |
msgid "Subject"
|
41 |
msgstr ""
|
42 |
|
43 |
+
#: src/Renderer/WPML_ColumnManager.php:36 src/WPML_OptionsManager.php:503
|
44 |
msgid "Message"
|
45 |
msgstr ""
|
46 |
|
68 |
msgid "No email found."
|
69 |
msgstr ""
|
70 |
|
71 |
+
#: src/WPML_LifeCycle.php:205 src/WPML_OptionsManager.php:444
|
72 |
msgid "Settings"
|
73 |
msgstr ""
|
74 |
|
76 |
msgid "WP Mail Log"
|
77 |
msgstr ""
|
78 |
|
79 |
+
#: src/WPML_OptionsManager.php:339 src/WPML_OptionsManager.php:340
|
80 |
+
#: src/WPML_OptionsManager.php:360
|
81 |
msgid "About"
|
82 |
msgstr ""
|
83 |
|
84 |
+
#: src/WPML_OptionsManager.php:349
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
msgid "Entries per page"
|
86 |
msgstr ""
|
87 |
|
88 |
+
#: src/WPML_OptionsManager.php:415 src/WPML_OptionsManager.php:478
|
89 |
msgid "You do not have sufficient permissions to access this page."
|
90 |
msgstr ""
|
91 |
|
92 |
+
#: src/WPML_OptionsManager.php:426
|
93 |
msgid "Log"
|
94 |
msgstr ""
|
95 |
|
96 |
+
#: src/WPML_OptionsManager.php:440
|
97 |
+
msgid "Email log"
|
98 |
+
msgstr ""
|
99 |
+
|
100 |
+
#: src/WPML_OptionsManager.php:520
|
101 |
msgid "Close"
|
102 |
msgstr ""
|
103 |
|
104 |
+
#: src/WPML_OptionsManager.php:534
|
105 |
msgid "Search"
|
106 |
msgstr ""
|
107 |
|
108 |
+
#: src/WPML_OptionsManager.php:558
|
109 |
msgid "true"
|
110 |
msgstr ""
|
111 |
|
112 |
+
#: src/WPML_OptionsManager.php:560
|
113 |
msgid "false"
|
114 |
msgstr ""
|
115 |
|
116 |
+
#: src/WPML_OptionsManager.php:563
|
117 |
msgid "Administrator"
|
118 |
msgstr ""
|
119 |
|
120 |
+
#: src/WPML_OptionsManager.php:565
|
121 |
msgid "Editor"
|
122 |
msgstr ""
|
123 |
|
124 |
+
#: src/WPML_OptionsManager.php:567
|
125 |
msgid "Author"
|
126 |
msgstr ""
|
127 |
|
128 |
+
#: src/WPML_OptionsManager.php:569
|
129 |
msgid "Contributor"
|
130 |
msgstr ""
|
131 |
|
132 |
+
#: src/WPML_OptionsManager.php:571
|
133 |
msgid "Subscriber"
|
134 |
msgstr ""
|
135 |
|
136 |
+
#: src/WPML_OptionsManager.php:573
|
137 |
msgid "Anyone"
|
138 |
msgstr ""
|
139 |
|
334 |
#: src/inc/class-wp-list-table.php:573
|
335 |
msgctxt "paging"
|
336 |
msgid "%1$s of %2$s"
|
337 |
+
msgstr ""
|
package.json
CHANGED
@@ -1,15 +1,15 @@
|
|
1 |
{
|
2 |
"name": "wp-mail-logging",
|
3 |
-
"version": "1.9.
|
4 |
"description": "WordPress plugin that logs each email sent by WordPress.",
|
5 |
"repository": {
|
6 |
"type": "git",
|
7 |
-
"url": "https://github.com/
|
8 |
},
|
9 |
"author": "No3x",
|
10 |
"license": "GPL-2.0",
|
11 |
"bugs": {
|
12 |
-
"url": "https://github.com/
|
13 |
},
|
14 |
"devDependencies": {
|
15 |
"gitignore-to-glob": "^0.1.2",
|
1 |
{
|
2 |
"name": "wp-mail-logging",
|
3 |
+
"version": "1.9.8",
|
4 |
"description": "WordPress plugin that logs each email sent by WordPress.",
|
5 |
"repository": {
|
6 |
"type": "git",
|
7 |
+
"url": "https://github.com/kgjerstad/wp-mail-logging"
|
8 |
},
|
9 |
"author": "No3x",
|
10 |
"license": "GPL-2.0",
|
11 |
"bugs": {
|
12 |
+
"url": "https://github.com/kgjerstad/wp-mail-logging/issues"
|
13 |
},
|
14 |
"devDependencies": {
|
15 |
"gitignore-to-glob": "^0.1.2",
|
phpunit.xml
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<phpunit
|
2 |
+
bootstrap="tests/phpunit/includes/bootstrap.php"
|
3 |
+
backupGlobals="false"
|
4 |
+
colors="true"
|
5 |
+
convertErrorsToExceptions="true"
|
6 |
+
convertNoticesToExceptions="true"
|
7 |
+
convertWarningsToExceptions="true"
|
8 |
+
>
|
9 |
+
<php>
|
10 |
+
<!-- Dirty hack to convince phpunit to use the right includes -->
|
11 |
+
<env name="WP_TESTS_DIR" value="/srv/www/wordpress-develop/public_html/tests/phpunit/" force="true" />
|
12 |
+
</php>
|
13 |
+
<testsuites>
|
14 |
+
<testsuite>
|
15 |
+
<directory suffix=".php">tests/phpunit</directory>
|
16 |
+
</testsuite>
|
17 |
+
</testsuites>
|
18 |
+
<filter>
|
19 |
+
<!--<blacklist>
|
20 |
+
<directory>.</directory>
|
21 |
+
<directory>tests</directory>
|
22 |
+
<directory>vendor</directory>
|
23 |
+
<directory>lib</directory>
|
24 |
+
<directory>inc</directory>
|
25 |
+
</blacklist>-->
|
26 |
+
<whitelist>
|
27 |
+
<directory suffix=".php">src</directory>
|
28 |
+
<exclude>
|
29 |
+
<directory>tests</directory>
|
30 |
+
</exclude>
|
31 |
+
</whitelist>
|
32 |
+
</filter>
|
33 |
+
<logging>
|
34 |
+
<log type="coverage-clover" target="build/logs/clover.xml"/>
|
35 |
+
<log type="coverage-text" target="php://stdout" />
|
36 |
+
</logging>
|
37 |
+
</phpunit>
|
readme.txt
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
=== WP Mail Logging
|
2 |
-
Contributors: MailPoet, No3x, tripflex
|
3 |
Tags: mail, email, log, logging, email log, debug, smtp, spam, deliverability
|
4 |
License: GPLv3
|
5 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
6 |
Requires at least: 5.0
|
7 |
Tested up to: 5.5
|
8 |
-
Stable tag: 1.9.
|
9 |
|
10 |
Log every single email sent by WordPress. Zero configuration. Entirely free.
|
11 |
|
@@ -99,8 +99,6 @@ We recommend in this case to send your WordPress email with a service provider,
|
|
99 |
|
100 |
### Credits
|
101 |
|
102 |
-
This plugin is maintained by <a href="https://www.mailpoet.com/">MailPoet, the most popular email plugin for WordPress</a>.
|
103 |
-
|
104 |
The plugin was created and launched in 2014 by <a href="https://no3x.de/">Christian Zöller</a>.
|
105 |
|
106 |
== Frequently Asked Questions ==
|
@@ -109,7 +107,7 @@ We answer in the forums, but only occasionally.
|
|
109 |
= Where can I report a bug? =
|
110 |
You can do so in the support forums. We'll be happy to review them.
|
111 |
= Can I submit changes to the plugin? =
|
112 |
-
Yes, directly on <a href="https://github.com/
|
113 |
|
114 |
== Screenshots ==
|
115 |
1. The List
|
@@ -118,6 +116,9 @@ Yes, directly on <a href="https://github.com/mailpoet/wp-mail-logging" rel="nofo
|
|
118 |
|
119 |
== Changelog ==
|
120 |
|
|
|
|
|
|
|
121 |
= 1.9.7 - 2020-09-02 =
|
122 |
- Added: wpml_banner_display filter to hide MailPoet banner;
|
123 |
- Updated: support for WordPress 5.5.
|
1 |
+
=== WP Mail Logging ===
|
2 |
+
Contributors: Wysija, MailPoet, No3x, tripflex
|
3 |
Tags: mail, email, log, logging, email log, debug, smtp, spam, deliverability
|
4 |
License: GPLv3
|
5 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
6 |
Requires at least: 5.0
|
7 |
Tested up to: 5.5
|
8 |
+
Stable tag: 1.9.8
|
9 |
|
10 |
Log every single email sent by WordPress. Zero configuration. Entirely free.
|
11 |
|
99 |
|
100 |
### Credits
|
101 |
|
|
|
|
|
102 |
The plugin was created and launched in 2014 by <a href="https://no3x.de/">Christian Zöller</a>.
|
103 |
|
104 |
== Frequently Asked Questions ==
|
107 |
= Where can I report a bug? =
|
108 |
You can do so in the support forums. We'll be happy to review them.
|
109 |
= Can I submit changes to the plugin? =
|
110 |
+
Yes, directly on <a href="https://github.com/kgjerstad/wp-mail-logging/" rel="nofollow">GitHub</a>.
|
111 |
|
112 |
== Screenshots ==
|
113 |
1. The List
|
116 |
|
117 |
== Changelog ==
|
118 |
|
119 |
+
= 1.9.8 - 2021-06-18 =
|
120 |
+
- Changed ownership!
|
121 |
+
|
122 |
= 1.9.7 - 2020-09-02 =
|
123 |
- Added: wpml_banner_display filter to hide MailPoet banner;
|
124 |
- Updated: support for WordPress 5.5.
|
src/WPML_OptionsManager.php
CHANGED
@@ -415,8 +415,6 @@ class WPML_OptionsManager {
|
|
415 |
wp_die(__('You do not have sufficient permissions to access this page.', 'wp-mail-logging'));
|
416 |
}
|
417 |
|
418 |
-
$this->redirectToFreePlan();
|
419 |
-
|
420 |
if (!class_exists( 'Email_Log_List_Table' ) ) {
|
421 |
require_once ( plugin_dir_path( __FILE__ ) . 'WPML_Email_Log_List.php' );
|
422 |
}
|
@@ -537,98 +535,9 @@ class WPML_OptionsManager {
|
|
537 |
$emailLogList->display();
|
538 |
?>
|
539 |
</form>
|
540 |
-
<?php
|
541 |
-
/**
|
542 |
-
* Control whether the banner is displayed or not
|
543 |
-
*
|
544 |
-
* @since 1.9.7
|
545 |
-
*
|
546 |
-
* @param boolean $display Whether the banner should be displayed. (default: true)
|
547 |
-
*
|
548 |
-
* @return boolean
|
549 |
-
*/
|
550 |
-
$display = apply_filters('wpml_banner_display', true);
|
551 |
-
if ( $display ) {
|
552 |
-
$this->displayMP3Banner();
|
553 |
-
}
|
554 |
-
?>
|
555 |
-
<?php
|
556 |
-
}
|
557 |
-
|
558 |
-
private function displayMP3Banner() {
|
559 |
-
$option = (int)get_option('wpml_banner_version');
|
560 |
-
if (!$option) {
|
561 |
-
$option = rand(1, 2);
|
562 |
-
add_option('wpml_banner_version', $option);
|
563 |
-
}
|
564 |
-
?>
|
565 |
-
<div style="background: #fff;border-left: 4px solid #fff;border-radius: 10px;box-shadow: 0 4px 35px rgba(195, 65, 2, .2);clear: both;margin-bottom: 15px;margin-top: 15px;padding: 20px;">
|
566 |
-
<h3><?php _e( 'Reliable and beautiful emails by MailPoet!', 'wp-mail-logging' );?></h3>
|
567 |
-
<?php
|
568 |
-
if ($option === 1) {
|
569 |
-
$this->displayMP3BannerVersionA();
|
570 |
-
} else {
|
571 |
-
$this->displayMP3BannerVersionB();
|
572 |
-
}
|
573 |
-
?>
|
574 |
-
</div>
|
575 |
-
<?php
|
576 |
-
}
|
577 |
-
|
578 |
-
private function displayMP3BannerVersionA() {
|
579 |
-
?>
|
580 |
-
<ul style="list-style-type:disc;list-style-position: inside">
|
581 |
-
<li><?php _e( '50 email templates to choose from', 'wp-mail-logging' );?></li>
|
582 |
-
<li><?php _e( 'Fun email designer', 'wp-mail-logging' );?></li>
|
583 |
-
<li><?php _e( 'Automated email marketing', 'wp-mail-logging' );?></li>
|
584 |
-
<li><?php _e( 'WooCommerce emails', 'wp-mail-logging' );?></li>
|
585 |
-
<li><?php _e( '99.1% success email deliverability', 'wp-mail-logging' );?></li>
|
586 |
-
<li><?php _e( 'Fast and friendly support', 'wp-mail-logging' );?></li>
|
587 |
-
<li><?php _e( 'Over 100,000 active users', 'wp-mail-logging' );?></li>
|
588 |
-
</ul>
|
589 |
-
<a
|
590 |
-
class="button button-primary"
|
591 |
-
href="?page=wpml_plugin_log&redirect=free-plan&ref=wml_1"
|
592 |
-
target="_blank"
|
593 |
-
>
|
594 |
-
<?php _e( 'Try MailPoet for free', 'wp-mail-logging' );?>
|
595 |
-
</a>
|
596 |
-
<p>
|
597 |
-
<?php _e( 'Testimonial', 'wp-mail-logging' );?>:
|
598 |
-
<i>
|
599 |
-
<?php _e( 'Thanks for this awesome plugin, love love love how it integrates with WordPress. I seriously spent days if not weeks on Mailchimp, and still haven’t been able to do what I did on MailPoet in 1 hour!', 'wp-mail-logging' );?>
|
600 |
-
</i>
|
601 |
-
— Kida Shey
|
602 |
-
</p>
|
603 |
<?php
|
604 |
}
|
605 |
|
606 |
-
private function displayMP3BannerVersionB() {
|
607 |
-
?>
|
608 |
-
<p>
|
609 |
-
<?php _e( 'Create beautiful email campaigns and reach your audience in a breeze with the MailPoet plugin. MailPoet is used by over 300,000 website owners making it the most popular email marketing solution in WordPress. Send beautiful newsletter, notify your readers about last articles and increase your WooCommerce sales!', 'wp-mail-logging' );?>
|
610 |
-
</p>
|
611 |
-
<p>
|
612 |
-
<a href="?page=wpml_plugin_log&redirect=free-plan&ref=wml_2" target="_blank" class="button button-primary">
|
613 |
-
<?php _e( 'Discover MailPoet for free', 'wp-mail-logging' );?>
|
614 |
-
</a>
|
615 |
-
</p>
|
616 |
-
<?php
|
617 |
-
}
|
618 |
-
|
619 |
-
private function redirectToFreePlan() {
|
620 |
-
if (
|
621 |
-
is_array($_GET)
|
622 |
-
&& array_key_exists('redirect', $_GET)
|
623 |
-
&& array_key_exists('ref', $_GET)
|
624 |
-
&& $_GET['redirect'] === 'free-plan'
|
625 |
-
) {
|
626 |
-
add_option('MAILPOET_REFERRAL_ID', 'wml');
|
627 |
-
wp_redirect( 'https://www.mailpoet.com/free-plan?ref=' . $_GET['ref'] );
|
628 |
-
exit;
|
629 |
-
}
|
630 |
-
}
|
631 |
-
|
632 |
/**
|
633 |
* Override this method and follow its format.
|
634 |
* The purpose of this method is to provide i18n display strings for the values of options.
|
415 |
wp_die(__('You do not have sufficient permissions to access this page.', 'wp-mail-logging'));
|
416 |
}
|
417 |
|
|
|
|
|
418 |
if (!class_exists( 'Email_Log_List_Table' ) ) {
|
419 |
require_once ( plugin_dir_path( __FILE__ ) . 'WPML_Email_Log_List.php' );
|
420 |
}
|
535 |
$emailLogList->display();
|
536 |
?>
|
537 |
</form>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
538 |
<?php
|
539 |
}
|
540 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
541 |
/**
|
542 |
* Override this method and follow its format.
|
543 |
* The purpose of this method is to provide i18n display strings for the values of options.
|
src/inc/redux/WPML_Redux_Framework_config.php
CHANGED
@@ -334,7 +334,7 @@ if (!class_exists('WPML_Redux_Framework_config')) {
|
|
334 |
|
335 |
// SOCIAL ICONS -> Setup custom links in the footer for quick links in your panel footer icons.
|
336 |
$this->args['share_icons'][] = array(
|
337 |
-
'url' => 'https://github.com/
|
338 |
'title' => 'Visit us on GitHub',
|
339 |
'icon' => 'el-icon-github'
|
340 |
//'img' => '', // You can use icon OR img. IMG needs to be a full URL.
|
334 |
|
335 |
// SOCIAL ICONS -> Setup custom links in the footer for quick links in your panel footer icons.
|
336 |
$this->args['share_icons'][] = array(
|
337 |
+
'url' => 'https://github.com/kgjerstad/wp-mail-logging',
|
338 |
'title' => 'Visit us on GitHub',
|
339 |
'icon' => 'el-icon-github'
|
340 |
//'img' => '', // You can use icon OR img. IMG needs to be a full URL.
|
tests/helper/WPML_IntegrationTestCase.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Helper;
|
4 |
+
|
5 |
+
use No3x\WPML\WPML_Plugin;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class WPML_UnitTestCase
|
9 |
+
* @package No3x\WPML\Tests\Helper
|
10 |
+
* @group ignore
|
11 |
+
*/
|
12 |
+
class WPML_IntegrationTestCase extends \WP_UnitTestCase {
|
13 |
+
|
14 |
+
/** @var WPML_Plugin */
|
15 |
+
private $plugin;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @return WPML_Plugin
|
19 |
+
*/
|
20 |
+
public function getPlugin() {
|
21 |
+
return $this->plugin;
|
22 |
+
}
|
23 |
+
|
24 |
+
function setUp() {
|
25 |
+
parent::setUp();
|
26 |
+
|
27 |
+
$this->plugin = apply_filters('wpml_get_di_service', 'plugin' );
|
28 |
+
|
29 |
+
if( ! isset( $_SERVER['SERVER_NAME'] ) ) {
|
30 |
+
$_SERVER['SERVER_NAME'] = 'vvv';
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
function tearDown() {
|
35 |
+
parent::tearDown();
|
36 |
+
}
|
37 |
+
}
|
tests/helper/WPMailArrayBuilder.php
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Helper;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class WPMailArrayBuilder builds message arrays as they are applied to the wp_mail filter.
|
7 |
+
* @package No3x\WPML\Tests
|
8 |
+
*/
|
9 |
+
class WPMailArrayBuilder {
|
10 |
+
private $to;
|
11 |
+
private $subject;
|
12 |
+
private $message;
|
13 |
+
private $headers;
|
14 |
+
private $attachments;
|
15 |
+
|
16 |
+
private function __construct() {
|
17 |
+
$this->to = 'example@exmple.com';
|
18 |
+
$this->subject = 'The subject';
|
19 |
+
$this->message = 'This is a message';
|
20 |
+
$this->headers = '';
|
21 |
+
$this->attachments = [];
|
22 |
+
}
|
23 |
+
|
24 |
+
public static function aMail() {
|
25 |
+
return new WPMailArrayBuilder();
|
26 |
+
}
|
27 |
+
|
28 |
+
public function withTo($to) {
|
29 |
+
$this->to = $to;
|
30 |
+
return $this;
|
31 |
+
}
|
32 |
+
|
33 |
+
public function withSubject($subject) {
|
34 |
+
$this->subject = $subject;
|
35 |
+
return $this;
|
36 |
+
}
|
37 |
+
|
38 |
+
public function withMessage($message) {
|
39 |
+
$this->message = $message;
|
40 |
+
return $this;
|
41 |
+
}
|
42 |
+
|
43 |
+
public function withNoHeaders() {
|
44 |
+
$this->headers = '';
|
45 |
+
return $this;
|
46 |
+
}
|
47 |
+
|
48 |
+
public function withHeaders($headers) {
|
49 |
+
$this->headers = $headers;
|
50 |
+
return $this;
|
51 |
+
}
|
52 |
+
|
53 |
+
public function withNoAttachments() {
|
54 |
+
$this->attachments = '';
|
55 |
+
return $this;
|
56 |
+
}
|
57 |
+
|
58 |
+
public function withAttachments($attachments) {
|
59 |
+
$this->attachments = $attachments;
|
60 |
+
return $this;
|
61 |
+
}
|
62 |
+
|
63 |
+
public function but() {
|
64 |
+
return WPMailArrayBuilder::aMail()
|
65 |
+
->withTo($this->to)
|
66 |
+
->withSubject($this->subject)
|
67 |
+
->withMessage($this->message)
|
68 |
+
->withHeaders($this->headers)
|
69 |
+
->withAttachments($this->attachments);
|
70 |
+
}
|
71 |
+
|
72 |
+
public function build() {
|
73 |
+
return [
|
74 |
+
'to' => $this->to,
|
75 |
+
'subject' => $this->subject,
|
76 |
+
'message' => $this->message,
|
77 |
+
'headers' => $this->headers,
|
78 |
+
'attachments' => $this->attachments
|
79 |
+
];
|
80 |
+
}
|
81 |
+
|
82 |
+
public function buildAsMandrillMail() {
|
83 |
+
$mandrillMail = $this->build();
|
84 |
+
$mandrillMail['html'] = $mandrillMail['message'];
|
85 |
+
unset($mandrillMail['message']);
|
86 |
+
return $mandrillMail;
|
87 |
+
}
|
88 |
+
|
89 |
+
public function buildWithoutHeaders() {
|
90 |
+
$mailArray = $this->build();
|
91 |
+
unset($mailArray['headers']);
|
92 |
+
return $mailArray;
|
93 |
+
}
|
94 |
+
|
95 |
+
public function buildWithoutAttachments() {
|
96 |
+
$mailArray = $this->build();
|
97 |
+
unset($mailArray['attachments']);
|
98 |
+
return $mailArray;
|
99 |
+
}
|
100 |
+
|
101 |
+
public function buildWithoutMessage() {
|
102 |
+
$mailArray = $this->build();
|
103 |
+
unset($mailArray['message']);
|
104 |
+
return $mailArray;
|
105 |
+
}
|
106 |
+
|
107 |
+
}
|
tests/phpunit/includes/bootstrap.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* PHPUnit tests bootstrap.
|
5 |
+
*/
|
6 |
+
|
7 |
+
/**
|
8 |
+
* The Composer-generated autoloader.
|
9 |
+
*/
|
10 |
+
echo "Executing wp-mail-logging Test Suite" . PHP_EOL;
|
11 |
+
|
12 |
+
ini_set('error_reporting', E_ALL); // or error_reporting(E_ALL);
|
13 |
+
ini_set('display_errors', '1');
|
14 |
+
ini_set('display_startup_errors', '1');
|
15 |
+
|
16 |
+
require_once( dirname( __FILE__ ) . '/../../../vendor/autoload.php' );
|
17 |
+
|
18 |
+
$_tests_dir = getenv( 'WP_TESTS_DIR' );
|
19 |
+
|
20 |
+
if ( ! $_tests_dir ) {
|
21 |
+
$_tests_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib';
|
22 |
+
}
|
23 |
+
|
24 |
+
echo 'Tests folder: ' . $_tests_dir . PHP_EOL;
|
25 |
+
|
26 |
+
if ( ! file_exists( $_tests_dir . '/includes/functions.php' ) ) {
|
27 |
+
echo "Could not find $_tests_dir/includes/functions.php, have you run bin/install-wp-tests.sh ?";
|
28 |
+
exit( 1 );
|
29 |
+
}
|
30 |
+
|
31 |
+
// Give access to tests_add_filter() function.
|
32 |
+
require_once $_tests_dir . '/includes/functions.php';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Manually load the plugin being tested.
|
36 |
+
*/
|
37 |
+
function _manually_load_plugin() {
|
38 |
+
$path = dirname(dirname( dirname( dirname( __FILE__ ) ) ) ) . '/wp-mail-logging.php';
|
39 |
+
echo "Plugin path: " . $path;
|
40 |
+
require $path;
|
41 |
+
}
|
42 |
+
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
43 |
+
|
44 |
+
// Start up the WP testing environment.
|
45 |
+
require $_tests_dir . '/includes/bootstrap.php';
|
46 |
+
|
47 |
+
// EOF
|
tests/phpunit/integration/WPML_Hook_Remover_Test.php
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Integration;
|
4 |
+
|
5 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
6 |
+
use No3x\WPML\WPML_Hook_Remover;
|
7 |
+
|
8 |
+
class WPML_Hook_Remover_Test extends WPML_IntegrationTestCase {
|
9 |
+
|
10 |
+
private $tag;
|
11 |
+
private $callable;
|
12 |
+
|
13 |
+
public function setUp() {
|
14 |
+
parent::setUp();
|
15 |
+
$this->tag = 'wp_mail';
|
16 |
+
$this->callable = [$this, 'callback_function'];
|
17 |
+
add_filter( $this->tag, $this->callable );
|
18 |
+
}
|
19 |
+
|
20 |
+
public function tearDown() {
|
21 |
+
remove_filter( $this->tag, $this->callable );
|
22 |
+
parent::tearDown();
|
23 |
+
}
|
24 |
+
|
25 |
+
public function callback_function() {}
|
26 |
+
|
27 |
+
public function testRemove() {
|
28 |
+
// The result is true if the hook was removed and it was in place before
|
29 |
+
$result = (new WPML_Hook_Remover())->remove_class_hook($this->tag, __CLASS__, 'callback_function');
|
30 |
+
$this->assertTrue($result);
|
31 |
+
}
|
32 |
+
|
33 |
+
public function testNotExistentHook() {
|
34 |
+
// The result is true if the hook was removed and it was in place before
|
35 |
+
$result = (new WPML_Hook_Remover())->remove_class_hook($this->tag, __CLASS__, 'not_existent');
|
36 |
+
$this->assertFalse($result);
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
tests/phpunit/integration/WPML_IntegrationTestCase_Test.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Unit;
|
4 |
+
|
5 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
6 |
+
|
7 |
+
class WPML_IntegrationTestCase_Test extends WPML_IntegrationTestCase {
|
8 |
+
|
9 |
+
function test_PluginInitialization() {
|
10 |
+
$this->assertFalse( null === $this->getPlugin() );
|
11 |
+
$this->assertInstanceOf( '\\No3x\\WPML\\WPML_Plugin', $this->getPlugin() );
|
12 |
+
}
|
13 |
+
|
14 |
+
}
|
tests/phpunit/integration/WPML_LogRotation_Test.php
ADDED
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Integration;
|
4 |
+
|
5 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
6 |
+
use No3x\WPML\Model\WPML_Mail as Mail;
|
7 |
+
use No3x\WPML\WPML_LogRotation;
|
8 |
+
use Arrayzy\ImmutableArray;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Tests for LogRotation
|
12 |
+
* @author No3x
|
13 |
+
* @since 1.6.0
|
14 |
+
* Tests are written in the AAA-Rule
|
15 |
+
* There are three basic sections for our test: Arrange, Act, and Assert.
|
16 |
+
*/
|
17 |
+
class WPML_LogRotation_Test extends WPML_IntegrationTestCase {
|
18 |
+
|
19 |
+
private function prepareMessages( $amount ) {
|
20 |
+
$to = 'email@example.com';
|
21 |
+
$subject = "Message Nr. %d";
|
22 |
+
$message = "This is a sample message. It is the %d. of this kind.";
|
23 |
+
|
24 |
+
for( $i = 0; $i < $amount; $i++ ) {
|
25 |
+
wp_mail(
|
26 |
+
$to,
|
27 |
+
sprintf($subject, $i),
|
28 |
+
sprintf($message, $i)
|
29 |
+
);
|
30 |
+
}
|
31 |
+
// Check if preparation worked fine
|
32 |
+
$this->assertEquals($this->count_mails(), $amount);
|
33 |
+
}
|
34 |
+
|
35 |
+
private function count_mails() {
|
36 |
+
return Mail::query()->find(true);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Query some mails.
|
41 |
+
* @param int $amount number of mails to query.
|
42 |
+
* @return Mail[] array
|
43 |
+
*/
|
44 |
+
private function query_some_mails( $amount ) {
|
45 |
+
return Mail::query()
|
46 |
+
->sort_by( Mail::get_primary_key() )
|
47 |
+
->order( 'desc' )
|
48 |
+
->limit( $amount )
|
49 |
+
->find();
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Get latest mail.
|
54 |
+
* @return Mail
|
55 |
+
*/
|
56 |
+
private function latest_mail() {
|
57 |
+
return ImmutableArray::create(
|
58 |
+
Mail::query()
|
59 |
+
->sort_by( Mail::get_primary_key() )
|
60 |
+
->order( 'desc' )
|
61 |
+
->limit(1)
|
62 |
+
->find()
|
63 |
+
)->first();
|
64 |
+
}
|
65 |
+
/**
|
66 |
+
* Get oldest mail.
|
67 |
+
* @return Mail
|
68 |
+
*/
|
69 |
+
private function oldest_mail() {
|
70 |
+
return ImmutableArray::create(
|
71 |
+
Mail::query()
|
72 |
+
->sort_by( Mail::get_primary_key() )
|
73 |
+
->order( 'asc' )
|
74 |
+
->limit(1)
|
75 |
+
->find()
|
76 |
+
)->first();
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Test limitNumberOfMailsByAmount - Check if the number of kept messages is correct.
|
81 |
+
* The LogRotation supports the limitation of stored mails by amount.
|
82 |
+
* This test checks if the amount of left/deleted mails is correct.
|
83 |
+
* @since 1.6.0
|
84 |
+
* @see WPML_LogRotation::limitNumberOfMailsByAmount
|
85 |
+
*/
|
86 |
+
function test_limitNumberOfMailsByAmount_count() {
|
87 |
+
global $wpml_settings;
|
88 |
+
$amount = 10;
|
89 |
+
$keep = 3;
|
90 |
+
$this->prepareMessages( $amount );
|
91 |
+
|
92 |
+
$wpml_settings['log-rotation-limit-amout'] = '1';
|
93 |
+
$wpml_settings['log-rotation-limit-amout-keep'] = $keep;
|
94 |
+
|
95 |
+
$this->assertEquals($this->count_mails(), $amount);
|
96 |
+
WPML_LogRotation::limitNumberOfMailsByAmount();
|
97 |
+
$this->assertEquals($this->count_mails(), $keep);
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Test limitNumberOfMailsByAmount - Check if old messages where deleted first.
|
102 |
+
* The LogRotation supports the limitation of stored mails by amount.
|
103 |
+
* This test checks if old messages are deleted first by asserting that after the policy is run the oldest mail is gone.
|
104 |
+
* @since 1.6.0
|
105 |
+
* @see WPML_LogRotation::limitNumberOfMailsByAmount
|
106 |
+
*/
|
107 |
+
function test_limitNumberOfMailsByAmount_order() {
|
108 |
+
global $wpml_settings;
|
109 |
+
$amount = 10;
|
110 |
+
$keep = 3;
|
111 |
+
$this->prepareMessages( $amount );
|
112 |
+
$wpml_settings['log-rotation-limit-amout'] = '1';
|
113 |
+
$wpml_settings['log-rotation-limit-amout-keep'] = $keep;
|
114 |
+
$oldest_mail_id = $this->oldest_mail()->get_mail_id();
|
115 |
+
|
116 |
+
WPML_LogRotation::limitNumberOfMailsByAmount();
|
117 |
+
|
118 |
+
// Assert oldest mail is gone.
|
119 |
+
$this->assertFalse( Mail::find_one( $oldest_mail_id ) );
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Test limitNumberOfMailsByTime - Check if all old messages where deleted.
|
124 |
+
* The LogRotation supports the limitation of stored mails by date.
|
125 |
+
* This test checks of old messages are deleted after given time by comparing the amount of mails.
|
126 |
+
* @since 1.6.0
|
127 |
+
* @see WPML_LogRotation::limitNumberOfMailsByTime
|
128 |
+
*/
|
129 |
+
function test_limitNumberOfMailsByTime_order() {
|
130 |
+
global $wpml_settings;
|
131 |
+
$amount = 10;
|
132 |
+
$old = 3;
|
133 |
+
$days = 5;
|
134 |
+
$this->prepareMessages( $amount );
|
135 |
+
$wpml_settings['log-rotation-delete-time'] = '1';
|
136 |
+
$wpml_settings['log-rotation-delete-time-days'] = $days;
|
137 |
+
|
138 |
+
// Make #$old mails #$days older:
|
139 |
+
foreach( $this->query_some_mails( $old ) as $mail ) {
|
140 |
+
$mail->set_timestamp( gmdate( 'Y-m-d H:i:s', ( time() + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) - ($days+1) * DAY_IN_SECONDS ) ) )
|
141 |
+
->save();
|
142 |
+
}
|
143 |
+
|
144 |
+
WPML_LogRotation::limitNumberOfMailsByTime();
|
145 |
+
|
146 |
+
// Assert that there are just $amount-$old mails left.
|
147 |
+
$this->assertEquals( $amount-$old, $this->count_mails() );
|
148 |
+
}
|
149 |
+
}
|
tests/phpunit/integration/WPML_MailRenderer_AJAX_Handler_Test.php
ADDED
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Integration;
|
4 |
+
|
5 |
+
|
6 |
+
use Mockery;
|
7 |
+
use No3x\WPML\Renderer\WPML_MailRenderer_AJAX_Handler;
|
8 |
+
use No3x\WPML\Renderer\WPML_MailRenderer;
|
9 |
+
|
10 |
+
use \Exception;
|
11 |
+
use WPAjaxDieContinueException;
|
12 |
+
|
13 |
+
class WPML_MailRenderer_AJAX_Handler_Test extends \WP_Ajax_UnitTestCase {
|
14 |
+
|
15 |
+
/** @var WPML_MailRenderer */
|
16 |
+
private $mailRendererMock;
|
17 |
+
/** @var WPML_MailRenderer_AJAX_Handler */
|
18 |
+
private $mailRendererAjaxHandler;
|
19 |
+
private $valid_id = 2;
|
20 |
+
|
21 |
+
public function setUp() {
|
22 |
+
parent::setUp();
|
23 |
+
|
24 |
+
$this->mailRendererMock = Mockery::mock('No3x\WPML\Renderer\WPML_MailRenderer');
|
25 |
+
|
26 |
+
$this->mailRendererMock->shouldReceive('getSupportedFormats')
|
27 |
+
->andReturn(['raw', 'html']);
|
28 |
+
|
29 |
+
$this->mailRendererAjaxHandler = new WPML_MailRenderer_AJAX_Handler($this->mailRendererMock, []);
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Test that the callback saves the value for administrators.
|
34 |
+
*/
|
35 |
+
public function test_nonce_invalid() {
|
36 |
+
$_POST['_wpnonce'] = $this->mailRendererAjaxHandler->get_ajax_data()["nonce"] . "invalid";
|
37 |
+
|
38 |
+
try {
|
39 |
+
$this->_handleAjax( WPML_MailRenderer_AJAX_Handler::ACTION );
|
40 |
+
$this->fail( 'Expected exception: WPAjaxDieContinueException' );
|
41 |
+
} catch ( WPAjaxDieContinueException $e ) {
|
42 |
+
// We expected this, do nothing.
|
43 |
+
}//end try
|
44 |
+
|
45 |
+
$this->checkJsonMessage();
|
46 |
+
$response = json_decode($this->_last_response, true);
|
47 |
+
$this->assertEquals(WPML_MailRenderer_AJAX_Handler::ERROR_NONCE_CODE, $response['data']['code']);
|
48 |
+
$this->assertEquals(WPML_MailRenderer_AJAX_Handler::ERROR_NONCE_MESSAGE, $response['data']['message']);
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Test that the callback saves the value for administrators.
|
53 |
+
*/
|
54 |
+
public function test_id_not_passed() {
|
55 |
+
$_POST['_wpnonce'] = $this->mailRendererAjaxHandler->get_ajax_data()["nonce"];
|
56 |
+
|
57 |
+
try {
|
58 |
+
$this->_handleAjax( WPML_MailRenderer_AJAX_Handler::ACTION );
|
59 |
+
$this->fail( 'Expected exception: WPAjaxDieContinueException' );
|
60 |
+
} catch ( WPAjaxDieContinueException $e ) {
|
61 |
+
// We expected this, do nothing.
|
62 |
+
}//end try
|
63 |
+
|
64 |
+
$this->checkJsonMessage();
|
65 |
+
$response = json_decode($this->_last_response, true);
|
66 |
+
$this->assertEquals(WPML_MailRenderer_AJAX_Handler::ERROR_ID_MISSING_CODE, $response['data']['code']);
|
67 |
+
$this->assertEquals(WPML_MailRenderer_AJAX_Handler::ERROR_ID_MISSING_MESSAGE, $response['data']['message']);
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Test that the callback saves the value for administrators.
|
72 |
+
*/
|
73 |
+
public function test_invalid_id_passed() {
|
74 |
+
$invalid_id = -1;
|
75 |
+
$this->mailRendererMock->shouldReceive('render')
|
76 |
+
->withArgs([$invalid_id, 'html'])
|
77 |
+
->times(1)
|
78 |
+
->andThrow("\Exception", "Requested mail not found in database.");
|
79 |
+
|
80 |
+
$_POST['_wpnonce'] = $this->mailRendererAjaxHandler->get_ajax_data()["nonce"];
|
81 |
+
$_POST['format'] = 'html';
|
82 |
+
$_POST['id'] = $invalid_id;
|
83 |
+
|
84 |
+
try {
|
85 |
+
$this->_handleAjax( WPML_MailRenderer_AJAX_Handler::ACTION );
|
86 |
+
$this->fail( 'Expected exception: WPAjaxDieContinueException' );
|
87 |
+
} catch ( WPAjaxDieContinueException $e ) {
|
88 |
+
// We expected this, do nothing.
|
89 |
+
}//end try
|
90 |
+
|
91 |
+
$this->checkJsonMessage();
|
92 |
+
$response = json_decode($this->_last_response, true);
|
93 |
+
$this->assertEquals(WPML_MailRenderer_AJAX_Handler::ERROR_OTHER_CODE, $response['data']['code']);
|
94 |
+
$this->assertEquals("Requested mail not found in database.", $response['data']['message']);
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Test that the callback saves the value for administrators.
|
99 |
+
*/
|
100 |
+
public function test_unknown_format_passed() {
|
101 |
+
$this->mailRendererMock->shouldReceive('render')
|
102 |
+
->withAnyArgs()
|
103 |
+
->times(1)
|
104 |
+
->andReturn("rendered");
|
105 |
+
|
106 |
+
$_POST['_wpnonce'] = $this->mailRendererAjaxHandler->get_ajax_data()["nonce"];
|
107 |
+
$_POST['id'] = $this->valid_id;
|
108 |
+
$_POST['format'] = 'no-valid-format';
|
109 |
+
|
110 |
+
try {
|
111 |
+
$this->_handleAjax( WPML_MailRenderer_AJAX_Handler::ACTION );
|
112 |
+
$this->fail( 'Expected exception: WPAjaxDieContinueException' );
|
113 |
+
} catch ( WPAjaxDieContinueException $e ) {
|
114 |
+
// We expected this, do nothing.
|
115 |
+
}//end try
|
116 |
+
|
117 |
+
$this->checkJsonMessage();
|
118 |
+
$response = json_decode($this->_last_response, true);
|
119 |
+
$this->assertEquals(WPML_MailRenderer_AJAX_Handler::ERROR_UNKNOWN_FORMAT_CODE, $response['data']['code']);
|
120 |
+
$this->assertEquals(WPML_MailRenderer_AJAX_Handler::ERROR_UNKNOWN_FORMAT_MESSAGE, $response['data']['message']);
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Test that the callback saves the value for administrators.
|
125 |
+
*/
|
126 |
+
public function test_render_is_called() {
|
127 |
+
$this->mailRendererMock->shouldReceive('render')
|
128 |
+
->withArgs([$this->valid_id, 'html'])
|
129 |
+
->times(1)
|
130 |
+
->andReturn("rendered");
|
131 |
+
|
132 |
+
$_POST['_wpnonce'] = $this->mailRendererAjaxHandler->get_ajax_data()["nonce"];
|
133 |
+
$_POST['id'] = $this->valid_id;
|
134 |
+
$_POST['format'] = 'html';
|
135 |
+
|
136 |
+
try {
|
137 |
+
$this->_handleAjax( WPML_MailRenderer_AJAX_Handler::ACTION );
|
138 |
+
$this->fail( 'Expected exception: WPAjaxDieContinueException' );
|
139 |
+
} catch ( WPAjaxDieContinueException $e ) {
|
140 |
+
// We expected this, do nothing.
|
141 |
+
}//end try
|
142 |
+
|
143 |
+
$this->checkJsonMessage(true);
|
144 |
+
$response = json_decode($this->_last_response, true);
|
145 |
+
$this->mailRendererMock->mockery_verify();
|
146 |
+
$this->assertEquals("rendered", $response['data']);
|
147 |
+
}
|
148 |
+
|
149 |
+
private function checkJsonMessage($success_expected = false) {
|
150 |
+
$this->assertJson( $this->_last_response );
|
151 |
+
$response = json_decode( $this->_last_response, true );
|
152 |
+
if( $success_expected ) {
|
153 |
+
$this->assertTrue( $response['success'] );
|
154 |
+
$this->assertArrayHasKey('data', $response);
|
155 |
+
} else {
|
156 |
+
$this->assertFalse( $response['success'] );
|
157 |
+
$this->assertArrayHasKey('code', $response["data"]);
|
158 |
+
$this->assertArrayHasKey('message', $response["data"]);
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
}
|
tests/phpunit/integration/WPML_Plugin_Test.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Integration;
|
4 |
+
|
5 |
+
|
6 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
7 |
+
use No3x\WPML\WPML_Plugin;
|
8 |
+
|
9 |
+
class WPML_Plugin_Test extends WPML_IntegrationTestCase {
|
10 |
+
|
11 |
+
function test_log_email() {
|
12 |
+
global $wpdb;
|
13 |
+
$tableName = WPML_Plugin::getTablename( 'mails' );
|
14 |
+
|
15 |
+
$to = array(
|
16 |
+
'email@example.com',
|
17 |
+
'email2@example.com'
|
18 |
+
);
|
19 |
+
|
20 |
+
$subject = rand_str();
|
21 |
+
$message = "Hello, this is a test message";
|
22 |
+
|
23 |
+
wp_mail($to, $subject, $message);
|
24 |
+
|
25 |
+
$rows = $wpdb->get_results( "SELECT * FROM $tableName WHERE subject = '{$subject}'" );
|
26 |
+
|
27 |
+
$count = count( $rows );
|
28 |
+
$this->assertEquals( 1, $count);
|
29 |
+
|
30 |
+
$row = $rows[0];
|
31 |
+
$this->assertEquals( $subject, $row->subject );
|
32 |
+
$this->assertEquals( $message, $row->message );
|
33 |
+
|
34 |
+
$this->assertTrue( strpos( $row->receiver, $to[0] ) !== false );
|
35 |
+
$this->assertTrue( strpos( $row->receiver, $to[1] ) !== false );
|
36 |
+
}
|
37 |
+
|
38 |
+
function test_charset_email() {
|
39 |
+
global $wpdb;
|
40 |
+
$tableName = WPML_Plugin::getTablename( 'mails' );
|
41 |
+
|
42 |
+
$to = array(
|
43 |
+
'email@example.com',
|
44 |
+
'email2@example.com'
|
45 |
+
);
|
46 |
+
|
47 |
+
$subject = rand_str();
|
48 |
+
$message = "Řekl, že přijde, jestliže v konkurzu zvítězí";
|
49 |
+
|
50 |
+
wp_mail($to, $subject, $message);
|
51 |
+
|
52 |
+
$rows = $wpdb->get_results( "SELECT * FROM $tableName" );
|
53 |
+
$row = $rows[0];
|
54 |
+
|
55 |
+
$this->assertTrue( strpos( $row->message, "?" ) === false );
|
56 |
+
|
57 |
+
}
|
58 |
+
}
|
tests/phpunit/integration/test-core-settings.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Integration;
|
4 |
+
|
5 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
6 |
+
use No3x\WPML\WPML_Plugin;
|
7 |
+
use No3x\WPML\WPML_InstallIndicator;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @author No3x
|
11 |
+
* Tests are written in the AAA-Rule
|
12 |
+
* There are three basic sections for our test: Arrange, Act, and Assert.
|
13 |
+
*/
|
14 |
+
class WPML_Plugin_CoreSettings extends WPML_IntegrationTestCase {
|
15 |
+
|
16 |
+
function test_getInstalled() {
|
17 |
+
|
18 |
+
$this->assertEquals( 'WPML_Plugin__installed', $this->getPlugin()->prefix( WPML_InstallIndicator::optionInstalled ) );
|
19 |
+
$this->assertEquals( 'WPML_Plugin__version', $this->getPlugin()->prefix( WPML_InstallIndicator::optionVersion ) );
|
20 |
+
|
21 |
+
}
|
22 |
+
}
|
tests/phpunit/unit/WPML_Attachment_Test.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests;
|
4 |
+
|
5 |
+
|
6 |
+
use No3x\WPML\WPML_Attachment;
|
7 |
+
|
8 |
+
class WPML_Attachment_Test extends \PHPUnit_Framework_TestCase {
|
9 |
+
|
10 |
+
/** @var $fsMock \No3x\WPML\FS\IFilesystem |\Mockery\MockInterface */
|
11 |
+
private $fsMock;
|
12 |
+
|
13 |
+
function setUp()
|
14 |
+
{
|
15 |
+
parent::setUp();
|
16 |
+
|
17 |
+
$this->fsMock = self::getMockBuilder('No3x\WPML\FS\IFilesystem')
|
18 |
+
->disableOriginalConstructor()
|
19 |
+
->getMock()
|
20 |
+
;
|
21 |
+
|
22 |
+
WPML_Attachment::setFS($this->fsMock);
|
23 |
+
}
|
24 |
+
|
25 |
+
|
26 |
+
public function test_fromRelativePath() {
|
27 |
+
|
28 |
+
$this->fsMock->expects(self::once())
|
29 |
+
->method('is_file')
|
30 |
+
->willReturn(true)
|
31 |
+
;
|
32 |
+
|
33 |
+
// The mimetype should not be determined, if it's not a file
|
34 |
+
$this->fsMock->expects(self::once())
|
35 |
+
->method('mime_content_type')
|
36 |
+
->willReturn('image/png')
|
37 |
+
;
|
38 |
+
|
39 |
+
$path = "/uploads/2000/04/image.png";
|
40 |
+
|
41 |
+
$attachment = WPML_Attachment::fromRelPath($path);
|
42 |
+
$this->assertFalse($attachment->isGone());
|
43 |
+
$this->assertEquals("image", $attachment->getIconClass());
|
44 |
+
$this->assertEquals(WP_CONTENT_DIR . '/uploads' . $path, $attachment->getPath());
|
45 |
+
}
|
46 |
+
|
47 |
+
public function test_fromRelativePath_InvalidPath() {
|
48 |
+
|
49 |
+
$this->fsMock->expects(self::once())
|
50 |
+
->method('is_file')
|
51 |
+
->willReturn(false)
|
52 |
+
;
|
53 |
+
|
54 |
+
// The mimetype should not be determined, if it's not a file
|
55 |
+
$this->fsMock->expects(self::never())
|
56 |
+
->method('mime_content_type')
|
57 |
+
;
|
58 |
+
|
59 |
+
$path = "/invalid";
|
60 |
+
|
61 |
+
$attachment = WPML_Attachment::fromRelPath($path);
|
62 |
+
$this->assertTrue($attachment->isGone());
|
63 |
+
$this->assertEquals("file", $attachment->getIconClass());
|
64 |
+
$this->assertEquals("/invalid", $attachment->getPath());
|
65 |
+
}
|
66 |
+
|
67 |
+
function test_fromAbsolutePath() {
|
68 |
+
|
69 |
+
$this->fsMock->expects(self::never())
|
70 |
+
->method('is_file')
|
71 |
+
;
|
72 |
+
|
73 |
+
// The mimetype should not be determined, if it's not a file
|
74 |
+
$this->fsMock->expects(self::once())
|
75 |
+
->method('mime_content_type')
|
76 |
+
->willReturn('image/png')
|
77 |
+
;
|
78 |
+
|
79 |
+
$path = WP_CONTENT_DIR . '/uploads/2000/04/image.png';
|
80 |
+
|
81 |
+
$attachment = WPML_Attachment::fromAbsPath($path);
|
82 |
+
$this->assertFalse($attachment->isGone());
|
83 |
+
$this->assertEquals("image", $attachment->getIconClass());
|
84 |
+
$this->assertEquals($path, $attachment->getPath());
|
85 |
+
|
86 |
+
}
|
87 |
+
|
88 |
+
function test_fromAbsolutePath_InvalidPath() {
|
89 |
+
|
90 |
+
$this->fsMock->expects(self::never())
|
91 |
+
->method('is_file')
|
92 |
+
;
|
93 |
+
|
94 |
+
// The mimetype should not be determined, if it's not a file
|
95 |
+
$this->fsMock->expects(self::once())
|
96 |
+
->method('mime_content_type')
|
97 |
+
->willReturn(false)
|
98 |
+
;
|
99 |
+
|
100 |
+
$path = WP_CONTENT_DIR . '/a/file/somewhere/else.png';
|
101 |
+
$path = WP_CONTENT_DIR . '../../else.png';
|
102 |
+
|
103 |
+
$attachment = WPML_Attachment::fromAbsPath($path);
|
104 |
+
$this->assertEquals("file", $attachment->getIconClass());
|
105 |
+
$this->assertEquals($path, $attachment->getPath());
|
106 |
+
$this->assertEquals("else.png", $attachment->toRelPath());
|
107 |
+
|
108 |
+
}
|
109 |
+
|
110 |
+
}
|
tests/phpunit/unit/WPML_ColumnManager_Test.php
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests;
|
4 |
+
|
5 |
+
|
6 |
+
use No3x\WPML\Model\WPML_Mail;
|
7 |
+
use No3x\WPML\Renderer\Column\ColumnFormat;
|
8 |
+
use No3x\WPML\Renderer\Exception\ColumnDoesntExistException;
|
9 |
+
use No3x\WPML\Renderer\WPML_ColumnManager;
|
10 |
+
use No3x\WPML\Tests\Helper\WPMailArrayBuilder;
|
11 |
+
use No3x\WPML\WPML_MailExtractor;
|
12 |
+
|
13 |
+
class WPML_ColumnManager_Test extends \PHPUnit_Framework_TestCase {
|
14 |
+
|
15 |
+
private $columnManager;
|
16 |
+
/** @var WPML_Mail */
|
17 |
+
private $mail;
|
18 |
+
private $item;
|
19 |
+
|
20 |
+
public function setUp() {
|
21 |
+
$this->columnManager = new WPML_ColumnManager();
|
22 |
+
|
23 |
+
$exampleAttachment1 = WP_CONTENT_DIR . '/uploads/2018/05/file.pdf';
|
24 |
+
$exampleAttachment2 = WP_CONTENT_DIR . '/uploads/2018/01/bill.pdf';
|
25 |
+
|
26 |
+
$mailArrayBuilder = WPMailArrayBuilder::aMail()
|
27 |
+
->withSubject("Test")
|
28 |
+
->withTo("example@exmple.com")
|
29 |
+
->withMessage("<b>Bold</b>")
|
30 |
+
->withHeaders("From: \"admin\" <admin@local.test>\r\n,\nCc: example2@example.com,\nReply-To: admin <admin@local.test>\r\n")
|
31 |
+
->withAttachments([$exampleAttachment1, $exampleAttachment2])
|
32 |
+
;
|
33 |
+
|
34 |
+
/** @var $mail WPML_Mail */
|
35 |
+
$mail = (new WPML_MailExtractor())->extract($mailArrayBuilder->build());
|
36 |
+
$mail->set_mail_id(2);
|
37 |
+
$mail->set_plugin_version('1.8.5');
|
38 |
+
$mail->set_timestamp('2018-09-24 16:02:11');
|
39 |
+
$mail->set_host('127.0.0.1');
|
40 |
+
$mail->set_error('bli');
|
41 |
+
|
42 |
+
$this->item = $mail->to_array();
|
43 |
+
}
|
44 |
+
|
45 |
+
public function test_columns() {
|
46 |
+
$columns = ['mail_id', 'timestamp', 'host', 'receiver', 'subject', 'message', 'headers', 'attachments', 'error', 'plugin_version'];
|
47 |
+
$this->assertEquals($columns, $this->columnManager->getColumnNames());
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @requires PHPUnit 5.2
|
52 |
+
*/
|
53 |
+
public function test_nonexistentdata() {
|
54 |
+
$column_name = 'host';
|
55 |
+
unset($this->item[$column_name]);
|
56 |
+
$this->expectException(ColumnDoesntExistException::get_class());
|
57 |
+
$this->expectExceptionMessage(sprintf(ColumnDoesntExistException::MESSAGE, $column_name));
|
58 |
+
$this->columnManager->getColumnRenderer($column_name)->render($this->item, ColumnFormat::FULL);
|
59 |
+
}
|
60 |
+
|
61 |
+
public function test_column_host() {
|
62 |
+
$actual = $this->columnManager->getColumnRenderer(WPML_ColumnManager::COLUMN_HOST)->render($this->item, ColumnFormat::FULL);
|
63 |
+
$this->assertEquals('127.0.0.1', $actual);
|
64 |
+
}
|
65 |
+
|
66 |
+
//TODO: need to test both time formats
|
67 |
+
public function test_column_timestamp() {
|
68 |
+
$actual = $this->columnManager->getColumnRenderer(WPML_ColumnManager::COLUMN_TIMESTAMP)->render($this->item, ColumnFormat::FULL);
|
69 |
+
$this->assertEquals('2018-09-24 16:02:11', $actual);
|
70 |
+
}
|
71 |
+
|
72 |
+
public function test_column_attachments_simple() {
|
73 |
+
$example1And2Expected = '/2018/05/file.pdf,\n/2018/01/bill.pdf';
|
74 |
+
$actual = $this->columnManager->getColumnRenderer(WPML_ColumnManager::COLUMN_ATTACHMENTS)->render($this->item, ColumnFormat::SIMPLE);
|
75 |
+
$this->assertEquals($example1And2Expected, $actual);
|
76 |
+
}
|
77 |
+
|
78 |
+
public function test_column_attachments_full() {
|
79 |
+
$example1And2Expected = '<i class="fa fa-times" title="Attachment file.pdf is not present"></i><i class="fa fa-times" title="Attachment bill.pdf is not present"></i>';
|
80 |
+
$actual = $this->columnManager->getColumnRenderer(WPML_ColumnManager::COLUMN_ATTACHMENTS)->render($this->item, ColumnFormat::FULL);
|
81 |
+
$this->assertEquals($example1And2Expected, $actual);
|
82 |
+
}
|
83 |
+
|
84 |
+
public function test_column_error_simple() {
|
85 |
+
$example1And2Expected = "bli";
|
86 |
+
$actual = $this->columnManager->getColumnRenderer(WPML_ColumnManager::COLUMN_ERROR)->render($this->item, ColumnFormat::SIMPLE);
|
87 |
+
$this->assertEquals($example1And2Expected, $actual);
|
88 |
+
}
|
89 |
+
|
90 |
+
public function test_column_error_empty() {
|
91 |
+
$expected = '';
|
92 |
+
$this->item['error'] = "";
|
93 |
+
$this->assertEquals($expected, $this->columnManager->getColumnRenderer(WPML_ColumnManager::COLUMN_ERROR)->render($this->item, ColumnFormat::FULL));
|
94 |
+
}
|
95 |
+
|
96 |
+
public function test_column_error_full() {
|
97 |
+
$example1And2Expected = '<i class="fa fa-exclamation-circle" title="bli"></i>';
|
98 |
+
$actual = $this->columnManager->getColumnRenderer(WPML_ColumnManager::COLUMN_ERROR)->render($this->item, ColumnFormat::FULL);
|
99 |
+
$this->assertEquals($example1And2Expected, $actual);
|
100 |
+
}
|
101 |
+
}
|
tests/phpunit/unit/WPML_Email_Log_List_Test.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace No3x\WPML\Tests;
|
3 |
+
|
4 |
+
|
5 |
+
use No3x\WPML\Model\WPML_Mail;
|
6 |
+
use No3x\WPML\Tests\Helper\WPMailArrayBuilder;
|
7 |
+
use No3x\WPML\WPML_Email_Log_List;
|
8 |
+
use No3x\WPML\WPML_MailExtractor;
|
9 |
+
|
10 |
+
class WPML_Email_Log_List_Test extends \PHPUnit_Framework_TestCase {
|
11 |
+
|
12 |
+
private $logListTable;
|
13 |
+
|
14 |
+
private $item;
|
15 |
+
private $item_id;
|
16 |
+
|
17 |
+
public function setUp() {
|
18 |
+
$this->logListTable = new WPML_Email_Log_List(null);
|
19 |
+
|
20 |
+
$this->item_id = 2;
|
21 |
+
|
22 |
+
$wpMailArrayBuilder = WPMailArrayBuilder::aMail()
|
23 |
+
->withSubject("Test")
|
24 |
+
->withTo("example@exmple.com")
|
25 |
+
->withMessage("Hello World")
|
26 |
+
;
|
27 |
+
/** @var $mail WPML_Mail */
|
28 |
+
$mail = (new WPML_MailExtractor())->extract($wpMailArrayBuilder->build());
|
29 |
+
$mail->set_mail_id($this->item_id);
|
30 |
+
|
31 |
+
$this->item = $mail->to_array();
|
32 |
+
}
|
33 |
+
|
34 |
+
public function test_column_message() {
|
35 |
+
$expected = '<a class="wp-mail-logging-view-message button button-secondary" href="#" data-mail-id="' . $this->item_id . '">View</a>';
|
36 |
+
$this->assertEquals($expected, $this->logListTable->column_message($this->item));
|
37 |
+
}
|
38 |
+
}
|
tests/phpunit/unit/WPML_Email_Resender_Test.php
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Unit;
|
4 |
+
|
5 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
6 |
+
use No3x\WPML\WPML_Email_Resender;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Test resend feature.
|
10 |
+
*/
|
11 |
+
|
12 |
+
class WPML_Email_Resender_Test extends \PHPUnit_Framework_TestCase {
|
13 |
+
|
14 |
+
/** @var WPML_Email_Resender $emailResender */
|
15 |
+
private $emailResender;
|
16 |
+
|
17 |
+
/** @var \No3x\WPML\WPML_Email_Dispatcher $dispatcherMock */
|
18 |
+
private $dispatcherMock;
|
19 |
+
|
20 |
+
/** @var \No3x\WPML\Model\WPML_Mail|\PHPUnit_Framework_MockObject_MockObject $mailMock */
|
21 |
+
private $mailMock;
|
22 |
+
|
23 |
+
function setUp() {
|
24 |
+
parent::setUp();
|
25 |
+
$this->dispatcherMock = self::getMockBuilder('No3x\WPML\WPML_Email_Dispatcher')
|
26 |
+
->disableOriginalConstructor()
|
27 |
+
->getMock()
|
28 |
+
;
|
29 |
+
$this->emailResender = new WPML_Email_Resender($this->dispatcherMock);
|
30 |
+
$this->mailMock = self::getMockBuilder('No3x\WPML\Model\WPML_Mail')
|
31 |
+
->disableOriginalConstructor()
|
32 |
+
->setMethods( array('get_headers', 'get_attachments', 'get_receiver') )
|
33 |
+
->getMock()
|
34 |
+
;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* The mail contents are stored with line breaks encoded as php string literals in the database.
|
39 |
+
* When loading this mail from the database to resend it in it's original format
|
40 |
+
* at least the headers need to be fixed. To do so the header string is split on the
|
41 |
+
* line endings (encoded as string literals) into an array.
|
42 |
+
* @dataProvider headersProvider
|
43 |
+
* @param string $headers header as string
|
44 |
+
* @param array $expectedHeaders expected header parsed as array
|
45 |
+
*/
|
46 |
+
function test_resendHeaders($headers, $expectedHeaders) {
|
47 |
+
|
48 |
+
$this->mailMock->expects(self::once())
|
49 |
+
->method('get_headers')
|
50 |
+
->willReturn($headers)
|
51 |
+
;
|
52 |
+
|
53 |
+
$this->dispatcherMock->expects(self::once())
|
54 |
+
->method('dispatch')
|
55 |
+
->with($this->anything(), $this->anything(), $this->anything(), $expectedHeaders, $this->anything())
|
56 |
+
;
|
57 |
+
|
58 |
+
$this->emailResender->resendMail($this->mailMock);
|
59 |
+
}
|
60 |
+
|
61 |
+
function test_multiple_receivers() {
|
62 |
+
|
63 |
+
$receivers_array = ['recipient1@example.com', 'recipient2@foo.example.com'];
|
64 |
+
$receivers = $receivers_array[0] . '\n' . $receivers_array[1];
|
65 |
+
|
66 |
+
$this->mailMock->expects(self::once())
|
67 |
+
->method('get_receiver')
|
68 |
+
->willReturn($receivers)
|
69 |
+
;
|
70 |
+
|
71 |
+
$this->dispatcherMock->expects(self::once())
|
72 |
+
->method('dispatch')
|
73 |
+
->with($this->equalTo($receivers_array), $this->mailMock->get_subject(), $this->mailMock->get_message(), $this->anything(), $this->anything())
|
74 |
+
;
|
75 |
+
|
76 |
+
$this->emailResender->resendMail($this->mailMock);
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
function headersProvider() {
|
81 |
+
return array(
|
82 |
+
"withoutFrom" => array(
|
83 |
+
"example@example.com,\\nReply-To: example@com,\\nBcc: example@example.com,\\nContent-type: text/html; charset=UTF-8",
|
84 |
+
array(
|
85 |
+
"example@example.com",
|
86 |
+
"Reply-To: example@com",
|
87 |
+
"Bcc: example@example.com",
|
88 |
+
"Content-type: text/html; charset=UTF-8"
|
89 |
+
)
|
90 |
+
),
|
91 |
+
"withRN" => array(
|
92 |
+
"example@example.com,\\r\\nReply-To: example@com",
|
93 |
+
array(
|
94 |
+
"example@example.com",
|
95 |
+
"Reply-To: example@com",
|
96 |
+
)
|
97 |
+
),
|
98 |
+
"withFrom" => array(
|
99 |
+
"From: \"example@example.com\" <example@example.de>,\\nContent-type: text/html; charset=UTF-8",
|
100 |
+
array(
|
101 |
+
"From: \"example@example.com\" <example@example.de>",
|
102 |
+
"Content-type: text/html; charset=UTF-8"
|
103 |
+
)
|
104 |
+
)
|
105 |
+
);
|
106 |
+
}
|
107 |
+
}
|
tests/phpunit/unit/WPML_MailExtractor_Test.php
ADDED
@@ -0,0 +1,187 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Unit;
|
4 |
+
|
5 |
+
use No3x\WPML\Tests\Helper\WPMailArrayBuilder;
|
6 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
7 |
+
use No3x\WPML\WPML_MailExtractor;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class WPML_MailExtractor_Test tests the mail extraction from a WordPress mail array specified at the codex
|
11 |
+
* @see https://developer.wordpress.org/reference/functions/wp_mail/
|
12 |
+
* @package No3x\WPML\Tests
|
13 |
+
*/
|
14 |
+
class WPML_MailExtractor_Test extends \PHPUnit_Framework_TestCase {
|
15 |
+
|
16 |
+
/** @var WPML_MailExtractor */
|
17 |
+
private $mailExtractor;
|
18 |
+
|
19 |
+
function setUp() {
|
20 |
+
parent::setUp();
|
21 |
+
$this->mailExtractor = new WPML_MailExtractor();
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Codex: (string|array) (Required) Array or comma-separated list of email addresses to send message.
|
26 |
+
* @dataProvider receiverProvider
|
27 |
+
* @param $mailArray array the mailArray
|
28 |
+
* @param $expected string the expected output
|
29 |
+
*/
|
30 |
+
function test_receiver($mailArray, $expected) {
|
31 |
+
$this->assertEquals($expected, $this->mailExtractor->extract($mailArray)->get_receiver());
|
32 |
+
}
|
33 |
+
|
34 |
+
function receiverProvider() {
|
35 |
+
$exampleEmail1 = 'example@example.com';
|
36 |
+
$exampleEmail2 = 'example2@example.com';
|
37 |
+
$example1And2Expected = $exampleEmail1 . ',\n' . $exampleEmail2;
|
38 |
+
return [
|
39 |
+
'single receiver' => [
|
40 |
+
WPMailArrayBuilder::aMail()->withTo($exampleEmail1)->build(),
|
41 |
+
$exampleEmail1
|
42 |
+
],
|
43 |
+
'multiple receivers' => [
|
44 |
+
WPMailArrayBuilder::aMail()->withTo($exampleEmail1 . ',' . $exampleEmail2)->build(),
|
45 |
+
$example1And2Expected
|
46 |
+
],
|
47 |
+
'array with single receiver' => [
|
48 |
+
WPMailArrayBuilder::aMail()->withTo([$exampleEmail1])->build(),
|
49 |
+
$exampleEmail1
|
50 |
+
],
|
51 |
+
'array with multiple receivers' => [
|
52 |
+
WPMailArrayBuilder::aMail()->withTo([$exampleEmail1, $exampleEmail2])->build(),
|
53 |
+
$example1And2Expected
|
54 |
+
],
|
55 |
+
];
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Codex: $subject (string) (Required) Email subject
|
60 |
+
*/
|
61 |
+
function test_subject() {
|
62 |
+
$subject = "This is a subject";
|
63 |
+
$mailArray = WPMailArrayBuilder::aMail()->withSubject($subject)->build();
|
64 |
+
$this->assertEquals($subject, $this->mailExtractor->extract($mailArray)->get_subject());
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Codex: $message (string) (Required) Message contents
|
69 |
+
*/
|
70 |
+
function test_message() {
|
71 |
+
$message = "This is a message";
|
72 |
+
$mailArray = WPMailArrayBuilder::aMail()->withMessage($message)->build();
|
73 |
+
$this->assertEquals($message, $this->mailExtractor->extract($mailArray)->get_message());
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @requires PHPUnit 5.7
|
78 |
+
* expectException is not present in older phpunit version.
|
79 |
+
*/
|
80 |
+
function test_no_messageField_throws_exception() {
|
81 |
+
$mailArray = WPMailArrayBuilder::aMail()->buildWithoutMessage();
|
82 |
+
$this->expectException("Exception");
|
83 |
+
$this->expectExceptionMessage(WPML_MailExtractor::ERROR_NO_FIELD);
|
84 |
+
$this->mailExtractor->extract($mailArray);
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Mandrill stores the message in the 'html' field instead of the 'message' field (see gh-22)
|
89 |
+
*/
|
90 |
+
function test_mandrillMail() {
|
91 |
+
$message = "This is a message in the html field";
|
92 |
+
$mailArray = WPMailArrayBuilder::aMail()->withMessage($message)->buildAsMandrillMail();
|
93 |
+
$this->assertEquals($message, $this->mailExtractor->extract($mailArray)->get_message());
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Codex: $headers (string|array) (Optional) Additional headers.
|
98 |
+
* Default value: ''
|
99 |
+
* @dataProvider headersProvider
|
100 |
+
* @param $mailArray array the mailArray
|
101 |
+
* @param $expected string the expected output
|
102 |
+
*/
|
103 |
+
function test_headers($mailArray, $expected) {
|
104 |
+
$this->assertEquals($expected, $this->mailExtractor->extract($mailArray)->get_headers());
|
105 |
+
}
|
106 |
+
|
107 |
+
function headersProvider() {
|
108 |
+
$exampleHeader = 'Content-Type: text/html; charset=UTF-8';
|
109 |
+
$example1And2Expected = $exampleHeader . ',\n' . $exampleHeader;
|
110 |
+
return [
|
111 |
+
'none header' => [
|
112 |
+
WPMailArrayBuilder::aMail()->buildWithoutHeaders(),
|
113 |
+
''
|
114 |
+
],
|
115 |
+
'empty header' => [
|
116 |
+
WPMailArrayBuilder::aMail()->but()->withNoHeaders()->build(),
|
117 |
+
''
|
118 |
+
],
|
119 |
+
'single header' => [
|
120 |
+
WPMailArrayBuilder::aMail()->withHeaders($exampleHeader)->build(),
|
121 |
+
$exampleHeader
|
122 |
+
],
|
123 |
+
'multiple header' => [
|
124 |
+
WPMailArrayBuilder::aMail()->withHeaders($exampleHeader . ',\n' . $exampleHeader)->build(),
|
125 |
+
$example1And2Expected
|
126 |
+
],
|
127 |
+
'array with single header' => [
|
128 |
+
WPMailArrayBuilder::aMail()->withHeaders([$exampleHeader])->build(),
|
129 |
+
$exampleHeader
|
130 |
+
],
|
131 |
+
'array with multiple headers' => [
|
132 |
+
WPMailArrayBuilder::aMail()->withHeaders([$exampleHeader, $exampleHeader])->build(),
|
133 |
+
$example1And2Expected
|
134 |
+
],
|
135 |
+
];
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Codex: $attachments (string|array) (Optional) Files to attach.
|
140 |
+
* Default value: array()
|
141 |
+
* @dataProvider attachmentsProvider
|
142 |
+
* @param $mailArray array the mailArray
|
143 |
+
* @param $expected string the expected output
|
144 |
+
*/
|
145 |
+
function test_attachments($mailArray, $expected) {
|
146 |
+
$this->assertEquals($expected, $this->mailExtractor->extract($mailArray)->get_attachments());
|
147 |
+
}
|
148 |
+
|
149 |
+
function attachmentsProvider() {
|
150 |
+
$exampleAttachment1 = WP_CONTENT_DIR . '/uploads/2018/05/file.pdf';
|
151 |
+
$exampleAttachment2 = WP_CONTENT_DIR . '/uploads/2018/01/bill.pdf';
|
152 |
+
|
153 |
+
$exampleAttachment1Expected = '/2018/05/file.pdf';
|
154 |
+
$example1And2Expected = '/2018/05/file.pdf,\n/2018/01/bill.pdf';
|
155 |
+
|
156 |
+
return [
|
157 |
+
'none attachments' => [
|
158 |
+
WPMailArrayBuilder::aMail()->buildWithoutAttachments(),
|
159 |
+
''
|
160 |
+
],
|
161 |
+
'empty attachments' => [
|
162 |
+
WPMailArrayBuilder::aMail()->but()->withNoAttachments()->build(),
|
163 |
+
''
|
164 |
+
],
|
165 |
+
'no wp-content in path' => [
|
166 |
+
WPMailArrayBuilder::aMail()->withAttachments('/tmp/0file.png')->build(),
|
167 |
+
'0file.png'
|
168 |
+
],
|
169 |
+
'single attachment' => [
|
170 |
+
WPMailArrayBuilder::aMail()->withAttachments($exampleAttachment1)->build(),
|
171 |
+
$exampleAttachment1Expected
|
172 |
+
],
|
173 |
+
'multiple attachments' => [
|
174 |
+
WPMailArrayBuilder::aMail()->withAttachments($exampleAttachment1 . ',\n' . $exampleAttachment2)->build(),
|
175 |
+
$example1And2Expected
|
176 |
+
],
|
177 |
+
'array with single attachment' => [
|
178 |
+
WPMailArrayBuilder::aMail()->withAttachments([$exampleAttachment1])->build(),
|
179 |
+
$exampleAttachment1Expected
|
180 |
+
],
|
181 |
+
'array with multiple attachments' => [
|
182 |
+
WPMailArrayBuilder::aMail()->withAttachments([$exampleAttachment1, $exampleAttachment2])->build(),
|
183 |
+
$example1And2Expected
|
184 |
+
],
|
185 |
+
];
|
186 |
+
}
|
187 |
+
}
|
tests/phpunit/unit/WPML_MailRenderer_Test.php
ADDED
@@ -0,0 +1,228 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests;
|
4 |
+
|
5 |
+
use Mockery;
|
6 |
+
use No3x\WPML\Model\WPML_Mail;
|
7 |
+
use No3x\WPML\Renderer\WPML_MailRenderer;
|
8 |
+
use No3x\WPML\Tests\Helper\WPMailArrayBuilder;
|
9 |
+
use No3x\WPML\WPML_MailExtractor;
|
10 |
+
|
11 |
+
class WPML_MailRenderer_Test extends \PHPUnit_Framework_TestCase {
|
12 |
+
|
13 |
+
/** @var WPML_MailRenderer */
|
14 |
+
private $mailRenderer;
|
15 |
+
|
16 |
+
/** @var $mailServiceMock \No3x\WPML\Model\IMailService|\Mockery\MockInterface */
|
17 |
+
private $mailServiceMock;
|
18 |
+
|
19 |
+
private $id = 2;
|
20 |
+
|
21 |
+
public function setUp() {
|
22 |
+
$this->mailServiceMock = Mockery::mock('No3x\WPML\Model\IMailService');
|
23 |
+
|
24 |
+
/** @var $mail WPML_Mail */
|
25 |
+
$mail = (new WPML_MailExtractor())->extract(WPMailArrayBuilder::aMail()
|
26 |
+
->withSubject("Test")
|
27 |
+
->withTo("example@exmple.com")
|
28 |
+
->withHeaders("From: \"admin\" <admin@local.test>\r\n,\nCc: example2@example.com,\nReply-To: admin <admin@local.test>\r\n")
|
29 |
+
->withMessage("<b>Bold</b><script>alert('xss');</script>")
|
30 |
+
->withAttachments(["file.pdf"])
|
31 |
+
->build());
|
32 |
+
$mail->set_mail_id($this->id);
|
33 |
+
$mail->set_plugin_version('1.8.5');
|
34 |
+
$mail->set_timestamp('2018-09-24 16:02:11');
|
35 |
+
$mail->set_host('127.0.0.1');
|
36 |
+
$mail->set_error('a');
|
37 |
+
|
38 |
+
$this->mailServiceMock->shouldReceive('find_one')
|
39 |
+
->times(1)
|
40 |
+
->with( $this->id )
|
41 |
+
->andReturn( $mail );
|
42 |
+
|
43 |
+
$this->mailRenderer = new WPML_MailRenderer($this->mailServiceMock);
|
44 |
+
}
|
45 |
+
|
46 |
+
public function test_print_mail_json() {
|
47 |
+
$expected = '<pre>{
|
48 |
+
"mail_id": "2",
|
49 |
+
"timestamp": "2018-09-24 16:02:11",
|
50 |
+
"host": "127.0.0.1",
|
51 |
+
"receiver": "example@exmple.com",
|
52 |
+
"subject": "Test",
|
53 |
+
"message": "<b>Bold<\/b><script>alert(\'xss\');<\/script>",
|
54 |
+
"headers": "From: "admin" <admin@local.test>\r\n,\nCc: example2@example.com,\nReply-To: admin <admin@local.test>\r\n",
|
55 |
+
"attachments": "file.pdf",
|
56 |
+
"error": "a",
|
57 |
+
"plugin_version": "1.8.5"
|
58 |
+
}</pre>';
|
59 |
+
|
60 |
+
$this->assertEquals($expected, $this->mailRenderer->render($this->id, WPML_MailRenderer::FORMAT_JSON));
|
61 |
+
$this->mailServiceMock->mockery_verify();
|
62 |
+
}
|
63 |
+
|
64 |
+
public function test_supported_formats() {
|
65 |
+
$this->assertEquals(['raw', 'html', 'json'], $this->mailRenderer->getSupportedFormats());
|
66 |
+
}
|
67 |
+
|
68 |
+
public function test_print_mail_json_fallback_to_raw() {
|
69 |
+
$this->mailServiceMock = Mockery::mock('No3x\WPML\Model\IMailService');
|
70 |
+
|
71 |
+
/** @var $mail WPML_Mail */
|
72 |
+
$mail = (new WPML_MailExtractor())->extract(WPMailArrayBuilder::aMail()
|
73 |
+
->withSubject("Test")
|
74 |
+
->withTo("example@exmple.com")
|
75 |
+
->withHeaders("Content-Type: text/html")
|
76 |
+
->withMessage("Message")
|
77 |
+
->build());
|
78 |
+
$mail->set_mail_id($this->id);
|
79 |
+
$mail->set_plugin_version('1.8.5');
|
80 |
+
$mail->set_timestamp('2018-09-24 16:02:11');
|
81 |
+
$mail->set_host('127.0.0.1');
|
82 |
+
$mail->set_error('a');
|
83 |
+
|
84 |
+
$this->mailServiceMock->shouldReceive('find_one')
|
85 |
+
->times(1)
|
86 |
+
->with( $this->id )
|
87 |
+
->andReturn( $mail );
|
88 |
+
|
89 |
+
$this->mailRenderer = new WPML_MailRenderer($this->mailServiceMock);
|
90 |
+
$this->assertContains("Fallback", $this->mailRenderer->render($this->id, WPML_MailRenderer::FORMAT_JSON));
|
91 |
+
$this->mailServiceMock->mockery_verify();
|
92 |
+
}
|
93 |
+
|
94 |
+
public function test_print_mail_raw() {
|
95 |
+
$expected = '<span class="title">Time: </span>2018-09-24 16:02:11<span class="title">Receiver: </span>example@exmple.com<span class="title">Subject: </span>Test<span class="title">Message: </span><b>Bold</b><span class="title">Headers: </span>From: "admin" ,\nCc: example2@example.com,\nReply-To: admin <span class="title">Attachments: </span><span class="title">Error: </span><i class="fa fa-exclamation-circle" title="a"></i>';
|
96 |
+
$actual = $this->mailRenderer->render($this->id, WPML_MailRenderer::FORMAT_RAW);
|
97 |
+
$this->assertContains('2018-09-24 16:02:11', $actual, "The timestamp should be in the rendered mail");
|
98 |
+
$this->assertContains('Test', $actual, "The subject should be in the rendered mail");
|
99 |
+
$this->assertContains('<b>Bold</b>', $actual, "The rendered mail must have html tags (<b>) escaped");
|
100 |
+
$this->assertNotContains('<script>alert(', $actual, "The rendered mail must strip out evil tags to protect against xss");
|
101 |
+
$this->assertNotContains('<i', $actual, "The rendered mail has no icons set because it show the and attachments raw");
|
102 |
+
}
|
103 |
+
|
104 |
+
public function test_print_mail_html() {
|
105 |
+
$expected = '<span class="title">Time: </span>2018-09-24 16:02:11<span class="title">Receiver: </span>example@exmple.com<span class="title">Subject: </span>Test<span class="title">Message: </span><b>Bold</b><span class="title">Headers: </span>From: "admin" ,\nCc: example2@example.com,\nReply-To: admin <span class="title">Attachments: </span><span class="title">Error: </span><i class="fa fa-exclamation-circle" title="a"></i>';
|
106 |
+
$actual = $this->mailRenderer->render($this->id, WPML_MailRenderer::FORMAT_HTML);
|
107 |
+
$this->assertContains('2018-09-24 16:02:11', $actual, "The timestamp should be in the rendered mail");
|
108 |
+
$this->assertContains('Test', $actual, "The subject should be in the rendered mail");
|
109 |
+
$this->assertContains('<b>Bold</b>', $actual, "The rendered mail must have html tags (<b>) not escaped");
|
110 |
+
$this->assertNotContains('<script>alert(', $actual, "The rendered mail must strip out evil tags to protect against xss");
|
111 |
+
$this->assertContains('<i class="fa fa-exclamation-circle"', $actual, "The rendered mail has icons for the error returned as html, it must not be escaped");
|
112 |
+
$this->assertContains('<i class="fa fa-times"', $actual, "The rendered mail has icons for the attachments returned as html, it must not be escaped");
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @dataProvider evilTextProvider
|
117 |
+
* @param $evilText string the message to be rendered
|
118 |
+
* @param $expected string the expected output
|
119 |
+
*/
|
120 |
+
function test_messageSanitationOnMessageAndSubject($evilText, $expected) {
|
121 |
+
|
122 |
+
$this->mailServiceMock = Mockery::mock('No3x\WPML\Model\IMailService');
|
123 |
+
|
124 |
+
/** @var $mail_raw WPML_Mail */
|
125 |
+
$mail_raw = (new WPML_MailExtractor())->extract(WPMailArrayBuilder::aMail()
|
126 |
+
->withSubject($evilText)
|
127 |
+
->withTo("example@exmple.com")
|
128 |
+
->withHeaders("From: \"admin\" <admin@local.test>\r\n,\nCc: example2@example.com,\nReply-To: admin <admin@local.test>\r\n")
|
129 |
+
->withMessage($evilText)
|
130 |
+
->build())
|
131 |
+
;
|
132 |
+
$mail_raw->set_mail_id($this->id);
|
133 |
+
$mail_raw->set_plugin_version('1.8.5');
|
134 |
+
$mail_raw->set_timestamp('2018-09-24 16:02:11');
|
135 |
+
$mail_raw->set_host('127.0.0.1');
|
136 |
+
$mail_raw->set_error('a');
|
137 |
+
|
138 |
+
/** @var $mail_html WPML_Mail */
|
139 |
+
$mail_html = WPML_Mail::create($mail_raw->to_array());
|
140 |
+
$mail_html->set_subject($evilText);
|
141 |
+
$mail_html->set_message($evilText);
|
142 |
+
|
143 |
+
$this->mailServiceMock->shouldReceive('find_one')
|
144 |
+
->times(1)
|
145 |
+
->with( $this->id )
|
146 |
+
->andReturn( $mail_raw )
|
147 |
+
// And then return $mail_html
|
148 |
+
->andReturn( $mail_html )
|
149 |
+
;
|
150 |
+
|
151 |
+
$this->mailRenderer = new WPML_MailRenderer($this->mailServiceMock);
|
152 |
+
|
153 |
+
$this->assertMessageAndTitleEqual($expected[0], WPML_MailRenderer::FORMAT_RAW);
|
154 |
+
$this->assertMessageAndTitleEqual($expected[1], WPML_MailRenderer::FORMAT_HTML);
|
155 |
+
}
|
156 |
+
|
157 |
+
private function assertMessageAndTitleEqual($expected, $format) {
|
158 |
+
$mail = $this->mailRenderer->render($this->id, $format);
|
159 |
+
$mail_message = $this->get_string_between($mail, 'Message: </span>', '<span ');
|
160 |
+
$mail_subject = $this->get_string_between($mail, 'Subject: </span>', '<span ');
|
161 |
+
$this->assertEquals($expected, $mail_message);
|
162 |
+
$this->assertEquals($expected, $mail_subject);
|
163 |
+
}
|
164 |
+
|
165 |
+
private function get_string_between($string, $start, $end){
|
166 |
+
$string = ' ' . $string;
|
167 |
+
$ini = strpos($string, $start);
|
168 |
+
if ($ini == 0) return "Could not find '{$start}' in the string";
|
169 |
+
$ini += strlen($start);
|
170 |
+
$len = strpos($string, $end, $ini) - $ini;
|
171 |
+
return substr($string, $ini, $len);
|
172 |
+
}
|
173 |
+
|
174 |
+
function evilTextProvider() {
|
175 |
+
return [
|
176 |
+
"plaintext" => [
|
177 |
+
"Hello World",
|
178 |
+
[
|
179 |
+
"Hello World",
|
180 |
+
"Hello World",
|
181 |
+
]
|
182 |
+
],
|
183 |
+
"html bold" => [
|
184 |
+
"<b>Hello World</b>",
|
185 |
+
[
|
186 |
+
"<b>Hello World</b>",
|
187 |
+
"<b>Hello World</b>",
|
188 |
+
]
|
189 |
+
],
|
190 |
+
"style" => [
|
191 |
+
"<style>body {background-color: red;}</style>",
|
192 |
+
[
|
193 |
+
"<style>body {background-color: red;}</style>",
|
194 |
+
"<style>body {background-color: red;}</style>",
|
195 |
+
]
|
196 |
+
],
|
197 |
+
"script alert()" => [
|
198 |
+
"<script>alert('XSS hacking!');</script>",
|
199 |
+
[
|
200 |
+
"<script>alert('XSS hacking!');</script>",
|
201 |
+
"alert('XSS hacking!');",
|
202 |
+
]
|
203 |
+
],
|
204 |
+
"html comment" => [
|
205 |
+
"<!-- Comment -->",
|
206 |
+
[
|
207 |
+
"<!-- Comment -->",
|
208 |
+
"<!-- Comment -->",
|
209 |
+
]
|
210 |
+
],
|
211 |
+
"html encoded comment" => [
|
212 |
+
"<!-- Comment -->",
|
213 |
+
[
|
214 |
+
"<!-- Comment -->",
|
215 |
+
"<!-- Comment -->",
|
216 |
+
]
|
217 |
+
],
|
218 |
+
"html embedded tag in comment" => [
|
219 |
+
"<!-- <b>This is commented out actually</b> -->",
|
220 |
+
[
|
221 |
+
"<!-- <b>This is commented out actually</b> -->",
|
222 |
+
"<!-- <b>This is commented out actually</b> -->",
|
223 |
+
]
|
224 |
+
],
|
225 |
+
];
|
226 |
+
}
|
227 |
+
|
228 |
+
}
|
tests/phpunit/unit/WPML_MessageSanitizer_Test.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Unit;
|
4 |
+
|
5 |
+
use No3x\WPML\WPML_MessageSanitizer;
|
6 |
+
|
7 |
+
class WPML_MessageSanitizer_Test extends \PHPUnit_Framework_TestCase {
|
8 |
+
|
9 |
+
/** @var WPML_MessageSanitizer */
|
10 |
+
private $messageSanitizer;
|
11 |
+
|
12 |
+
function setUp() {
|
13 |
+
parent::setUp();
|
14 |
+
$this->messageSanitizer = new WPML_MessageSanitizer();
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* The sanitizer removes evil code from the text to output.
|
19 |
+
* It removes unsafe html and keeps html comments.
|
20 |
+
* @dataProvider messagesProvider
|
21 |
+
* @param $message string the message to be sanitized
|
22 |
+
* @param $expected string the expected output
|
23 |
+
*/
|
24 |
+
function test_messageSanitation($message, $expected) {
|
25 |
+
$this->assertEquals($expected, $this->messageSanitizer->sanitize($message));
|
26 |
+
}
|
27 |
+
|
28 |
+
function messagesProvider() {
|
29 |
+
return [
|
30 |
+
"plaintext" => [
|
31 |
+
"Hello World",
|
32 |
+
"Hello World"
|
33 |
+
],
|
34 |
+
"html bold" => [
|
35 |
+
"<b>Hello World</b>",
|
36 |
+
"<b>Hello World</b>"
|
37 |
+
],
|
38 |
+
"style" => [
|
39 |
+
"<style>body {background-color: red;}</style>",
|
40 |
+
"<style>body {background-color: red;}</style>"
|
41 |
+
],
|
42 |
+
"script alert()" => [
|
43 |
+
"<script>alert('XSS hacking!');</script>",
|
44 |
+
"alert('XSS hacking!');"
|
45 |
+
],
|
46 |
+
"html comment" => [
|
47 |
+
"<!-- Comment -->",
|
48 |
+
"<!-- Comment -->"
|
49 |
+
],
|
50 |
+
"html encoded comment" => [
|
51 |
+
"<!-- Comment -->",
|
52 |
+
"<!-- Comment -->"
|
53 |
+
],
|
54 |
+
"html embedded tag in comment" => [
|
55 |
+
"<!-- <b>This is commented out actually</b> -->",
|
56 |
+
"<!-- <b>This is commented out actually</b> -->"
|
57 |
+
],
|
58 |
+
];
|
59 |
+
}
|
60 |
+
}
|
tests/phpunit/unit/WPML_Plugin_Test.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Unit;
|
4 |
+
|
5 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
6 |
+
use No3x\WPML\WPML_Plugin;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @author No3x
|
10 |
+
* Tests are written in the AAA-Rule
|
11 |
+
* There are three basic sections for our test: Arrange, Act, and Assert.
|
12 |
+
*/
|
13 |
+
class WPML_Plugin_Test extends \PHPUnit_Framework_TestCase {
|
14 |
+
|
15 |
+
function test_getTablename() {
|
16 |
+
global $wpdb;
|
17 |
+
|
18 |
+
// Arrange
|
19 |
+
$tableName = 'testTable';
|
20 |
+
// Act
|
21 |
+
$prefixed = WPML_Plugin::getTablename( $tableName );
|
22 |
+
// Assert
|
23 |
+
$this->assertEquals( $wpdb->prefix . 'wpml_testTable', $prefixed );
|
24 |
+
}
|
25 |
+
|
26 |
+
function test_version_compare() {
|
27 |
+
$this->assertEquals( 1, version_compare( '1.6.0', '1.4.0' ) );
|
28 |
+
$this->assertEquals( 1, version_compare( '1.4.0', '1.4.0_betaR1' ) );
|
29 |
+
$this->assertEquals( 1, version_compare( '1.4.0_betaR2', '1.4.0_betaR1' ) );
|
30 |
+
$this->assertEquals( 1, version_compare( '1.6.0_betaR2', '1.4.0_betaR1' ) );
|
31 |
+
}
|
32 |
+
|
33 |
+
function test_getClass() {
|
34 |
+
$this->assertEquals( 'No3x\WPML\WPML_Plugin', WPML_Plugin::getClass());
|
35 |
+
}
|
36 |
+
}
|
tests/phpunit/unit/WPML_PrivacyController_Test.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests\Unit;
|
4 |
+
|
5 |
+
use No3x\WPML\Model\WPML_Mail;
|
6 |
+
use No3x\WPML\ORM\DefaultQueryFactory;
|
7 |
+
use No3x\WPML\ORM\QueryFactory;
|
8 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
9 |
+
use No3x\WPML\WPML_PrivacyController;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Class WPML_MailExtractor_Test tests the function of the privacy integration
|
13 |
+
* @package No3x\WPML\Tests
|
14 |
+
*/
|
15 |
+
class WPML_PrivacyController_Test extends \PHPUnit_Framework_TestCase {
|
16 |
+
|
17 |
+
const emailAddress = 'example@example.com';
|
18 |
+
|
19 |
+
/** @var WPML_PrivacyController */
|
20 |
+
private $privacyController;
|
21 |
+
|
22 |
+
/** @var \No3x\WPML\ORM\Query|\PHPUnit_Framework_MockObject_MockObject $queryMock */
|
23 |
+
private $queryMock;
|
24 |
+
|
25 |
+
function setUp() {
|
26 |
+
parent::setUp();
|
27 |
+
|
28 |
+
$this->queryMock = self::getMockBuilder('No3x\WPML\ORM\Query')
|
29 |
+
->disableOriginalConstructor()
|
30 |
+
->setMethods(['find'])
|
31 |
+
->getMock()
|
32 |
+
;
|
33 |
+
|
34 |
+
WPML_Mail::setQueryFactory(new QueryMockFactory($this->queryMock));
|
35 |
+
|
36 |
+
$this->privacyController = new WPML_PrivacyController(null);
|
37 |
+
}
|
38 |
+
|
39 |
+
public function testQueryMockFactory() {
|
40 |
+
$this->assertInstanceOf('No3x\WPML\ORM\Query', WPML_Mail::query());
|
41 |
+
}
|
42 |
+
|
43 |
+
private function mockMail($id) {
|
44 |
+
$mail1 = self::getMockBuilder('No3x\WPML\ORM\Query')
|
45 |
+
->disableOriginalConstructor()
|
46 |
+
->setMethods(['get_mail_id', 'to_array', 'delete'])
|
47 |
+
->getMock()
|
48 |
+
;
|
49 |
+
|
50 |
+
$mail1->expects(self::any())
|
51 |
+
->method('get_mail_id')
|
52 |
+
->willReturn($id)
|
53 |
+
;
|
54 |
+
|
55 |
+
$mail1->expects(self::any())
|
56 |
+
->method('to_array')
|
57 |
+
->willReturn(['mail_id' => $id])
|
58 |
+
;
|
59 |
+
|
60 |
+
$mail1->expects(self::any())
|
61 |
+
->method('delete')
|
62 |
+
->willReturn(true)
|
63 |
+
;
|
64 |
+
|
65 |
+
return $mail1;
|
66 |
+
}
|
67 |
+
|
68 |
+
private function setupPrivacyControllerDataQuery() {
|
69 |
+
|
70 |
+
$mail1 = $this->mockMail(1);
|
71 |
+
$mail2 = $this->mockMail(2);
|
72 |
+
|
73 |
+
$data = [$mail1, $mail2];
|
74 |
+
|
75 |
+
$this->queryMock->expects(self::once())
|
76 |
+
->method('find')
|
77 |
+
->willReturn($data)
|
78 |
+
;
|
79 |
+
|
80 |
+
$idsOfMocks = [1, 2];
|
81 |
+
|
82 |
+
return $idsOfMocks;
|
83 |
+
}
|
84 |
+
|
85 |
+
public function testExport() {
|
86 |
+
$idsExpected = $this->setupPrivacyControllerDataQuery();
|
87 |
+
|
88 |
+
$export = $this->privacyController->export(self::emailAddress);
|
89 |
+
|
90 |
+
$idsActual = [
|
91 |
+
$export['data'][0]['data'][0]['value'],
|
92 |
+
$export['data'][1]['data'][0]['value']
|
93 |
+
];
|
94 |
+
|
95 |
+
$this->assertEquals($idsExpected, $idsActual);
|
96 |
+
$this->assertTrue($export['done']);
|
97 |
+
}
|
98 |
+
|
99 |
+
public function testErasure() {
|
100 |
+
$this->setupPrivacyControllerDataQuery();
|
101 |
+
|
102 |
+
$erase = $this->privacyController->erase(self::emailAddress);
|
103 |
+
|
104 |
+
$this->assertTrue($erase['done']);
|
105 |
+
$this->assertTrue($erase['items_removed']);
|
106 |
+
$this->assertFalse($erase['items_retained']);
|
107 |
+
}
|
108 |
+
|
109 |
+
|
110 |
+
}
|
111 |
+
|
112 |
+
class QueryMockFactory implements QueryFactory {
|
113 |
+
|
114 |
+
private $queryMock;
|
115 |
+
|
116 |
+
public function __construct($queryMock) {
|
117 |
+
$this->queryMock = $queryMock;
|
118 |
+
}
|
119 |
+
|
120 |
+
public function buildQuery($modelClass) {
|
121 |
+
return $this->queryMock;
|
122 |
+
}
|
123 |
+
}
|
tests/phpunit/unit/WPML_Utils_Test.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Tests;
|
4 |
+
|
5 |
+
use No3x\WPML\Tests\Helper\WPML_IntegrationTestCase;
|
6 |
+
use No3x\WPML\WPML_Utils;
|
7 |
+
|
8 |
+
class WPML_Utils_Test extends \PHPUnit_Framework_TestCase {
|
9 |
+
|
10 |
+
public function test_determine_fa_icon() {
|
11 |
+
// test file icon rendered properly (gh-90)
|
12 |
+
$this->assertNotSame('<i class="fa fa-file-file-o"></i>', WPML_Utils::determine_fa_icon("file"));
|
13 |
+
$this->assertSame('<i class="fa fa-file-o"></i>', WPML_Utils::determine_fa_icon("file"));
|
14 |
+
$this->assertSame('<i class="fa fa-file-archive-o"></i>', WPML_Utils::determine_fa_icon("archive"));
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* The sanitizer removes evil code from the text to output.
|
19 |
+
* It removes unsafe html and keeps html comments.
|
20 |
+
* @dataProvider expectedValuesProvider
|
21 |
+
* @param $in string the message to be sanitized
|
22 |
+
* @param $expected string the expected output
|
23 |
+
*/
|
24 |
+
function test_sanitizeExpectedValue($in, $expected) {
|
25 |
+
$this->assertSame($expected, WPML_Utils::sanitize_expected_value($in['value'], $in['allowed_values'], $in['default_value']));
|
26 |
+
}
|
27 |
+
|
28 |
+
function expectedValuesProvider() {
|
29 |
+
return [
|
30 |
+
'allowed value is allowed value' => [
|
31 |
+
[
|
32 |
+
'value' => 'a',
|
33 |
+
'allowed_values' => 'a',
|
34 |
+
'default_value' => null
|
35 |
+
],
|
36 |
+
'a'
|
37 |
+
],
|
38 |
+
'allowed value in set' => [
|
39 |
+
[
|
40 |
+
'value' => 'a',
|
41 |
+
'allowed_values' => [
|
42 |
+
'a'
|
43 |
+
],
|
44 |
+
'default_value' => null
|
45 |
+
],
|
46 |
+
'a'
|
47 |
+
],
|
48 |
+
'allowed value in set with others' => [
|
49 |
+
[
|
50 |
+
'value' => 'a',
|
51 |
+
'allowed_values' => [
|
52 |
+
'b', 'a', 'c'
|
53 |
+
],
|
54 |
+
'default_value' => null
|
55 |
+
],
|
56 |
+
'a'
|
57 |
+
],
|
58 |
+
'default if no match' => [
|
59 |
+
[
|
60 |
+
'value' => 'a',
|
61 |
+
'allowed_values' => [
|
62 |
+
'b'
|
63 |
+
],
|
64 |
+
'default_value' => 'hello world'
|
65 |
+
],
|
66 |
+
'hello world'
|
67 |
+
],
|
68 |
+
'false if no match and no meaningful default' => [
|
69 |
+
[
|
70 |
+
'value' => 'a',
|
71 |
+
'allowed_values' => [
|
72 |
+
'b'
|
73 |
+
],
|
74 |
+
'default_value' => null
|
75 |
+
],
|
76 |
+
false
|
77 |
+
],
|
78 |
+
];
|
79 |
+
}
|
80 |
+
}
|
vendor/autoload.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload.php @generated by Composer
|
4 |
+
|
5 |
+
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
+
|
7 |
+
return ComposerAutoloaderInit64bcd231a77bf5f7870b38c2e715eb2f::getLoader();
|
vendor/composer/ClassLoader.php
ADDED
@@ -0,0 +1,481 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Composer.
|
5 |
+
*
|
6 |
+
* (c) Nils Adermann <naderman@naderman.de>
|
7 |
+
* Jordi Boggiano <j.boggiano@seld.be>
|
8 |
+
*
|
9 |
+
* For the full copyright and license information, please view the LICENSE
|
10 |
+
* file that was distributed with this source code.
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace Composer\Autoload;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
17 |
+
*
|
18 |
+
* $loader = new \Composer\Autoload\ClassLoader();
|
19 |
+
*
|
20 |
+
* // register classes with namespaces
|
21 |
+
* $loader->add('Symfony\Component', __DIR__.'/component');
|
22 |
+
* $loader->add('Symfony', __DIR__.'/framework');
|
23 |
+
*
|
24 |
+
* // activate the autoloader
|
25 |
+
* $loader->register();
|
26 |
+
*
|
27 |
+
* // to enable searching the include path (eg. for PEAR packages)
|
28 |
+
* $loader->setUseIncludePath(true);
|
29 |
+
*
|
30 |
+
* In this example, if you try to use a class in the Symfony\Component
|
31 |
+
* namespace or one of its children (Symfony\Component\Console for instance),
|
32 |
+
* the autoloader will first look for the class under the component/
|
33 |
+
* directory, and it will then fallback to the framework/ directory if not
|
34 |
+
* found before giving up.
|
35 |
+
*
|
36 |
+
* This class is loosely based on the Symfony UniversalClassLoader.
|
37 |
+
*
|
38 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
39 |
+
* @author Jordi Boggiano <j.boggiano@seld.be>
|
40 |
+
* @see https://www.php-fig.org/psr/psr-0/
|
41 |
+
* @see https://www.php-fig.org/psr/psr-4/
|
42 |
+
*/
|
43 |
+
class ClassLoader
|
44 |
+
{
|
45 |
+
private $vendorDir;
|
46 |
+
|
47 |
+
// PSR-4
|
48 |
+
private $prefixLengthsPsr4 = array();
|
49 |
+
private $prefixDirsPsr4 = array();
|
50 |
+
private $fallbackDirsPsr4 = array();
|
51 |
+
|
52 |
+
// PSR-0
|
53 |
+
private $prefixesPsr0 = array();
|
54 |
+
private $fallbackDirsPsr0 = array();
|
55 |
+
|
56 |
+
private $useIncludePath = false;
|
57 |
+
private $classMap = array();
|
58 |
+
private $classMapAuthoritative = false;
|
59 |
+
private $missingClasses = array();
|
60 |
+
private $apcuPrefix;
|
61 |
+
|
62 |
+
private static $registeredLoaders = array();
|
63 |
+
|
64 |
+
public function __construct($vendorDir = null)
|
65 |
+
{
|
66 |
+
$this->vendorDir = $vendorDir;
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getPrefixes()
|
70 |
+
{
|
71 |
+
if (!empty($this->prefixesPsr0)) {
|
72 |
+
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
73 |
+
}
|
74 |
+
|
75 |
+
return array();
|
76 |
+
}
|
77 |
+
|
78 |
+
public function getPrefixesPsr4()
|
79 |
+
{
|
80 |
+
return $this->prefixDirsPsr4;
|
81 |
+
}
|
82 |
+
|
83 |
+
public function getFallbackDirs()
|
84 |
+
{
|
85 |
+
return $this->fallbackDirsPsr0;
|
86 |
+
}
|
87 |
+
|
88 |
+
public function getFallbackDirsPsr4()
|
89 |
+
{
|
90 |
+
return $this->fallbackDirsPsr4;
|
91 |
+
}
|
92 |
+
|
93 |
+
public function getClassMap()
|
94 |
+
{
|
95 |
+
return $this->classMap;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* @param array $classMap Class to filename map
|
100 |
+
*/
|
101 |
+
public function addClassMap(array $classMap)
|
102 |
+
{
|
103 |
+
if ($this->classMap) {
|
104 |
+
$this->classMap = array_merge($this->classMap, $classMap);
|
105 |
+
} else {
|
106 |
+
$this->classMap = $classMap;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Registers a set of PSR-0 directories for a given prefix, either
|
112 |
+
* appending or prepending to the ones previously set for this prefix.
|
113 |
+
*
|
114 |
+
* @param string $prefix The prefix
|
115 |
+
* @param array|string $paths The PSR-0 root directories
|
116 |
+
* @param bool $prepend Whether to prepend the directories
|
117 |
+
*/
|
118 |
+
public function add($prefix, $paths, $prepend = false)
|
119 |
+
{
|
120 |
+
if (!$prefix) {
|
121 |
+
if ($prepend) {
|
122 |
+
$this->fallbackDirsPsr0 = array_merge(
|
123 |
+
(array) $paths,
|
124 |
+
$this->fallbackDirsPsr0
|
125 |
+
);
|
126 |
+
} else {
|
127 |
+
$this->fallbackDirsPsr0 = array_merge(
|
128 |
+
$this->fallbackDirsPsr0,
|
129 |
+
(array) $paths
|
130 |
+
);
|
131 |
+
}
|
132 |
+
|
133 |
+
return;
|
134 |
+
}
|
135 |
+
|
136 |
+
$first = $prefix[0];
|
137 |
+
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
138 |
+
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
139 |
+
|
140 |
+
return;
|
141 |
+
}
|
142 |
+
if ($prepend) {
|
143 |
+
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
144 |
+
(array) $paths,
|
145 |
+
$this->prefixesPsr0[$first][$prefix]
|
146 |
+
);
|
147 |
+
} else {
|
148 |
+
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
149 |
+
$this->prefixesPsr0[$first][$prefix],
|
150 |
+
(array) $paths
|
151 |
+
);
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Registers a set of PSR-4 directories for a given namespace, either
|
157 |
+
* appending or prepending to the ones previously set for this namespace.
|
158 |
+
*
|
159 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
160 |
+
* @param array|string $paths The PSR-4 base directories
|
161 |
+
* @param bool $prepend Whether to prepend the directories
|
162 |
+
*
|
163 |
+
* @throws \InvalidArgumentException
|
164 |
+
*/
|
165 |
+
public function addPsr4($prefix, $paths, $prepend = false)
|
166 |
+
{
|
167 |
+
if (!$prefix) {
|
168 |
+
// Register directories for the root namespace.
|
169 |
+
if ($prepend) {
|
170 |
+
$this->fallbackDirsPsr4 = array_merge(
|
171 |
+
(array) $paths,
|
172 |
+
$this->fallbackDirsPsr4
|
173 |
+
);
|
174 |
+
} else {
|
175 |
+
$this->fallbackDirsPsr4 = array_merge(
|
176 |
+
$this->fallbackDirsPsr4,
|
177 |
+
(array) $paths
|
178 |
+
);
|
179 |
+
}
|
180 |
+
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
181 |
+
// Register directories for a new namespace.
|
182 |
+
$length = strlen($prefix);
|
183 |
+
if ('\\' !== $prefix[$length - 1]) {
|
184 |
+
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
185 |
+
}
|
186 |
+
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
187 |
+
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
188 |
+
} elseif ($prepend) {
|
189 |
+
// Prepend directories for an already registered namespace.
|
190 |
+
$this->prefixDirsPsr4[$prefix] = array_merge(
|
191 |
+
(array) $paths,
|
192 |
+
$this->prefixDirsPsr4[$prefix]
|
193 |
+
);
|
194 |
+
} else {
|
195 |
+
// Append directories for an already registered namespace.
|
196 |
+
$this->prefixDirsPsr4[$prefix] = array_merge(
|
197 |
+
$this->prefixDirsPsr4[$prefix],
|
198 |
+
(array) $paths
|
199 |
+
);
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Registers a set of PSR-0 directories for a given prefix,
|
205 |
+
* replacing any others previously set for this prefix.
|
206 |
+
*
|
207 |
+
* @param string $prefix The prefix
|
208 |
+
* @param array|string $paths The PSR-0 base directories
|
209 |
+
*/
|
210 |
+
public function set($prefix, $paths)
|
211 |
+
{
|
212 |
+
if (!$prefix) {
|
213 |
+
$this->fallbackDirsPsr0 = (array) $paths;
|
214 |
+
} else {
|
215 |
+
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
216 |
+
}
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Registers a set of PSR-4 directories for a given namespace,
|
221 |
+
* replacing any others previously set for this namespace.
|
222 |
+
*
|
223 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
224 |
+
* @param array|string $paths The PSR-4 base directories
|
225 |
+
*
|
226 |
+
* @throws \InvalidArgumentException
|
227 |
+
*/
|
228 |
+
public function setPsr4($prefix, $paths)
|
229 |
+
{
|
230 |
+
if (!$prefix) {
|
231 |
+
$this->fallbackDirsPsr4 = (array) $paths;
|
232 |
+
} else {
|
233 |
+
$length = strlen($prefix);
|
234 |
+
if ('\\' !== $prefix[$length - 1]) {
|
235 |
+
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
236 |
+
}
|
237 |
+
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
238 |
+
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
239 |
+
}
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Turns on searching the include path for class files.
|
244 |
+
*
|
245 |
+
* @param bool $useIncludePath
|
246 |
+
*/
|
247 |
+
public function setUseIncludePath($useIncludePath)
|
248 |
+
{
|
249 |
+
$this->useIncludePath = $useIncludePath;
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Can be used to check if the autoloader uses the include path to check
|
254 |
+
* for classes.
|
255 |
+
*
|
256 |
+
* @return bool
|
257 |
+
*/
|
258 |
+
public function getUseIncludePath()
|
259 |
+
{
|
260 |
+
return $this->useIncludePath;
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Turns off searching the prefix and fallback directories for classes
|
265 |
+
* that have not been registered with the class map.
|
266 |
+
*
|
267 |
+
* @param bool $classMapAuthoritative
|
268 |
+
*/
|
269 |
+
public function setClassMapAuthoritative($classMapAuthoritative)
|
270 |
+
{
|
271 |
+
$this->classMapAuthoritative = $classMapAuthoritative;
|
272 |
+
}
|
273 |
+
|
274 |
+
/**
|
275 |
+
* Should class lookup fail if not found in the current class map?
|
276 |
+
*
|
277 |
+
* @return bool
|
278 |
+
*/
|
279 |
+
public function isClassMapAuthoritative()
|
280 |
+
{
|
281 |
+
return $this->classMapAuthoritative;
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
286 |
+
*
|
287 |
+
* @param string|null $apcuPrefix
|
288 |
+
*/
|
289 |
+
public function setApcuPrefix($apcuPrefix)
|
290 |
+
{
|
291 |
+
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* The APCu prefix in use, or null if APCu caching is not enabled.
|
296 |
+
*
|
297 |
+
* @return string|null
|
298 |
+
*/
|
299 |
+
public function getApcuPrefix()
|
300 |
+
{
|
301 |
+
return $this->apcuPrefix;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Registers this instance as an autoloader.
|
306 |
+
*
|
307 |
+
* @param bool $prepend Whether to prepend the autoloader or not
|
308 |
+
*/
|
309 |
+
public function register($prepend = false)
|
310 |
+
{
|
311 |
+
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
312 |
+
|
313 |
+
if (null === $this->vendorDir) {
|
314 |
+
return;
|
315 |
+
}
|
316 |
+
|
317 |
+
if ($prepend) {
|
318 |
+
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
319 |
+
} else {
|
320 |
+
unset(self::$registeredLoaders[$this->vendorDir]);
|
321 |
+
self::$registeredLoaders[$this->vendorDir] = $this;
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Unregisters this instance as an autoloader.
|
327 |
+
*/
|
328 |
+
public function unregister()
|
329 |
+
{
|
330 |
+
spl_autoload_unregister(array($this, 'loadClass'));
|
331 |
+
|
332 |
+
if (null !== $this->vendorDir) {
|
333 |
+
unset(self::$registeredLoaders[$this->vendorDir]);
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Loads the given class or interface.
|
339 |
+
*
|
340 |
+
* @param string $class The name of the class
|
341 |
+
* @return true|null True if loaded, null otherwise
|
342 |
+
*/
|
343 |
+
public function loadClass($class)
|
344 |
+
{
|
345 |
+
if ($file = $this->findFile($class)) {
|
346 |
+
includeFile($file);
|
347 |
+
|
348 |
+
return true;
|
349 |
+
}
|
350 |
+
|
351 |
+
return null;
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Finds the path to the file where the class is defined.
|
356 |
+
*
|
357 |
+
* @param string $class The name of the class
|
358 |
+
*
|
359 |
+
* @return string|false The path if found, false otherwise
|
360 |
+
*/
|
361 |
+
public function findFile($class)
|
362 |
+
{
|
363 |
+
// class map lookup
|
364 |
+
if (isset($this->classMap[$class])) {
|
365 |
+
return $this->classMap[$class];
|
366 |
+
}
|
367 |
+
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
368 |
+
return false;
|
369 |
+
}
|
370 |
+
if (null !== $this->apcuPrefix) {
|
371 |
+
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
372 |
+
if ($hit) {
|
373 |
+
return $file;
|
374 |
+
}
|
375 |
+
}
|
376 |
+
|
377 |
+
$file = $this->findFileWithExtension($class, '.php');
|
378 |
+
|
379 |
+
// Search for Hack files if we are running on HHVM
|
380 |
+
if (false === $file && defined('HHVM_VERSION')) {
|
381 |
+
$file = $this->findFileWithExtension($class, '.hh');
|
382 |
+
}
|
383 |
+
|
384 |
+
if (null !== $this->apcuPrefix) {
|
385 |
+
apcu_add($this->apcuPrefix.$class, $file);
|
386 |
+
}
|
387 |
+
|
388 |
+
if (false === $file) {
|
389 |
+
// Remember that this class does not exist.
|
390 |
+
$this->missingClasses[$class] = true;
|
391 |
+
}
|
392 |
+
|
393 |
+
return $file;
|
394 |
+
}
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
398 |
+
*
|
399 |
+
* @return self[]
|
400 |
+
*/
|
401 |
+
public static function getRegisteredLoaders()
|
402 |
+
{
|
403 |
+
return self::$registeredLoaders;
|
404 |
+
}
|
405 |
+
|
406 |
+
private function findFileWithExtension($class, $ext)
|
407 |
+
{
|
408 |
+
// PSR-4 lookup
|
409 |
+
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
410 |
+
|
411 |
+
$first = $class[0];
|
412 |
+
if (isset($this->prefixLengthsPsr4[$first])) {
|
413 |
+
$subPath = $class;
|
414 |
+
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
415 |
+
$subPath = substr($subPath, 0, $lastPos);
|
416 |
+
$search = $subPath . '\\';
|
417 |
+
if (isset($this->prefixDirsPsr4[$search])) {
|
418 |
+
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
419 |
+
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
420 |
+
if (file_exists($file = $dir . $pathEnd)) {
|
421 |
+
return $file;
|
422 |
+
}
|
423 |
+
}
|
424 |
+
}
|
425 |
+
}
|
426 |
+
}
|
427 |
+
|
428 |
+
// PSR-4 fallback dirs
|
429 |
+
foreach ($this->fallbackDirsPsr4 as $dir) {
|
430 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
431 |
+
return $file;
|
432 |
+
}
|
433 |
+
}
|
434 |
+
|
435 |
+
// PSR-0 lookup
|
436 |
+
if (false !== $pos = strrpos($class, '\\')) {
|
437 |
+
// namespaced class name
|
438 |
+
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
439 |
+
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
440 |
+
} else {
|
441 |
+
// PEAR-like class name
|
442 |
+
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
443 |
+
}
|
444 |
+
|
445 |
+
if (isset($this->prefixesPsr0[$first])) {
|
446 |
+
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
447 |
+
if (0 === strpos($class, $prefix)) {
|
448 |
+
foreach ($dirs as $dir) {
|
449 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
450 |
+
return $file;
|
451 |
+
}
|
452 |
+
}
|
453 |
+
}
|
454 |
+
}
|
455 |
+
}
|
456 |
+
|
457 |
+
// PSR-0 fallback dirs
|
458 |
+
foreach ($this->fallbackDirsPsr0 as $dir) {
|
459 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
460 |
+
return $file;
|
461 |
+
}
|
462 |
+
}
|
463 |
+
|
464 |
+
// PSR-0 include paths.
|
465 |
+
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
466 |
+
return $file;
|
467 |
+
}
|
468 |
+
|
469 |
+
return false;
|
470 |
+
}
|
471 |
+
}
|
472 |
+
|
473 |
+
/**
|
474 |
+
* Scope isolated include.
|
475 |
+
*
|
476 |
+
* Prevents access to $this/self from included files.
|
477 |
+
*/
|
478 |
+
function includeFile($file)
|
479 |
+
{
|
480 |
+
include $file;
|
481 |
+
}
|
vendor/composer/InstalledVersions.php
ADDED
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Composer.
|
5 |
+
*
|
6 |
+
* (c) Nils Adermann <naderman@naderman.de>
|
7 |
+
* Jordi Boggiano <j.boggiano@seld.be>
|
8 |
+
*
|
9 |
+
* For the full copyright and license information, please view the LICENSE
|
10 |
+
* file that was distributed with this source code.
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace Composer;
|
14 |
+
|
15 |
+
use Composer\Autoload\ClassLoader;
|
16 |
+
use Composer\Semver\VersionParser;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* This class is copied in every Composer installed project and available to all
|
20 |
+
*
|
21 |
+
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
22 |
+
*
|
23 |
+
* To require it's presence, you can require `composer-runtime-api ^2.0`
|
24 |
+
*/
|
25 |
+
class InstalledVersions
|
26 |
+
{
|
27 |
+
private static $installed;
|
28 |
+
private static $canGetVendors;
|
29 |
+
private static $installedByVendor = array();
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
33 |
+
*
|
34 |
+
* @return string[]
|
35 |
+
* @psalm-return list<string>
|
36 |
+
*/
|
37 |
+
public static function getInstalledPackages()
|
38 |
+
{
|
39 |
+
$packages = array();
|
40 |
+
foreach (self::getInstalled() as $installed) {
|
41 |
+
$packages[] = array_keys($installed['versions']);
|
42 |
+
}
|
43 |
+
|
44 |
+
if (1 === \count($packages)) {
|
45 |
+
return $packages[0];
|
46 |
+
}
|
47 |
+
|
48 |
+
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Returns a list of all package names with a specific type e.g. 'library'
|
53 |
+
*
|
54 |
+
* @param string $type
|
55 |
+
* @return string[]
|
56 |
+
* @psalm-return list<string>
|
57 |
+
*/
|
58 |
+
public static function getInstalledPackagesByType($type)
|
59 |
+
{
|
60 |
+
$packagesByType = array();
|
61 |
+
|
62 |
+
foreach (self::getInstalled() as $installed) {
|
63 |
+
foreach ($installed['versions'] as $name => $package) {
|
64 |
+
if (isset($package['type']) && $package['type'] === $type) {
|
65 |
+
$packagesByType[] = $name;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
return $packagesByType;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Checks whether the given package is installed
|
75 |
+
*
|
76 |
+
* This also returns true if the package name is provided or replaced by another package
|
77 |
+
*
|
78 |
+
* @param string $packageName
|
79 |
+
* @param bool $includeDevRequirements
|
80 |
+
* @return bool
|
81 |
+
*/
|
82 |
+
public static function isInstalled($packageName, $includeDevRequirements = true)
|
83 |
+
{
|
84 |
+
foreach (self::getInstalled() as $installed) {
|
85 |
+
if (isset($installed['versions'][$packageName])) {
|
86 |
+
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
return false;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Checks whether the given package satisfies a version constraint
|
95 |
+
*
|
96 |
+
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
97 |
+
*
|
98 |
+
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
99 |
+
*
|
100 |
+
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
101 |
+
* @param string $packageName
|
102 |
+
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
103 |
+
* @return bool
|
104 |
+
*/
|
105 |
+
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
106 |
+
{
|
107 |
+
$constraint = $parser->parseConstraints($constraint);
|
108 |
+
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
109 |
+
|
110 |
+
return $provided->matches($constraint);
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Returns a version constraint representing all the range(s) which are installed for a given package
|
115 |
+
*
|
116 |
+
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
117 |
+
* whether a given version of a package is installed, and not just whether it exists
|
118 |
+
*
|
119 |
+
* @param string $packageName
|
120 |
+
* @return string Version constraint usable with composer/semver
|
121 |
+
*/
|
122 |
+
public static function getVersionRanges($packageName)
|
123 |
+
{
|
124 |
+
foreach (self::getInstalled() as $installed) {
|
125 |
+
if (!isset($installed['versions'][$packageName])) {
|
126 |
+
continue;
|
127 |
+
}
|
128 |
+
|
129 |
+
$ranges = array();
|
130 |
+
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
131 |
+
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
132 |
+
}
|
133 |
+
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
134 |
+
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
135 |
+
}
|
136 |
+
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
137 |
+
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
138 |
+
}
|
139 |
+
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
140 |
+
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
141 |
+
}
|
142 |
+
|
143 |
+
return implode(' || ', $ranges);
|
144 |
+
}
|
145 |
+
|
146 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* @param string $packageName
|
151 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
152 |
+
*/
|
153 |
+
public static function getVersion($packageName)
|
154 |
+
{
|
155 |
+
foreach (self::getInstalled() as $installed) {
|
156 |
+
if (!isset($installed['versions'][$packageName])) {
|
157 |
+
continue;
|
158 |
+
}
|
159 |
+
|
160 |
+
if (!isset($installed['versions'][$packageName]['version'])) {
|
161 |
+
return null;
|
162 |
+
}
|
163 |
+
|
164 |
+
return $installed['versions'][$packageName]['version'];
|
165 |
+
}
|
166 |
+
|
167 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param string $packageName
|
172 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
173 |
+
*/
|
174 |
+
public static function getPrettyVersion($packageName)
|
175 |
+
{
|
176 |
+
foreach (self::getInstalled() as $installed) {
|
177 |
+
if (!isset($installed['versions'][$packageName])) {
|
178 |
+
continue;
|
179 |
+
}
|
180 |
+
|
181 |
+
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
182 |
+
return null;
|
183 |
+
}
|
184 |
+
|
185 |
+
return $installed['versions'][$packageName]['pretty_version'];
|
186 |
+
}
|
187 |
+
|
188 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* @param string $packageName
|
193 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
194 |
+
*/
|
195 |
+
public static function getReference($packageName)
|
196 |
+
{
|
197 |
+
foreach (self::getInstalled() as $installed) {
|
198 |
+
if (!isset($installed['versions'][$packageName])) {
|
199 |
+
continue;
|
200 |
+
}
|
201 |
+
|
202 |
+
if (!isset($installed['versions'][$packageName]['reference'])) {
|
203 |
+
return null;
|
204 |
+
}
|
205 |
+
|
206 |
+
return $installed['versions'][$packageName]['reference'];
|
207 |
+
}
|
208 |
+
|
209 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* @param string $packageName
|
214 |
+
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
215 |
+
*/
|
216 |
+
public static function getInstallPath($packageName)
|
217 |
+
{
|
218 |
+
foreach (self::getInstalled() as $installed) {
|
219 |
+
if (!isset($installed['versions'][$packageName])) {
|
220 |
+
continue;
|
221 |
+
}
|
222 |
+
|
223 |
+
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
224 |
+
}
|
225 |
+
|
226 |
+
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* @return array
|
231 |
+
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}
|
232 |
+
*/
|
233 |
+
public static function getRootPackage()
|
234 |
+
{
|
235 |
+
$installed = self::getInstalled();
|
236 |
+
|
237 |
+
return $installed[0]['root'];
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Returns the raw installed.php data for custom implementations
|
242 |
+
*
|
243 |
+
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
244 |
+
* @return array[]
|
245 |
+
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>}
|
246 |
+
*/
|
247 |
+
public static function getRawData()
|
248 |
+
{
|
249 |
+
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
250 |
+
|
251 |
+
if (null === self::$installed) {
|
252 |
+
// only require the installed.php file if this file is loaded from its dumped location,
|
253 |
+
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
254 |
+
if (substr(__DIR__, -8, 1) !== 'C') {
|
255 |
+
self::$installed = include __DIR__ . '/installed.php';
|
256 |
+
} else {
|
257 |
+
self::$installed = array();
|
258 |
+
}
|
259 |
+
}
|
260 |
+
|
261 |
+
return self::$installed;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
266 |
+
*
|
267 |
+
* @return array[]
|
268 |
+
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>}>
|
269 |
+
*/
|
270 |
+
public static function getAllRawData()
|
271 |
+
{
|
272 |
+
return self::getInstalled();
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* Lets you reload the static array from another file
|
277 |
+
*
|
278 |
+
* This is only useful for complex integrations in which a project needs to use
|
279 |
+
* this class but then also needs to execute another project's autoloader in process,
|
280 |
+
* and wants to ensure both projects have access to their version of installed.php.
|
281 |
+
*
|
282 |
+
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
283 |
+
* the data it needs from this class, then call reload() with
|
284 |
+
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
285 |
+
* the project in which it runs can then also use this class safely, without
|
286 |
+
* interference between PHPUnit's dependencies and the project's dependencies.
|
287 |
+
*
|
288 |
+
* @param array[] $data A vendor/composer/installed.php data set
|
289 |
+
* @return void
|
290 |
+
*
|
291 |
+
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>} $data
|
292 |
+
*/
|
293 |
+
public static function reload($data)
|
294 |
+
{
|
295 |
+
self::$installed = $data;
|
296 |
+
self::$installedByVendor = array();
|
297 |
+
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* @return array[]
|
301 |
+
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string}>}>
|
302 |
+
*/
|
303 |
+
private static function getInstalled()
|
304 |
+
{
|
305 |
+
if (null === self::$canGetVendors) {
|
306 |
+
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
307 |
+
}
|
308 |
+
|
309 |
+
$installed = array();
|
310 |
+
|
311 |
+
if (self::$canGetVendors) {
|
312 |
+
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
313 |
+
if (isset(self::$installedByVendor[$vendorDir])) {
|
314 |
+
$installed[] = self::$installedByVendor[$vendorDir];
|
315 |
+
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
316 |
+
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
317 |
+
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
318 |
+
self::$installed = $installed[count($installed) - 1];
|
319 |
+
}
|
320 |
+
}
|
321 |
+
}
|
322 |
+
}
|
323 |
+
|
324 |
+
if (null === self::$installed) {
|
325 |
+
// only require the installed.php file if this file is loaded from its dumped location,
|
326 |
+
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
327 |
+
if (substr(__DIR__, -8, 1) !== 'C') {
|
328 |
+
self::$installed = require __DIR__ . '/installed.php';
|
329 |
+
} else {
|
330 |
+
self::$installed = array();
|
331 |
+
}
|
332 |
+
}
|
333 |
+
$installed[] = self::$installed;
|
334 |
+
|
335 |
+
return $installed;
|
336 |
+
}
|
337 |
+
}
|
vendor/composer/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
Copyright (c) Nils Adermann, Jordi Boggiano
|
3 |
+
|
4 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5 |
+
of this software and associated documentation files (the "Software"), to deal
|
6 |
+
in the Software without restriction, including without limitation the rights
|
7 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8 |
+
copies of the Software, and to permit persons to whom the Software is furnished
|
9 |
+
to do so, subject to the following conditions:
|
10 |
+
|
11 |
+
The above copyright notice and this permission notice shall be included in all
|
12 |
+
copies or substantial portions of the Software.
|
13 |
+
|
14 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20 |
+
THE SOFTWARE.
|
21 |
+
|
vendor/composer/autoload_classmap.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_classmap.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
10 |
+
);
|
vendor/composer/autoload_namespaces.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_namespaces.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
);
|
vendor/composer/autoload_psr4.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_psr4.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
'No3x\\WPML\\Tests\\Helper\\' => array($baseDir . '/tests/helper'),
|
10 |
+
'No3x\\WPML\\Tests\\' => array($baseDir . '/tests/phpunit/tests'),
|
11 |
+
);
|
vendor/composer/autoload_real.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_real.php @generated by Composer
|
4 |
+
|
5 |
+
class ComposerAutoloaderInit64bcd231a77bf5f7870b38c2e715eb2f
|
6 |
+
{
|
7 |
+
private static $loader;
|
8 |
+
|
9 |
+
public static function loadClassLoader($class)
|
10 |
+
{
|
11 |
+
if ('Composer\Autoload\ClassLoader' === $class) {
|
12 |
+
require __DIR__ . '/ClassLoader.php';
|
13 |
+
}
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return \Composer\Autoload\ClassLoader
|
18 |
+
*/
|
19 |
+
public static function getLoader()
|
20 |
+
{
|
21 |
+
if (null !== self::$loader) {
|
22 |
+
return self::$loader;
|
23 |
+
}
|
24 |
+
|
25 |
+
require __DIR__ . '/platform_check.php';
|
26 |
+
|
27 |
+
spl_autoload_register(array('ComposerAutoloaderInit64bcd231a77bf5f7870b38c2e715eb2f', 'loadClassLoader'), true, true);
|
28 |
+
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
29 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit64bcd231a77bf5f7870b38c2e715eb2f', 'loadClassLoader'));
|
30 |
+
|
31 |
+
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
32 |
+
if ($useStaticLoader) {
|
33 |
+
require __DIR__ . '/autoload_static.php';
|
34 |
+
|
35 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit64bcd231a77bf5f7870b38c2e715eb2f::getInitializer($loader));
|
36 |
+
} else {
|
37 |
+
$map = require __DIR__ . '/autoload_namespaces.php';
|
38 |
+
foreach ($map as $namespace => $path) {
|
39 |
+
$loader->set($namespace, $path);
|
40 |
+
}
|
41 |
+
|
42 |
+
$map = require __DIR__ . '/autoload_psr4.php';
|
43 |
+
foreach ($map as $namespace => $path) {
|
44 |
+
$loader->setPsr4($namespace, $path);
|
45 |
+
}
|
46 |
+
|
47 |
+
$classMap = require __DIR__ . '/autoload_classmap.php';
|
48 |
+
if ($classMap) {
|
49 |
+
$loader->addClassMap($classMap);
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
$loader->register(true);
|
54 |
+
|
55 |
+
return $loader;
|
56 |
+
}
|
57 |
+
}
|
vendor/composer/autoload_static.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_static.php @generated by Composer
|
4 |
+
|
5 |
+
namespace Composer\Autoload;
|
6 |
+
|
7 |
+
class ComposerStaticInit64bcd231a77bf5f7870b38c2e715eb2f
|
8 |
+
{
|
9 |
+
public static $prefixLengthsPsr4 = array (
|
10 |
+
'N' =>
|
11 |
+
array (
|
12 |
+
'No3x\\WPML\\Tests\\Helper\\' => 23,
|
13 |
+
'No3x\\WPML\\Tests\\' => 16,
|
14 |
+
),
|
15 |
+
);
|
16 |
+
|
17 |
+
public static $prefixDirsPsr4 = array (
|
18 |
+
'No3x\\WPML\\Tests\\Helper\\' =>
|
19 |
+
array (
|
20 |
+
0 => __DIR__ . '/../..' . '/tests/helper',
|
21 |
+
),
|
22 |
+
'No3x\\WPML\\Tests\\' =>
|
23 |
+
array (
|
24 |
+
0 => __DIR__ . '/../..' . '/tests/phpunit/tests',
|
25 |
+
),
|
26 |
+
);
|
27 |
+
|
28 |
+
public static $classMap = array (
|
29 |
+
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
30 |
+
);
|
31 |
+
|
32 |
+
public static function getInitializer(ClassLoader $loader)
|
33 |
+
{
|
34 |
+
return \Closure::bind(function () use ($loader) {
|
35 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInit64bcd231a77bf5f7870b38c2e715eb2f::$prefixLengthsPsr4;
|
36 |
+
$loader->prefixDirsPsr4 = ComposerStaticInit64bcd231a77bf5f7870b38c2e715eb2f::$prefixDirsPsr4;
|
37 |
+
$loader->classMap = ComposerStaticInit64bcd231a77bf5f7870b38c2e715eb2f::$classMap;
|
38 |
+
|
39 |
+
}, null, ClassLoader::class);
|
40 |
+
}
|
41 |
+
}
|
vendor/composer/installed.json
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"packages": [],
|
3 |
+
"dev": false,
|
4 |
+
"dev-package-names": []
|
5 |
+
}
|
vendor/composer/installed.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php return array(
|
2 |
+
'root' => array(
|
3 |
+
'pretty_version' => 'dev-master',
|
4 |
+
'version' => 'dev-master',
|
5 |
+
'type' => 'wordpress-plugin',
|
6 |
+
'install_path' => __DIR__ . '/../../',
|
7 |
+
'aliases' => array(),
|
8 |
+
'reference' => '82f63ffa7dcfa1746f9b199d64a6cfcfcf9df33b',
|
9 |
+
'name' => 'no3x/wp-mail-logging',
|
10 |
+
'dev' => false,
|
11 |
+
),
|
12 |
+
'versions' => array(
|
13 |
+
'no3x/wp-mail-logging' => array(
|
14 |
+
'pretty_version' => 'dev-master',
|
15 |
+
'version' => 'dev-master',
|
16 |
+
'type' => 'wordpress-plugin',
|
17 |
+
'install_path' => __DIR__ . '/../../',
|
18 |
+
'aliases' => array(),
|
19 |
+
'reference' => '82f63ffa7dcfa1746f9b199d64a6cfcfcf9df33b',
|
20 |
+
'dev_requirement' => false,
|
21 |
+
),
|
22 |
+
),
|
23 |
+
);
|
vendor/composer/platform_check.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// platform_check.php @generated by Composer
|
4 |
+
|
5 |
+
$issues = array();
|
6 |
+
|
7 |
+
if (!(PHP_VERSION_ID >= 50400)) {
|
8 |
+
$issues[] = 'Your Composer dependencies require a PHP version ">= 5.4.0". You are running ' . PHP_VERSION . '.';
|
9 |
+
}
|
10 |
+
|
11 |
+
if ($issues) {
|
12 |
+
if (!headers_sent()) {
|
13 |
+
header('HTTP/1.1 500 Internal Server Error');
|
14 |
+
}
|
15 |
+
if (!ini_get('display_errors')) {
|
16 |
+
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
17 |
+
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
18 |
+
} elseif (!headers_sent()) {
|
19 |
+
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
20 |
+
}
|
21 |
+
}
|
22 |
+
trigger_error(
|
23 |
+
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
24 |
+
E_USER_ERROR
|
25 |
+
);
|
26 |
+
}
|
wp-mail-logging.php
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: WP Mail Logging
|
4 |
-
Plugin URI:
|
5 |
-
Support URI: https://github.com/
|
6 |
-
Version: 1.9.
|
7 |
-
Author:
|
8 |
-
Author URI: https://
|
9 |
Description: Logs each email sent by WordPress.
|
10 |
Text Domain: wp-mail-logging
|
11 |
License: GPLv3
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: WP Mail Logging
|
4 |
+
Plugin URI: https://wordpress.org/plugins/wp-mail-logging/
|
5 |
+
Support URI: https://github.com/kgjerstad/wp-mail-logging/issues
|
6 |
+
Version: 1.9.8
|
7 |
+
Author: Wysija
|
8 |
+
Author URI: https://profiles.wordpress.org/wysija/
|
9 |
Description: Logs each email sent by WordPress.
|
10 |
Text Domain: wp-mail-logging
|
11 |
License: GPLv3
|