diff --git a/.appveyor.yml b/.appveyor.yml
index ba159debdd..0aca957045 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -15,12 +15,14 @@ environment:
matrix:
- php_ver_target: 7.2
DLLVersion: "5.3.0"
+ WINCACHE: "2.0.0.8"
- php_ver_target: 7.3
+ WINCACHE: "2.0.0.8"
init:
- SET PATH=C:\Program Files\OpenSSL;C:\tools\php;%PATH%
- SET COMPOSER_NO_INTERACTION=1
- - SET PHP=1 # This var relates to caching the php install
+ - SET PHP=1 # This var relates to caching the php install
- SET ANSICON=121x90 (121x90)
services:
- mssql2014
@@ -33,14 +35,14 @@ install:
- IF EXIST C:\tools\php (SET PHP=0)
# TODO: This is a workaround for https://github.com/chocolatey/choco/issues/1843. Once this is fixed we
# should go back to latest version in appveyor saving ourselves test time
- - ps: choco install chocolatey -y --version 0.10.13 --allow-downgrade
+ - ps: choco upgrade chocolatey -y --version 0.10.13 --allow-downgrade
- ps: >-
If ($env:PHP -eq "1") {
appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php_ver_target | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','')
}
- appveyor-retry cinst -y sqlite
- cd C:\tools\php
- # Get the MSSQL DLL's
+ # Get the MSSQL DLLs
- ps: >-
If ($env:PHP -eq "1") {
cd c:\tools\php\ext
@@ -52,10 +54,11 @@ install:
$source = "https://windows.php.net/downloads/pecl/releases/pdo_sqlsrv/$($env:DLLVersion)/php_pdo_sqlsrv-$($env:DLLVersion)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip"
$destination = "c:\tools\php\ext\php_pdo_sqlsrv-$($env:DLLVersion)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip"
Invoke-WebRequest $source -OutFile $destination
- #appveyor-retry appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/pdo_sqlsrv/$($env:DLLVersion)/php_pdo_sqlsrv-$($env:DLLVersion)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip
+ #appveyor-retry appveyor DownloadFile https://windows.php.net/downloads/pecl/releases/pdo_sqlsrv/$($env:DLLVersion)/php_pdo_sqlsrv-$($env:DLLVersion)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip
7z x -y php_pdo_sqlsrv-$($env:DLLVersion)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip > $null
Remove-Item c:\tools\php\ext* -include .zip
- cd c:\tools\php}
+ cd c:\tools\php
+ }
- IF %PHP%==1 copy php.ini-production php.ini /Y
- IF %PHP%==1 echo date.timezone="UTC" >> php.ini
- IF %PHP%==1 echo extension_dir=ext >> php.ini
@@ -80,18 +83,19 @@ install:
- IF %PHP%==1 echo extension=php_curl.dll >> php.ini
# Get the Wincache DLLs
- ps: >-
- If ($env:PHP -eq "1") {
- $wincache = "2.0.0.8"
+ If ($env:PHP -eq "1" -and $env:WINCACHE) {
cd c:\tools\php\ext
- $source = "http://windows.php.net/downloads/pecl/releases/wincache/$($wincache)/php_wincache-$($wincache)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip"
- $destination = "c:\tools\php\ext\php_wincache-$($wincache)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip"
+ $source = "https://windows.php.net/downloads/pecl/releases/wincache/$($env:WINCACHE)/php_wincache-$($env:WINCACHE)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip"
+ $destination = "c:\tools\php\ext\php_wincache-$($env:WINCACHE)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip"
Invoke-WebRequest $source -OutFile $destination
- #appveyor-retry appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/wincache/$($wincache)/php_wincache-$($wincache)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip
- 7z x -y php_wincache-$($wincache)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip > $null
+ #appveyor-retry appveyor DownloadFile https://windows.php.net/downloads/pecl/releases/wincache/$($env:WINCACHE)/php_wincache-$($env:WINCACHE)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip
+ 7z x -y php_wincache-$($env:WINCACHE)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip > $null
Remove-Item C:\tools\php\ext* -include .zip
- cd c:\tools\php}
- - IF %PHP%==1 echo extension=php_wincache.dll >> php.ini
- - IF %PHP%==1 echo wincache.enablecli = 1 >> php.ini
+ cd c:\tools\php
+ Add-Content php.ini "`nextension=php_wincache.dll"
+ Add-Content php.ini "`wincache.enablecli = 1"
+ Add-Content php.ini "`n"
+ }
- IF %PHP%==1 echo zend_extension=php_opcache.dll >> php.ini
- IF %PHP%==1 echo opcache.enable_cli=1 >> php.ini
- IF %PHP%==1 echo extension=php_ldap.dll >> php.ini
diff --git a/.drone.yml b/.drone.yml
index 3dc1713583..1d63c73f3a 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -11,16 +11,14 @@ steps:
settings:
restore: true
mount:
- - ./node_modules
- ./libraries/vendor
- - ./administrator/components/com_media/node_modules
cache_key: [ DRONE_REPO_NAMESPACE, DRONE_REPO_NAME, DRONE_BRANCH, DRONE_STAGE_NUMBER ]
volumes:
- name: cache
path: /cache
- name: composer
- image: joomlaprojects/docker-tools:develop
+ image: joomlaprojects/docker-images:php7.3-composer
depends_on: [ restore-cache ]
commands:
- composer validate --no-check-all --strict
@@ -35,20 +33,46 @@ steps:
- echo $(date)
- name: npm
- image: joomlaprojects/docker-tools:develop
+ image: node:current-alpine
depends_on: [ phpcs ]
commands:
- npm ci --unsafe-perm
+ - name: publish-diff
+ image: joomlaprojects/docker-images:patchtester
+ depends_on: [ npm ]
+ environment:
+ CMP_ARCHIVE_NAME: "build"
+ CMP_MASTER_FOLDER: "/reference"
+ CMP_SLAVE_FOLDER: "." # The directory the current repo is in
+ FTP_USERNAME:
+ from_secret: ftpusername
+ FTP_PASSWORD:
+ from_secret: ftppassword
+ FTP_HOSTNAME: ci.joomla.org
+ FTP_PORT: "21"
+ FTP_DEST_DIR: /artifacts
+ FTP_VERIFY: "false"
+ FTP_SECURE: "true"
+ BRANCH_NAME: "4.0-dev" # Current branch to check against (from repo joomla/joomla-cms)
+ DRONE_PULL_REQUEST: DRONE_PULL_REQUEST
+ commands:
+ - export PULL_ID=$DRONE_PULL_REQUEST
+ - /bin/compare.sh
+ volumes:
+ - name: reference
+ path: /reference
+ when:
+ branch:
+ - 4.0-dev
+
- name: rebuild-cache
image: drillster/drone-volume-cache
depends_on: [ npm ]
settings:
rebuild: true
mount:
- - ./node_modules
- ./libraries/vendor
- - ./administrator/components/com_media/node_modules
cache_key: [ DRONE_REPO_NAMESPACE, DRONE_REPO_NAME, DRONE_BRANCH, DRONE_STAGE_NUMBER ]
volumes:
- name: cache
@@ -121,32 +145,34 @@ steps:
- php -v
- ./libraries/vendor/bin/phpunit --testsuite Integration --configuration phpunit-pgsql.xml.dist
-# - name: php73-integration-pgsql
-# depends_on: [ npm ]
-# image: joomlaprojects/docker-images:php7.3
-# commands:
-# - php -v
-# - ./libraries/vendor/bin/phpunit --testsuite Integration --configuration phpunit-pgsql.xml.dist
-
-# - name: php74-integration-pgsql
-# depends_on: [ npm ]
-# image: joomlaprojects/docker-images:php7.4
-# failure: ignore
-# commands:
-# - php -v
-# - ./libraries/vendor/bin/phpunit --testsuite Integration --configuration phpunit-pgsql.xml.dist
-
-# - name: php80-integration-pgsql
-# depends_on: [ npm ]
-# image: joomlaprojects/docker-images:php8.0
-# failure: ignore
-# commands:
-# - php -v
-# - ./libraries/vendor/bin/phpunit --testsuite Integration --configuration phpunit-pgsql.xml.dist
+ - name: php73-integration-pgsql
+ depends_on: [ npm ]
+ image: joomlaprojects/docker-images:php7.3
+ commands:
+ - php -v
+ - ./libraries/vendor/bin/phpunit --testsuite Integration --configuration phpunit-pgsql.xml.dist
+
+ - name: php74-integration-pgsql
+ depends_on: [ npm ]
+ image: joomlaprojects/docker-images:php7.4
+ failure: ignore
+ commands:
+ - php -v
+ - ./libraries/vendor/bin/phpunit --testsuite Integration --configuration phpunit-pgsql.xml.dist
+
+ - name: php80-integration-pgsql
+ depends_on: [ npm ]
+ image: joomlaprojects/docker-images:php8.0
+ failure: ignore
+ commands:
+ - php -v
+ - ./libraries/vendor/bin/phpunit --testsuite Integration --configuration phpunit-pgsql.xml.dist
- name: javascript-cs
depends_on: [ npm ]
- image: joomlaprojects/docker-systemtests:develop
+ image: joomlaprojects/docker-images:systemtests
+ environment:
+ JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1
commands:
- export DISPLAY=:0
- Xvfb -screen 0 1024x768x24 -ac +extension GLX +render -noreset > /dev/null 2>&1 &
@@ -156,7 +182,9 @@ steps:
- name: javascript-tests
depends_on: [ npm ]
- image: joomlaprojects/docker-systemtests:develop
+ image: joomlaprojects/docker-images:systemtests
+ environment:
+ JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1
commands:
- export DISPLAY=:0
- Xvfb -screen 0 1024x768x24 -ac +extension GLX +render -noreset > /dev/null 2>&1 &
@@ -166,26 +194,39 @@ steps:
- name: system-tests-mysql
depends_on: [ javascript-tests ]
- image: joomlaprojects/docker-systemtests:latest
+ image: joomlaprojects/docker-images:systemtests
+ environment:
+ JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1
commands:
- bash tests/Codeception/drone-system-run.sh "$(pwd)" mysql
- name: system-tests-mysql8
depends_on: [ system-tests-mysql ]
- image: joomlaprojects/docker-systemtests:latest
- failure: ignore
+ image: joomlaprojects/docker-images:systemtests
+ environment:
+ JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1
commands:
- bash tests/Codeception/drone-system-run.sh "$(pwd)" mysql8
- name: system-tests-postgres
depends_on: [ system-tests-mysql8 ]
- image: joomlaprojects/docker-systemtests:latest
+ image: joomlaprojects/docker-images:systemtests
+ environment:
+ JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1
commands:
- bash tests/Codeception/drone-system-run.sh "$(pwd)" postgres
+ - name: api-tests
+ depends_on: [ system-tests-postgres ]
+ image: joomlaprojects/docker-images:systemtests
+ environment:
+ JOOMLA_INSTALLATION_DISABLE_LOCALHOST_CHECK: 1
+ commands:
+ - bash tests/Codeception/drone-api-run.sh "$(pwd)"
+
- name: artifacts-system-tests
image: cschlosser/drone-ftps
- depends_on: [ system-tests-postgres ]
+ depends_on: [ api-tests ]
environment:
FTP_USERNAME:
from_secret: ftpusername
@@ -197,21 +238,15 @@ steps:
PLUGIN_SECURE: false
PLUGIN_EXCLUDE: ^\.git/$
commands:
- - export PLUGIN_DEST_DIR=$PLUGIN_DEST_DIR/$DRONE_REPO/$DRONE_BRANCH/$DRONE_PULL_REQUEST_$DRONE_BUILD_NUMBER/system-tests
+ - export PLUGIN_DEST_DIR=$PLUGIN_DEST_DIR/$DRONE_REPO/$DRONE_BRANCH/$DRONE_PULL_REQUEST/system-tests/$DRONE_BUILD_NUMBER
- echo https://ci.joomla.org:444$PLUGIN_DEST_DIR
- /bin/upload.sh
when:
status:
- - failure
-
- - name: api-tests
- depends_on: [ system-tests-postgres ]
- image: joomlaprojects/docker-systemtests:latest
- commands:
- - bash tests/Codeception/drone-api-run.sh "$(pwd)"
+ - failure
- name: analysis4x
- image: rips/rips-cli:1.2.1
+ image: rips/rips-cli:3.2.2
depends_on: [ api-tests ]
when:
repo:
@@ -220,10 +255,11 @@ steps:
- 4.0-dev
commands:
- export RIPS_BASE_URI='https://api.rips.joomla.org'
- - rips-cli rips:scan:start -a 3 -t 1 -R -k -p $(pwd) -t 1 -T $DRONE_REPO_NAMESPACE-$DRONE_BRANCH || { echo "Please contact the security team at security@joomla.org"; exit 1; }
+ - rips-cli rips:list --table=scans -n -p filter='{"__and":[{"__lessThan":{"percent":100}}]}'
+ - rips-cli rips:scan:start -G -a 2 -t 1 -R -k -p $(pwd) -t 1 -T $DRONE_REPO_NAMESPACE-$DRONE_BRANCH || { echo "Please contact the security team at security@joomla.org"; exit 1; }
environment:
- RIPS_USERNAME:
- from_secret: RIPS_USERNAME
+ RIPS_EMAIL:
+ from_secret: RIPS_EMAIL
RIPS_PASSWORD:
from_secret: RIPS_PASSWORD
@@ -234,6 +270,9 @@ volumes:
- name: cache
host:
path: /tmp/cache
+- name: reference
+ host:
+ path: /tmp/reference
services:
- name: mysql
@@ -270,6 +309,6 @@ services:
---
kind: signature
-hmac: 5cdcb0e095c87e88b88c3b90a80343bd4f1d61b7df795aca67870eaa3bc1b112
+hmac: bf9ea2d23f5b94fc80c2cb5fbd9b8c5f7b1423319c01a904b0b499233eb873f6
...
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000000..0be9be57ae
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+custom: https://community.joomla.org/sponsorship-campaigns.html
diff --git a/SECURITY.md b/.github/SECURITY.md
similarity index 87%
rename from SECURITY.md
rename to .github/SECURITY.md
index 449c2a5978..52af74f0b6 100644
--- a/SECURITY.md
+++ b/.github/SECURITY.md
@@ -9,9 +9,7 @@ This document outlines security procedures and policies for the `Joomla! Project
## Reporting a Bug
-The `Joomla` team and community take all security bugs in `Joomla` seriously.
-
-The Joomla! Project takes security vulnerabilities very seriously. As such, the Joomla! Security Strike Team (JSST) oversees the project's security issues and follows some specific procedures when dealing with these issues.
+The `Joomla` team and community take all security bugs in `Joomla` seriously. The Joomla! Security Strike Team (JSST) oversees the project's security issues and follows some specific procedures when dealing with these issues.
If you find a possible vulnerability, please report it to the JSST using the [online form](https://developer.joomla.org/security/contact-the-team.html) or via email at security@joomla.org
@@ -25,7 +23,7 @@ Thank you for improving the security of `Joomla`.
## Response Handling
-The JSST aims to ensure all issues are handled in a timely manner and for clear communication between the team and issue reporters. As such, we have established the following guidelines for responding to issue reports:
+The JSST aims to ensure all issues are handled in a timely manner and for clear communication between the team and issue reporters. We have established the following guidelines for responding to issue reports:
* Within 24 hours every report gets acknowledged
* Within 7 days every report gets a further response stating either
diff --git a/README.md b/README.md
index 618890eef1..660bc70609 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Build Status
| ------------- | ------------- |
| [](https://ci.joomla.org/joomla/joomla-cms) | [](https://ci.appveyor.com/project/release-joomla/joomla-cms) |
-What is this?
+Overview
---------------------
* This is the source of Joomla! 4.x.
* Joomla's [Official website](https://www.joomla.org).
diff --git a/README.txt b/README.txt
index 09203ba7d7..898e3565d6 100644
--- a/README.txt
+++ b/README.txt
@@ -1,4 +1,6 @@
-1- What is this?
+Joomla! CMS™
+
+1- Overview
* This is a Joomla! 4.x installation/upgrade package.
* Joomla! Official site: https://www.joomla.org
* Joomla! 4.0 version history - https://docs.joomla.org/Special:MyLanguage/Joomla_4.0_version_history
diff --git a/RoboFile.php b/RoboFile.php
deleted file mode 100644
index 4223b3680b..0000000000
--- a/RoboFile.php
+++ /dev/null
@@ -1,494 +0,0 @@
-getSuiteConfig()['modules']['config']['Helper\\Acceptance']['cmsPath'];
- $localUser = $this->getSuiteConfig()['modules']['config']['Helper\\Acceptance']['localUser'];
-
- // Clean old testing site
- if (is_dir($cmsPath))
- {
- try
- {
- $this->taskDeleteDir($cmsPath)->run();
- }
- catch (Exception $e)
- {
- // Sorry, we tried :(
- $this->say('Sorry, you will have to delete ' . $cmsPath . ' manually.');
-
- exit(1);
- }
- }
-
- $exclude = [
- '.drone',
- '.github',
- '.git',
- '.run',
- '.idea',
- 'build',
- 'dev',
- 'node_modules',
- 'tests',
- 'test-install',
- '.appveyor.yml',
- '.babelrc',
- '.drone.yml',
- '.editorconfig',
- '.eslintignore',
- '.eslintrc',
- '.gitignore',
- '.hound.yml',
- '.php_cs',
- '.travis.yml',
- 'appveyor-phpunit.xml',
- 'build.js',
- 'build.xml',
- 'codeception.yml',
- 'composer.json',
- 'composer.lock',
- 'configuration.php',
- 'drone-package.json',
- 'Gemfile',
- 'htaccess.txt',
- 'karma.conf.js',
- 'package.json',
- 'package-lock.json',
- 'phpunit.xml.dist',
- 'RoboFile.dist.ini',
- 'RoboFile.php',
- 'robots.txt.dist',
- 'scss-lint.yml',
- 'selenium.log',
- 'travisci-phpunit.xml',
- ];
-
- $this->copyJoomla($cmsPath, $exclude);
-
- // Optionally change owner to fix permissions issues
- if (!empty($localUser))
- {
- $this->_exec('chown -R ' . $localUser . ' ' . $cmsPath);
- }
-
- // Optionally uses Joomla default htaccess file. Used by TravisCI
- if ($useHtaccess == true)
- {
- $this->say('Renaming htaccess.txt to .htaccess');
- $this->_copy('./htaccess.txt', $cmsPath . '/.htaccess');
- $this->_exec('sed -e "s,# RewriteBase /,RewriteBase /test-install/joomla-cms,g" -in-place test-install/joomla-cms/.htaccess');
- }
- }
-
- /**
- * Copy the Joomla installation excluding folders
- *
- * @param string $dst Target folder
- * @param array $exclude Exclude list of folders
- *
- * @throws Exception
- *
- * @since 3.7.3
- *
- * @return void
- */
- protected function copyJoomla($dst, $exclude = array())
- {
- $dir = @opendir(".");
-
- if (false === $dir)
- {
- throw new Exception($this, "Cannot open source directory");
- }
-
- if (!is_dir($dst))
- {
- mkdir($dst, 0755, true);
- }
-
- while (false !== ($file = readdir($dir)))
- {
- if (in_array($file, $exclude))
- {
- continue;
- }
-
- if (($file !== '.') && ($file !== '..'))
- {
- $srcFile = "." . '/' . $file;
- $destFile = $dst . '/' . $file;
-
- if (is_dir($srcFile))
- {
- $this->_copyDir($srcFile, $destFile);
- }
- else
- {
- copy($srcFile, $destFile);
- }
- }
- }
-
- closedir($dir);
- }
-
- /**
- * Executes all the Selenium System Tests in a suite on your machine
- *
- * @param array $opts Array of configuration options:
- * - 'use-htaccess': renames and enable embedded Joomla .htaccess file
- * - 'env': set a specific environment to get configuration from
- *
- * @return void
- * @since 3.7.3
- *
- * @throws Exception
- */
- public function runTests($opts = ['use-htaccess' => false, 'env' => 'desktop'])
- {
- $this->say("Running tests");
-
- $pathToCodeception = $this->prepareRun($opts);
-
- $suites = [
- 'acceptance/install/',
- 'acceptance/administrator/components/com_content',
- 'acceptance/administrator/components/com_media',
- 'acceptance/administrator/components/com_menu',
- 'acceptance/administrator/components/com_users',
- ];
-
- foreach ($suites as $suite) {
- $this->taskCodecept($pathToCodeception)
- ->arg('--fail-fast')
- ->arg('--steps')
- ->arg('--debug')
- ->env($opts['env'])
- ->arg($this->testsPath . $suite)
- ->run()
- ->stopOnFail();
- }
- }
-
- /**
- * Install only Joomla
- *
- * @param array $opts Additional options
- *
- * @return void
- * @since 4.0.0
- *
- * @throws Exception
- */
- public function runInstall($opts = ['use-htaccess' => false, 'env' => 'desktop'])
- {
- $this->say("Running Installation");
-
- $pathToCodeception = $this->prepareRun($opts);
-
- $this->taskCodecept($pathToCodeception)
- ->arg('--fail-fast')
- ->arg('--steps')
- ->arg('--debug')
- ->env($opts['env'])
- ->arg($this->testsPath . 'acceptance/install/')
- ->run()
- ->stopOnFail();
- }
-
- /**
- * Prepare the installation
- *
- * @param array $opts Optional Options
- *
- * @return string Path to codeception
- *
- * @since 4.0.0
- * @throws Exception
- */
- protected function prepareRun($opts = ['use-htaccess' => false, 'env' => 'desktop'])
- {
- $this->createTestingSite($opts['use-htaccess']);
-
- $this->taskRunSelenium(self::SELENIUM_FOLDER, $this->getWebdriver())->run();
-
- // Wait until the server started
- sleep(3);
-
- // Make sure to run the build command to generate AcceptanceTester
- if ($this->isWindows())
- {
- $this->_exec('php ' . $this->getWindowsPath($this->vendorPath . 'bin/codecept') . ' build');
- $pathToCodeception = $this->getWindowsPath($this->vendorPath . 'bin/codecept');
- }
- else
- {
- $this->_exec('php ' . $this->vendorPath . 'bin/codecept build');
-
- $pathToCodeception = $this->vendorPath . 'bin/codecept';
- }
-
- return $pathToCodeception;
- }
-
- /**
- * Executes a specific Selenium System Tests in your machine
- *
- * @param string $pathToTestFile Optional name of the test to be run
- * @param string $suite Optional name of the suite containing the tests, Acceptance by default.
- *
- * @since 3.7.3
- *
- * @throws Exception if test not found
- *
- * @return void
- */
- public function runTest($pathToTestFile = null, $suite = 'acceptance')
- {
- $this->taskRunSelenium(self::SELENIUM_FOLDER, $this->getWebdriver());
-
- // Make sure to run the build command to generate AcceptanceTester
- $path = $this->vendorPath . 'bin/codecept';
- $this->_exec('php ' . $this->isWindows() ? $this->getWindowsPath($path) : $path . ' build');
-
- if (!$pathToTestFile)
- {
- $this->say('Available tests in the system:');
-
- $iterator = new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator(
- $this->testsPath . '/' . $suite,
- RecursiveDirectoryIterator::SKIP_DOTS
- ),
- RecursiveIteratorIterator::SELF_FIRST
- );
-
- $tests = array();
- $i = 1;
-
- $iterator->rewind();
-
- while ($iterator->valid())
- {
- if (strripos($iterator->getSubPathName(), 'cept.php')
- || strripos($iterator->getSubPathName(), 'cest.php')
- || strripos($iterator->getSubPathName(), '.feature')
- )
- {
- $this->say('[' . $i . '] ' . $iterator->getSubPathName());
-
- $tests[$i] = $iterator->getSubPathName();
- $i++;
- }
-
- $iterator->next();
- }
-
- $this->say('');
- $testNumber = $this->ask('Type the number of the test in the list that you want to run...');
- $test = $tests[$testNumber];
- }
-
- $pathToTestFile = $this->testsPath . '/' . $suite . '/' . $test;
-
- // Loading the class to display the methods in the class
-
- // Logic to fetch the class name from the file name
- $fileName = explode("/", $test);
-
- // If the selected file is cest only then we will give the option to execute individual methods, we don't need this in cept or feature files
- $i = 1;
-
- if (isset($fileName[1]) && strripos($fileName[1], 'cest'))
- {
- require $this->testsPath . '/' . $suite . '/' . $test;
-
- $className = explode(".", $fileName[1]);
- $class_methods = get_class_methods($className[0]);
-
- $this->say('[' . $i . '] ' . 'All');
-
- $methods[$i] = 'All';
- $i++;
-
- foreach ($class_methods as $method_name)
- {
- $reflect = new ReflectionMethod($className[0], $method_name);
-
- if (!$reflect->isConstructor() && $reflect->isPublic())
- {
- $this->say('[' . $i . '] ' . $method_name);
-
- $methods[$i] = $method_name;
-
- $i++;
- }
- }
-
- $this->say('');
- $methodNumber = $this->ask('Please choose the method in the test that you would want to run...');
- $method = $methods[$methodNumber];
- }
-
- if (isset($method) && $method != 'All')
- {
- $pathToTestFile = $pathToTestFile . ':' . $method;
- }
-
- $testPathCodecept = $this->vendorPath . 'bin/codecept';
-
- $this->taskCodecept($this->isWindows() ? $this->getWindowsPath($testPathCodecept) : $testPathCodecept)
- ->test($pathToTestFile)
- ->arg('--steps')
- ->arg('--debug')
- ->run()
- ->stopOnFail();
- }
-
- /**
- * Check if local OS is Windows
- *
- * @return bool
- *
- * @since 3.7.3
- */
- private function isWindows()
- {
- return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
- }
-
- /**
- * Return the correct path for Windows (needed by CMD)
- *
- * @param string $path Linux path
- *
- * @return string
- *
- * @since 3.7.3
- */
- private function getWindowsPath($path)
- {
- return str_replace('/', DIRECTORY_SEPARATOR, $path);
- }
-
- /**
- * Detect the correct driver for selenium
- *
- * @return string the webdriver string to use with selenium
- *
- * @since 3.7.3
- */
- public function getWebdriver()
- {
- $suiteConfig = $this->getSuiteConfig();
- $driver = $suiteConfig['modules']['config']['JoomlaBrowser']['browser'];
-
- return $driver;
- }
-
- /**
- * Get the suite configuration
- *
- * @param string $suite Name of the test suite
- *
- * @return array
- *
- * @since 3.7.3
- */
- private function getSuiteConfig($suite = 'acceptance')
- {
- if (!$this->suiteConfig)
- {
- $this->suiteConfig = Symfony\Component\Yaml\Yaml::parse(file_get_contents(__DIR__ . '/tests/Codeception/' . $suite . '.suite.yml'));
- }
-
- return $this->suiteConfig;
- }
-}
diff --git a/administrator/components/com_actionlogs/Field/ExtensionField.php b/administrator/components/com_actionlogs/Field/ExtensionField.php
index 4c420de9b5..18909fd6d0 100644
--- a/administrator/components/com_actionlogs/Field/ExtensionField.php
+++ b/administrator/components/com_actionlogs/Field/ExtensionField.php
@@ -4,7 +4,7 @@
* @subpackage com_actionlogs
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
- * @license GNU General Public License version 2 or later; see LICENSE
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Actionlogs\Administrator\Field;
diff --git a/administrator/components/com_actionlogs/Field/LogcreatorField.php b/administrator/components/com_actionlogs/Field/LogcreatorField.php
index 28ff4cb68d..bedc838c15 100644
--- a/administrator/components/com_actionlogs/Field/LogcreatorField.php
+++ b/administrator/components/com_actionlogs/Field/LogcreatorField.php
@@ -4,7 +4,7 @@
* @subpackage com_actionlogs
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
- * @license GNU General Public License version 2 or later; see LICENSE
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Actionlogs\Administrator\Field;
@@ -58,12 +58,12 @@ protected function getOptions()
// Construct the query
$query = $db->getQuery(true)
->select($db->quoteName('u.id', 'value'))
- ->select($db->quoteName('u.name', 'text'))
+ ->select($db->quoteName('u.username', 'text'))
->from($db->quoteName('#__users', 'u'))
->join('INNER', $db->quoteName('#__action_logs', 'c') . ' ON ' . $db->quoteName('c.user_id') . ' = ' . $db->quoteName('u.id'))
->group($db->quoteName('u.id'))
- ->group($db->quoteName('u.name'))
- ->order($db->quoteName('u.name'));
+ ->group($db->quoteName('u.username'))
+ ->order($db->quoteName('u.username'));
// Setup the query
$db->setQuery($query);
diff --git a/administrator/components/com_actionlogs/Field/LogsdaterangeField.php b/administrator/components/com_actionlogs/Field/LogsdaterangeField.php
index 44f37727d2..643235bed6 100644
--- a/administrator/components/com_actionlogs/Field/LogsdaterangeField.php
+++ b/administrator/components/com_actionlogs/Field/LogsdaterangeField.php
@@ -4,7 +4,7 @@
* @subpackage com_actionlogs
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
- * @license GNU General Public License version 2 or later; see LICENSE
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Actionlogs\Administrator\Field;
diff --git a/administrator/components/com_actionlogs/Field/LogtypeField.php b/administrator/components/com_actionlogs/Field/LogtypeField.php
index 4a82a9fe16..cd26bff607 100644
--- a/administrator/components/com_actionlogs/Field/LogtypeField.php
+++ b/administrator/components/com_actionlogs/Field/LogtypeField.php
@@ -4,7 +4,7 @@
* @subpackage com_actionlogs
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
- * @license GNU General Public License version 2 or later; see LICENSE
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\Component\Actionlogs\Administrator\Field;
diff --git a/administrator/components/com_actionlogs/Helper/ActionlogsHelper.php b/administrator/components/com_actionlogs/Helper/ActionlogsHelper.php
index dfa7388bc7..64a0cd4896 100644
--- a/administrator/components/com_actionlogs/Helper/ActionlogsHelper.php
+++ b/administrator/components/com_actionlogs/Helper/ActionlogsHelper.php
@@ -26,6 +26,14 @@
*/
class ActionlogsHelper
{
+ /**
+ * Array of characters starting a formula
+ *
+ * @var array
+ * @since 3.9.7
+ */
+ private static $characters = array('=', '+', '-', '@');
+
/**
* Method to convert logs objects array to an iterable type for use with a CSV export
*
@@ -49,8 +57,10 @@ public static function getCsvData($data): Generator
);
}
+ $disabledText = Text::_('COM_ACTIONLOGS_DISABLED');
+
// Header row
- yield ['Id', 'Message', 'Date', 'Extension', 'User', 'Ip'];
+ yield ['Id', 'Action', 'Extension', 'Date', 'Name', 'IP Address'];
foreach ($data as $log)
{
@@ -58,14 +68,14 @@ public static function getCsvData($data): Generator
static::loadTranslationFiles($extension);
- yield [
+ yield array(
'id' => $log->id,
- 'message' => strip_tags(static::getHumanReadableLogMessage($log, false)),
+ 'message' => self::escapeCsvFormula(strip_tags(static::getHumanReadableLogMessage($log, false))),
+ 'extension' => self::escapeCsvFormula(Text::_($extension)),
'date' => (new Date($log->log_date, new \DateTimeZone('UTC')))->format('Y-m-d H:i:s T'),
- 'extension' => Text::_($extension),
- 'name' => $log->name,
- 'ip_address' => Text::_($log->ip_address),
- ];
+ 'name' => self::escapeCsvFormula($log->name),
+ 'ip_address' => self::escapeCsvFormula($log->ip_address === 'COM_ACTIONLOGS_DISABLED' ? $disabledText : $log->ip_address)
+ );
}
}
@@ -196,7 +206,7 @@ public static function getHumanReadableLogMessage($log, $generateLinks = true)
$messageData['type'] = Text::_($messageData['type']);
}
- $linkMode = Factory::getApplication()->get('force_ssl', 0) >= 1 ? 1 : -1;
+ $linkMode = Factory::getApplication()->get('force_ssl', 0) >= 1 ? Route::TLS_FORCE : Route::TLS_IGNORE;
foreach ($messageData as $key => $value)
{
@@ -330,4 +340,28 @@ public static function loadActionLogPluginsLanguage()
// Load com_privacy too.
$lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true);
}
+
+ /**
+ * Escapes potential characters that start a formula in a CSV value to prevent injection attacks
+ *
+ * @param mixed $value csv field value
+ *
+ * @return mixed
+ *
+ * @since 3.9.7
+ */
+ protected static function escapeCsvFormula($value)
+ {
+ if ($value == '')
+ {
+ return $value;
+ }
+
+ if (in_array($value[0], self::$characters, true))
+ {
+ $value = ' ' . $value;
+ }
+
+ return $value;
+ }
}
diff --git a/administrator/components/com_actionlogs/Model/ActionlogsModel.php b/administrator/components/com_actionlogs/Model/ActionlogsModel.php
index 4b2a9b504f..9a71e58694 100644
--- a/administrator/components/com_actionlogs/Model/ActionlogsModel.php
+++ b/administrator/components/com_actionlogs/Model/ActionlogsModel.php
@@ -151,7 +151,7 @@ protected function getListQuery()
$date = $this->buildDateRange($dateRange);
// If the chosen range is not more than a year ago
- if ($date['dNow'] != false)
+ if ($date['dNow'] !== false && $date['dStart'] !== false)
{
$dStart = $date['dStart']->format('Y-m-d H:i:s');
$dNow = $date['dNow']->format('Y-m-d H:i:s');
diff --git a/administrator/components/com_actionlogs/View/Actionlogs/HtmlView.php b/administrator/components/com_actionlogs/View/Actionlogs/HtmlView.php
index dd42b5e14f..0e9385a365 100644
--- a/administrator/components/com_actionlogs/View/Actionlogs/HtmlView.php
+++ b/administrator/components/com_actionlogs/View/Actionlogs/HtmlView.php
@@ -101,7 +101,7 @@ public function display($tpl = null)
$params = ComponentHelper::getParams('com_actionlogs');
$this->showIpColumn = (bool) $params->get('ip_logging', 0);
- if (count($errors = $this->get('Errors')))
+ if (count($errors = $model->getErrors()))
{
throw new GenericDataException(implode("\n", $errors), 500);
}
diff --git a/administrator/components/com_actionlogs/actionlogs.xml b/administrator/components/com_actionlogs/actionlogs.xml
index 758465b5b5..46360db19a 100644
--- a/administrator/components/com_actionlogs/actionlogs.xml
+++ b/administrator/components/com_actionlogs/actionlogs.xml
@@ -27,8 +27,8 @@