├── .githooks
└── pre-commit
├── .github
└── workflows
│ └── php.yml
├── .gitignore
├── .make
├── check-compatibility.sh
├── check-composer.sh
├── check-duplicates.sh
├── check-npm.sh
├── deploy-cleanup.js
├── deploy-copy.js
└── deploy-update-version.js
├── .scrutinizer.yml
├── Makefile
├── README.md
├── composer.json
├── phpcs.xml
├── phpunit.xml
├── src
├── Config
│ └── Factory.php
├── DataConvert.php
├── DynamicContent
│ ├── Field.php
│ └── Strings.php
├── Hooks
│ ├── DynamicElements.php
│ ├── Frontend.php
│ ├── GutenbergCleanup.php
│ └── LandingPages.php
├── LanguageSwitcher
│ ├── LanguageSwitcher.php
│ ├── Widget.php
│ └── WidgetAdaptor.php
├── class-wpml-elementor-adjust-global-widget-id-factory.php
├── class-wpml-elementor-adjust-global-widget-id.php
├── class-wpml-elementor-data-settings.php
├── class-wpml-elementor-db-factory.php
├── class-wpml-elementor-db.php
├── class-wpml-elementor-integration-factory.php
├── class-wpml-elementor-pb-handle-custom-fields-factory.php
├── class-wpml-elementor-register-strings.php
├── class-wpml-elementor-translatable-nodes.php
├── class-wpml-elementor-translate-ids-factory.php
├── class-wpml-elementor-translate-ids.php
├── class-wpml-elementor-update-translation.php
├── class-wpml-elementor-urls-factory.php
├── class-wpml-elementor-urls.php
├── class-wpml-elementor-woocommerce-hooks-factory.php
├── class-wpml-elementor-woocommerce-hooks.php
├── class-wpml-pb-fix-maintenance-query.php
├── media
│ ├── class-wpml-elementor-media-hooks-factory.php
│ ├── class-wpml-elementor-media-node-provider.php
│ ├── class-wpml-elementor-media-nodes-iterator.php
│ ├── class-wpml-elementor-update-media-factory.php
│ └── modules
│ │ ├── AllNodes.php
│ │ ├── Hotspot.php
│ │ ├── VideoPlaylist.php
│ │ ├── abstract
│ │ ├── class-wpml-elementor-media-node-with-image-property.php
│ │ ├── class-wpml-elementor-media-node-with-images-property.php
│ │ ├── class-wpml-elementor-media-node-with-slides.php
│ │ └── class-wpml-elementor-media-node.php
│ │ ├── class-wpml-elementor-media-node-call-to-action.php
│ │ ├── class-wpml-elementor-media-node-image-box.php
│ │ ├── class-wpml-elementor-media-node-image-carousel.php
│ │ ├── class-wpml-elementor-media-node-image-gallery.php
│ │ ├── class-wpml-elementor-media-node-image.php
│ │ ├── class-wpml-elementor-media-node-media-carousel.php
│ │ ├── class-wpml-elementor-media-node-slides.php
│ │ ├── class-wpml-elementor-media-node-wp-widget-media-gallery.php
│ │ └── class-wpml-elementor-media-node-wp-widget-media-image.php
└── modules
│ ├── MediaCarousel.php
│ ├── ModuleWithItemsFromConfig.php
│ ├── MultipleGallery.php
│ ├── Reviews.php
│ ├── class-wpml-elementor-accordion.php
│ ├── class-wpml-elementor-form.php
│ ├── class-wpml-elementor-icon-list.php
│ ├── class-wpml-elementor-module-with-items.php
│ ├── class-wpml-elementor-price-list.php
│ ├── class-wpml-elementor-price-table.php
│ ├── class-wpml-elementor-slides.php
│ ├── class-wpml-elementor-tabs.php
│ ├── class-wpml-elementor-testimonial-carousel.php
│ └── class-wpml-elementor-toggle.php
└── tests
└── phpunit
├── bootstrap.php
├── stubs
├── IWPML_Backend_Action.php
├── IWPML_DIC_Action.php
├── IWPML_Frontend_Action.php
├── interface-iwpml-action.php
└── stub-elementor-db.php
├── tests
├── DynamicContent
│ └── TestStrings.php
├── Hooks
│ ├── TestDynamicElements.php
│ ├── TestFrontend.php
│ ├── TestGutenbergCleanup.php
│ └── TestLandingPages.php
├── LanguageSwitcher
│ ├── TestLanguageSwitcher.php
│ ├── TestWidget.php
│ └── TestWidgetAdaptor.php
├── media
│ ├── modules
│ │ ├── TestHotspot.php
│ │ ├── TestVideoPlaylist.php
│ │ ├── test-AllNodes.php
│ │ ├── test-wpml-elementor-media-node-call-to-action.php
│ │ ├── test-wpml-elementor-media-node-image-box.php
│ │ ├── test-wpml-elementor-media-node-image-carousel.php
│ │ ├── test-wpml-elementor-media-node-image-gallery.php
│ │ ├── test-wpml-elementor-media-node-image.php
│ │ ├── test-wpml-elementor-media-node-media-carousel.php
│ │ ├── test-wpml-elementor-media-node-slides.php
│ │ ├── test-wpml-elementor-media-node-wp-widget-media-gallery.php
│ │ └── test-wpml-elementor-media-node-wp-widget-media-image.php
│ ├── test-wpml-elementor-media-hooks-factory.php
│ ├── test-wpml-elementor-media-node-provider.php
│ ├── test-wpml-elementor-media-nodes-iterator.php
│ └── test-wpml-elementor-update-media-factory.php
├── modules
│ ├── TestMediaCarousel.php
│ ├── TestModuleWithItemsFromConfig.php
│ ├── TestMultipleGallery.php
│ ├── TestReviews.php
│ ├── Test_WPML_Elementor_Module_With_Items.php
│ ├── test-wpml-elementor-accordion.php
│ ├── test-wpml-elementor-form.php
│ ├── test-wpml-elementor-icon-list.php
│ ├── test-wpml-elementor-price-list.php
│ ├── test-wpml-elementor-price-table.php
│ ├── test-wpml-elementor-slides.php
│ ├── test-wpml-elementor-tabs.php
│ ├── test-wpml-elementor-testimonial-carousel.php
│ └── test-wpml-elementor-toggle.php
├── test-pb-fix-maintenance-query.php
├── test-wpml-elementor-adjust-global-widget-id.php
├── test-wpml-elementor-data-settings.php
├── test-wpml-elementor-db-factory.php
├── test-wpml-elementor-db.php
├── test-wpml-elementor-integration-factory.php
├── test-wpml-elementor-register-strings.php
├── test-wpml-elementor-translatable-nodes.php
├── test-wpml-elementor-translate-ids.php
├── test-wpml-elementor-update-translation.php
├── test-wpml-elementor-urls.php
├── test-wpml-elementor-woocommerce-hooks-factory.php
├── test-wpml-elementor-woocommerce-hooks.php
└── test-wpml-pb-handle-custom-fields-factory.php
└── util
└── wpml-pb-test-case2.php
/.githooks/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
3 |
4 | if [ $BRANCH_NAME != '(no branch)' ]
5 | then
6 | make precommit
7 | fi
8 |
--------------------------------------------------------------------------------
/.github/workflows/php.yml:
--------------------------------------------------------------------------------
1 | name: OTGS CI
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | test:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v2
10 |
11 | - uses: nanasess/setup-php@master
12 | with:
13 | php-version: '7.4'
14 |
15 | - name: Set github token for composer
16 | run: composer config -g github-oauth.github.com ${{ secrets.GITHUB_TOKEN }}
17 |
18 | - name: Validate composer.json and composer.lock
19 | run: composer validate
20 |
21 | - name: Install dependencies
22 | run: composer install --prefer-dist --no-progress --no-suggest
23 |
24 | - name: Run test suite
25 | run: ./vendor/bin/phpunit
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea
3 | composer.phar
4 | composer.lock
5 | /vendor/
6 |
--------------------------------------------------------------------------------
/.make/check-compatibility.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php`
4 |
5 | # Determine if a file list is passed
6 | if [[ "$#" -eq 1 ]]
7 | then
8 | oIFS=$IFS
9 | IFS='
10 | '
11 | STAGED_FILES="$1"
12 | IFS=${oIFS}
13 | fi
14 | STAGED_FILES=${STAGED_FILES:-$STAGED_FILES_CMD}
15 |
16 | echo "Checking PHP Lint..."
17 | for FILE in ${STAGED_FILES}
18 | do
19 | php -l -d display_errors=0 ./${FILE}
20 | if [[ $? != 0 ]]
21 | then
22 | echo "Fix the error before commit."
23 | exit 1
24 | else
25 | echo ":: PHP Lint: OK"
26 | fi
27 |
28 | if [[ ${FILE} != tests/* ]]
29 | then
30 | FILES="$FILES ./$FILE"
31 | fi
32 |
33 | FILES="$FILES ./$FILE"
34 | done
35 |
36 | if [[ "$FILES" != "" ]]
37 | then
38 | echo "Running compatibility checks..."
39 | ./vendor/bin/phpcs --standard=./phpcs.compatibility.xml --colors ${FILES}
40 |
41 | if [[ $? != 0 ]]
42 | then
43 | echo "Fix the error before commit!"
44 | exit 1
45 | else
46 | echo ":: Compatibility checks: OK"
47 | fi
48 |
49 | echo "Running Code Sniffer..."
50 | ./vendor/bin/phpcs --colors ${FILES}
51 |
52 | if [[ $? != 0 ]]
53 | then
54 | echo "Fix the error before commit!"
55 | echo "Run"
56 | echo " ./vendor/bin/phpcbf $FILES"
57 | echo "for automatic fix or fix it manually."
58 | exit 1
59 | else
60 | echo ":: Code Sniffer: OK!"
61 | fi
62 | fi
63 |
64 | exit $?
65 |
--------------------------------------------------------------------------------
/.make/check-composer.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | STAGED_FILES=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep -E '^composer.(lock|json)'`
4 |
5 | for FILE in ${STAGED_FILES}
6 | do
7 | FILES="$FILES ./$FILE"
8 | done
9 |
10 | if [[ "$FILES" != "" ]]
11 | then
12 | echo "Validating composer.json"
13 | composer validate --no-check-all
14 |
15 | if [[ $? != 0 ]]
16 | then
17 | exit 1
18 | fi
19 | fi
20 |
21 | exit $?
22 |
--------------------------------------------------------------------------------
/.make/check-duplicates.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php`
4 |
5 | # Determine if a file list is passed
6 | if [[ "$#" -eq 1 ]]
7 | then
8 | oIFS=$IFS
9 | IFS='
10 | '
11 | STAGED_FILES="$1"
12 | IFS=${oIFS}
13 | fi
14 | STAGED_FILES=${STAGED_FILES:-$STAGED_FILES_CMD}
15 |
16 | echo "Checking PHP Lint..."
17 | for FILE in ${STAGED_FILES}
18 | do
19 | if [[ ${FILE} != tests/* ]]
20 | then
21 | FILES="$FILES ./$FILE"
22 | fi
23 | done
24 |
25 | if [[ "$FILES" != "" ]]
26 | then
27 | echo "Running duplicates checks..."
28 | echo "vendor/bin/phpcpd --exclude tests --exclude vendor --${FILES}"
29 | vendor/bin/phpcpd --exclude tests --exclude vendor -- ${FILES}
30 |
31 | if [[ $? != 0 ]]
32 | then
33 | echo "Fix the error before commit!"
34 | exit 1
35 | else
36 | echo ":: Duplicates checks: OK"
37 | fi
38 | fi
39 |
40 | exit $?
41 |
--------------------------------------------------------------------------------
/.make/check-npm.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | STAGED_FILES=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep -E '^src/(yarn.lock|package.json)'`
4 |
5 | for FILE in ${STAGED_FILES}
6 | do
7 | FILES="$FILES ./$FILE"
8 | done
9 |
10 | if [[ "$FILES" != "" ]]
11 | then
12 | echo "Validating package.json"
13 | npm doctor
14 |
15 | if [[ $? != 0 ]]
16 | then
17 | echo "Tip: if you get a failed 'npm config get registry' check, try \`npm config set registry https://registry.npmjs.org/\`"
18 | echo "Tip: if you get a failed 'Perms check on local node_modules' check, try \`sudo chown -R $(whoami) ./node_modules\`"
19 | echo "Tip: if you still get a failed 'Perms check on local node_modules' check, try \`rm -rf node_modules\` followed by \`npm install\`"
20 | exit 1
21 | fi
22 | fi
23 |
24 | exit $?
25 |
--------------------------------------------------------------------------------
/.make/deploy-cleanup.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const path = require('path');
4 | const del = require('del');
5 |
6 | const argv = require('yargs')
7 | .usage('Usage: [options]')
8 | .option('t', {
9 | description: 'The target path to cleanup',
10 | alias: 'target',
11 | demandOption: true,
12 | string: true
13 | })
14 | .option('d', {
15 | description: 'Debug',
16 | alias: 'debug',
17 | boolean: true,
18 | default: false
19 | })
20 | .argv;
21 |
22 | const targetPath = path.normalize(argv.target);
23 |
24 | cleanupTarget();
25 |
26 | function cleanupTarget() {
27 | if (!process.env.OTGS_CI_DEPLOY_DEL && argv.debug) {
28 | setTestPatterns();
29 | }
30 |
31 | if (process.env.OTGS_CI_DEPLOY_DEL) {
32 | const currentDirectory = process.cwd();
33 | process.chdir(targetPath);
34 | const del_patterns = JSON.parse(process.env.OTGS_CI_DEPLOY_DEL);
35 |
36 | return del(del_patterns, {dot: true,})
37 | .then(paths => {
38 | process.chdir(currentDirectory);
39 | return console.info(`Deleted ${paths.length} files`);
40 | })
41 | .catch(error => console.error(error));
42 | } else {
43 | throw new Error('An environment variable named OTGS_CI_DEPLOY_DEL and containing a JSON array of Glob patterns is required.');
44 | }
45 | }
46 |
47 | function setTestPatterns() {
48 | const testPatterns = [
49 | "**/*/*.css.map",
50 | "**/*/*.js.map",
51 | "**/*/*.scss",
52 | "*.js",
53 | "*.json",
54 | "*.sh",
55 | "*.xml",
56 | "*.xml.dist",
57 | ".*",
58 | ".babelrc",
59 | ".browserslistrc",
60 | ".eslintrc",
61 | ".githooks",
62 | ".make",
63 | "build",
64 | "composer.*",
65 | "libraries/**/*/*.log",
66 | "libraries/**/*/*.md",
67 | "libraries/**/*/.*",
68 | "libraries/**/*/bin",
69 | "libraries/**/*/demo",
70 | "libraries/**/*/doc",
71 | "libraries/**/*/node_modules",
72 | "libraries/**/*/src",
73 | "libraries/**/*/test",
74 | "libraries/vkBeautify/**/*",
75 | "Makefile",
76 | "node_modules",
77 | "package.json",
78 | "postcss.config.json",
79 | "README.md",
80 | "res/scss",
81 | "src",
82 | "tests",
83 | "vendor/**/*/*.json",
84 | "vendor/**/*/*.md",
85 | "vendor/**/*/*.txt",
86 | "vendor/**/*/*.xml",
87 | "vendor/**/*/*.xml.dist",
88 | "vendor/**/*/.*",
89 | "vendor/**/*/composer.*",
90 | "vendor/**/*/test/**",
91 | "vendor/**/*/tests/**",
92 | "vendor/bin",
93 | "vendor/wimg",
94 | "vendor/xrstf",
95 | "webpack.config.js",
96 | "yarn-error.log",
97 | "yarn.lock",
98 | "!changelog.md",
99 | "!libraries/vkBeautify/vkbeautify.js",
100 | "!license.txt",
101 | "!readme.txt",
102 | "!vendor/**/*/lib/test*",
103 | "!vendor/**/*/README.md",
104 | "!vendor/**/*/src/test*",
105 | "!vendor/otgs/installer/*.xml",
106 | "!wpml-config.xml",
107 | "!wpml-dependencies.json"
108 | ];
109 |
110 | process.env.OTGS_CI_DEPLOY_DEL = JSON.stringify(testPatterns);
111 | }
112 |
--------------------------------------------------------------------------------
/.make/deploy-copy.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require('fs-extra');
4 | const path = require('path');
5 | const copy = require('recursive-copy');
6 |
7 | const argv = require('yargs')
8 | .usage('Usage: [options]')
9 | .option('s', {
10 | description: 'The source path',
11 | alias: 'source',
12 | string: true,
13 | default: process.cwd(),
14 | })
15 | .option('t', {
16 | description: 'The target path',
17 | alias: 'target',
18 | demandOption: true,
19 | string: true,
20 | })
21 | .option('d', {
22 | description: 'Debug',
23 | alias: 'debug',
24 | boolean: true,
25 | default: false
26 | })
27 | .demand('t')
28 | .argv;
29 |
30 | const sourcePath = validatePath(path.normalize(argv.source));
31 | const targetPath = path.normalize(argv.target);
32 |
33 | emptyTargetDirectory().then(() => copySourceFiles());
34 |
35 | function validatePath(pathToCheck) {
36 | if (pathToCheck && fs.existsSync(pathToCheck)) {
37 | return pathToCheck;
38 | }
39 | throw new Error(pathToCheck + ' does not exist!');
40 | }
41 |
42 |
43 | function emptyTargetDirectory() {
44 |
45 | return fs.remove(targetPath)
46 | .then(() => console.log(targetPath + ' removed.'))
47 | .catch(err => console.error(err));
48 |
49 | }
50 |
51 | function copySourceFiles() {
52 | return copy(sourcePath, targetPath, {
53 | dot: false,
54 | junk: false,
55 | results: true,
56 | })
57 | // .on(copy.events.COPY_FILE_COMPLETE, function (copyOperation) {
58 | // process.stdout.write('.');
59 | // // console.info('Copied to ' + copyOperation.dest);
60 | // })
61 | .on(copy.events.ERROR, function (error, copyOperation) {
62 | console.error('Unable to copy ' + copyOperation.dest);
63 | })
64 | .then(function (results) {
65 | console.info('\n' + results.length + ' file(s) copied');
66 | })
67 | .catch(function (error) {
68 | return console.error('\nCopy failed: ' + error);
69 | });
70 | }
71 |
--------------------------------------------------------------------------------
/.make/deploy-update-version.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require('fs-extra');
4 | const path = require('path');
5 |
6 | const argv = require('yargs')
7 | .usage('Usage: [options]')
8 | .option('t', {
9 | description: 'The target path to update',
10 | alias: 'target',
11 | default: process.cwd(),
12 | string: true
13 | })
14 | .option('r', {
15 | description: 'The version',
16 | alias: 'ref',
17 | demandOption: true,
18 | string: true,
19 | })
20 | .option('d', {
21 | description: 'Debug',
22 | alias: 'debug',
23 | boolean: true,
24 | default: false
25 | })
26 | .argv;
27 |
28 | const targetPath = path.normalize(argv.target);
29 |
30 | updatePluginVersion();
31 |
32 | function updatePluginVersion() {
33 | if (!process.env.OTGS_CI_REPLACEMENTS && argv.debug) {
34 | setTestPatterns();
35 | }
36 |
37 | const tag = argv.ref.trim();
38 |
39 | if (process.env.OTGS_CI_REPLACEMENTS) {
40 | const currentDirectory = process.cwd();
41 | process.chdir(targetPath);
42 |
43 | const mainPluginFile = getMainPluginFile();
44 |
45 | if (mainPluginFile) {
46 | const file = mainPluginFile.file;
47 | const content = mainPluginFile.content;
48 | let updatedContent = content;
49 |
50 | console.info('- Found "' + file + '": updating...');
51 |
52 | const replacement_patterns = JSON.parse(process.env.OTGS_CI_REPLACEMENTS.replace(/(%)(\d)/g, '$$$2'));
53 |
54 | replacement_patterns
55 | .filter(regex_args => {
56 | const regExp = new RegExp(regex_args.searchPattern, 'g');
57 | return regExp.test(updatedContent);
58 | })
59 | .map((regex_args, index) => {
60 |
61 | const use = regex_args.extractSemVer ? regex_args.extractSemVer : false;
62 | const tagName = use ? extractSemVer(tag) : tag;
63 | const tagSlug = tagName.trim().replace(/\./g, '-');
64 |
65 | const regExp = new RegExp(regex_args.searchPattern, 'g');
66 |
67 | if (regExp.test(updatedContent)) {
68 | process.stdout.write((index + 1) + ') Will search for "' + regex_args.searchPattern);
69 | process.stdout.write(' using "' + tagName + '" as a tag and "' + tagSlug + '" as a tag slug');
70 | process.stdout.write(' and replacing it with "' + regex_args.replacePattern + '"\n');
71 |
72 | updatedContent = updatedContent.replace(regExp, regex_args.replacePattern)
73 | .replace(/{{tag-slug}}/g, tagSlug)
74 | .replace(/{{tag}}/g, tagName);
75 | }
76 | });
77 |
78 | if (!argv.dryRun && updatedContent !== content) {
79 | fs.writeFileSync(file, updatedContent, {encoding: 'utf8'});
80 | }
81 |
82 | process.chdir(currentDirectory);
83 | }
84 | } else {
85 | console.info('A constant named OTGS_CI_REPLACEMENTS hasn\'t been set: skipping.');
86 | }
87 | }
88 |
89 | function extractSemVer(version) {
90 | const versionElements = version
91 | .trim()
92 | .replace(/-/g, '.')
93 | .replace(/_/g, '.')
94 | .replace(/\+/g, '.')
95 | .replace(/([^0-9.]+)/, '.$1.')
96 | .replace(/\.{2,}/g, '.')
97 | .split('.');
98 |
99 | const nakedElements = ['0', '0', '0'];
100 |
101 | versionElements
102 | .filter(element => !isNaN(element))
103 | .slice(0, 3)
104 | .map((element, index) => {
105 | nakedElements[index] = element;
106 | });
107 |
108 | return nakedElements.join('.');
109 | }
110 |
111 | function getMainPluginFile() {
112 | const files = fs.readdirSync(process.cwd());
113 |
114 | const phpFiles = files
115 | .filter(file => path.extname(file).toLowerCase() === '.php')
116 | .filter(file => {
117 |
118 | const content = fs.readFileSync(file, 'utf8')
119 | .replace(/[\t\n\r]/g, '')
120 | .trim();
121 |
122 | return content.indexOf(' 0
124 | && content.indexOf('Description: ') > 0;
125 |
126 | });
127 |
128 | if (phpFiles) {
129 | const file = phpFiles[0];
130 | return {file, content: fs.readFileSync(file, 'utf8')};
131 | }
132 | return null;
133 | }
134 |
135 | function setTestPatterns() {
136 | const testPatterns = [
137 | {
138 | "searchPattern": "(Version:\\s*)(\\d*.*)",
139 | "replacePattern": "%1{{tag}}"
140 | },
141 | {
142 | "searchPattern": "(GRAVITYFORMS_MULTILINGUAL_VERSION\\',\\s*\\')(\\d*.*)(\\')",
143 | "replacePattern": "%1{{tag}}%3",
144 | "extractSemVer": true
145 | },
146 | {
147 | "searchPattern": "(wpml.org\\/version\\/wpml-)([\\d\\-*]*)(\\/\">WPML )([\\d\\.*]*)( release notes)",
148 | "replacePattern": "%1{{tag-slug}}%3{{tag}}%5"
149 | },
150 | {
151 | "searchPattern": "(WCML_VERSION\\',\\s*\\')(\\d*.*)(\\')",
152 | "replacePattern": "%1{{tag}}%3",
153 | "extractSemVer": true
154 | },
155 | {
156 | "searchPattern": "(wpml.org\\/version\\/cms-nav-)([\\d\\-*]*)(\\/\">WPML CMS Nav )([\\d\\.*]*)( release notes)",
157 | "replacePattern": "%1{{tag-slug}}%3{{tag}}%5"
158 | },
159 | {
160 | "searchPattern": "(wpml.org\\/version\\/gravityforms-multilingual-)([\\d\\-*]*)(\\/\">Gravity Forms Multilingual )([\\d\\.*]*)( release notes)",
161 | "replacePattern": "%1{{tag-slug}}%3{{tag}}%5"
162 | },
163 | {
164 | "searchPattern": "(wpml.org\\/version\\/media-translation-)([\\d\\-*]*)(\\/\">WPML Media Translation )([\\d\\.*]*)( release notes)",
165 | "replacePattern": "%1{{tag-slug}}%3{{tag}}%5"
166 | },
167 | {
168 | "searchPattern": "(wpml.org\\/version\\/sticky-links-)([\\d\\-*]*)(\\/\">WPML Sticky Links )([\\d\\.*]*)( release notes)",
169 | "replacePattern": "%1{{tag-slug}}%3{{tag}}%5"
170 | },
171 | {
172 | "searchPattern": "(wpml.org\\/version\\/string-translation-)([\\d\\-*]*)(\\/\">WPML String Translation )([\\d\\.*]*)( release notes)",
173 | "replacePattern": "%1{{tag-slug}}%3{{tag}}%5"
174 | },
175 | {
176 | "searchPattern": "(wpml.org\\/version\\/translation-management-)([\\d\\-*]*)(\\/\">WPML Translation Management )([\\d\\.*]*)( release notes)",
177 | "replacePattern": "%1{{tag-slug}}%3{{tag}}%5"
178 | },
179 | {
180 | "searchPattern": "(ICL_SITEPRESS_VERSION\\',\\s*\\')(\\d*.*)(\\')",
181 | "replacePattern": "%1{{tag}}%3",
182 | "extractSemVer": true
183 | },
184 | {
185 | "searchPattern": "(WPML_CMS_NAV_VERSION\\',\\s*\\')(\\d*.*)(\\')",
186 | "replacePattern": "%1{{tag}}%3",
187 | "extractSemVer": true
188 | },
189 | {
190 | "searchPattern": "(WPML_MEDIA_VERSION\\',\\s*\\')(\\d*.*)(\\')",
191 | "replacePattern": "%1{{tag}}%3",
192 | "extractSemVer": true
193 | },
194 | {
195 | "searchPattern": "(WPML_ST_VERSION\\',\\s*\\')(\\d*.*)(\\')",
196 | "replacePattern": "%1{{tag}}%3",
197 | "extractSemVer": true
198 | },
199 | {
200 | "searchPattern": "(WPML_STICKY_LINKS_VERSION\\',\\s*\\')(\\d*.*)(\\')",
201 | "replacePattern": "%1{{tag}}%3",
202 | "extractSemVer": true
203 | },
204 | {
205 | "searchPattern": "(WPML_TM_VERSION\\',\\s*\\')(\\d*.*)(\\')",
206 | "replacePattern": "%1{{tag}}%3",
207 | "extractSemVer": true
208 | }
209 | ];
210 |
211 | process.env.OTGS_CI_REPLACEMENTS = JSON.stringify(testPatterns);
212 | }
213 |
--------------------------------------------------------------------------------
/.scrutinizer.yml:
--------------------------------------------------------------------------------
1 | ---
2 | checks:
3 | php:
4 | code_rating: true
5 | duplication: true
6 | filter:
7 | excluded_paths:
8 | - "tests/"
9 | - "vendor/"
10 | coding_style:
11 | php:
12 | indentation:
13 | general:
14 | use_tabs: true
15 | spaces:
16 | around_operators:
17 | concatenation: true
18 | negation: true
19 |
20 | build:
21 | cache:
22 | directories:
23 | - vendor/
24 | nodes:
25 | phpcs:
26 | environment:
27 | php: 7.3
28 | tests:
29 | override:
30 | - on_node: 1
31 | idle_timeout: 4800
32 | command: "phpcs-run ./"
33 |
34 | php56:
35 | environment:
36 | php: 5.6
37 | php70:
38 | environment:
39 | php: 7.0
40 | php71:
41 | environment:
42 | php: 7.1
43 | php72:
44 | environment:
45 | php: 7.2
46 |
47 | php73-cover:
48 | environment:
49 | php: 7.3
50 | tests:
51 | override:
52 | - on_node: 2
53 | idle_timeout: 4800
54 | command: "./vendor/bin/phpunit --fail-on-warning --coverage-clover ./coverage.xml"
55 | coverage:
56 | file: ./coverage.xml
57 | format: php-clover
58 | tests:
59 | override:
60 | - on_node: 1
61 | idle_timeout: 4800
62 | command: "./vendor/bin/phpunit"
63 |
64 | build_failure_conditions:
65 | - 'project.metric_change("scrutinizer.test_coverage", < 0)'
66 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Tutorial: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/
2 | # Docs: https://www.gnu.org/software/make/
3 |
4 | # Help
5 | .PHONY: help
6 |
7 | help:
8 | $(info Run `make setup` to configure the Git Hooks and install the dependencies`)
9 | $(info Run `make install` to install the dependencies)
10 | $(info Run `make install-prod` to install the dependencies in production mode)
11 | $(info - Run `make composer-install` to only install Composer dependencies)
12 | $(info - Run `make composer-install-prod` to only install Composer dependencies in production mode)
13 | $(info - Run `make npm-install` to only install Node dependencies)
14 | $(info - Run `make npm-install-prod` to only install Node dependencies in production mode)
15 | $(info Run `make tests` to run all tests)
16 | $(info - Run `make jest` to run only Jest tests)
17 | $(info - Run `make phpunit` to run only PhpUnit tests)
18 | $(info Run `make dev` to bundle WebPack modules in development mode)
19 | $(info Run `make prod` to bundle WebPack modules in production mode)
20 |
21 | # Setup
22 | .PHONY: setup githooks
23 |
24 | setup:: githooks
25 | setup:: install
26 |
27 | githooks:
28 | ifdef CI
29 | $(info Skipping Git Hooks in CI)
30 | else ifdef OS
31 | cp .githooks/* .git/hooks/
32 | $(info Looks like you are on Windows... files copied.)
33 |
34 | else
35 | @find .git/hooks -type l -exec rm {} \;
36 | @find .githooks -type f -exec ln -sf ../../{} .git/hooks/ \;
37 | $(info Git Hooks installed)
38 | endif
39 |
40 | # Install
41 | .PHONY: install
42 |
43 | install: composer-install
44 | install: npm-install
45 |
46 | install-prod: composer-install-prod
47 | install-prod: npm-install-prod
48 |
49 | # Build
50 | .PHONY: dev prod
51 |
52 | dev prod: npm-install
53 | @npm run build:$@
54 | $(info WebPack modules bundled)
55 |
56 | # Tests
57 | .PHONY: tests
58 |
59 | tests:: jest
60 | tests:: phpunit
61 |
62 | # Git Hooks
63 | .PHONY: precommit
64 |
65 | precommit:: validate-composer
66 | precommit:: validate-npm
67 | precommit:: dupes
68 | precommit:: compatibility
69 |
70 | # precommit
71 | .PHONY: dupes compatibility validate-composer validate-npm
72 |
73 | dupes: composer-install
74 | ./.make/check-duplicates.sh
75 |
76 | compatibility: composer-install
77 | ./.make/check-compatibility.sh
78 |
79 | validate-composer: composer-install
80 | ./.make/check-composer.sh
81 |
82 | validate-npm: npm-install
83 | ./.make/check-npm.sh
84 |
85 |
86 | # Dependency managers
87 |
88 | ## Composer
89 | .PHONY: composer-install
90 |
91 | composer.lock: composer-install
92 | @touch $@
93 |
94 | vendor/autoload.php: composer-install
95 | @touch $@
96 |
97 | composer-install:
98 | $(info Installing Composer dependencies)
99 | @composer install
100 |
101 | composer-install-prod:
102 | $(info Installing Composer dependencies)
103 | @composer --no-dev install
104 |
105 | ## NPM
106 | .PHONY: npm-install
107 |
108 | package.json: npm-install
109 | @touch $@
110 |
111 | package-lock.json: npm-install
112 | @touch $@
113 |
114 | npm-install:
115 | $(info Installing Node dependencies)
116 | @npm install
117 |
118 | npm-install-prod:
119 | $(info Installing Node dependencies)
120 | @npm --prod install
121 |
122 | # Tests
123 | .PHONY: jest phpunit
124 |
125 | jest: npm-install
126 | $(info Running Jest)
127 | @npm run test
128 |
129 | phpunit: composer-install
130 | $(info Running PhpUnit)
131 | @vendor/bin/phpunit --fail-on-warning
132 | # Use the following if the phpunit.xml is on a different location
133 | # @vendor/bin/phpunit --fail-on-warning --configuration tests/phpunit/phpunit.xml
134 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This package has been merged into the [WPML Page Builders](https://git.onthegosystems.com/glue-plugins/wpml/wpml-page-builders) addon.
2 |
3 | ----
4 |
5 | # wpml-page-builders-elementor
6 | A library used by [WPML](https://wpml.org) for handling [Elementor](https://wpml.org/documentation/plugins-compatibility/elementor/).
7 |
8 | 
9 |
10 | 
11 |
12 | [](https://scrutinizer-ci.com/g/OnTheGoSystems/wpml-page-builders-elementor/build-status/master)
13 |
14 | ## Packagist
15 |
16 | [](https://packagist.org/packages/wpml/page-builders-elementor)
17 |
18 | [](https://packagist.org/packages/wpml/page-builders-elementor)
19 |
20 | [](https://packagist.org/packages/wpml/page-builders-elementor)
21 |
22 | [](https://packagist.org/packages/wpml/page-builders-elementor)
23 |
24 | [](https://packagist.org/packages/wpml/page-builders-elementor)
25 |
26 | ## Monthly Downloads
27 | [](https://packagist.org/packages/wpml/page-builders-elementor)
28 |
29 | ## Daily Downloads
30 | [](https://packagist.org/packages/wpml/page-builders-elementor)
31 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wpml/page-builders-elementor",
3 | "description": "A library used by WPML to handle Elementor",
4 | "type": "library",
5 | "license": "GPL-3.0-or-later",
6 | "authors": [
7 | {
8 | "name": "OnTheGoSystems",
9 | "email": "hello@wpml.org"
10 | }
11 | ],
12 | "repositories": {
13 | "elementor": {
14 | "type":"package",
15 | "package": {
16 | "name": "elementor/elementor",
17 | "version":"master",
18 | "source": {
19 | "url": "https://github.com/elementor/elementor.git",
20 | "type": "git",
21 | "reference":"master"
22 | }
23 | }
24 | },
25 | "collect": {
26 | "type": "vcs",
27 | "url": "https://github.com/OnTheGoSystems/collect.git"
28 | }
29 | },
30 | "autoload": {
31 | "classmap": [
32 | "src/"
33 | ]
34 | },
35 | "autoload-dev": {
36 | "classmap": [
37 | "tests/phpunit/stubs/",
38 | "tests/phpunit/util/"
39 | ]
40 | },
41 | "require": {
42 | "roave/security-advisories": "dev-master",
43 | "jakeasmith/http_build_url": "^1.0"
44 | },
45 | "require-dev": {
46 | "phpunit/phpunit": "~5.7",
47 | "otgs/unit-tests-framework": "~1.2.0",
48 | "wpml/page-builders": "dev-master",
49 | "elementor/elementor": "dev-master",
50 | "wpml/collect": "dev-wpml-collect-rename",
51 | "wpml/fp": "^0.1.1",
52 | "wpml/wp": "^0.1.1",
53 | "composer/composer": "^1.10"
54 | },
55 | "scripts": {
56 | "post-update-cmd": [
57 | "sed -i'' 's/final public function add_group_control/public function add_group_control/g' ./vendor/elementor/elementor/includes/base/controls-stack.php"
58 | ]
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
<\/p>\n
Something sure!<\/p>\n
<\/p>' ); 98 | 99 | \WP_Mock::userFunction( 'update_metadata', [ 100 | 'times' => 0 101 | ]); 102 | 103 | $isEditedWithElementor = FunctionMocker::replace( WPML_Elementor_Data_Settings::class . '::is_edited_with_elementor', true ); 104 | 105 | \WP_Mock::userFunction( 'update_post_metadata' )->never(); 106 | 107 | $subject = new GutenbergCleanup(); 108 | 109 | $this->assertSame( 110 | $check, 111 | $subject->removeGutenbergFootprint( $check, $postId, $metaKey, $metaValue ) 112 | ); 113 | 114 | $isEditedWithElementor->wasCalledWithOnce( [ $postId ] ); 115 | } 116 | 117 | /** 118 | * @test 119 | */ 120 | public function itShouldRemoveGbFootprintIfOneBlockIsFound() { 121 | $check = 'some boolean'; 122 | $postId = 123; 123 | $metaKey = WPML_Elementor_Data_Settings::META_KEY_DATA; 124 | $metaValue = self::getMetaValue( '
<\/p>\n
Something sure!<\/p>\n
<\/p>' ); 125 | $newMetaValue = self::getMetaValue( '
<\/p>\n
Something sure!<\/p>\n
<\/p>' ); 126 | 127 | \WP_Mock::userFunction( 'update_metadata', [ 128 | 'args' => [ 'post', $postId, WPML_Elementor_Data_Settings::META_KEY_DATA, $newMetaValue ], 129 | 'times' => 1 130 | ]); 131 | 132 | $elementorPackage = $this->getPackage( 'elementor', $postId ); 133 | $gutenbergPackage = $this->getPackage( 'gutenberg', $postId ); 134 | $unknownPackage = $this->getPackage( 'unknown', $postId ); 135 | 136 | $isEditedWithElementor = FunctionMocker::replace( WPML_Elementor_Data_Settings::class . '::is_edited_with_elementor', true ); 137 | 138 | \WP_Mock::onFilter( 'wpml_st_get_post_string_packages' ) 139 | ->with( [], $postId ) 140 | ->reply( [ $elementorPackage, $gutenbergPackage, $unknownPackage ] ); 141 | 142 | $deleteAction = FunctionMocker::replace( 'do_action' ); 143 | 144 | $subject = new GutenbergCleanup(); 145 | 146 | $this->assertTrue( 147 | $subject->removeGutenbergFootprint( $check, $postId, $metaKey, $metaValue ) 148 | ); 149 | 150 | $isEditedWithElementor->wasCalledWithOnce( [ $postId ] ); 151 | $deleteAction->wasCalledWithOnce( [ 'wpml_delete_package', $gutenbergPackage->name, $gutenbergPackage->kind ] ); 152 | } 153 | 154 | private static function getMetaValue( $editorContent ) { 155 | return '[{"id":"dc45eec","elType":"section","settings":[],"elements":[{"id":"761adbdf","elType":"column","settings":{"_column_size":100},"elements":[{"id":"88004c2","elType":"widget","settings":{"title":"Add Your Heading Text Here"},"elements":[],"widgetType":"heading"},{"id":"888e41","elType":"widget","settings":{"editor":"' . $editorContent . '","__globals__":{"text_color":"globals\/colors?id=accent"}},"elements":[],"widgetType":"text-editor"}],"isInner":false}],"isInner":false}]'; 156 | } 157 | 158 | private function getPackage( $kind, $name ) { 159 | $package = $this->getMockBuilder( '\WPML_Package' )->getMock(); 160 | $package->kind_slug = strtolower( $kind ); 161 | $package->kind = strtoupper( $kind ); 162 | $package->name = $name; 163 | 164 | return $package; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /tests/phpunit/tests/Hooks/TestLandingPages.php: -------------------------------------------------------------------------------- 1 | with( 'permalink_structure' )->andReturn( '' ); 16 | 17 | $subject = $this->getSubject(); 18 | \WP_Mock::expectFilterNotAdded( 'post_type_link', [ $subject, 'adjustLink' ], PHP_INT_MAX, 2 ); 19 | $subject->add_hooks(); 20 | } 21 | 22 | /** 23 | * @test 24 | */ 25 | public function itShouldAddHooksWithCustomPermalinks() { 26 | \WP_Mock::userFunction( 'get_option' )->with( 'permalink_structure' )->andReturn( 'some custom permalinks' ); 27 | 28 | $subject = $this->getSubject(); 29 | \WP_Mock::expectFilterAdded( 'post_type_link', [ $subject, 'adjustLink' ], PHP_INT_MAX, 2 ); 30 | $subject->add_hooks(); 31 | } 32 | 33 | /** 34 | * @test 35 | * @dataProvider dpShouldNotFilterLinks 36 | * 37 | * @param \WP_Post $post 38 | */ 39 | public function itShouldNotFilterLinks( $post ) { 40 | $postUrl = 'https://example.com/city/london/'; 41 | 42 | $this->assertEquals( 43 | $postUrl, 44 | $this->getSubject()->adjustLink( $postUrl, $post ) 45 | ); 46 | } 47 | 48 | public function dpShouldNotFilterLinks() { 49 | return [ 50 | 'not a landing page' => [ $this->getPost( 123, 'city', 'publish' ) ], 51 | 'not published' => [ $this->getPost( 123, LandingPages::POST_TYPE, 'draft' ) ], 52 | ]; 53 | } 54 | 55 | /** 56 | * @test 57 | */ 58 | public function itShouldFilterLinks() { 59 | $homeUrl = 'https://example.com'; 60 | $postUrl = $homeUrl . '/my-landing-page/'; 61 | $post = $this->getPost( 123, LandingPages::POST_TYPE, 'publish','translated-landing-page' ); 62 | $postLang = 'fr'; 63 | $translatedUrl = $homeUrl . '/' . $postLang . '/' . $post->post_name; 64 | 65 | \WP_Mock::userFunction( 'get_home_url' )->andReturn( $homeUrl ); 66 | \WP_Mock::userFunction( 'wp_parse_url', [ 67 | 'return' => function( $url ) { return parse_url( $url ); }, 68 | ] ); 69 | \WP_Mock::userFunction( 'trailingslashit', [ 70 | 'return' => function( $value ) { return $value . '/'; }, 71 | ] ); 72 | 73 | $sitepress = $this->getSitepress(); 74 | $sitepress->method( 'get_language_for_element' ) 75 | ->with( $post->ID, 'post_' . LandingPages::POST_TYPE ) 76 | ->willReturn( $postLang ); 77 | $sitepress->method( 'convert_url' ) 78 | ->with( $homeUrl . '/' . $post->post_name . '/' ) 79 | ->willReturn( $translatedUrl ); 80 | 81 | $subject = $this->getSubject( $sitepress ); 82 | 83 | $this->assertEquals( 84 | $translatedUrl, 85 | $subject->adjustLink( $postUrl, $post ) 86 | ); 87 | } 88 | 89 | private function getSubject( $sitepress = null ) { 90 | $sitepress = $sitepress ?: $this->getSitepress(); 91 | return new LandingPages( $sitepress ); 92 | } 93 | 94 | private function getSitepress() { 95 | return $this->getMockBuilder( \SitePress::class ) 96 | ->setMethods( [ 97 | 'get_language_for_element', 98 | 'convert_url', 99 | ] ) 100 | ->getMock(); 101 | } 102 | 103 | private function getPost( $id, $type, $status = 'publish', $name = 'something' ) { 104 | $post = $this->getMockBuilder( \WP_Post::class )->getMock(); 105 | $post->ID = $id; 106 | $post->post_type = $type; 107 | $post->post_status = $status; 108 | $post->post_name = $name; 109 | 110 | return $post; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /tests/phpunit/tests/LanguageSwitcher/TestLanguageSwitcher.php: -------------------------------------------------------------------------------- 1 | add_hooks(); 18 | } 19 | 20 | /** 21 | * @test 22 | */ 23 | public function itShouldregisterWidgets() { 24 | $subject = new LanguageSwitcher(); 25 | 26 | $widgetManager = $this->getMockBuilder( 'Elementor\Widgets_Manager' ) 27 | ->setMethods( [ 'register_widget_type' ] ) 28 | ->disableOriginalConstructor() 29 | ->getMock(); 30 | $widgetManager->expects( $this->once() )->method( 'register_widget_type' )->with( new Widget() ); 31 | 32 | $elementorPlugin = \Mockery::mock( 'alias:Elementor\Plugin' ); 33 | $elementorPlugin->shouldReceive( 'instance' )->andReturnSelf(); 34 | $elementorPlugin->widgets_manager = $widgetManager; 35 | 36 | $subject->registerWidgets(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/phpunit/tests/LanguageSwitcher/TestWidget.php: -------------------------------------------------------------------------------- 1 | getAdaptor(); 24 | $adaptor->method( 'getName' )->willReturn( 'my name' ); 25 | 26 | $subject = $this->getSubject( $adaptor ); 27 | 28 | $this->assertEquals( 'my name', $subject->get_name() ); 29 | } 30 | 31 | /** 32 | * @test 33 | */ 34 | public function itShouldGetTitle() { 35 | $adaptor = $this->getAdaptor(); 36 | $adaptor->method( 'getTitle' )->willReturn( 'my title' ); 37 | 38 | $subject = $this->getSubject( $adaptor ); 39 | 40 | $this->assertEquals( 'my title', $subject->get_title() ); 41 | } 42 | 43 | /** 44 | * @test 45 | */ 46 | public function itShouldGetIcon() { 47 | $adaptor = $this->getAdaptor(); 48 | $adaptor->method( 'getIcon' )->willReturn( 'my icon' ); 49 | 50 | $subject = $this->getSubject( $adaptor ); 51 | 52 | $this->assertEquals( 'my icon', $subject->get_icon() ); 53 | } 54 | 55 | /** 56 | * @test 57 | */ 58 | public function itShouldGetCategories() { 59 | $categories = [ 'my category' ]; 60 | 61 | $adaptor = $this->getAdaptor(); 62 | $adaptor->method( 'getCategories' )->willReturn( $categories ); 63 | 64 | $subject = $this->getSubject( $adaptor ); 65 | 66 | $this->assertEquals( $categories, $subject->get_categories() ); 67 | } 68 | 69 | private function getSubject( $adaptor ) { 70 | return new Widget( [], null, $adaptor ); 71 | } 72 | 73 | private function getAdaptor() { 74 | return $this->getMockBuilder( WidgetAdaptor::class ) 75 | ->setMethods( 76 | [ 77 | 'getName', 78 | 'getTitle', 79 | 'getIcon', 80 | 'getCategories', 81 | ] 82 | )->disableOriginalConstructor()->getMock(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/TestHotspot.php: -------------------------------------------------------------------------------- 1 | 'bar', 24 | 'image' => [ 25 | 'url' => $url, 26 | 'id' => $id, 27 | ], 28 | ]; 29 | }; 30 | 31 | $mediaTranslate = $this->getMockBuilder( \WPML_Page_Builders_Media_Translate::class ) 32 | ->setMethods( [ 'translate_id', 'translate_image_url' ] ) 33 | ->disableOriginalConstructor()->getMock(); 34 | 35 | $mediaTranslate->method( 'translate_id' ) 36 | ->with( $id, $targetLang ) 37 | ->willReturn( $idConverted ); 38 | $mediaTranslate->method( 'translate_image_url' ) 39 | ->with( $url, $targetLang, $sourceLang ) 40 | ->willReturn( $urlConverted ); 41 | 42 | $subject = new Hotspot( $mediaTranslate ); 43 | 44 | $this->assertEquals( 45 | $getSettings( $urlConverted, $idConverted ), 46 | $subject->translate( $getSettings( $url, $id ), $targetLang, $sourceLang ) 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/TestVideoPlaylist.php: -------------------------------------------------------------------------------- 1 | 'bar', 24 | 'tabs' => [ 25 | [ 26 | 'thumbnail' => [ 27 | 'url' => $url, 28 | 'id' => $id, 29 | ], 30 | ], 31 | [ 32 | 'thumbnail' => [ 33 | 'id' => $id, 34 | ], 35 | ], 36 | [ 37 | 'thumbnail' => [], 38 | ], 39 | ], 40 | ]; 41 | }; 42 | 43 | $mediaTranslate = $this->getMockBuilder( \WPML_Page_Builders_Media_Translate::class ) 44 | ->setMethods( [ 'translate_id', 'translate_image_url' ] ) 45 | ->disableOriginalConstructor()->getMock(); 46 | 47 | $mediaTranslate->method( 'translate_id' ) 48 | ->with( $id, $targetLang ) 49 | ->willReturn( $idConverted ); 50 | $mediaTranslate->method( 'translate_image_url' ) 51 | ->with( $url, $targetLang, $sourceLang ) 52 | ->willReturn( $urlConverted ); 53 | 54 | $subject = new VideoPlaylist( $mediaTranslate ); 55 | 56 | $this->assertEquals( 57 | $getSettings( $urlConverted, $idConverted ), 58 | $subject->translate( $getSettings( $url, $id ), $targetLang, $sourceLang ) 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-AllNodes.php: -------------------------------------------------------------------------------- 1 | 20, 18 | 'background_image' => [ 19 | 'url' => 'background_image_1', 20 | 'id' => 1, 21 | ], 22 | 'background_size' => 'contain', 23 | 'background_hover_image' => [ 24 | 'url' => 'background_image_2', 25 | 'id' => 2, 26 | ], 27 | ]; 28 | 29 | $source = 'en'; 30 | $target = 'fr'; 31 | 32 | $expected = [ 33 | 'structure' => 20, 34 | 'background_image' => [ 35 | 'url' => 'translated_background_image_1', 36 | 'id' => 101, 37 | ], 38 | 'background_size' => 'contain', 39 | 'background_hover_image' => [ 40 | 'url' => 'translated_background_image_2', 41 | 'id' => 102, 42 | ], 43 | ]; 44 | 45 | $mediaTranslate = $this->createMock( '\WPML_Page_Builders_Media_Translate' ); 46 | $mediaTranslate->method( 'translate_id' )->willReturnCallback( Math::add( 100 ) ); 47 | $mediaTranslate->method( 'translate_image_url' )->willReturnMap( [ 48 | [ 'background_image_1', $target, $source, 'translated_background_image_1' ], 49 | [ 'background_image_2', $target, $source, 'translated_background_image_2' ], 50 | ] ); 51 | 52 | $subject = new AllNodes( $mediaTranslate ); 53 | 54 | $this->assertEquals( $expected, $subject->translate( $settings, $target, $source ) ); 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-wpml-elementor-media-node-call-to-action.php: -------------------------------------------------------------------------------- 1 | array( 'id' => $original_id, 'url' => $original_url ), 21 | ); 22 | 23 | $expected_settings = array( 24 | 'bg_image' => array( 'id' => $translated_id, 'url' => $translated_url ), 25 | ); 26 | 27 | $media_translate = $this->get_media_translate(); 28 | $media_translate->method( 'translate_id' )->with( $original_id, $target_lang )->willReturn( $translated_id ); 29 | $media_translate->method( 'translate_image_url' ) 30 | ->with( $original_url, $target_lang, $source_lang )->willReturn( $translated_url ); 31 | 32 | $subject = $this->get_subject( $media_translate ); 33 | 34 | $this->assertEquals( $expected_settings, $subject->translate( $settings, $target_lang, $source_lang ) ); 35 | } 36 | 37 | /** 38 | * @test 39 | */ 40 | public function it_should_not_translate_if_property_is_missing() { 41 | $settings = array( 'something' ); 42 | 43 | $media_translate = $this->get_media_translate(); 44 | 45 | $subject = $this->get_subject( $media_translate ); 46 | 47 | $this->assertEquals( $settings, $subject->translate( $settings, 'fr', 'en' ) ); 48 | } 49 | 50 | private function get_subject( $media_translate ) { 51 | return new WPML_Elementor_Media_Node_Call_To_Action( $media_translate ); 52 | } 53 | 54 | private function get_media_translate() { 55 | return $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 56 | ->setMethods( array( 'translate_id', 'translate_image_url' ) ) 57 | ->disableOriginalConstructor()->getMock(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-wpml-elementor-media-node-image-box.php: -------------------------------------------------------------------------------- 1 | array( 'id' => $original_id, 'url' => $original_url ), 21 | ); 22 | 23 | $expected_settings = array( 24 | 'image' => array( 'id' => $translated_id, 'url' => $translated_url ), 25 | ); 26 | 27 | $media_translate = $this->get_media_translate(); 28 | $media_translate->method( 'translate_id' )->with( $original_id, $target_lang )->willReturn( $translated_id ); 29 | $media_translate->method( 'translate_image_url' ) 30 | ->with( $original_url, $target_lang, $source_lang )->willReturn( $translated_url ); 31 | 32 | $subject = $this->get_subject( $media_translate ); 33 | 34 | $this->assertEquals( $expected_settings, $subject->translate( $settings, $target_lang, $source_lang ) ); 35 | } 36 | 37 | /** 38 | * @test 39 | */ 40 | public function it_should_not_translate_if_property_is_missing() { 41 | $settings = array( 'something' ); 42 | 43 | $media_translate = $this->get_media_translate(); 44 | 45 | $subject = $this->get_subject( $media_translate ); 46 | 47 | $this->assertEquals( $settings, $subject->translate( $settings, 'fr', 'en' ) ); 48 | } 49 | 50 | private function get_subject( $media_translate ) { 51 | return new WPML_Elementor_Media_Node_Image_Box( $media_translate ); 52 | } 53 | 54 | private function get_media_translate() { 55 | return $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 56 | ->setMethods( array( 'translate_id', 'translate_image_url' ) ) 57 | ->disableOriginalConstructor()->getMock(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-wpml-elementor-media-node-image-carousel.php: -------------------------------------------------------------------------------- 1 | array( 21 | array( 'id' => $original_id, 'url' => $original_url ), 22 | ), 23 | ); 24 | 25 | $expected_settings = array( 26 | 'carousel' => array( 27 | array( 'id' => $translated_id, 'url' => $translated_url ), 28 | ), 29 | ); 30 | 31 | $media_translate = $this->get_media_translate(); 32 | $media_translate->method( 'translate_id' )->with( $original_id, $target_lang )->willReturn( $translated_id ); 33 | $media_translate->method( 'translate_image_url' ) 34 | ->with( $original_url, $target_lang, $source_lang )->willReturn( $translated_url ); 35 | 36 | $subject = $this->get_subject( $media_translate ); 37 | 38 | $this->assertEquals( $expected_settings, $subject->translate( $settings, $target_lang, $source_lang ) ); 39 | } 40 | 41 | /** 42 | * @test 43 | */ 44 | public function it_should_not_translate_if_property_is_missing() { 45 | $settings = array( 'something' ); 46 | 47 | $media_translate = $this->get_media_translate(); 48 | 49 | $subject = $this->get_subject( $media_translate ); 50 | 51 | $this->assertEquals( $settings, $subject->translate( $settings, 'fr', 'en' ) ); 52 | } 53 | 54 | private function get_subject( $media_translate ) { 55 | return new WPML_Elementor_Media_Node_Image_Carousel( $media_translate ); 56 | } 57 | 58 | private function get_media_translate() { 59 | return $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 60 | ->setMethods( array( 'translate_id', 'translate_image_url' ) ) 61 | ->disableOriginalConstructor()->getMock(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-wpml-elementor-media-node-image-gallery.php: -------------------------------------------------------------------------------- 1 | array( 21 | array( 'id' => $original_id, 'url' => $original_url ), 22 | ), 23 | ); 24 | 25 | $expected_settings = array( 26 | 'wp_gallery' => array( 27 | array( 'id' => $translated_id, 'url' => $translated_url ), 28 | ), 29 | ); 30 | 31 | $media_translate = $this->get_media_translate(); 32 | $media_translate->method( 'translate_id' )->with( $original_id, $target_lang )->willReturn( $translated_id ); 33 | $media_translate->method( 'translate_image_url' ) 34 | ->with( $original_url, $target_lang, $source_lang )->willReturn( $translated_url ); 35 | 36 | $subject = $this->get_subject( $media_translate ); 37 | 38 | $this->assertEquals( $expected_settings, $subject->translate( $settings, $target_lang, $source_lang ) ); 39 | } 40 | 41 | /** 42 | * @test 43 | */ 44 | public function it_should_not_translate_if_property_is_missing() { 45 | $settings = array( 'something' ); 46 | 47 | $media_translate = $this->get_media_translate(); 48 | 49 | $subject = $this->get_subject( $media_translate ); 50 | 51 | $this->assertEquals( $settings, $subject->translate( $settings, 'fr', 'en' ) ); 52 | } 53 | 54 | private function get_subject( $media_translate ) { 55 | return new WPML_Elementor_Media_Node_Image_Gallery( $media_translate ); 56 | } 57 | 58 | private function get_media_translate() { 59 | return $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 60 | ->setMethods( array( 'translate_id', 'translate_image_url' ) ) 61 | ->disableOriginalConstructor()->getMock(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-wpml-elementor-media-node-image.php: -------------------------------------------------------------------------------- 1 | array( 'id' => $original_id, 'url' => $original_url ), 21 | '_background_image' => array( 'id' => $original_id, 'url' => $original_url ), 22 | '_background_hover_image' => array( 'id' => $original_id, 'url' => $original_url ), 23 | ); 24 | 25 | $expected_settings = array( 26 | 'image' => array( 'id' => $translated_id, 'url' => $translated_url ), 27 | '_background_image' => array( 'id' => $translated_id, 'url' => $translated_url ), 28 | '_background_hover_image' => array( 'id' => $translated_id, 'url' => $translated_url ), 29 | 'caption' => $target_lang . 'The caption', 30 | ); 31 | 32 | \WP_Mock::userFunction( 'wp_prepare_attachment_for_js', array( 33 | 'args' => array( $translated_id ), 34 | 'return' => array( 35 | 'caption' => $target_lang . 'The caption', 36 | ), 37 | )); 38 | 39 | $media_translate = $this->get_media_translate(); 40 | $media_translate->method( 'translate_id' )->with( $original_id, $target_lang )->willReturn( $translated_id ); 41 | $media_translate->method( 'translate_image_url' ) 42 | ->with( $original_url, $target_lang, $source_lang )->willReturn( $translated_url ); 43 | 44 | $subject = $this->get_subject( $media_translate ); 45 | 46 | $this->assertEquals( $expected_settings, $subject->translate( $settings, $target_lang, $source_lang ) ); 47 | } 48 | 49 | /** 50 | * @test 51 | */ 52 | public function it_should_not_translate_if_properties_missing() { 53 | $settings = array( 54 | 'caption' => '', 55 | ); 56 | 57 | \WP_Mock::userFunction( 'wp_prepare_attachment_for_js' )->andReturn( $settings ); 58 | 59 | $media_translate = $this->get_media_translate(); 60 | 61 | $subject = $this->get_subject( $media_translate ); 62 | 63 | $this->assertEquals( $settings, $subject->translate( $settings, 'fr', 'en' ) ); 64 | } 65 | 66 | private function get_subject( $media_translate ) { 67 | return new WPML_Elementor_Media_Node_Image( $media_translate ); 68 | } 69 | 70 | private function get_media_translate() { 71 | return $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 72 | ->setMethods( array( 'translate_id', 'translate_image_url' ) ) 73 | ->disableOriginalConstructor()->getMock(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-wpml-elementor-media-node-media-carousel.php: -------------------------------------------------------------------------------- 1 | array( 21 | array( 22 | 'image' => array( 'id' => $original_id, 'url' => $original_url ), 23 | ), 24 | ), 25 | ); 26 | 27 | $expected_settings = array( 28 | 'slides' => array( 29 | array( 30 | 'image' => array( 'id' => $translated_id, 'url' => $translated_url ), 31 | ), 32 | ), 33 | ); 34 | 35 | $media_translate = $this->get_media_translate(); 36 | $media_translate->method( 'translate_id' )->with( $original_id, $target_lang )->willReturn( $translated_id ); 37 | $media_translate->method( 'translate_image_url' ) 38 | ->with( $original_url, $target_lang, $source_lang )->willReturn( $translated_url ); 39 | 40 | $subject = $this->get_subject( $media_translate ); 41 | 42 | $this->assertEquals( $expected_settings, $subject->translate( $settings, $target_lang, $source_lang ) ); 43 | } 44 | 45 | /** 46 | * @test 47 | * @dataProvider dp_should_not_translate 48 | * 49 | * @param array $settings 50 | */ 51 | public function it_should_not_translate_if_slide_is_incomplete( $settings ) { 52 | $media_translate = $this->get_media_translate(); 53 | 54 | $subject = $this->get_subject( $media_translate ); 55 | 56 | $this->assertEquals( $settings, $subject->translate( $settings, 'fr', 'en' ) ); 57 | } 58 | 59 | public function dp_should_not_translate() { 60 | return array( 61 | array( array() ), 62 | array( array( 'slides' => 'no an array' ) ), 63 | array( array( 'slides' => array( 'image' => array() ) ) ), 64 | ); 65 | } 66 | 67 | private function get_subject( $media_translate ) { 68 | return new WPML_Elementor_Media_Node_Media_Carousel( $media_translate ); 69 | } 70 | 71 | private function get_media_translate() { 72 | return $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 73 | ->setMethods( array( 'translate_id', 'translate_image_url' ) ) 74 | ->disableOriginalConstructor()->getMock(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-wpml-elementor-media-node-slides.php: -------------------------------------------------------------------------------- 1 | array( 21 | array( 22 | 'background_image' => array( 'id' => $original_id, 'url' => $original_url ), 23 | ), 24 | ), 25 | ); 26 | 27 | $expected_settings = array( 28 | 'slides' => array( 29 | array( 30 | 'background_image' => array( 'id' => $translated_id, 'url' => $translated_url ), 31 | ), 32 | ), 33 | ); 34 | 35 | $media_translate = $this->get_media_translate(); 36 | $media_translate->method( 'translate_id' )->with( $original_id, $target_lang )->willReturn( $translated_id ); 37 | $media_translate->method( 'translate_image_url' ) 38 | ->with( $original_url, $target_lang, $source_lang )->willReturn( $translated_url ); 39 | 40 | $subject = $this->get_subject( $media_translate ); 41 | 42 | $this->assertEquals( $expected_settings, $subject->translate( $settings, $target_lang, $source_lang ) ); 43 | } 44 | 45 | /** 46 | * @test 47 | * @dataProvider dp_should_not_translate 48 | * 49 | * @param array $settings 50 | */ 51 | public function it_should_not_translate_if_slide_is_incomplete( $settings ) { 52 | $media_translate = $this->get_media_translate(); 53 | 54 | $subject = $this->get_subject( $media_translate ); 55 | 56 | $this->assertEquals( $settings, $subject->translate( $settings, 'fr', 'en' ) ); 57 | } 58 | 59 | public function dp_should_not_translate() { 60 | return array( 61 | array( array() ), 62 | array( array( 'slides' => 'no an array' ) ), 63 | array( array( 'slides' => array( 'background_image' => array() ) ) ), 64 | ); 65 | } 66 | 67 | private function get_subject( $media_translate ) { 68 | return new WPML_Elementor_Media_Node_Slides( $media_translate ); 69 | } 70 | 71 | private function get_media_translate() { 72 | return $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 73 | ->setMethods( array( 'translate_id', 'translate_image_url' ) ) 74 | ->disableOriginalConstructor()->getMock(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-wpml-elementor-media-node-wp-widget-media-gallery.php: -------------------------------------------------------------------------------- 1 | array( 21 | 'ids' => "$original_id_1,$original_id_2", 22 | ), 23 | ); 24 | 25 | $expected_settings = array( 26 | 'wp' => array( 27 | 'ids' => "$translated_id_1,$translated_id_2", 28 | ), 29 | ); 30 | 31 | $media_translate = $this->get_media_translate(); 32 | $media_translate->method( 'translate_id' )->willReturnMap( 33 | array( 34 | array( $original_id_1, $target_lang, $translated_id_1 ), 35 | array( $original_id_2, $target_lang, $translated_id_2 ), 36 | ) 37 | ); 38 | 39 | $subject = $this->get_subject( $media_translate ); 40 | 41 | $this->assertEquals( $expected_settings, $subject->translate( $settings, $target_lang, $source_lang ) ); 42 | } 43 | 44 | /** 45 | * @test 46 | * @dataProvider dp_should_not_translate 47 | * 48 | * @param array $settings 49 | */ 50 | public function it_should_not_translate_if_slide_is_incomplete( $settings ) { 51 | $media_translate = $this->get_media_translate(); 52 | 53 | $subject = $this->get_subject( $media_translate ); 54 | 55 | $this->assertEquals( $settings, $subject->translate( $settings, 'fr', 'en' ) ); 56 | } 57 | 58 | public function dp_should_not_translate() { 59 | return array( 60 | array( array() ), 61 | array( array( 'wp' => 'no an array' ) ), 62 | array( array( 'wp' => array( 'ids' => '' ) ) ), 63 | ); 64 | } 65 | 66 | private function get_subject( $media_translate ) { 67 | return new WPML_Elementor_Media_Node_WP_Widget_Media_Gallery( $media_translate ); 68 | } 69 | 70 | private function get_media_translate() { 71 | return $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 72 | ->setMethods( array( 'translate_id', 'translate_image_url' ) ) 73 | ->disableOriginalConstructor()->getMock(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/modules/test-wpml-elementor-media-node-wp-widget-media-image.php: -------------------------------------------------------------------------------- 1 | array( 21 | 'attachment_id' => $original_id, 22 | 'url' => $original_url, 23 | 'caption' => 'the caption', 24 | 'alt' => 'the alt', 25 | 'image_title' => 'the image title', 26 | ), 27 | ); 28 | 29 | $expected_settings = array( 30 | 'wp' => array( 31 | 'attachment_id' => $translated_id, 32 | 'url' => $translated_url, 33 | 'caption' => $target_lang . 'the caption', 34 | 'alt' => $target_lang . 'the alt', 35 | 'image_title' => $target_lang . 'the image title', 36 | ), 37 | ); 38 | 39 | \WP_Mock::userFunction( 'wp_prepare_attachment_for_js', array( 40 | 'args' => array( $translated_id ), 41 | 'return' => array( 42 | 'caption' => $target_lang . 'the caption', 43 | 'alt' => $target_lang . 'the alt', 44 | 'title' => $target_lang . 'the image title', 45 | ), 46 | )); 47 | 48 | $media_translate = $this->get_media_translate(); 49 | $media_translate->method( 'translate_id' )->with( $original_id, $target_lang )->willReturn( $translated_id ); 50 | $media_translate->method( 'translate_image_url' ) 51 | ->with( $original_url, $target_lang, $source_lang )->willReturn( $translated_url ); 52 | 53 | $subject = $this->get_subject( $media_translate ); 54 | 55 | $this->assertEquals( $expected_settings, $subject->translate( $settings, $target_lang, $source_lang ) ); 56 | } 57 | 58 | /** 59 | * @test 60 | * @dataProvider dp_should_not_translate 61 | * 62 | * @param array $settings 63 | */ 64 | public function it_should_not_translate_if_slide_is_incomplete( $settings ) { 65 | $media_translate = $this->get_media_translate(); 66 | 67 | $subject = $this->get_subject( $media_translate ); 68 | 69 | $this->assertEquals( $settings, $subject->translate( $settings, 'fr', 'en' ) ); 70 | } 71 | 72 | public function dp_should_not_translate() { 73 | return array( 74 | array( array() ), 75 | array( array( 'wp' => 'no an array' ) ), 76 | ); 77 | } 78 | 79 | private function get_subject( $media_translate ) { 80 | return new WPML_Elementor_Media_Node_WP_Widget_Media_Image( $media_translate ); 81 | } 82 | 83 | private function get_media_translate() { 84 | return $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 85 | ->setMethods( array( 'translate_id', 'translate_image_url' ) ) 86 | ->disableOriginalConstructor()->getMock(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/test-wpml-elementor-media-hooks-factory.php: -------------------------------------------------------------------------------- 1 | getMockBuilder( 'SitePress' )->getMock(); 13 | \Mockery::mock( 'alias:WPML_Page_Builders_Media_Hooks' ); 14 | $subject = new WPML_Elementor_Media_Hooks_Factory(); 15 | $this->assertInstanceOf( 'WPML_Page_Builders_Media_Hooks', $subject->create() ); 16 | } 17 | 18 | /** 19 | * @test 20 | */ 21 | public function it_should_implements_backend_and_fronted_action() { 22 | $subject = new WPML_Elementor_Media_Hooks_Factory(); 23 | $this->assertInstanceOf( 'IWPML_Backend_Action_Loader', $subject ); 24 | $this->assertInstanceOf( 'IWPML_Frontend_Action_Loader', $subject ); 25 | } 26 | } 27 | 28 | if ( ! interface_exists( 'IWPML_PB_Media_Update_Factory' ) ) { 29 | interface IWPML_PB_Media_Update_Factory {} 30 | } 31 | -------------------------------------------------------------------------------- /tests/phpunit/tests/media/test-wpml-elementor-media-node-provider.php: -------------------------------------------------------------------------------- 1 | getMockBuilder( 'SitePress' )->disableOriginalConstructor()->getMock(); 17 | $this->mock_external_classes(); 18 | 19 | $media_translate = $this->getMockBuilder( 'WPML_Page_Builders_Media_Translate' ) 20 | ->disableOriginalConstructor()->getMock(); 21 | 22 | $subject = new WPML_Elementor_Media_Node_Provider( $media_translate ); 23 | 24 | $this->assertInstanceOf( $class_name, $subject->get( $type ) ); 25 | $this->assertSame( $subject->get( $type ), $subject->get( $type ) ); 26 | } 27 | 28 | public function dp_node_types() { 29 | return array( 30 | 'image' => array( 'image', 'WPML_Elementor_Media_Node_Image' ), 31 | 'slides' => array( 'slides', 'WPML_Elementor_Media_Node_Slides' ), 32 | 'call-to-action' => array( 'call-to-action', 'WPML_Elementor_Media_Node_Call_To_Action' ), 33 | 'media-carousel' => array( 'media-carousel', 'WPML_Elementor_Media_Node_Media_Carousel' ), 34 | 'image-box' => array( 'image-box', 'WPML_Elementor_Media_Node_Image_Box' ), 35 | 'image-gallery' => array( 'image-gallery', 'WPML_Elementor_Media_Node_Image_Gallery' ), 36 | 'image-carousel' => array( 'image-carousel', 'WPML_Elementor_Media_Node_Image_Carousel' ), 37 | 'wp-widget-media_image' => array( 'wp-widget-media_image', 'WPML_Elementor_Media_Node_WP_Widget_Media_Image' ), 38 | 'wp-widget-media_gallery' => array( 'wp-widget-media_gallery', 'WPML_Elementor_Media_Node_WP_Widget_Media_Gallery' ), 39 | 'background-images' => array( 'all_nodes', \WPML\PB\Elementor\Media\Modules\AllNodes::class ), 40 | 'video-playlist' => array( 'video-playlist', \WPML\PB\Elementor\Media\Modules\VideoPlaylist::class ), 41 | 'hotspot' => array( 'hotspot', \WPML\PB\Elementor\Media\Modules\Hotspot::class ), 42 | ); 43 | } 44 | 45 | private function mock_external_classes() { 46 | $this->getMockBuilder( 'WPML_Translation_Element_Factory' )->getMock(); 47 | $this->getMockBuilder( 'WPML_Media_Image_Translate' )->getMock(); 48 | $this->getMockBuilder( 'WPML_Media_Attachment_By_URL_Factory' )->getMock(); 49 | } 50 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/media/test-wpml-elementor-media-nodes-iterator.php: -------------------------------------------------------------------------------- 1 | 'column', 21 | 'elements' => array( 22 | array( 23 | 'elType' => 'widget', 24 | 'widgetType' => 'image', 25 | 'settings' => $image_data, 26 | ), 27 | ), 28 | ), 29 | array( 30 | 'elType' => 'widget', 31 | 'widgetType' => 'slides', 32 | 'settings' => $slides_data, 33 | 'elements' => array(), 34 | ), 35 | array( 36 | 'elType' => 'section', 37 | 'widgetType' => 'section', 38 | 'settings' => [ 'background image data' ], 39 | 'elements' => array(), 40 | ), 41 | // Not supported module 42 | array( 43 | 'elType' => 'widget', 44 | 'widgetType' => 'not-supported', 45 | 'settings' => array(), 46 | 'elements' => array(), 47 | ), 48 | // Not translated modules 49 | array(), 50 | array( 'elType' => 'not a widget' ), 51 | array( 'elType' => 'widget' ), 52 | array( 'elType' => 'widget', 'settings' => array() ), 53 | array( 'elType' => 'widget', 'widgetType' => 'image' ), 54 | ); 55 | 56 | $translated_image_data = array( 'translated image data' ); 57 | $translated_slides_data = array( 'translated slides data' ); 58 | 59 | $expected_data = $data; 60 | $expected_data[0]['elements'][0]['settings'] = $translated_image_data; 61 | $expected_data[1]['settings'] = $translated_slides_data; 62 | $expected_data[2]['settings'] = ['translated background image data']; 63 | 64 | 65 | $node_image = $this->get_node(); 66 | $node_image->method( 'translate' )->with( $image_data, $lang, $source_lang ) 67 | ->willReturn( $translated_image_data ); 68 | 69 | $node_slides = $this->get_node(); 70 | $node_slides->method( 'translate' )->with( $slides_data, $lang, $source_lang ) 71 | ->willReturn( $translated_slides_data ); 72 | 73 | $all_nodes = $this->createMock( \WPML\PB\Elementor\Media\Modules\AllNodes::class ); 74 | $all_nodes->method( 'translate' )->willReturnCallback( function ( $settings ) { 75 | return $settings === ['background image data'] ? ['translated background image data'] : $settings; 76 | } ); 77 | 78 | $node_provider = $this->get_node_provider(); 79 | $node_provider->method( 'get' )->willReturnMap( 80 | [ 81 | [ 'image', $node_image ], 82 | [ 'slides', $node_slides ], 83 | [ 'not-supported', null ], 84 | [ 'all_nodes', $all_nodes ], 85 | ] 86 | ); 87 | 88 | $subject = $this->get_subject( $node_provider ); 89 | 90 | $this->assertEquals( $expected_data, $subject->translate( $data, $lang, $source_lang ) ); 91 | } 92 | 93 | private function get_subject( $node_provider ) { 94 | return new WPML_Elementor_Media_Nodes_Iterator( $node_provider ); 95 | } 96 | 97 | private function get_node_provider() { 98 | return $this->getMockBuilder( 'WPML_Elementor_Media_Node_Provider' ) 99 | ->setMethods( array( 'get' ) )->disableOriginalConstructor()->getMock(); 100 | } 101 | 102 | private function get_node() { 103 | return $this->getMockBuilder( 'WPML_Elementor_Media_Node' ) 104 | ->setMethods( array( 'translate' ) )->disableOriginalConstructor()->getMock(); 105 | } 106 | } 107 | 108 | if ( ! interface_exists( 'IWPML_PB_Media_Nodes_Iterator' ) ) { 109 | interface IWPML_PB_Media_Nodes_Iterator {} 110 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/media/test-wpml-elementor-update-media-factory.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf( 'IWPML_PB_Media_Update_Factory', $subject ); 20 | } 21 | 22 | /** 23 | * @test 24 | */ 25 | public function it_should_return_an_instance_of_page_builders_media_update() { 26 | $subject = new WPML_Elementor_Update_Media_Factory(); 27 | $this->assertInstanceOf( 'WPML_Page_Builders_Update_Media', $subject->create() ); 28 | } 29 | } 30 | 31 | if ( ! interface_exists( 'IWPML_PB_Media_Update_Factory' ) ) { 32 | interface IWPML_PB_Media_Update_Factory {} 33 | } 34 | -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/TestMediaCarousel.php: -------------------------------------------------------------------------------- 1 | assertEquals( [ 'image_link_to' => [ 'url' ] ], $subject->get_fields() ); 17 | } 18 | 19 | /** 20 | * @test 21 | */ 22 | public function it_get_items_field() { 23 | $subject = new MediaCarousel(); 24 | $this->assertEquals( 'slides', $subject->get_items_field() ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/TestModuleWithItemsFromConfig.php: -------------------------------------------------------------------------------- 1 | 'title', 19 | 'type' => 'The slide title', 20 | 'editor_type' => 'LINE', 21 | ], 22 | 'link' => [ 23 | 'field' => 'url', 24 | 'type' => 'The slide url', 25 | 'editor_type' => 'LINK', 26 | ], 27 | ]; 28 | 29 | 30 | $subject = new ModuleWithItemsFromConfig( $itemsField, $config ); 31 | 32 | $this->assertEquals( $itemsField, $subject->get_items_field() ); 33 | 34 | $this->assertEquals( 35 | [ 'title', 'link' => [ 'url' ] ], 36 | $subject->get_fields() 37 | ); 38 | 39 | // Title field 40 | $this->assertEquals( 'The slide title', $subject->get_title( 'title' ) ); 41 | $this->assertEquals( 'LINE', $subject->get_editor_type( 'title' ) ); 42 | 43 | // Link field 44 | $this->assertEquals( 'The slide url', $subject->get_title( 'url' ) ); 45 | $this->assertEquals( 'LINK', $subject->get_editor_type( 'url' ) ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/TestMultipleGallery.php: -------------------------------------------------------------------------------- 1 | assertEquals( [ 'gallery_title' ], $subject->get_fields() ); 17 | } 18 | 19 | /** 20 | * @test 21 | */ 22 | public function it_get_items_field() { 23 | $subject = new MulitpleGallery(); 24 | $this->assertEquals( 'galleries', $subject->get_items_field() ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/TestReviews.php: -------------------------------------------------------------------------------- 1 | assertEquals( [ 'content', 'name', 'title', 'link' => [ 'field' => 'url' ] ], $subject->get_fields() ); 17 | } 18 | 19 | /** 20 | * @test 21 | */ 22 | public function it_get_items_field() { 23 | $subject = new Reviews(); 24 | $this->assertEquals( 'slides', $subject->get_items_field() ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/Test_WPML_Elementor_Module_With_Items.php: -------------------------------------------------------------------------------- 1 | 'id_1', 21 | 'field_A' => self::get_string_value( 'field_A', 'id_1' ), 22 | 'field_B' => [ 'inner_field_B' => self::get_string_value( 'inner_field_B', 'id_1' ) ], 23 | ], 24 | [ 25 | '_id' => 'id_2', 26 | 'field_A' => self::get_string_value( 'field_A', 'id_2' ), 27 | 'not_translated' => 'not translated field', 28 | ], 29 | ]; 30 | 31 | $element = self::get_element( $fields ); 32 | 33 | $expected_strings = array_merge( 34 | $strings, 35 | [ 36 | $this->get_string( 'field_A', 'id_1' ), 37 | $this->get_string( 'inner_field_B', 'id_1' ), 38 | $this->get_string( 'field_A', 'id_2' ), 39 | ] 40 | ); 41 | 42 | $subject = new WPML_Elementor_Module_With_Items_For_Test(); 43 | 44 | $this->assertEquals( $expected_strings, $subject->get( self::NODE_ID, $element, $strings ) ); 45 | } 46 | 47 | /** 48 | * @test 49 | */ 50 | public function it_updates_a_field() { 51 | $translated_value = 'the translated value'; 52 | 53 | $string = $this->get_string( 'field_A', 'id_2' ); 54 | $string->set_value( $translated_value ); 55 | 56 | $field_to_translate = [ 57 | '_id' => 'id_2', 58 | 'field_A' => 'something to translate', 59 | 'not_translated' => 'not translated field', 60 | ]; 61 | 62 | $expected_translated_field = $field_to_translate; 63 | $expected_translated_field['field_A'] = $translated_value; 64 | // We are modifying the field, and this 'index' will be used outside the class... 65 | $expected_translated_field['index'] = 1; 66 | 67 | $fields = [ 68 | [ 69 | '_id' => 'id_1', 70 | 'field_A' => 'some value for field_A - id_1', 71 | 'field_B' => [ 'inner_field_B' => 'some value for inner_field_B - id_1' ], 72 | ], 73 | $field_to_translate, 74 | [ 75 | '_id' => 'id_3', 76 | 'field_A' => 'some value for field_A - id_3', 77 | 'field_B' => [ 'inner_field_B' => 'some value for inner_field_B - id_3' ], 78 | ], 79 | ]; 80 | 81 | $element = self::get_element( $fields ); 82 | 83 | $subject = new WPML_Elementor_Module_With_Items_For_Test(); 84 | 85 | $this->assertEquals( 86 | $expected_translated_field, 87 | $subject->update( self::NODE_ID, $element, $string ) 88 | ); 89 | } 90 | 91 | /** 92 | * @test 93 | */ 94 | public function it_updates_a_inner_field() { 95 | $translated_value = 'the translated value'; 96 | 97 | $string = $this->get_string( 'inner_field_B', 'id_2' ); 98 | $string->set_value( $translated_value ); 99 | 100 | $field_to_translate = [ 101 | '_id' => 'id_2', 102 | 'field_A' => 'something', 103 | 'field_B' => [ 104 | 'foo' => 'bar', 105 | 'inner_field_B' => 'TO BE TRANSLATED', 106 | 'hello' => 'there', 107 | ], 108 | ]; 109 | 110 | $expected_translated_field = $field_to_translate; 111 | $expected_translated_field['field_B']['inner_field_B'] = $translated_value; 112 | // We are modifying the field, and this 'index' will be used outside the class... 113 | $expected_translated_field['index'] = 1; 114 | 115 | $fields = [ 116 | [ 117 | '_id' => 'id_1', 118 | 'field_A' => 'some value for field_A - id_1', 119 | 'field_B' => [ 'inner_field_B' => 'some value for inner_field_B - id_1' ], 120 | ], 121 | $field_to_translate, 122 | [ 123 | '_id' => 'id_3', 124 | 'field_A' => 'some value for field_A - id_3', 125 | 'field_B' => [ 'inner_field_B' => 'some value for inner_field_B - id_3' ], 126 | ], 127 | ]; 128 | 129 | $element = self::get_element( $fields ); 130 | 131 | $subject = new WPML_Elementor_Module_With_Items_For_Test(); 132 | 133 | $this->assertEquals( 134 | $expected_translated_field, 135 | $subject->update( self::NODE_ID, $element, $string ) 136 | ); 137 | } 138 | 139 | public static function get_string_value( $name, $item_id ) { 140 | return "The value for $name - $item_id"; 141 | } 142 | 143 | public static function get_field_prop( $field, $prop ) { 144 | return "The $prop for $field"; 145 | } 146 | 147 | private static function get_string( $field, $item_id ) { 148 | return new WPML_PB_String( 149 | self::get_string_value( $field, $item_id ), 150 | WPML_Elementor_Module_With_Items_For_Test::WIDGET_TYPE . '-' . $field . '-' . Test_WPML_Elementor_Module_With_Items::NODE_ID . '-' . $item_id, 151 | Test_WPML_Elementor_Module_With_Items::get_field_prop( $field, 'title' ), 152 | Test_WPML_Elementor_Module_With_Items::get_field_prop( $field, 'type' ) 153 | ); 154 | } 155 | 156 | private static function get_element( array $fields ) { 157 | return [ 158 | WPML_Elementor_Translatable_Nodes::TYPE => WPML_Elementor_Module_With_Items_For_Test::WIDGET_TYPE, 159 | WPML_Elementor_Translatable_Nodes::SETTINGS_FIELD => [ 160 | 'test_field' => $fields, 161 | ], 162 | ]; 163 | } 164 | } 165 | 166 | class WPML_Elementor_Module_With_Items_For_Test extends WPML_Elementor_Module_With_Items { 167 | 168 | const WIDGET_TYPE = 'nice-widget'; 169 | 170 | public function get_fields() { 171 | return [ 172 | 'first_missing_field_in_widget', 173 | 'field_A', 174 | 'field_B' => [ 175 | 'first_missing_inner_field', 176 | 'inner_field_B', 177 | 'second_missing_inner_field', 178 | ], 179 | 'second_missing_field_in_widget', 180 | ]; 181 | } 182 | 183 | protected function get_title( $field ) { 184 | return Test_WPML_Elementor_Module_With_Items::get_field_prop( $field, 'title' ); 185 | } 186 | 187 | protected function get_editor_type( $field ) { 188 | return Test_WPML_Elementor_Module_With_Items::get_field_prop( $field, 'type' ); 189 | } 190 | 191 | public function get_items_field() { 192 | return 'test_field'; 193 | } 194 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/test-wpml-elementor-accordion.php: -------------------------------------------------------------------------------- 1 | assertEquals( $expected, $subject->get_fields() ); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function it_get_items_field() { 25 | $subject = new WPML_Elementor_Accordion(); 26 | $this->assertEquals( 'tabs', $subject->get_items_field() ); 27 | } 28 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/test-wpml-elementor-form.php: -------------------------------------------------------------------------------- 1 | assertEquals( $expected, $subject->get_fields() ); 29 | } 30 | 31 | /** 32 | * @test 33 | */ 34 | public function it_get_items_field() { 35 | $subject = new WPML_Elementor_Form(); 36 | $this->assertEquals( 'form_fields', $subject->get_items_field() ); 37 | } 38 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/test-wpml-elementor-icon-list.php: -------------------------------------------------------------------------------- 1 | array( 'url' ) ); 17 | $subject = new WPML_Elementor_Icon_List(); 18 | $this->assertEquals( $expected, $subject->get_fields() ); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function it_get_items_field() { 25 | $subject = new WPML_Elementor_Icon_List(); 26 | $this->assertEquals( 'icon_list', $subject->get_items_field() ); 27 | } 28 | 29 | /** 30 | * @test 31 | * @group wpmlcore-5929 32 | */ 33 | public function it_should_get() { 34 | $node_id ='f94a4f8'; 35 | $element = array( 36 | 'id' => $node_id, 37 | 'elType' => 'widget', 38 | 'settings' => array( 39 | 'icon_list' => array( 40 | array( 41 | 'text' => 'List Item #1', 42 | 'icon' => 'fa fa-check', 43 | '_id' => '38f8b31', 44 | 'link' => array( 45 | 'url' => 'http://wpml.local/sample-page/', 46 | 'is_external' => '', 47 | 'nofollow' => '', 48 | ), 49 | ), 50 | ), 51 | ), 52 | 'elements' => array(), 53 | 'widgetType' => 'icon-list', 54 | ); 55 | 56 | $strings = array(); 57 | 58 | $expected_text_string = new WPML_PB_String( 59 | 'List Item #1', 60 | 'icon-list-text-f94a4f8-38f8b31', 61 | 'Icon List: Text', 62 | 'LINE' 63 | ); 64 | 65 | $expected_link_string = new WPML_PB_String( 66 | 'http://wpml.local/sample-page/', 67 | 'icon-list-url-f94a4f8-38f8b31', 68 | 'Icon List: Link URL', 69 | 'LINK' 70 | ); 71 | 72 | $subject = new WPML_Elementor_Icon_List(); 73 | 74 | $actual_strings = $subject->get( $node_id, $element, $strings ); 75 | 76 | $this->assertEquals( $expected_text_string, $actual_strings[0] ); 77 | $this->assertEquals( $expected_link_string, $actual_strings[1] ); 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/test-wpml-elementor-price-list.php: -------------------------------------------------------------------------------- 1 | array( 'url' ) ); 17 | $subject = new WPML_Elementor_Price_List(); 18 | $this->assertEquals( $expected, $subject->get_fields() ); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function it_get_items_field() { 25 | $subject = new WPML_Elementor_Price_List(); 26 | $this->assertEquals( 'price_list', $subject->get_items_field() ); 27 | } 28 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/test-wpml-elementor-price-table.php: -------------------------------------------------------------------------------- 1 | assertEquals( $expected, $subject->get_fields() ); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function it_get_items_field() { 25 | $subject = new WPML_Elementor_Price_Table(); 26 | $this->assertEquals( 'features_list', $subject->get_items_field() ); 27 | } 28 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/test-wpml-elementor-slides.php: -------------------------------------------------------------------------------- 1 | array( 'url' ) ); 17 | $subject = new WPML_Elementor_Slides(); 18 | $this->assertEquals( $expected, $subject->get_fields() ); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function it_get_items_field() { 25 | $subject = new WPML_Elementor_Slides(); 26 | $this->assertEquals( 'slides', $subject->get_items_field() ); 27 | } 28 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/test-wpml-elementor-tabs.php: -------------------------------------------------------------------------------- 1 | assertEquals( $expected, $subject->get_fields() ); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function it_get_items_field() { 25 | $subject = new WPML_Elementor_Tabs(); 26 | $this->assertEquals( 'tabs', $subject->get_items_field() ); 27 | } 28 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/test-wpml-elementor-testimonial-carousel.php: -------------------------------------------------------------------------------- 1 | assertEquals( $expected, $subject->get_fields() ); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function it_get_items_field() { 25 | $subject = new WPML_Elementor_Testimonial_Carousel(); 26 | $this->assertEquals( 'slides', $subject->get_items_field() ); 27 | } 28 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/modules/test-wpml-elementor-toggle.php: -------------------------------------------------------------------------------- 1 | assertEquals( $expected, $subject->get_fields() ); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function it_get_items_field() { 25 | $subject = new WPML_Elementor_Toggle(); 26 | $this->assertEquals( 'tabs', $subject->get_items_field() ); 27 | } 28 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/test-pb-fix-maintenance-query.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf( 'IWPML_Frontend_Action', $subject ); 17 | } 18 | 19 | /** 20 | * @test 21 | */ 22 | public function it_adds_hooks() { 23 | $subject = new WPML_PB_Fix_Maintenance_Query(); 24 | \WP_Mock::expectActionAdded( 'template_redirect', array( $subject, 'fix_global_query' ), 12 ); 25 | $subject->add_hooks(); 26 | } 27 | 28 | /** 29 | * @test 30 | * @group wpmlcore-6218 31 | */ 32 | public function it_does_not_fix_global_query_if_post_is_not_set() { 33 | $original_post = new stdClass(); 34 | $template_post = new stdClass(); 35 | $template_id = 3; 36 | 37 | $post_backup = isset( $GLOBALS['post'] ) ? $GLOBALS['post'] : null; 38 | $the_query_backup = isset( $GLOBALS['wp_the_query'] ) ? $GLOBALS['wp_the_query'] : null; 39 | $query_backup = isset( $GLOBALS['wp_query'] ) ? $GLOBALS['wp_query'] : null; 40 | 41 | $GLOBALS['post'] = null; 42 | $GLOBALS['wp_the_query'] = $original_post; 43 | $GLOBALS['wp_query'] = $template_post; 44 | 45 | $subject = new WPML_PB_Fix_Maintenance_Query(); 46 | 47 | \mockery::mock( 'overload:' . \Elementor\Maintenance_Mode::class ) 48 | ->shouldReceive( 'get' ) 49 | ->with( 'template_id' ) 50 | ->andReturn( $template_id ); 51 | 52 | $subject->fix_global_query(); 53 | $this->assertEquals( $original_post, $GLOBALS['wp_the_query'] ); 54 | $this->assertEquals( $template_post, $GLOBALS['wp_query'] ); 55 | 56 | $GLOBALS['post'] = $post_backup; 57 | $GLOBALS['wp_the_query'] = $the_query_backup; 58 | $GLOBALS['post'] = $post_backup; 59 | $GLOBALS['wp_query'] = $query_backup; 60 | } 61 | 62 | /** 63 | * @test 64 | */ 65 | public function it_fixes_global_query() { 66 | $original_post = new stdClass(); 67 | $template_post = new stdClass(); 68 | $template_id = 3; 69 | 70 | $post_backup = isset( $GLOBALS['post'] ) ? $GLOBALS['post'] : null; 71 | $the_query_backup = isset( $GLOBALS['wp_the_query'] ) ? $GLOBALS['wp_the_query'] : null; 72 | $query_backup = isset( $GLOBALS['wp_query'] ) ? $GLOBALS['wp_query'] : null; 73 | 74 | $GLOBALS['post'] = $template_post; 75 | $GLOBALS['post']->ID = $template_id; 76 | $GLOBALS['wp_the_query'] = $original_post; 77 | $GLOBALS['wp_query'] = $template_post; 78 | 79 | $subject = new WPML_PB_Fix_Maintenance_Query(); 80 | 81 | \mockery::mock( 'overload:' . \Elementor\Maintenance_Mode::class ) 82 | ->shouldReceive( 'get' ) 83 | ->with( 'template_id' ) 84 | ->andReturn( $template_id ); 85 | 86 | $subject->fix_global_query(); 87 | $this->assertEquals( $GLOBALS['wp_query'], $GLOBALS['wp_the_query'] ); 88 | 89 | $GLOBALS['post'] = $post_backup; 90 | $GLOBALS['wp_the_query'] = $the_query_backup; 91 | $GLOBALS['post'] = $post_backup; 92 | $GLOBALS['wp_query'] = $query_backup; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/phpunit/tests/test-wpml-elementor-db-factory.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf( 'WPML_Elementor_DB', $subject->create() ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/phpunit/tests/test-wpml-elementor-db.php: -------------------------------------------------------------------------------- 1 | getMockBuilder( '\Elementor\DB' ) 17 | ->setMethods( array( 'save_plain_text' ) ) 18 | ->disableOriginalConstructor() 19 | ->getMock(); 20 | 21 | $post_id = mt_rand( 1, 10 ); 22 | 23 | $elementor_db->expects( $this->once() ) 24 | ->method( 'save_plain_text' ) 25 | ->with( $post_id ); 26 | 27 | $subject = new WPML_Elementor_DB( $elementor_db ); 28 | $subject->save_plain_text( $post_id ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/phpunit/tests/test-wpml-elementor-integration-factory.php: -------------------------------------------------------------------------------- 1 | shouldReceive( 'load' ) 22 | ->once() 23 | ->with( array( 24 | 'WPML_Elementor_Translate_IDs_Factory', 25 | 'WPML_Elementor_URLs_Factory', 26 | 'WPML_Elementor_Adjust_Global_Widget_ID_Factory', 27 | 'WPML_PB_Elementor_Handle_Custom_Fields_Factory', 28 | 'WPML_Elementor_Media_Hooks_Factory', 29 | 'WPML_Elementor_WooCommerce_Hooks_Factory', 30 | \WPML\PB\Elementor\LanguageSwitcher\LanguageSwitcher::class, 31 | \WPML\PB\Elementor\Hooks\DynamicElements::class, 32 | \WPML\PB\Elementor\Hooks\GutenbergCleanup::class, 33 | \WPML\PB\Elementor\Hooks\Frontend::class, 34 | \WPML\PB\Elementor\Config\Factory::class, 35 | \WPML\PB\Elementor\Hooks\LandingPages::class, 36 | ) ); 37 | 38 | $string_registration = \Mockery::mock( 'overload:WPML_PB_String_Registration' ); 39 | 40 | $string_registration_factory = \Mockery::mock( 'overload:WPML_String_Registration_Factory' ); 41 | $string_registration_factory->shouldReceive( 'create' ) 42 | ->andReturn( $string_registration ); 43 | 44 | $this->assertInstanceOf( 'WPML_Page_Builders_Integration', $elementor_factory->create() ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/phpunit/tests/test-wpml-elementor-register-strings.php: -------------------------------------------------------------------------------- 1 | get_post_and_package( 'Elementor' ); 16 | $node_id = mt_rand(); 17 | $settings = array( 18 | 'id' => $node_id, 19 | 'elType' => 'widget', 20 | 'settings' => array( 21 | 'editor' => '', 22 | ), 23 | 'widgetType' => 'text-editor', 24 | ); 25 | $string = new WPML_PB_String( rand_str(), rand_str(), rand_str(), rand_str() ); 26 | $strings = array( $string ); 27 | 28 | $elementor_data = array( 29 | array( 30 | 'id' => mt_rand(), 31 | 'elements' => array( 32 | array( 33 | 'id' => mt_rand(), 34 | 'elements' => array( 35 | array( 36 | 'id' => $node_id, 37 | 'elType' => 'widget', 38 | 'settings' => array( 39 | 'editor' => '', 40 | ), 41 | 'widgetType' => 'text-editor', 42 | ), 43 | ), 44 | ), 45 | ), 46 | ), 47 | ); 48 | 49 | \WP_Mock::wpFunction( 'get_post_meta', array( 50 | 'times' => 1, 51 | 'args' => array( $post->ID, '_elementor_data', false ), 52 | 'return' => array( json_encode( $elementor_data ) ), 53 | ) ); 54 | 55 | WP_Mock::expectAction( 'wpml_start_string_package_registration', $package ); 56 | WP_Mock::expectAction( 'wpml_delete_unused_package_strings', $package ); 57 | 58 | $translatable_nodes = $this->getMockBuilder( 'WPML_Elementor_Translatable_Nodes' ) 59 | ->setMethods( array( 'get', 'initialize_nodes_to_translate' ) ) 60 | ->disableOriginalConstructor() 61 | ->getMock(); 62 | $translatable_nodes->expects( $this->once() ) 63 | ->method( 'get' ) 64 | ->with( $node_id, $settings ) 65 | ->willReturn( $strings ); 66 | 67 | $data_settings = $this->getMockBuilder( 'WPML_Elementor_Data_Settings' ) 68 | ->disableOriginalConstructor() 69 | ->getMock(); 70 | 71 | $data_settings->method( 'get_meta_field' ) 72 | ->willReturn( '_elementor_data' ); 73 | 74 | $data_settings->method( 'get_node_id_field' ) 75 | ->willReturn( 'id' ); 76 | 77 | $data_settings->method( 'convert_data_to_array' ) 78 | ->with( array( json_encode( $elementor_data ) ) ) 79 | ->willReturn( json_decode( json_encode( $elementor_data ), true ) ); 80 | 81 | $data_settings->method( 'is_handling_post' )->with( $post->ID )->willReturn( true ); 82 | 83 | $string_registration = $this->getMockBuilder( 'WPML_PB_String_Registration' ) 84 | ->setMethods( array( 'register_string' ) ) 85 | ->disableOriginalConstructor() 86 | ->getMock(); 87 | 88 | $string_registration->expects( $this->once() ) 89 | ->method( 'register_string' ) 90 | ->with( 91 | $package['post_id'], 92 | $string->get_value(), 93 | $string->get_editor_type(), 94 | $string->get_title(), 95 | $string->get_name() ); 96 | 97 | $subject = new WPML_Elementor_Register_Strings( $translatable_nodes, $data_settings, $string_registration ); 98 | $subject->register_strings( $post, $package ); 99 | } 100 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/test-wpml-elementor-urls.php: -------------------------------------------------------------------------------- 1 | expectFilterAdded( 'elementor/document/urls/edit', array( 17 | $subject, 18 | 'adjust_edit_with_elementor_url' 19 | ), 10, 2 ); 20 | 21 | $this->expectFilterAdded( 'wpml_is_pagination_url_in_post', [ 22 | $subject, 23 | 'is_pagination_url' 24 | ], 10, 3 ); 25 | 26 | $this->expectFilterAdded( 'paginate_links', [ 27 | $subject, 28 | 'fix_pagination_link_with_language_param' 29 | ], 10, 1 ); 30 | 31 | $subject->add_hooks(); 32 | 33 | } 34 | 35 | /** 36 | * @test 37 | */ 38 | public function it_adjusts_url_for_domain() { 39 | 40 | $original_url = 'http://my-site.com/wp-admin/post.php?post=6&action=elementor'; 41 | $translated_url = 'http://fr.my-site.com/wp-admin/post.php?post=6&action=elementor'; 42 | 43 | $post_language = 'fr'; 44 | 45 | $post = (object) array( 'ID' => 123 ); 46 | 47 | $post_element = \Mockery::mock( 'WPML_Post_Element' ); 48 | $post_element->shouldReceive( 'get_language_code' )->andReturn( $post_language ); 49 | 50 | $element_factory = \Mockery::mock( 'WPML_Translation_Element_Factory' ); 51 | $element_factory->shouldReceive( 'create_post' ) 52 | ->with( $post->ID ) 53 | ->andReturn( $post_element ); 54 | 55 | $language_converter = \Mockery::mock( 'IWPML_URL_Converter_Strategy' ); 56 | $language_converter->shouldReceive( 'convert_admin_url_string' ) 57 | ->with( $original_url, $post_language ) 58 | ->andReturn( $translated_url ); 59 | 60 | $current_language = \Mockery::mock( 'IWPML_Current_Language' ); 61 | 62 | $subject = new WPML_Elementor_URLs( 63 | $element_factory, 64 | $language_converter, 65 | $current_language 66 | ); 67 | 68 | $elementor_document = \Mockery::mock( 'Elementor_Document' ); // Note: this is not the real class name 69 | $elementor_document->shouldReceive( 'get_main_post' )->andReturn( $post ); 70 | 71 | $this->assertEquals( $translated_url, $subject->adjust_edit_with_elementor_url( $original_url, $elementor_document ) ); 72 | } 73 | 74 | /** 75 | * @test 76 | */ 77 | public function it_adjusts_url_for_domain_using_current_language_if_element_has_no_language() { 78 | $original_url = 'http://my-site.com/wp-admin/post.php?post=6&action=elementor'; 79 | $translated_url = 'http://fr.my-site.com/wp-admin/post.php?post=6&action=elementor'; 80 | 81 | $site_language = 'fr'; 82 | 83 | $post = (object) array( 'ID' => 123 ); 84 | 85 | $post_element = \Mockery::mock( 'WPML_Post_Element' ); 86 | $post_element->shouldReceive( 'get_language_code' )->andReturn( '' ); 87 | 88 | $element_factory = \Mockery::mock( 'WPML_Translation_Element_Factory' ); 89 | $element_factory->shouldReceive( 'create_post' ) 90 | ->with( $post->ID ) 91 | ->andReturn( $post_element ); 92 | 93 | $language_converter = \Mockery::mock( 'IWPML_URL_Converter_Strategy' ); 94 | $language_converter->shouldReceive( 'convert_admin_url_string' ) 95 | ->with( $original_url, $site_language ) 96 | ->andReturn( $translated_url ); 97 | 98 | $current_language = \Mockery::mock( 'IWPML_Current_Language' ); 99 | $current_language->shouldReceive( 'get_current_language' )->andReturn( $site_language ); 100 | 101 | $subject = $this->get_subject( 102 | $element_factory, 103 | $language_converter, 104 | $current_language 105 | ); 106 | 107 | $elementor_document = \Mockery::mock( 'Elementor_Document' ); // Note: this is not the real class name 108 | $elementor_document->shouldReceive( 'get_main_post' )->andReturn( $post ); 109 | 110 | $this->assertEquals( $translated_url, $subject->adjust_edit_with_elementor_url( $original_url, $elementor_document ) ); 111 | } 112 | 113 | public function pagination_provider(){ 114 | return [ 115 | [ 'elementor-post', 'index.php/elementor-post/2/' ], 116 | [ 'elementor/post', 'index.php/elementor/post/2/' ] 117 | ]; 118 | } 119 | 120 | /** 121 | * @test 122 | * 123 | * @dataProvider pagination_provider 124 | * 125 | * @param string $post_name 126 | * @param string $path 127 | */ 128 | public function it_filters_pagination_in_post( $post_name, $path ) { 129 | 130 | $element_factory = \Mockery::mock( 'WPML_Translation_Element_Factory' ); 131 | $language_converter = \Mockery::mock( 'IWPML_URL_Converter_Strategy' ); 132 | $current_language = \Mockery::mock( 'IWPML_Current_Language' ); 133 | 134 | WP_Mock::userFunction( 'get_post_meta', [ 'return' => 'builder' ] ); 135 | WP_Mock::userFunction( 'get_the_ID', [ 'return' => 1 ] ); 136 | 137 | $subject = $this->get_subject( 138 | $element_factory, 139 | $language_converter, 140 | $current_language 141 | ); 142 | 143 | $this->assertSame( 144 | true, 145 | $subject->is_pagination_url( false, $path, $post_name ) 146 | ); 147 | } 148 | 149 | /** 150 | * @test 151 | */ 152 | public function it_fixes_pagination_link_with_langauge_param() { 153 | $post_name = 'elementor-post'; 154 | $lang = 'de'; 155 | $link_without_lang = "http://example.com/$post_name/2/"; 156 | $link = "http://example.com/$post_name/?lang=$lang/2/"; 157 | $proper_link = "http://example.com/$post_name/2/?lang=$lang"; 158 | 159 | $element_factory = \Mockery::mock( 'WPML_Translation_Element_Factory' ); 160 | $language_converter = \Mockery::mock( 'IWPML_URL_Converter_Strategy' ); 161 | $current_language = \Mockery::mock( 'IWPML_Current_Language' ); 162 | 163 | $current_language->shouldReceive( 'get_current_language' )->andReturn( $lang ); 164 | 165 | $language_converter->shouldReceive( 'convert_url_string' ) 166 | ->with( $link_without_lang, $lang ) 167 | ->andReturn( $proper_link ); 168 | 169 | WP_Mock::userFunction( 'get_post_meta', [ 'return' => 'builder' ] ); 170 | WP_Mock::userFunction( 'get_the_ID', [ 'return' => 1 ] ); 171 | WP_Mock::userFunction( 'get_post', [ 172 | 'return' => (object) [ 173 | 'ID' => 1, 174 | 'post_name' => $post_name 175 | ] 176 | ] ); 177 | 178 | $subject = $this->get_subject( 179 | $element_factory, 180 | $language_converter, 181 | $current_language 182 | ); 183 | 184 | $this->assertSame( 185 | $proper_link, 186 | $subject->fix_pagination_link_with_language_param( $link ) 187 | ); 188 | } 189 | 190 | private function get_subject( $element_factory, $language_converter, $current_language ) { 191 | return new WPML_Elementor_URLs( 192 | $element_factory, 193 | $language_converter, 194 | $current_language 195 | ); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /tests/phpunit/tests/test-wpml-elementor-woocommerce-hooks-factory.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf( WPML_Elementor_WooCommerce_Hooks::class, $subject->create() ); 16 | } 17 | } -------------------------------------------------------------------------------- /tests/phpunit/tests/test-wpml-elementor-woocommerce-hooks.php: -------------------------------------------------------------------------------- 1 | add_hooks(); 23 | } 24 | 25 | /** 26 | * @test 27 | */ 28 | public function it_should_not_change_if_post_type_is_NOT_in_query_vars() { 29 | $subject = new WPML_Elementor_WooCommerce_Hooks(); 30 | 31 | $query = $this->get_wp_query(); 32 | 33 | $_POST['action'] = 'elementor_ajax'; 34 | 35 | $query->query_vars[ 'suppress_filters' ] = true; 36 | 37 | $filtered_query = $subject->do_not_suppress_filters_on_product_widget( $query ); 38 | 39 | $this->assertTrue( $filtered_query->query_vars['suppress_filters'] ); 40 | } 41 | 42 | /** 43 | * @test 44 | */ 45 | public function it_should_not_change_if_post_type_is_not_product() { 46 | $subject = new WPML_Elementor_WooCommerce_Hooks(); 47 | 48 | $query = $this->get_wp_query(); 49 | 50 | $_POST['action'] = 'elementor_ajax'; 51 | 52 | $query->query_vars[ 'suppress_filters' ] = true; 53 | $query->query_vars[ 'post_type' ] = 'something'; 54 | 55 | $filtered_query = $subject->do_not_suppress_filters_on_product_widget( $query ); 56 | 57 | $this->assertTrue( $filtered_query->query_vars['suppress_filters'] ); 58 | } 59 | 60 | /** 61 | * @test 62 | */ 63 | public function it_should_not_change_if_action_global_is_not_set() { 64 | $subject = new WPML_Elementor_WooCommerce_Hooks(); 65 | 66 | $query = $this->get_wp_query(); 67 | 68 | $query->query_vars[ 'suppress_filters' ] = true; 69 | $query->query_vars[ 'post_type' ] = 'product'; 70 | 71 | $filtered_query = $subject->do_not_suppress_filters_on_product_widget( $query ); 72 | 73 | $this->assertTrue( $filtered_query->query_vars['suppress_filters'] ); 74 | } 75 | 76 | /** 77 | * @test 78 | */ 79 | public function it_should_not_change_if_action_global_is_different_than_the_one_for_adding_widgets() { 80 | $subject = new WPML_Elementor_WooCommerce_Hooks(); 81 | 82 | $query = $this->get_wp_query(); 83 | 84 | $query->query_vars[ 'suppress_filters' ] = true; 85 | $query->query_vars[ 'post_type' ] = 'product'; 86 | 87 | $_POST['action'] = 'some-other-action'; 88 | 89 | $filtered_query = $subject->do_not_suppress_filters_on_product_widget( $query ); 90 | 91 | $this->assertTrue( $filtered_query->query_vars['suppress_filters'] ); 92 | } 93 | 94 | /** 95 | * @test 96 | */ 97 | public function it_should_set_suppress_filters_to_false() { 98 | $subject = new WPML_Elementor_WooCommerce_Hooks(); 99 | 100 | $query = $this->get_wp_query(); 101 | 102 | $query->query_vars[ 'suppress_filters' ] = true; 103 | $query->query_vars[ 'post_type' ] = 'product'; 104 | 105 | $_POST['action'] = 'elementor_ajax'; 106 | 107 | $filtered_query = $subject->do_not_suppress_filters_on_product_widget( $query ); 108 | 109 | $this->assertFalse( $filtered_query->query_vars['suppress_filters'] ); 110 | } 111 | 112 | /** 113 | * @return \WP_Query|\PHPUnit_Framework_MockObject_MockObject 114 | */ 115 | private function get_wp_query() { 116 | return $this->getMockBuilder( 'WP_Query' ) 117 | ->disableOriginalConstructor() 118 | ->getMock(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /tests/phpunit/tests/test-wpml-pb-handle-custom-fields-factory.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf( 'IWPML_Backend_Action_Loader', $subject ); 16 | $this->assertInstanceOf( 'IWPML_AJAX_Action_Loader', $subject ); 17 | $this->assertInstanceOf( 'IWPML_Frontend_Action_Loader', $subject ); 18 | } 19 | 20 | /** 21 | * @test 22 | */ 23 | public function it_returns_instance() { 24 | \Mockery::mock( 'overload:WPML_PB_Handle_Custom_Fields' ); 25 | 26 | $subject = new WPML_PB_Elementor_Handle_Custom_Fields_Factory(); 27 | $this->assertInstanceOf( 'WPML_PB_Handle_Custom_Fields', $subject->create() ); 28 | } 29 | } 30 | 31 | if ( ! interface_exists( 'IWPML_Backend_Action_Loader' ) ) { 32 | interface IWPML_Backend_Action_Loader{} 33 | } 34 | 35 | if ( ! interface_exists( 'IWPML_AJAX_Action_Loader' ) ) { 36 | interface IWPML_AJAX_Action_Loader{} 37 | } 38 | 39 | if ( ! interface_exists( 'IWPML_Frontend_Action_Loader' ) ) { 40 | interface IWPML_Frontend_Action_Loader{} 41 | } -------------------------------------------------------------------------------- /tests/phpunit/util/wpml-pb-test-case2.php: -------------------------------------------------------------------------------- 1 | add_shortcodes( 26 | array( 27 | array( 28 | 'tag' => array( 29 | 'value' => 'vc_column_text', 30 | 'encoding' => $encoding, 31 | ), 32 | 'attributes' => array( 33 | array( 'value' => 'text', 'encoding' => $encoding ), 34 | array( 'value' => 'heading', 'encoding' => $encoding ), 35 | array( 'value' => 'title', 'encoding' => $encoding ), 36 | ), 37 | ), 38 | array( 39 | 'tag' => array( 40 | 'value' => 'vc_text_separator', 41 | 'encoding' => $encoding, 42 | ), 43 | 'attributes' => array( 44 | array( 'value' => 'text', 'encoding' => $encoding ), 45 | array( 'value' => 'heading', 'encoding' => $encoding ), 46 | array( 'value' => 'title', 'encoding' => $encoding ), 47 | ), 48 | ), 49 | array( 50 | 'tag' => array( 51 | 'value' => 'vc_message', 52 | 'encoding' => $encoding, 53 | ), 54 | ), 55 | ) 56 | ); 57 | 58 | $strategy->set_factory( $factory ); 59 | return $strategy; 60 | } 61 | 62 | protected function get_api_hooks_strategy( WPML_PB_Factory $factory ) { 63 | $strategy = new WPML_PB_API_Hooks_Strategy( 'Layout' ); 64 | $strategy->set_factory( $factory ); 65 | return $strategy; 66 | } 67 | 68 | protected function get_post_and_package( $name = '' ) { 69 | if ( ! $name ) { 70 | $name = rand_str(); 71 | } 72 | $post_id = rand(); 73 | 74 | $post = $this->get_post_stub(); 75 | $post->ID = $post_id; 76 | 77 | $package = array( 78 | 'kind' => $name, 79 | 'name' => $post_id, 80 | 'title' => 'Page Builder Page ' . $post_id, 81 | 'post_id' => $post_id, 82 | ); 83 | 84 | return array( $name, $post, $package ); 85 | } 86 | 87 | private function get_post_stub() { 88 | return $this->getMockBuilder( 'WP_Post' ) 89 | ->disableOriginalConstructor() 90 | ->getMock(); 91 | } 92 | 93 | /** 94 | * @return array 95 | */ 96 | protected function get_dummy_ls_languages() { 97 | return array( 98 | 'en' => array( 99 | 'code' => 'en', 100 | 'id' => '1', 101 | 'native_name' => 'English', 102 | 'major' => '1', 103 | 'active' => '1', 104 | 'default_locale' => 'en_US', 105 | 'encode_url' => '0', 106 | 'tag' => 'en', 107 | 'translated_name' => 'English', 108 | 'display_name' => 'English', 109 | 'url' => 'http://example.org', 110 | 'country_flag_url' => 'http://example.org/wp-content/plugins/sitepress-multilingual-cms/res/flags/en.png', 111 | 'language_code' => 'en', 112 | ), 113 | 'fr' => array( 114 | 'code' => 'fr', 115 | 'id' => '4', 116 | 'native_name' => 'Français', 117 | 'major' => '1', 118 | 'active' => 0, 119 | 'default_locale' => 'fr_FR', 120 | 'encode_url' => '0', 121 | 'tag' => 'fr', 122 | 'translated_name' => 'French', 123 | 'display_name' => 'French', 124 | 'url' => 'http://example.org?lang=fr', 125 | 'country_flag_url' => 'http://example.org/wp-content/plugins/sitepress-multilingual-cms/res/flags/fr.png', 126 | 'language_code' => 'fr', 127 | ), 128 | 'de' => array( 129 | 'code' => 'de', 130 | 'id' => '3', 131 | 'native_name' => 'Deutsch', 132 | 'major' => '1', 133 | 'active' => 0, 134 | 'default_locale' => 'de_DE', 135 | 'encode_url' => '0', 136 | 'tag' => 'de', 137 | 'translated_name' => 'German', 138 | 'display_name' => 'German', 139 | 'url' => 'http://example.org?lang=de', 140 | 'country_flag_url' => 'http://example.org/wp-content/plugins/sitepress-multilingual-cms/res/flags/de.png', 141 | 'language_code' => 'de', 142 | ), 143 | 'it' => array( 144 | 'code' => 'it', 145 | 'id' => '27', 146 | 'native_name' => 'Italiano', 147 | 'major' => '1', 148 | 'active' => 0, 149 | 'default_locale' => 'it_IT', 150 | 'encode_url' => '0', 151 | 'tag' => 'it', 152 | 'translated_name' => 'Italian', 153 | 'display_name' => 'Italian', 154 | 'url' => 'http://example.org?lang=it', 155 | 'country_flag_url' => 'http://example.org/wp-content/plugins/sitepress-multilingual-cms/res/flags/it.png', 156 | 'language_code' => 'it', 157 | ), 158 | 'ru' => array( 159 | 'code' => 'ru', 160 | 'id' => '46', 161 | 'native_name' => 'Русский', 162 | 'major' => '1', 163 | 'active' => 0, 164 | 'default_locale' => 'ru_RU', 165 | 'encode_url' => '0', 166 | 'tag' => 'ru', 167 | 'translated_name' => 'Russian', 168 | 'display_name' => 'Russian', 169 | 'url' => 'http://example.org?lang=ru', 170 | 'country_flag_url' => 'http://example.org/wp-content/plugins/sitepress-multilingual-cms/res/flags/ru.png', 171 | 'language_code' => 'ru', 172 | ), 173 | 'es' => array( 174 | 'code' => 'es', 175 | 'id' => '2', 176 | 'native_name' => 'Español', 177 | 'major' => '1', 178 | 'active' => 0, 179 | 'default_locale' => 'es_ES', 180 | 'encode_url' => '0', 181 | 'tag' => 'es', 182 | 'translated_name' => 'Spanish', 183 | 'display_name' => 'Spanish', 184 | 'url' => 'http://example.org?lang=es', 185 | 'country_flag_url' => 'http://example.org/wp-content/plugins/sitepress-multilingual-cms/res/flags/es.png', 186 | 'language_code' => 'es', 187 | ), 188 | ); 189 | } 190 | } 191 | 192 | --------------------------------------------------------------------------------