diff --git a/.appveyor.yml b/.appveyor.yml index 7bbd2ee4f0c3d..c0c142c4fde63 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,17 +2,38 @@ build: false platform: - x64 clone_folder: C:\projects\joomla-cms + +branches: + except: + - /l10n_*/ + ## Build matrix for lowest and highest possible targets environment: + DLLVersion: "5.8.0" + PHPBuild: "x64" + VC: "vc15" matrix: - php_ver_target: 5.6 + PHPBuild: "x86" + VC: "vc11" + WINCACHE: "1.3.7.12" - php_ver_target: 7.0 + DLLVersion: "5.3.0" + VC: "vc14" + WINCACHE: "2.0.0.8" - php_ver_target: 7.1 + DLLVersion: "5.3.0" + VC: "vc14" + WINCACHE: "2.0.0.8" + - php_ver_target: 7.2 + DLLVersion: "5.3.0" + - php_ver_target: 7.3 + - php_ver_target: 7.4 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 @@ -23,15 +44,14 @@ services: ## Install PHP and composer, and run the appropriate composer command 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 upgrade chocolatey -y --version 0.10.13 --allow-downgrade --no-progress - ps: >- If ($env:php_ver_target -eq "5.6") { - appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y --forcex86 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|]','') - $VC = "vc11" - $PHPBuild = "x86" + appveyor-retry cinst --no-progress --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y --forcex86 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|]','') } Else { - 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|]','') - $VC = "vc14" - $PHPBuild = "x64" + appveyor-retry cinst --no-progress --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 @@ -39,20 +59,30 @@ install: - ps: >- If ($env:PHP -eq "1") { If ($env:php_ver_target -eq "5.6") { - appveyor-retry appveyor DownloadFile https://cdn.joomla.org/ci/php-sqlsrv.zip + $source = "https://cdn.joomla.org/ci/php-sqlsrv.zip" + $destination = "c:\tools\php\php-sqlsrv.zip" + Invoke-WebRequest $source -OutFile $destination + #appveyor-retry appveyor DownloadFile https://cdn.joomla.org/ci/php-sqlsrv.zip 7z x -y php-sqlsrv.zip > $null copy SQLSRV\php_sqlsrv_56_nts.dll ext\php_sqlsrv_nts.dll copy SQLSRV\php_pdo_sqlsrv_56_nts.dll ext\php_pdo_sqlsrv_nts.dll Remove-Item C:\tools\php\* -include .zip } Else { - $DLLVersion = "4.1.6.1" cd c:\tools\php\ext - appveyor-retry appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/sqlsrv/$($DLLVersion)/php_sqlsrv-$($DLLVersion)-$($env:php_ver_target)-nts-vc14-x64.zip - 7z x -y php_sqlsrv-$($DLLVersion)-$($env:php_ver_target)-nts-vc14-x64.zip > $null - appveyor-retry appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/pdo_sqlsrv/$($DLLVersion)/php_pdo_sqlsrv-$($DLLVersion)-$($env:php_ver_target)-nts-vc14-x64.zip - 7z x -y php_pdo_sqlsrv-$($DLLVersion)-$($env:php_ver_target)-nts-vc14-x64.zip > $null + $source = "https://windows.php.net/downloads/pecl/releases/sqlsrv/$($env:DLLVersion)/php_sqlsrv-$($env:DLLVersion)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip" + $destination = "c:\tools\php\ext\php_sqlsrv-$($env:DLLVersion)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip" + Invoke-WebRequest $source -OutFile $destination + #appveyor-retry appveyor DownloadFile https://windows.php.net/downloads/pecl/releases/sqlsrv/$($env:DLLVersion)/php_sqlsrv-$($env:DLLVersion)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip + 7z x -y php_sqlsrv-$($env:DLLVersion)-$($env:php_ver_target)-nts-$($env:VC)-$($env:PHPBuild).zip > $null + $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 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,19 +110,24 @@ install: - IF %PHP%==1 echo extension=php_curl.dll >> php.ini # Get the Wincache DLLs - ps: >- - If ($env:PHP -eq "1") { - If ($env:php_ver_target -eq "5.6") {$wincache = "1.3.7.12"} Else {$wincache = "2.0.0.8"} + If ($env:PHP -eq "1" -and $env:WINCACHE) { cd c:\tools\php\ext - appveyor-retry appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/wincache/$($wincache)/php_wincache-$($wincache)-$($env:php_ver_target)-nts-$($VC)-$($PHPBuild).zip - 7z x -y php_wincache-$($wincache)-$($env:php_ver_target)-nts-$($VC)-$($PHPBuild).zip > $null + $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 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 - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat - - appveyor-retry appveyor DownloadFile https://getcomposer.org/composer.phar + - IF %PHP%==1 appveyor-retry appveyor DownloadFile https://getcomposer.org/download/latest-1.x/composer.phar - cd C:\projects\joomla-cms - appveyor-retry composer install --no-progress --profile @@ -117,4 +152,4 @@ before_test: test_script: - cd C:\projects\joomla-cms - - libraries/vendor/bin/phpunit -c appveyor-phpunit.xml + - ps: If ($env:php_ver_target -eq "5.6") {libraries/vendor/bin/phpunit -c appveyor-phpunit.xml --exclude-group not-on-windows } Else {libraries/vendor/bin/phpunit -c appveyor-phpunit.xml} diff --git a/.drone.jsonnet b/.drone.jsonnet new file mode 100644 index 0000000000000..319f5754648d4 --- /dev/null +++ b/.drone.jsonnet @@ -0,0 +1,184 @@ +local volumes = [ + { + name: "composer-cache", + path: "/tmp/composer-cache", + }, +]; + +local hostvolumes = [ + { + name: "composer-cache", + host: {path: "/tmp/composer-cache"} + }, +]; + +local composer(phpversion) = { + name: "composer", + image: "joomlaprojects/docker-images:php" + phpversion, + volumes: volumes, + commands: ["php -v", "composer install"] +}; + +local prepare(phpversion) = { + name: "prepare", + image: "joomlaprojects/docker-images:php" + phpversion, + environment: {PGPASSWORD: "joomla_ut"}, + commands: [ + "php -v", + "sleep 20", + "mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < \"tests/unit/schema/mysql.sql\"", + "psql -h postgres -d joomla_ut -U joomla_ut -a -f \"tests/unit/schema/postgresql.sql\"" + ] +}; + +local phpunit(phpversion, ignore_result) = { + name: "PHPUnit", + image: "joomlaprojects/docker-images:php" + phpversion, + [if ignore_result then "failure"]: "ignore", + commands: ["libraries/vendor/bin/phpunit"] +}; + +local pipeline(phpversion, ignore_result) = { + kind: "pipeline", + name: "PHP " + phpversion, + volumes: hostvolumes, + steps: [ + composer(phpversion), + prepare(phpversion), + phpunit(phpversion, ignore_result) + ], + services: [ + { + name: "mysql", + image: "mysql:5.7", + environment: { + MYSQL_USER: "joomla_ut", + MYSQL_PASSWORD: "joomla_ut", + MYSQL_ROOT_PASSWORD: "joomla_ut", + MYSQL_DATABASE: "joomla_ut" + } + }, + { + name: "postgres", + image: "postgres:11-alpine", + ports: [5432], + environment: { + POSTGRES_USER: "joomla_ut", + POSTGRES_PASSWORD: "joomla_ut", + POSTGRES_DB: "joomla_ut" + } + }, + { + name: "memcached", + image: "memcached:alpine" + }, + { + name:"redis", + image: "redis:alpine" + } + ] +}; + +[ + { + kind: "pipeline", + name: "Codequality", + volumes: hostvolumes, + steps: [ + { + name: "composer", + image: "joomlaprojects/docker-images:php7.4", + volumes: volumes, + commands: [ + "php -v", + "composer install", + "composer require phpmd/phpmd" + ] + }, + { + name: "phpcs", + image: "joomlaprojects/docker-images:php7.2", + commands: [ + "php -v", + "libraries/vendor/bin/phpcs --report=full --encoding=utf-8 --extensions=php -p --standard=build/phpcs/Joomla ." + ] + }, + { + name: "javascript", + image: "joomlaprojects/docker-images:systemtests", + commands: [ + "echo $(date)", + "export DISPLAY=:0", + "Xvfb -screen 0 1024x768x24 -ac +extension GLX +render -noreset > /dev/null 2>&1 &", + "sleep 3", + "fluxbox > /dev/null 2>&1 &", + "cd tests/javascript", + "npm install", + "cd ../..", + "tests/javascript/node_modules/karma/bin/karma start karma.conf.js --single-run", + "echo $(date)" + ] + } + ] + }, + pipeline("5.3", false), + pipeline("5.4", false), + pipeline("5.5", false), + pipeline("5.6", false), + pipeline("7.0", false), + pipeline("7.1", false), + pipeline("7.2", false), + pipeline("7.3", false), + pipeline("7.4", false), + pipeline("8.0", true), + { + kind: "pipeline", + name: "package", + steps: [ + { + name: "packager", + image: "joomlaprojects/docker-images:packager", + environment: { + 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", + HTTP_ROOT: "https://ci.joomla.org/artifacts", + DRONE_PULL_REQUEST: "DRONE_PULL_REQUEST", + DRONE_COMMIT: "DRONE_COMMIT", + GITHUB_TOKEN: {from_secret: "github_token"} + }, + commands: [ + "if [ $DRONE_REPO_NAME != 'joomla-cms' ]; then echo \"The packager only runs on the joomla/joomla-cms repo\"; exit 0; fi", + "/bin/drone_build.sh" + ] + } + ] + }, + { + kind: "pipeline", + name: "Rips", + steps: [ + { + name: "analysis3x", + image: "rips/rips-cli:3.2.2", + when: { + repo: ["joomla/joomla-cms", "joomla/cms-security"], + branch: ["3.10-dev"] + }, + commands: [ + "export RIPS_BASE_URI='https://api.rips.joomla.org'", + "rips-cli rips:list --table=scans --parameter filter='{\"__and\":[{\"__lessThan\":{\"percent\":100}}]}'", + "rips-cli rips:scan:start --progress --application=1 --threshold=0 --path=$(pwd) --remove-code --remove-upload --tag=$DRONE_REPO_NAMESPACE-$DRONE_BRANCH || { echo \"Please contact the security team at security@joomla.org\"; exit 1; }" + ], + environment: { + RIPS_EMAIL: {from_secret:"RIPS_EMAIL"}, + RIPS_PASSWORD: {from_secret: "RIPS_PASSWORD"} + } + } + ] + } +] diff --git a/.drone.yml b/.drone.yml index 85f368db19b48..ec83ca28dcc6f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,28 +1,702 @@ -pipeline: - clone: - image: plugins/git - depth: 1 - - phpcs: - image: joomlaprojects/docker-phpcs - commands: - - echo $(date) - - /root/.composer/vendor/bin/phpcs --report=full --extensions=php -p --standard=build/phpcs/Joomla . - - echo $(date) - - javascript: - image: joomlaprojects/docker-systemtests:latest - commands: - - echo $(date) - - apt-get install nodejs npm - - ln -s /usr/bin/nodejs /usr/bin/node - - export DISPLAY=:0 - - Xvfb -screen 0 1024x768x24 -ac +extension GLX +render -noreset > /dev/null 2>&1 & - - sleep 3 - - fluxbox > /dev/null 2>&1 & - - cd tests/javascript - - npm install - - cd ../.. - - tests/javascript/node_modules/karma/bin/karma start karma.conf.js --single-run - - echo $(date) +--- +kind: pipeline +name: Codequality +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php7.4 + commands: + - php -v + - git config --global url."git://".insteadOf https:// + - git config --global url."ssh://".insteadOf https:// + - composer install + - composer require phpmd/phpmd + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: phpcs + image: joomlaprojects/docker-images:php7.2 + commands: + - php -v + - libraries/vendor/bin/phpcs --report=full --encoding=utf-8 --extensions=php -p --standard=build/phpcs/Joomla . + +- name: javascript + image: joomlaprojects/docker-images:systemtests + commands: + - echo $(date) + - export DISPLAY=:0 + - Xvfb -screen 0 1024x768x24 -ac +extension GLX +render -noreset > /dev/null 2>&1 & + - sleep 3 + - fluxbox > /dev/null 2>&1 & + - cd tests/javascript + - npm install + - cd ../.. + - tests/javascript/node_modules/karma/bin/karma start karma.conf.js --single-run + - echo $(date) + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 5.3 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php5.3 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php5.3 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php5.3 + commands: + - libraries/vendor/bin/phpunit + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 5.4 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php5.4 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php5.4 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php5.4 + commands: + - libraries/vendor/bin/phpunit + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 5.5 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php5.5 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php5.5 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php5.5 + commands: + - libraries/vendor/bin/phpunit + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 5.6 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php5.6 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php5.6 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php5.6 + commands: + - libraries/vendor/bin/phpunit + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 7.0 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php7.0 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php7.0 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php7.0 + commands: + - libraries/vendor/bin/phpunit + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 7.1 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php7.1 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php7.1 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php7.1 + commands: + - libraries/vendor/bin/phpunit + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 7.2 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php7.2 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php7.2 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php7.2 + commands: + - libraries/vendor/bin/phpunit + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 7.3 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php7.3 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php7.3 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php7.3 + commands: + - libraries/vendor/bin/phpunit + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 7.4 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php7.4 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php7.4 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php7.4 + commands: + - libraries/vendor/bin/phpunit + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: PHP 8.0 + +platform: + os: linux + arch: amd64 + +steps: +- name: composer + image: joomlaprojects/docker-images:php8.0 + commands: + - php -v + - composer install + volumes: + - name: composer-cache + path: /tmp/composer-cache + +- name: prepare + image: joomlaprojects/docker-images:php8.0 + commands: + - php -v + - sleep 20 + - mysql --host=mysql --user=joomla_ut --password=joomla_ut --database=joomla_ut < "tests/unit/schema/mysql.sql" + - psql -h postgres -d joomla_ut -U joomla_ut -a -f "tests/unit/schema/postgresql.sql" + environment: + PGPASSWORD: joomla_ut + +- name: PHPUnit + image: joomlaprojects/docker-images:php8.0 + commands: + - libraries/vendor/bin/phpunit + failure: ignore + +services: +- name: mysql + image: mysql:5.7 + environment: + MYSQL_DATABASE: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_USER: joomla_ut + +- name: postgres + image: postgres:11-alpine + environment: + POSTGRES_DB: joomla_ut + POSTGRES_PASSWORD: joomla_ut + POSTGRES_USER: joomla_ut + ports: + - 5432 + +- name: memcached + image: memcached:alpine + +- name: redis + image: redis:alpine + +volumes: +- name: composer-cache + host: + path: /tmp/composer-cache + +--- +kind: pipeline +name: package + +platform: + os: linux + arch: amd64 + +steps: +- name: packager + image: joomlaprojects/docker-images:packager + commands: + - if [ $DRONE_REPO_NAME != 'joomla-cms' ]; then echo "The packager only runs on the joomla/joomla-cms repo"; exit 0; fi + - /bin/drone_build.sh + environment: + DRONE_COMMIT: DRONE_COMMIT + DRONE_PULL_REQUEST: DRONE_PULL_REQUEST + FTP_DEST_DIR: /artifacts + FTP_HOSTNAME: ci.joomla.org + FTP_PASSWORD: + from_secret: ftppassword + FTP_PORT: 21 + FTP_SECURE: true + FTP_USERNAME: + from_secret: ftpusername + FTP_VERIFY: false + GITHUB_TOKEN: + from_secret: github_token + HTTP_ROOT: https://ci.joomla.org/artifacts + +--- +kind: signature +hmac: 3c5994d3c3278a6443da81dbed98b9f3d0abfdfa1dba4c1f20a2372bb6c3cfa5 + +... diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000..2a99737fc49e9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000000..a9411d8f2b773 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,50 @@ +# Custom Fields +administrator/components/com_fields/* @laoneo +components/com_fields/* @laoneo +plugins/content/fields/* @laoneo +plugins/editors-xtd/fields/* @laoneo +plugins/fields/* @laoneo +plugins/systems/fields/* @laoneo + +# Smart Search +#administrator/components/com_finder/* +#components/com_finder/* +#modules/mod_finder/* +#plugins/content/finder/* +#plugins/finder/* + +# CodeMirror +media/editors/codemirror/* @okonomiyaki3000 +plugins/editors/codemirror/* @okonomiyaki3000 + +# Statistics Server +plugins/system/stats/* @wilsonge + +# Release Tools +build.xml @wilsonge +build/build.php @rdeutz @wilsonge +build/bump.php @rdeutz @wilsonge +build/deleted_file_check.php @rdeutz @wilsonge + +# Core/Extension Install/Update Tools +administrator/components/com_joomlaupdate/* @rdeutz @wilsonge @zero-24 +libraries/src/Installer/* @rdeutz @wilsonge @zero-24 +libraries/src/Updater/* @rdeutz @wilsonge @zero-24 + +# Automated Testing +build/jenkins/* @rdeutz +build/travis/* @rdeutz +tests/codeception/* @rdeutz +tests/javascript/* @wilsonge @rdeutz +tests/unit/* @rdeutz +.appveyor.yml @rdeutz +.drone.yml @rdeutz +.hound.yml @wilsonge +.travis.yml @rdeutz +appveyor-phpunit.xml @rdeutz +codeception.yml @rdeutz +karma.conf.js @wilsonge @rdeutz +phpunit.xml.dist @rdeutz +RoboFile.dist.ini @rdeutz +RoboFile.php @rdeutz +travis-phpunit.xml @rdeutz diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a569407e7d792..1a821a0882411 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,7 +6,7 @@ You are welcome to submit a contribution for review and possible inclusion in th 2) Follow the [Joomla! Coding Standards](https://developer.joomla.org/coding-standards.html). -3) When filing an issue or opening a PR, please include a clear title and description. The title should be a short summary of an issue and, if possible, should include a reference to an open issue. For example, `Invalid Query in com_admin (Ref #1234)` would be sufficient. All issues and PRs should include a description with as much detail as possible. +3) When filing an issue or opening a PR, please include a clear title and description. The title should be a short summary of an issue and, if possible, should include a reference to an open issue. For example, `Invalid Query in com_admin (Ref #1234)` would be sufficient. All issues and PRs should include a description with as much detail as possible. If it is a PR, include what the issue is, what the PR is addressing, testing instructions and environmental information (PHP version, database driver and version, and other data you can retrieve from your site's system information view) in case the issue is specific to certain environments. If additional information is needed, please be prepared to provide it as our community members review your submission. 4) Report security issues to the Joomla! Security Strike Team (JSST) at security@joomla.org or use the [JSST contact form](https://developer.joomla.org/contact-security-team.html). Please do not use the public tracker for security issues. @@ -14,12 +14,11 @@ If it is a PR, include what the issue is, what the PR is addressing, testing ins Please be patient as not all items will be tested immediately (remember, all bug testing for the Joomla! CMS is done by volunteers) and be receptive to feedback about your code. #### Branches -PRs should usually be made to the `staging` branch as this contains the most recent version of the code. +PRs should usually be made to the `4.1-dev` branch as this contains the most recent version of the code. There are other branches available which serve specific purposes. | Branch | Purpose | | ------ | ------- | -| staging | Current codebase. Branch for the next minor Joomla version. New backward compatible features go into this branch. | -| master | Each commit made to staging gets tested if it passes unit tests and codestyle rules. It is then merged into master. This is done automatically. | -| 3.8-dev | Branch for the next minor Joomla version. The 3.8.0 release will only include compatibility features for 4.0. Commits to staging will be applied to this branch as well. | -| 4.0-dev | Branch for the next major Joomla version. New features go into this branch. Commits to staging will be applied to this branch as well. | +| 3.10-dev | Branch for the Joomla 3.x series. The 3.10 series release will only include compatibility features for 4.x as well as bugfixes and security patches. | +| 4.1-dev | Branch for the current minor Joomla version. Commits to 3.10-dev will be applied to this branch as well. | +| 4.2-dev | Branch for the next minor Joomla version. New features go into this branch. Commits to 4.1-dev will be applied to this branch as well. | diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000000..1914e099bd843 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: joomla +custom: https://community.joomla.org/sponsorship-campaigns.html diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md new file mode 100644 index 0000000000000..f234699b23618 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -0,0 +1,23 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +### Steps to reproduce the issue + + + +### Expected result + + + +### Actual result + + + +### System information (as much as possible) + + + +### Additional comments diff --git a/.github/ISSUE_TEMPLATE/Custom.md b/.github/ISSUE_TEMPLATE/Custom.md new file mode 100644 index 0000000000000..1c32a221edc25 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Custom.md @@ -0,0 +1,16 @@ +--- +name: Fix this template +about: Suggest a fix it + +--- + +### What needs to be fixed + + +### Why this should be fixed + + +### How would you fix it + + +### Side Effects expected diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md new file mode 100644 index 0000000000000..e853c4610a791 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -0,0 +1,15 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +### Is your feature request related to a problem? Please describe. + + + +### Describe the solution you'd like + + + +### Additional context diff --git a/.github/ISSUE_TEMPLATE/Security.md b/.github/ISSUE_TEMPLATE/Security.md new file mode 100644 index 0000000000000..d7ff7ea26e670 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Security.md @@ -0,0 +1,11 @@ +--- +name: Security +about: Report a security issue + +--- + +Security issues should **NOT** be reported on this repository. + +If you believe you have found a security issue, please contact the Joomla Security Strike Team via email at security@joomla.org or through the contact form at https://developer.joomla.org/security/contact-the-team.html. + +Please see https://developer.joomla.org/security.html for more information on how the Joomla project responds to security issues. diff --git a/.github/ISSUE_TEMPLATE/rfc.md b/.github/ISSUE_TEMPLATE/rfc.md new file mode 100644 index 0000000000000..1d1f75c3c8b11 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/rfc.md @@ -0,0 +1,13 @@ +--- +name: Start a Request for Comment +about: Start a Request for Comment discussion + +--- + +### Problem identified + + +### Proposed solution + + +### Open questions diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f4fe8a2a74159..32e34f654da80 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,11 +8,11 @@ Pull Request for Issue # . -### Expected result +### Actual result BEFORE applying this Pull Request -### Actual result +### Expected result AFTER applying this Pull Request diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000000000..01c59d2e40a74 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,37 @@ +# Security Policies and Procedures + +This document outlines security procedures and policies for the `Joomla! Project`. + + * [Reporting a Bug](#reporting-a-bug) + * [Response Handling](#response-handling) + * [Security Announcement Policy](#security-announcement-policy) + * [Further Details on the Joomla! Security Policies](https://security.joomla.org) + +## Reporting a Bug + +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 + +We maintain a list of [GPG keys and addresses](https://developer.joomla.org/security/gpg-keys.html) for the security@joomla.org address and members of the JSST to allow signed and encrypted communications. + +To report an issue in a Joomla! extension, please submit it to the [Vulnerable Extensions List.](https://vel.joomla.org/submit-vel) + +For support with a site which has been attacked, please visit the [Joomla! Forum.](https://forum.joomla.org/viewforum.php?f=714) + +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. 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 + * the issue is closed (and why) + * the issue is still under investigation; if needed, additional information will be requested +* Within 21 days every report must be resolved unless there are exceptional circumstances requiring additional time + +## Security Announcement Policy +* Verified vulnerabilities will only be publicly announced AFTER a release is issued which fixes the vulnerability. +* All announcements will contain as much information as possible, but will NOT contain step-by-step instructions for the vulnerability. +* The `Joomla! Project` will properly credit individuals and/or organizations who responsibly disclose security issues to the JSST. You can indicate the way you would like to be referred to in the advisory about the vulnerability. Our preference is to use full names. If you do not specify then we will use the contact name associated with the email address the report was received from. You can also request a pseudonym or having your name withheld. diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000000000..a6a7ed25eeaee --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,8 @@ +Where can you get support and help? +==================== +* [The Joomla! Documentation](https://docs.joomla.org/Special:MyLanguage/Main_Page). +* [Frequently Asked Questions](https://docs.joomla.org/Special:MyLanguage/Category:FAQ) (FAQ). +* Find the [information you need](https://docs.joomla.org/Special:MyLanguage/Start_here). +* Find [help and other users](https://www.joomla.org/about-joomla/create-and-share.html). +* Post questions at [our forums](https://forum.joomla.org). +* [Joomla Resources Directory](https://community.joomla.org/service-providers-directory/) (JRD). diff --git a/.github/workflows/cacert-update.yml b/.github/workflows/cacert-update.yml new file mode 100644 index 0000000000000..33efb33bd6354 --- /dev/null +++ b/.github/workflows/cacert-update.yml @@ -0,0 +1,38 @@ +name: Cron to update Mozilla CaCert files in the Joomla Core + +on: + workflow_dispatch: + schedule: + # * is a special character in YAML so you have to quote this string + # Runs on the first day of every month at 03:00 + - cron: '0 3 1 * *' + +jobs: + build: + if: (github.event_name == 'schedule' && github.repository == 'joomla/joomla-cms') || (github.event_name != 'schedule') + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + ref: 3.10-dev + + - name: Download the latest cacert file + uses: wei/wget@v1 + with: + args: -O libraries/src/Http/Transport/cacert.pem https://curl.se/ca/cacert.pem + + - name: Copy the cacert file to the FOF repo + run: cp "libraries/src/Http/Transport/cacert.pem" "libraries/fof/download/adapter/cacert.pem" + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + id: cpr + with: + branch: mozilla_ca_update + + - name: Log resulting Pull Request + run: | + echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" + echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" diff --git a/.gitignore b/.gitignore index fe2b19d07b093..a95bc8a723aed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ # IDE & System Related Files # .buildpath -.editorconfig .project .settings .DS_Store @@ -12,6 +11,8 @@ /administrator/logs /cache /installation/cache +/installation/sessions +/libraries/autoload_psr4.php /tmp /configuration.php /.htaccess @@ -21,6 +22,9 @@ # Test Related Files # /phpunit.xml +# Stubs file holding mapped classes +/stubs.php + # Node modules # node_modules/ @@ -34,6 +38,7 @@ phpdoc-* /media/com_patchtester # Install from Web plugin # +/media/plg_installer_webinstaller /plugins/installer/webinstaller # Languages # @@ -65,23 +70,49 @@ Desktop.ini # Extra files installed by Composer not needed in the CMS environment # This should only ignore files like unit testing or READMEs, production # code must remain to ensure all libraries properly function +/libraries/vendor/bin +/libraries/vendor/brumann/polyfill-unserialize/.gitattributes +/libraries/vendor/brumann/polyfill-unserialize/.gitignore +/libraries/vendor/brumann/polyfill-unserialize/.travis.yml +/libraries/vendor/brumann/polyfill-unserialize/composer.json +/libraries/vendor/brumann/polyfill-unserialize/composer.lock +/libraries/vendor/brumann/polyfill-unserialize/LICENSE +/libraries/vendor/brumann/polyfill-unserialize/phpunit.xml.dist +/libraries/vendor/brumann/polyfill-unserialize/README.md +/libraries/vendor/brumann/polyfill-unserialize/tests +/libraries/vendor/google/recaptcha/examples +/libraries/vendor/google/recaptcha/tests +/libraries/vendor/google/recaptcha/.gitignore +/libraries/vendor/google/recaptcha/.travis.yml +/libraries/vendor/google/recaptcha/composer.json +/libraries/vendor/google/recaptcha/CONTRIBUTING.md +/libraries/vendor/google/recaptcha/phpunit.xml.dist +/libraries/vendor/google/recaptcha/README.md /libraries/vendor/ircmaxell/password-compat/test /libraries/vendor/ircmaxell/password-compat/.travis.yml /libraries/vendor/ircmaxell/password-compat/composer.json /libraries/vendor/ircmaxell/password-compat/phpunit.xml.dist /libraries/vendor/ircmaxell/password-compat/README.md /libraries/vendor/ircmaxell/password-compat/version-test.php +/libraries/vendor/joomla/*/.gitattributes /libraries/vendor/joomla/*/.github /libraries/vendor/joomla/*/.gitignore /libraries/vendor/joomla/*/.gitmodules +/libraries/vendor/joomla/*/.drone.jsonnet +/libraries/vendor/joomla/*/.drone.yml /libraries/vendor/joomla/*/docs /libraries/vendor/joomla/*/Tests /libraries/vendor/joomla/*/vendor +/libraries/vendor/joomla/*/.scrutinizer.yml /libraries/vendor/joomla/*/.travis.yml +/libraries/vendor/joomla/*/.mono /libraries/vendor/joomla/*/CONTRIBUTING.md /libraries/vendor/joomla/*/composer.json /libraries/vendor/joomla/*/phpunit.xml.dist /libraries/vendor/joomla/*/README.md +/libraries/vendor/joomla/*/ruleset.xml +/libraries/vendor/joomla/session/Joomla/Session/.drone.jsonnet +/libraries/vendor/joomla/session/Joomla/Session/.drone.yml /libraries/vendor/joomla/session/Joomla/Session/.github /libraries/vendor/joomla/session/Joomla/Session/_Tests /libraries/vendor/joomla/session/Joomla/Session/build @@ -90,14 +121,18 @@ Desktop.ini /libraries/vendor/joomla/session/Joomla/Session/composer.json /libraries/vendor/joomla/session/Joomla/Session/phpunit.xml.dist /libraries/vendor/joomla/session/Joomla/Session/README.md +/libraries/vendor/joomla/session/Joomla/Session/ruleset.xml /libraries/vendor/leafo/lessphp/docs /libraries/vendor/leafo/lessphp/tests +/libraries/vendor/leafo/lessphp/.drone.yml /libraries/vendor/leafo/lessphp/.gitignore /libraries/vendor/leafo/lessphp/.travis.yml /libraries/vendor/leafo/lessphp/composer.json /libraries/vendor/leafo/lessphp/Makefile /libraries/vendor/leafo/lessphp/package.sh +/libraries/vendor/leafo/lessphp/phpunit.xml.dist /libraries/vendor/leafo/lessphp/README.md +/libraries/vendor/leafo/lessphp/ruleset.xml /libraries/vendor/paragonie/random_compat/.gitignore /libraries/vendor/paragonie/random_compat/.scrutinizer.yml /libraries/vendor/paragonie/random_compat/.travis.yml @@ -113,30 +148,64 @@ Desktop.ini /libraries/vendor/paragonie/random_compat/psalm-autoload.php /libraries/vendor/paragonie/random_compat/psalm.xml /libraries/vendor/paragonie/random_compat/tests +/libraries/vendor/paragonie/sodium_compat/.gitignore +/libraries/vendor/paragonie/sodium_compat/.github +/libraries/vendor/paragonie/sodium_compat/appveyor.yml +/libraries/vendor/paragonie/sodium_compat/build-phar.sh +/libraries/vendor/paragonie/sodium_compat/composer.json +/libraries/vendor/paragonie/sodium_compat/composer-php52.json +/libraries/vendor/paragonie/sodium_compat/composer.lock +/libraries/vendor/paragonie/sodium_compat/dist +/libraries/vendor/paragonie/sodium_compat/phpunit.xml.dist +/libraries/vendor/paragonie/sodium_compat/psalm-above-3.xml +/libraries/vendor/paragonie/sodium_compat/psalm-below-3.xml +/libraries/vendor/paragonie/sodium_compat/README.md +/libraries/vendor/paragonie/sodium_compat/src/Core/Curve25519/README.md /libraries/vendor/phpmailer/phpmailer/docs /libraries/vendor/phpmailer/phpmailer/examples /libraries/vendor/phpmailer/phpmailer/language /libraries/vendor/phpmailer/phpmailer/test +/libraries/vendor/phpmailer/phpmailer/SECURITY.md +/libraries/vendor/phpmailer/phpmailer/.github +/libraries/vendor/phpmailer/phpmailer/.gitattributes /libraries/vendor/phpmailer/phpmailer/.gitignore /libraries/vendor/phpmailer/phpmailer/.scrutinizer.yml /libraries/vendor/phpmailer/phpmailer/.travis.yml /libraries/vendor/phpmailer/phpmailer/changelog.md /libraries/vendor/phpmailer/phpmailer/composer.json +/libraries/vendor/phpmailer/phpmailer/composer.lock +/libraries/vendor/phpmailer/phpmailer/ISSUE_TEMPLATE.md +/libraries/vendor/phpmailer/phpmailer/phpdoc.dist.xml /libraries/vendor/phpmailer/phpmailer/README.md /libraries/vendor/phpmailer/phpmailer/travis.phpunit.xml.dist +/libraries/vendor/phpmailer/phpmailer/UPGRADING.md /libraries/vendor/phpmailer/phpmailer/extras/README.md /libraries/vendor/phpmailer/phpmailer/get_oauth_token.php +/libraries/vendor/psr/container/.gitignore +/libraries/vendor/psr/container/composer.json +/libraries/vendor/psr/container/README.md /libraries/vendor/psr/log/Psr/Log/Test /libraries/vendor/psr/log/.gitignore /libraries/vendor/psr/log/composer.json /libraries/vendor/psr/log/README.md +/libraries/vendor/symfony/polyfill-ctype/composer.json +/libraries/vendor/symfony/polyfill-ctype/README.md /libraries/vendor/symfony/polyfill-php55/composer.json /libraries/vendor/symfony/polyfill-php55/README.md /libraries/vendor/symfony/polyfill-php56/composer.json /libraries/vendor/symfony/polyfill-php56/README.md +/libraries/vendor/symfony/polyfill-php71/composer.json +/libraries/vendor/symfony/polyfill-php71/README.md +/libraries/vendor/symfony/polyfill-php73/composer.json +/libraries/vendor/symfony/polyfill-php73/README.md /libraries/vendor/symfony/polyfill-util/composer.json /libraries/vendor/symfony/polyfill-util/README.md +/libraries/vendor/symfony/polyfill-util/LegacyTestListener.php /libraries/vendor/symfony/polyfill-util/TestListener.php +/libraries/vendor/symfony/polyfill-util/TestListenerTrait.php +/libraries/vendor/symfony/polyfill-util/TestListenerForV5.php +/libraries/vendor/symfony/polyfill-util/TestListenerForV6.php +/libraries/vendor/symfony/polyfill-util/TestListenerForV7.php /libraries/vendor/symfony/yaml/Tests /libraries/vendor/symfony/yaml/.gitignore /libraries/vendor/symfony/yaml/CHANGELOG.md @@ -153,3 +222,27 @@ Desktop.ini /libraries/vendor/simplepie/simplepie/build /libraries/vendor/simplepie/simplepie/idn/ReadMe.txt /libraries/vendor/simplepie/simplepie/composer.json +/libraries/vendor/typo3/phar-stream-wrapper/tests +/libraries/vendor/typo3/phar-stream-wrapper/.appveyor.yml +/libraries/vendor/typo3/phar-stream-wrapper/.gitattributes +/libraries/vendor/typo3/phar-stream-wrapper/.gitignore +/libraries/vendor/typo3/phar-stream-wrapper/.travis.yml +/libraries/vendor/typo3/phar-stream-wrapper/composer.json +/libraries/vendor/typo3/phar-stream-wrapper/LICENSE +/libraries/vendor/typo3/phar-stream-wrapper/phpunit.xml +/libraries/vendor/typo3/phar-stream-wrapper/README.md + +# System Test related files +tests/codeception/acceptance.suite.yml +tests/codeception/_support/_generated/*TesterActions.php +tests/codeception/joomla-cms* +tests/codeception/_output* +selenium-server-standalone.jar +selenium.log +tests/codeception/cache +tests/codeception/_output +tests/codeception/vendor +composer.phar + +# Build related +RoboFile.ini diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 14dae27f2374f..0000000000000 --- a/.travis.yml +++ /dev/null @@ -1,43 +0,0 @@ -# Forces new Travis-CI Infrastructure -sudo: false - -language: php - -env: - global: - - RUN_UNIT_TESTS="yes" - - INSTALL_MEMCACHE="yes" - - INSTALL_MEMCACHED="yes" - - INSTALL_REDIS="yes" - -matrix: - fast_finish: true - include: - - php: 7.0 - env: INSTALL_APCU="yes" INSTALL_APCU_BC_BETA="no" INSTALL_MEMCACHE="no" INSTALL_MEMCACHED="no" INSTALL_REDIS="no" # Disabled apcu_bc install until https://github.com/travis-ci/travis-ci/issues/5207 is resolved - - php: 7.1 - env: INSTALL_APCU="yes" INSTALL_APCU_BC_BETA="no" INSTALL_MEMCACHE="no" INSTALL_MEMCACHED="no" INSTALL_REDIS="no" # Disabled apcu_bc install until https://github.com/travis-ci/travis-ci/issues/5207 is resolved - - php: 5.3 - env: INSTALL_APC="yes" - - php: 5.4 - env: INSTALL_APC="yes" - - php: 5.5 - env: INSTALL_APCU="yes" - - php: 5.6 - env: INSTALL_APCU="yes" - -services: - - memcache - - memcached - - redis-server - -before_script: - # Make sure all dev dependencies are installed - - if [[ $RUN_UNIT_TESTS == "yes" ]]; then bash build/travis/unit-tests.sh $PWD; fi - -script: - - if [[ $RUN_UNIT_TESTS == "yes" ]]; then libraries/vendor/bin/phpunit --configuration travisci-phpunit.xml; fi - -branches: - except: - - 2.5.x diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000000..42c3562bfdfdc --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,62 @@ +# Joomla Contributor Covenant Code of Conduct + +This document outlines the Code of Conduct for all persons volunteering their service to the Joomla Project and/or Open Source Matters. It covers your behaviour as a member of the Joomla community, in any forum, mailing list, Wiki, Web site, IRC channel, install-fest, public meeting or private correspondence. + +If you cannot agree to any of these principles, then volunteering in the Joomla Project is not for you. Contributing to our community assumes acceptance of these principles: +## Be Considerate + +You are working with others as a team so be considerate of how your actions or contribution affects your colleagues and the community as a whole. +## Be Respectful + +Treat one another and members of the community with respect. Everyone can make a valuable contribution to Joomla. We may not always agree, but disagreement is no excuse for poor behavior or poor manners. + +We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It's important to remember that a community where people feel uncomfortable or threatened is not a productive one. We expect the members of Joomla community to be respectful when dealing with other volunteers as well as with people from outside projects and initiatives and with users. + +Avoid becoming involved in flame wars, trolling, personal attacks, and repetitive arguments. Take the matters "outside" (off-list, etc) if it helps resolve the situation, and do not use communal methods of communication to be a vehicle for your private "wall of shame." +## Be Collaborative + +Joomla is free software and about collaboration and working together. Collaboration reduces redundancy of work done in the free software world, and improves the quality of the software produced regardless of whether you are writing code or performing some other task. + +When you disagree, consult others. Disagreements, both political and technical, happen all the time, and Joomla is no exception. Disagreement, debate and constructive criticism is often how progress is made and are a necessary part of doing complex work in a team. + +The important goal is not to avoid disagreements or differing views but to resolve them constructively. Above all, avoid making conflicts about the work into personal conflicts. Debate should never include reference to someone's nationality, gender, religion or other personal characteristics. + +You should turn to the community and to the community process to seek advice and to resolve disagreements. Team leaders and Department Coordinators are able to help you figure out which direction will be most acceptable. + +When you are unsure, ask for help. Nobody knows everything and nobody is expected to be perfect. Asking questions avoids many problems down the road and so questions are encouraged. Those who are asked should be responsive and helpful. However, when asking a question, care must be taken to do so in an appropriate forum. Off-topic questions, such as requests for help on a development mailing list, detract from productive discussion. +## Step Down Considerately + +People on every project come and go, and Joomla is no different. When you leave or disengage from the community, in whole or in part, we ask that you do so in a way that minimizes disruption to the Project. This means you should tell people you are leaving and take the proper steps to ensure that others can pick up where you leave off. +## Be Available + +Check your e-mails regularly and answer them promptly—even if it's "I'll get back to you." +## Be Honest + +Sometimes the hardest thing to say is "no" or admit you've forgotten to do something. Be honest with each other and yourself with regards to what you say and what you can realistically commit to. +## Follow the Rules + +Volunteers are expected to uphold Joomla's licensing and trademark requirements including, but not limited to, compliance on their own or affiliate Web sites and extensions. Make sure you have sought the appropriate approvals for domain name, name and logo usage prior to volunteering and that any extensions you distribute comply with the Joomla license. + +All work contributed to the Project, whether code, documentation or other material, must observe the appropriate licenses as set down by the Core Team and Open Source Matters. + +Some contributors represent the Joomla Project in specific areas, but you should not speak on behalf of the Project or present yourself as an official representative of the Project unless you are specifically authorized to do so, and you should never state your opinions as the official policies of the Project. +## Exercise Discretion and Confidentiality at Appropriate Times + +Depending on your role, you will be privy to various levels of information. As a volunteer you are expected to keep site access details (such as logins, FTP details, etc.) secure at all times. + +Information contained within private forums (for example, about serious security matters, legal cases, or personal details), private mailing lists, chats or other mediums is also to be kept confidential even after you have discontinued your service. Breaches in the area of privacy and confidentiality are taken very seriously by the Project. +## Conflict of Interest + +When using Project resources or making decisions within the board, your department, team, or subteam or the concerning Project's policy positions, you must do so based only on the best interests of the Project and its user community. If you have a situation or affiliation that might constitute or lead to a conflict of interest or might be perceived by a reasonable person in the community to be a conflict of interest, disclose this to your Team Leaders or the team as a whole. If appropriate, after discussing with your team, you should remove yourself from specific decisions or discussions in which you may have a conflict of interest. +## Conflict Resolution Team + +Should you wish to make a CoC violation report or are facing a conflict that has failed to be resolved in the manner set out in this CoC, please [click here](https://docs.google.com/forms/d/e/1FAIpQLSea_VL9NUvUM3iX-gptNuJe5oz5-jp9y5Y4v9ZyKImblfYTcQ/viewform) to access the report form. +## The Fine Print + +Members of the board of Open Source Matters are governed by additional guidelines and requirements and, where a conflict exists, these take precedence over this Code of Conduct. +## The Last Bit + +This Code of Conduct has changed over time and will continue to develop, but was originally derived, with permission, from the Ubuntu CoC. + +Last Updated 8th of June 2017 +Online version of this document is available at https://www.joomla.org/about-joomla/the-project/code-of-conduct.html diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000000000..5b7fd8f3ce9e2 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,75 @@ +#!groovy + +pipeline { + agent any + + stages { + + stage('codestyles') { + agent { + docker 'joomlaprojects/docker-phpcs' + } + steps { + sh '/usr/local/vendor/bin/phpcs --report=full --extensions=php -p --standard=build/phpcs/Joomla .' + } + } + + stage("Testing PHP") { + steps { + // You can only use the parallel step if it's the *only* step in the stage. + parallel( + PHP53: { + sh 'export PHPVERSION=php53;/usr/local/bin/docker-compose --project-name php53-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml run --rm test bash build/jenkins/unit-tests.sh' + }, + PHP54: { + sh 'export PHPVERSION=php54;/usr/local/bin/docker-compose --project-name php54-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml run --rm test bash build/jenkins/unit-tests.sh' + }, + PHP55: { + sh 'export PHPVERSION=php55;/usr/local/bin/docker-compose --project-name php55-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml run --rm test bash build/jenkins/unit-tests.sh' + }, + PHP56: { + sh 'export PHPVERSION=php56;/usr/local/bin/docker-compose --project-name php56-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml run --rm test bash build/jenkins/unit-tests.sh' + }, + PHP70: { + sh 'export PHPVERSION=php70;/usr/local/bin/docker-compose --project-name php70-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml run --rm test bash build/jenkins/unit-tests.sh' + }, + PHP71: { + sh 'export PHPVERSION=php71;/usr/local/bin/docker-compose --project-name php71-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml run --rm test bash build/jenkins/unit-tests.sh' + } + ) + } + post { + always { + // Spin down containers no matter what happens + sh 'export PHPVERSION=php53;/usr/local/bin/docker-compose --project-name php53-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml down' + sh 'export PHPVERSION=php54;/usr/local/bin/docker-compose --project-name php54-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml down' + sh 'export PHPVERSION=php55;/usr/local/bin/docker-compose --project-name php55-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml down' + sh 'export PHPVERSION=php56;/usr/local/bin/docker-compose --project-name php56-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml down' + sh 'export PHPVERSION=php70;/usr/local/bin/docker-compose --project-name php70-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml down' + sh 'export PHPVERSION=php71;/usr/local/bin/docker-compose --project-name php71-$BRANCH_NAME-$BUILD_NUMBER -f build/jenkins/docker-compose.yml down' + } + } + } + + stage('Testing-Javascript') { + agent { + docker { + image 'joomlaprojects/docker-systemtests' + args '--user 0' + } + } + steps { + sh ''' + ln -s /usr/bin/nodejs /usr/bin/node && \ + export DISPLAY=:0 && \ + (Xvfb -screen 0 1024x768x24 -ac +extension GLX +render -noreset &) && \ + sleep 3 && \ + (fluxbox &) && \ + cd tests/javascript && npm install --no-optional && cd ../.. && \ + tests/javascript/node_modules/karma/bin/karma start karma.conf.js --single-run + ''' + } + } + } + +} diff --git a/README.md b/README.md index 2b631d9f72d89..a6bb987ceca3f 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,16 @@ Joomla! CMS™ [![Analytics](https://ga-beacon.appspot.com/UA-544070-3/joomla-cm Build Status --------------------- -Travis-CI: [![Build Status](https://travis-ci.org/joomla/joomla-cms.svg?branch=staging)](https://travis-ci.org/joomla/joomla-cms) - -Drone -CI: [![Build Status](http://213.160.72.75/api/badges/joomla/joomla-cms/status.svg)](http://213.160.72.75/joomla/joomla-cms) - -AppVeyor: [![Build status](https://ci.appveyor.com/api/projects/status/bpcxulw6nnxlv8kb/branch/staging?svg=true)](https://ci.appveyor.com/project/joomla/joomla-cms) - -Jenkins: [![Build Status](http://build.joomla.org/job/cms/badge/icon)](http://build.joomla.org/job/cms/) +| Drone-CI | AppVeyor | +| ------------- | ------------- | +| [![Build Status](https://ci.joomla.org/api/badges/joomla/joomla-cms/status.svg)](https://ci.joomla.org/joomla/joomla-cms) | [![Build status](https://ci.appveyor.com/api/projects/status/ru6sxal8jmfckvjc/branch/3.10-dev?svg=true)](https://ci.appveyor.com/project/release-joomla/joomla-cms) | What is this? --------------------- * This is a Joomla! 3.x installation/upgrade package. * Joomla's [Official website](https://www.joomla.org). -* Joomla! 3.7 [version history](https://docs.joomla.org/Special:MyLanguage/Joomla_3.7_version_history). -* Detailed changes are in the [changelog](https://github.com/joomla/joomla-cms/commits/master). +* Joomla! 3.10 [version history](https://docs.joomla.org/Special:MyLanguage/Joomla_3.10_version_history). +* Detailed changes are in the [changelog](https://github.com/joomla/joomla-cms/commits/3.10-dev). What is Joomla? --------------------- @@ -28,7 +24,7 @@ Is Joomla! for you? --------------------- * Joomla! is [the right solution for most content web projects](https://docs.joomla.org/Special:MyLanguage/Portal:Learn_More). * View Joomla's [core features here](https://www.joomla.org/core-features.html). -* Try it out for yourself in our [online demo](https://demo.joomla.org). +* Try it out for yourself on our [free hosting service](https://launch.joomla.org). How to find a Joomla! translation? --------------------- @@ -55,7 +51,7 @@ Is it easy to change the layout display? Ready to install Joomla? --------------------- -* Check the [minimum requirements](https://downloads.joomla.org/technical-requirements). +* Check the [minimum requirements](https://downloads.joomla.org/technical-requirements). * How do you [install Joomla](https://docs.joomla.org/Special:MyLanguage/J3.x:Installing_Joomla)? * You could start your Joomla! experience by [building your site on a local test server](https://docs.joomla.org/Special:MyLanguage/Installing_Joomla_locally). When ready, it can be moved to an online hosting account of your choice. @@ -66,12 +62,12 @@ Updates are free! Where can you get support and help? --------------------- -* [The Joomla! Documentation](https://docs.joomla.org/Special:MyLanguage/Main_Page); -* [Frequently Asked Questions](https://docs.joomla.org/Special:MyLanguage/Category:FAQ) (FAQ); -* Find the [information you need](https://docs.joomla.org/Special:MyLanguage/Start_here); -* Find [help and other users](https://www.joomla.org/about-joomla/create-and-share.html); -* Post questions at [our forums](https://forum.joomla.org); -* [Joomla Resources Directory](https://resources.joomla.org/) (JRD). +* [The Joomla! Documentation](https://docs.joomla.org/Special:MyLanguage/Main_Page). +* [Frequently Asked Questions](https://docs.joomla.org/Special:MyLanguage/Category:FAQ) (FAQ). +* Find the [information you need](https://docs.joomla.org/Special:MyLanguage/Start_here). +* Find [help and other users](https://www.joomla.org/about-joomla/create-and-share.html). +* Post questions at [our forums](https://forum.joomla.org). +* [Joomla Resources Directory](https://community.joomla.org/service-providers-directory/) (JRD). Do you already have a Joomla! site that isn't built with Joomla! 3.x? --------------------- @@ -82,15 +78,14 @@ Do you already have a Joomla! site that isn't built with Joomla! 3.x? Do you want to improve Joomla? -------------------- -* Where to [request a feature](https://issues.joomla.org/)? -* How do you [report a bug](https://docs.joomla.org/Special:MyLanguage/Filing_bugs_and_issues) on the [Issue Tracker](https://issues.joomla.org/)? -* Get Involved: Joomla! is community developed software. [Join the community](https://volunteers.joomla.org/). +* Where to [request a feature](https://issues.joomla.org)? +* How do you [report a bug](https://docs.joomla.org/Special:MyLanguage/Filing_bugs_and_issues) on the [Issue Tracker](https://issues.joomla.org)? +* Get Involved: Joomla! is community developed software. [Join the community](https://volunteers.joomla.org). * Documentation for [Developers](https://docs.joomla.org/Special:MyLanguage/Portal:Developers). * Documentation for [Web designers](https://docs.joomla.org/Special:MyLanguage/Web_designers). Copyright --------------------- -* Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. -* [Special Thanks](https://docs.joomla.org/Special:MyLanguage/Joomla!_Credits_and_Thanks) +* Copyright (C) 2005 - 2021 Open Source Matters. All rights reserved. * Distributed under the GNU General Public License version 2 or later * See [License details](https://docs.joomla.org/Special:MyLanguage/Joomla_Licenses) diff --git a/README.txt b/README.txt index a9c9c1789e1cf..b79531f1d1013 100644 --- a/README.txt +++ b/README.txt @@ -1,8 +1,8 @@ 1- What is this? * This is a Joomla! installation/upgrade package to version 3.x * Joomla! Official site: https://www.joomla.org - * Joomla! 3.7 version history - https://docs.joomla.org/Special:MyLanguage/Joomla_3.7_version_history - * Detailed changes in the Changelog: https://github.com/joomla/joomla-cms/commits/master + * Joomla! 3.10 version history - https://docs.joomla.org/Special:MyLanguage/Joomla_3.10_version_history + * Detailed changes in the Changelog: https://github.com/joomla/joomla-cms/commits/3.10-dev 2- What is Joomla? * Joomla! is a Content Management System (CMS) which enables you to build Web sites and powerful online applications. @@ -13,7 +13,7 @@ 3- Is Joomla! for you? * Joomla! is the right solution for most content web projects: https://docs.joomla.org/Special:MyLanguage/Portal:Learn_More * See Joomla's core features - https://www.joomla.org/core-features.html - * Try out our online demo: https://demo.joomla.org/ + * Try out our free hosting service: https://launch.joomla.org 4- How to find a Joomla! translation? * Repository of accredited language packs: https://community.joomla.org/translations.html @@ -50,7 +50,7 @@ * Find the information you need: https://docs.joomla.org/Special:MyLanguage/Start_here * Find help and other users: https://www.joomla.org/about-joomla/create-and-share.html * Post questions at our forums: https://forum.joomla.org - * Joomla! Resources Directory (JRD): https://resources.joomla.org/ + * Joomla! Resources Directory (JRD): https://community.joomla.org/service-providers-directory/ 11- Do you already have a Joomla! site that's not built with Joomla! 3.x ? * What's new in Joomla! 3.x: https://www.joomla.org/3 @@ -59,14 +59,13 @@ * How to migrate from 1.5.x to 3.x? Tutorial: https://docs.joomla.org/Special:MyLanguage/Joomla_1.5_to_3.x_Step_by_Step_Migration 12- Do you want to improve Joomla? - * Where to request a feature? https://issues.joomla.org/ + * Where to request a feature? https://issues.joomla.org * How do you report a bug? https://docs.joomla.org/Special:MyLanguage/Filing_bugs_and_issues - * Get Involved: Joomla! is a community developed software. Join the community at https://volunteers.joomla.org/ + * Get Involved: Joomla! is a community developed software. Join the community at https://volunteers.joomla.org * Documentation for Developers: https://docs.joomla.org/Special:MyLanguage/Portal:Developers * Documentation for Web designers: https://docs.joomla.org/Special:MyLanguage/Web_designers Copyright: - * Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. - * Special Thanks: https://docs.joomla.org/Special:MyLanguage/Joomla!_Credits_and_Thanks + * (C) 2005 Open Source Matters, Inc. * Distributed under the GNU General Public License version 2 or later - * See Licenses details at https://docs.joomla.org/Special:MyLanguage/Joomla_Licenses + * See License details at https://docs.joomla.org/Special:MyLanguage/Joomla_Licenses diff --git a/RoboFile.dist.ini b/RoboFile.dist.ini new file mode 100644 index 0000000000000..ea5cafda52596 --- /dev/null +++ b/RoboFile.dist.ini @@ -0,0 +1,6 @@ +; If you want to setup your test website (document root) in a different folder, you can do that here. +; You can also set an absolute path, i.e. /path/to/my/cms/folder +cmsPath = tests/codeception/joomla-cms + +; (Linux / Mac only) If you want to set a different owner for the CMS root folder, you can set it here. +localUser = diff --git a/RoboFile.php b/RoboFile.php new file mode 100644 index 0000000000000..b3718332dcad5 --- /dev/null +++ b/RoboFile.php @@ -0,0 +1,558 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/** + * This is joomla project's console command file for Robo.li task runner. + * + * Or do: $ composer install, and afterwards you will be able to execute robo like + * $ ./libraries/vendor/bin/robo + * + * @see http://robo.li/ + */ +require_once __DIR__ . '/tests/codeception/vendor/autoload.php'; + +if (!defined('JPATH_BASE')) +{ + define('JPATH_BASE', __DIR__); +} + +/** + * System Test (Codeception) test execution for Joomla! + * + * @package RoboFile + * + * @since 3.7.3 + */ +class RoboFile extends \Robo\Tasks +{ + // Load tasks from composer, see composer.json + use \Joomla\Jorobo\Tasks\loadTasks; + + /** + * Path to the codeception tests folder + * + * @var string + * @since 3.7.3 + */ + private $testsPath = 'tests/codeception/'; + + /** + * Local configuration parameters + * + * @var array + * @since 3.7.3 + */ + private $configuration = array(); + + /** + * @var array | null + * @since 3.7.3 + */ + private $suiteConfig; + + /** + * Path to the local CMS test folder + * + * @var string + * @since 3.7.3 + */ + protected $cmsPath = null; + + /** + * RoboFile constructor. + * + * @since 3.7.3 + */ + public function __construct() + { + $this->configuration = $this->getConfiguration(); + $this->cmsPath = $this->getTestingPath(); + + // Set default timezone (so no warnings are generated if it is not set) + date_default_timezone_set('UTC'); + } + + /** + * Get (optional) configuration from an external file + * + * @since 3.7.3 + * + * @return \stdClass|null + */ + public function getConfiguration() + { + $configurationFile = __DIR__ . '/RoboFile.ini'; + + if (!file_exists($configurationFile)) + { + $this->say('No local configuration file'); + + return null; + } + + $configuration = parse_ini_file($configurationFile); + + if ($configuration === false) + { + $this->say('Local configuration file is empty or wrong (check is it in correct .ini format'); + + return null; + } + + return json_decode(json_encode($configuration)); + } + + /** + * Get the correct CMS root path + * + * @since 3.7.3 + * + * @return string + */ + private function getTestingPath() + { + if (empty($this->configuration->cmsPath)) + { + return $this->testsPath . 'joomla-cms'; + } + + if (!file_exists(dirname($this->configuration->cmsPath))) + { + $this->say('CMS path written in local configuration does not exists or is not readable'); + + return $this->testsPath . 'joomla-cms'; + } + + return $this->configuration->cmsPath; + } + + /** + * Creates a testing Joomla site for running the tests (use it before run:test) + * + * @param bool $useHtaccess (1/0) Rename and enable embedded Joomla .htaccess file + * + * @since 3.7.3 + * + * @return void + */ + public function createTestingSite($useHtaccess = false) + { + // Clean old testing site + if (is_dir($this->cmsPath)) + { + try + { + $this->taskDeleteDir($this->cmsPath)->run(); + } + catch (Exception $e) + { + // Sorry, we tried :( + $this->say('Sorry, you will have to delete ' . $this->cmsPath . ' manually.'); + + exit(1); + } + } + + $exclude = ['tests', 'tests-phpunit', '.run', '.github', '.git']; + + $this->copyJoomla($this->cmsPath, $exclude); + + // Optionally change owner to fix permissions issues + if (!empty($this->configuration->localUser)) + { + $this->_exec('chown -R ' . $this->configuration->localUser . ' ' . $this->cmsPath); + } + + // Optionally uses Joomla default htaccess file. Used by TravisCI + if ($useHtaccess == true) + { + $this->say('Renaming htaccess.txt to .htaccess'); + $this->_copy('./htaccess.txt', $this->cmsPath . '/.htaccess'); + $this->_exec('sed -e "s,# RewriteBase /,RewriteBase /tests/codeception/joomla-cms,g" -in-place tests/codeception/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); + } + + /** + * Downloads Composer + * + * @since 3.7.3 + * + * @return void + */ + private function getComposer() + { + // Make sure we have Composer + if (!file_exists($this->testsPath . 'composer.phar')) + { + $this->_exec('curl -o ' . $this->testsPath . 'composer.phar --retry 3 --retry-delay 5 -sS https://getcomposer.org/installer | php'); + } + } + + /** + * Runs Selenium Standalone Server. + * + * @since 3.7.3 + * + * @return void + */ + public function runSelenium() + { + if (!$this->isWindows()) + { + $this->_exec($this->testsPath . "vendor/bin/selenium-server-standalone " . $this->getWebDriver() . ' >> selenium.log 2>&1 &'); + } + else + { + $this->_exec("START java.exe -jar " . $this->getWebDriver() . ' tests\codeception\vendor\joomla-projects\selenium-server-standalone\bin\selenium-server-standalone.jar '); + } + + sleep(3); + } + + /** + * 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 + * + * @since 3.7.3 + * + * @return mixed + */ + public function runTests($opts = ['use-htaccess' => false, 'env' => 'desktop']) + { + $this->say("Running tests"); + + $this->createTestingSite($opts['use-htaccess']); + + $this->getComposer(); + $this->taskComposerInstall($this->testsPath . 'composer.phar')->run(); + + $this->runSelenium(); + + // Make sure to run the build command to generate AcceptanceTester + if ($this->isWindows()) + { + $this->_exec('php ' . $this->getWindowsPath($this->testsPath . 'vendor/bin/codecept') . ' build'); + $pathToCodeception = $this->getWindowsPath($this->testsPath . 'vendor/bin/codecept'); + } + else + { + $this->_exec('php ' . $this->testsPath . 'vendor/bin/codecept build'); + + $pathToCodeception = $this->testsPath . 'vendor/bin/codecept'; + } + + $this->taskCodecept($pathToCodeception) + ->arg('--steps') + ->arg('--debug') + ->arg('--fail-fast') + ->env($opts['env']) + ->arg($this->testsPath . 'acceptance/install/') + ->run() + ->stopOnFail(); + + $this->taskCodecept() + ->arg('--steps') + ->arg('--debug') + ->arg('--fail-fast') + ->env($opts['env']) + ->arg($this->testsPath . '/acceptance/administrator/components/com_users') + ->run() + ->stopOnFail(); + } + + /** + * 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 + * + * @return void + */ + public function runTest($pathToTestFile = null, $suite = 'acceptance') + { + $this->runSelenium(); + + // Make sure to run the build command to generate AcceptanceTester + $path = 'tests/codeception/vendor/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->testsPath . 'vendor/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(); + $codeceptMainConfig = \Codeception\Configuration::config(); + $browser = $suiteConfig['modules']['config']['JoomlaBrowser']['browser']; + + if ($browser == 'chrome') + { + $driver['type'] = 'webdriver.chrome.driver'; + } + elseif ($browser == 'firefox') + { + $driver['type'] = 'webdriver.gecko.driver'; + } + elseif ($browser == 'MicrosoftEdge') + { + $driver['type'] = 'webdriver.edge.driver'; + + // Check if we are using Windows Insider builds + if ($suiteConfig['modules']['config']['AcceptanceHelper']['MicrosoftEdgeInsiders']) + { + $browser = 'MicrosoftEdgeInsiders'; + } + } + elseif ($browser == 'internet explorer') + { + $driver['type'] = 'webdriver.ie.driver'; + } + + // Check if we have a path for this browser and OS in the codeception settings + if (isset($codeceptMainConfig['webdrivers'][$browser][$this->getOs()])) + { + $driverPath = $codeceptMainConfig['webdrivers'][$browser][$this->getOs()]; + } + else + { + $this->yell('No driver for your browser. Check your browser in acceptance.suite.yml and the webDrivers in codeception.yml'); + + // We can't do anything without a driver, exit + exit(1); + } + + $driver['path'] = $driverPath; + + return '-D' . implode('=', $driver); + } + + /** + * Return the os name + * + * @return string + * + * @since 3.7.3 + */ + private function getOs() + { + $os = php_uname('s'); + + if (strpos(strtolower($os), 'windows') !== false) + { + return 'windows'; + } + + if (strpos(strtolower($os), 'darwin') !== false) + { + return 'mac'; + } + + return 'linux'; + } + + /** + * 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("tests/codeception/{$suite}.suite.yml")); + } + + return $this->suiteConfig; + } +} diff --git a/administrator/components/com_actionlogs/actionlogs.php b/administrator/components/com_actionlogs/actionlogs.php new file mode 100644 index 0000000000000..fbefc60e437fb --- /dev/null +++ b/administrator/components/com_actionlogs/actionlogs.php @@ -0,0 +1,24 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Access\Exception\NotAllowed; +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\MVC\Controller\BaseController; + +if (!Factory::getUser()->authorise('core.admin')) +{ + throw new NotAllowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = BaseController::getInstance('Actionlogs'); +$controller->execute(Factory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/administrator/components/com_actionlogs/actionlogs.xml b/administrator/components/com_actionlogs/actionlogs.xml new file mode 100644 index 0000000000000..104d814abff59 --- /dev/null +++ b/administrator/components/com_actionlogs/actionlogs.xml @@ -0,0 +1,29 @@ + + + com_actionlogs + Joomla! Project + May 2018 + (C) 2018 Open Source Matters, Inc. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + COM_ACTIONLOGS_XML_DESCRIPTION + + COM_ACTIONLOGS + + actionlogs.php + config.xml + access.xml + controller.php + controllers + helpers + models + views + + + language/en-GB.com_actionlogs.ini + language/en-GB.com_actionlogs.sys.ini + + + diff --git a/administrator/components/com_actionlogs/config.xml b/administrator/components/com_actionlogs/config.xml new file mode 100644 index 0000000000000..ce40015c59884 --- /dev/null +++ b/administrator/components/com_actionlogs/config.xml @@ -0,0 +1,35 @@ + + +
+ + + + + + + + + +
+
diff --git a/administrator/components/com_actionlogs/controller.php b/administrator/components/com_actionlogs/controller.php new file mode 100644 index 0000000000000..973c98b3e3512 --- /dev/null +++ b/administrator/components/com_actionlogs/controller.php @@ -0,0 +1,19 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Actionlogs Controller + * + * @since 3.9.0 + */ +class ActionlogsController extends JControllerLegacy +{ +} diff --git a/administrator/components/com_actionlogs/controllers/actionlogs.php b/administrator/components/com_actionlogs/controllers/actionlogs.php new file mode 100644 index 0000000000000..260976a5f9fef --- /dev/null +++ b/administrator/components/com_actionlogs/controllers/actionlogs.php @@ -0,0 +1,159 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Date\Date; +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; +use Joomla\Utilities\ArrayHelper; + +JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + +/** + * Actionlogs list controller class. + * + * @since 3.9.0 + */ +class ActionlogsControllerActionlogs extends JControllerAdmin +{ + /** + * Constructor. + * + * @param array $config An optional associative array of configuration settings. + * + * @since 3.9.0 + */ + public function __construct(array $config = array()) + { + parent::__construct($config); + + $this->registerTask('exportSelectedLogs', 'exportLogs'); + } + + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return object The model. + * + * @since 3.9.0 + */ + public function getModel($name = 'Actionlogs', $prefix = 'ActionlogsModel', $config = array('ignore_request' => true)) + { + // Return the model + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to export logs + * + * @return void + * + * @since 3.9.0 + */ + public function exportLogs() + { + // Check for request forgeries. + $this->checkToken(); + + $task = $this->getTask(); + + $pks = array(); + + if ($task == 'exportSelectedLogs') + { + // Get selected logs + $pks = ArrayHelper::toInteger(explode(',', $this->input->post->getString('cids'))); + } + + /** @var ActionlogsModelActionlogs $model */ + $model = $this->getModel(); + + // Get the logs data + $data = $model->getLogDataAsIterator($pks); + + if (count($data)) + { + + try + { + $rows = ActionlogsHelper::getCsvData($data); + } + catch (InvalidArgumentException $exception) + { + $this->setMessage(Text::_('COM_ACTIONLOGS_ERROR_COULD_NOT_EXPORT_DATA'), 'error'); + $this->setRedirect(Route::_('index.php?option=com_actionlogs&view=actionlogs', false)); + + return; + } + + // Destroy the iterator now + unset($data); + + $date = new Date('now', new DateTimeZone('UTC')); + $filename = 'logs_' . $date->format('Y-m-d_His_T'); + + $csvDelimiter = ComponentHelper::getComponent('com_actionlogs')->getParams()->get('csv_delimiter', ','); + + $app = Factory::getApplication(); + $app->setHeader('Content-Type', 'application/csv', true) + ->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '.csv"', true) + ->setHeader('Cache-Control', 'must-revalidate', true) + ->sendHeaders(); + + $output = fopen("php://output", "w"); + + foreach ($rows as $row) + { + fputcsv($output, $row, $csvDelimiter); + } + + fclose($output); + $app->triggerEvent('onAfterLogExport', array()); + $app->close(); + } + else + { + $this->setMessage(Text::_('COM_ACTIONLOGS_NO_LOGS_TO_EXPORT')); + $this->setRedirect(Route::_('index.php?option=com_actionlogs&view=actionlogs', false)); + } + } + + /** + * Clean out the logs + * + * @return void + * + * @since 3.9.0 + */ + public function purge() + { + // Check for request forgeries. + $this->checkToken(); + + $model = $this->getModel(); + + if ($model->purge()) + { + $message = Text::_('COM_ACTIONLOGS_PURGE_SUCCESS'); + } + else + { + $message = Text::_('COM_ACTIONLOGS_PURGE_FAIL'); + } + + $this->setRedirect(Route::_('index.php?option=com_actionlogs&view=actionlogs', false), $message); + } +} diff --git a/administrator/components/com_actionlogs/helpers/actionlogs.php b/administrator/components/com_actionlogs/helpers/actionlogs.php new file mode 100644 index 0000000000000..3b8ea02063c4b --- /dev/null +++ b/administrator/components/com_actionlogs/helpers/actionlogs.php @@ -0,0 +1,380 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Date\Date; +use Joomla\CMS\Factory; +use Joomla\CMS\Filesystem\Path; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; +use Joomla\String\StringHelper; + +/** + * Actionlogs component helper. + * + * @since 3.9.0 + */ +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 + * + * @param array|Traversable $data The logs data objects to be exported + * + * @return array|Generator For PHP 5.5 and newer, a Generator is returned; PHP 5.4 and earlier use an array + * + * @since 3.9.0 + * @throws InvalidArgumentException + */ + public static function getCsvData($data) + { + if (!is_iterable($data)) + { + throw new InvalidArgumentException( + sprintf( + '%s() requires an array or object implementing the Traversable interface, a %s was given.', + __METHOD__, + gettype($data) === 'object' ? get_class($data) : gettype($data) + ) + ); + } + + if (version_compare(PHP_VERSION, '5.5', '>=')) + { + // Only include the PHP 5.5 helper in this conditional to prevent the potential of parse errors for PHP 5.4 or earlier + JLoader::register('ActionlogsHelperPhp55', __DIR__ . '/actionlogsphp55.php'); + + return ActionlogsHelperPhp55::getCsvAsGenerator($data); + } + + $disabledText = Text::_('COM_ACTIONLOGS_DISABLED'); + + $rows = array(); + + // Header row + $rows[] = array('Id', 'Message', 'Date', 'Extension', 'User', 'Ip'); + + foreach ($data as $log) + { + $date = new Date($log->log_date, new DateTimeZone('UTC')); + $extension = strtok($log->extension, '.'); + + static::loadTranslationFiles($extension); + + $rows[] = array( + 'id' => $log->id, + 'message' => self::escapeCsvFormula(strip_tags(static::getHumanReadableLogMessage($log, false))), + 'date' => $date->format('Y-m-d H:i:s T'), + 'extension' => self::escapeCsvFormula(Text::_($extension)), + 'name' => self::escapeCsvFormula($log->name), + 'ip_address' => self::escapeCsvFormula($log->ip_address === 'COM_ACTIONLOGS_DISABLED' ? $disabledText : $log->ip_address) + ); + } + + return $rows; + } + + /** + * Load the translation files for an extension + * + * @param string $extension Extension name + * + * @return void + * + * @since 3.9.0 + */ + public static function loadTranslationFiles($extension) + { + static $cache = array(); + $extension = strtolower($extension); + + if (isset($cache[$extension])) + { + return; + } + + $lang = Factory::getLanguage(); + $source = ''; + + switch (substr($extension, 0, 3)) + { + case 'com': + default: + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + break; + + case 'lib': + $source = JPATH_LIBRARIES . '/' . substr($extension, 4); + break; + + case 'mod': + $source = JPATH_SITE . '/modules/' . $extension; + break; + + case 'plg': + $parts = explode('_', $extension, 3); + + if (count($parts) > 2) + { + $source = JPATH_PLUGINS . '/' . $parts[1] . '/' . $parts[2]; + } + break; + + case 'pkg': + $source = JPATH_SITE; + break; + + case 'tpl': + $source = JPATH_BASE . '/templates/' . substr($extension, 4); + break; + + } + + $lang->load($extension, JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($extension, $source, null, false, true); + + if (!$lang->hasKey(strtoupper($extension))) + { + $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($extension . '.sys', $source, null, false, true); + } + + $cache[$extension] = true; + } + + /** + * Get parameters to be + * + * @param string $context The context of the content + * + * @return mixed An object contains content type parameters, or null if not found + * + * @since 3.9.0 + */ + public static function getLogContentTypeParams($context) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('a.*') + ->from($db->quoteName('#__action_log_config', 'a')) + ->where($db->quoteName('a.type_alias') . ' = ' . $db->quote($context)); + + $db->setQuery($query); + + return $db->loadObject(); + } + + /** + * Get human readable log message for a User Action Log + * + * @param stdClass $log A User Action log message record + * @param boolean $generateLinks Flag to disable link generation when creating a message + * + * @return string + * + * @since 3.9.0 + */ + public static function getHumanReadableLogMessage($log, $generateLinks = true) + { + static $links = array(); + + $message = Text::_($log->message_language_key); + $messageData = json_decode($log->message, true); + + // Special handling for translation extension name + if (isset($messageData['extension_name'])) + { + static::loadTranslationFiles($messageData['extension_name']); + $messageData['extension_name'] = Text::_($messageData['extension_name']); + } + + // Translating application + if (isset($messageData['app'])) + { + $messageData['app'] = Text::_($messageData['app']); + } + + // Translating type + if (isset($messageData['type'])) + { + $messageData['type'] = Text::_($messageData['type']); + } + + $linkMode = Factory::getApplication()->get('force_ssl', 0) >= 1 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + foreach ($messageData as $key => $value) + { + // Escape any markup in the values to prevent XSS attacks + $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); + + // Convert relative url to absolute url so that it is clickable in action logs notification email + if ($generateLinks && StringHelper::strpos($value, 'index.php?') === 0) + { + if (!isset($links[$value])) + { + $links[$value] = Route::link('administrator', $value, false, $linkMode, true); + } + + $value = $links[$value]; + } + + $message = str_replace('{' . $key . '}', $value, $message); + } + + return $message; + } + + /** + * Get link to an item of given content type + * + * @param string $component + * @param string $contentType + * @param integer $id + * @param string $urlVar + * @param JObject $object + * + * @return string Link to the content item + * + * @since 3.9.0 + */ + public static function getContentTypeLink($component, $contentType, $id, $urlVar = 'id', $object = null) + { + // Try to find the component helper. + $eName = str_replace('com_', '', $component); + $file = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php'); + + if (file_exists($file)) + { + $prefix = ucfirst(str_replace('com_', '', $component)); + $cName = $prefix . 'Helper'; + + JLoader::register($cName, $file); + + if (class_exists($cName) && is_callable(array($cName, 'getContentTypeLink'))) + { + return $cName::getContentTypeLink($contentType, $id, $object); + } + } + + if (empty($urlVar)) + { + $urlVar = 'id'; + } + + // Return default link to avoid having to implement getContentTypeLink in most of our components + return 'index.php?option=' . $component . '&task=' . $contentType . '.edit&' . $urlVar . '=' . $id; + } + + /** + * Load both enabled and disabled actionlog plugins language file. + * + * It is used to make sure actions log is displayed properly instead of only language items displayed when a plugin is disabled. + * + * @return void + * + * @since 3.9.0 + */ + public static function loadActionLogPluginsLanguage() + { + $lang = Factory::getLanguage(); + $db = Factory::getDbo(); + + // Get all (both enabled and disabled) actionlog plugins + $query = $db->getQuery(true) + ->select( + $db->quoteName( + array( + 'folder', + 'element', + 'params', + 'extension_id' + ), + array( + 'type', + 'name', + 'params', + 'id' + ) + ) + ) + ->from('#__extensions') + ->where('type = ' . $db->quote('plugin')) + ->where('folder = ' . $db->quote('actionlog')) + ->where('state IN (0,1)') + ->order('ordering'); + $db->setQuery($query); + + try + { + $rows = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + $rows = array(); + } + + if (empty($rows)) + { + return; + } + + foreach ($rows as $row) + { + $name = $row->name; + $type = $row->type; + $extension = 'Plg_' . $type . '_' . $name; + $extension = strtolower($extension); + + // If language already loaded, don't load it again. + if ($lang->getPaths($extension)) + { + continue; + } + + $lang->load($extension, JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($extension, JPATH_PLUGINS . '/' . $type . '/' . $name, null, false, true); + } + + // 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/helpers/actionlogsphp55.php b/administrator/components/com_actionlogs/helpers/actionlogsphp55.php new file mode 100644 index 0000000000000..f7b7ecd4bd014 --- /dev/null +++ b/administrator/components/com_actionlogs/helpers/actionlogsphp55.php @@ -0,0 +1,102 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Date\Date; +use Joomla\CMS\Language\Text; + +/** + * Actionlogs component helper for newer PHP versions. + * + * This file should only be included in environments running PHP 5.5 or newer and may potentially cause a parse error on older versions. + * + * @since 3.9.0 + * @deprecated Will be inlined back into ActionlogsHelper when PHP 5.5 or newer is the minimum supported PHP version + * @internal + */ +class ActionlogsHelperPhp55 +{ + /** + * Array of characters starting a formula + * + * @var array + * @since 3.9.7 + */ + private static $characters = array('=', '+', '-', '@'); + + /** + * Method to convert logs objects array to a Generator for use with a CSV export + * + * @param array|Traversable $data The logs data objects to be exported + * + * @return Generator + * + * @since 3.9.0 + * @throws InvalidArgumentException + */ + public static function getCsvAsGenerator($data) + { + if (!is_iterable($data)) + { + throw new InvalidArgumentException( + sprintf( + '%s() requires an array or object implementing the Traversable interface, a %s was given.', + __METHOD__, + gettype($data) === 'object' ? get_class($data) : gettype($data) + ) + ); + } + + $disabledText = Text::_('COM_ACTIONLOGS_DISABLED'); + + // Header row + yield array('Id', 'Message', 'Date', 'Extension', 'User', 'Ip'); + + foreach ($data as $log) + { + $extension = strtok($log->extension, '.'); + + ActionlogsHelper::loadTranslationFiles($extension); + + yield array( + 'id' => $log->id, + 'message' => self::escapeCsvFormula(strip_tags(ActionlogsHelper::getHumanReadableLogMessage($log, false))), + 'date' => (new Date($log->log_date, new DateTimeZone('UTC')))->format('Y-m-d H:i:s T'), + 'extension' => self::escapeCsvFormula(Text::_($extension)), + 'name' => self::escapeCsvFormula($log->name), + 'ip_address' => self::escapeCsvFormula($log->ip_address === 'COM_ACTIONLOGS_DISABLED' ? $disabledText : $log->ip_address) + ); + } + } + + /** + * 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/layouts/logstable.php b/administrator/components/com_actionlogs/layouts/logstable.php new file mode 100644 index 0000000000000..dcb3932332f24 --- /dev/null +++ b/administrator/components/com_actionlogs/layouts/logstable.php @@ -0,0 +1,50 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; + +Factory::getLanguage()->load("com_actionlogs", JPATH_ADMINISTRATOR, null, false, true); + +$messages = $displayData['messages']; +$showIpColumn = $displayData['showIpColumn']; +?> +

+ +

+

+ +

+ + + + + + + + + + + + + + + + + + + + + + + +
message; ?>log_date, 'Y-m-d H:i:s T', 'UTC'); ?>extension; ?>ip_address); ?>
diff --git a/administrator/components/com_actionlogs/libraries/actionlogplugin.php b/administrator/components/com_actionlogs/libraries/actionlogplugin.php new file mode 100644 index 0000000000000..7adeff9743429 --- /dev/null +++ b/administrator/components/com_actionlogs/libraries/actionlogplugin.php @@ -0,0 +1,99 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\MVC\Model\BaseDatabaseModel; + +BaseDatabaseModel::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + +/** + * Abstract Action Log Plugin + * + * @since 3.9.0 + */ +abstract class ActionLogPlugin extends JPlugin +{ + /** + * Application object. + * + * @var JApplicationCms + * @since 3.9.0 + */ + protected $app; + + /** + * Database object. + * + * @var JDatabaseDriver + * @since 3.9.0 + */ + protected $db; + + /** + * Load plugin language file automatically so that it can be used inside component + * + * @var boolean + * @since 3.9.0 + */ + protected $autoloadLanguage = true; + + /** + * Proxy for ActionlogsModelUserlog addLog method + * + * This method adds a record to #__action_logs contains (message_language_key, message, date, context, user) + * + * @param array $messages The contents of the messages to be logged + * @param string $messageLanguageKey The language key of the message + * @param string $context The context of the content passed to the plugin + * @param int $userId ID of user perform the action, usually ID of current logged in user + * + * @return void + * + * @since 3.9.0 + */ + protected function addLog($messages, $messageLanguageKey, $context, $userId = null) + { + $user = Factory::getUser(); + + foreach ($messages as $index => $message) + { + if (!array_key_exists('userid', $message)) + { + $message['userid'] = $user->id; + } + + if (!array_key_exists('username', $message)) + { + $message['username'] = $user->username; + } + + if (!array_key_exists('accountlink', $message)) + { + $message['accountlink'] = 'index.php?option=com_users&task=user.edit&id=' . $user->id; + } + + if (array_key_exists('type', $message)) + { + $message['type'] = strtoupper($message['type']); + } + + if (array_key_exists('app', $message)) + { + $message['app'] = strtoupper($message['app']); + } + + $messages[$index] = $message; + } + + /** @var ActionlogsModelActionlog $model **/ + $model = BaseDatabaseModel::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog($messages, strtoupper($messageLanguageKey), $context, $userId); + } +} diff --git a/administrator/components/com_actionlogs/models/actionlog.php b/administrator/components/com_actionlogs/models/actionlog.php new file mode 100644 index 0000000000000..a10d6d1489dae --- /dev/null +++ b/administrator/components/com_actionlogs/models/actionlog.php @@ -0,0 +1,176 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Layout\FileLayout; +use Joomla\Utilities\IpHelper; + +JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + +/** + * Methods supporting a list of Actionlog records. + * + * @since 3.9.0 + */ +class ActionlogsModelActionlog extends JModelLegacy +{ + /** + * Function to add logs to the database + * This method adds a record to #__action_logs contains (message_language_key, message, date, context, user) + * + * @param array $messages The contents of the messages to be logged + * @param string $messageLanguageKey The language key of the message + * @param string $context The context of the content passed to the plugin + * @param integer $userId ID of user perform the action, usually ID of current logged in user + * + * @return void + * + * @since 3.9.0 + */ + public function addLog($messages, $messageLanguageKey, $context, $userId = null) + { + $user = Factory::getUser($userId); + $db = $this->getDbo(); + $date = Factory::getDate(); + $params = ComponentHelper::getComponent('com_actionlogs')->getParams(); + + if ($params->get('ip_logging', 0)) + { + $ip = IpHelper::getIp(); + + if (!filter_var($ip, FILTER_VALIDATE_IP)) + { + $ip = 'COM_ACTIONLOGS_IP_INVALID'; + } + } + else + { + $ip = 'COM_ACTIONLOGS_DISABLED'; + } + + $loggedMessages = array(); + + foreach ($messages as $message) + { + $logMessage = new stdClass; + $logMessage->message_language_key = $messageLanguageKey; + $logMessage->message = json_encode($message); + $logMessage->log_date = (string) $date; + $logMessage->extension = $context; + $logMessage->user_id = $user->id; + $logMessage->ip_address = $ip; + $logMessage->item_id = isset($message['id']) ? (int) $message['id'] : 0; + + try + { + $db->insertObject('#__action_logs', $logMessage); + $loggedMessages[] = $logMessage; + } + catch (RuntimeException $e) + { + // Ignore it + } + } + + // Send notification email to users who choose to be notified about the action logs + $this->sendNotificationEmails($loggedMessages, $user->name, $context); + } + + /** + * Send notification emails about the action log + * + * @param array $messages The logged messages + * @param string $username The username + * @param string $context The Context + * + * @return void + * + * @since 3.9.0 + */ + protected function sendNotificationEmails($messages, $username, $context) + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + $params = ComponentHelper::getParams('com_actionlogs'); + $showIpColumn = (bool) $params->get('ip_logging', 0); + + $query + ->select($db->quoteName(array('u.email', 'l.extensions'))) + ->from($db->quoteName('#__users', 'u')) + ->where($db->quoteName('u.block') . ' = 0') + ->join( + 'INNER', + $db->quoteName('#__action_logs_users', 'l') . ' ON ( ' . $db->quoteName('l.notify') . ' = 1 AND ' + . $db->quoteName('l.user_id') . ' = ' . $db->quoteName('u.id') . ')' + ); + + $db->setQuery($query); + + try + { + $users = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + + return; + } + + $recipients = array(); + + foreach ($users as $user) + { + $extensions = json_decode($user->extensions, true); + + if ($extensions && in_array(strtok($context, '.'), $extensions)) + { + $recipients[] = $user->email; + } + } + + if (empty($recipients)) + { + return; + } + + $layout = new FileLayout('components.com_actionlogs.layouts.logstable', JPATH_ADMINISTRATOR); + $extension = strtok($context, '.'); + ActionlogsHelper::loadTranslationFiles($extension); + + foreach ($messages as $message) + { + $message->extension = Text::_($extension); + $message->message = ActionlogsHelper::getHumanReadableLogMessage($message); + } + + $displayData = array( + 'messages' => $messages, + 'username' => $username, + 'showIpColumn' => $showIpColumn, + ); + + $body = $layout->render($displayData); + $mailer = Factory::getMailer(); + $mailer->addRecipient($recipients); + $mailer->setSubject(Text::_('COM_ACTIONLOGS_EMAIL_SUBJECT')); + $mailer->isHTML(true); + $mailer->Encoding = 'base64'; + $mailer->setBody($body); + + if (!$mailer->Send()) + { + JError::raiseWarning(500, Text::_('JERROR_SENDING_EMAIL')); + } + } +} diff --git a/administrator/components/com_actionlogs/models/actionlogs.php b/administrator/components/com_actionlogs/models/actionlogs.php new file mode 100644 index 0000000000000..b278c617f0433 --- /dev/null +++ b/administrator/components/com_actionlogs/models/actionlogs.php @@ -0,0 +1,396 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Date\Date; +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\Utilities\ArrayHelper; + +/** + * Methods supporting a list of article records. + * + * @since 3.9.0 + */ +class ActionlogsModelActionlogs extends JModelList +{ + /** + * Constructor. + * + * @param array $config An optional associative array of configuration settings. + * + * @since 3.9.0 + */ + public function __construct($config = array()) + { + if (empty($config['filter_fields'])) + { + $config['filter_fields'] = array( + 'a.id', 'id', + 'a.extension', 'extension', + 'a.user_id', 'user', + 'a.message', 'message', + 'a.log_date', 'log_date', + 'a.ip_address', 'ip_address', + 'dateRange', + ); + } + + parent::__construct($config); + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState($ordering = 'a.id', $direction = 'desc') + { + $app = Factory::getApplication(); + + $search = $app->getUserStateFromRequest($this->context . 'filter.search', 'filter_search', '', 'string'); + $this->setState('filter.search', $search); + + $user = $app->getUserStateFromRequest($this->context . 'filter.user', 'filter_user', '', 'string'); + $this->setState('filter.user', $user); + + $extension = $app->getUserStateFromRequest($this->context . 'filter.extension', 'filter_extension', '', 'string'); + $this->setState('filter.extension', $extension); + + $ip_address = $app->getUserStateFromRequest($this->context . 'filter.ip_address', 'filter_ip_address', '', 'string'); + $this->setState('filter.ip_address', $ip_address); + + $dateRange = $app->getUserStateFromRequest($this->context . 'filter.dateRange', 'filter_dateRange', '', 'string'); + $this->setState('filter.dateRange', $dateRange); + + parent::populateState($ordering, $direction); + } + + /** + * Build an SQL query to load the list data. + * + * @return JDatabaseQuery + * + * @since 3.9.0 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('a.*, u.name') + ->from('#__action_logs AS a') + ->leftJoin('#__users AS u ON a.user_id = u.id'); + + // Get ordering + $fullorderCol = $this->state->get('list.fullordering', 'a.id DESC'); + + // Apply ordering + if (!empty($fullorderCol)) + { + $query->order($db->escape($fullorderCol)); + } + + // Get filter by user + $user = $this->getState('filter.user'); + + // Apply filter by user + if (!empty($user)) + { + $query->where($db->quoteName('a.user_id') . ' = ' . (int) $user); + } + + // Get filter by extension + $extension = $this->getState('filter.extension'); + + // Apply filter by extension + if (!empty($extension)) + { + $query->where($db->quoteName('a.extension') . ' LIKE ' . $db->quote($extension . '%')); + } + + // Get filter by date range + $dateRange = $this->getState('filter.dateRange'); + + // Apply filter by date range + if (!empty($dateRange)) + { + $date = $this->buildDateRange($dateRange); + + // If the chosen range is not more than a year ago + if ($date['dNow'] != false) + { + $query->where( + $db->qn('a.log_date') . ' >= ' . $db->quote($date['dStart']->format('Y-m-d H:i:s')) . + ' AND ' . $db->qn('a.log_date') . ' <= ' . $db->quote($date['dNow']->format('Y-m-d H:i:s')) + ); + } + } + + // Filter the items over the search string if set. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'item_id:') === 0) + { + $query->where($db->quoteName('a.item_id') . ' = ' . (int) substr($search, 8)); + } + else + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(' . $db->quoteName('u.username') . ' LIKE ' . $search . ')'); + } + } + + return $query; + } + + /** + * Construct the date range to filter on. + * + * @param string $range The textual range to construct the filter for. + * + * @return array The date range to filter on. + * + * @since 3.9.0 + */ + private function buildDateRange($range) + { + // Get UTC for now. + $dNow = new Date; + $dStart = clone $dNow; + + switch ($range) + { + case 'past_week': + $dStart->modify('-7 day'); + break; + + case 'past_1month': + $dStart->modify('-1 month'); + break; + + case 'past_3month': + $dStart->modify('-3 month'); + break; + + case 'past_6month': + $dStart->modify('-6 month'); + break; + + case 'past_year': + $dStart->modify('-1 year'); + break; + + case 'today': + // Ranges that need to align with local 'days' need special treatment. + $offset = Factory::getApplication()->get('offset'); + + // Reset the start time to be the beginning of today, local time. + $dStart = new Date('now', $offset); + $dStart->setTime(0, 0, 0); + + // Now change the timezone back to UTC. + $tz = new DateTimeZone('GMT'); + $dStart->setTimezone($tz); + break; + } + + return array('dNow' => $dNow, 'dStart' => $dStart); + } + + /** + * Get all log entries for an item + * + * @param string $extension The extension the item belongs to + * @param integer $itemId The item ID + * + * @return array + * + * @since 3.9.0 + */ + public function getLogsForItem($extension, $itemId) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('a.*, u.name') + ->from('#__action_logs AS a') + ->innerJoin('#__users AS u ON a.user_id = u.id') + ->where($db->quoteName('a.extension') . ' = ' . $db->quote($extension)) + ->where($db->quoteName('a.item_id') . ' = ' . (int) $itemId); + + // Get ordering + $fullorderCol = $this->getState('list.fullordering', 'a.id DESC'); + + // Apply ordering + if (!empty($fullorderCol)) + { + $query->order($db->escape($fullorderCol)); + } + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Get logs data into JTable object + * + * @param integer[]|null $pks An optional array of log record IDs to load + * + * @return array All logs in the table + * + * @since 3.9.0 + */ + public function getLogsData($pks = null) + { + $db = $this->getDbo(); + $query = $this->getLogDataQuery($pks); + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Get logs data as a database iterator + * + * @param integer[]|null $pks An optional array of log record IDs to load + * + * @return JDatabaseIterator + * + * @since 3.9.0 + */ + public function getLogDataAsIterator($pks = null) + { + $db = $this->getDbo(); + $query = $this->getLogDataQuery($pks); + + $db->setQuery($query); + + return $db->getIterator(); + } + + /** + * Get the query for loading logs data + * + * @param integer[]|null $pks An optional array of log record IDs to load + * + * @return JDatabaseQuery + * + * @since 3.9.0 + */ + private function getLogDataQuery($pks = null) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('a.*, u.name') + ->from('#__action_logs AS a') + ->innerJoin('#__users AS u ON a.user_id = u.id'); + + if (is_array($pks) && count($pks) > 0) + { + $query->where($db->quoteName('a.id') . ' IN (' . implode(',', ArrayHelper::toInteger($pks)) . ')'); + } + + return $query; + } + + /** + * Delete logs + * + * @param array $pks Primary keys of logs + * + * @return boolean + * + * @since 3.9.0 + */ + public function delete(&$pks) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__action_logs')) + ->where($db->quoteName('id') . ' IN (' . implode(',', ArrayHelper::toInteger($pks)) . ')'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + Factory::getApplication()->triggerEvent('onAfterLogPurge', array()); + + return true; + } + + /** + * Removes all of logs from the table. + * + * @return boolean result of operation + * + * @since 3.9.0 + */ + public function purge() + { + try + { + $this->getDbo()->truncateTable('#__action_logs'); + } + catch (Exception $e) + { + return false; + } + + Factory::getApplication()->triggerEvent('onAfterLogPurge', array()); + + return true; + } + + /** + * Get the filter form + * + * @param array $data data + * @param boolean $loadData load current data + * + * @return \JForm|boolean The \JForm object or false on error + * + * @since 3.9.0 + */ + public function getFilterForm($data = array(), $loadData = true) + { + $form = parent::getFilterForm($data, $loadData); + $params = ComponentHelper::getParams('com_actionlogs'); + $ipLogging = (bool) $params->get('ip_logging', 0); + + // Add ip sort options to sort dropdown + if ($form && $ipLogging) + { + /* @var JFormFieldList $field */ + $field = $form->getField('fullordering', 'list'); + $field->addOption(Text::_('COM_ACTIONLOGS_IP_ADDRESS_ASC'), array('value' => 'a.ip_address ASC')); + $field->addOption(Text::_('COM_ACTIONLOGS_IP_ADDRESS_DESC'), array('value' => 'a.ip_address DESC')); + } + + return $form; + } +} diff --git a/administrator/components/com_actionlogs/models/fields/extension.php b/administrator/components/com_actionlogs/models/fields/extension.php new file mode 100644 index 0000000000000..e2d4497c392d6 --- /dev/null +++ b/administrator/components/com_actionlogs/models/fields/extension.php @@ -0,0 +1,73 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\Form\FormHelper; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; + +FormHelper::loadFieldClass('list'); +JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + +/** + * Field to load a list of all extensions that have logged actions + * + * @since 3.9.0 + */ +class JFormFieldExtension extends JFormFieldList +{ + /** + * The form field type. + * + * @var string + * @since 3.9.0 + */ + protected $type = 'extension'; + + /** + * Method to get the options to populate list + * + * @return array The field option objects. + * + * @since 3.9.0 + */ + public function getOptions() + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT ' . $db->quoteName('extension')) + ->from($db->quoteName('#__action_logs')) + ->order($db->quoteName('extension')); + + $db->setQuery($query); + $context = $db->loadColumn(); + + $options = array(); + + if (count($context) > 0) + { + foreach ($context as $item) + { + $extensions[] = strtok($item, '.'); + } + + $extensions = array_unique($extensions); + + foreach ($extensions as $extension) + { + ActionlogsHelper::loadTranslationFiles($extension); + $options[] = HTMLHelper::_('select.option', $extension, Text::_($extension)); + } + } + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_actionlogs/models/fields/logcreator.php b/administrator/components/com_actionlogs/models/fields/logcreator.php new file mode 100644 index 0000000000000..a2743a5e7f131 --- /dev/null +++ b/administrator/components/com_actionlogs/models/fields/logcreator.php @@ -0,0 +1,82 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\Form\FormHelper; + +FormHelper::loadFieldClass('list'); + +/** + * Field to load a list of all users that have logged actions + * + * @since 3.9.0 + */ +class JFormFieldLogCreator extends JFormFieldList +{ + /** + * The form field type. + * + * @var string + * @since 3.9.0 + */ + protected $type = 'LogCreator'; + + /** + * Cached array of the category items. + * + * @var array + * @since 3.9.0 + */ + protected static $options = array(); + + /** + * Method to get the options to populate list + * + * @return array The field option objects. + * + * @since 3.9.0 + */ + protected function getOptions() + { + // Accepted modifiers + $hash = md5($this->element); + + if (!isset(static::$options[$hash])) + { + static::$options[$hash] = parent::getOptions(); + + $options = array(); + + $db = Factory::getDbo(); + + // Construct the query + $query = $db->getQuery(true) + ->select($db->quoteName('u.id', 'value')) + ->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.username')) + ->order($db->quoteName('u.username')); + + // Setup the query + $db->setQuery($query); + + // Return the result + if ($options = $db->loadObjectList()) + { + static::$options[$hash] = array_merge(static::$options[$hash], $options); + } + } + + return static::$options[$hash]; + } +} diff --git a/administrator/components/com_actionlogs/models/fields/logsdaterange.php b/administrator/components/com_actionlogs/models/fields/logsdaterange.php new file mode 100644 index 0000000000000..518f65a9e1c5a --- /dev/null +++ b/administrator/components/com_actionlogs/models/fields/logsdaterange.php @@ -0,0 +1,62 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\Form\FormHelper; + +FormHelper::loadFieldClass('predefinedlist'); + +/** + * Field to show a list of range dates to sort with + * + * @since 3.9.0 + */ +class JFormFieldLogsDateRange extends JFormFieldPredefinedList +{ + /** + * The form field type. + * + * @var string + * @since 3.9.0 + */ + protected $type = 'logsdaterange'; + + /** + * Available options + * + * @var array + * @since 3.9.0 + */ + protected $predefinedOptions = array( + 'today' => 'COM_ACTIONLOGS_OPTION_RANGE_TODAY', + 'past_week' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_WEEK', + 'past_1month' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_1MONTH', + 'past_3month' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_3MONTH', + 'past_6month' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_6MONTH', + 'past_year' => 'COM_ACTIONLOGS_OPTION_RANGE_PAST_YEAR', + ); + + /** + * Method to instantiate the form field object. + * + * @param JForm $form The form to attach to the form field object. + * + * @since 3.9.0 + */ + public function __construct($form = null) + { + parent::__construct($form); + + // Load the required language + $lang = Factory::getLanguage(); + $lang->load('com_actionlogs', JPATH_ADMINISTRATOR); + } +} diff --git a/administrator/components/com_actionlogs/models/fields/logtype.php b/administrator/components/com_actionlogs/models/fields/logtype.php new file mode 100644 index 0000000000000..ed611bf7491b9 --- /dev/null +++ b/administrator/components/com_actionlogs/models/fields/logtype.php @@ -0,0 +1,66 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Application\ApplicationHelper; +use Joomla\CMS\Factory; +use Joomla\CMS\Form\FormHelper; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; + +FormHelper::loadFieldClass('checkboxes'); +JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + +/** + * Field to load a list of all users that have logged actions + * + * @since 3.9.0 + */ +class JFormFieldLogType extends JFormFieldCheckboxes +{ + /** + * The form field type. + * + * @var string + * @since 3.9.0 + */ + protected $type = 'LogType'; + + /** + * Method to get the field options. + * + * @return array The field option objects. + * + * @since 3.9.0 + */ + public function getOptions() + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('extension')) + ->from($db->quoteName('#__action_logs_extensions')); + + $extensions = $db->setQuery($query)->loadColumn(); + + $options = array(); + $tmp = array('checked' => true); + + foreach ($extensions as $extension) + { + ActionlogsHelper::loadTranslationFiles($extension); + $option = HTMLHelper::_('select.option', $extension, Text::_($extension)); + $options[ApplicationHelper::stringURLSafe(Text::_($extension)) . '_' . $extension] = (object) array_merge($tmp, (array) $option); + } + + ksort($options); + + return array_merge(parent::getOptions(), array_values($options)); + } +} diff --git a/administrator/components/com_actionlogs/models/fields/plugininfo.php b/administrator/components/com_actionlogs/models/fields/plugininfo.php new file mode 100644 index 0000000000000..3db5197d19f0d --- /dev/null +++ b/administrator/components/com_actionlogs/models/fields/plugininfo.php @@ -0,0 +1,65 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Information field. + * + * @since 3.9.2 + */ +class JFormFieldPluginInfo extends JFormField +{ + /** + * The form field type. + * + * @var string + * @since 3.9.2 + */ + protected $type = 'PluginInfo'; + + /** + * Method to get the field input markup. + * + * @return string The field input markup. + * + * @since 3.9.2 + */ + protected function getInput() + { + $db = JFactory::getDbo(); + $result = null; + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('actionlog')) + ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')); + $db->setQuery($query); + + try + { + $result = (int) $db->loadResult(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + $link = JHtml::_( + 'link', + JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . $result), + JText::_('PLG_SYSTEM_ACTIONLOGS_JOOMLA_ACTIONLOG_DISABLED'), + array('class' => 'alert-link') + ); + + return '
' + . JText::sprintf('PLG_SYSTEM_ACTIONLOGS_JOOMLA_ACTIONLOG_DISABLED_REDIRECT', $link) + . '
'; + } +} diff --git a/administrator/components/com_actionlogs/models/forms/filter_actionlogs.xml b/administrator/components/com_actionlogs/models/forms/filter_actionlogs.xml new file mode 100644 index 0000000000000..e46fc35d7364e --- /dev/null +++ b/administrator/components/com_actionlogs/models/forms/filter_actionlogs.xml @@ -0,0 +1,71 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_actionlogs/views/actionlogs/tmpl/default.php b/administrator/components/com_actionlogs/views/actionlogs/tmpl/default.php new file mode 100644 index 0000000000000..27e71abaeca04 --- /dev/null +++ b/administrator/components/com_actionlogs/views/actionlogs/tmpl/default.php @@ -0,0 +1,143 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Layout\LayoutHelper; +use Joomla\CMS\Router\Route; + +/** @var ActionlogsViewActionlogs $this */ + +JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + +HTMLHelper::_('bootstrap.tooltip'); +HTMLHelper::_('behavior.multiselect'); +HTMLHelper::_('formbehavior.chosen', 'select'); + +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +Factory::getDocument()->addScriptDeclaration(' + Joomla.submitbutton = function(task) + { + if (task == "actionlogs.exportLogs") + { + Joomla.submitform(task, document.getElementById("exportForm")); + + return; + } + + if (task == "actionlogs.exportSelectedLogs") + { + // Get id of selected action logs item and pass it to export form hidden input + var cids = []; + + jQuery("input[name=\'cid[]\']:checked").each(function() { + cids.push(jQuery(this).val()); + }); + + document.exportForm.cids.value = cids.join(","); + Joomla.submitform(task, document.getElementById("exportForm")); + + return; + } + + Joomla.submitform(task); + }; +'); +?> +
+
+ $this)); ?> + items)) : ?> +
+ +
+ + + + + + + + + showIpColumn) : ?> + + + + + + + + + + + items as $i => $item) : + $extension = strtok($item->extension, '.'); + ActionlogsHelper::loadTranslationFiles($extension); ?> + + + + + + + showIpColumn) : ?> + + + + + + +
+ + + + + + + + + + + + + +
+ pagination->getListFooter(); ?> +
+ id); ?> + + + + escape(Text::_($extension)); ?> + + + log_date); ?> + + + escape($item->name); ?> + + escape($item->ip_address)); ?> + + id; ?> +
+ + + + +
+
+
+ + + +
diff --git a/administrator/components/com_actionlogs/views/actionlogs/tmpl/default.xml b/administrator/components/com_actionlogs/views/actionlogs/tmpl/default.xml new file mode 100644 index 0000000000000..e4ff2b8024255 --- /dev/null +++ b/administrator/components/com_actionlogs/views/actionlogs/tmpl/default.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/administrator/components/com_actionlogs/views/actionlogs/view.html.php b/administrator/components/com_actionlogs/views/actionlogs/view.html.php new file mode 100644 index 0000000000000..18e7d30035fe7 --- /dev/null +++ b/administrator/components/com_actionlogs/views/actionlogs/view.html.php @@ -0,0 +1,112 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Toolbar\Toolbar; +use Joomla\CMS\Toolbar\ToolbarHelper; + +JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + +/** + * View class for a list of logs. + * + * @since 3.9.0 + */ +class ActionlogsViewActionlogs extends JViewLegacy +{ + /** + * An array of items. + * + * @var array + * @since 3.9.0 + */ + protected $items; + + /** + * The model state + * + * @var array + * @since 3.9.0 + */ + protected $state; + + /** + * The pagination object + * + * @var JPagination + * @since 3.9.0 + */ + protected $pagination; + + /** + * The active search filters + * + * @var array + * @since 3.9.0 + */ + public $activeFilters; + + /** + * Method to display the view. + * + * @param string $tpl A template file to load. [optional] + * + * @return mixed A string if successful, otherwise an Error object. + * + * @since 3.9.0 + */ + public function display($tpl = null) + { + $params = ComponentHelper::getParams('com_actionlogs'); + + $this->items = $this->get('Items'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->pagination = $this->get('Pagination'); + $this->showIpColumn = (bool) $params->get('ip_logging', 0); + + if (count($errors = $this->get('Errors'))) + { + JError::raiseError(500, implode("\n", $errors)); + + return false; + } + + $this->addToolBar(); + + // Load all actionlog plugins language files + ActionlogsHelper::loadActionLogPluginsLanguage(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + ToolbarHelper::title(Text::_('COM_ACTIONLOGS_MANAGER_USERLOGS'), 'list-2'); + + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'actionlogs.delete'); + $bar = Toolbar::getInstance('toolbar'); + $bar->appendButton('Confirm', 'COM_ACTIONLOGS_PURGE_CONFIRM', 'delete', 'COM_ACTIONLOGS_TOOLBAR_PURGE', 'actionlogs.purge', false); + ToolbarHelper::preferences('com_actionlogs'); + ToolbarHelper::help('JHELP_COMPONENTS_ACTIONLOGS'); + ToolBarHelper::custom('actionlogs.exportSelectedLogs', 'download', '', 'COM_ACTIONLOGS_EXPORT_CSV', true); + ToolBarHelper::custom('actionlogs.exportLogs', 'download', '', 'COM_ACTIONLOGS_EXPORT_ALL_CSV', false); + } +} diff --git a/administrator/components/com_admin/admin.php b/administrator/components/com_admin/admin.php index e4f61bfbb0ee5..499a4946fea4a 100644 --- a/administrator/components/com_admin/admin.php +++ b/administrator/components/com_admin/admin.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/admin.xml b/administrator/components/com_admin/admin.xml index 9cbd5f7140866..f3c58dfed7958 100644 --- a/administrator/components/com_admin/admin.xml +++ b/administrator/components/com_admin/admin.xml @@ -3,7 +3,7 @@ com_admin Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_admin/controller.php b/administrator/components/com_admin/controller.php index 8d95c42abe836..c0f12d2f366de 100644 --- a/administrator/components/com_admin/controller.php +++ b/administrator/components/com_admin/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,4 +16,28 @@ */ class AdminController extends JControllerLegacy { + /** + * View method + * + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link \JFilterInput::clean()}. + * + * @return \JControllerLegacy A \JControllerLegacy object to support chaining. + * + * @since 3.9 + */ + public function display($cachable = false, $urlparams = array()) + { + $viewName = $this->input->get('view', $this->default_view); + $format = $this->input->get('format', 'html'); + + // Check CSRF token for sysinfo export views + if ($viewName === 'sysinfo' && ($format === 'text' || $format === 'json')) + { + // Check for request forgeries. + $this->checkToken('GET'); + } + + return parent::display($cachable, $urlparams); + } } diff --git a/administrator/components/com_admin/controllers/profile.php b/administrator/components/com_admin/controllers/profile.php index 0c7496f417f33..fca3247296965 100644 --- a/administrator/components/com_admin/controllers/profile.php +++ b/administrator/components/com_admin/controllers/profile.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/helpers/html/directory.php b/administrator/components/com_admin/helpers/html/directory.php index f0b7bb523a603..d4efd4988cded 100644 --- a/administrator/components/com_admin/helpers/html/directory.php +++ b/administrator/components/com_admin/helpers/html/directory.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/helpers/html/phpsetting.php b/administrator/components/com_admin/helpers/html/phpsetting.php index bf753492dec2d..8cfd82897f517 100644 --- a/administrator/components/com_admin/helpers/html/phpsetting.php +++ b/administrator/components/com_admin/helpers/html/phpsetting.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/helpers/html/system.php b/administrator/components/com_admin/helpers/html/system.php index 6d8c3dc7fb804..b380828134b4d 100644 --- a/administrator/components/com_admin/helpers/html/system.php +++ b/administrator/components/com_admin/helpers/html/system.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/models/forms/profile.xml b/administrator/components/com_admin/models/forms/profile.xml index f665004d4fbe7..f1c87b385065a 100644 --- a/administrator/components/com_admin/models/forms/profile.xml +++ b/administrator/components/com_admin/models/forms/profile.xml @@ -1,8 +1,8 @@
- - - - - + +
@@ -100,18 +106,19 @@
- - JOPTION_USE_DEFAULT - JOPTION_USE_DEFAULT - - - - - - * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/models/profile.php b/administrator/components/com_admin/models/profile.php index 9cc985eb23d01..afd0bb92bf67d 100644 --- a/administrator/components/com_admin/models/profile.php +++ b/administrator/components/com_admin/models/profile.php @@ -3,13 +3,15 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +// Load the helper and model used for two factor authentication JLoader::register('UsersModelUser', JPATH_ADMINISTRATOR . '/components/com_users/models/user.php'); +JLoader::register('UsersHelper', JPATH_ADMINISTRATOR . '/components/com_users/helpers/users.php'); /** * User model. @@ -21,7 +23,7 @@ class AdminModelProfile extends UsersModelUser /** * Method to get the record form. * - * @param array $data An optional array of data for the form to interogate. + * @param array $data An optional array of data for the form to interrogate. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return JForm A JForm object on success, false on failure @@ -137,6 +139,57 @@ public function save($data) unset($data['username']); } + // Handle the two factor authentication setup + if (isset($data['twofactor']['method'])) + { + $twoFactorMethod = $data['twofactor']['method']; + + // Get the current One Time Password (two factor auth) configuration + $otpConfig = $this->getOtpConfig($user->id); + + if ($twoFactorMethod !== 'none') + { + // Run the plugins + FOFPlatform::getInstance()->importPlugin('twofactorauth'); + $otpConfigReplies = FOFPlatform::getInstance()->runPlugins('onUserTwofactorApplyConfiguration', array($twoFactorMethod)); + + // Look for a valid reply + foreach ($otpConfigReplies as $reply) + { + if (!is_object($reply) || empty($reply->method) || ($reply->method != $twoFactorMethod)) + { + continue; + } + + $otpConfig->method = $reply->method; + $otpConfig->config = $reply->config; + + break; + } + + // Save OTP configuration. + $this->setOtpConfig($user->id, $otpConfig); + + // Generate one time emergency passwords if required (depleted or not set) + if (empty($otpConfig->otep)) + { + $this->generateOteps($user->id); + } + } + else + { + $otpConfig->method = 'none'; + $otpConfig->config = array(); + $this->setOtpConfig($user->id, $otpConfig); + } + + // Unset the raw data + unset($data['twofactor']); + + // Reload the user record with the updated OTP configuration + $user->load($user->id); + } + // Bind the data. if (!$user->bind($data)) { @@ -159,4 +212,78 @@ public function save($data) return true; } + + /** + * Gets the configuration forms for all two-factor authentication methods + * in an array. + * + * @param integer $userId The user ID to load the forms for (optional) + * + * @return array + * + * @since __DEPOLOY_VERSION__ + */ + public function getTwofactorform($userId = null) + { + $userId = (!empty($userId)) ? $userId : (int) JFactory::getUser()->id; + $model = new UsersModelUser; + + return $model->getTwofactorform($userId); + } + + /** + * Returns the one time password (OTP) – a.k.a. two factor authentication – + * configuration for a particular user. + * + * @param integer $userId The numeric ID of the user + * + * @return stdClass An object holding the OTP configuration for this user + * + * @since __DEPOLOY_VERSION__ + */ + public function getOtpConfig($userId = null) + { + $userId = (!empty($userId)) ? $userId : (int) JFactory::getUser()->id; + $model = new UsersModelUser; + + return $model->getOtpConfig($userId); + } + + /** + * Sets the one time password (OTP) – a.k.a. two factor authentication – + * configuration for a particular user. The $otpConfig object is the same as + * the one returned by the getOtpConfig method. + * + * @param integer $userId The numeric ID of the user + * @param stdClass $otpConfig The OTP configuration object + * + * @return boolean True on success + * + * @since __DEPOLOY_VERSION__ + */ + public function setOtpConfig($userId, $otpConfig) + { + $userId = (!empty($userId)) ? $userId : (int) JFactory::getUser()->id; + $model = new UsersModelUser; + + return $model->setOtpConfig($userId, $otpConfig); + } + + /** + * Generates a new set of One Time Emergency Passwords (OTEPs) for a given user. + * + * @param integer $userId The user ID + * @param integer $count How many OTEPs to generate? Default: 10 + * + * @return array The generated OTEPs + * + * @since __DEPOLOY_VERSION__ + */ + public function generateOteps($userId, $count = 10) + { + $userId = (!empty($userId)) ? $userId : (int) JFactory::getUser()->id; + $model = new UsersModelUser; + + return $model->generateOteps($userId, $count); + } } diff --git a/administrator/components/com_admin/models/sysinfo.php b/administrator/components/com_admin/models/sysinfo.php index b2c9ea6ed1abf..22e6efc874d34 100644 --- a/administrator/components/com_admin/models/sysinfo.php +++ b/administrator/components/com_admin/models/sysinfo.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -118,11 +118,15 @@ class AdminModelSysInfo extends JModelLegacy 'proxy_host', 'proxy_user', 'proxy_pass', + 'redis_server_host', + 'redis_server_auth', 'secret', 'sendmail', 'session.save_path', 'session_memcache_server_host', 'session_memcached_server_host', + 'session_redis_server_host', + 'session_redis_server_auth', 'sitename', 'smtphost', 'tmp_path', @@ -158,8 +162,8 @@ class AdminModelSysInfo extends JModelLegacy /** * Remove sections of data marked as private in the privateSettings * - * @param array $dataArray Array with data tha may contain private informati - * @param string $dataType Type of data to search for an specific section in the privateSettings array + * @param array $dataArray Array with data that may contain private information + * @param string $dataType Type of data to search for a specific section in the privateSettings array * * @return array * @@ -193,7 +197,7 @@ protected function cleanPrivateData($dataArray, $dataType = 'other') } /** - * Offuscate section values + * Obfuscate section values * * @param mixed $sectionValues Section data * @@ -242,7 +246,7 @@ public function &getPhpSettings() 'file_uploads' => ini_get('file_uploads') == '1', 'magic_quotes_gpc' => ini_get('magic_quotes_gpc') == '1', 'register_globals' => ini_get('register_globals') == '1', - 'output_buffering' => (bool) ini_get('output_buffering'), + 'output_buffering' => (int) ini_get('output_buffering') !== 0, 'open_basedir' => ini_get('open_basedir'), 'session.save_path' => ini_get('session.save_path'), 'session.auto_start' => ini_get('session.auto_start'), @@ -252,7 +256,6 @@ public function &getPhpSettings() 'zip' => function_exists('zip_open') && function_exists('zip_read'), 'mbstring' => extension_loaded('mbstring'), 'iconv' => function_exists('iconv'), - 'mcrypt' => extension_loaded('mcrypt'), 'max_input_vars' => ini_get('max_input_vars'), ); @@ -275,7 +278,11 @@ public function &getConfig() $registry = new Registry(new JConfig); $this->config = $registry->toArray(); - $hidden = array('host', 'user', 'password', 'ftp_user', 'ftp_pass', 'smtpuser', 'smtppass',); + $hidden = array( + 'host', 'user', 'password', 'ftp_user', 'ftp_pass', + 'smtpuser', 'smtppass', 'redis_server_auth', 'session_redis_server_auth', + 'proxy_user', 'proxy_pass', 'secret' + ); foreach ($hidden as $key) { @@ -305,6 +312,7 @@ public function &getInfo() $this->info = array( 'php' => php_uname(), + 'dbserver' => $db->getServerType(), 'dbversion' => $db->getVersion(), 'dbcollation' => $db->getCollation(), 'dbconnectioncollation' => $db->getConnectionCollation(), @@ -519,6 +527,7 @@ public function getDirectory($public = false) $cparams = JComponentHelper::getParams('com_media'); $this->addDirectory('administrator/components', JPATH_ADMINISTRATOR . '/components'); + $this->addDirectory('administrator/components/com_joomlaupdate', JPATH_ADMINISTRATOR . '/components/com_joomlaupdate'); $this->addDirectory('administrator/language', JPATH_ADMINISTRATOR . '/language'); // List all admin languages @@ -526,7 +535,7 @@ public function getDirectory($public = false) foreach ($admin_langs as $folder) { - if (!$folder->isDir() || $folder->isDot()) + if ($folder->isDot() || !$folder->isDir()) { continue; } @@ -542,7 +551,7 @@ public function getDirectory($public = false) foreach ($manifests as $folder) { - if (!$folder->isDir() || $folder->isDot()) + if ($folder->isDot() || !$folder->isDir()) { continue; } @@ -565,7 +574,7 @@ public function getDirectory($public = false) foreach ($image_folders as $folder) { - if (!$folder->isDir() || $folder->isDot()) + if ($folder->isDot() || !$folder->isDir()) { continue; } @@ -583,7 +592,7 @@ public function getDirectory($public = false) foreach ($site_langs as $folder) { - if (!$folder->isDir() || $folder->isDot()) + if ($folder->isDot() || !$folder->isDir()) { continue; } @@ -601,7 +610,7 @@ public function getDirectory($public = false) foreach ($plugin_groups as $folder) { - if (!$folder->isDir() || $folder->isDot()) + if ($folder->isDot() || !$folder->isDir()) { continue; } diff --git a/administrator/components/com_admin/postinstall/addnosniff.php b/administrator/components/com_admin/postinstall/addnosniff.php new file mode 100644 index 0000000000000..b8dcab690900b --- /dev/null +++ b/administrator/components/com_admin/postinstall/addnosniff.php @@ -0,0 +1,27 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + * + * This file contains post-installation message handling for notifying users of a change + * in the default .htaccess and web.config files. + */ + +defined('_JEXEC') or die; + +/** + * Notifies users of the add the nosniff headers by applying the changes from the default .htaccess or web.config file + * + * This check returns true regardless of condition. + * + * @return boolean + * + * @since 3.4 + */ +function admin_postinstall_addnosniff_condition() +{ + return true; +} diff --git a/administrator/components/com_admin/postinstall/behindproxy.php b/administrator/components/com_admin/postinstall/behindproxy.php new file mode 100644 index 0000000000000..cd1ab838c9922 --- /dev/null +++ b/administrator/components/com_admin/postinstall/behindproxy.php @@ -0,0 +1,90 @@ +get('behind_loadbalancer', '0')) + { + return false; + } + + if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) + { + return true; + } + + if (array_key_exists('HTTP_CLIENT_IP', $_SERVER) && !empty($_SERVER['HTTP_CLIENT_IP'])) + { + return true; + } + + return false; +} + + +/** + * Enables the Behind Load Balancer setting in Global Configuration + * + * @return void + * + * @since 3.9.26 + */ +function behindproxy_postinstall_action() +{ + $prev = ArrayHelper::fromObject(new JConfig); + $data = array_merge($prev, array('behind_loadbalancer' => '1')); + + $config = new Registry($data); + + jimport('joomla.filesystem.path'); + jimport('joomla.filesystem.file'); + + // Set the configuration file path. + $file = JPATH_CONFIGURATION . '/configuration.php'; + + // Get the new FTP credentials. + $ftp = JClientHelper::getCredentials('ftp', true); + + // Attempt to make the file writeable if using FTP. + if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0644')) + { + JError::raiseNotice(500, JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE')); + } + + // Attempt to write the configuration file as a PHP class named JConfig. + $configuration = $config->toString('PHP', array('class' => 'JConfig', 'closingtag' => false)); + + if (!File::write($file, $configuration)) + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_CONFIG_ERROR_WRITE_FAILED'), 'error'); + + return; + } + + // Attempt to make the file unwriteable if NOT using FTP. + if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0444')) + { + JError::raiseNotice(500, JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE')); + } +} diff --git a/administrator/components/com_admin/postinstall/eaccelerator.php b/administrator/components/com_admin/postinstall/eaccelerator.php index 9136998a23de4..fea19d91084ca 100644 --- a/administrator/components/com_admin/postinstall/eaccelerator.php +++ b/administrator/components/com_admin/postinstall/eaccelerator.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt * * This file contains post-installation message handling for eAccelerator compatibility. @@ -60,7 +60,7 @@ function admin_postinstall_eaccelerator_action() // Attempt to make the file writeable if using FTP. if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0644')) { - JError::raiseNotice('SOME_ERROR_CODE', JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE')); + JError::raiseNotice(500, JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE')); } // Attempt to write the configuration file as a PHP class named JConfig. @@ -73,9 +73,9 @@ function admin_postinstall_eaccelerator_action() return; } - // Attempt to make the file unwriteable if using FTP. + // Attempt to make the file unwriteable if NOT using FTP. if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0444')) { - JError::raiseNotice('SOME_ERROR_CODE', JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE')); + JError::raiseNotice(500, JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE')); } } diff --git a/administrator/components/com_admin/postinstall/htaccess.php b/administrator/components/com_admin/postinstall/htaccess.php index 0ce7291f4d7dd..9ae0c85a3fca5 100644 --- a/administrator/components/com_admin/postinstall/htaccess.php +++ b/administrator/components/com_admin/postinstall/htaccess.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2014 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt * * This file contains post-installation message handling for notifying users of a change diff --git a/administrator/components/com_admin/postinstall/htaccesssvg.php b/administrator/components/com_admin/postinstall/htaccesssvg.php new file mode 100644 index 0000000000000..91645751f1d39 --- /dev/null +++ b/administrator/components/com_admin/postinstall/htaccesssvg.php @@ -0,0 +1,27 @@ + * @license GNU General Public License version 2 or later; see LICENSE.txt * * This file contains post-installation message handling for Joomla 4.0 pre checks @@ -12,13 +12,15 @@ defined('_JEXEC') or die; /** - * Checks if the installation meats the current requirements for Joomla 4 + * Checks if the installation meets the current requirements for Joomla 4 * * @return boolean True if any check fails. * * @since 3.7 * * @link https://developer.joomla.org/news/658-joomla4-manifesto.html + * @link https://developer.joomla.org/news/704-looking-forward-with-joomla-4.html + * @link https://developer.joomla.org/news/788-joomla-4-on-the-move.html */ function admin_postinstall_joomla40checks_condition() { @@ -32,15 +34,27 @@ function admin_postinstall_joomla40checks_condition() return true; } - if ($serverType == 'postgresql' && version_compare($serverVersion, '9.2', 'lt')) + if ($serverType == 'postgresql' && version_compare($serverVersion, '11.0', 'lt')) { - // PostgreSQL minimum version is 9.2 + // PostgreSQL minimum version is 11.0 return true; } - if ($serverType == 'mysql' && version_compare($serverVersion, '5.5.3', 'lt')) + // Check whether we have a MariaDB version string and extract the proper version from it + if ($serverType == 'mysql' && stripos($serverVersion, 'mariadb') !== false) { - // MySQL minimum version is 5.5.3 + $serverVersion = preg_replace('/^5\.5\.5-/', '', $serverVersion); + + // MariaDB minimum version is 10.1 + if (version_compare($serverVersion, '10.1', 'lt')) + { + return true; + } + } + + if ($serverType == 'mysql' && version_compare($serverVersion, '5.6', 'lt')) + { + // MySQL minimum version is 5.6.0 return true; } @@ -50,6 +64,12 @@ function admin_postinstall_joomla40checks_condition() return true; } - // PHP minimum version is 5.5 - return version_compare(PHP_VERSION, '5.5.9', 'lt'); + if ($db->name === 'postgresql') + { + // Using deprecated PostgreSQL driver + return true; + } + + // PHP minimum version is 7.2.5 + return version_compare(PHP_VERSION, '7.2.5', 'lt'); } diff --git a/administrator/components/com_admin/postinstall/languageaccess340.php b/administrator/components/com_admin/postinstall/languageaccess340.php index d55964eb122dd..1e4aa682f1d48 100644 --- a/administrator/components/com_admin/postinstall/languageaccess340.php +++ b/administrator/components/com_admin/postinstall/languageaccess340.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt * * This file contains post-installation message handling for the checks if the installation is diff --git a/administrator/components/com_admin/postinstall/statscollection.php b/administrator/components/com_admin/postinstall/statscollection.php index c6df9cc32da69..c1cf1a3a9886a 100644 --- a/administrator/components/com_admin/postinstall/statscollection.php +++ b/administrator/components/com_admin/postinstall/statscollection.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt * * This file contains post-installation message handling for the checking minimum PHP version support diff --git a/administrator/components/com_admin/postinstall/textfilter3919.php b/administrator/components/com_admin/postinstall/textfilter3919.php new file mode 100644 index 0000000000000..cc7abcb4ce339 --- /dev/null +++ b/administrator/components/com_admin/postinstall/textfilter3919.php @@ -0,0 +1,27 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + * + * This file contains post-installation message handling for notifying users of a change + * in the default textfilter settings + */ + +defined('_JEXEC') or die; + +/** + * Notifies users the changes from the default textfilter. + * + * This check returns true regardless of condition. + * + * @return boolean + * + * @since 3.9.19 + */ +function admin_postinstall_textfilter3919_condition() +{ + return true; +} diff --git a/administrator/components/com_admin/postinstall/updatedefaultsettings.php b/administrator/components/com_admin/postinstall/updatedefaultsettings.php new file mode 100644 index 0000000000000..86774efe721a1 --- /dev/null +++ b/administrator/components/com_admin/postinstall/updatedefaultsettings.php @@ -0,0 +1,27 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + * + * This file contains post-installation message handling for notifying users of a change + * in various default settings. + */ + +defined('_JEXEC') or die; + +/** + * Notifies users of a change in various default settings + * + * This check returns true regardless of condition. + * + * @return boolean + * + * @since 3.8.8 + */ +function admin_postinstall_updatedefaultsettings_condition() +{ + return true; +} diff --git a/administrator/components/com_admin/script.php b/administrator/components/com_admin/script.php index d245cccf84871..1b75d451350d8 100644 --- a/administrator/components/com_admin/script.php +++ b/administrator/components/com_admin/script.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -380,183 +380,7 @@ protected function removeJedUpdateserver() */ protected function updateManifestCaches() { - $extensions = array( - // Components - // `type`, `element`, `folder`, `client_id` - array('component', 'com_mailto', '', 0), - array('component', 'com_wrapper', '', 0), - array('component', 'com_admin', '', 1), - array('component', 'com_ajax', '', 1), - array('component', 'com_banners', '', 1), - array('component', 'com_cache', '', 1), - array('component', 'com_categories', '', 1), - array('component', 'com_checkin', '', 1), - array('component', 'com_contact', '', 1), - array('component', 'com_cpanel', '', 1), - array('component', 'com_installer', '', 1), - array('component', 'com_languages', '', 1), - array('component', 'com_login', '', 1), - array('component', 'com_media', '', 1), - array('component', 'com_menus', '', 1), - array('component', 'com_messages', '', 1), - array('component', 'com_modules', '', 1), - array('component', 'com_newsfeeds', '', 1), - array('component', 'com_plugins', '', 1), - array('component', 'com_search', '', 1), - array('component', 'com_templates', '', 1), - array('component', 'com_content', '', 1), - array('component', 'com_config', '', 1), - array('component', 'com_redirect', '', 1), - array('component', 'com_users', '', 1), - array('component', 'com_finder', '', 1), - array('component', 'com_tags', '', 1), - array('component', 'com_contenthistory', '', 1), - array('component', 'com_postinstall', '', 1), - array('component', 'com_joomlaupdate', '', 1), - array('component', 'com_fields', '', 1), - array('component', 'com_associations', '', 1), - - // Libraries - array('library', 'phputf8', '', 0), - array('library', 'joomla', '', 0), - array('library', 'idna_convert', '', 0), - array('library', 'fof', '', 0), - array('library', 'phpass', '', 0), - - // Modules - // - Site - array('module', 'mod_articles_archive', '', 0), - array('module', 'mod_articles_latest', '', 0), - array('module', 'mod_articles_popular', '', 0), - array('module', 'mod_banners', '', 0), - array('module', 'mod_breadcrumbs', '', 0), - array('module', 'mod_custom', '', 0), - array('module', 'mod_feed', '', 0), - array('module', 'mod_footer', '', 0), - array('module', 'mod_login', '', 0), - array('module', 'mod_menu', '', 0), - array('module', 'mod_articles_news', '', 0), - array('module', 'mod_random_image', '', 0), - array('module', 'mod_related_items', '', 0), - array('module', 'mod_search', '', 0), - array('module', 'mod_stats', '', 0), - array('module', 'mod_syndicate', '', 0), - array('module', 'mod_users_latest', '', 0), - array('module', 'mod_whosonline', '', 0), - array('module', 'mod_wrapper', '', 0), - array('module', 'mod_articles_category', '', 0), - array('module', 'mod_articles_categories', '', 0), - array('module', 'mod_languages', '', 0), - array('module', 'mod_tags_popular', '', 0), - array('module', 'mod_tags_similar', '', 0), - - // - Administrator - array('module', 'mod_custom', '', 1), - array('module', 'mod_feed', '', 1), - array('module', 'mod_latest', '', 1), - array('module', 'mod_logged', '', 1), - array('module', 'mod_login', '', 1), - array('module', 'mod_menu', '', 1), - array('module', 'mod_popular', '', 1), - array('module', 'mod_quickicon', '', 1), - array('module', 'mod_stats_admin', '', 1), - array('module', 'mod_status', '', 1), - array('module', 'mod_submenu', '', 1), - array('module', 'mod_title', '', 1), - array('module', 'mod_toolbar', '', 1), - array('module', 'mod_multilangstatus', '', 1), - - // Plugins - array('plugin', 'gmail', 'authentication', 0), - array('plugin', 'joomla', 'authentication', 0), - array('plugin', 'ldap', 'authentication', 0), - array('plugin', 'contact', 'content', 0), - array('plugin', 'emailcloak', 'content', 0), - array('plugin', 'loadmodule', 'content', 0), - array('plugin', 'pagebreak', 'content', 0), - array('plugin', 'pagenavigation', 'content', 0), - array('plugin', 'vote', 'content', 0), - array('plugin', 'codemirror', 'editors', 0), - array('plugin', 'none', 'editors', 0), - array('plugin', 'tinymce', 'editors', 0), - array('plugin', 'article', 'editors-xtd', 0), - array('plugin', 'image', 'editors-xtd', 0), - array('plugin', 'pagebreak', 'editors-xtd', 0), - array('plugin', 'readmore', 'editors-xtd', 0), - array('plugin', 'categories', 'search', 0), - array('plugin', 'contacts', 'search', 0), - array('plugin', 'content', 'search', 0), - array('plugin', 'newsfeeds', 'search', 0), - array('plugin', 'tags', 'search', 0), - array('plugin', 'languagefilter', 'system', 0), - array('plugin', 'p3p', 'system', 0), - array('plugin', 'cache', 'system', 0), - array('plugin', 'debug', 'system', 0), - array('plugin', 'log', 'system', 0), - array('plugin', 'redirect', 'system', 0), - array('plugin', 'remember', 'system', 0), - array('plugin', 'sef', 'system', 0), - array('plugin', 'logout', 'system', 0), - array('plugin', 'contactcreator', 'user', 0), - array('plugin', 'joomla', 'user', 0), - array('plugin', 'profile', 'user', 0), - array('plugin', 'joomla', 'extension', 0), - array('plugin', 'joomla', 'content', 0), - array('plugin', 'languagecode', 'system', 0), - array('plugin', 'joomlaupdate', 'quickicon', 0), - array('plugin', 'extensionupdate', 'quickicon', 0), - array('plugin', 'recaptcha', 'captcha', 0), - array('plugin', 'categories', 'finder', 0), - array('plugin', 'contacts', 'finder', 0), - array('plugin', 'content', 'finder', 0), - array('plugin', 'newsfeeds', 'finder', 0), - array('plugin', 'tags', 'finder', 0), - array('plugin', 'totp', 'twofactorauth', 0), - array('plugin', 'yubikey', 'twofactorauth', 0), - array('plugin', 'updatenotification', 'system', 0), - array('plugin', 'module', 'editors-xtd', 0), - array('plugin', 'stats', 'system', 0), - array('plugin', 'packageinstaller', 'installer', 0), - array('plugin', 'folderinstaller', 'installer', 0), - array('plugin', 'urlinstaller', 'installer', 0), - array('plugin', 'phpversioncheck', 'quickicon', 0), - array('plugin', 'menu', 'editors-xtd', 0), - array('plugin', 'contact', 'editors-xtd', 0), - array('plugin', 'fields', 'system', 0), - array('plugin', 'calendar', 'fields', 0), - array('plugin', 'checkboxes', 'fields', 0), - array('plugin', 'color', 'fields', 0), - array('plugin', 'editor', 'fields', 0), - array('plugin', 'imagelist', 'fields', 0), - array('plugin', 'integer', 'fields', 0), - array('plugin', 'list', 'fields', 0), - array('plugin', 'media', 'fields', 0), - array('plugin', 'radio', 'fields', 0), - array('plugin', 'sql', 'fields', 0), - array('plugin', 'text', 'fields', 0), - array('plugin', 'textarea', 'fields', 0), - array('plugin', 'url', 'fields', 0), - array('plugin', 'user', 'fields', 0), - array('plugin', 'usergrouplist', 'fields', 0), - array('plugin', 'fields', 'content', 0), - array('plugin', 'fields', 'editors-xtd', 0), - - // Templates - array('template', 'beez3', '', 0), - array('template', 'hathor', '', 1), - array('template', 'protostar', '', 0), - array('template', 'isis', '', 1), - - // Languages - array('language', 'en-GB', '', 0), - array('language', 'en-GB', '', 1), - - // Files - array('file', 'joomla', '', 0), - - // Packages - array('package', 'pkg_en-GB', '', 0), - ); + $extensions = JExtensionHelper::getCoreExtensions(); // Attempt to refresh manifest caches $db = JFactory::getDbo(); @@ -606,74 +430,53 @@ protected function updateManifestCaches() public function deleteUnexistingFiles() { $files = array( - // Joomla 1.6 - 1.7 - 2.5 - '/libraries/cms/cmsloader.php', - '/libraries/joomla/database/databaseexception.php', - '/libraries/joomla/database/databasequery.php', - '/libraries/joomla/environment/response.php', - '/libraries/joomla/form/fields/templatestyle.php', - '/libraries/joomla/form/fields/user.php', - '/libraries/joomla/form/fields/menu.php', - '/libraries/joomla/form/fields/helpsite.php', - '/libraries/joomla/github/gists.php', - '/libraries/joomla/github/issues.php', - '/libraries/joomla/github/pulls.php', - '/libraries/joomla/log/logentry.php', - '/administrator/components/com_admin/sql/updates/mysql/1.7.0.sql', - '/administrator/components/com_admin/sql/updates/sqlsrv/2.5.2-2012-03-05.sql', - '/administrator/components/com_admin/sql/updates/sqlsrv/2.5.3-2012-03-13.sql', - '/administrator/components/com_admin/sql/updates/sqlsrv/index.html', + /* + * Joomla 1.5 + * + * Because of the way some sites were upgraded forward from 1.5, they may still have some files from the + * core libraries that need to be explicitly checked for and removed because of the migration of the + * core libraries to using PHP namespaces. For example, the JVersion file is in an autoloaded path in 2.5+ + * and due to the autoloader priorities the JVersion class will be used before the namespaced + * Joomla\CMS\Version. This is a failsafe to ensure those files which MAY conflict with the current API + * are removed. + */ + '/libraries/joomla/version.php', + + /* + * Joomla 1.6 - 1.7 - 2.5 + */ '/administrator/components/com_content/models/fields/filters.php', - '/administrator/components/com_users/controllers/config.php', '/administrator/components/com_users/helpers/levels.php', - '/administrator/language/en-GB/en-GB.plg_system_finder.ini', - '/administrator/language/en-GB/en-GB.plg_system_finder.sys.ini', '/administrator/modules/mod_quickicon/tmpl/default_button.php', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlist/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autolink/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autoresize/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/contextmenu/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/directionality/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullscreen/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/iespell/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/insertdatetime/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/layer/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/lists/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/nonbreaking/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/noneditable/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/pagebreak/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/print/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/save/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/tabfocus/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualchars/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/wordcount/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/editor_template_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/editor_template_src.js', - '/media/editors/tinymce/jscripts/tiny_mce/tiny_mce_src.js', - '/media/com_finder/images/calendar.png', - '/media/com_finder/images/mime/index.html', - '/media/com_finder/images/mime/pdf.png', - '/components/com_media/controller.php', - '/components/com_media/helpers/index.html', - '/components/com_media/helpers/media.php', - // Joomla 3.0 + '/administrator/templates/bluestork/params.ini', + '/administrator/templates/hathor/params.ini', + '/includes/version.php', + '/libraries/joomla/application/applicationexception.php', + '/libraries/joomla/client/http.php', + '/libraries/joomla/database/databaseexception.php', + '/libraries/joomla/database/databasequery.php', + '/libraries/joomla/filter/filterinput.php', + '/libraries/joomla/filter/filteroutput.php', + '/libraries/joomla/form/formfield.php', + '/libraries/joomla/form/formrule.php', + '/libraries/joomla/log/logentry.php', + '/libraries/joomla/utilities/garbagecron.txt', + '/libraries/joomlacms/index.html', + '/libraries/phpmailer/language/phpmailer.lang-en.php', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/img/flash.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/img/flv_player.swf', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/img/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/img/quicktime.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/img/realmedia.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/img/shockwave.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/img/trans.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/img/windowsmedia.gif', + '/media/system/css/modal_msie.css', + '/media/system/images/modal/closebox.gif', + + /* + * Joomla 2.5.0 thru 3.0.0 + */ '/administrator/components/com_admin/sql/updates/mysql/1.7.0-2011-06-06-2.sql', '/administrator/components/com_admin/sql/updates/mysql/1.7.0-2011-06-06.sql', '/administrator/components/com_admin/sql/updates/mysql/1.7.0.sql', @@ -689,6 +492,9 @@ public function deleteUnexistingFiles() '/administrator/components/com_admin/sql/updates/mysql/1.7.4-2011-11-19.sql', '/administrator/components/com_admin/sql/updates/mysql/1.7.4-2011-11-23.sql', '/administrator/components/com_admin/sql/updates/mysql/1.7.4-2011-12-12.sql', + '/administrator/components/com_admin/sql/updates/sqlsrv/2.5.2-2012-03-05.sql', + '/administrator/components/com_admin/sql/updates/sqlsrv/2.5.3-2012-03-13.sql', + '/administrator/components/com_admin/sql/updates/sqlsrv/index.html', '/administrator/components/com_admin/views/sysinfo/tmpl/default_navigation.php', '/administrator/components/com_categories/config.xml', '/administrator/components/com_categories/helpers/categoriesadministrator.php', @@ -716,8 +522,11 @@ public function deleteUnexistingFiles() '/administrator/components/com_templates/views/prevuuw/tmpl/default.php', '/administrator/components/com_templates/views/prevuuw/tmpl/index.html', '/administrator/components/com_templates/views/prevuuw/view.html.php', + '/administrator/components/com_users/controllers/config.php', '/administrator/includes/menu.php', '/administrator/includes/router.php', + '/administrator/language/en-GB/en-GB.plg_system_finder.ini', + '/administrator/language/en-GB/en-GB.plg_system_finder.sys.ini', '/administrator/manifests/packages/pkg_joomla.xml', '/administrator/modules/mod_submenu/helper.php', '/administrator/templates/hathor/css/ie6.css', @@ -730,6 +539,7 @@ public function deleteUnexistingFiles() '/includes/pathway.php', '/includes/router.php', '/language/en-GB/en-GB.pkg_joomla.sys.ini', + '/libraries/cms/cmsloader.php', '/libraries/cms/controller/index.html', '/libraries/cms/controller/legacy.php', '/libraries/cms/model/index.html', @@ -821,9 +631,13 @@ public function deleteUnexistingFiles() '/libraries/joomla/form/fields/contentlanguage.php', '/libraries/joomla/form/fields/editor.php', '/libraries/joomla/form/fields/editors.php', + '/libraries/joomla/form/fields/helpsite.php', '/libraries/joomla/form/fields/media.php', + '/libraries/joomla/form/fields/menu.php', '/libraries/joomla/form/fields/menuitem.php', '/libraries/joomla/form/fields/modulelayout.php', + '/libraries/joomla/form/fields/templatestyle.php', + '/libraries/joomla/form/fields/user.php', '/libraries/joomla/html/editor.php', '/libraries/joomla/html/html/access.php', '/libraries/joomla/html/html/batch.php', @@ -916,10 +730,73 @@ public function deleteUnexistingFiles() '/libraries/joomla/utilities/simplexml.php', '/libraries/joomla/utilities/string.php', '/libraries/joomla/utilities/xmlelement.php', + '/media/com_finder/images/calendar.png', + '/media/com_finder/images/index.html', + '/media/com_finder/images/mime/index.html', + '/media/com_finder/images/mime/pdf.png', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlist/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autolink/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autoresize/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/contextmenu/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/directionality/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullscreen/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/iespell/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/insertdatetime/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/layer/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/lists/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/nonbreaking/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/noneditable/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/pagebreak/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/print/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/save/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/tabfocus/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualchars/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/wordcount/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/editor_template_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/editor_template_src.js', + '/media/editors/tinymce/jscripts/tiny_mce/tiny_mce_src.js', '/media/plg_quickicon_extensionupdate/extensionupdatecheck.js', '/media/plg_quickicon_joomlaupdate/jupdatecheck.js', - // Joomla! 3.1 - '/libraries/joomla/application/router.php', + + /* + * Joomla! 3.0.0 thru 3.1.0 + */ + '/administrator/components/com_languages/views/installed/tmpl/default_ftp.php', + '/administrator/language/en-GB/en-GB.plg_content_geshi.ini', + '/administrator/language/en-GB/en-GB.plg_content_geshi.sys.ini', + '/administrator/templates/hathor/html/com_contact/contact/edit_metadata.php', + '/administrator/templates/hathor/html/com_newsfeeds/newsfeed/edit_metadata.php', + '/administrator/templates/hathor/html/com_weblinks/weblink/edit_metadata.php', + '/administrator/templates/hathor/html/mod_submenu/default.php', + '/administrator/templates/hathor/html/mod_submenu/index.html', + '/libraries/cms/feed/entry.php', + '/libraries/cms/feed/factory.php', + '/libraries/cms/feed/feed.php', + '/libraries/cms/feed/index.html', + '/libraries/cms/feed/link.php', + '/libraries/cms/feed/parser.php', + '/libraries/cms/feed/parser/atom.php', + '/libraries/cms/feed/parser/index.html', + '/libraries/cms/feed/parser/namespace.php', + '/libraries/cms/feed/parser/rss.php', + '/libraries/cms/feed/person.php', '/libraries/joomla/form/rules/boolean.php', '/libraries/joomla/form/rules/color.php', '/libraries/joomla/form/rules/email.php', @@ -930,28 +807,6 @@ public function deleteUnexistingFiles() '/libraries/joomla/form/rules/tel.php', '/libraries/joomla/form/rules/url.php', '/libraries/joomla/form/rules/username.php', - '/libraries/joomla/html/access.php', - '/libraries/joomla/html/behavior.php', - '/libraries/joomla/html/content.php', - '/libraries/joomla/html/date.php', - '/libraries/joomla/html/email.php', - '/libraries/joomla/html/form.php', - '/libraries/joomla/html/grid.php', - '/libraries/joomla/html/html.php', - '/libraries/joomla/html/index.html', - '/libraries/joomla/html/jgrid.php', - '/libraries/joomla/html/list.php', - '/libraries/joomla/html/number.php', - '/libraries/joomla/html/rules.php', - '/libraries/joomla/html/select.php', - '/libraries/joomla/html/sliders.php', - '/libraries/joomla/html/string.php', - '/libraries/joomla/html/tabs.php', - '/libraries/joomla/html/tel.php', - '/libraries/joomla/html/user.php', - '/libraries/joomla/html/language/index.html', - '/libraries/joomla/html/language/en-GB/en-GB.jhtmldate.ini', - '/libraries/joomla/html/language/en-GB/index.html', '/libraries/joomla/installer/adapters/component.php', '/libraries/joomla/installer/adapters/file.php', '/libraries/joomla/installer/adapters/index.html', @@ -964,18 +819,9 @@ public function deleteUnexistingFiles() '/libraries/joomla/installer/extension.php', '/libraries/joomla/installer/helper.php', '/libraries/joomla/installer/index.html', + '/libraries/joomla/installer/installer.php', '/libraries/joomla/installer/librarymanifest.php', '/libraries/joomla/installer/packagemanifest.php', - '/libraries/joomla/pagination/index.html', - '/libraries/joomla/pagination/object.php', - '/libraries/joomla/pagination/pagination.php', - '/libraries/legacy/html/contentlanguage.php', - '/libraries/legacy/html/index.html', - '/libraries/legacy/html/menu.php', - '/libraries/legacy/menu/index.html', - '/libraries/legacy/menu/menu.php', - '/libraries/legacy/pathway/index.html', - '/libraries/legacy/pathway/pathway.php', '/media/system/css/mooRainbow.css', '/media/system/js/mooRainbow-uncompressed.js', '/media/system/js/mooRainbow.js', @@ -985,77 +831,257 @@ public function deleteUnexistingFiles() '/media/system/js/uploader.js', '/media/system/swf/index.html', '/media/system/swf/uploader.swf', - // Joomla! 3.2 + + /* + * Joomla! 3.1.0 thru 3.2.0 + */ + '/administrator/components/com_banners/models/fields/ordering.php', + '/administrator/components/com_config/helper/component.php', + '/administrator/components/com_config/models/fields/filters.php', + '/administrator/components/com_config/models/fields/index.html', + '/administrator/components/com_config/models/forms/application.xml', + '/administrator/components/com_config/models/forms/index.html', + '/administrator/components/com_config/views/application/index.html', + '/administrator/components/com_config/views/application/tmpl/default.php', + '/administrator/components/com_config/views/application/tmpl/default_cache.php', + '/administrator/components/com_config/views/application/tmpl/default_cookie.php', + '/administrator/components/com_config/views/application/tmpl/default_database.php', + '/administrator/components/com_config/views/application/tmpl/default_debug.php', + '/administrator/components/com_config/views/application/tmpl/default_filters.php', + '/administrator/components/com_config/views/application/tmpl/default_ftp.php', + '/administrator/components/com_config/views/application/tmpl/default_ftplogin.php', + '/administrator/components/com_config/views/application/tmpl/default_locale.php', + '/administrator/components/com_config/views/application/tmpl/default_mail.php', + '/administrator/components/com_config/views/application/tmpl/default_metadata.php', + '/administrator/components/com_config/views/application/tmpl/default_navigation.php', + '/administrator/components/com_config/views/application/tmpl/default_permissions.php', + '/administrator/components/com_config/views/application/tmpl/default_seo.php', + '/administrator/components/com_config/views/application/tmpl/default_server.php', + '/administrator/components/com_config/views/application/tmpl/default_session.php', + '/administrator/components/com_config/views/application/tmpl/default_site.php', + '/administrator/components/com_config/views/application/tmpl/default_system.php', + '/administrator/components/com_config/views/application/tmpl/index.html', + '/administrator/components/com_config/views/application/view.html.php', + '/administrator/components/com_config/views/close/index.html', + '/administrator/components/com_config/views/close/view.html.php', + '/administrator/components/com_config/views/component/index.html', + '/administrator/components/com_config/views/component/tmpl/default.php', + '/administrator/components/com_config/views/component/tmpl/default_navigation.php', + '/administrator/components/com_config/views/component/tmpl/index.html', + '/administrator/components/com_config/views/component/view.html.php', + '/administrator/components/com_config/views/index.html', '/administrator/components/com_contact/models/fields/modal/contacts.php', + '/administrator/components/com_contact/models/fields/ordering.php', '/administrator/components/com_newsfeeds/models/fields/modal/newsfeeds.php', - '/libraries/idna_convert/example.php', - '/media/editors/tinymce/jscripts/tiny_mce/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/license.txt', - '/media/editors/tinymce/jscripts/tiny_mce/tiny_mce.js', - '/media/editors/tinymce/jscripts/tiny_mce/tiny_mce_popup.js', - '/media/editors/tinymce/jscripts/tiny_mce/langs/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/langs/en.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/rule.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/css/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/css/advhr.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/js/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/js/rule.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/langs/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/image.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/css/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/css/advimage.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/img/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/img/sample.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/js/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/js/image.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/langs/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/link.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/css/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/css/advlink.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/js/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/js/advlink.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/langs/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlist/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlist/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autolink/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autolink/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autoresize/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autoresize/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/langs/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/langs/en.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/bbcode/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/compat3x/editable_selects.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/compat3x/form_utils.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/compat3x/mctabs.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/compat3x/tiny_mce_popup.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/compat3x/validate.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/contextmenu/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/contextmenu/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/directionality/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/directionality/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/emotions.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-cool.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-cry.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-embarassed.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-foot-in-mouth.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-frown.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-innocent.gif', + '/administrator/components/com_newsfeeds/models/fields/ordering.php', + '/administrator/components/com_plugins/models/fields/ordering.php', + '/administrator/components/com_templates/controllers/source.php', + '/administrator/components/com_templates/models/source.php', + '/administrator/components/com_templates/views/source/index.html', + '/administrator/components/com_templates/views/source/tmpl/edit.php', + '/administrator/components/com_templates/views/source/tmpl/edit_ftp.php', + '/administrator/components/com_templates/views/source/tmpl/index.html', + '/administrator/components/com_templates/views/source/view.html.php', + '/administrator/components/com_weblinks/models/fields/index.html', + '/administrator/components/com_weblinks/models/fields/ordering.php', + '/administrator/help/en-GB/Components_Banners_Banners.html', + '/administrator/help/en-GB/Components_Banners_Banners_Edit.html', + '/administrator/help/en-GB/Components_Banners_Categories.html', + '/administrator/help/en-GB/Components_Banners_Category_Edit.html', + '/administrator/help/en-GB/Components_Banners_Clients.html', + '/administrator/help/en-GB/Components_Banners_Clients_Edit.html', + '/administrator/help/en-GB/Components_Banners_Tracks.html', + '/administrator/help/en-GB/Components_Contact_Categories.html', + '/administrator/help/en-GB/Components_Contact_Category_Edit.html', + '/administrator/help/en-GB/Components_Contacts_Contacts.html', + '/administrator/help/en-GB/Components_Contacts_Contacts_Edit.html', + '/administrator/help/en-GB/Components_Content_Categories.html', + '/administrator/help/en-GB/Components_Content_Category_Edit.html', + '/administrator/help/en-GB/Components_Messaging_Inbox.html', + '/administrator/help/en-GB/Components_Messaging_Read.html', + '/administrator/help/en-GB/Components_Messaging_Write.html', + '/administrator/help/en-GB/Components_Newsfeeds_Categories.html', + '/administrator/help/en-GB/Components_Newsfeeds_Category_Edit.html', + '/administrator/help/en-GB/Components_Newsfeeds_Feeds.html', + '/administrator/help/en-GB/Components_Newsfeeds_Feeds_Edit.html', + '/administrator/help/en-GB/Components_Redirect_Manager.html', + '/administrator/help/en-GB/Components_Redirect_Manager_Edit.html', + '/administrator/help/en-GB/Components_Search.html', + '/administrator/help/en-GB/Components_Weblinks_Categories.html', + '/administrator/help/en-GB/Components_Weblinks_Category_Edit.html', + '/administrator/help/en-GB/Components_Weblinks_Links.html', + '/administrator/help/en-GB/Components_Weblinks_Links_Edit.html', + '/administrator/help/en-GB/Content_Article_Manager.html', + '/administrator/help/en-GB/Content_Article_Manager_Edit.html', + '/administrator/help/en-GB/Content_Featured_Articles.html', + '/administrator/help/en-GB/Content_Media_Manager.html', + '/administrator/help/en-GB/Extensions_Extension_Manager_Discover.html', + '/administrator/help/en-GB/Extensions_Extension_Manager_Install.html', + '/administrator/help/en-GB/Extensions_Extension_Manager_Manage.html', + '/administrator/help/en-GB/Extensions_Extension_Manager_Update.html', + '/administrator/help/en-GB/Extensions_Extension_Manager_Warnings.html', + '/administrator/help/en-GB/Extensions_Language_Manager_Content.html', + '/administrator/help/en-GB/Extensions_Language_Manager_Edit.html', + '/administrator/help/en-GB/Extensions_Language_Manager_Installed.html', + '/administrator/help/en-GB/Extensions_Module_Manager.html', + '/administrator/help/en-GB/Extensions_Module_Manager_Edit.html', + '/administrator/help/en-GB/Extensions_Plugin_Manager.html', + '/administrator/help/en-GB/Extensions_Plugin_Manager_Edit.html', + '/administrator/help/en-GB/Extensions_Template_Manager_Styles.html', + '/administrator/help/en-GB/Extensions_Template_Manager_Styles_Edit.html', + '/administrator/help/en-GB/Extensions_Template_Manager_Templates.html', + '/administrator/help/en-GB/Extensions_Template_Manager_Templates_Edit.html', + '/administrator/help/en-GB/Extensions_Template_Manager_Templates_Edit_Source.html', + '/administrator/help/en-GB/Glossary.html', + '/administrator/help/en-GB/Menus_Menu_Item_Manager.html', + '/administrator/help/en-GB/Menus_Menu_Item_Manager_Edit.html', + '/administrator/help/en-GB/Menus_Menu_Manager.html', + '/administrator/help/en-GB/Menus_Menu_Manager_Edit.html', + '/administrator/help/en-GB/Site_Global_Configuration.html', + '/administrator/help/en-GB/Site_Maintenance_Clear_Cache.html', + '/administrator/help/en-GB/Site_Maintenance_Global_Check-in.html', + '/administrator/help/en-GB/Site_Maintenance_Purge_Expired_Cache.html', + '/administrator/help/en-GB/Site_System_Information.html', + '/administrator/help/en-GB/Start_Here.html', + '/administrator/help/en-GB/Users_Access_Levels.html', + '/administrator/help/en-GB/Users_Access_Levels_Edit.html', + '/administrator/help/en-GB/Users_Debug_Users.html', + '/administrator/help/en-GB/Users_Groups.html', + '/administrator/help/en-GB/Users_Groups_Edit.html', + '/administrator/help/en-GB/Users_Mass_Mail_Users.html', + '/administrator/help/en-GB/Users_User_Manager.html', + '/administrator/help/en-GB/Users_User_Manager_Edit.html', + '/administrator/help/en-GB/css/docbook.css', + '/administrator/help/en-GB/css/help.css', + '/administrator/includes/application.php', + '/includes/application.php', + '/libraries/joomla/application/router.php', + '/libraries/joomla/environment/response.php', + '/libraries/joomla/html/access.php', + '/libraries/joomla/html/behavior.php', + '/libraries/joomla/html/content.php', + '/libraries/joomla/html/date.php', + '/libraries/joomla/html/email.php', + '/libraries/joomla/html/form.php', + '/libraries/joomla/html/grid.php', + '/libraries/joomla/html/html.php', + '/libraries/joomla/html/index.html', + '/libraries/joomla/html/jgrid.php', + '/libraries/joomla/html/language/en-GB/en-GB.jhtmldate.ini', + '/libraries/joomla/html/language/en-GB/index.html', + '/libraries/joomla/html/language/index.html', + '/libraries/joomla/html/list.php', + '/libraries/joomla/html/number.php', + '/libraries/joomla/html/rules.php', + '/libraries/joomla/html/select.php', + '/libraries/joomla/html/sliders.php', + '/libraries/joomla/html/string.php', + '/libraries/joomla/html/tabs.php', + '/libraries/joomla/html/tel.php', + '/libraries/joomla/html/user.php', + '/libraries/joomla/pagination/index.html', + '/libraries/joomla/pagination/object.php', + '/libraries/joomla/pagination/pagination.php', + '/libraries/joomla/plugin/helper.php', + '/libraries/joomla/plugin/index.html', + '/libraries/joomla/plugin/plugin.php', + '/libraries/legacy/application/helper.php', + '/libraries/legacy/component/helper.php', + '/libraries/legacy/component/index.html', + '/libraries/legacy/html/contentlanguage.php', + '/libraries/legacy/html/index.html', + '/libraries/legacy/html/menu.php', + '/libraries/legacy/menu/index.html', + '/libraries/legacy/menu/menu.php', + '/libraries/legacy/module/helper.php', + '/libraries/legacy/module/index.html', + '/libraries/legacy/pathway/index.html', + '/libraries/legacy/pathway/pathway.php', + '/media/editors/codemirror/css/csscolors.css', + '/media/editors/codemirror/css/jscolors.css', + '/media/editors/codemirror/css/phpcolors.css', + '/media/editors/codemirror/css/sparqlcolors.css', + '/media/editors/codemirror/css/xmlcolors.css', + '/media/editors/codemirror/js/basefiles-uncompressed.js', + '/media/editors/codemirror/js/basefiles.js', + '/media/editors/codemirror/js/codemirror-uncompressed.js', + '/media/editors/codemirror/js/editor.js', + '/media/editors/codemirror/js/highlight.js', + '/media/editors/codemirror/js/mirrorframe.js', + '/media/editors/codemirror/js/parsecss.js', + '/media/editors/codemirror/js/parsedummy.js', + '/media/editors/codemirror/js/parsehtmlmixed.js', + '/media/editors/codemirror/js/parsejavascript.js', + '/media/editors/codemirror/js/parsephp.js', + '/media/editors/codemirror/js/parsephphtmlmixed.js', + '/media/editors/codemirror/js/parsesparql.js', + '/media/editors/codemirror/js/parsexml.js', + '/media/editors/codemirror/js/select.js', + '/media/editors/codemirror/js/stringstream.js', + '/media/editors/codemirror/js/tokenize.js', + '/media/editors/codemirror/js/tokenizejavascript.js', + '/media/editors/codemirror/js/tokenizephp.js', + '/media/editors/codemirror/js/undo.js', + '/media/editors/codemirror/js/util.js', + '/media/editors/tinymce/jscripts/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/langs/en.js', + '/media/editors/tinymce/jscripts/tiny_mce/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/license.txt', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/css/advhr.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/css/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/js/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/js/rule.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/langs/en_dlg.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advhr/rule.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/css/advimage.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/css/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/image.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/img/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/img/sample.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/js/image.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/js/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/langs/en_dlg.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advimage/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/css/advlink.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/css/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/js/advlink.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/js/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/langs/en_dlg.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlink/link.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlist/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/advlist/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autolink/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autolink/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autoresize/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autoresize/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/langs/en.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/autosave/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/bbcode/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/bbcode/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/contextmenu/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/contextmenu/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/directionality/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/directionality/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/emotions.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-cool.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-cry.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-embarassed.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-foot-in-mouth.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-frown.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-innocent.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-kiss.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-laughing.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-money-mouth.gif', @@ -1066,179 +1092,176 @@ public function deleteUnexistingFiles() '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-undecided.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-wink.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-yell.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/js/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/js/emotions.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/css/fullpage.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/css/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/editor_plugin.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/fullpage.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/css/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/css/fullpage.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/js/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/js/fullpage.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullscreen/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullscreen/editor_plugin.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullscreen/fullscreen.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/iespell/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullscreen/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/iespell/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/iespell/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/template.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/button.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif', '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/insertdatetime/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/skins/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/template.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/insertdatetime/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/layer/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/insertdatetime/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/layer/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/lists/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/layer/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/lists/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/media.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/moxieplayer.swf', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/lists/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/css/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/css/media.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/js/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/js/embed.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/js/media.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/nonbreaking/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/media.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/media/moxieplayer.swf', '/media/editors/tinymce/jscripts/tiny_mce/plugins/nonbreaking/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/noneditable/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/nonbreaking/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/noneditable/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/pagebreak/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/noneditable/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/pagebreak/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/pagebreak/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/pastetext.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/pastetext.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/js/pastetext.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/js/pasteword.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/pastetext.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/pasteword.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/editor_plugin.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/example.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/preview.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/jscripts/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/jscripts/embed.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/print/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/jscripts/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/preview/preview.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/print/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/save/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/print/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/save/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/searchreplace.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/save/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/css/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/css/searchreplace.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/js/searchreplace.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/css/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/searchreplace.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/css/content.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/css/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/editor_plugin.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/img/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/img/wline.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/props.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/readme.txt', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/spellchecker/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/css/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/css/props.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/js/props.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/tabfocus/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/props.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/readme.txt', '/media/editors/tinymce/jscripts/tiny_mce/plugins/tabfocus/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/tabfocus/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/cell.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/merge_cells.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/row.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/table.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/css/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/css/cell.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/css/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/css/row.css', '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/css/table.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/js/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/js/cell.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/js/merge_cells.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/js/row.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/js/table.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/merge_cells.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/row.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/table.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/blank.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/template.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/css/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/css/template.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/js/template.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualblocks/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualblocks/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/template/template.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualblocks/css/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualblocks/css/visualblocks.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualchars/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualblocks/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualblocks/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualchars/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/wordcount/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/visualchars/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/wordcount/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/wordcount/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/abbr.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/acronym.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/attributes.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/cite.htm', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/css/attributes.css', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/css/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/css/popup.css', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/del.htm', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/editor_plugin.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/ins.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/css/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/css/attributes.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/css/popup.css', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/js/abbr.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/js/acronym.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/js/attributes.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/js/cite.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/js/del.js', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/js/element_common.js', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/js/ins.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/themes/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/about.htm', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/anchor.htm', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/charmap.htm', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/color_picker.htm', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/editor_template.js', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/image.htm', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/link.htm', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/shortcuts.htm', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/source_editor.htm', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/colorpicker.jpg', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/flash.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/icons.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/iframe.gif', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/pagebreak.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/quicktime.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/realmedia.gif', @@ -1246,206 +1269,135 @@ public function deleteUnexistingFiles() '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/trans.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/video.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/windowsmedia.gif', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/js/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/js/about.js', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/js/anchor.js', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/js/charmap.js', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/js/color_picker.js', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/js/image.js', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/js/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/js/link.js', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/js/source_editor.js', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/langs/en.js', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/langs/en_dlg.js', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/link.htm', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/shortcuts.htm', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/content.css', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/dialog.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/ui.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/img/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/img/buttons.png', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/img/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/img/items.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/img/menu_check.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/img/progress.gif', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/img/tabs.gif', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/highcontrast/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/ui.css', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/highcontrast/content.css', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/highcontrast/dialog.css', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/highcontrast/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/highcontrast/ui.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/content.css', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/dialog.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/ui.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/ui_black.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/img/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg.png', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_black.png', '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_silver.png', - '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/img/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/ui.css', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/ui_black.css', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css', + '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/source_editor.htm', + '/media/editors/tinymce/jscripts/tiny_mce/themes/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/editor_template.js', - '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/img/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/img/icons.gif', - '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/langs/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/img/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/langs/en.js', - '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/default/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/langs/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/default/content.css', + '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/default/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/default/ui.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/o2k7/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/o2k7/content.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/o2k7/ui.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/o2k7/img/index.html', '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/o2k7/img/button_bg.png', - '/media/editors/tinymce/jscripts/tiny_mce/utils/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/o2k7/img/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/o2k7/index.html', + '/media/editors/tinymce/jscripts/tiny_mce/themes/simple/skins/o2k7/ui.css', + '/media/editors/tinymce/jscripts/tiny_mce/tiny_mce.js', + '/media/editors/tinymce/jscripts/tiny_mce/tiny_mce_popup.js', '/media/editors/tinymce/jscripts/tiny_mce/utils/editable_selects.js', '/media/editors/tinymce/jscripts/tiny_mce/utils/form_utils.js', + '/media/editors/tinymce/jscripts/tiny_mce/utils/index.html', '/media/editors/tinymce/jscripts/tiny_mce/utils/mctabs.js', '/media/editors/tinymce/jscripts/tiny_mce/utils/validate.js', - '/administrator/components/com_banners/models/fields/ordering.php', - '/administrator/components/com_contact/models/fields/ordering.php', - '/administrator/components/com_newsfeeds/models/fields/ordering.php', - '/administrator/components/com_plugins/models/fields/ordering.php', - '/administrator/components/com_weblinks/models/fields/ordering.php', - '/administrator/includes/application.php', - '/includes/application.php', - '/libraries/legacy/application/helper.php', - '/libraries/joomla/plugin/helper.php', - '/libraries/joomla/plugin/index.html', - '/libraries/joomla/plugin/plugin.php', - '/libraries/legacy/component/helper.php', - '/libraries/legacy/component/index.html', - '/libraries/legacy/module/helper.php', - '/libraries/legacy/module/index.html', - '/administrator/components/com_templates/controllers/source.php', - '/administrator/components/com_templates/models/source.php', - '/administrator/components/com_templates/views/source/index.html', - '/administrator/components/com_templates/views/source/tmpl/edit.php', - '/administrator/components/com_templates/views/source/tmpl/edit_ftp.php', - '/administrator/components/com_templates/views/source/tmpl/index.html', - '/administrator/components/com_templates/views/source/view.html.php', - '/media/editors/codemirror/css/csscolors.css', - '/media/editors/codemirror/css/jscolors.css', - '/media/editors/codemirror/css/phpcolors.css', - '/media/editors/codemirror/css/sparqlcolors.css', - '/media/editors/codemirror/css/xmlcolors.css', - '/media/editors/codemirror/js/basefiles-uncompressed.js', - '/media/editors/codemirror/js/basefiles.js', - '/media/editors/codemirror/js/codemirror-uncompressed.js', - '/media/editors/codemirror/js/editor.js', - '/media/editors/codemirror/js/highlight.js', - '/media/editors/codemirror/js/mirrorframe.js', - '/media/editors/codemirror/js/parsecss.js', - '/media/editors/codemirror/js/parsedummy.js', - '/media/editors/codemirror/js/parsehtmlmixed.js', - '/media/editors/codemirror/js/parsejavascript.js', - '/media/editors/codemirror/js/parsephp.js', - '/media/editors/codemirror/js/parsephphtmlmixed.js', - '/media/editors/codemirror/js/parsesparql.js', - '/media/editors/codemirror/js/parsexml.js', - '/media/editors/codemirror/js/select.js', - '/media/editors/codemirror/js/stringstream.js', - '/media/editors/codemirror/js/tokenize.js', - '/media/editors/codemirror/js/tokenizejavascript.js', - '/media/editors/codemirror/js/tokenizephp.js', - '/media/editors/codemirror/js/undo.js', - '/media/editors/codemirror/js/util.js', - '/administrator/components/com_weblinks/models/fields/index.html', - '/plugins/user/joomla/postinstall/actions.php', - '/plugins/user/joomla/postinstall/index.html', - '/media/com_finder/js/finder.js', - '/media/com_finder/js/highlighter.js', + '/media/editors/tinymce/templates/template_list.js', + '/media/system/swf/uploader.swf', + '/templates/protostar/html/editor_content.css', + + /* + * Joomla! 3.2.0 thru 3.3.0 + */ + '/libraries/fof/platform/joomla.php', + '/libraries/fof/readme.txt', + '/libraries/joomla/github/gists.php', + '/libraries/joomla/github/issues.php', + '/libraries/joomla/github/pulls.php', + '/libraries/joomla/github/users.php', '/libraries/joomla/registry/format.php', - '/libraries/joomla/registry/index.html', - '/libraries/joomla/registry/registry.php', '/libraries/joomla/registry/format/index.html', '/libraries/joomla/registry/format/ini.php', '/libraries/joomla/registry/format/json.php', '/libraries/joomla/registry/format/php.php', '/libraries/joomla/registry/format/xml.php', - '/libraries/joomla/github/users.php', - '/media/system/js/validate-jquery-uncompressed.js', - '/templates/beez3/html/message.php', - '/libraries/fof/platform/joomla.php', - '/libraries/fof/readme.txt', - // Joomla 3.3.1 - '/administrator/templates/isis/html/message.php', - // Joomla 3.3.6 - '/media/editors/tinymce/plugins/compat3x/editable_selects.js', - '/media/editors/tinymce/plugins/compat3x/form_utils.js', - '/media/editors/tinymce/plugins/compat3x/mctabs.js', - '/media/editors/tinymce/plugins/compat3x/tiny_mce_popup.js', - '/media/editors/tinymce/plugins/compat3x/validate.js', - // Joomla! 3.4 + '/libraries/joomla/registry/index.html', + '/libraries/joomla/registry/registry.php', + '/media/com_finder/js/finder.js', + '/media/com_finder/js/highlighter.js', + '/plugins/user/joomla/postinstall/actions.php', + '/plugins/user/joomla/postinstall/index.html', + + /* + * Joomla! 3.3.0 thru 3.4.0 + */ '/administrator/components/com_tags/helpers/html/index.html', '/administrator/components/com_tags/models/fields/index.html', '/administrator/manifests/libraries/phpmailer.xml', '/administrator/templates/hathor/html/com_finder/filter/index.html', '/administrator/templates/hathor/html/com_finder/statistics/index.html', + '/administrator/templates/isis/html/message.php', '/components/com_contact/helpers/icon.php', '/language/en-GB/en-GB.lib_phpmailer.sys.ini', '/libraries/compat/jsonserializable.php', - '/libraries/compat/password/lib/index.html', + '/libraries/compat/password/LICENSE.md', '/libraries/compat/password/lib/password.php', '/libraries/compat/password/lib/version_test.php', - '/libraries/compat/password/index.html', - '/libraries/compat/password/LICENSE.md', - '/libraries/compat/index.html', - '/libraries/fof/controller.php', - '/libraries/fof/dispatcher.php', - '/libraries/fof/inflector.php', - '/libraries/fof/input.php', - '/libraries/fof/model.php', - '/libraries/fof/query.abstract.php', - '/libraries/fof/query.element.php', - '/libraries/fof/query.mysql.php', - '/libraries/fof/query.mysqli.php', - '/libraries/fof/query.sqlazure.php', - '/libraries/fof/query.sqlsrv.php', - '/libraries/fof/render.abstract.php', - '/libraries/fof/render.joomla.php', - '/libraries/fof/render.joomla3.php', - '/libraries/fof/render.strapper.php', - '/libraries/fof/string.utils.php', - '/libraries/fof/table.php', - '/libraries/fof/template.utils.php', - '/libraries/fof/toolbar.php', - '/libraries/fof/view.csv.php', - '/libraries/fof/view.html.php', - '/libraries/fof/view.json.php', - '/libraries/fof/view.php', + '/libraries/framework/Joomla/Application/Cli/CliOutput.php', + '/libraries/framework/Joomla/Application/Cli/ColorProcessor.php', + '/libraries/framework/Joomla/Application/Cli/ColorStyle.php', '/libraries/framework/Joomla/Application/Cli/Output/Processor/ColorProcessor.php', '/libraries/framework/Joomla/Application/Cli/Output/Processor/ProcessorInterface.php', '/libraries/framework/Joomla/Application/Cli/Output/Stdout.php', '/libraries/framework/Joomla/Application/Cli/Output/Xml.php', - '/libraries/framework/Joomla/Application/Cli/CliOutput.php', - '/libraries/framework/Joomla/Application/Cli/ColorProcessor.php', - '/libraries/framework/Joomla/Application/Cli/ColorStyle.php', - '/libraries/framework/index.html', - '/libraries/framework/Joomla/DI/Exception/DependencyResolutionException.php', - '/libraries/framework/Joomla/DI/Exception/index.html', '/libraries/framework/Joomla/DI/Container.php', '/libraries/framework/Joomla/DI/ContainerAwareInterface.php', - '/libraries/framework/Joomla/DI/index.html', + '/libraries/framework/Joomla/DI/Exception/DependencyResolutionException.php', '/libraries/framework/Joomla/DI/ServiceProviderInterface.php', - '/libraries/framework/Joomla/Registry/Format/index.html', + '/libraries/framework/Joomla/Registry/AbstractRegistryFormat.php', '/libraries/framework/Joomla/Registry/Format/Ini.php', '/libraries/framework/Joomla/Registry/Format/Json.php', '/libraries/framework/Joomla/Registry/Format/Php.php', '/libraries/framework/Joomla/Registry/Format/Xml.php', '/libraries/framework/Joomla/Registry/Format/Yaml.php', - '/libraries/framework/Joomla/Registry/AbstractRegistryFormat.php', - '/libraries/framework/Joomla/Registry/index.html', '/libraries/framework/Joomla/Registry/Registry.php', + '/libraries/framework/Symfony/Component/Yaml/Dumper.php', + '/libraries/framework/Symfony/Component/Yaml/Escaper.php', '/libraries/framework/Symfony/Component/Yaml/Exception/DumpException.php', '/libraries/framework/Symfony/Component/Yaml/Exception/ExceptionInterface.php', - '/libraries/framework/Symfony/Component/Yaml/Exception/index.html', '/libraries/framework/Symfony/Component/Yaml/Exception/ParseException.php', '/libraries/framework/Symfony/Component/Yaml/Exception/RuntimeException.php', - '/libraries/framework/Symfony/Component/Yaml/Dumper.php', - '/libraries/framework/Symfony/Component/Yaml/Escaper.php', - '/libraries/framework/Symfony/Component/Yaml/index.html', '/libraries/framework/Symfony/Component/Yaml/Inline.php', '/libraries/framework/Symfony/Component/Yaml/LICENSE', '/libraries/framework/Symfony/Component/Yaml/Parser.php', @@ -1453,17 +1405,14 @@ public function deleteUnexistingFiles() '/libraries/framework/Symfony/Component/Yaml/Yaml.php', '/libraries/joomla/string/inflector.php', '/libraries/joomla/string/normalise.php', - '/libraries/phpmailer/language/index.html', - '/libraries/phpmailer/language/phpmailer.lang-joomla.php', - '/libraries/phpmailer/index.html', '/libraries/phpmailer/LICENSE', + '/libraries/phpmailer/language/phpmailer.lang-joomla.php', '/libraries/phpmailer/phpmailer.php', - '/libraries/phpmailer/pop.php', + '/libraries/phpmailer/pop3.php', '/libraries/phpmailer/smtp.php', '/media/editors/codemirror/css/ambiance.css', '/media/editors/codemirror/css/codemirror.css', '/media/editors/codemirror/css/configuration.css', - '/media/editors/codemirror/css/index.html', '/media/editors/codemirror/js/brace-fold.js', '/media/editors/codemirror/js/clike.js', '/media/editors/codemirror/js/closebrackets.js', @@ -1475,136 +1424,59 @@ public function deleteUnexistingFiles() '/media/editors/codemirror/js/fullscreen.js', '/media/editors/codemirror/js/htmlmixed.js', '/media/editors/codemirror/js/indent-fold.js', - '/media/editors/codemirror/js/index.html', '/media/editors/codemirror/js/javascript.js', '/media/editors/codemirror/js/less.js', '/media/editors/codemirror/js/matchbrackets.js', '/media/editors/codemirror/js/matchtags.js', '/media/editors/codemirror/js/php.js', '/media/editors/codemirror/js/xml-fold.js', - '/media/editors/codemirror/js/xml.js', - '/media/editors/tinymce/skins/lightgray/fonts/icomoon.svg', - '/media/editors/tinymce/skins/lightgray/fonts/icomoon.ttf', - '/media/editors/tinymce/skins/lightgray/fonts/icomoon.woff', - '/media/editors/tinymce/skins/lightgray/fonts/icomoon-small.eot', - '/media/editors/tinymce/skins/lightgray/fonts/icomoon-small.svg', - '/media/editors/tinymce/skins/lightgray/fonts/icomoon-small.ttf', - '/media/editors/tinymce/skins/lightgray/fonts/icomoon-small.woff', - '/media/editors/tinymce/skins/lightgray/fonts/readme.md', - '/media/editors/tinymce/skins/lightgray/fonts/tinymce.dev.svg', - '/media/editors/tinymce/skins/lightgray/fonts/tinymce-small.dev.svg', - '/media/editors/tinymce/skins/lightgray/img/wline.gif', - '/plugins/editors/codemirror/styles.css', - '/plugins/editors/codemirror/styles.min.css', - // Joomla! 3.4.1 - '/libraries/joomla/environment/request.php', - '/media/editors/tinymce/templates/template_list.js', - '/media/editors/codemirror/lib/addons-uncompressed.js', - '/media/editors/codemirror/lib/codemirror-uncompressed.css', - '/media/editors/codemirror/lib/codemirror-uncompressed.js', - '/administrator/help/en-GB/Components_Banners_Banners.html', - '/administrator/help/en-GB/Components_Banners_Banners_Edit.html', - '/administrator/help/en-GB/Components_Banners_Categories.html', - '/administrator/help/en-GB/Components_Banners_Category_Edit.html', - '/administrator/help/en-GB/Components_Banners_Clients.html', - '/administrator/help/en-GB/Components_Banners_Clients_Edit.html', - '/administrator/help/en-GB/Components_Banners_Tracks.html', - '/administrator/help/en-GB/Components_Contact_Categories.html', - '/administrator/help/en-GB/Components_Contact_Category_Edit.html', - '/administrator/help/en-GB/Components_Contacts_Contacts.html', - '/administrator/help/en-GB/Components_Contacts_Contacts_Edit.html', - '/administrator/help/en-GB/Components_Content_Categories.html', - '/administrator/help/en-GB/Components_Content_Category_Edit.html', - '/administrator/help/en-GB/Components_Messaging_Inbox.html', - '/administrator/help/en-GB/Components_Messaging_Read.html', - '/administrator/help/en-GB/Components_Messaging_Write.html', - '/administrator/help/en-GB/Components_Newsfeeds_Categories.html', - '/administrator/help/en-GB/Components_Newsfeeds_Category_Edit.html', - '/administrator/help/en-GB/Components_Newsfeeds_Feeds.html', - '/administrator/help/en-GB/Components_Newsfeeds_Feeds_Edit.html', - '/administrator/help/en-GB/Components_Redirect_Manager.html', - '/administrator/help/en-GB/Components_Redirect_Manager_Edit.html', - '/administrator/help/en-GB/Components_Search.html', - '/administrator/help/en-GB/Components_Weblinks_Categories.html', - '/administrator/help/en-GB/Components_Weblinks_Category_Edit.html', - '/administrator/help/en-GB/Components_Weblinks_Links.html', - '/administrator/help/en-GB/Components_Weblinks_Links_Edit.html', - '/administrator/help/en-GB/Content_Article_Manager.html', - '/administrator/help/en-GB/Content_Article_Manager_Edit.html', - '/administrator/help/en-GB/Content_Featured_Articles.html', - '/administrator/help/en-GB/Content_Media_Manager.html', - '/administrator/help/en-GB/Extensions_Extension_Manager_Discover.html', - '/administrator/help/en-GB/Extensions_Extension_Manager_Install.html', - '/administrator/help/en-GB/Extensions_Extension_Manager_Manage.html', - '/administrator/help/en-GB/Extensions_Extension_Manager_Update.html', - '/administrator/help/en-GB/Extensions_Extension_Manager_Warnings.html', - '/administrator/help/en-GB/Extensions_Language_Manager_Content.html', - '/administrator/help/en-GB/Extensions_Language_Manager_Edit.html', - '/administrator/help/en-GB/Extensions_Language_Manager_Installed.html', - '/administrator/help/en-GB/Extensions_Module_Manager.html', - '/administrator/help/en-GB/Extensions_Module_Manager_Edit.html', - '/administrator/help/en-GB/Extensions_Plugin_Manager.html', - '/administrator/help/en-GB/Extensions_Plugin_Manager_Edit.html', - '/administrator/help/en-GB/Extensions_Template_Manager_Styles.html', - '/administrator/help/en-GB/Extensions_Template_Manager_Styles_Edit.html', - '/administrator/help/en-GB/Extensions_Template_Manager_Templates.html', - '/administrator/help/en-GB/Extensions_Template_Manager_Templates_Edit.html', - '/administrator/help/en-GB/Extensions_Template_Manager_Templates_Edit_Source.html', - '/administrator/help/en-GB/Glossary.html', - '/administrator/help/en-GB/Menus_Menu_Item_Manager.html', - '/administrator/help/en-GB/Menus_Menu_Item_Manager_Edit.html', - '/administrator/help/en-GB/Menus_Menu_Manager.html', - '/administrator/help/en-GB/Menus_Menu_Manager_Edit.html', - '/administrator/help/en-GB/Site_Global_Configuration.html', - '/administrator/help/en-GB/Site_Maintenance_Clear_Cache.html', - '/administrator/help/en-GB/Site_Maintenance_Global_Check-in.html', - '/administrator/help/en-GB/Site_Maintenance_Purge_Expired_Cache.html', - '/administrator/help/en-GB/Site_System_Information.html', - '/administrator/help/en-GB/Start_Here.html', - '/administrator/help/en-GB/Users_Access_Levels.html', - '/administrator/help/en-GB/Users_Access_Levels_Edit.html', - '/administrator/help/en-GB/Users_Debug_Users.html', - '/administrator/help/en-GB/Users_Groups.html', - '/administrator/help/en-GB/Users_Groups_Edit.html', - '/administrator/help/en-GB/Users_Mass_Mail_Users.html', - '/administrator/help/en-GB/Users_User_Manager.html', - '/administrator/help/en-GB/Users_User_Manager_Edit.html', - '/administrator/components/com_config/views/index.html', - '/administrator/components/com_config/views/application/index.html', - '/administrator/components/com_config/views/application/view.html.php', - '/administrator/components/com_config/views/application/tmpl/default.php', - '/administrator/components/com_config/views/application/tmpl/default_cache.php', - '/administrator/components/com_config/views/application/tmpl/default_cookie.php', - '/administrator/components/com_config/views/application/tmpl/default_database.php', - '/administrator/components/com_config/views/application/tmpl/default_debug.php', - '/administrator/components/com_config/views/application/tmpl/default_filters.php', - '/administrator/components/com_config/views/application/tmpl/default_ftp.php', - '/administrator/components/com_config/views/application/tmpl/default_ftplogin.php', - '/administrator/components/com_config/views/application/tmpl/default_locale.php', - '/administrator/components/com_config/views/application/tmpl/default_mail.php', - '/administrator/components/com_config/views/application/tmpl/default_metadata.php', - '/administrator/components/com_config/views/application/tmpl/default_navigation.php', - '/administrator/components/com_config/views/application/tmpl/default_permissions.php', - '/administrator/components/com_config/views/application/tmpl/default_seo.php', - '/administrator/components/com_config/views/application/tmpl/default_server.php', - '/administrator/components/com_config/views/application/tmpl/default_session.php', - '/administrator/components/com_config/views/application/tmpl/default_site.php', - '/administrator/components/com_config/views/application/tmpl/default_system.php', - '/administrator/components/com_config/views/application/tmpl/index.html', - '/administrator/components/com_config/views/close/index.html', - '/administrator/components/com_config/views/close/view.html.php', - '/administrator/components/com_config/views/component/index.html', - '/administrator/components/com_config/views/component/view.html.php', - '/administrator/components/com_config/views/component/tmpl/default.php', - '/administrator/components/com_config/views/component/tmpl/index.html', - '/administrator/components/com_config/models/fields/filters.php', - '/administrator/components/com_config/models/fields/index.html', - '/administrator/components/com_config/models/forms/application.xml', - '/administrator/components/com_config/models/forms/index.html', - // Joomla 3.4.2 - '/libraries/composer_autoload.php', + '/media/editors/codemirror/js/xml.js', + '/media/system/js/validate-jquery-uncompressed.js', + '/templates/beez3/html/message.php', + + /* + * Joomla! 3.4.0 thru 3.5.0 + */ + '/administrator/components/com_config/controller/application/refreshhelp.php', + '/administrator/components/com_media/models/forms/index.html', '/administrator/templates/hathor/html/com_categories/categories/default_batch.php', '/administrator/templates/hathor/html/com_tags/tags/default_batch.php', + '/components/com_wrapper/views/wrapper/metadata.xml', + '/libraries/classloader.php', + '/libraries/ClassLoader.php', + '/libraries/composer_autoload.php', + '/libraries/joomla/document/error/error.php', + '/libraries/joomla/document/feed/feed.php', + '/libraries/joomla/document/html/html.php', + '/libraries/joomla/document/image/image.php', + '/libraries/joomla/document/json/json.php', + '/libraries/joomla/document/opensearch/opensearch.php', + '/libraries/joomla/document/raw/raw.php', + '/libraries/joomla/document/xml/xml.php', + '/libraries/vendor/phpmailer/phpmailer/extras/class.html2text.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Escaper.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Unescaper.php', + '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php', + '/media/com_banners/banner.js', + '/media/com_finder/css/finder-rtl.css', + '/media/com_finder/css/selectfilter.css', + '/media/com_finder/css/sliderfilter.css', + '/media/com_finder/js/sliderfilter.js', + '/media/com_joomlaupdate/default.js', + '/media/com_joomlaupdate/encryption.js', + '/media/com_joomlaupdate/json2.js', + '/media/com_joomlaupdate/update.js', + '/media/editors/codemirror/lib/addons-uncompressed.js', + '/media/editors/codemirror/lib/codemirror-uncompressed.css', + '/media/editors/codemirror/lib/codemirror-uncompressed.js', '/media/editors/codemirror/mode/clike/scala.html', '/media/editors/codemirror/mode/css/less.html', '/media/editors/codemirror/mode/css/less_test.js', @@ -1616,102 +1488,92 @@ public function deleteUnexistingFiles() '/media/editors/codemirror/mode/javascript/json-ld.html', '/media/editors/codemirror/mode/javascript/test.js', '/media/editors/codemirror/mode/javascript/typescript.html', + '/media/editors/codemirror/mode/kotlin/kotlin.js', + '/media/editors/codemirror/mode/kotlin/kotlin.min.js', '/media/editors/codemirror/mode/markdown/test.js', '/media/editors/codemirror/mode/php/test.js', '/media/editors/codemirror/mode/ruby/test.js', '/media/editors/codemirror/mode/shell/test.js', '/media/editors/codemirror/mode/slim/test.js', + '/media/editors/codemirror/mode/smartymixed/smartymixed.js', '/media/editors/codemirror/mode/stex/test.js', '/media/editors/codemirror/mode/textile/test.js', '/media/editors/codemirror/mode/verilog/test.js', '/media/editors/codemirror/mode/xml/test.js', '/media/editors/codemirror/mode/xquery/test.js', - // Joomla 3.4.3 - '/libraries/classloader.php', - '/libraries/ClassLoader.php', - // Joomla 3.4.6 - '/components/com_wrapper/views/wrapper/metadata.xml', - // Joomla 3.5.0 - '/media/com_joomlaupdate/default.js', - '/media/com_joomlaupdate/encryption.js', - '/media/com_joomlaupdate/json2.js', - '/media/com_joomlaupdate/update.js', - '/media/com_finder/css/finder-rtl.css', - '/media/com_finder/css/selectfilter.css', - '/media/com_finder/css/sliderfilter.css', - '/media/com_finder/js/sliderfilter.js', - '/media/editors/codemirror/mode/kotlin/kotlin.js', - '/media/editors/codemirror/mode/kotlin/kotlin.min.js', '/media/editors/tinymce/plugins/compat3x/editable_selects.js', '/media/editors/tinymce/plugins/compat3x/form_utils.js', '/media/editors/tinymce/plugins/compat3x/mctabs.js', '/media/editors/tinymce/plugins/compat3x/tiny_mce_popup.js', '/media/editors/tinymce/plugins/compat3x/validate.js', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Dumper.php', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Escaper.php', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Inline.php', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/LICENSE', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Parser.php', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Unescaper.php', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Yaml.php', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php', - '/libraries/vendor/phpmailer/phpmailer/extras/class.html2text.php', - '/libraries/joomla/document/error/error.php', - '/libraries/joomla/document/feed/feed.php', - '/libraries/joomla/document/html/html.php', - '/libraries/joomla/document/image/image.php', - '/libraries/joomla/document/json/json.php', - '/libraries/joomla/document/opensearch/opensearch.php', - '/libraries/joomla/document/raw/raw.php', - '/libraries/joomla/document/xml/xml.php', - '/plugins/editors/tinymce/fields/skins.php', - '/plugins/user/profile/fields/dob.php', - '/plugins/user/profile/fields/tos.php', + '/media/editors/tinymce/skins/lightgray/fonts/icomoon-small.eot', + '/media/editors/tinymce/skins/lightgray/fonts/icomoon-small.svg', + '/media/editors/tinymce/skins/lightgray/fonts/icomoon-small.ttf', + '/media/editors/tinymce/skins/lightgray/fonts/icomoon-small.woff', + '/media/editors/tinymce/skins/lightgray/fonts/icomoon.eot', + '/media/editors/tinymce/skins/lightgray/fonts/icomoon.svg', + '/media/editors/tinymce/skins/lightgray/fonts/icomoon.ttf', + '/media/editors/tinymce/skins/lightgray/fonts/icomoon.woff', + '/media/editors/tinymce/skins/lightgray/fonts/readme.md', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce-small.dev.svg', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce.dev.svg', + '/media/editors/tinymce/skins/lightgray/img/wline.gif', + '/media/mod_languages/images/km_kr.gif', + '/plugins/editors/codemirror/styles.css', + '/plugins/editors/codemirror/styles.min.css', + + /* + * Joomla! 3.5.0 thru 3.6.0 + */ '/administrator/components/com_installer/views/languages/tmpl/default_filter.php', '/administrator/components/com_joomlaupdate/helpers/download.php', - '/administrator/components/com_config/controller/application/refreshhelp.php', - '/administrator/components/com_media/models/forms/index.html', - // Joomla 3.6.0 - '/libraries/simplepie/README.txt', - '/libraries/simplepie/simplepie.php', + '/administrator/manifests/libraries/simplepie.xml', + '/administrator/templates/isis/js/bootstrap.min.js', + '/administrator/templates/isis/js/jquery.js', + '/libraries/joomla/application/web/client.php', '/libraries/simplepie/LICENSE.txt', + '/libraries/simplepie/README.txt', '/libraries/simplepie/idn/LICENCE', '/libraries/simplepie/idn/ReadMe.txt', '/libraries/simplepie/idn/idna_convert.class.php', '/libraries/simplepie/idn/npdata.ser', - '/administrator/manifests/libraries/simplepie.xml', - '/administrator/templates/isis/js/jquery.js', - '/administrator/templates/isis/js/bootstrap.min.js', + '/libraries/simplepie/simplepie.php', '/media/system/js/permissions.min.js', - '/libraries/platform.php', + '/plugins/editors/tinymce/fields/skins.php', + '/plugins/user/profile/fields/dob.php', '/plugins/user/profile/fields/tos.php', - '/libraries/joomla/application/web/client.php', - // Joomla! 3.6.1 - '/libraries/joomla/database/iterator/azure.php', - '/media/editors/tinymce/skins/lightgray/fonts/icomoon.eot', - // Joomla! 3.6.3 - '/media/editors/codemirror/mode/jade/jade.js', - '/media/editors/codemirror/mode/jade/jade.min.js', - // Joomla 3.7.0 - '/libraries/joomla/user/authentication.php', - '/libraries/platform.php', - '/libraries/joomla/data/data.php', - '/libraries/joomla/data/dumpable.php', - '/libraries/joomla/data/set.php', + + /* + * Joomla! 3.6.0 thru 3.7.0 + */ '/administrator/components/com_banners/views/banners/tmpl/default_batch.php', + '/administrator/components/com_cache/layouts/joomla/searchtools/default.php', + '/administrator/components/com_cache/layouts/joomla/searchtools/default/bar.php', + '/administrator/components/com_categories/views/categories/tmpl/default_batch.php', '/administrator/components/com_categories/views/category/tmpl/edit_extrafields.php', '/administrator/components/com_categories/views/category/tmpl/edit_options.php', - '/administrator/components/com_categories/views/categories/tmpl/default_batch.php', '/administrator/components/com_content/views/articles/tmpl/default_batch.php', + '/administrator/components/com_installer/controllers/languages.php', + '/administrator/components/com_languages/layouts/joomla/searchtools/default.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs_doc.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs_folder.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs_img.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs_video.php', '/administrator/components/com_menus/views/items/tmpl/default_batch.php', + '/administrator/components/com_messages/layouts/toolbar/mysettings.php', + '/administrator/components/com_modules/layouts/joomla/searchtools/default.php', + '/administrator/components/com_modules/layouts/joomla/searchtools/default/bar.php', '/administrator/components/com_modules/views/modules/tmpl/default_batch.php', '/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch.php', '/administrator/components/com_redirect/views/links/tmpl/default_batch.php', '/administrator/components/com_tags/views/tags/tmpl/default_batch.php', + '/administrator/components/com_templates/layouts/joomla/searchtools/default.php', + '/administrator/components/com_templates/layouts/joomla/searchtools/default/bar.php', + '/administrator/components/com_users/models/fields/components.php', '/administrator/components/com_users/views/users/tmpl/default_batch.php', + '/administrator/modules/mod_menu/tmpl/default_disabled.php', + '/administrator/modules/mod_menu/tmpl/default_enabled.php', + '/administrator/templates/hathor/html/mod_menu/default_enabled.php', '/components/com_contact/metadata.xml', '/components/com_contact/views/category/metadata.xml', '/components/com_contact/views/contact/metadata.xml', @@ -1739,37 +1601,459 @@ public function deleteUnexistingFiles() '/components/com_users/views/remind/metadata.xml', '/components/com_users/views/reset/metadata.xml', '/components/com_wrapper/metadata.xml', - '/administrator/components/com_cache/layouts/joomla/searchtools/default/bar.php', - '/administrator/components/com_cache/layouts/joomla/searchtools/default.php', - '/administrator/components/com_languages/layouts/joomla/searchtools/default/bar.php', - '/administrator/components/com_languages/layouts/joomla/searchtools/default.php', - '/administrator/components/com_modules/layouts/joomla/searchtools/default/bar.php', - '/administrator/components/com_modules/layouts/joomla/searchtools/default.php', - '/administrator/components/com_templates/layouts/joomla/searchtools/default/bar.php', - '/administrator/components/com_templates/layouts/joomla/searchtools/default.php', - '/administrator/modules/mod_menu/tmpl/default_enabled.php', - '/administrator/modules/mod_menu/tmpl/default_disabled.php', - '/administrator/templates/hathor/html/mod_menu/default_enabled.php', - '/administrator/components/com_users/models/fields/components.php', - '/administrator/components/com_installer/controllers/languages.php', - '/administrator/components/com_media/views/medialist/tmpl/thumbs_doc.php', - '/administrator/components/com_media/views/medialist/tmpl/thumbs_folder.php', - '/administrator/components/com_media/views/medialist/tmpl/thumbs_img.php', - '/administrator/components/com_media/views/medialist/tmpl/thumbs_video.php', + '/libraries/joomla/data/data.php', + '/libraries/joomla/data/dumpable.php', + '/libraries/joomla/data/set.php', + '/libraries/joomla/database/iterator/azure.php', + '/libraries/joomla/user/authentication.php', + '/libraries/platform.php', + '/media/editors/codemirror/mode/jade/jade.js', + '/media/editors/codemirror/mode/jade/jade.min.js', '/media/editors/none/none.js', '/media/editors/none/none.min.js', + '/media/editors/tinymce/plugins/jdragdrop/plugin.js', + '/media/editors/tinymce/plugins/jdragdrop/plugin.min.js', '/media/editors/tinymce/plugins/media/moxieplayer.swf', '/media/system/js/tiny-close.js', '/media/system/js/tiny-close.min.js', - '/administrator/components/com_messages/layouts/toolbar/mysettings.php', - '/media/editors/tinymce/plugins/jdragdrop/plugin.js', - '/media/editors/tinymce/plugins/jdragdrop/plugin.min.js', - // Joomla 3.7.1 - '/media/editors/tinymce/langs/uk-UA.js', - '/media/system/js/fields/calendar-locales/zh.js', - // Joomla 3.7.3 + + /* + * Joomla! 3.7.0 thru 3.8.0 + */ '/administrator/components/com_admin/postinstall/phpversion.php', + '/administrator/components/com_content/models/fields/votelist.php', + '/administrator/modules/mod_menu/preset/disabled.php', + '/administrator/modules/mod_menu/preset/enabled.php', '/components/com_content/layouts/field/prepare/modal_article.php', + '/components/com_fields/controllers/field.php', + '/libraries/cms/application/administrator.php', + '/libraries/cms/application/cms.php', + '/libraries/cms/application/helper.php', + '/libraries/cms/application/site.php', + '/libraries/cms/authentication/helper.php', + '/libraries/cms/captcha/captcha.php', + '/libraries/cms/component/exception/missing.php', + '/libraries/cms/component/helper.php', + '/libraries/cms/component/record.php', + '/libraries/cms/component/router/base.php', + '/libraries/cms/component/router/interface.php', + '/libraries/cms/component/router/legacy.php', + '/libraries/cms/component/router/rules/interface.php', + '/libraries/cms/component/router/rules/menu.php', + '/libraries/cms/component/router/rules/nomenu.php', + '/libraries/cms/component/router/rules/standard.php', + '/libraries/cms/component/router/view.php', + '/libraries/cms/component/router/viewconfiguration.php', + '/libraries/cms/editor/editor.php', + '/libraries/cms/error/page.php', + '/libraries/cms/form/field/author.php', + '/libraries/cms/form/field/captcha.php', + '/libraries/cms/form/field/chromestyle.php', + '/libraries/cms/form/field/contenthistory.php', + '/libraries/cms/form/field/contentlanguage.php', + '/libraries/cms/form/field/contenttype.php', + '/libraries/cms/form/field/editor.php', + '/libraries/cms/form/field/frontend_language.php', + '/libraries/cms/form/field/headertag.php', + '/libraries/cms/form/field/helpsite.php', + '/libraries/cms/form/field/lastvisitdaterange.php', + '/libraries/cms/form/field/limitbox.php', + '/libraries/cms/form/field/media.php', + '/libraries/cms/form/field/menu.php', + '/libraries/cms/form/field/menuitem.php', + '/libraries/cms/form/field/moduleorder.php', + '/libraries/cms/form/field/moduleposition.php', + '/libraries/cms/form/field/moduletag.php', + '/libraries/cms/form/field/ordering.php', + '/libraries/cms/form/field/plugin_status.php', + '/libraries/cms/form/field/registrationdaterange.php', + '/libraries/cms/form/field/status.php', + '/libraries/cms/form/field/tag.php', + '/libraries/cms/form/field/templatestyle.php', + '/libraries/cms/form/field/user.php', + '/libraries/cms/form/field/useractive.php', + '/libraries/cms/form/field/usergrouplist.php', + '/libraries/cms/form/field/userstate.php', + '/libraries/cms/form/rule/captcha.php', + '/libraries/cms/form/rule/notequals.php', + '/libraries/cms/form/rule/password.php', + '/libraries/cms/help/help.php', + '/libraries/cms/helper/content.php', + '/libraries/cms/helper/contenthistory.php', + '/libraries/cms/helper/helper.php', + '/libraries/cms/helper/media.php', + '/libraries/cms/helper/route.php', + '/libraries/cms/helper/tags.php', + '/libraries/cms/helper/usergroups.php', + '/libraries/cms/html/html.php', + '/libraries/cms/installer/adapter.php', + '/libraries/cms/installer/adapter/component.php', + '/libraries/cms/installer/adapter/file.php', + '/libraries/cms/installer/adapter/language.php', + '/libraries/cms/installer/adapter/library.php', + '/libraries/cms/installer/adapter/module.php', + '/libraries/cms/installer/adapter/package.php', + '/libraries/cms/installer/adapter/plugin.php', + '/libraries/cms/installer/adapter/template.php', + '/libraries/cms/installer/extension.php', + '/libraries/cms/installer/helper.php', + '/libraries/cms/installer/installer.php', + '/libraries/cms/installer/manifest.php', + '/libraries/cms/installer/manifest/library.php', + '/libraries/cms/installer/manifest/package.php', + '/libraries/cms/installer/script.php', + '/libraries/cms/language/associations.php', + '/libraries/cms/language/multilang.php', + '/libraries/cms/layout/base.php', + '/libraries/cms/layout/file.php', + '/libraries/cms/layout/helper.php', + '/libraries/cms/layout/layout.php', + '/libraries/cms/library/helper.php', + '/libraries/cms/menu/administrator.php', + '/libraries/cms/menu/item.php', + '/libraries/cms/menu/menu.php', + '/libraries/cms/menu/site.php', + '/libraries/cms/module/helper.php', + '/libraries/cms/pagination/object.php', + '/libraries/cms/pagination/pagination.php', + '/libraries/cms/pathway/pathway.php', + '/libraries/cms/pathway/site.php', + '/libraries/cms/plugin/helper.php', + '/libraries/cms/plugin/plugin.php', + '/libraries/cms/response/json.php', + '/libraries/cms/router/administrator.php', + '/libraries/cms/router/router.php', + '/libraries/cms/router/site.php', + '/libraries/cms/schema/changeitem.php', + '/libraries/cms/schema/changeitem/mysql.php', + '/libraries/cms/schema/changeitem/postgresql.php', + '/libraries/cms/schema/changeitem/sqlsrv.php', + '/libraries/cms/schema/changeset.php', + '/libraries/cms/search/helper.php', + '/libraries/cms/table/contenthistory.php', + '/libraries/cms/table/contenttype.php', + '/libraries/cms/table/corecontent.php', + '/libraries/cms/table/ucm.php', + '/libraries/cms/toolbar/button.php', + '/libraries/cms/toolbar/button/confirm.php', + '/libraries/cms/toolbar/button/custom.php', + '/libraries/cms/toolbar/button/help.php', + '/libraries/cms/toolbar/button/link.php', + '/libraries/cms/toolbar/button/popup.php', + '/libraries/cms/toolbar/button/separator.php', + '/libraries/cms/toolbar/button/slider.php', + '/libraries/cms/toolbar/button/standard.php', + '/libraries/cms/toolbar/toolbar.php', + '/libraries/cms/ucm/base.php', + '/libraries/cms/ucm/content.php', + '/libraries/cms/ucm/type.php', + '/libraries/cms/ucm/ucm.php', + '/libraries/cms/version/version.php', + '/libraries/joomla/access/access.php', + '/libraries/joomla/access/exception/notallowed.php', + '/libraries/joomla/access/rule.php', + '/libraries/joomla/access/rules.php', + '/libraries/joomla/access/wrapper/access.php', + '/libraries/joomla/application/base.php', + '/libraries/joomla/application/cli.php', + '/libraries/joomla/application/daemon.php', + '/libraries/joomla/application/route.php', + '/libraries/joomla/application/web.php', + '/libraries/joomla/association/extension/helper.php', + '/libraries/joomla/association/extension/interface.php', + '/libraries/joomla/authentication/authentication.php', + '/libraries/joomla/authentication/response.php', + '/libraries/joomla/cache/cache.php', + '/libraries/joomla/cache/controller.php', + '/libraries/joomla/cache/controller/callback.php', + '/libraries/joomla/cache/controller/output.php', + '/libraries/joomla/cache/controller/page.php', + '/libraries/joomla/cache/controller/view.php', + '/libraries/joomla/cache/exception.php', + '/libraries/joomla/cache/exception/connecting.php', + '/libraries/joomla/cache/exception/unsupported.php', + '/libraries/joomla/cache/storage.php', + '/libraries/joomla/cache/storage/apc.php', + '/libraries/joomla/cache/storage/apcu.php', + '/libraries/joomla/cache/storage/cachelite.php', + '/libraries/joomla/cache/storage/file.php', + '/libraries/joomla/cache/storage/helper.php', + '/libraries/joomla/cache/storage/memcache.php', + '/libraries/joomla/cache/storage/memcached.php', + '/libraries/joomla/cache/storage/redis.php', + '/libraries/joomla/cache/storage/wincache.php', + '/libraries/joomla/cache/storage/xcache.php', + '/libraries/joomla/client/ftp.php', + '/libraries/joomla/client/helper.php', + '/libraries/joomla/client/ldap.php', + '/libraries/joomla/client/wrapper/helper.php', + '/libraries/joomla/crypt/README.md', + '/libraries/joomla/crypt/cipher.php', + '/libraries/joomla/crypt/cipher/3des.php', + '/libraries/joomla/crypt/cipher/blowfish.php', + '/libraries/joomla/crypt/cipher/crypto.php', + '/libraries/joomla/crypt/cipher/mcrypt.php', + '/libraries/joomla/crypt/cipher/rijndael256.php', + '/libraries/joomla/crypt/cipher/simple.php', + '/libraries/joomla/crypt/crypt.php', + '/libraries/joomla/crypt/key.php', + '/libraries/joomla/crypt/password.php', + '/libraries/joomla/crypt/password/simple.php', + '/libraries/joomla/date/date.php', + '/libraries/joomla/document/document.php', + '/libraries/joomla/document/error.php', + '/libraries/joomla/document/feed.php', + '/libraries/joomla/document/feed/renderer/atom.php', + '/libraries/joomla/document/feed/renderer/rss.php', + '/libraries/joomla/document/html.php', + '/libraries/joomla/document/html/renderer/component.php', + '/libraries/joomla/document/html/renderer/head.php', + '/libraries/joomla/document/html/renderer/message.php', + '/libraries/joomla/document/html/renderer/module.php', + '/libraries/joomla/document/html/renderer/modules.php', + '/libraries/joomla/document/image.php', + '/libraries/joomla/document/json.php', + '/libraries/joomla/document/opensearch.php', + '/libraries/joomla/document/raw.php', + '/libraries/joomla/document/renderer.php', + '/libraries/joomla/document/renderer/feed/atom.php', + '/libraries/joomla/document/renderer/feed/rss.php', + '/libraries/joomla/document/renderer/html/component.php', + '/libraries/joomla/document/renderer/html/head.php', + '/libraries/joomla/document/renderer/html/message.php', + '/libraries/joomla/document/renderer/html/module.php', + '/libraries/joomla/document/renderer/html/modules.php', + '/libraries/joomla/document/xml.php', + '/libraries/joomla/environment/browser.php', + '/libraries/joomla/factory.php', + '/libraries/joomla/feed/entry.php', + '/libraries/joomla/feed/factory.php', + '/libraries/joomla/feed/feed.php', + '/libraries/joomla/feed/link.php', + '/libraries/joomla/feed/parser.php', + '/libraries/joomla/feed/parser/atom.php', + '/libraries/joomla/feed/parser/namespace.php', + '/libraries/joomla/feed/parser/rss.php', + '/libraries/joomla/feed/parser/rss/itunes.php', + '/libraries/joomla/feed/parser/rss/media.php', + '/libraries/joomla/feed/person.php', + '/libraries/joomla/filter/input.php', + '/libraries/joomla/filter/output.php', + '/libraries/joomla/filter/wrapper/output.php', + '/libraries/joomla/form/field.php', + '/libraries/joomla/form/form.php', + '/libraries/joomla/form/helper.php', + '/libraries/joomla/form/rule.php', + '/libraries/joomla/form/rule/boolean.php', + '/libraries/joomla/form/rule/calendar.php', + '/libraries/joomla/form/rule/color.php', + '/libraries/joomla/form/rule/email.php', + '/libraries/joomla/form/rule/equals.php', + '/libraries/joomla/form/rule/number.php', + '/libraries/joomla/form/rule/options.php', + '/libraries/joomla/form/rule/rules.php', + '/libraries/joomla/form/rule/tel.php', + '/libraries/joomla/form/rule/url.php', + '/libraries/joomla/form/rule/username.php', + '/libraries/joomla/form/wrapper/helper.php', + '/libraries/joomla/http/factory.php', + '/libraries/joomla/http/http.php', + '/libraries/joomla/http/response.php', + '/libraries/joomla/http/transport.php', + '/libraries/joomla/http/transport/cacert.pem', + '/libraries/joomla/http/transport/curl.php', + '/libraries/joomla/http/transport/socket.php', + '/libraries/joomla/http/transport/stream.php', + '/libraries/joomla/http/wrapper/factory.php', + '/libraries/joomla/image/filter.php', + '/libraries/joomla/image/filter/backgroundfill.php', + '/libraries/joomla/image/filter/brightness.php', + '/libraries/joomla/image/filter/contrast.php', + '/libraries/joomla/image/filter/edgedetect.php', + '/libraries/joomla/image/filter/emboss.php', + '/libraries/joomla/image/filter/grayscale.php', + '/libraries/joomla/image/filter/negate.php', + '/libraries/joomla/image/filter/sketchy.php', + '/libraries/joomla/image/filter/smooth.php', + '/libraries/joomla/image/image.php', + '/libraries/joomla/input/cli.php', + '/libraries/joomla/input/cookie.php', + '/libraries/joomla/input/files.php', + '/libraries/joomla/input/input.php', + '/libraries/joomla/input/json.php', + '/libraries/joomla/language/helper.php', + '/libraries/joomla/language/language.php', + '/libraries/joomla/language/stemmer.php', + '/libraries/joomla/language/stemmer/porteren.php', + '/libraries/joomla/language/text.php', + '/libraries/joomla/language/transliterate.php', + '/libraries/joomla/language/wrapper/helper.php', + '/libraries/joomla/language/wrapper/text.php', + '/libraries/joomla/language/wrapper/transliterate.php', + '/libraries/joomla/log/entry.php', + '/libraries/joomla/log/log.php', + '/libraries/joomla/log/logger.php', + '/libraries/joomla/log/logger/callback.php', + '/libraries/joomla/log/logger/database.php', + '/libraries/joomla/log/logger/echo.php', + '/libraries/joomla/log/logger/formattedtext.php', + '/libraries/joomla/log/logger/messagequeue.php', + '/libraries/joomla/log/logger/syslog.php', + '/libraries/joomla/log/logger/w3c.php', + '/libraries/joomla/mail/helper.php', + '/libraries/joomla/mail/language/phpmailer.lang-joomla.php', + '/libraries/joomla/mail/mail.php', + '/libraries/joomla/mail/wrapper/helper.php', + '/libraries/joomla/microdata/microdata.php', + '/libraries/joomla/microdata/types.json', + '/libraries/joomla/object/object.php', + '/libraries/joomla/profiler/profiler.php', + '/libraries/joomla/session/exception/unsupported.php', + '/libraries/joomla/session/session.php', + '/libraries/joomla/string/punycode.php', + '/libraries/joomla/table/asset.php', + '/libraries/joomla/table/extension.php', + '/libraries/joomla/table/interface.php', + '/libraries/joomla/table/language.php', + '/libraries/joomla/table/nested.php', + '/libraries/joomla/table/observer.php', + '/libraries/joomla/table/observer/contenthistory.php', + '/libraries/joomla/table/observer/tags.php', + '/libraries/joomla/table/table.php', + '/libraries/joomla/table/update.php', + '/libraries/joomla/table/updatesite.php', + '/libraries/joomla/table/user.php', + '/libraries/joomla/table/usergroup.php', + '/libraries/joomla/table/viewlevel.php', + '/libraries/joomla/updater/adapters/collection.php', + '/libraries/joomla/updater/adapters/extension.php', + '/libraries/joomla/updater/update.php', + '/libraries/joomla/updater/updateadapter.php', + '/libraries/joomla/updater/updater.php', + '/libraries/joomla/uri/uri.php', + '/libraries/joomla/user/helper.php', + '/libraries/joomla/user/user.php', + '/libraries/joomla/user/wrapper/helper.php', + '/libraries/joomla/utilities/buffer.php', + '/libraries/joomla/utilities/utility.php', + '/libraries/legacy/access/rule.php', + '/libraries/legacy/access/rules.php', + '/libraries/legacy/application/cli.php', + '/libraries/legacy/application/daemon.php', + '/libraries/legacy/categories/categories.php', + '/libraries/legacy/controller/admin.php', + '/libraries/legacy/controller/form.php', + '/libraries/legacy/controller/legacy.php', + '/libraries/legacy/model/admin.php', + '/libraries/legacy/model/form.php', + '/libraries/legacy/model/item.php', + '/libraries/legacy/model/legacy.php', + '/libraries/legacy/model/list.php', + '/libraries/legacy/table/category.php', + '/libraries/legacy/table/content.php', + '/libraries/legacy/table/menu.php', + '/libraries/legacy/table/menu/type.php', + '/libraries/legacy/table/module.php', + '/libraries/legacy/view/categories.php', + '/libraries/legacy/view/category.php', + '/libraries/legacy/view/categoryfeed.php', + '/libraries/legacy/view/legacy.php', + '/libraries/legacy/web/client.php', + '/libraries/legacy/web/web.php', + '/media/editors/tinymce/langs/uk-UA.js', + '/media/system/js/fields/calendar-locales/zh.js', + + /* + * Joomla! 3.8.0 thru 3.9.0 + */ + '/administrator/components/com_users/controllers/profile.json.php', + '/administrator/includes/toolbar.php', + '/components/com_users/controllers/profile_base_json.php', + '/components/com_users/controllers/profile.json.php', + '/libraries/joomla/filesystem/file.php', + '/libraries/joomla/filesystem/folder.php', + '/libraries/joomla/filesystem/helper.php', + '/libraries/joomla/filesystem/meta/language/en-GB/en-GB.lib_joomla_filesystem_patcher.ini', + '/libraries/joomla/filesystem/patcher.php', + '/libraries/joomla/filesystem/path.php', + '/libraries/joomla/filesystem/stream.php', + '/libraries/joomla/filesystem/streams/string.php', + '/libraries/joomla/filesystem/support/stringcontroller.php', + '/libraries/joomla/filesystem/wrapper/file.php', + '/libraries/joomla/filesystem/wrapper/folder.php', + '/libraries/joomla/filesystem/wrapper/path.php', + '/libraries/src/Mail/language/phpmailer.lang-joomla.php', + '/plugins/captcha/recaptcha/recaptchalib.php', + + /* + * Joomla! 3.9.0 thru 3.10.0 + */ + '/SECURITY.md', + '/administrator/components/com_users/controllers/profile.json.php', + '/components/com_users/controllers/profile.json.php', + '/components/com_users/controllers/profile_base_json.php', + '/tests/unit/suites/libraries/cms/form/field/JFormFieldHelpsiteTest.php', + + /* + * Legacy FOF + */ + '/libraries/fof/controller.php', + '/libraries/fof/dispatcher.php', + '/libraries/fof/inflector.php', + '/libraries/fof/input.php', + '/libraries/fof/model.php', + '/libraries/fof/query.abstract.php', + '/libraries/fof/query.element.php', + '/libraries/fof/query.mysql.php', + '/libraries/fof/query.mysqli.php', + '/libraries/fof/query.sqlazure.php', + '/libraries/fof/query.sqlsrv.php', + '/libraries/fof/render.abstract.php', + '/libraries/fof/render.joomla.php', + '/libraries/fof/render.joomla3.php', + '/libraries/fof/render.strapper.php', + '/libraries/fof/string.utils.php', + '/libraries/fof/table.php', + '/libraries/fof/template.utils.php', + '/libraries/fof/toolbar.php', + '/libraries/fof/view.csv.php', + '/libraries/fof/view.html.php', + '/libraries/fof/view.json.php', + '/libraries/fof/view.php', + + /* + * Joomla! 3.9.7 + */ + '/administrator/components/com_joomlaupdate/access.xml', + + // Joomla! 3.9.13 + '/libraries/vendor/phpmailer/phpmailer/composer.lock', + + // Joomla! 3.9.17 + '/administrator/components/com_templates/controllers/template.php.orig', + + // Joomla! 3.9.21 + '/.github/SECURITY.md', + + // Joomla! 3.9.23 + '/.drone.jsonnet', + + // Joomla! added by the 3.9.23-rc1 + '/libraries/vendor/bin/lessify', + '/libraries/vendor/bin/lessify.bat', + '/libraries/vendor/bin/plessc', + '/libraries/vendor/bin/plessc.bat', + '/libraries/vendor/joomla/archive/.drone.jsonnet', + '/libraries/vendor/joomla/archive/.drone.yml', + '/libraries/vendor/joomla/string/.drone.jsonnet', + '/libraries/vendor/joomla/string/.drone.yml', + '/libraries/vendor/leafo/lessphp/.drone.yml', + '/libraries/vendor/leafo/lessphp/phpunit.xml.dist', + '/libraries/vendor/leafo/lessphp/ruleset.xml', + + // Joomla 3.10.0 + '/libraries/joomla/base/adapter.php', + '/libraries/joomla/base/adapterinstance.php', ); // TODO There is an issue while deleting folders using the ftp mode @@ -1804,6 +2088,9 @@ public function deleteUnexistingFiles() '/libraries/joomla/image/filters', '/libraries/joomla/log/loggers', // Joomla! 3.1 + '/libraries/cms/feed/parser/rss', + '/libraries/cms/feed/parser', + '/libraries/cms/feed', '/libraries/joomla/form/rules', '/libraries/joomla/html/language/en-GB', '/libraries/joomla/html/language', @@ -1885,10 +2172,6 @@ public function deleteUnexistingFiles() '/administrator/components/com_cache/layouts/joomla/searchtools', '/administrator/components/com_cache/layouts/joomla', '/administrator/components/com_cache/layouts', - '/administrator/components/com_languages/layouts/joomla/searchtools/default', - '/administrator/components/com_languages/layouts/joomla/searchtools', - '/administrator/components/com_languages/layouts/joomla', - '/administrator/components/com_languages/layouts', '/administrator/components/com_modules/layouts/joomla/searchtools/default', '/administrator/components/com_modules/layouts/joomla/searchtools', '/administrator/components/com_modules/layouts/joomla', @@ -1899,6 +2182,120 @@ public function deleteUnexistingFiles() '/administrator/templates/hathor/html/mod_menu', '/administrator/components/com_messages/layouts/toolbar', '/administrator/components/com_messages/layouts', + // Joomla! 3.7.4 + '/components/com_fields/controllers', + // Joomla! 3.8.0 + '/administrator/modules/mod_menu/preset', + '/libraries/cms/application', + '/libraries/cms/authentication', + '/libraries/cms/captcha', + '/libraries/cms/component/exception', + '/libraries/cms/component/router/rules', + '/libraries/cms/component/router', + '/libraries/cms/component', + '/libraries/cms/editor', + '/libraries/cms/error', + '/libraries/cms/extension', + '/libraries/cms/form/field', + '/libraries/cms/form/rule', + '/libraries/cms/form', + '/libraries/cms/help', + '/libraries/cms/helper', + '/libraries/cms/installer/adapter', + '/libraries/cms/installer/manifest', + '/libraries/cms/installer', + '/libraries/cms/language', + '/libraries/cms/layout', + '/libraries/cms/library', + '/libraries/cms/menu', + '/libraries/cms/module', + '/libraries/cms/pagination', + '/libraries/cms/pathway', + '/libraries/cms/plugin', + '/libraries/cms/response', + '/libraries/cms/router', + '/libraries/cms/schema/changeitem', + '/libraries/cms/schema', + '/libraries/cms/search', + '/libraries/cms/table', + '/libraries/cms/toolbar/button', + '/libraries/cms/toolbar', + '/libraries/cms/ucm', + '/libraries/cms/version', + '/libraries/joomla/access/exception', + '/libraries/joomla/access/wrapper', + '/libraries/joomla/access', + '/libraries/joomla/association/extension', + '/libraries/joomla/association', + '/libraries/joomla/authentication', + '/libraries/joomla/cache/controller', + '/libraries/joomla/cache/exception', + '/libraries/joomla/cache/storage', + '/libraries/joomla/cache', + '/libraries/joomla/client/wrapper', + '/libraries/joomla/client', + '/libraries/joomla/crypt/cipher', + '/libraries/joomla/crypt/password', + '/libraries/joomla/crypt', + '/libraries/joomla/date', + '/libraries/joomla/document/feed/renderer', + '/libraries/joomla/document/feed', + '/libraries/joomla/document/html/renderer', + '/libraries/joomla/document/html', + '/libraries/joomla/document/renderer/feed', + '/libraries/joomla/document/renderer/html', + '/libraries/joomla/document/renderer', + '/libraries/joomla/document', + '/libraries/joomla/environment', + '/libraries/joomla/feed/parser/rss', + '/libraries/joomla/feed/parser', + '/libraries/joomla/feed', + '/libraries/joomla/filter/wrapper', + '/libraries/joomla/filter', + '/libraries/joomla/form/rule', + '/libraries/joomla/form/wrapper', + '/libraries/joomla/http/transport', + '/libraries/joomla/http/wrapper', + '/libraries/joomla/http', + '/libraries/joomla/image/filter', + '/libraries/joomla/image', + '/libraries/joomla/input', + '/libraries/joomla/language/stemmer', + '/libraries/joomla/language/wrapper', + '/libraries/joomla/language', + '/libraries/joomla/log/logger', + '/libraries/joomla/log', + '/libraries/joomla/mail/language', + '/libraries/joomla/mail/wrapper', + '/libraries/joomla/mail', + '/libraries/joomla/microdata', + '/libraries/joomla/object', + '/libraries/joomla/profiler', + '/libraries/joomla/session/exception', + '/libraries/joomla/table', + '/libraries/joomla/updater/adapters', + '/libraries/joomla/updater', + '/libraries/joomla/uri', + '/libraries/joomla/user/wrapper', + '/libraries/joomla/user', + '/libraries/legacy/access', + '/libraries/legacy/categories', + '/libraries/legacy/controller', + '/libraries/legacy/model', + '/libraries/legacy/table/menu', + '/libraries/legacy/view', + '/libraries/legacy/web', + '/media/editors/tinymce/plugins/jdragdrop', + // Joomla! 3.9.0 + '/libraries/joomla/filesystem/meta/language/en-GB', + '/libraries/joomla/filesystem/meta/language', + '/libraries/joomla/filesystem/meta', + '/libraries/joomla/filesystem/streams', + '/libraries/joomla/filesystem/support', + '/libraries/joomla/filesystem/wrapper', + '/libraries/joomla/filesystem', + // Joomla 3.10.0 + '/libraries/joomla/base', ); jimport('joomla.filesystem.file'); @@ -1930,6 +2327,8 @@ public function deleteUnexistingFiles() { JFile::delete(JPATH_ROOT . '/administrator/manifests/packages/pkg_weblinks.xml'); } + + $this->fixFilenameCasing(); } /** @@ -1972,6 +2371,8 @@ public function updateAssets($installer) 'com_postinstall', 'com_fields', 'com_associations', + 'com_privacy', + 'com_actionlogs', ); foreach ($newComponents as $component) @@ -2086,11 +2487,19 @@ public function convertTablesToUtf8mb4($doDbFixMsg = false) // Set required conversion status if ($db->hasUTF8mb4Support()) { - $converted = 2; + $convertedStep1 = 2; + $convertedStep2 = 4; + + // The first step has to be repeated if it has not been run (converted = 4 in database) + $convertedRequired = 5; } else { - $converted = 1; + $convertedStep1 = 1; + $convertedStep2 = 3; + + // All done after step 2 + $convertedRequired = 3; } // Check conversion status in database @@ -2116,72 +2525,122 @@ public function convertTablesToUtf8mb4($doDbFixMsg = false) return; } - // Nothing to do, saved conversion status from DB is equal to required - if ($convertedDB == $converted) + // Nothing to do, saved conversion status from DB is equal to required final status + if ($convertedDB == $convertedRequired) { return; } - // Step 1: Drop indexes later to be added again with column lengths limitations at step 2 - $fileName1 = JPATH_ROOT . '/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-01.sql'; + $converted = $convertedDB; + $hasErrors = false; - if (is_file($fileName1)) + // Steps 1 and 2: Convert core tables if necessary and not to be done at later steps + if ($convertedDB < $convertedStep1 || ($convertedRequired == 5 && ($convertedDB == 3 || $convertedDB == 4))) { - $fileContents1 = @file_get_contents($fileName1); - $queries1 = $db->splitSql($fileContents1); + // Step 1: Drop indexes later to be added again with column lengths limitations at step 2 + $fileName1 = JPATH_ROOT . '/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-01.sql'; - if (!empty($queries1)) + if (is_file($fileName1)) { - foreach ($queries1 as $query1) + $fileContents1 = @file_get_contents($fileName1); + $queries1 = $db->splitSql($fileContents1); + + if (!empty($queries1)) { - try + foreach ($queries1 as $query1) { - $db->setQuery($query1)->execute(); + try + { + $db->setQuery($query1)->execute(); + } + catch (Exception $e) + { + // If the query fails we will go on. It just means the index to be dropped does not exist. + } } - catch (Exception $e) + } + } + + // Step 2: Perform the index modifications and conversions + $fileName2 = JPATH_ROOT . '/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-02.sql'; + + if (is_file($fileName2)) + { + $fileContents2 = @file_get_contents($fileName2); + $queries2 = $db->splitSql($fileContents2); + + if (!empty($queries2)) + { + foreach ($queries2 as $query2) { - // If the query fails we will go on. It just means the index to be dropped does not exist. + try + { + $db->setQuery($db->convertUtf8mb4QueryToUtf8($query2))->execute(); + } + catch (Exception $e) + { + $hasErrors = true; + + // Still render the error message from the Exception object + JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } } } } - } - // Step 2: Perform the index modifications and conversions - $fileName2 = JPATH_ROOT . '/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-02.sql'; + if (!$hasErrors) + { + $converted = $convertedStep1; + } + } - if (is_file($fileName2)) + // Step 3: Convert action logs and privacy suite tables if necessary and conversion hasn't failed before + if (!$hasErrors && $convertedDB < $convertedStep2) { - $fileContents2 = @file_get_contents($fileName2); - $queries2 = $db->splitSql($fileContents2); + $fileName3 = JPATH_ROOT . '/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-03.sql'; - if (!empty($queries2)) + if (is_file($fileName3)) { - foreach ($queries2 as $query2) + $fileContents3 = @file_get_contents($fileName3); + $queries3 = $db->splitSql($fileContents3); + + if (!empty($queries3)) { - try + foreach ($queries3 as $query3) { - $db->setQuery($db->convertUtf8mb4QueryToUtf8($query2))->execute(); - } - catch (Exception $e) - { - $converted = 0; - - // Still render the error message from the Exception object - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + try + { + $db->setQuery($db->convertUtf8mb4QueryToUtf8($query3))->execute(); + } + catch (Exception $e) + { + $hasErrors = true; + + // Still render the error message from the Exception object + JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } } } } } - if ($doDbFixMsg && $converted == 0) + if (!$hasErrors) + { + $converted = $convertedRequired; + } + + if ($doDbFixMsg && $hasErrors) { // Show an error message telling to check database problems JFactory::getApplication()->enqueueMessage(JText::_('JLIB_DATABASE_ERROR_DATABASE_UPGRADE_FAILED'), 'error'); } - // Set flag in database if the update is done. - $db->setQuery('UPDATE ' . $db->quoteName('#__utf8_conversion') - . ' SET ' . $db->quoteName('converted') . ' = ' . $converted . ';')->execute(); + // Set flag in database if the conversion status has changed. + if ($converted != $convertedDB) + { + $db->setQuery('UPDATE ' . $db->quoteName('#__utf8_conversion') + . ' SET ' . $db->quoteName('converted') . ' = ' . $converted . ';')->execute(); + } } /** @@ -2203,4 +2662,67 @@ private function cleanJoomlaCache() $model->setState('client_id', 1); $model->clean(); } + + /** + * Renames or removes incorrectly cased files. + * + * @return void + * + * @since 3.9.25 + */ + protected function fixFilenameCasing() + { + $files = array( + '/libraries/src/Filesystem/Support/Stringcontroller.php' => '/libraries/src/Filesystem/Support/StringController.php', + '/libraries/vendor/paragonie/sodium_compat/src/Core/Xsalsa20.php' => '/libraries/vendor/paragonie/sodium_compat/src/Core/XSalsa20.php', + '/media/mod_languages/images/si_LK.gif' => '/media/mod_languages/images/si_lk.gif', + ); + + foreach ($files as $old => $expected) + { + $oldRealpath = realpath(JPATH_ROOT . $old); + + // On Unix without incorrectly cased file. + if ($oldRealpath === false) + { + continue; + } + + $oldBasename = basename($oldRealpath); + $newRealpath = realpath(JPATH_ROOT . $expected); + $newBasename = basename($newRealpath); + $expectedBasename = basename($expected); + + // On Windows or Unix with only the incorrectly cased file. + if ($newBasename !== $expectedBasename) + { + // Rename the file. + rename(JPATH_ROOT . $old, JPATH_ROOT . $old . '.tmp'); + rename(JPATH_ROOT . $old . '.tmp', JPATH_ROOT . $expected); + + continue; + } + + // There might still be an incorrectly cased file on other OS than Windows. + if ($oldBasename === basename($old)) + { + // Check if case-insensitive file system, eg on OSX. + if (fileinode($oldRealpath) === fileinode($newRealpath)) + { + // Check deeper because even realpath or glob might not return the actual case. + if (!in_array($expectedBasename, scandir(dirname($newRealpath)))) + { + // Rename the file. + rename(JPATH_ROOT . $old, JPATH_ROOT . $old . '.tmp'); + rename(JPATH_ROOT . $old . '.tmp', JPATH_ROOT . $expected); + } + } + else + { + // On Unix with both files: Delete the incorrectly cased file. + unlink(JPATH_ROOT . $old); + } + } + } + } } diff --git a/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-01.sql b/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-01.sql index ef2951ee7e976..843ab1256a981 100644 --- a/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-01.sql +++ b/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-01.sql @@ -16,6 +16,7 @@ ALTER TABLE `#__banners` DROP KEY `idx_metakey_prefix`; ALTER TABLE `#__banner_clients` DROP KEY `idx_metakey_prefix`; ALTER TABLE `#__categories` DROP KEY `idx_path`; ALTER TABLE `#__categories` DROP KEY `idx_alias`; +ALTER TABLE `#__content` DROP KEY `idx_alias`; ALTER TABLE `#__content_types` DROP KEY `idx_alias`; ALTER TABLE `#__fields` DROP KEY `idx_context`; ALTER TABLE `#__fields_groups` DROP KEY `idx_context`; diff --git a/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-02.sql b/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-02.sql index 699b6ed5454be..52b04a2d7f1c9 100644 --- a/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-02.sql +++ b/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-02.sql @@ -41,14 +41,14 @@ ALTER TABLE `#__newsfeeds` MODIFY `alias` varchar(400) NOT NULL DEFAULT ''; ALTER TABLE `#__tags` MODIFY `path` varchar(400) NOT NULL DEFAULT ''; ALTER TABLE `#__tags` MODIFY `alias` varchar(400) NOT NULL DEFAULT ''; ALTER TABLE `#__ucm_content` MODIFY `core_type_alias` varchar(400) NOT NULL DEFAULT '' COMMENT 'FK to the content types table'; -ALTER TABLE `#__ucm_content` MODIFY `core_title` varchar(400) NOT NULL; +ALTER TABLE `#__ucm_content` MODIFY `core_title` varchar(400) NOT NULL DEFAULT ''; ALTER TABLE `#__ucm_content` MODIFY `core_alias` varchar(400) NOT NULL DEFAULT ''; ALTER TABLE `#__users` MODIFY `name` varchar(400) NOT NULL DEFAULT ''; -- --- Step 2.2: Convert all tables to utf8mb4 chracter set with utf8mb4_unicode_ci collation +-- Step 2.2: Convert all tables to utf8mb4 character set with utf8mb4_unicode_ci collation -- except #__finder_xxx tables, those will have utf8mb4_general_ci collation. --- Note: The database driver for mysql will change utf8mb4 to utf8 if utf8mb4 is not supported +-- Note: The database driver for mysql will change utf8mb4 to utf8 if utf8mb4 is not supported -- ALTER TABLE `#__assets` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; @@ -224,6 +224,7 @@ ALTER TABLE `#__banners` ADD KEY `idx_metakey_prefix` (`metakey_prefix`(100)); ALTER TABLE `#__banner_clients` ADD KEY `idx_metakey_prefix` (`metakey_prefix`(100)); ALTER TABLE `#__categories` ADD KEY `idx_path` (`path`(100)); ALTER TABLE `#__categories` ADD KEY `idx_alias` (`alias`(100)); +ALTER TABLE `#__content` ADD KEY `idx_alias` (`alias`(191)); ALTER TABLE `#__content_types` ADD KEY `idx_alias` (`type_alias`(100)); ALTER TABLE `#__fields` ADD KEY `idx_context` (`context`(191)); ALTER TABLE `#__fields_groups` ADD KEY `idx_context` (`context`(191)); diff --git a/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-03.sql b/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-03.sql new file mode 100644 index 0000000000000..93fcf9ee3d18d --- /dev/null +++ b/administrator/components/com_admin/sql/others/mysql/utf8mb4-conversion-03.sql @@ -0,0 +1,33 @@ +-- +-- Step 3 of the UTF-8 Multibyte (utf8mb4) conversion for MySQL +-- +-- Convert the tables for action logs and the privacy suite which have been +-- forgotten to be added to the utf8mb4 conversion before. +-- +-- This file here will be processed with reporting exceptions, in opposite +-- to the file for step 1. +-- + +-- +-- Step 3.1: Convert action logs and privacy suite tables to utf8mb4 character set with +-- utf8mb4_unicode_ci collation +-- Note: The database driver for mysql will change utf8mb4 to utf8 if utf8mb4 is not supported +-- + +ALTER TABLE `#__action_logs` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__action_logs_extensions` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__action_logs_users` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__action_log_config` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__privacy_consents` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__privacy_requests` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- +-- Step 3.2: Set default character set and collation for previously converted tables +-- + +ALTER TABLE `#__action_logs` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__action_logs_extensions` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__action_logs_users` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__action_log_config` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__privacy_consents` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `#__privacy_requests` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-06.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-06.sql index 7ee6938657c94..783643c396a66 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-06.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-06.sql @@ -2,8 +2,8 @@ INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder` (437, 'plg_quickicon_joomlaupdate', 'plugin', 'joomlaupdate', 'quickicon', 0, 1, 1, 1, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (438, 'plg_quickicon_extensionupdate', 'plugin', 'extensionupdate', 'quickicon', 0, 1, 1, 1, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); -ALTER TABLE `#__update_sites` ADD COLUMN `last_check_timestamp` bigint(20) DEFAULT '0' AFTER `enabled`; +ALTER TABLE `#__update_sites` ADD COLUMN `last_check_timestamp` bigint DEFAULT '0' AFTER `enabled`; REPLACE INTO `#__update_sites` VALUES -(1, 'Joomla Core', 'collection', 'http://update.joomla.org/core/list.xml', 1, 0), -(2, 'Joomla Extension Directory', 'collection', 'http://update.joomla.org/jed/list.xml', 1, 0); +(1, 'Joomla Core', 'collection', 'https://update.joomla.org/core/list.xml', 1, 0), +(2, 'Joomla Extension Directory', 'collection', 'https://update.joomla.org/jed/list.xml', 1, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-16.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-16.sql index 77ed80d3fc383..9c42fc9636b8d 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-16.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-16.sql @@ -1,5 +1,5 @@ CREATE TABLE IF NOT EXISTS `#__overrider` ( - `id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', + `id` int NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', `constant` varchar(255) NOT NULL, `string` text NOT NULL, `file` varchar(255) NOT NULL, diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-19.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-19.sql index 94e9c9ae44543..36d3af1003152 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-19.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-19.sql @@ -1,15 +1,15 @@ CREATE TABLE IF NOT EXISTS `#__user_notes` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `user_id` int(10) unsigned NOT NULL DEFAULT '0', - `catid` int(10) unsigned NOT NULL DEFAULT '0', + `id` int unsigned NOT NULL AUTO_INCREMENT, + `user_id` int unsigned NOT NULL DEFAULT '0', + `catid` int unsigned NOT NULL DEFAULT '0', `subject` varchar(100) NOT NULL DEFAULT '', `body` text NOT NULL, - `state` tinyint(3) NOT NULL DEFAULT '0', - `checked_out` int(10) unsigned NOT NULL DEFAULT '0', + `state` tinyint NOT NULL DEFAULT '0', + `checked_out` int unsigned NOT NULL DEFAULT '0', `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_user_id` int(10) unsigned NOT NULL DEFAULT '0', + `created_user_id` int unsigned NOT NULL DEFAULT '0', `created_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `modified_user_id` int(10) unsigned NOT NULL, + `modified_user_id` int unsigned NOT NULL, `modified_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `review_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `publish_up` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-1.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-1.sql index 7c1615481965e..c7ced55b9c865 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-1.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-1.sql @@ -2,7 +2,7 @@ INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder` (27, 'com_finder', 'component', 'com_finder', '', 1, 1, 0, 0, '', '{"show_description":"1","description_length":255,"allow_empty_query":"0","show_url":"1","show_advanced":"1","expand_advanced":"0","show_date_filters":"0","highlight_terms":"1","opensearch_name":"","opensearch_description":"","batch_size":"50","memory_table_limit":30000,"title_multiplier":"1.7","text_multiplier":"0.7","meta_multiplier":"1.2","path_multiplier":"2.0","misc_multiplier":"0.3","stemmer":"porter_en"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (439, 'plg_captcha_recaptcha', 'plugin', 'recaptcha', 'captcha', 0, 1, 1, 0, '{}', '{"public_key":"","private_key":"","theme":"clean"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (440, 'plg_system_highlight', 'plugin', 'highlight', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 7, 0), -(441, 'plg_content_finder', 'plugin', 'finder', 'content', 0, 0, 1, 0, '{"legacy":false,"name":"plg_content_finder","type":"plugin","creationDate":"December 2011","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"1.7.0","description":"PLG_CONTENT_FINDER_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(441, 'plg_content_finder', 'plugin', 'finder', 'content', 0, 0, 1, 0, '{"legacy":false,"name":"plg_content_finder","type":"plugin","creationDate":"December 2011","author":"Joomla! Project","copyright":"(C) 2011 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"1.7.0","description":"PLG_CONTENT_FINDER_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (442, 'plg_finder_categories', 'plugin', 'categories', 'finder', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 1, 0), (443, 'plg_finder_contacts', 'plugin', 'contacts', 'finder', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 2, 0), (444, 'plg_finder_content', 'plugin', 'content', 'finder', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 3, 0), diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-2.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-2.sql index dd1a0d44f16c3..16d7f6d115d3f 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-2.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-2.sql @@ -1,6 +1,6 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -8,8 +8,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( ) DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `#__finder_links_terms1` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -17,8 +17,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms1` ( ) DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `#__finder_links_terms2` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -26,8 +26,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms2` ( ) DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `#__finder_links_terms3` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -36,8 +36,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms3` ( CREATE TABLE IF NOT EXISTS `#__finder_links_terms4` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -46,8 +46,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms4` ( CREATE TABLE IF NOT EXISTS `#__finder_links_terms5` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -56,8 +56,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms5` ( CREATE TABLE IF NOT EXISTS `#__finder_links_terms6` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -66,8 +66,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms6` ( CREATE TABLE IF NOT EXISTS `#__finder_links_terms7` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -76,8 +76,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms7` ( CREATE TABLE IF NOT EXISTS `#__finder_links_terms8` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -86,8 +86,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms8` ( CREATE TABLE IF NOT EXISTS `#__finder_links_terms9` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -96,8 +96,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms9` ( CREATE TABLE IF NOT EXISTS `#__finder_links_termsa` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -106,8 +106,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsa` ( CREATE TABLE IF NOT EXISTS `#__finder_links_termsb` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -116,8 +116,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsb` ( CREATE TABLE IF NOT EXISTS `#__finder_links_termsc` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -126,8 +126,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsc` ( CREATE TABLE IF NOT EXISTS `#__finder_links_termsd` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -136,8 +136,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsd` ( CREATE TABLE IF NOT EXISTS `#__finder_links_termse` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -146,8 +146,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termse` ( CREATE TABLE IF NOT EXISTS `#__finder_links_termsf` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -156,12 +156,12 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsf` ( CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` ( - `id` int(10) unsigned NOT NULL auto_increment, - `parent_id` int(10) unsigned NOT NULL default '0', + `id` int unsigned NOT NULL auto_increment, + `parent_id` int unsigned NOT NULL default '0', `title` varchar(255) NOT NULL, - `state` tinyint(1) unsigned NOT NULL default '1', - `access` tinyint(1) unsigned NOT NULL default '0', - `ordering` tinyint(1) unsigned NOT NULL default '0', + `state` tinyint unsigned NOT NULL default '1', + `access` tinyint unsigned NOT NULL default '0', + `ordering` tinyint unsigned NOT NULL default '0', PRIMARY KEY (`id`), KEY `parent_id` (`parent_id`), KEY `state` (`state`), @@ -172,8 +172,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` ( CREATE TABLE IF NOT EXISTS `#__finder_taxonomy_map` ( - `link_id` int(10) unsigned NOT NULL, - `node_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `node_id` int unsigned NOT NULL, PRIMARY KEY (`link_id`,`node_id`), KEY `link_id` (`link_id`), KEY `node_id` (`node_id`) @@ -181,14 +181,14 @@ CREATE TABLE IF NOT EXISTS `#__finder_taxonomy_map` ( CREATE TABLE IF NOT EXISTS `#__finder_terms` ( - `term_id` int(10) unsigned NOT NULL auto_increment, + `term_id` int unsigned NOT NULL auto_increment, `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, - `common` tinyint(1) unsigned NOT NULL default '0', - `phrase` tinyint(1) unsigned NOT NULL default '0', + `common` tinyint unsigned NOT NULL default '0', + `phrase` tinyint unsigned NOT NULL default '0', `weight` float unsigned NOT NULL default '0', `soundex` varchar(75) NOT NULL, - `links` int(10) NOT NULL default '0', + `links` int NOT NULL default '0', PRIMARY KEY (`term_id`), UNIQUE KEY `idx_term` (`term`), KEY `idx_term_phrase` (`term`,`phrase`), @@ -208,24 +208,24 @@ CREATE TABLE IF NOT EXISTS `#__finder_terms_common` ( CREATE TABLE IF NOT EXISTS `#__finder_tokens` ( `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, - `common` tinyint(1) unsigned NOT NULL default '0', - `phrase` tinyint(1) unsigned NOT NULL default '0', + `common` tinyint unsigned NOT NULL default '0', + `phrase` tinyint unsigned NOT NULL default '0', `weight` float unsigned NOT NULL default '1', - `context` tinyint(1) unsigned NOT NULL default '2', + `context` tinyint unsigned NOT NULL default '2', KEY `idx_word` (`term`), KEY `idx_context` (`context`) ) ENGINE=MEMORY DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `#__finder_tokens_aggregate` ( - `term_id` int(10) unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `map_suffix` char(1) NOT NULL, `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, - `common` tinyint(1) unsigned NOT NULL default '0', - `phrase` tinyint(1) unsigned NOT NULL default '0', + `common` tinyint unsigned NOT NULL default '0', + `phrase` tinyint unsigned NOT NULL default '0', `term_weight` float unsigned NOT NULL, - `context` tinyint(1) unsigned NOT NULL default '2', + `context` tinyint unsigned NOT NULL default '2', `context_weight` float unsigned NOT NULL, `total_weight` float unsigned NOT NULL, KEY `token` (`term`), @@ -234,7 +234,7 @@ CREATE TABLE IF NOT EXISTS `#__finder_tokens_aggregate` ( CREATE TABLE IF NOT EXISTS `#__finder_types` ( - `id` int(10) unsigned NOT NULL auto_increment, + `id` int unsigned NOT NULL auto_increment, `title` varchar(100) NOT NULL, `mime` varchar(100) NOT NULL, PRIMARY KEY (`id`), diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-23.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-23.sql index 5dae6e534ee56..ee3e643e7c0f5 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-23.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-23.sql @@ -1,32 +1,32 @@ CREATE TABLE IF NOT EXISTS `#__finder_filters` ( - `filter_id` int(10) unsigned NOT NULL auto_increment, + `filter_id` int unsigned NOT NULL auto_increment, `title` varchar(255) NOT NULL, `alias` varchar(255) NOT NULL, - `state` tinyint(1) NOT NULL default '1', + `state` tinyint NOT NULL default '1', `created` datetime NOT NULL default '0000-00-00 00:00:00', - `created_by` int(10) unsigned NOT NULL, + `created_by` int unsigned NOT NULL, `created_by_alias` varchar(255) NOT NULL, `modified` datetime NOT NULL default '0000-00-00 00:00:00', - `modified_by` int(10) unsigned NOT NULL default '0', - `checked_out` int(10) unsigned NOT NULL default '0', + `modified_by` int unsigned NOT NULL default '0', + `checked_out` int unsigned NOT NULL default '0', `checked_out_time` datetime NOT NULL default '0000-00-00 00:00:00', - `map_count` int(10) unsigned NOT NULL default '0', + `map_count` int unsigned NOT NULL default '0', `data` text NOT NULL, `params` mediumtext, PRIMARY KEY (`filter_id`) ) DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `#__finder_links` ( - `link_id` int(10) unsigned NOT NULL auto_increment, + `link_id` int unsigned NOT NULL auto_increment, `url` varchar(255) NOT NULL, `route` varchar(255) NOT NULL, `title` varchar(255) default NULL, `description` varchar(255) default NULL, `indexdate` datetime NOT NULL default '0000-00-00 00:00:00', `md5sum` varchar(32) default NULL, - `published` tinyint(1) NOT NULL default '1', - `state` int(5) default '1', - `access` int(5) default '0', + `published` tinyint NOT NULL default '1', + `state` int default '1', + `access` int default '0', `language` varchar(8) NOT NULL, `publish_start_date` datetime NOT NULL default '0000-00-00 00:00:00', `publish_end_date` datetime NOT NULL default '0000-00-00 00:00:00', @@ -34,7 +34,7 @@ CREATE TABLE IF NOT EXISTS `#__finder_links` ( `end_date` datetime NOT NULL default '0000-00-00 00:00:00', `list_price` double unsigned NOT NULL default '0', `sale_price` double unsigned NOT NULL default '0', - `type_id` int(11) NOT NULL, + `type_id` int NOT NULL, `object` mediumblob NOT NULL, PRIMARY KEY (`link_id`), KEY `idx_type` (`type_id`), diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.1-2012-01-26.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.1-2012-01-26.sql index 012462ebac59e..c8755d0d6b72c 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.1-2012-01-26.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.1-2012-01-26.sql @@ -1,8 +1,8 @@ INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES -(314, 'mod_version', 'module', 'mod_version', '', 1, 1, 1, 0, '{"legacy":false,"name":"mod_version","type":"module","creationDate":"January 2012","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"2.5.0","description":"MOD_VERSION_XML_DESCRIPTION","group":""}', '{"format":"short","product":"1","cache":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0); +(314, 'mod_version', 'module', 'mod_version', '', 1, 1, 1, 0, '{"legacy":false,"name":"mod_version","type":"module","creationDate":"January 2012","author":"Joomla! Project","copyright":"(C) 2012 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"2.5.0","description":"MOD_VERSION_XML_DESCRIPTION","group":""}', '{"format":"short","product":"1","cache":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0); INSERT INTO `#__modules` (`title`, `note`, `content`, `ordering`, `position`, `checked_out`, `checked_out_time`, `publish_up`, `publish_down`, `published`, `module`, `access`, `showtitle`, `params`, `client_id`, `language`) VALUES ('Joomla Version', '', '', 1, 'footer', 0, '0000-00-00 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 1, 'mod_version', 3, 1, '{"format":"short","product":"1","layout":"_:default","moduleclass_sfx":"","cache":"0"}', 1, '*'); -INSERT INTO `#__modules_menu` (`moduleid`, `menuid`) VALUES -(LAST_INSERT_ID(), 0); \ No newline at end of file +INSERT INTO `#__modules_menu` (`moduleid`, `menuid`) VALUES +(LAST_INSERT_ID(), 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.4-2012-03-18.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.4-2012-03-18.sql index d94a5b5c19115..12622ca3e9a53 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.4-2012-03-18.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.4-2012-03-18.sql @@ -1,5 +1,5 @@ INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES -(28, 'com_joomlaupdate', 'component', 'com_joomlaupdate', '', 1, 1, 0, 1, '{"legacy":false,"name":"com_joomlaupdate","type":"component","creationDate":"February 2012","author":"Joomla! Project","copyright":"(C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"2.5.2","description":"COM_JOOMLAUPDATE_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); +(28, 'com_joomlaupdate', 'component', 'com_joomlaupdate', '', 1, 1, 0, 1, '{"legacy":false,"name":"com_joomlaupdate","type":"component","creationDate":"February 2012","author":"Joomla! Project","copyright":"(C) 2012 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"2.5.2","description":"COM_JOOMLAUPDATE_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); INSERT INTO `#__menu` (`menutype`, `title`, `alias`, `note`, `path`, `link`, `type`, `published`, `parent_id`, `level`, `component_id`, `ordering`, `checked_out`, `checked_out_time`, `browserNav`, `access`, `img`, `template_style_id`, `params`, `lft`, `rgt`, `home`, `language`, `client_id`) VALUES ('menu', 'com_joomlaupdate', 'Joomla! Update', '', 'Joomla! Update', 'index.php?option=com_joomlaupdate', 'component', 0, 1, 1, 28, 0, 0, '0000-00-00 00:00:00', 0, 0, 'class:joomlaupdate', 0, '', 41, 42, 0, '*', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.5.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.5.sql index c73b70888bb22..6ba668bd49d65 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.5.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.5.sql @@ -1,3 +1,3 @@ -ALTER TABLE `#__redirect_links` ADD COLUMN `hits` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `comment`; +ALTER TABLE `#__redirect_links` ADD COLUMN `hits` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `comment`; ALTER TABLE `#__users` ADD COLUMN `lastResetTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Date of last password reset'; -ALTER TABLE `#__users` ADD COLUMN `resetCount` int(11) NOT NULL DEFAULT '0' COMMENT 'Count of password resets since lastResetTime'; \ No newline at end of file +ALTER TABLE `#__users` ADD COLUMN `resetCount` int NOT NULL DEFAULT '0' COMMENT 'Count of password resets since lastResetTime'; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.7.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.7.sql index 32097972fb583..edb2486371704 100644 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.7.sql +++ b/administrator/components/com_admin/sql/updates/mysql/2.5.7.sql @@ -1 +1 @@ -INSERT INTO `#__update_sites` (`name`, `type`, `location`, `enabled`, `last_check_timestamp`) VALUES('Accredited Joomla! Translations','collection','http://update.joomla.org/language/translationlist.xml',1,0);INSERT INTO `#__update_sites_extensions` (`update_site_id`, `extension_id`) VALUES(LAST_INSERT_ID(),600);UPDATE `#__assets` SET name=REPLACE( name, 'com_user.notes.category','com_users.category' );UPDATE `#__categories` SET extension=REPLACE( extension, 'com_user.notes.category','com_users.category' ); \ No newline at end of file +INSERT INTO `#__update_sites` (`name`, `type`, `location`, `enabled`, `last_check_timestamp`) VALUES('Accredited Joomla! Translations','collection','https://update.joomla.org/language/translationlist.xml',1,0);INSERT INTO `#__update_sites_extensions` (`update_site_id`, `extension_id`) VALUES(LAST_INSERT_ID(),600);UPDATE `#__assets` SET name=REPLACE( name, 'com_user.notes.category','com_users.category' );UPDATE `#__categories` SET extension=REPLACE( extension, 'com_user.notes.category','com_users.category' ); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.0.0.sql b/administrator/components/com_admin/sql/updates/mysql/3.0.0.sql index 9476cf457d332..8ce2faaf88f22 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.0.0.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.0.0.sql @@ -93,17 +93,17 @@ ALTER TABLE `#__user_usergroup_map` ENGINE=InnoDB; ALTER TABLE `#__viewlevels` ENGINE=InnoDB; ALTER TABLE `#__newsfeeds` ADD COLUMN `description` text NOT NULL; -ALTER TABLE `#__newsfeeds` ADD COLUMN `version` int(10) unsigned NOT NULL DEFAULT '1'; -ALTER TABLE `#__newsfeeds` ADD COLUMN `hits` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `#__newsfeeds` ADD COLUMN `version` int unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `#__newsfeeds` ADD COLUMN `hits` int unsigned NOT NULL DEFAULT '0'; ALTER TABLE `#__newsfeeds` ADD COLUMN `images` text NOT NULL; -ALTER TABLE `#__contact_details` ADD COLUMN `version` int(10) unsigned NOT NULL DEFAULT '1'; -ALTER TABLE `#__contact_details` ADD COLUMN `hits` int(10) unsigned NOT NULL DEFAULT '0'; -ALTER TABLE `#__banners` ADD COLUMN `created_by` int(10) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `#__contact_details` ADD COLUMN `version` int unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `#__contact_details` ADD COLUMN `hits` int unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `#__banners` ADD COLUMN `created_by` int unsigned NOT NULL DEFAULT '0'; ALTER TABLE `#__banners` ADD COLUMN `created_by_alias` varchar(255) NOT NULL DEFAULT ''; ALTER TABLE `#__banners` ADD COLUMN `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'; -ALTER TABLE `#__banners` ADD COLUMN `modified_by` int(10) unsigned NOT NULL DEFAULT '0'; -ALTER TABLE `#__banners` ADD COLUMN `version` int(10) unsigned NOT NULL DEFAULT '1'; -ALTER TABLE `#__categories` ADD COLUMN `version` int(10) unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `#__banners` ADD COLUMN `modified_by` int unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `#__banners` ADD COLUMN `version` int unsigned NOT NULL DEFAULT '1'; +ALTER TABLE `#__categories` ADD COLUMN `version` int unsigned NOT NULL DEFAULT '1'; UPDATE `#__assets` SET name=REPLACE( name, 'com_user.notes.category','com_users.category' ); UPDATE `#__categories` SET extension=REPLACE( extension, 'com_user.notes.category','com_users.category' ); @@ -114,12 +114,12 @@ ALTER TABLE `#__finder_tokens_aggregate` ADD COLUMN `language` char(3) NOT NULL INSERT INTO `#__extensions` (`name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES - ('isis', 'template', 'isis', '', 1, 1, 1, 0, '{"name":"isis","type":"template","creationDate":"3\\/30\\/2012","author":"Kyle Ledbetter","copyright":"Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"","version":"1.0","description":"TPL_ISIS_XML_DESCRIPTION","group":""}', '{"templateColor":"","logoFile":""}', '', '', 0, '0000-00-00 00:00:00', 0, 0), - ('protostar', 'template', 'protostar', '', 0, 1, 1, 0, '{"name":"protostar","type":"template","creationDate":"4\\/30\\/2012","author":"Kyle Ledbetter","copyright":"Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"","version":"1.0","description":"TPL_PROTOSTAR_XML_DESCRIPTION","group":""}', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), - ('beez3', 'template', 'beez3', '', 0, 1, 1, 0, '{"legacy":false,"name":"beez3","type":"template","creationDate":"25 November 2009","author":"Angie Radtke","copyright":"Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.","authorEmail":"a.radtke@derauftritt.de","authorUrl":"http:\\/\\/www.der-auftritt.de","version":"1.6.0","description":"TPL_BEEZ3_XML_DESCRIPTION","group":""}', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '0000-00-00 00:00:00', 0, 0); + ('isis', 'template', 'isis', '', 1, 1, 1, 0, '{"name":"isis","type":"template","creationDate":"3\\/30\\/2012","author":"Kyle Ledbetter","copyright":"(C) 2012 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"","version":"1.0","description":"TPL_ISIS_XML_DESCRIPTION","group":""}', '{"templateColor":"","logoFile":""}', '', '', 0, '0000-00-00 00:00:00', 0, 0), + ('protostar', 'template', 'protostar', '', 0, 1, 1, 0, '{"name":"protostar","type":"template","creationDate":"4\\/30\\/2012","author":"Kyle Ledbetter","copyright":"(C) 2012 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"","version":"1.0","description":"TPL_PROTOSTAR_XML_DESCRIPTION","group":""}', '{"templateColor":"","logoFile":"","googleFont":"0","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), + ('beez3', 'template', 'beez3', '', 0, 1, 1, 0, '{"legacy":false,"name":"beez3","type":"template","creationDate":"25 November 2009","author":"Angie Radtke","copyright":"(C) 2009 Open Source Matters, Inc.","authorEmail":"a.radtke@derauftritt.de","authorUrl":"http:\\/\\/www.der-auftritt.de","version":"1.6.0","description":"TPL_BEEZ3_XML_DESCRIPTION","group":""}', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '0000-00-00 00:00:00', 0, 0); INSERT INTO `#__template_styles` (`template`, `client_id`, `home`, `title`, `params`) VALUES - ('protostar', 0, '0', 'protostar - Default', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}'), + ('protostar', 0, '0', 'protostar - Default', '{"templateColor":"","logoFile":"","googleFont":"0","googleFontName":"Open+Sans","fluidContainer":"0"}'), ('isis', 1, '1', 'isis - Default', '{"templateColor":"","logoFile":""}'), ('beez3', 0, '0', 'beez3 - Default', '{"wrapperSmall":53,"wrapperLarge":72,"logo":"","sitetitle":"","sitedescription":"","navposition":"center","bootstrap":"","templatecolor":"nature","headerImage":"","backgroundcolor":"#eee"}'); @@ -139,9 +139,9 @@ SET home = 0 WHERE template = 'bluestork'; INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES -(315, 'mod_stats_admin', 'module', 'mod_stats_admin', '', 1, 1, 1, 0, '{"name":"mod_stats_admin","type":"module","creationDate":"September 2012","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"MOD_STATS_XML_DESCRIPTION","group":""}', '{"serverinfo":"0","siteinfo":"0","counter":"0","increase":"0","cache":"1","cache_time":"900","cachemode":"static"}', '', '', 0, '0000-00-00 00:00:00', 0, 0); +(315, 'mod_stats_admin', 'module', 'mod_stats_admin', '', 1, 1, 1, 0, '{"name":"mod_stats_admin","type":"module","creationDate":"September 2012","author":"Joomla! Project","copyright":"(C) 2012 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"MOD_STATS_XML_DESCRIPTION","group":""}', '{"serverinfo":"0","siteinfo":"0","counter":"0","increase":"0","cache":"1","cache_time":"900","cachemode":"static"}', '', '', 0, '0000-00-00 00:00:00', 0, 0); UPDATE `#__update_sites` -SET location = 'http://update.joomla.org/language/translationlist_3.xml' -WHERE location = 'http://update.joomla.org/language/translationlist.xml' +SET location = 'https://update.joomla.org/language/translationlist_3.xml' +WHERE location = 'https://update.joomla.org/language/translationlist.xml' AND name = 'Accredited Joomla! Translations'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.0.3.sql b/administrator/components/com_admin/sql/updates/mysql/3.0.3.sql index 23fcc72c144df..b1fc21009ac58 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.0.3.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.0.3.sql @@ -1 +1 @@ -ALTER TABLE `#__associations` CHANGE `id` `id` INT(11) NOT NULL COMMENT 'A reference to the associated item.'; \ No newline at end of file +ALTER TABLE `#__associations` CHANGE `id` `id` INT NOT NULL COMMENT 'A reference to the associated item.'; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.1.0.sql b/administrator/components/com_admin/sql/updates/mysql/3.1.0.sql index 29ec9e2fe7f74..52d5bdd65df8d 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.1.0.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.1.0.sql @@ -3,7 +3,7 @@ -- CREATE TABLE IF NOT EXISTS `#__content_types` ( - `type_id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `type_id` int unsigned NOT NULL AUTO_INCREMENT, `type_title` varchar(255) NOT NULL DEFAULT '', `type_alias` varchar(255) NOT NULL DEFAULT '', `table` varchar(255) NOT NULL DEFAULT '', @@ -30,11 +30,11 @@ INSERT INTO `#__content_types` (`type_id`, `type_title`, `type_alias`, `table`, CREATE TABLE IF NOT EXISTS `#__contentitem_tag_map` ( `type_alias` varchar(255) NOT NULL DEFAULT '', - `core_content_id` int(10) unsigned NOT NULL COMMENT 'PK from the core content table', - `content_item_id` int(11) NOT NULL COMMENT 'PK from the content type table', - `tag_id` int(10) unsigned NOT NULL COMMENT 'PK from the tag table', + `core_content_id` int unsigned NOT NULL COMMENT 'PK from the core content table', + `content_item_id` int NOT NULL COMMENT 'PK from the content type table', + `tag_id` int unsigned NOT NULL COMMENT 'PK from the tag table', `tag_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Date of most recent save for this tag-item', - `type_id` mediumint(8) NOT NULL COMMENT 'PK from the content_type table', + `type_id` mediumint NOT NULL COMMENT 'PK from the content_type table', UNIQUE KEY `uc_ItemnameTagid` (`type_id`,`content_item_id`,`tag_id`), KEY `idx_tag_type` (`tag_id`,`type_id`), KEY `idx_date_id` (`tag_date`,`tag_id`), @@ -44,34 +44,34 @@ CREATE TABLE IF NOT EXISTS `#__contentitem_tag_map` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Maps items from content tables to tags'; CREATE TABLE IF NOT EXISTS `#__tags` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `parent_id` int(10) unsigned NOT NULL DEFAULT '0', - `lft` int(11) NOT NULL DEFAULT '0', - `rgt` int(11) NOT NULL DEFAULT '0', - `level` int(10) unsigned NOT NULL DEFAULT '0', + `id` int unsigned NOT NULL AUTO_INCREMENT, + `parent_id` int unsigned NOT NULL DEFAULT '0', + `lft` int NOT NULL DEFAULT '0', + `rgt` int NOT NULL DEFAULT '0', + `level` int unsigned NOT NULL DEFAULT '0', `path` varchar(255) NOT NULL DEFAULT '', `title` varchar(255) NOT NULL, `alias` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `note` varchar(255) NOT NULL DEFAULT '', `description` mediumtext NOT NULL, - `published` tinyint(1) NOT NULL DEFAULT '0', - `checked_out` int(11) unsigned NOT NULL DEFAULT '0', + `published` tinyint NOT NULL DEFAULT '0', + `checked_out` int unsigned NOT NULL DEFAULT '0', `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `access` int(10) unsigned NOT NULL DEFAULT '0', + `access` int unsigned NOT NULL DEFAULT '0', `params` text NOT NULL, `metadesc` varchar(1024) NOT NULL COMMENT 'The meta description for the page.', `metakey` varchar(1024) NOT NULL COMMENT 'The meta keywords for the page.', `metadata` varchar(2048) NOT NULL COMMENT 'JSON encoded metadata properties.', - `created_user_id` int(10) unsigned NOT NULL DEFAULT '0', + `created_user_id` int unsigned NOT NULL DEFAULT '0', `created_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `created_by_alias` varchar(255) NOT NULL DEFAULT '', - `modified_user_id` int(10) unsigned NOT NULL DEFAULT '0', + `modified_user_id` int unsigned NOT NULL DEFAULT '0', `modified_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `images` text NOT NULL, `urls` text NOT NULL, - `hits` int(10) unsigned NOT NULL DEFAULT '0', + `hits` int unsigned NOT NULL DEFAULT '0', `language` char(7) NOT NULL, - `version` int(10) unsigned NOT NULL DEFAULT '1', + `version` int unsigned NOT NULL DEFAULT '1', `publish_up` datetime NOT NULL default '0000-00-00 00:00:00', `publish_down` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`), @@ -96,10 +96,10 @@ VALUES (1, 0, 0, 1, 0, '', 'ROOT', 'root', '', '', 1, 0, '0000-00-00 00:00:00', -- CREATE TABLE IF NOT EXISTS `#__ucm_base` ( - `ucm_id` int(10) unsigned NOT NULL, - `ucm_item_id` int(10) NOT NULL, - `ucm_type_id` int(11) NOT NULL, - `ucm_language_id` int(11) NOT NULL, + `ucm_id` int unsigned NOT NULL, + `ucm_item_id` int NOT NULL, + `ucm_type_id` int NOT NULL, + `ucm_language_id` int NOT NULL, PRIMARY KEY (`ucm_id`), KEY `idx_ucm_item_id` (`ucm_item_id`), KEY `idx_ucm_type_id` (`ucm_type_id`), @@ -108,38 +108,38 @@ CREATE TABLE IF NOT EXISTS `#__ucm_base` ( CREATE TABLE IF NOT EXISTS `#__ucm_content` ( - `core_content_id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `core_content_id` int unsigned NOT NULL AUTO_INCREMENT, `core_type_alias` varchar(255) NOT NULL DEFAULT '' COMMENT 'FK to the content types table', `core_title` varchar(255) NOT NULL, `core_alias` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', `core_body` mediumtext NOT NULL, - `core_state` tinyint(1) NOT NULL DEFAULT '0', + `core_state` tinyint NOT NULL DEFAULT '0', `core_checked_out_time` varchar(255) NOT NULL DEFAULT '', - `core_checked_out_user_id` int(10) unsigned NOT NULL DEFAULT '0', - `core_access` int(10) unsigned NOT NULL DEFAULT '0', + `core_checked_out_user_id` int unsigned NOT NULL DEFAULT '0', + `core_access` int unsigned NOT NULL DEFAULT '0', `core_params` text NOT NULL, - `core_featured` tinyint(4) unsigned NOT NULL DEFAULT '0', + `core_featured` tinyint unsigned NOT NULL DEFAULT '0', `core_metadata` varchar(2048) NOT NULL COMMENT 'JSON encoded metadata properties.', - `core_created_user_id` int(10) unsigned NOT NULL DEFAULT '0', + `core_created_user_id` int unsigned NOT NULL DEFAULT '0', `core_created_by_alias` varchar(255) NOT NULL DEFAULT '', `core_created_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `core_modified_user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Most recent user that modified', + `core_modified_user_id` int unsigned NOT NULL DEFAULT '0' COMMENT 'Most recent user that modified', `core_modified_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `core_language` char(7) NOT NULL, `core_publish_up` datetime NOT NULL, `core_publish_down` datetime NOT NULL, - `core_content_item_id` int(10) unsigned COMMENT 'ID from the individual type table', - `asset_id` int(10) unsigned COMMENT 'FK to the #__assets table.', + `core_content_item_id` int unsigned COMMENT 'ID from the individual type table', + `asset_id` int unsigned COMMENT 'FK to the #__assets table.', `core_images` text NOT NULL, `core_urls` text NOT NULL, - `core_hits` int(10) unsigned NOT NULL DEFAULT '0', - `core_version` int(10) unsigned NOT NULL DEFAULT '1', - `core_ordering` int(11) NOT NULL DEFAULT '0', + `core_hits` int unsigned NOT NULL DEFAULT '0', + `core_version` int unsigned NOT NULL DEFAULT '1', + `core_ordering` int NOT NULL DEFAULT '0', `core_metakey` text NOT NULL, `core_metadesc` text NOT NULL, - `core_catid` int(10) unsigned NOT NULL DEFAULT '0', + `core_catid` int unsigned NOT NULL DEFAULT '0', `core_xreference` varchar(50) NOT NULL COMMENT 'A reference to enable linkages to external data sets.', - `core_type_id` int(10) unsigned, + `core_type_id` int unsigned, PRIMARY KEY (`core_content_id`), KEY `tag_idx` (`core_state`,`core_access`), KEY `idx_access` (`core_access`), @@ -156,10 +156,10 @@ CREATE TABLE IF NOT EXISTS `#__ucm_content` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Contains core content data in name spaced fields'; INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES -(29, 'com_tags', 'component', 'com_tags', '', 1, 1, 1, 1, '{"legacy":false,"name":"com_tags","type":"component","creationDate":"March 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"COM_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(316, 'mod_tags_popular', 'module', 'mod_tags_popular', '', 0, 1, 1, 0, '{"name":"mod_tags_popular","type":"module","creationDate":"January 2013","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"MOD_TAGS_POPULAR_XML_DESCRIPTION","group":""}', '{"maximum":"5","timeframe":"alltime","owncache":"1"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(317, 'mod_tags_similar', 'module', 'mod_tags_similar', '', 0, 1, 1, 0, '{"name":"mod_tags_similar","type":"module","creationDate":"January 2013","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"MOD_TAGS_SIMILAR_XML_DESCRIPTION","group":""}', '{"maximum":"5","matchtype":"any","owncache":"1"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(447, 'plg_finder_tags', 'plugin', 'tags', 'finder', 0, 1, 1, 0, '{"name":"plg_finder_tags","type":"plugin","creationDate":"February 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"PLG_FINDER_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); +(29, 'com_tags', 'component', 'com_tags', '', 1, 1, 1, 1, '{"legacy":false,"name":"com_tags","type":"component","creationDate":"March 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"COM_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(316, 'mod_tags_popular', 'module', 'mod_tags_popular', '', 0, 1, 1, 0, '{"name":"mod_tags_popular","type":"module","creationDate":"January 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"MOD_TAGS_POPULAR_XML_DESCRIPTION","group":""}', '{"maximum":"5","timeframe":"alltime","owncache":"1"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(317, 'mod_tags_similar', 'module', 'mod_tags_similar', '', 0, 1, 1, 0, '{"name":"mod_tags_similar","type":"module","creationDate":"January 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"MOD_TAGS_SIMILAR_XML_DESCRIPTION","group":""}', '{"maximum":"5","matchtype":"any","owncache":"1"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(447, 'plg_finder_tags', 'plugin', 'tags', 'finder', 0, 1, 1, 0, '{"name":"plg_finder_tags","type":"plugin","creationDate":"February 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"PLG_FINDER_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); INSERT INTO `#__menu` (`menutype`, `title`, `alias`, `note`, `path`, `link`, `type`, `published`, `parent_id`, `level`, `component_id`, `checked_out`, `checked_out_time`, `browserNav`, `access`, `img`, `template_style_id`, `params`, `lft`, `rgt`, `home`, `language`, `client_id`) VALUES ('main', 'com_tags', 'Tags', '', 'Tags', 'index.php?option=com_tags', 'component', 0, 1, 1, 29, 0, '0000-00-00 00:00:00', 0, 1, 'class:tags', 0, '', 45, 46, 0, '', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.10.0-2020-08-10.sql b/administrator/components/com_admin/sql/updates/mysql/3.10.0-2020-08-10.sql new file mode 100644 index 0000000000000..17aaaa2e0af57 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.10.0-2020-08-10.sql @@ -0,0 +1,6 @@ +-- +-- These database columns are not used in Joomla 3.10 but will be used in Joomla 4. +-- They are added to 3.10 because otherwise the update to 4 will fail. +-- +ALTER TABLE `#__template_styles` ADD COLUMN `inheritable` tinyint NOT NULL DEFAULT 0; +ALTER TABLE `#__template_styles` ADD COLUMN `parent` varchar(50) DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.10.0-2021-05-28.sql b/administrator/components/com_admin/sql/updates/mysql/3.10.0-2021-05-28.sql new file mode 100644 index 0000000000000..9aec68b97c195 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.10.0-2021-05-28.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(0, 'plg_quickicon_eos310', 'plugin', 'eos310', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.10.7-2022-02-20.sql b/administrator/components/com_admin/sql/updates/mysql/3.10.7-2022-02-20.sql new file mode 100644 index 0000000000000..7e0070197e22b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.10.7-2022-02-20.sql @@ -0,0 +1 @@ +DELETE FROM `#__postinstall_messages` WHERE `title_key` = 'COM_ADMIN_POSTINSTALL_MSG_FLOC_BLOCKER_TITLE'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.0.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.0.sql index 02b067d2e97b6..ca462d61e77ae 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.0.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.2.0.sql @@ -19,34 +19,34 @@ UPDATE `#__extensions` SET `params` = '{"template_positions_display":"0","upload UPDATE `#__extensions` SET `params` = '{"lineNumbers":"1","lineWrapping":"1","matchTags":"1","matchBrackets":"1","marker-gutter":"1","autoCloseTags":"1","autoCloseBrackets":"1","autoFocus":"1","theme":"default","tabmode":"indent"}' WHERE `extension_id` = 410; INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES -(30, 'com_contenthistory', 'component', 'com_contenthistory', '', 1, 1, 1, 0, '{"name":"com_contenthistory","type":"component","creationDate":"May 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.\\n\\t","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_CONTENTHISTORY_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 1, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(30, 'com_contenthistory', 'component', 'com_contenthistory', '', 1, 1, 1, 0, '{"name":"com_contenthistory","type":"component","creationDate":"May 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.\\n\\t","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_CONTENTHISTORY_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 1, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (32, 'com_postinstall', 'component', 'com_postinstall', '', 1, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (105, 'FOF', 'library', 'fof', '', 0, 1, 1, 1, '{"legacy":false,"name":"FOF","type":"library","creationDate":"2013-10-08","author":"Nicholas K. Dionysopoulos \/ Akeeba Ltd","copyright":"(C)2011-2013 Nicholas K. Dionysopoulos","authorEmail":"nicholas@akeebabackup.com","authorUrl":"https:\/\/www.akeebabackup.com","version":"2.1.rc4","description":"Framework-on-Framework (FOF) - A rapid component development framework for Joomla!","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(448, 'plg_twofactorauth_totp', 'plugin', 'totp', 'twofactorauth', 0, 0, 1, 0, '{"name":"plg_twofactorauth_totp","type":"plugin","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(449, 'plg_authentication_cookie', 'plugin', 'cookie', 'authentication', 0, 1, 1, 0, '{"name":"plg_authentication_cookie","type":"plugin","creationDate":"July 2013","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"PLG_AUTH_COOKIE_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(450, 'plg_twofactorauth_yubikey', 'plugin', 'yubikey', 'twofactorauth', 0, 0, 1, 0, '{"name":"plg_twofactorauth_yubikey","type":"plugin","creationDate":"Se[ptember 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"PLG_TWOFACTORAUTH_YUBIKEY_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); +(448, 'plg_twofactorauth_totp', 'plugin', 'totp', 'twofactorauth', 0, 0, 1, 0, '{"name":"plg_twofactorauth_totp","type":"plugin","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(449, 'plg_authentication_cookie', 'plugin', 'cookie', 'authentication', 0, 1, 1, 0, '{"name":"plg_authentication_cookie","type":"plugin","creationDate":"July 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"PLG_AUTH_COOKIE_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(450, 'plg_twofactorauth_yubikey', 'plugin', 'yubikey', 'twofactorauth', 0, 0, 1, 0, '{"name":"plg_twofactorauth_yubikey","type":"plugin","creationDate":"Se[ptember 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"PLG_TWOFACTORAUTH_YUBIKEY_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); INSERT INTO `#__menu` (`menutype`, `title`, `alias`, `note`, `path`, `link`, `type`, `published`, `parent_id`, `level`, `component_id`, `checked_out`, `checked_out_time`, `browserNav`, `access`, `img`, `template_style_id`, `params`, `lft`, `rgt`, `home`, `language`, `client_id`) VALUES ('main', 'com_postinstall', 'Post-installation messages', '', 'Post-installation messages', 'index.php?option=com_postinstall', 'component', 0, 1, 1, 32, 0, '0000-00-00 00:00:00', 0, 1, 'class:postinstall', 0, '', 45, 46, 0, '*', 1); -ALTER TABLE `#__modules` ADD COLUMN `asset_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'FK to the #__assets table.' AFTER `id`; +ALTER TABLE `#__modules` ADD COLUMN `asset_id` INT UNSIGNED NOT NULL DEFAULT '0' COMMENT 'FK to the #__assets table.' AFTER `id`; CREATE TABLE `#__postinstall_messages` ( - `postinstall_message_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `extension_id` bigint(20) NOT NULL DEFAULT '700' COMMENT 'FK to #__extensions', + `postinstall_message_id` bigint unsigned NOT NULL AUTO_INCREMENT, + `extension_id` bigint NOT NULL DEFAULT '700' COMMENT 'FK to #__extensions', `title_key` varchar(255) NOT NULL DEFAULT '' COMMENT 'Lang key for the title', `description_key` varchar(255) NOT NULL DEFAULT '' COMMENT 'Lang key for description', `action_key` varchar(255) NOT NULL DEFAULT '', `language_extension` varchar(255) NOT NULL DEFAULT 'com_postinstall' COMMENT 'Extension holding lang keys', - `language_client_id` tinyint(3) NOT NULL DEFAULT '1', + `language_client_id` tinyint NOT NULL DEFAULT '1', `type` varchar(10) NOT NULL DEFAULT 'link' COMMENT 'Message type - message, link, action', `action_file` varchar(255) DEFAULT '' COMMENT 'RAD URI to the PHP file containing action method', `action` varchar(255) DEFAULT '' COMMENT 'Action method name or URL', `condition_file` varchar(255) DEFAULT NULL COMMENT 'RAD URI to file holding display condition method', `condition_method` varchar(255) DEFAULT NULL COMMENT 'Display condition method, must return boolean', `version_introduced` varchar(50) NOT NULL DEFAULT '3.2.0' COMMENT 'Version when this message was introduced', - `enabled` tinyint(3) NOT NULL DEFAULT '1', + `enabled` tinyint NOT NULL DEFAULT '1', PRIMARY KEY (`postinstall_message_id`) ) DEFAULT CHARSET=utf8; @@ -55,16 +55,16 @@ INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description (700, 'COM_CPANEL_MSG_EACCELERATOR_TITLE', 'COM_CPANEL_MSG_EACCELERATOR_BODY', 'COM_CPANEL_MSG_EACCELERATOR_BUTTON', 'com_cpanel', 1, 'action', 'admin://components/com_admin/postinstall/eaccelerator.php', 'admin_postinstall_eaccelerator_action', 'admin://components/com_admin/postinstall/eaccelerator.php', 'admin_postinstall_eaccelerator_condition', '3.2.0', 1); CREATE TABLE IF NOT EXISTS `#__ucm_history` ( - `version_id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `ucm_item_id` int(10) unsigned NOT NULL, - `ucm_type_id` int(10) unsigned NOT NULL, + `version_id` int unsigned NOT NULL AUTO_INCREMENT, + `ucm_item_id` int unsigned NOT NULL, + `ucm_type_id` int unsigned NOT NULL, `version_note` varchar(255) NOT NULL DEFAULT '' COMMENT 'Optional version name', `save_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `editor_user_id` int(10) unsigned NOT NULL DEFAULT '0', - `character_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Number of characters in this version.', + `editor_user_id` int unsigned NOT NULL DEFAULT '0', + `character_count` int unsigned NOT NULL DEFAULT '0' COMMENT 'Number of characters in this version.', `sha1_hash` varchar(50) NOT NULL DEFAULT '' COMMENT 'SHA1 hash of the version_data column.', `version_data` mediumtext NOT NULL COMMENT 'json-encoded string of version data', - `keep_forever` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0=auto delete; 1=keep', + `keep_forever` tinyint NOT NULL DEFAULT '0' COMMENT '0=auto delete; 1=keep', PRIMARY KEY (`version_id`), KEY `idx_ucm_item_id` (`ucm_type_id`,`ucm_item_id`), KEY `idx_save_date` (`save_date`) @@ -74,11 +74,11 @@ ALTER TABLE `#__users` ADD COLUMN `otpKey` varchar(1000) NOT NULL DEFAULT '' COM ALTER TABLE `#__users` ADD COLUMN `otep` varchar(1000) NOT NULL DEFAULT '' COMMENT 'One time emergency passwords'; CREATE TABLE IF NOT EXISTS `#__user_keys` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `user_id` varchar(255) NOT NULL, `token` varchar(255) NOT NULL, `series` varchar(255) NOT NULL, - `invalid` tinyint(4) NOT NULL, + `invalid` tinyint NOT NULL, `time` varchar(200) NOT NULL, `uastring` varchar(255) NOT NULL, PRIMARY KEY (`id`), diff --git a/administrator/components/com_admin/sql/updates/mysql/3.3.0-2014-02-16.sql b/administrator/components/com_admin/sql/updates/mysql/3.3.0-2014-02-16.sql index e280281553ad3..ffaa92782eafd 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.3.0-2014-02-16.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.3.0-2014-02-16.sql @@ -1 +1 @@ -ALTER TABLE `#__users` ADD COLUMN `requireReset` tinyint(4) NOT NULL DEFAULT 0 COMMENT 'Require user to reset password on next login' AFTER `otep`; +ALTER TABLE `#__users` ADD COLUMN `requireReset` tinyint NOT NULL DEFAULT 0 COMMENT 'Require user to reset password on next login' AFTER `otep`; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.3.6-2014-09-30.sql b/administrator/components/com_admin/sql/updates/mysql/3.3.6-2014-09-30.sql index 73b7c1ba0ed3f..eb7048877c84c 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.3.6-2014-09-30.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.3.6-2014-09-30.sql @@ -1,5 +1,5 @@ INSERT INTO `#__update_sites` (`name`, `type`, `location`, `enabled`) VALUES -('Joomla! Update Component Update Site', 'extension', 'http://update.joomla.org/core/extensions/com_joomlaupdate.xml', 1); +('Joomla! Update Component Update Site', 'extension', 'https://update.joomla.org/core/extensions/com_joomlaupdate.xml', 1); INSERT INTO `#__update_sites_extensions` (`update_site_id`, `extension_id`) VALUES ((SELECT `update_site_id` FROM `#__update_sites` WHERE `name` = 'Joomla! Update Component Update Site'), (SELECT `extension_id` FROM `#__extensions` WHERE `name` = 'com_joomlaupdate')); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-16.sql b/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-16.sql index 37620c9c50f00..06d6aeb1ee4c9 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-16.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-16.sql @@ -1,4 +1,4 @@ -ALTER TABLE `#__redirect_links` ADD COLUMN `header` smallint(3) NOT NULL DEFAULT 301; +ALTER TABLE `#__redirect_links` ADD COLUMN `header` smallint NOT NULL DEFAULT 301; -- -- The following statement has to be disabled because it conflicts with -- a later change added with Joomla! 3.5.0 for long URLs in this table diff --git a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-07-01.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-07-01.sql index e76947836f087..018e755929500 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-07-01.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-07-01.sql @@ -1,2 +1,2 @@ -ALTER TABLE `#__session` MODIFY `session_id` varchar(191) NOT NULL DEFAULT ''; +-- ALTER TABLE `#__session` MODIFY `session_id` varchar(191) NOT NULL DEFAULT ''; ALTER TABLE `#__user_keys` MODIFY `series` varchar(191) NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2016-02-26.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2016-02-26.sql index 0aa843cbfbc91..c1e065f1aa56f 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2016-02-26.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2016-02-26.sql @@ -8,7 +8,7 @@ -- CREATE TABLE IF NOT EXISTS `#__utf8_conversion` ( - `converted` tinyint(4) NOT NULL DEFAULT 0 + `converted` tinyint NOT NULL DEFAULT 0 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; INSERT INTO `#__utf8_conversion` (`converted`) VALUES (0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-09.sql b/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-09.sql index 95678415b6501..4089ba0ec50c7 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-09.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-09.sql @@ -2,4 +2,4 @@ -- Add ACL check for to #__menu_types -- -ALTER TABLE `#__menu_types` ADD COLUMN `asset_id` INT(11) NOT NULL AFTER `id`; \ No newline at end of file +ALTER TABLE `#__menu_types` ADD COLUMN `asset_id` INT NOT NULL AFTER `id`; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-05.sql b/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-05.sql index 4fcc47c42f600..408e2e1d13979 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-05.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-05.sql @@ -2,4 +2,4 @@ -- Add ACL check for to #__languages -- -ALTER TABLE `#__languages` ADD COLUMN `asset_id` INT(11) NOT NULL AFTER `lang_id`; \ No newline at end of file +ALTER TABLE `#__languages` ADD COLUMN `asset_id` INT NOT NULL AFTER `lang_id`; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-29.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-29.sql index 2525369981db7..be1973b97d93d 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-29.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-29.sql @@ -1,28 +1,28 @@ CREATE TABLE IF NOT EXISTS `#__fields` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `asset_id` int(10) unsigned NOT NULL DEFAULT 0, + `id` int unsigned NOT NULL AUTO_INCREMENT, + `asset_id` int unsigned NOT NULL DEFAULT 0, `context` varchar(255) NOT NULL DEFAULT '', - `group_id` int(10) unsigned NOT NULL DEFAULT 0, + `group_id` int unsigned NOT NULL DEFAULT 0, `title` varchar(255) NOT NULL DEFAULT '', `name` varchar(255) NOT NULL DEFAULT '', `label` varchar(255) NOT NULL DEFAULT '', - `default_value` text NOT NULL DEFAULT '', + `default_value` text, `type` varchar(255) NOT NULL DEFAULT 'text', `note` varchar(255) NOT NULL DEFAULT '', `description` text NOT NULL, - `state` tinyint(1) NOT NULL DEFAULT '0', - `required` tinyint(1) NOT NULL DEFAULT '0', - `checked_out` int(11) NOT NULL DEFAULT '0', + `state` tinyint NOT NULL DEFAULT '0', + `required` tinyint NOT NULL DEFAULT '0', + `checked_out` int NOT NULL DEFAULT '0', `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `ordering` int(11) NOT NULL DEFAULT '0', + `ordering` int NOT NULL DEFAULT '0', `params` text NOT NULL, `fieldparams` text NOT NULL, `language` char(7) NOT NULL DEFAULT '', `created_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_user_id` int(10) unsigned NOT NULL DEFAULT '0', + `created_user_id` int unsigned NOT NULL DEFAULT '0', `modified_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `modified_by` int(10) unsigned NOT NULL DEFAULT '0', - `access` int(11) NOT NULL DEFAULT '1', + `modified_by` int unsigned NOT NULL DEFAULT '0', + `access` int NOT NULL DEFAULT '1', PRIMARY KEY (`id`), KEY `idx_checkout` (`checked_out`), KEY `idx_state` (`state`), @@ -33,28 +33,28 @@ CREATE TABLE IF NOT EXISTS `#__fields` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `#__fields_categories` ( - `field_id` int(11) NOT NULL DEFAULT 0, - `category_id` int(11) NOT NULL DEFAULT 0, + `field_id` int NOT NULL DEFAULT 0, + `category_id` int NOT NULL DEFAULT 0, PRIMARY KEY (`field_id`,`category_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `#__fields_groups` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `asset_id` int(10) unsigned NOT NULL DEFAULT 0, + `id` int unsigned NOT NULL AUTO_INCREMENT, + `asset_id` int unsigned NOT NULL DEFAULT 0, `context` varchar(255) NOT NULL DEFAULT '', `title` varchar(255) NOT NULL DEFAULT '', `note` varchar(255) NOT NULL DEFAULT '', `description` text NOT NULL, - `state` tinyint(1) NOT NULL DEFAULT '0', - `checked_out` int(11) NOT NULL DEFAULT '0', + `state` tinyint NOT NULL DEFAULT '0', + `checked_out` int NOT NULL DEFAULT '0', `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `ordering` int(11) NOT NULL DEFAULT '0', + `ordering` int NOT NULL DEFAULT '0', `language` char(7) NOT NULL DEFAULT '', `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_by` int(10) unsigned NOT NULL DEFAULT '0', + `created_by` int unsigned NOT NULL DEFAULT '0', `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `modified_by` int(10) unsigned NOT NULL DEFAULT '0', - `access` int(11) NOT NULL DEFAULT '1', + `modified_by` int unsigned NOT NULL DEFAULT '0', + `access` int NOT NULL DEFAULT '1', PRIMARY KEY (`id`), KEY `idx_checkout` (`checked_out`), KEY `idx_state` (`state`), @@ -65,9 +65,9 @@ CREATE TABLE IF NOT EXISTS `#__fields_groups` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `#__fields_values` ( - `field_id` int(10) unsigned NOT NULL, + `field_id` int unsigned NOT NULL, `item_id` varchar(255) NOT NULL COMMENT 'Allow references to items which have strings as ids, eg. none db systems.', - `value` text NOT NULL DEFAULT '', + `value` text, KEY `idx_field_id` (`field_id`), KEY `idx_item_id` (`item_id`(191)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-02.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-02.sql index 73fd38ff7dd95..9f2fcb721c3b4 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-02.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-02.sql @@ -1 +1 @@ -ALTER TABLE `#__session` MODIFY `client_id` tinyint(3) unsigned DEFAULT NULL; +ALTER TABLE `#__session` MODIFY `client_id` tinyint unsigned DEFAULT NULL; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-04.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-04.sql index 0281c97232aaa..b6e78dde388eb 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-04.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-04.sql @@ -1 +1 @@ -ALTER TABLE `#__extensions` CHANGE `enabled` `enabled` TINYINT(3) NOT NULL DEFAULT '0'; \ No newline at end of file +ALTER TABLE `#__extensions` CHANGE `enabled` `enabled` TINYINT NOT NULL DEFAULT '0'; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-19.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-19.sql index fe2029766a597..04e4a21013e2f 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-19.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-19.sql @@ -1,3 +1,3 @@ -ALTER TABLE `#__menu_types` ADD COLUMN `client_id` int(11) NOT NULL DEFAULT 0; +ALTER TABLE `#__menu_types` ADD COLUMN `client_id` int NOT NULL DEFAULT 0; UPDATE `#__menu` SET `published` = 1 WHERE `menutype` = 'main' OR `menutype` = 'menu'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-24.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-24.sql index 2b2a91013014a..78dbb4bd3bedd 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-24.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-24.sql @@ -1,4 +1,4 @@ -ALTER TABLE `#__extensions` ADD COLUMN `package_id` int(11) NOT NULL DEFAULT 0 COMMENT 'Parent package ID for extensions installed as a package.' AFTER `extension_id`; +ALTER TABLE `#__extensions` ADD COLUMN `package_id` int NOT NULL DEFAULT 0 COMMENT 'Parent package ID for extensions installed as a package.' AFTER `extension_id`; UPDATE `#__extensions` AS `e1` INNER JOIN (SELECT `extension_id` FROM `#__extensions` WHERE `type` = 'package' AND `element` = 'pkg_en-GB') AS `e2` diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-27.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-27.sql index f6874ee5a5c36..86285429a73ea 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-27.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-27.sql @@ -1,2 +1,2 @@ -- Normalize modules content field with other db systems. Add default value. -ALTER TABLE `#__modules` MODIFY `content` text NOT NULL DEFAULT ''; +ALTER TABLE `#__modules` MODIFY `content` text; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-08.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-08.sql index 6836086861ca5..aa70585d89059 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-08.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-08.sql @@ -1,18 +1,18 @@ -- Normalize ucm_content_table default values. ALTER TABLE `#__ucm_content` MODIFY `core_title` varchar(400) NOT NULL DEFAULT ''; ALTER TABLE `#__ucm_content` MODIFY `core_alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT ''; -ALTER TABLE `#__ucm_content` MODIFY `core_body` mediumtext NOT NULL DEFAULT ''; +ALTER TABLE `#__ucm_content` MODIFY `core_body` mediumtext; ALTER TABLE `#__ucm_content` MODIFY `core_checked_out_time` varchar(255) NOT NULL DEFAULT '0000-00-00 00:00:00'; -ALTER TABLE `#__ucm_content` MODIFY `core_params` text NOT NULL DEFAULT ''; +ALTER TABLE `#__ucm_content` MODIFY `core_params` text; ALTER TABLE `#__ucm_content` MODIFY `core_metadata` varchar(2048) NOT NULL DEFAULT '' COMMENT 'JSON encoded metadata properties.'; ALTER TABLE `#__ucm_content` MODIFY `core_language` char(7) NOT NULL DEFAULT ''; ALTER TABLE `#__ucm_content` MODIFY `core_publish_up` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'; ALTER TABLE `#__ucm_content` MODIFY `core_publish_down` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'; -ALTER TABLE `#__ucm_content` MODIFY `core_content_item_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'ID from the individual type table'; -ALTER TABLE `#__ucm_content` MODIFY `asset_id` int(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.'; -ALTER TABLE `#__ucm_content` MODIFY `core_images` text NOT NULL DEFAULT ''; -ALTER TABLE `#__ucm_content` MODIFY `core_urls` text NOT NULL DEFAULT ''; -ALTER TABLE `#__ucm_content` MODIFY `core_metakey` text NOT NULL DEFAULT ''; -ALTER TABLE `#__ucm_content` MODIFY `core_metadesc` text NOT NULL DEFAULT ''; +ALTER TABLE `#__ucm_content` MODIFY `core_content_item_id` int unsigned NOT NULL DEFAULT 0 COMMENT 'ID from the individual type table'; +ALTER TABLE `#__ucm_content` MODIFY `asset_id` int unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.'; +ALTER TABLE `#__ucm_content` MODIFY `core_images` text; +ALTER TABLE `#__ucm_content` MODIFY `core_urls` text; +ALTER TABLE `#__ucm_content` MODIFY `core_metakey` text; +ALTER TABLE `#__ucm_content` MODIFY `core_metadesc` text; ALTER TABLE `#__ucm_content` MODIFY `core_xreference` varchar(50) NOT NULL DEFAULT '' COMMENT 'A reference to enable linkages to external data sets.'; -ALTER TABLE `#__ucm_content` MODIFY `core_type_id` int(10) unsigned NOT NULL DEFAULT 0; +ALTER TABLE `#__ucm_content` MODIFY `core_type_id` int unsigned NOT NULL DEFAULT 0; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-09.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-09.sql index 162635df1fbe5..719418183c38d 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-09.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-09.sql @@ -1,7 +1,7 @@ -- Normalize categories table default values. ALTER TABLE `#__categories` MODIFY `title` varchar(255) NOT NULL DEFAULT ''; -ALTER TABLE `#__categories` MODIFY `description` mediumtext NOT NULL DEFAULT ''; -ALTER TABLE `#__categories` MODIFY `params` text NOT NULL DEFAULT ''; +ALTER TABLE `#__categories` MODIFY `description` mediumtext; +ALTER TABLE `#__categories` MODIFY `params` text; ALTER TABLE `#__categories` MODIFY `metadesc` varchar(1024) NOT NULL DEFAULT '' COMMENT 'The meta description for the page.'; ALTER TABLE `#__categories` MODIFY `metakey` varchar(1024) NOT NULL DEFAULT '' COMMENT 'The meta keywords for the page.'; ALTER TABLE `#__categories` MODIFY `metadata` varchar(2048) NOT NULL DEFAULT '' COMMENT 'JSON encoded metadata properties.'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-17.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-17.sql index 60627ac7c82e7..fe041e904b7e5 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-17.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-17.sql @@ -1,2 +1,58 @@ -- Sync menutype for admin menu and set client_id correct -UPDATE `#__menu` SET `menutype` = 'main', `client_id` = 1 WHERE `menutype` = 'main' OR `menutype` = 'menu'; + +-- Note: This file had to be modified with Joomla 3.7.3 because the +-- original version made site menus disappear if there were menu types +-- "main" or "menu" defined for the site. + +-- Step 1: If there is any user-defined menu and menu type "main" for the site +-- (client_id = 0), then change the menu type for the menu, any module and the +-- menu type to something very likely not being used yet and just within the +-- max. length of 24 characters. +UPDATE `#__menu` + SET `menutype` = 'main_is_reserved_133C585' + WHERE `client_id` = 0 + AND `menutype` = 'main' + AND (SELECT COUNT(`id`) FROM `#__menu_types` WHERE `client_id` = 0 AND `menutype` = 'main') > 0; + +UPDATE `#__modules` + SET `params` = REPLACE(`params`,'"menutype":"main"','"menutype":"main_is_reserved_133C585"') + WHERE `client_id` = 0 + AND (SELECT COUNT(`id`) FROM `#__menu_types` WHERE `client_id` = 0 AND `menutype` = 'main') > 0; + +UPDATE `#__menu_types` + SET `menutype` = 'main_is_reserved_133C585' + WHERE `client_id` = 0 + AND `menutype` = 'main'; + +-- Step 2: What remains now are the main menu items, possibly with wrong +-- client_id if there was nothing hit by step 1 because there was no record in +-- the menu types table with client_id = 0. +UPDATE `#__menu` + SET `client_id` = 1 + WHERE `menutype` = 'main'; + +-- Step 3: If we have menu items for the admin using menutype = "menu" and +-- having correct client_id = 1, we can be sure they belong to the admin menu +-- and so rename the menutype. +UPDATE `#__menu` + SET `menutype` = 'main' + WHERE `client_id` = 1 + AND `menutype` = 'menu'; + +-- Step 4: If there is no user-defined menu type "menu" for the site, we can +-- assume that any menu items for that menu type belong to the admin. +-- Fix the client_id for those as it was done with the original version of this +-- schema update script here. +UPDATE `#__menu` + SET `menutype` = 'main', + `client_id` = 1 + WHERE `menutype` = 'menu' + AND (SELECT COUNT(`id`) FROM `#__menu_types` WHERE `client_id` = 0 AND `menutype` = 'menu') = 0; + +-- Step 5: For the standard admin menu items of menutype "main" there is no record +-- in the menutype table on a clean Joomla installation. If there is one, it is a +-- mistake and it should be deleted. This is also the case with menu type "menu" +-- for the admin, for which we changed the menutype of the menu items in step 3. +DELETE FROM `#__menu_types` + WHERE `client_id` = 1 + AND `menutype` IN ('main', 'menu'); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-03.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-03.sql index ada236b5889cf..beaaae960cdf7 100644 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-03.sql +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-03.sql @@ -1,5 +1,5 @@ -ALTER TABLE `#__languages` MODIFY `asset_id` int(10) unsigned NOT NULL DEFAULT 0; -ALTER TABLE `#__menu_types` MODIFY `asset_id` int(10) unsigned NOT NULL DEFAULT 0; +ALTER TABLE `#__languages` MODIFY `asset_id` int unsigned NOT NULL DEFAULT 0; +ALTER TABLE `#__menu_types` MODIFY `asset_id` int unsigned NOT NULL DEFAULT 0; ALTER TABLE `#__content` MODIFY `xreference` varchar(50) NOT NULL DEFAULT ''; ALTER TABLE `#__newsfeeds` MODIFY `xreference` varchar(50) NOT NULL DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.3-2017-06-03.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.3-2017-06-03.sql new file mode 100644 index 0000000000000..eac66fa67b28e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.3-2017-06-03.sql @@ -0,0 +1 @@ +ALTER TABLE `#__menu` MODIFY `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'The time the menu item was checked out.'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.4-2017-07-05.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.4-2017-07-05.sql new file mode 100644 index 0000000000000..0c4bb1b3b6d9e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.7.4-2017-07-05.sql @@ -0,0 +1 @@ +DELETE FROM `#__postinstall_messages` WHERE `title_key` = 'COM_CPANEL_MSG_PHPVERSION_TITLE'; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.8.0-2017-07-28.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.0-2017-07-28.sql new file mode 100644 index 0000000000000..3ea86df61fc79 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.8.0-2017-07-28.sql @@ -0,0 +1 @@ +ALTER TABLE `#__fields_groups` ADD COLUMN `params` TEXT NOT NULL AFTER `ordering`; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.8.0-2017-07-31.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.0-2017-07-31.sql new file mode 100644 index 0000000000000..81a631edd50c8 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.8.0-2017-07-31.sql @@ -0,0 +1,5 @@ +INSERT INTO `#__extensions` +(`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) +VALUES + (318, 0, 'mod_sampledata', 'module', 'mod_sampledata', '', 1, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), + (479, 0, 'plg_sampledata_blog', 'plugin', 'blog', 'sampledata', 0, 0, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.8.2-2017-10-14.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.2-2017-10-14.sql new file mode 100644 index 0000000000000..d379ef208d611 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.8.2-2017-10-14.sql @@ -0,0 +1,5 @@ +-- +-- Add index for alias check #__content +-- + +ALTER TABLE `#__content` ADD INDEX `idx_alias` (`alias`(191)); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.8.4-2018-01-16.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.4-2018-01-16.sql new file mode 100644 index 0000000000000..1d204b7f63f13 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.8.4-2018-01-16.sql @@ -0,0 +1,2 @@ +ALTER TABLE `#__user_keys` DROP INDEX `series_2`; +ALTER TABLE `#__user_keys` DROP INDEX `series_3`; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.8.6-2018-02-14.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.6-2018-02-14.sql new file mode 100644 index 0000000000000..b88087a13504f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.8.6-2018-02-14.sql @@ -0,0 +1,6 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); + +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `action_file`, `action`, `condition_file`, `condition_method`, `version_introduced`, `enabled`) +VALUES +(700, 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION', 'plg_captcha_recaptcha', 1, 'action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_condition', '3.8.6', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.8.8-2018-05-18.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.8-2018-05-18.sql new file mode 100644 index 0000000000000..981549dd05ab5 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.8.8-2018-05-18.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `action_file`, `action`, `condition_file`, `condition_method`, `version_introduced`, `enabled`) +VALUES +(700, 'COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_TITLE', 'COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/updatedefaultsettings.php', 'admin_postinstall_updatedefaultsettings_condition', '3.8.8', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.8.9-2018-06-19.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.9-2018-06-19.sql new file mode 100644 index 0000000000000..cd46b4624a2ac --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.8.9-2018-06-19.sql @@ -0,0 +1,2 @@ +-- Enable Sample Data Module. +UPDATE `#__extensions` SET `enabled` = '1' WHERE `name` = 'mod_sampledata'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-02.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-02.sql new file mode 100644 index 0000000000000..c2488dd013b54 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-02.sql @@ -0,0 +1,16 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(35, 0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); + +CREATE TABLE IF NOT EXISTS `#__privacy_requests` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `email` varchar(100) NOT NULL DEFAULT '', + `requested_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `status` tinyint NOT NULL DEFAULT 0, + `request_type` varchar(25) NOT NULL DEFAULT '', + `confirm_token` varchar(100) NOT NULL DEFAULT '', + `confirm_token_created_at` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `checked_out` int NOT NULL DEFAULT 0, + `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + KEY `idx_checkout` (`checked_out`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-03.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-03.sql new file mode 100644 index 0000000000000..d1f294af6a0ff --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-03.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(482, 0, 'plg_content_confirmconsent', 'plugin', 'confirmconsent', 'content', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-05.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-05.sql new file mode 100644 index 0000000000000..23edbd62d0c0d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-05.sql @@ -0,0 +1,85 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(36, 0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(483, 0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(484, 0, 'plg_actionlog_joomla', 'plugin', 'joomla', 'actionlog', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); + + +-- +-- Table structure for table `#__action_logs` +-- + +CREATE TABLE IF NOT EXISTS `#__action_logs` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `message_language_key` varchar(255) NOT NULL DEFAULT '', + `message` text NOT NULL, + `log_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `extension` varchar(50) NOT NULL DEFAULT '', + `user_id` int NOT NULL DEFAULT 0, + `item_id` int NOT NULL DEFAULT 0, + `ip_address` VARCHAR(40) NOT NULL DEFAULT '0.0.0.0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +-- +-- Table structure for table `#__action_logs_extensions` +-- + +CREATE TABLE IF NOT EXISTS `#__action_logs_extensions` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `extension` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +INSERT INTO `#__action_logs_extensions` (`id`, `extension`) VALUES +(1, 'com_banners'), +(2, 'com_cache'), +(3, 'com_categories'), +(4, 'com_config'), +(5, 'com_contact'), +(6, 'com_content'), +(7, 'com_installer'), +(8, 'com_media'), +(9, 'com_menus'), +(10, 'com_messages'), +(11, 'com_modules'), +(12, 'com_newsfeeds'), +(13, 'com_plugins'), +(14, 'com_redirect'), +(15, 'com_tags'), +(16, 'com_templates'), +(17, 'com_users'); + +-- +-- Table structure for table `#__action_log_config` +-- + +CREATE TABLE IF NOT EXISTS `#__action_log_config` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `type_title` varchar(255) NOT NULL DEFAULT '', + `type_alias` varchar(255) NOT NULL DEFAULT '', + `id_holder` varchar(255), + `title_holder` varchar(255), + `table_name` varchar(255), + `text_prefix` varchar(255), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +INSERT INTO `#__action_log_config` (`id`, `type_title`, `type_alias`, `id_holder`, `title_holder`, `table_name`, `text_prefix`) VALUES +(1, 'article', 'com_content.article', 'id' ,'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(2, 'article', 'com_content.form', 'id', 'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(3, 'banner', 'com_banners.banner', 'id' ,'name' , '#__banners', 'PLG_ACTIONLOG_JOOMLA'), +(4, 'user_note', 'com_users.note', 'id', 'subject' ,'#__user_notes', 'PLG_ACTIONLOG_JOOMLA'), +(5, 'media', 'com_media.file', '' , 'name' , '', 'PLG_ACTIONLOG_JOOMLA'), +(6, 'category', 'com_categories.category', 'id' , 'title' , '#__categories', 'PLG_ACTIONLOG_JOOMLA'), +(7, 'menu', 'com_menus.menu', 'id' ,'title' , '#__menu_types', 'PLG_ACTIONLOG_JOOMLA'), +(8, 'menu_item', 'com_menus.item', 'id' , 'title' , '#__menu', 'PLG_ACTIONLOG_JOOMLA'), +(9, 'newsfeed', 'com_newsfeeds.newsfeed', 'id' ,'name' , '#__newsfeeds', 'PLG_ACTIONLOG_JOOMLA'), +(10, 'link', 'com_redirect.link', 'id', 'old_url' , '#__redirect_links', 'PLG_ACTIONLOG_JOOMLA'), +(11, 'tag', 'com_tags.tag', 'id', 'title' , '#__tags', 'PLG_ACTIONLOG_JOOMLA'), +(12, 'style', 'com_templates.style', 'id' , 'title' , '#__template_styles', 'PLG_ACTIONLOG_JOOMLA'), +(13, 'plugin', 'com_plugins.plugin', 'extension_id' , 'name' , '#__extensions', 'PLG_ACTIONLOG_JOOMLA'), +(14, 'component_config', 'com_config.component', 'extension_id' , 'name', '', 'PLG_ACTIONLOG_JOOMLA'), +(15, 'contact', 'com_contact.contact', 'id', 'name', '#__contact_details', 'PLG_ACTIONLOG_JOOMLA'), +(16, 'module', 'com_modules.module', 'id' ,'title', '#__modules', 'PLG_ACTIONLOG_JOOMLA'), +(17, 'access_level', 'com_users.level', 'id' , 'title', '#__viewlevels', 'PLG_ACTIONLOG_JOOMLA'), +(18, 'banner_client', 'com_banners.client', 'id', 'name', '#__banner_clients', 'PLG_ACTIONLOG_JOOMLA'); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-19.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-19.sql new file mode 100644 index 0000000000000..512acbd7f707e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-19.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(481, 0, 'plg_fields_repeatable', 'plugin', 'repeatable', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-20.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-20.sql new file mode 100644 index 0000000000000..8b918f8c257be --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-20.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(319, 0, 'mod_latestactions', 'module', 'mod_latestactions', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-24.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-24.sql new file mode 100644 index 0000000000000..5a1cd89365325 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-24.sql @@ -0,0 +1,14 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(485, 0, 'plg_system_privacyconsent', 'plugin', 'privacyconsent', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); + +CREATE TABLE IF NOT EXISTS `#__privacy_consents` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `user_id` int unsigned NOT NULL DEFAULT 0, + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `subject` varchar(255) NOT NULL DEFAULT '', + `body` text NOT NULL, + `remind` tinyint NOT NULL DEFAULT 0, + `token` varchar(100) NOT NULL DEFAULT '', + PRIMARY KEY (`id`), + KEY `idx_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-27.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-27.sql new file mode 100644 index 0000000000000..ab0958e02c946 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-05-27.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(486, 0, 'plg_system_logrotation', 'plugin', 'logrotation', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(487, 0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-02.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-02.sql new file mode 100644 index 0000000000000..676a90a35da52 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-02.sql @@ -0,0 +1,4 @@ +ALTER TABLE `#__content` ADD COLUMN `note` VARCHAR(255) NOT NULL DEFAULT ''; + +UPDATE `#__content_types` SET `field_mappings` = +'{"common":{"core_content_item_id":"id","core_title":"title","core_state":"state","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"introtext", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"attribs", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"urls", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"asset_id", "note":"note"}, "special":{"fulltext":"fulltext"}}' WHERE `type_alias` = 'com_content.article'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-12.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-12.sql new file mode 100644 index 0000000000000..c45e9d6c7d9fd --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-12.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(320, 0, 'mod_privacy_dashboard', 'module', 'mod_privacy_dashboard', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-13.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-13.sql new file mode 100644 index 0000000000000..edda43880912d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-13.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(488, 0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-14.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-14.sql new file mode 100644 index 0000000000000..cc18b1d191c96 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-14.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `action_file`, `action`, `condition_file`, `condition_method`, `version_introduced`, `enabled`) VALUES +(700, 'COM_ACTIONLOGS_POSTINSTALL_TITLE', 'COM_ACTIONLOGS_POSTINSTALL_BODY', '', 'com_actionlogs', 1, 'message', '', '', '', '', '3.9.0', 1), +(700, 'COM_PRIVACY_POSTINSTALL_TITLE', 'COM_PRIVACY_POSTINSTALL_BODY', '', 'com_privacy', 1, 'message', '', '', '', '', '3.9.0', 1); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-17.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-17.sql new file mode 100644 index 0000000000000..d3d3ee5f930f3 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-06-17.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(489, 0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-09.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-09.sql new file mode 100644 index 0000000000000..7c8215c3f93e6 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-09.sql @@ -0,0 +1,4 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(490, 0, 'plg_privacy_contact', 'plugin', 'contact', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(491, 0, 'plg_privacy_content', 'plugin', 'content', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-10.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-10.sql new file mode 100644 index 0000000000000..3c8c70a81ade9 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-10.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__action_log_config` (`id`, `type_title`, `type_alias`, `id_holder`, `title_holder`, `table_name`, `text_prefix`) + VALUES (19, 'application_config', 'com_config.application', '', 'name', '', 'PLG_ACTIONLOG_JOOMLA'); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-11.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-11.sql new file mode 100644 index 0000000000000..a6b89c858e868 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-07-11.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-08-12.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-08-12.sql new file mode 100644 index 0000000000000..47766a8be970f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-08-12.sql @@ -0,0 +1 @@ +ALTER TABLE `#__privacy_consents` ADD COLUMN `state` INT NOT NULL DEFAULT 1 AFTER `user_id`; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-08-28.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-08-28.sql new file mode 100644 index 0000000000000..26c9db6ecf61e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-08-28.sql @@ -0,0 +1,3 @@ +ALTER TABLE `#__session` MODIFY `session_id` varbinary(192) NOT NULL; +ALTER TABLE `#__session` MODIFY `guest` tinyint unsigned DEFAULT 1; +ALTER TABLE `#__session` MODIFY `time` int NOT NULL DEFAULT 0; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-08-29.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-08-29.sql new file mode 100644 index 0000000000000..9fe0097bbc15a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-08-29.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(494, 0, 'plg_captcha_recaptcha_invisible', 'plugin', 'recaptcha_invisible', 'captcha', 0, 0, 1, 0, '', '{"public_key":"","private_key":"","theme":"clean"}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-09-04.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-09-04.sql new file mode 100644 index 0000000000000..9e2d67e313327 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-09-04.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS `#__action_logs_users` ( + `user_id` int UNSIGNED NOT NULL, + `notify` tinyint UNSIGNED NOT NULL, + `extensions` text NOT NULL, + PRIMARY KEY (`user_id`), + KEY `idx_notify` (`notify`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-10-15.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-10-15.sql new file mode 100644 index 0000000000000..c9a13c1f64a00 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-10-15.sql @@ -0,0 +1,4 @@ +ALTER TABLE `#__action_logs` ADD INDEX `idx_user_id` (`user_id`); +ALTER TABLE `#__action_logs` ADD INDEX `idx_user_id_logdate` (`user_id`, `log_date`); +ALTER TABLE `#__action_logs` ADD INDEX `idx_user_id_extension` (`user_id`, `extension`); +ALTER TABLE `#__action_logs` ADD INDEX `idx_extension_item_id` (`extension`, `item_id`); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-10-20.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-10-20.sql new file mode 100644 index 0000000000000..79f266d89036f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-10-20.sql @@ -0,0 +1,3 @@ +ALTER TABLE `#__privacy_requests` DROP INDEX `idx_checkout`; +ALTER TABLE `#__privacy_requests` DROP COLUMN `checked_out`; +ALTER TABLE `#__privacy_requests` DROP COLUMN `checked_out_time`; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-10-21.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-10-21.sql new file mode 100644 index 0000000000000..1fafdfdc2c74d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.0-2018-10-21.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(495, 0, 'plg_privacy_consents', 'plugin', 'consents', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.10-2019-07-09.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.10-2019-07-09.sql new file mode 100644 index 0000000000000..3738ee367d0ac --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.10-2019-07-09.sql @@ -0,0 +1 @@ +ALTER TABLE `#__template_styles` MODIFY `home` char(7) NOT NULL DEFAULT '0'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.16-2020-02-15.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.16-2020-02-15.sql new file mode 100644 index 0000000000000..929ff845fb0e3 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.16-2020-02-15.sql @@ -0,0 +1,12 @@ +ALTER TABLE `#__categories` MODIFY `description` mediumtext; +ALTER TABLE `#__categories` MODIFY `params` text; +ALTER TABLE `#__fields` MODIFY `default_value` text; +ALTER TABLE `#__fields_values` MODIFY `value` text; +ALTER TABLE `#__finder_links` MODIFY `description` text; +ALTER TABLE `#__modules` MODIFY `content` text; +ALTER TABLE `#__ucm_content` MODIFY `core_body` mediumtext; +ALTER TABLE `#__ucm_content` MODIFY `core_params` text; +ALTER TABLE `#__ucm_content` MODIFY `core_images` text; +ALTER TABLE `#__ucm_content` MODIFY `core_urls` text; +ALTER TABLE `#__ucm_content` MODIFY `core_metakey` text; +ALTER TABLE `#__ucm_content` MODIFY `core_metadesc` text; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.16-2020-03-04.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.16-2020-03-04.sql new file mode 100644 index 0000000000000..e010ec4d5baf0 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.16-2020-03-04.sql @@ -0,0 +1,2 @@ +ALTER TABLE `#__users` DROP INDEX `username`; +ALTER TABLE `#__users` ADD UNIQUE INDEX `idx_username` (`username`); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.19-2020-05-16.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.19-2020-05-16.sql new file mode 100644 index 0000000000000..72bb1e445f0f9 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.19-2020-05-16.sql @@ -0,0 +1,2 @@ +-- Add back the default value which might have been lost with utf8mb4 conversion on certain CMS versions +ALTER TABLE `#__ucm_content` MODIFY `core_title` varchar(400) NOT NULL DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.19-2020-06-01.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.19-2020-06-01.sql new file mode 100644 index 0000000000000..b1dafe3c66888 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.19-2020-06-01.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `action_file`, `action`, `condition_file`, `condition_method`, `version_introduced`, `enabled`) +VALUES +(700, 'COM_CPANEL_MSG_TEXTFILTER3919_TITLE', 'COM_CPANEL_MSG_TEXTFILTER3919_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/textfilter3919.php', 'admin_postinstall_textfilter3919_condition', '3.9.19', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.21-2020-08-02.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.21-2020-08-02.sql new file mode 100644 index 0000000000000..62259eb3d06ac --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.21-2020-08-02.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `action_file`, `action`, `condition_file`, `condition_method`, `version_introduced`, `enabled`) +VALUES +(700, 'COM_CPANEL_MSG_HTACCESSSVG_TITLE', 'COM_CPANEL_MSG_HTACCESSSVG_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/htaccesssvg.php', 'admin_postinstall_htaccesssvg_condition', '3.9.21', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.22-2020-09-16.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.22-2020-09-16.sql new file mode 100644 index 0000000000000..6bb54d13ce8ec --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.22-2020-09-16.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `version_introduced`, `enabled`) +VALUES +(700, 'COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_DESCRIPTION', '', 'com_admin', 1, 'message', '3.9.22', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.26-2021-04-07.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.26-2021-04-07.sql new file mode 100644 index 0000000000000..3ca32d45fde62 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.26-2021-04-07.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `version_introduced`, `enabled`, `condition_file`, `condition_method`, `action_file`, `action`) +VALUES +(700, 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_DESCRIPTION', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_ACTION', 'com_admin', 1, 'action', '3.9.26', 1, 'admin://components/com_admin/postinstall/behindproxy.php', 'admin_postinstall_behindproxy_condition', 'admin://components/com_admin/postinstall/behindproxy.php', 'behindproxy_postinstall_action'); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.27-2021-04-20.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.27-2021-04-20.sql new file mode 100644 index 0000000000000..42748f289e559 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.27-2021-04-20.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `language_extension`, `language_client_id`, `type`, `version_introduced`, `enabled`) +VALUES +(700, 'COM_ADMIN_POSTINSTALL_MSG_FLOC_BLOCKER_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_FLOC_BLOCKER_DESCRIPTION', 'com_admin', 1, 'message', '3.9.27', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.3-2019-01-12.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.3-2019-01-12.sql new file mode 100644 index 0000000000000..f5d2d6ca9c050 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.3-2019-01-12.sql @@ -0,0 +1,6 @@ +UPDATE `#__extensions` +SET `params` = REPLACE(`params`, '"com_categories",', '"com_categories","com_checkin",') +WHERE `name` = 'com_actionlogs'; + +INSERT INTO `#__action_logs_extensions` (`extension`) VALUES +('com_checkin'); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.3-2019-02-07.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.3-2019-02-07.sql new file mode 100644 index 0000000000000..4536e316ad09e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.3-2019-02-07.sql @@ -0,0 +1,3 @@ +INSERT INTO `#__postinstall_messages` (`extension_id`, `title_key`, `description_key`, `action_key`, `language_extension`, `language_client_id`, `type`, `action_file`, `action`, `condition_file`, `condition_method`, `version_introduced`, `enabled`) +VALUES +(700, 'COM_CPANEL_MSG_ADDNOSNIFF_TITLE', 'COM_CPANEL_MSG_ADDNOSNIFF_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/addnosniff.php', 'admin_postinstall_addnosniff_condition', '3.9.3', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.7-2019-04-23.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.7-2019-04-23.sql new file mode 100644 index 0000000000000..8250cfbcb04e7 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.7-2019-04-23.sql @@ -0,0 +1 @@ +ALTER TABLE `#__session` ADD INDEX `client_id_guest` (`client_id`, `guest`); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.7-2019-04-26.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.7-2019-04-26.sql new file mode 100644 index 0000000000000..5a13011beeae1 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.7-2019-04-26.sql @@ -0,0 +1 @@ +UPDATE `#__content_types` SET `content_history_options` = REPLACE(`content_history_options`, '\"ignoreChanges\":[\"modified_by\", \"modified\", \"checked_out\", \"checked_out_time\", \"version\", \"hits\"]', '\"ignoreChanges\":[\"modified_by\", \"modified\", \"checked_out\", \"checked_out_time\", \"version\", \"hits\", \"ordering\"]'); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.7-2019-05-16.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.7-2019-05-16.sql new file mode 100644 index 0000000000000..e03422239c89e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.7-2019-05-16.sql @@ -0,0 +1 @@ +# Query removed, see https://github.com/joomla/joomla-cms/pull/25177 diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.8-2019-06-11.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.8-2019-06-11.sql new file mode 100644 index 0000000000000..61d79e585edb8 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.8-2019-06-11.sql @@ -0,0 +1 @@ +UPDATE #__users SET params = REPLACE(params, '",,"', '","'); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.9.8-2019-06-15.sql b/administrator/components/com_admin/sql/updates/mysql/3.9.8-2019-06-15.sql new file mode 100644 index 0000000000000..33df450aa00ca --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.9.8-2019-06-15.sql @@ -0,0 +1,4 @@ +ALTER TABLE `#__template_styles` DROP INDEX `idx_home`; +# Query removed, see https://github.com/joomla/joomla-cms/pull/25484 +ALTER TABLE `#__template_styles` ADD INDEX `idx_client_id` (`client_id`); +ALTER TABLE `#__template_styles` ADD INDEX `idx_client_id_home` (`client_id`, `home`); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.1.0.sql b/administrator/components/com_admin/sql/updates/postgresql/3.1.0.sql index 7a7ec83dd5247..6f44725507f2b 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.1.0.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.1.0.sql @@ -1,6 +1,15 @@ /* Changes to tables where data type conflicts exist with MySQL (mainly dealing with null values */ -ALTER TABLE "#__modules" ALTER COLUMN "content" SET DEFAULT ''; -ALTER TABLE "#__updates" ALTER COLUMN "data" SET DEFAULT ''; + +-- +-- The following statement has to be disabled because it conflicts with +-- a later change added with Joomla! 3.9.16, see file 3.9.16-2020-02-15.sql +-- +-- ALTER TABLE "#__modules" ALTER COLUMN "content" SET DEFAULT ''; +-- +-- The following statement has to be disabled because it conflicts with +-- a later change added with Joomla! 3.8.8 to repair the update of database schema changes +-- +-- ALTER TABLE "#__updates" ALTER COLUMN "data" SET DEFAULT ''; /* Tags database schema */ @@ -72,7 +81,7 @@ CREATE TABLE "#__tags" ( "title" character varying(255) NOT NULL, "alias" character varying(255) DEFAULT '' NOT NULL, "note" character varying(255) DEFAULT '' NOT NULL, - "description" text DEFAULT '' NOT NULL, + "description" text, "published" smallint DEFAULT 0 NOT NULL, "checked_out" bigint DEFAULT 0 NOT NULL, "checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, @@ -183,11 +192,11 @@ CREATE INDEX "#__ucm_content_idx_core_type_id" ON "#__ucm_content" ("core_type_i -- Add extensions table records -- INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES -(29, 'com_tags', 'component', 'com_tags', '', 1, 1, 1, 1, '{"legacy":false,"name":"com_tags","type":"component","creationDate":"March 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"COM_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(315, 'mod_stats_admin', 'module', 'mod_stats_admin', '', 1, 1, 1, 0, '{"name":"mod_stats_admin","type":"module","creationDate":"September 2012","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"MOD_STATS_XML_DESCRIPTION","group":""}', '{"serverinfo":"0","siteinfo":"0","counter":"0","increase":"0","cache":"1","cache_time":"900","cachemode":"static"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(316, 'mod_tags_popular', 'module', 'mod_tags_popular', '', 0, 1, 1, 0, '{"name":"mod_tags_popular","type":"module","creationDate":"January 2013","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"MOD_TAGS_POPULAR_XML_DESCRIPTION","group":""}', '{"maximum":"5","timeframe":"alltime","owncache":"1"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(317, 'mod_tags_similar', 'module', 'mod_tags_similar', '', 0, 1, 1, 0, '{"name":"mod_tags_similar","type":"module","creationDate":"January 2013","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"MOD_TAGS_SIMILAR_XML_DESCRIPTION","group":""}', '{"maximum":"5","matchtype":"any","owncache":"1"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(447, 'plg_finder_tags', 'plugin', 'tags', 'finder', 0, 1, 1, 0, '{"name":"plg_finder_tags","type":"plugin","creationDate":"February 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"PLG_FINDER_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); +(29, 'com_tags', 'component', 'com_tags', '', 1, 1, 1, 1, '{"legacy":false,"name":"com_tags","type":"component","creationDate":"March 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"COM_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(315, 'mod_stats_admin', 'module', 'mod_stats_admin', '', 1, 1, 1, 0, '{"name":"mod_stats_admin","type":"module","creationDate":"September 2012","author":"Joomla! Project","copyright":"(C) 2012 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"MOD_STATS_XML_DESCRIPTION","group":""}', '{"serverinfo":"0","siteinfo":"0","counter":"0","increase":"0","cache":"1","cache_time":"900","cachemode":"static"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(316, 'mod_tags_popular', 'module', 'mod_tags_popular', '', 0, 1, 1, 0, '{"name":"mod_tags_popular","type":"module","creationDate":"January 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"MOD_TAGS_POPULAR_XML_DESCRIPTION","group":""}', '{"maximum":"5","timeframe":"alltime","owncache":"1"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(317, 'mod_tags_similar', 'module', 'mod_tags_similar', '', 0, 1, 1, 0, '{"name":"mod_tags_similar","type":"module","creationDate":"January 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"MOD_TAGS_SIMILAR_XML_DESCRIPTION","group":""}', '{"maximum":"5","matchtype":"any","owncache":"1"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(447, 'plg_finder_tags', 'plugin', 'tags', 'finder', 0, 1, 1, 0, '{"name":"plg_finder_tags","type":"plugin","creationDate":"February 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"PLG_FINDER_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); -- -- Add menu table records diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.10.0-2020-08-10.sql b/administrator/components/com_admin/sql/updates/postgresql/3.10.0-2020-08-10.sql new file mode 100644 index 0000000000000..72fc2120309c5 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.10.0-2020-08-10.sql @@ -0,0 +1,6 @@ +-- +-- These database columns are not used in Joomla 3.10 but will be used in Joomla 4. +-- They are added to 3.10 because otherwise the update to 4 will fail. +-- +ALTER TABLE "#__template_styles" ADD COLUMN "inheritable" smallint NOT NULL DEFAULT 0; +ALTER TABLE "#__template_styles" ADD COLUMN "parent" character varying(50) DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.10.0-2021-05-28.sql b/administrator/components/com_admin/sql/updates/postgresql/3.10.0-2021-05-28.sql new file mode 100644 index 0000000000000..e420377288209 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.10.0-2021-05-28.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(0, 'plg_quickicon_eos310', 'plugin', 'eos310', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.10.7-2022-02-20.sql.sql b/administrator/components/com_admin/sql/updates/postgresql/3.10.7-2022-02-20.sql.sql new file mode 100644 index 0000000000000..011c2a13ae9dc --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.10.7-2022-02-20.sql.sql @@ -0,0 +1 @@ +DELETE FROM "#__postinstall_messages" WHERE "title_key" = 'COM_ADMIN_POSTINSTALL_MSG_FLOC_BLOCKER_TITLE'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.0.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.0.sql index b6020f0a3b936..1592d3e57af2b 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.0.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.2.0.sql @@ -19,13 +19,13 @@ UPDATE "#__extensions" SET "params" = '{"template_positions_display":"0","upload UPDATE "#__extensions" SET "params" = '{"lineNumbers":"1","lineWrapping":"1","matchTags":"1","matchBrackets":"1","marker-gutter":"1","autoCloseTags":"1","autoCloseBrackets":"1","autoFocus":"1","theme":"default","tabmode":"indent"}' WHERE "extension_id" = 410; INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES -(30, 'com_contenthistory', 'component', 'com_contenthistory', '', 1, 1, 1, 0, '{"name":"com_contenthistory","type":"component","creationDate":"May 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.\\n\\t","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_CONTENTHISTORY_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 1, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(30, 'com_contenthistory', 'component', 'com_contenthistory', '', 1, 1, 1, 0, '{"name":"com_contenthistory","type":"component","creationDate":"May 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.\\n\\t","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_CONTENTHISTORY_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 1, 0, '{"name":"com_ajax","type":"component","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"COM_AJAX_DESC","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (32, 'com_postinstall', 'component', 'com_postinstall', '', 1, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (105, 'FOF', 'library', 'fof', '', 0, 1, 1, 1, '{"legacy":false,"name":"FOF","type":"library","creationDate":"2013-10-08","author":"Nicholas K. Dionysopoulos \/ Akeeba Ltd","copyright":"(C)2011-2013 Nicholas K. Dionysopoulos","authorEmail":"nicholas@akeebabackup.com","authorUrl":"https:\/\/www.akeebabackup.com","version":"2.1.rc4","description":"Framework-on-Framework (FOF) - A rapid component development framework for Joomla!","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(448, 'plg_twofactorauth_totp', 'plugin', 'totp', 'twofactorauth', 0, 0, 1, 0, '{"name":"plg_twofactorauth_totp","type":"plugin","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(449, 'plg_authentication_cookie', 'plugin', 'cookie', 'authentication', 0, 1, 1, 0, '{"name":"plg_authentication_cookie","type":"plugin","creationDate":"July 2013","author":"Joomla! Project","copyright":"Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"PLG_AUTH_COOKIE_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(450, 'plg_twofactorauth_yubikey', 'plugin', 'yubikey', 'twofactorauth', 0, 0, 1, 0, '{"name":"plg_twofactorauth_yubikey","type":"plugin","creationDate":"Se[ptember 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2016 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"PLG_TWOFACTORAUTH_YUBIKEY_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); +(448, 'plg_twofactorauth_totp', 'plugin', 'totp', 'twofactorauth', 0, 0, 1, 0, '{"name":"plg_twofactorauth_totp","type":"plugin","creationDate":"August 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(449, 'plg_authentication_cookie', 'plugin', 'cookie', 'authentication', 0, 1, 1, 0, '{"name":"plg_authentication_cookie","type":"plugin","creationDate":"July 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.0.0","description":"PLG_AUTH_COOKIE_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(450, 'plg_twofactorauth_yubikey', 'plugin', 'yubikey', 'twofactorauth', 0, 0, 1, 0, '{"name":"plg_twofactorauth_yubikey","type":"plugin","creationDate":"Se[ptember 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.2.0","description":"PLG_TWOFACTORAUTH_YUBIKEY_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); INSERT INTO "#__menu" ("menutype", "title", "alias", "note", "path", "link", "type", "published", "parent_id", "level", "component_id", "checked_out", "checked_out_time", "browserNav", "access", "img", "template_style_id", "params", "lft", "rgt", "home", "language", "client_id") VALUES ('main', 'com_postinstall', 'Post-installation messages', '', 'Post-installation messages', 'index.php?option=com_postinstall', 'component', 0, 1, 1, 32, 0, '1970-01-01 00:00:00', 0, 1, 'class:postinstall', 0, '', 45, 46, 0, '*', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.3.6-2014-09-30.sql b/administrator/components/com_admin/sql/updates/postgresql/3.3.6-2014-09-30.sql index fae9c20d45522..d54a13381e721 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.3.6-2014-09-30.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.3.6-2014-09-30.sql @@ -1,5 +1,5 @@ INSERT INTO "#__update_sites" ("name", "type", "location", "enabled") VALUES -('Joomla! Update Component Update Site', 'extension', 'http://update.joomla.org/core/extensions/com_joomlaupdate.xml', 1); +('Joomla! Update Component Update Site', 'extension', 'https://update.joomla.org/core/extensions/com_joomlaupdate.xml', 1); INSERT INTO "#__update_sites_extensions" ("update_site_id", "extension_id") VALUES ((SELECT "update_site_id" FROM "#__update_sites" WHERE "name" = 'Joomla! Update Component Update Site'), (SELECT "extension_id" FROM "#__extensions" WHERE "name" = 'com_joomlaupdate')); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-10-04.sql b/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-10-04.sql index 5a4262f94e7a1..efe8c54737fff 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-10-04.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-10-04.sql @@ -1,3 +1,7 @@ ALTER TABLE "#__finder_links" ALTER COLUMN "title" TYPE character varying(400); ALTER TABLE "#__finder_links" ALTER COLUMN "description" TYPE text; -ALTER TABLE "#__finder_links" ALTER COLUMN "description" SET NOT NULL; +-- +-- The following statement has to be disabled because it conflicts with +-- a later change added with Joomla! 3.9.16, see file 3.9.16-2020-02-15.sql +-- +-- ALTER TABLE "#__finder_links" ALTER COLUMN "description" SET NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-29.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-29.sql index 1676d972db1fa..6122643dc3502 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-29.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-29.sql @@ -9,17 +9,17 @@ CREATE TABLE "#__fields" ( "title" varchar(255) DEFAULT '' NOT NULL, "name" varchar(255) DEFAULT '' NOT NULL, "label" varchar(255) DEFAULT '' NOT NULL, - "default_value" text DEFAULT '' NOT NULL, + "default_value" text, "type" varchar(255) DEFAULT 'text' NOT NULL, "note" varchar(255) DEFAULT '' NOT NULL, - "description" text DEFAULT '' NOT NULL, + "description" text, "state" smallint DEFAULT 0 NOT NULL, "required" smallint DEFAULT 0 NOT NULL, "checked_out" integer DEFAULT 0 NOT NULL, "checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "ordering" bigint DEFAULT 0 NOT NULL, - "params" text DEFAULT '' NOT NULL, - "fieldparams" text DEFAULT '' NOT NULL, + "params" text, + "fieldparams" text, "language" varchar(7) DEFAULT '' NOT NULL, "created_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, "created_user_id" bigint DEFAULT 0 NOT NULL, @@ -53,7 +53,7 @@ CREATE TABLE "#__fields_groups" ( "context" varchar(255) DEFAULT '' NOT NULL, "title" varchar(255) DEFAULT '' NOT NULL, "note" varchar(255) DEFAULT '' NOT NULL, - "description" text DEFAULT '' NOT NULL, + "description" text, "state" smallint DEFAULT 0 NOT NULL, "checked_out" integer DEFAULT 0 NOT NULL, "checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, @@ -79,7 +79,7 @@ CREATE INDEX "#__fields_groups_idx_language" ON "#__fields_groups" ("language"); CREATE TABLE "#__fields_values" ( "field_id" bigint DEFAULT 0 NOT NULL, "item_id" varchar(255) DEFAULT '' NOT NULL, -"value" text DEFAULT '' NOT NULL +"value" text ); CREATE INDEX "#__fields_values_idx_field_id" ON "#__fields_values" ("field_id"); CREATE INDEX "#__fields_values_idx_item_id" ON "#__fields_values" ("item_id"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-19.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-19.sql index da2b368041418..1711f5761e2e9 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-19.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-19.sql @@ -1,3 +1,3 @@ -ALTER TABLE "#__menu_types" ADD "client_id" int DEFAULT 0 NOT NULL; +ALTER TABLE "#__menu_types" ADD COLUMN "client_id" int DEFAULT 0 NOT NULL; UPDATE "#__menu" SET "published" = 1 WHERE "menutype" = 'main' OR "menutype" = 'menu'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-21.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-21.sql index 3fee4a355d6a9..e68abd215444d 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-21.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-21.sql @@ -1,2 +1,2 @@ -- Replace language image UNIQUE index for a normal INDEX. -ALTER TABLE "#__languages" DROP CONSTRAINT "#__idx_image"; +ALTER TABLE "#__languages" DROP CONSTRAINT "#__languages_idx_image"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-08.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-08.sql index 35cbc78a02002..7b9ef266cc5ba 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-08.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-08.sql @@ -1,9 +1,14 @@ -- Normalize ucm_content_table default values. ALTER TABLE "#__ucm_content" ALTER COLUMN "core_title" SET DEFAULT ''; -ALTER TABLE "#__ucm_content" ALTER COLUMN "core_body" SET DEFAULT ''; -ALTER TABLE "#__ucm_content" ALTER COLUMN "core_params" SET DEFAULT ''; -ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metadata" SET DEFAULT ''; -ALTER TABLE "#__ucm_content" ALTER COLUMN "core_images" SET DEFAULT ''; -ALTER TABLE "#__ucm_content" ALTER COLUMN "core_urls" SET DEFAULT ''; -ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metakey" SET DEFAULT ''; -ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metadesc" SET DEFAULT ''; + +-- +-- The following statements have to be disabled because they conflict with +-- a later change added with Joomla! 3.9.16, see file 3.9.16-2020-02-15.sql +-- +-- ALTER TABLE "#__ucm_content" ALTER COLUMN "core_body" SET DEFAULT ''; +-- ALTER TABLE "#__ucm_content" ALTER COLUMN "core_params" SET DEFAULT ''; +-- ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metadata" SET DEFAULT ''; +-- ALTER TABLE "#__ucm_content" ALTER COLUMN "core_images" SET DEFAULT ''; +-- ALTER TABLE "#__ucm_content" ALTER COLUMN "core_urls" SET DEFAULT ''; +-- ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metakey" SET DEFAULT ''; +-- ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metadesc" SET DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-09.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-09.sql index 8d4895fb4d79f..e3cc644324478 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-09.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-09.sql @@ -1,6 +1,10 @@ -- Normalize categories table default values. ALTER TABLE "#__categories" ALTER COLUMN "title" SET DEFAULT ''; -ALTER TABLE "#__categories" ALTER COLUMN "params" SET DEFAULT ''; +-- +-- The following statement has to be disabled because it conflicts with +-- a later change added with Joomla! 3.9.16, see file 3.9.16-2020-02-15.sql +-- +-- ALTER TABLE "#__categories" ALTER COLUMN "params" SET DEFAULT ''; ALTER TABLE "#__categories" ALTER COLUMN "metadesc" SET DEFAULT ''; ALTER TABLE "#__categories" ALTER COLUMN "metakey" SET DEFAULT ''; ALTER TABLE "#__categories" ALTER COLUMN "metadata" SET DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-17.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-17.sql index 4f13b235764f7..3009938a54d1c 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-17.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-17.sql @@ -1,3 +1,58 @@ -- Sync menutype for admin menu and set client_id correct -UPDATE "#__menu" SET "client_id" = 1 WHERE "menutype" = 'main' OR "menutype" = 'menu'; -UPDATE "#__menu" SET "menutype" = 'main' WHERE "menutype" = 'main' OR "menutype" = 'menu'; + +-- Note: This file had to be modified with Joomla 3.7.3 because the +-- original version made site menus disappear if there were menu types +-- "main" or "menu" defined for the site. + +-- Step 1: If there is any user-defined menu and menu type "main" for the site +-- (client_id = 0), then change the menu type for the menu, any module and the +-- menu type to something very likely not being used yet and just within the +-- max. length of 24 characters. +UPDATE "#__menu" + SET "menutype" = 'main_is_reserved_133C585' + WHERE "client_id" = 0 + AND "menutype" = 'main' + AND (SELECT COUNT("id") FROM "#__menu_types" WHERE "client_id" = 0 AND "menutype" = 'main') > 0; + +UPDATE "#__modules" + SET "params" = REPLACE("params",'"menutype":"main"','"menutype":"main_is_reserved_133C585"') + WHERE "client_id" = 0 + AND (SELECT COUNT("id") FROM "#__menu_types" WHERE "client_id" = 0 AND "menutype" = 'main') > 0; + +UPDATE "#__menu_types" + SET "menutype" = 'main_is_reserved_133C585' + WHERE "client_id" = 0 + AND "menutype" = 'main'; + +-- Step 2: What remains now are the main menu items, possibly with wrong +-- client_id if there was nothing hit by step 1 because there was no record in +-- the menu types table with client_id = 0. +UPDATE "#__menu" + SET "client_id" = 1 + WHERE "menutype" = 'main'; + +-- Step 3: If we have menu items for the admin using menutype = "menu" and +-- having correct client_id = 1, we can be sure they belong to the admin menu +-- and so rename the menutype. +UPDATE "#__menu" + SET "menutype" = 'main' + WHERE "client_id" = 1 + AND "menutype" = 'menu'; + +-- Step 4: If there is no user-defined menu type "menu" for the site, we can +-- assume that any menu items for that menu type belong to the admin. +-- Fix the client_id for those as it was done with the original version of this +-- schema update script here. +UPDATE "#__menu" + SET "menutype" = 'main', + "client_id" = 1 + WHERE "menutype" = 'menu' + AND (SELECT COUNT("id") FROM "#__menu_types" WHERE "client_id" = 0 AND "menutype" = 'menu') > 0; + +-- Step 5: For the standard admin menu items of menutype "main" there is no record +-- in the menutype table on a clean Joomla installation. If there is one, it is a +-- mistake and it should be deleted. This is also the case with menu type "menu" +-- for the admin, for which we changed the menutype of the menu items in step 3. +DELETE FROM "#__menu_types" + WHERE "client_id" = 1 + AND "menutype" IN ('main', 'menu'); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-19.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-19.sql index 5df4318cc3680..a71c3e11b2db5 100644 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-19.sql +++ b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-19.sql @@ -1,2 +1,2 @@ -- Set integer field default values. -UPDATE `#__extensions` SET `params` = '{"multiple":"0","first":"1","last":"100","step":"1"}' WHERE `name` = 'plg_fields_integer'; +UPDATE "#__extensions" SET "params" = '{"multiple":"0","first":"1","last":"100","step":"1"}' WHERE "name" = 'plg_fields_integer'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.4-2017-07-05.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.4-2017-07-05.sql new file mode 100644 index 0000000000000..e9f5f2b099a0f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.7.4-2017-07-05.sql @@ -0,0 +1 @@ +DELETE FROM "#__postinstall_messages" WHERE "title_key" = 'COM_CPANEL_MSG_PHPVERSION_TITLE'; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.8.0-2017-07-28.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.0-2017-07-28.sql new file mode 100644 index 0000000000000..6b88b64d45039 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.8.0-2017-07-28.sql @@ -0,0 +1 @@ +ALTER TABLE "#__fields_groups" ADD COLUMN "params" TEXT NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.8.0-2017-07-31.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.0-2017-07-31.sql new file mode 100644 index 0000000000000..e03ec77abc604 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.8.0-2017-07-31.sql @@ -0,0 +1,5 @@ +INSERT INTO "#__extensions" +("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") +VALUES + (318, 0, 'mod_sampledata', 'module', 'mod_sampledata', '', 1, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), + (479, 0, 'plg_sampledata_blog', 'plugin', 'blog', 'sampledata', 0, 0, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.8.2-2017-10-14.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.2-2017-10-14.sql new file mode 100644 index 0000000000000..f7183db8bd2a3 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.8.2-2017-10-14.sql @@ -0,0 +1,5 @@ +-- +-- Add index for alias check #__content +-- + +CREATE INDEX "#__content_idx_alias" ON "#__content" ("alias"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.8.4-2018-01-16.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.4-2018-01-16.sql new file mode 100644 index 0000000000000..4546bab50b54a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.8.4-2018-01-16.sql @@ -0,0 +1,2 @@ +DROP INDEX "#__user_keys_series_2"; +DROP INDEX "#__user_keys_series_3"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.8.6-2018-02-14.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.6-2018-02-14.sql new file mode 100644 index 0000000000000..bd70f521d3872 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.8.6-2018-02-14.sql @@ -0,0 +1,6 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); + +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "action_file", "action", "condition_file", "condition_method", "version_introduced", "enabled") +VALUES +(700, 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION', 'plg_captcha_recaptcha', 1, 'action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_condition', '3.8.6', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.8.8-2018-05-18.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.8-2018-05-18.sql new file mode 100644 index 0000000000000..975876d250321 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.8.8-2018-05-18.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "action_file", "action", "condition_file", "condition_method", "version_introduced", "enabled") +VALUES +(700, 'COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_TITLE', 'COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/updatedefaultsettings.php', 'admin_postinstall_updatedefaultsettings_condition', '3.8.8', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.8.9-2018-06-19.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.9-2018-06-19.sql new file mode 100644 index 0000000000000..666def7ad577b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.8.9-2018-06-19.sql @@ -0,0 +1,2 @@ +-- Enable Sample Data Module. +UPDATE "#__extensions" SET "enabled" = '1' WHERE "name" = 'mod_sampledata'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-02.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-02.sql new file mode 100644 index 0000000000000..ae705b2f6e56b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-02.sql @@ -0,0 +1,16 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(35, 0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); + +CREATE TABLE "#__privacy_requests" ( + "id" serial NOT NULL, + "email" varchar(100) DEFAULT '' NOT NULL, + "requested_at" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "status" smallint DEFAULT 0 NOT NULL, + "request_type" varchar(25) DEFAULT '' NOT NULL, + "confirm_token" varchar(100) DEFAULT '' NOT NULL, + "confirm_token_created_at" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "checked_out" integer DEFAULT 0 NOT NULL, + "checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "#__privacy_requests_idx_checked_out" ON "#__privacy_requests" ("checked_out"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-03.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-03.sql new file mode 100644 index 0000000000000..6ef9999e731f4 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-03.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(482, 0, 'plg_content_confirmconsent', 'plugin', 'confirmconsent', 'content', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-05.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-05.sql new file mode 100644 index 0000000000000..94366fa954c7e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-05.sql @@ -0,0 +1,92 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(36, 0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(483, 0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(484, 0, 'plg_actionlog_joomla', 'plugin', 'joomla', 'actionlog', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); + +-- +-- Table: #__action_logs +-- +CREATE TABLE "#__action_logs" ( + "id" serial NOT NULL, + "message_language_key" varchar(255) NOT NULL DEFAULT '', + "message" text NOT NULL DEFAULT '', + "log_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "extension" varchar(50) NOT NULL DEFAULT '', + "user_id" integer DEFAULT 0 NOT NULL, + "item_id" integer DEFAULT 0 NOT NULL, + "ip_address" varchar(40) NOT NULL DEFAULT '0.0.0.0', + PRIMARY KEY ("id") +); + +-- Table: #__action_logs_extensions +-- +CREATE TABLE "#__action_logs_extensions" ( + "id" serial NOT NULL, + "extension" varchar(50) NOT NULL DEFAULT '', + PRIMARY KEY ("id") +); + +-- +-- Dumping data for table '#__action_logs_extensions' +-- +INSERT INTO "#__action_logs_extensions" ("id", "extension") VALUES +(1, 'com_banners'), +(2, 'com_cache'), +(3, 'com_categories'), +(4, 'com_config'), +(5, 'com_contact'), +(6, 'com_content'), +(7, 'com_installer'), +(8, 'com_media'), +(9, 'com_menus'), +(10, 'com_messages'), +(11, 'com_modules'), +(12, 'com_newsfeeds'), +(13, 'com_plugins'), +(14, 'com_redirect'), +(15, 'com_tags'), +(16, 'com_templates'), +(17, 'com_users'); + +SELECT setval('#__action_logs_extensions_id_seq', 18, false); +-- -------------------------------------------------------- + +-- +-- Table: #__action_log_config +-- +CREATE TABLE "#__action_log_config" ( + "id" serial NOT NULL, + "type_title" varchar(255) NOT NULL DEFAULT '', + "type_alias" varchar(255) NOT NULL DEFAULT '', + "id_holder" varchar(255) NULL, + "title_holder" varchar(255) NULL, + "table_name" varchar(255) NULL, + "text_prefix" varchar(255) NULL, + PRIMARY KEY ("id") +); + +-- +-- Dumping data for table #__action_log_config +-- +INSERT INTO "#__action_log_config" ("id", "type_title", "type_alias", "id_holder", "title_holder", "table_name", "text_prefix") VALUES +(1, 'article', 'com_content.article', 'id' ,'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(2, 'article', 'com_content.form', 'id', 'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(3, 'banner', 'com_banners.banner', 'id' ,'name' , '#__banners', 'PLG_ACTIONLOG_JOOMLA'), +(4, 'user_note', 'com_users.note', 'id', 'subject' ,'#__user_notes', 'PLG_ACTIONLOG_JOOMLA'), +(5, 'media', 'com_media.file', '' , 'name' , '', 'PLG_ACTIONLOG_JOOMLA'), +(6, 'category', 'com_categories.category', 'id' , 'title' , '#__categories', 'PLG_ACTIONLOG_JOOMLA'), +(7, 'menu', 'com_menus.menu', 'id' ,'title' , '#__menu_types', 'PLG_ACTIONLOG_JOOMLA'), +(8, 'menu_item', 'com_menus.item', 'id' , 'title' , '#__menu', 'PLG_ACTIONLOG_JOOMLA'), +(9, 'newsfeed', 'com_newsfeeds.newsfeed', 'id' ,'name' , '#__newsfeeds', 'PLG_ACTIONLOG_JOOMLA'), +(10, 'link', 'com_redirect.link', 'id', 'old_url' , '#__redirect_links', 'PLG_ACTIONLOG_JOOMLA'), +(11, 'tag', 'com_tags.tag', 'id', 'title' , '#__tags', 'PLG_ACTIONLOG_JOOMLA'), +(12, 'style', 'com_templates.style', 'id' , 'title' , '#__template_styles', 'PLG_ACTIONLOG_JOOMLA'), +(13, 'plugin', 'com_plugins.plugin', 'extension_id' , 'name' , '#__extensions', 'PLG_ACTIONLOG_JOOMLA'), +(14, 'component_config', 'com_config.component', 'extension_id' , 'name', '', 'PLG_ACTIONLOG_JOOMLA'), +(15, 'contact', 'com_contact.contact', 'id', 'name', '#__contact_details', 'PLG_ACTIONLOG_JOOMLA'), +(16, 'module', 'com_modules.module', 'id' ,'title', '#__modules', 'PLG_ACTIONLOG_JOOMLA'), +(17, 'access_level', 'com_users.level', 'id' , 'title', '#__viewlevels', 'PLG_ACTIONLOG_JOOMLA'), +(18, 'banner_client', 'com_banners.client', 'id', 'name', '#__banner_clients', 'PLG_ACTIONLOG_JOOMLA'); + + +SELECT setval('#__action_log_config_id_seq', 18, false); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-19.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-19.sql new file mode 100644 index 0000000000000..b8ce724e76bf4 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-19.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(481, 0, 'plg_fields_repeatable', 'plugin', 'repeatable', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-20.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-20.sql new file mode 100644 index 0000000000000..1245f67a7df6b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-20.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(319, 0, 'mod_latestactions', 'module', 'mod_latestactions', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-24.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-24.sql new file mode 100644 index 0000000000000..649caf5771667 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-24.sql @@ -0,0 +1,18 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(485, 0, 'plg_system_privacyconsent', 'plugin', 'privacyconsent', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); + +-- +-- Table structure for table `#__privacy_consents` +-- + +CREATE TABLE "#__privacy_consents" ( + "id" serial NOT NULL, + "user_id" bigint DEFAULT 0 NOT NULL, + "created" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "subject" varchar(255) DEFAULT '' NOT NULL, + "body" text NOT NULL, + "remind" smallint DEFAULT 0 NOT NULL, + "token" varchar(100) DEFAULT '' NOT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX "#__privacy_consents_idx_user_id" ON "#__privacy_consents" ("user_id"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-27.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-27.sql new file mode 100644 index 0000000000000..9d13ef54ad8e7 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-05-27.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(486, 0, 'plg_system_logrotation', 'plugin', 'logrotation', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(487, 0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-02.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-02.sql new file mode 100644 index 0000000000000..ad80aeae81ecf --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-02.sql @@ -0,0 +1,4 @@ +ALTER TABLE "#__content" ADD COLUMN "note" VARCHAR(255) NOT NULL DEFAULT ''; + +UPDATE "#__content_types" SET "field_mappings" = +'{"common":{"core_content_item_id":"id","core_title":"title","core_state":"state","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"introtext", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"attribs", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"urls", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"asset_id", "note":"note"}, "special":{"fulltext":"fulltext"}}' WHERE "type_alias" = 'com_content.article'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-12.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-12.sql new file mode 100644 index 0000000000000..f1d2dffb8e93e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-12.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(320, 0, 'mod_privacy_dashboard', 'module', 'mod_privacy_dashboard', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-13.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-13.sql new file mode 100644 index 0000000000000..86a8fa6ba7167 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-13.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(488, 0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-14.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-14.sql new file mode 100644 index 0000000000000..f2e932fee5a4f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-14.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "action_file", "action", "condition_file", "condition_method", "version_introduced", "enabled") VALUES +(700, 'COM_ACTIONLOGS_POSTINSTALL_TITLE', 'COM_ACTIONLOGS_POSTINSTALL_BODY', '', 'com_actionlogs', 1, 'message', '', '', '', '', '3.9.0', 1), +(700, 'COM_PRIVACY_POSTINSTALL_TITLE', 'COM_PRIVACY_POSTINSTALL_BODY', '', 'com_privacy', 1, 'message', '', '', '', '', '3.9.0', 1); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-17.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-17.sql new file mode 100644 index 0000000000000..e10fe5087a320 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-06-17.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(489, 0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-09.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-09.sql new file mode 100644 index 0000000000000..951914be74db4 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-09.sql @@ -0,0 +1,4 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(490, 0, 'plg_privacy_contact', 'plugin', 'contact', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(491, 0, 'plg_privacy_content', 'plugin', 'content', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-10.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-10.sql new file mode 100644 index 0000000000000..74e65fd4b16be --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-10.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__action_log_config" ("id", "type_title", "type_alias", "id_holder", "title_holder", "table_name", "text_prefix") + VALUES (19, 'application_config', 'com_config.application', '', 'name', '', 'PLG_ACTIONLOG_JOOMLA'); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-11.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-11.sql new file mode 100644 index 0000000000000..270a1af635148 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-07-11.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-08-12.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-08-12.sql new file mode 100644 index 0000000000000..4e56e40bb7911 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-08-12.sql @@ -0,0 +1 @@ +ALTER TABLE "#__privacy_consents" ADD COLUMN "state" smallint DEFAULT 1 NOT NULL; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-08-28.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-08-28.sql new file mode 100644 index 0000000000000..2492ac1788f60 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-08-28.sql @@ -0,0 +1,7 @@ +ALTER TABLE "#__session" ALTER COLUMN "session_id" DROP DEFAULT; +ALTER TABLE "#__session" ALTER COLUMN "session_id" TYPE bytea USING "session_id"::bytea; +ALTER TABLE "#__session" ALTER COLUMN "session_id" SET NOT NULL; +ALTER TABLE "#__session" ALTER COLUMN "time" DROP DEFAULT, + ALTER COLUMN "time" TYPE integer USING "time"::integer; +ALTER TABLE "#__session" ALTER COLUMN "time" SET DEFAULT 0; +ALTER TABLE "#__session" ALTER COLUMN "time" SET NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-08-29.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-08-29.sql new file mode 100644 index 0000000000000..b4421597d895b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-08-29.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(494, 0, 'plg_captcha_recaptcha_invisible', 'plugin', 'recaptcha_invisible', 'captcha', 0, 0, 1, 0, '', '{"public_key":"","private_key":"","theme":"clean"}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-09-04.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-09-04.sql new file mode 100644 index 0000000000000..1823a0a8fed4b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-09-04.sql @@ -0,0 +1,8 @@ +CREATE TABLE "#__action_logs_users" ( + "user_id" integer NOT NULL, + "notify" integer NOT NULL, + "extensions" text NOT NULL, + PRIMARY KEY ("user_id") +); + +CREATE INDEX "#__action_logs_users_idx_notify" ON "#__action_logs_users" ("notify"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-10-15.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-10-15.sql new file mode 100644 index 0000000000000..358decd0a484a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-10-15.sql @@ -0,0 +1,4 @@ +CREATE INDEX "#__action_logs_idx_user_id" ON "#__action_logs" ("user_id"); +CREATE INDEX "#__action_logs_idx_user_id_logdate" ON "#__action_logs" ("user_id", "log_date"); +CREATE INDEX "#__action_logs_idx_user_id_extension" ON "#__action_logs" ("user_id", "extension"); +CREATE INDEX "#__action_logs_idx_extension_itemid" ON "#__action_logs" ("extension", "item_id"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-10-20.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-10-20.sql new file mode 100644 index 0000000000000..a33f707516f5a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-10-20.sql @@ -0,0 +1,3 @@ +DROP INDEX "#__privacy_requests_idx_checked_out"; +ALTER TABLE "#__privacy_requests" DROP COLUMN "checked_out"; +ALTER TABLE "#__privacy_requests" DROP COLUMN "checked_out_time"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-10-21.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-10-21.sql new file mode 100644 index 0000000000000..271663e64fbc2 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.0-2018-10-21.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(495, 0, 'plg_privacy_consents', 'plugin', 'consents', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.10-2019-07-09.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.10-2019-07-09.sql new file mode 100644 index 0000000000000..b1a394cd5c582 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.10-2019-07-09.sql @@ -0,0 +1,2 @@ +ALTER TABLE "#__template_styles" ALTER COLUMN "home" TYPE character varying(7); +ALTER TABLE "#__template_styles" ALTER COLUMN "home" SET DEFAULT '0'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.15-2020-01-08.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.15-2020-01-08.sql new file mode 100644 index 0000000000000..a25179f9b38d1 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.15-2020-01-08.sql @@ -0,0 +1 @@ +CREATE INDEX "#__users_email_lower" ON "#__users" (lower("email")); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.16-2020-02-15.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.16-2020-02-15.sql new file mode 100644 index 0000000000000..6ea38fd84b8f2 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.16-2020-02-15.sql @@ -0,0 +1,52 @@ +ALTER TABLE "#__categories" ALTER COLUMN "description" DROP NOT NULL; +ALTER TABLE "#__categories" ALTER COLUMN "description" DROP DEFAULT; + +ALTER TABLE "#__categories" ALTER COLUMN "params" DROP NOT NULL; +ALTER TABLE "#__categories" ALTER COLUMN "params" DROP DEFAULT; + +ALTER TABLE "#__fields" ALTER COLUMN "default_value" DROP NOT NULL; +ALTER TABLE "#__fields" ALTER COLUMN "default_value" DROP DEFAULT; + +ALTER TABLE "#__fields" ALTER COLUMN "description" DROP DEFAULT; + +ALTER TABLE "#__fields" ALTER COLUMN "params" DROP DEFAULT; + +ALTER TABLE "#__fields" ALTER COLUMN "fieldparams" DROP DEFAULT; + +ALTER TABLE "#__fields_groups" ALTER COLUMN "params" DROP DEFAULT; + +ALTER TABLE "#__fields_values" ALTER COLUMN "value" DROP NOT NULL; +ALTER TABLE "#__fields_values" ALTER COLUMN "value" DROP DEFAULT; + +ALTER TABLE "#__finder_links" ALTER COLUMN "description" DROP NOT NULL; +ALTER TABLE "#__finder_links" ALTER COLUMN "description" DROP DEFAULT; + +ALTER TABLE "#__menu" ALTER COLUMN "params" DROP DEFAULT; + +ALTER TABLE "#__modules" ALTER COLUMN "content" DROP NOT NULL; +ALTER TABLE "#__modules" ALTER COLUMN "content" DROP DEFAULT; + +ALTER TABLE "#__tags" ALTER COLUMN "description" DROP DEFAULT; + +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_body" DROP NOT NULL; +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_body" DROP DEFAULT; + +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_params" DROP NOT NULL; +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_params" DROP DEFAULT; + +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metadata" DROP NOT NULL; +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metadata" DROP DEFAULT; + +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_images" DROP NOT NULL; +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_images" DROP DEFAULT; + +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_urls" DROP NOT NULL; +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_urls" DROP DEFAULT; + +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metakey" DROP NOT NULL; +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metakey" DROP DEFAULT; + +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metadesc" DROP NOT NULL; +ALTER TABLE "#__ucm_content" ALTER COLUMN "core_metadesc" DROP DEFAULT; + +ALTER TABLE "#__action_logs" ALTER COLUMN "message" DROP DEFAULT; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.16-2020-03-04.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.16-2020-03-04.sql new file mode 100644 index 0000000000000..3cfda3a1f7776 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.16-2020-03-04.sql @@ -0,0 +1,2 @@ +DROP INDEX IF EXISTS "#__users_username"; +ALTER TABLE "#__users" ADD CONSTRAINT "#__users_idx_username" UNIQUE ("username"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.19-2020-06-01.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.19-2020-06-01.sql new file mode 100644 index 0000000000000..f196a8a7b6bc8 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.19-2020-06-01.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "action_file", "action", "condition_file", "condition_method", "version_introduced", "enabled") +VALUES +(700, 'COM_CPANEL_MSG_TEXTFILTER3919_TITLE', 'COM_CPANEL_MSG_TEXTFILTER3919_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/textfilter3919.php', 'admin_postinstall_textfilter3919_condition', '3.9.19', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.21-2020-08-02.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.21-2020-08-02.sql new file mode 100644 index 0000000000000..dc2c47969420b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.21-2020-08-02.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "action_file", "action", "condition_file", "condition_method", "version_introduced", "enabled") +VALUES +(700, 'COM_CPANEL_MSG_HTACCESSSVG_TITLE', 'COM_CPANEL_MSG_HTACCESSSVG_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/htaccesssvg.php', 'admin_postinstall_htaccesssvg_condition', '3.9.21', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.22-2020-09-16.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.22-2020-09-16.sql new file mode 100644 index 0000000000000..87e0c23f0b6a4 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.22-2020-09-16.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "version_introduced", "enabled") +VALUES +(700, 'COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_DESCRIPTION', '', 'com_admin', 1, 'message', '3.9.22', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.26-2021-04-07.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.26-2021-04-07.sql new file mode 100644 index 0000000000000..b0175336d31dd --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.26-2021-04-07.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "version_introduced", "enabled", "condition_file", "condition_method", "action_file", "action") +VALUES +(700, 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_DESCRIPTION', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_ACTION', 'com_admin', 1, 'action', '3.9.26', 1, 'admin://components/com_admin/postinstall/behindproxy.php', 'admin_postinstall_behindproxy_condition', 'admin://components/com_admin/postinstall/behindproxy.php', 'behindproxy_postinstall_action'); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.27-2021-04-20.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.27-2021-04-20.sql new file mode 100644 index 0000000000000..c34c3ad0be557 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.27-2021-04-20.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "language_extension", "language_client_id", "type", "version_introduced", "enabled") +VALUES +(700, 'COM_ADMIN_POSTINSTALL_MSG_FLOC_BLOCKER_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_FLOC_BLOCKER_DESCRIPTION', 'com_admin', 1, 'message', '3.9.27', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.3-2019-01-12.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.3-2019-01-12.sql new file mode 100644 index 0000000000000..c31ae5d91173e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.3-2019-01-12.sql @@ -0,0 +1,8 @@ +UPDATE "#__extensions" +SET "params" = REPLACE("params", '"com_categories",', '"com_categories","com_checkin",') +WHERE "name" = 'com_actionlogs'; + +INSERT INTO "#__action_logs_extensions" ("extension") VALUES +('com_checkin'); + +SELECT setval('#__action_logs_extensions_id_seq', max(id)) FROM "#__action_logs_extensions"; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.3-2019-02-07.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.3-2019-02-07.sql new file mode 100644 index 0000000000000..228a572d131d0 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.3-2019-02-07.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "action_file", "action", "condition_file", "condition_method", "version_introduced", "enabled") +VALUES +(700, 'COM_CPANEL_MSG_ADDNOSNIFF_TITLE', 'COM_CPANEL_MSG_ADDNOSNIFF_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/addnosniff.php', 'admin_postinstall_addnosniff_condition', '3.9.3', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.7-2019-04-23.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.7-2019-04-23.sql new file mode 100644 index 0000000000000..88dc5d39f8d5e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.7-2019-04-23.sql @@ -0,0 +1 @@ +CREATE INDEX "#__session_idx_client_id_guest" ON "#__session" ("client_id", "guest"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.7-2019-04-26.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.7-2019-04-26.sql new file mode 100644 index 0000000000000..0439a87b08e84 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.7-2019-04-26.sql @@ -0,0 +1 @@ +UPDATE "#__content_types" SET "content_history_options" = REPLACE("content_history_options", '\"ignoreChanges\":[\"modified_by\", \"modified\", \"checked_out\", \"checked_out_time\", \"version\", \"hits\"]', '\"ignoreChanges\":[\"modified_by\", \"modified\", \"checked_out\", \"checked_out_time\", \"version\", \"hits\", \"ordering\"]'); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.7-2019-05-16.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.7-2019-05-16.sql new file mode 100644 index 0000000000000..e03422239c89e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.7-2019-05-16.sql @@ -0,0 +1 @@ +# Query removed, see https://github.com/joomla/joomla-cms/pull/25177 diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.8-2019-06-11.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.8-2019-06-11.sql new file mode 100644 index 0000000000000..018e8d73c3bde --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.8-2019-06-11.sql @@ -0,0 +1 @@ +UPDATE "#__users" SET "params" = REPLACE("params", '",,"', '","'); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.9.8-2019-06-15.sql b/administrator/components/com_admin/sql/updates/postgresql/3.9.8-2019-06-15.sql new file mode 100644 index 0000000000000..3acf06149c527 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.9.8-2019-06-15.sql @@ -0,0 +1,4 @@ +DROP INDEX IF EXISTS "#__template_styles_idx_home"; +# Queries removed, see https://github.com/joomla/joomla-cms/pull/25484 +CREATE INDEX "#__template_styles_idx_client_id" ON "#__template_styles" ("client_id"); +CREATE INDEX "#__template_styles_idx_client_id_home" ON "#__template_styles" ("client_id", "home"); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-18.sql b/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-18.sql index f3f38ed99e370..36759a4627132 100644 --- a/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-18.sql +++ b/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-18.sql @@ -1,7 +1,7 @@ SET IDENTITY_INSERT [#__extensions] ON; INSERT INTO [#__extensions] ([extension_id], [name], [type], [element], [folder], [client_id], [enabled], [access], [protected], [manifest_cache], [params], [custom_data], [system_data], [checked_out], [checked_out_time], [ordering], [state]) -SELECT 28, 'com_joomlaupdate', 'component', 'com_joomlaupdate', '', 1, 1, 0, 1, '{"legacy":false,"name":"com_joomlaupdate","type":"component","creationDate":"February 2012","author":"Joomla! Project","copyright":"(C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"2.5.2","description":"COM_JOOMLAUPDATE_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0; +SELECT 28, 'com_joomlaupdate', 'component', 'com_joomlaupdate', '', 1, 1, 0, 1, '{"legacy":false,"name":"com_joomlaupdate","type":"component","creationDate":"February 2012","author":"Joomla! Project","copyright":"(C) 2012 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"2.5.2","description":"COM_JOOMLAUPDATE_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0; SET IDENTITY_INSERT [#__extensions] OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/2.5.7.sql b/administrator/components/com_admin/sql/updates/sqlazure/2.5.7.sql index a3655c75bafd8..b249c8a8cbbef 100644 --- a/administrator/components/com_admin/sql/updates/sqlazure/2.5.7.sql +++ b/administrator/components/com_admin/sql/updates/sqlazure/2.5.7.sql @@ -1,5 +1,5 @@ INSERT INTO [#__update_sites] ([name], [type], [location], [enabled], [last_check_timestamp]) -SELECT 'Accredited Joomla! Translations', 'collection', 'http://update.joomla.org/language/translationlist.xml', 1, 0; +SELECT 'Accredited Joomla! Translations', 'collection', 'https://update.joomla.org/language/translationlist.xml', 1, 0; INSERT INTO [#__update_sites_extensions] ([update_site_id], [extension_id]) SELECT SCOPE_IDENTITY(), 600; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.1.0.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.1.0.sql index a2f47b58adfef..b2a78f3c1e096 100644 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.1.0.sql +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.1.0.sql @@ -318,7 +318,7 @@ CREATE NONCLUSTERED INDEX [idx_core_type_id] ON [#__ucm_content] SET IDENTITY_INSERT [#__extensions] ON; INSERT INTO [#__extensions] ([extension_id], [name], [type], [element], [folder], [client_id], [enabled], [access], [protected], [manifest_cache], [params], [custom_data], [system_data], [checked_out], [checked_out_time], [ordering], [state]) -SELECT 29, 'com_tags', 'component', 'com_tags', '', 1, 1, 1, 1, '{"name":"com_joomlaupdate","type":"component","creationDate":"March 2013","author":"Joomla! Project","copyright":"(C) 2005 - 2017 Open Source Matters. All rights reserved.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"COM_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0; +SELECT 29, 'com_tags', 'component', 'com_tags', '', 1, 1, 1, 1, '{"name":"com_joomlaupdate","type":"component","creationDate":"March 2013","author":"Joomla! Project","copyright":"(C) 2013 Open Source Matters, Inc.","authorEmail":"admin@joomla.org","authorUrl":"www.joomla.org","version":"3.1.0","description":"COM_TAGS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0; SET IDENTITY_INSERT [#__extensions] OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.10.0-2021-05-28.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.10.0-2021-05-28.sql new file mode 100644 index 0000000000000..99a2032e512c2 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.10.0-2021-05-28.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(0, 'plg_quickicon_eos310', 'plugin', 'eos310', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.10.1-2021-08-17.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.10.1-2021-08-17.sql new file mode 100644 index 0000000000000..0b7c592d78dc1 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.10.1-2021-08-17.sql @@ -0,0 +1,6 @@ +-- +-- These database columns are not used in Joomla 3.10 but will be used in Joomla 4. +-- They are added to 3.10 because otherwise the update to 4 will fail. +-- +ALTER TABLE [#__template_styles] ADD [inheritable] [smallint] NOT NULL DEFAULT 0; +ALTER TABLE [#__template_styles] ADD [parent] [nvarchar](50) NOT NULL DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.10.7-2022-02-20.sql.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.10.7-2022-02-20.sql.sql new file mode 100644 index 0000000000000..f176bd3ce4229 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.10.7-2022-02-20.sql.sql @@ -0,0 +1 @@ +DELETE FROM [#__postinstall_messages] WHERE [title_key] = 'COM_ADMIN_POSTINSTALL_MSG_FLOC_BLOCKER_TITLE'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.3.6-2014-09-30.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.3.6-2014-09-30.sql index 309ade5b7c50a..1ff46584f11cd 100644 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.3.6-2014-09-30.sql +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.3.6-2014-09-30.sql @@ -1,5 +1,5 @@ INSERT INTO [#__update_sites] ([name], [type], [location], [enabled]) -SELECT 'Joomla! Update Component Update Site', 'extension', 'http://update.joomla.org/core/extensions/com_joomlaupdate.xml', 1; +SELECT 'Joomla! Update Component Update Site', 'extension', 'https://update.joomla.org/core/extensions/com_joomlaupdate.xml', 1; INSERT INTO [#__update_sites_extensions] ([update_site_id], [extension_id]) SELECT (SELECT [update_site_id] FROM [#__update_sites] WHERE [name] = 'Joomla! Update Component Update Site'), (SELECT [extension_id] FROM [#__extensions] WHERE [name] = 'com_joomlaupdate'); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-17.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-17.sql index 7bf8964d9c432..86ffa3836f9d5 100644 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-17.sql +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-17.sql @@ -1,6 +1,62 @@ -- Sync menutype for admin menu and set client_id correct -UPDATE [#__menu] SET [client_id] = 1 WHERE [menutype] = 'main' OR [menutype] = 'menu'; -UPDATE [#__menu] SET [menutype] = 'main' WHERE [menutype] = 'main' OR [menutype] = 'menu'; +-- Note: This change had to be modified with Joomla 3.7.3 because the +-- original version made site menus disappear if there were menu types +-- "main" or "menu" defined for the site. + +-- Step 1: If there is any user-defined menu and menu type "main" for the site +-- (client_id = 0), then change the menu type for the menu, any module and the +-- menu type to something very likely not being used yet and just within the +-- max. length of 24 characters. +UPDATE [#__menu] + SET [menutype] = 'main_is_reserved_133C585' + WHERE [client_id] = 0 + AND [menutype] = 'main' + AND (SELECT COUNT([id]) FROM [#__menu_types] WHERE [client_id] = 0 AND [menutype] = 'main') > 0; + +UPDATE [#__modules] + SET [params] = REPLACE([params],'"menutype":"main"','"menutype":"main_is_reserved_133C585"') + WHERE [client_id] = 0 + AND (SELECT COUNT([id]) FROM [#__menu_types] WHERE [client_id] = 0 AND [menutype] = 'main') > 0; + +UPDATE [#__menu_types] + SET [menutype] = 'main_is_reserved_133C585' + WHERE [client_id] = 0 + AND [menutype] = 'main'; + +-- Step 2: What remains now are the main menu items, possibly with wrong +-- client_id if there was nothing hit by step 1 because there was no record in +-- the menu types table with client_id = 0. +UPDATE [#__menu] + SET [client_id] = 1 + WHERE [menutype] = 'main'; + +-- Step 3: If we have menu items for the admin using menutype = "menu" and +-- having correct client_id = 1, we can be sure they belong to the admin menu +-- and so rename the menutype. +UPDATE [#__menu] + SET [menutype] = 'main' + WHERE [client_id] = 1 + AND [menutype] = 'menu'; + +-- Step 4: If there is no user-defined menu type "menu" for the site, we can +-- assume that any menu items for that menu type belong to the admin. +-- Fix the client_id for those as it was done with the original version of this +-- schema update script here. +UPDATE [#__menu] + SET [menutype] = 'main', + [client_id] = 1 + WHERE [menutype] = 'menu' + AND (SELECT COUNT([id]) FROM [#__menu_types] WHERE [client_id] = 0 AND [menutype] = 'menu') > 0; + +-- Step 5: For the standard admin menu items of menutype "main" there is no record +-- in the menutype table on a clean Joomla installation. If there is one, it is a +-- mistake and it should be deleted. This is also the case with menu type "menu" +-- for the admin, for which we changed the menutype of the menu items in step 3. +DELETE FROM [#__menu_types] + WHERE [client_id] = 1 + AND [menutype] IN ('main', 'menu'); + +-- End sync menutype for admin menu and set client_id correct SET IDENTITY_INSERT #__extensions ON; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.4-2017-07-05.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.4-2017-07-05.sql new file mode 100644 index 0000000000000..5fa10e2f7f73b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.7.4-2017-07-05.sql @@ -0,0 +1 @@ +DELETE FROM [#__postinstall_messages] WHERE [title_key] = 'COM_CPANEL_MSG_PHPVERSION_TITLE'; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-28.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-28.sql new file mode 100644 index 0000000000000..b25399e2478ec --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-28.sql @@ -0,0 +1 @@ +ALTER TABLE [#__fields_groups] ADD [params] [text] NOT NULL DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-31.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-31.sql new file mode 100644 index 0000000000000..b9ed858fcd02b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-31.sql @@ -0,0 +1,4 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") +VALUES + (318, 0, 'mod_sampledata', 'module', 'mod_sampledata', '', 1, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), + (479, 0, 'plg_sampledata_blog', 'plugin', 'blog', 'sampledata', 0, 0, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.8.2-2017-10-14.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.8.2-2017-10-14.sql new file mode 100644 index 0000000000000..72df8133711c1 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.8.2-2017-10-14.sql @@ -0,0 +1,8 @@ +-- +-- Add index for alias check #__content +-- + +CREATE NONCLUSTERED INDEX [idx_alias] ON [#__content] +( + [alias] ASC +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.8.4-2018-01-16.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.8.4-2018-01-16.sql new file mode 100644 index 0000000000000..15c43cf51df1c --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.8.4-2018-01-16.sql @@ -0,0 +1,2 @@ +ALTER TABLE [#__user_keys] DROP CONSTRAINT [#__user_keys$series_2]; +ALTER TABLE [#__user_keys] DROP CONSTRAINT [#__user_keys$series_3]; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.8.6-2018-02-14.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.8.6-2018-02-14.sql new file mode 100644 index 0000000000000..29ad515aec05a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.8.6-2018-02-14.sql @@ -0,0 +1,6 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "action_file", "action", "condition_file", "condition_method", "version_introduced", "enabled") +VALUES +(700, 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY', 'PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION', 'plg_captcha_recaptcha', 1, 'action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_action', 'site://plugins/captcha/recaptcha/postinstall/actions.php', 'recaptcha_postinstall_condition', '3.8.6', 1); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.8.8-2018-05-18.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.8.8-2018-05-18.sql new file mode 100644 index 0000000000000..f4c1998c71c39 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.8.8-2018-05-18.sql @@ -0,0 +1,2 @@ +INSERT INTO [#__postinstall_messages] ([extension_id], [title_key], [description_key], [action_key], [language_extension], [language_client_id], [type], [action_file], [action], [condition_file], [condition_method], [version_introduced], [enabled]) +SELECT 700, 'COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_TITLE', 'COM_CPANEL_MSG_UPDATEDEFAULTSETTINGS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/updatedefaultsettings.php', 'admin_postinstall_updatedefaultsettings_condition', '3.8.8', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.8.9-2018-06-19.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.8.9-2018-06-19.sql new file mode 100644 index 0000000000000..e1f8d0af48bd0 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.8.9-2018-06-19.sql @@ -0,0 +1,3 @@ +-- Enable Sample Data Module. +UPDATE [#__extensions] SET [enabled] = '1' WHERE [name] = 'mod_sampledata'; + diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-02.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-02.sql new file mode 100644 index 0000000000000..79370b47c0c56 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-02.sql @@ -0,0 +1,25 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(35, 0, 'com_privacy', 'component', 'com_privacy', '', 1, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; + +CREATE TABLE "#__privacy_requests" ( + "id" int IDENTITY(1,1) NOT NULL, + "email" nvarchar(100) NOT NULL DEFAULT '', + "requested_at" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', + "status" smallint NOT NULL, + "request_type" nvarchar(25) NOT NULL DEFAULT '', + "confirm_token" nvarchar(100) NOT NULL DEFAULT '', + "confirm_token_created_at" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', + "checked_out" bigint NOT NULL DEFAULT 0, + "checked_out_time" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', +CONSTRAINT "PK_#__privacy_requests_id" PRIMARY KEY CLUSTERED( + "id" ASC) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON +) ON [PRIMARY]) ON [PRIMARY]; + +CREATE NONCLUSTERED INDEX "idx_checkout" ON "#__privacy_requests" ( + "checked_out" ASC) +WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-03.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-03.sql new file mode 100644 index 0000000000000..8e8ef50ad7e90 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-03.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(482, 0, 'plg_content_confirmconsent', 'plugin', 'confirmconsent', 'content', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-05.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-05.sql new file mode 100644 index 0000000000000..6a95db975d8ba --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-05.sql @@ -0,0 +1,93 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(36, 0, 'com_actionlogs', 'component', 'com_actionlogs', '', 1, 1, 1, 1, '', '{"ip_logging":0,"csv_delimiter":",","loggable_extensions":["com_banners","com_cache","com_categories","com_config","com_contact","com_content","com_installer","com_media","com_menus","com_messages","com_modules","com_newsfeeds","com_plugins","com_redirect","com_tags","com_templates","com_users"]}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(483, 0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(484, 0, 'plg_actionlog_joomla', 'plugin', 'joomla', 'actionlog', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; + +CREATE TABLE "#__action_logs" ( + "id" "int" IDENTITY(1,1) NOT NULL, + "message_language_key" "nvarchar"(255) NOT NULL DEFAULT '', + "message" "nvarchar"(max) NOT NULL DEFAULT '', + "log_date" "datetime" NOT NULL DEFAULT '1900-01-01 00:00:00', + "extension" "nvarchar"(255) NOT NULL DEFAULT '', + "user_id" "bigint" NOT NULL DEFAULT 0, + "item_id" "bigint" NOT NULL DEFAULT 0, + "ip_address" "nvarchar"(40) NOT NULL DEFAULT '0.0.0.0', + CONSTRAINT "PK_#__action_logs_id" PRIMARY KEY CLUSTERED + ( + "id" ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]; + +CREATE TABLE "#__action_logs_extensions" ( + "id" "int" IDENTITY(1,1) NOT NULL, + "extension" "nvarchar"(255) NOT NULL DEFAULT '', + CONSTRAINT "PK_#__action_logs_extensions_id" PRIMARY KEY CLUSTERED + ( + "id" ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]; + +SET IDENTITY_INSERT "#__action_logs_extensions" ON; + +INSERT INTO "#__action_logs_extensions" ("id", "extension") VALUES +(1, 'com_banners'), +(2, 'com_cache'), +(3, 'com_categories'), +(4, 'com_config'), +(5, 'com_contact'), +(6, 'com_content'), +(7, 'com_installer'), +(8, 'com_media'), +(9, 'com_menus'), +(10, 'com_messages'), +(11, 'com_modules'), +(12, 'com_newsfeeds'), +(13, 'com_plugins'), +(14, 'com_redirect'), +(15, 'com_tags'), +(16, 'com_templates'), +(17, 'com_users'); + +SET IDENTITY_INSERT "#__action_logs_extensions" OFF; + +CREATE TABLE "#__action_log_config" ( + "id" "int" IDENTITY(1,1) NOT NULL, + "type_title" "nvarchar"(255) NOT NULL DEFAULT '', + "type_alias" "nvarchar"(255) NOT NULL DEFAULT '', + "id_holder" "nvarchar"(255) NULL, + "title_holder" "nvarchar"(255) NULL, + "table_name" "nvarchar"(255) NULL, + "text_prefix" "nvarchar"(255) NULL, + CONSTRAINT "PK_#__action_log_config_id" PRIMARY KEY CLUSTERED + ( + "id" ASC + )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] + ) ON [PRIMARY]; + +SET IDENTITY_INSERT "#__action_log_config" ON; + +INSERT INTO "#__action_log_config" ("id", "type_title", "type_alias", "id_holder", "title_holder", "table_name", "text_prefix") VALUES +(1, 'article', 'com_content.article', 'id' ,'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(2, 'article', 'com_content.form', 'id', 'title' , '#__content', 'PLG_ACTIONLOG_JOOMLA'), +(3, 'banner', 'com_banners.banner', 'id' ,'name' , '#__banners', 'PLG_ACTIONLOG_JOOMLA'), +(4, 'user_note', 'com_users.note', 'id', 'subject' ,'#__user_notes', 'PLG_ACTIONLOG_JOOMLA'), +(5, 'media', 'com_media.file', '' , 'name' , '', 'PLG_ACTIONLOG_JOOMLA'), +(6, 'category', 'com_categories.category', 'id' , 'title' , '#__categories', 'PLG_ACTIONLOG_JOOMLA'), +(7, 'menu', 'com_menus.menu', 'id' ,'title' , '#__menu_types', 'PLG_ACTIONLOG_JOOMLA'), +(8, 'menu_item', 'com_menus.item', 'id' , 'title' , '#__menu', 'PLG_ACTIONLOG_JOOMLA'), +(9, 'newsfeed', 'com_newsfeeds.newsfeed', 'id' ,'name' , '#__newsfeeds', 'PLG_ACTIONLOG_JOOMLA'), +(10, 'link', 'com_redirect.link', 'id', 'old_url' , '#__redirect_links', 'PLG_ACTIONLOG_JOOMLA'), +(11, 'tag', 'com_tags.tag', 'id', 'title' , '#__tags', 'PLG_ACTIONLOG_JOOMLA'), +(12, 'style', 'com_templates.style', 'id' , 'title' , '#__template_styles', 'PLG_ACTIONLOG_JOOMLA'), +(13, 'plugin', 'com_plugins.plugin', 'extension_id' , 'name' , '#__extensions', 'PLG_ACTIONLOG_JOOMLA'), +(14, 'component_config', 'com_config.component', 'extension_id' , 'name', '', 'PLG_ACTIONLOG_JOOMLA'), +(15, 'contact', 'com_contact.contact', 'id', 'name', '#__contact_details', 'PLG_ACTIONLOG_JOOMLA'), +(16, 'module', 'com_modules.module', 'id' ,'title', '#__modules', 'PLG_ACTIONLOG_JOOMLA'), +(17, 'access_level', 'com_users.level', 'id' , 'title', '#__viewlevels', 'PLG_ACTIONLOG_JOOMLA'), +(18, 'banner_client', 'com_banners.client', 'id', 'name', '#__banner_clients', 'PLG_ACTIONLOG_JOOMLA'); + +SET IDENTITY_INSERT "#__action_log_config" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-19.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-19.sql new file mode 100644 index 0000000000000..b443ff5878831 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-19.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(481, 0, 'plg_fields_repeatable', 'plugin', 'repeatable', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-20.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-20.sql new file mode 100644 index 0000000000000..5ac337fdfd0ad --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-20.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(319, 0, 'mod_latestactions', 'module', 'mod_latestactions', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-24.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-24.sql new file mode 100644 index 0000000000000..472e9e4a4101c --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-24.sql @@ -0,0 +1,27 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(485, 0, 'plg_system_privacyconsent', 'plugin', 'privacyconsent', 'system', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; + +-- +-- Table structure for table `#__privacy_consents` +-- + +CREATE TABLE "#__privacy_consents" ( + "id" int IDENTITY(1,1) NOT NULL, + "user_id" bigint NOT NULL DEFAULT 0, + "created" datetime2(0) NOT NULL DEFAULT '1900-01-01 00:00:00', + "subject" nvarchar(255) NOT NULL DEFAULT '', + "body" nvarchar(max) NOT NULL, + "remind" smallint NOT NULL, + "token" nvarchar(100) NOT NULL DEFAULT '', +CONSTRAINT "PK_#__privacy_consents_id" PRIMARY KEY CLUSTERED( + "id" ASC) +WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON +) ON [PRIMARY]) ON [PRIMARY]; + +CREATE NONCLUSTERED INDEX "idx_user_id" ON "#__privacy_consents" ( + "user_id" ASC) +WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-27.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-27.sql new file mode 100644 index 0000000000000..bcbbd0909805f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-05-27.sql @@ -0,0 +1,7 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(486, 0, 'plg_system_logrotation', 'plugin', 'logrotation', 'system', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(487, 0, 'plg_privacy_user', 'plugin', 'user', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-02.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-02.sql new file mode 100644 index 0000000000000..db21952d6d333 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-02.sql @@ -0,0 +1,4 @@ +ALTER TABLE "#__content" ADD "note" "nvarchar"(255) NOT NULL DEFAULT ''; + +UPDATE "#__content_types" SET "field_mappings" = +'{"common":{"core_content_item_id":"id","core_title":"title","core_state":"state","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"introtext", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"attribs", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"urls", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"asset_id", "note":"note"}, "special":{"fulltext":"fulltext"}}' WHERE "type_alias" = 'com_content.article'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-12.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-12.sql new file mode 100644 index 0000000000000..5fd86609eb03b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-12.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(320, 0, 'mod_privacy_dashboard', 'module', 'mod_privacy_dashboard', '', 1, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-13.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-13.sql new file mode 100644 index 0000000000000..a7a0e06c9aaab --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-13.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(488, 0, 'plg_quickicon_privacycheck', 'plugin', 'privacycheck', 'quickicon', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-14.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-14.sql new file mode 100644 index 0000000000000..bc2ea36823a30 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-14.sql @@ -0,0 +1,3 @@ +INSERT INTO "#__postinstall_messages" ("extension_id", "title_key", "description_key", "action_key", "language_extension", "language_client_id", "type", "action_file", "action", "condition_file", "condition_method", "version_introduced", "enabled") VALUES +(700, 'COM_ACTIONLOGS_POSTINSTALL_TITLE', 'COM_ACTIONLOGS_POSTINSTALL_BODY', '', 'com_actionlogs', 1, 'message', '', '', '', '', '3.9.0', 1), +(700, 'COM_PRIVACY_POSTINSTALL_TITLE', 'COM_PRIVACY_POSTINSTALL_BODY', '', 'com_privacy', 1, 'message', '', '', '', '', '3.9.0', 1); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-17.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-17.sql new file mode 100644 index 0000000000000..13d99b939cf67 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-06-17.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(489, 0, 'plg_user_terms', 'plugin', 'terms', 'user', 0, 0, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-09.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-09.sql new file mode 100644 index 0000000000000..a5878803c5161 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-09.sql @@ -0,0 +1,8 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(490, 0, 'plg_privacy_contact', 'plugin', 'contact', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(491, 0, 'plg_privacy_content', 'plugin', 'content', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(492, 0, 'plg_privacy_message', 'plugin', 'message', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-10.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-10.sql new file mode 100644 index 0000000000000..e02cf8ddd2ca8 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-10.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__action_log_config" ON; + +INSERT INTO "#__action_log_config" ("id", "type_title", "type_alias", "id_holder", "title_holder", "table_name", "text_prefix") VALUES +(19, 'application_config', 'com_config.application', '', 'name', '', 'PLG_ACTIONLOG_JOOMLA'); + +SET IDENTITY_INSERT "#__action_log_config" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-11.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-11.sql new file mode 100644 index 0000000000000..a70be4087de2e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-07-11.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(493, 0, 'plg_privacy_actionlogs', 'plugin', 'actionlogs', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-08-12.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-08-12.sql new file mode 100644 index 0000000000000..1b87d3dcb83a5 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-08-12.sql @@ -0,0 +1 @@ +ALTER TABLE "#__privacy_consents" ADD "state" "smallint" NOT NULL DEFAULT 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-08-28.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-08-28.sql new file mode 100644 index 0000000000000..08aad74dd3964 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-08-28.sql @@ -0,0 +1,15 @@ +sp_rename "#__session", "#__session_old"; + +SELECT cast("session_id" AS varbinary) AS "session_id", "client_id", "guest", cast("time" AS int) AS "time", "data", "userid", "username" +INTO "#__session" +FROM "#__session_old"; + +DROP TABLE "#__session_old"; + +ALTER TABLE "#__session" ALTER COLUMN "session_id" varbinary(192) NOT NULL; +ALTER TABLE "#__session" ADD CONSTRAINT "PK_#__session_session_id" PRIMARY KEY CLUSTERED ("session_id") ON [PRIMARY]; +ALTER TABLE "#__session" ALTER COLUMN "time" int NOT NULL; +ALTER TABLE "#__session" ADD DEFAULT (0) FOR "time"; + +CREATE NONCLUSTERED INDEX "time" ON "#__session" ("time"); +CREATE NONCLUSTERED INDEX "userid" ON "#__session" ("userid"); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-08-29.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-08-29.sql new file mode 100644 index 0000000000000..33e25674a3895 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-08-29.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(494, 0, 'plg_captcha_recaptcha_invisible', 'plugin', 'recaptcha_invisible', 'captcha', 0, 0, 1, 0, '', '{"public_key":"","private_key":"","theme":"clean"}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-09-04.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-09-04.sql new file mode 100644 index 0000000000000..37ed98a44ccd3 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-09-04.sql @@ -0,0 +1,14 @@ +CREATE TABLE "#__action_logs_users" ( + "user_id" int NOT NULL, + "notify" tinyint NOT NULL, + "extensions" nvarchar(max) NOT NULL, + CONSTRAINT "PK_#__action_logs_users_user_id" PRIMARY KEY NONCLUSTERED +( + "user_id" ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY]; + +CREATE CLUSTERED INDEX "idx_notify" ON "#__action_logs_users" +( + "notify" ASC +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-10-15.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-10-15.sql new file mode 100644 index 0000000000000..a1687a9ffc328 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-10-15.sql @@ -0,0 +1,22 @@ +CREATE NONCLUSTERED INDEX "idx_user_id" ON "#__action_logs" +( + "user_id" ASC +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); + +CREATE NONCLUSTERED INDEX "idx_user_id_logdate" ON "#__action_logs" +( + "user_id" ASC, + "log_date" ASC +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); + +CREATE NONCLUSTERED INDEX "idx_user_id_extension" ON "#__action_logs" +( + "user_id" ASC, + "extension" ASC +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); + +CREATE NONCLUSTERED INDEX "idx_extension_itemid" ON "#__action_logs" +( + "extension" ASC, + "item_id" +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-10-20.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-10-20.sql new file mode 100644 index 0000000000000..491cc9fa3de34 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-10-20.sql @@ -0,0 +1,25 @@ +-- Drop default values +DECLARE @table AS nvarchar(100) +DECLARE @constraintName AS nvarchar(100) +DECLARE @constraintQuery AS nvarchar(1000) +SET QUOTED_IDENTIFIER OFF +SET @table = "#__privacy_requests" +SET QUOTED_IDENTIFIER ON + +-- Drop default value from checked_out +SELECT @constraintName = name FROM sys.default_constraints +WHERE parent_object_id = object_id(@table) +AND parent_column_id = columnproperty(object_id(@table), 'checked_out', 'ColumnId') +SET @constraintQuery = 'ALTER TABLE [' + @table + '] DROP CONSTRAINT [' + @constraintName + ']' +EXECUTE sp_executesql @constraintQuery + +-- Drop default value from checked_out_time +SELECT @constraintName = name FROM sys.default_constraints +WHERE parent_object_id = object_id(@table) +AND parent_column_id = columnproperty(object_id(@table), 'checked_out_time', 'ColumnId') +SET @constraintQuery = 'ALTER TABLE [' + @table + '] DROP CONSTRAINT [' + @constraintName + ']' +EXECUTE sp_executesql @constraintQuery; + +DROP INDEX "idx_checkout" ON "#__privacy_requests"; +ALTER TABLE "#__privacy_requests" DROP COLUMN "checked_out"; +ALTER TABLE "#__privacy_requests" DROP COLUMN "checked_out_time"; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-10-21.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-10-21.sql new file mode 100644 index 0000000000000..9ea6d75325ff0 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.0-2018-10-21.sql @@ -0,0 +1,6 @@ +SET IDENTITY_INSERT "#__extensions" ON; + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(495, 0, 'plg_privacy_consents', 'plugin', 'consents', 'privacy', 0, 1, 1, 0, '', '{}', '', '', 0, '1900-01-01 00:00:00', 0, 0); + +SET IDENTITY_INSERT "#__extensions" OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.10-2019-07-09.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.10-2019-07-09.sql new file mode 100644 index 0000000000000..af8f28708f799 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.10-2019-07-09.sql @@ -0,0 +1,2 @@ +ALTER TABLE [#__template_styles] ALTER COLUMN [home] nvarchar(7) NOT NULL; +ALTER TABLE [#__template_styles] ADD DEFAULT ('0') FOR [home]; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.16-2020-03-04.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.16-2020-03-04.sql new file mode 100644 index 0000000000000..be4a5611ba8a1 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.16-2020-03-04.sql @@ -0,0 +1,6 @@ +DROP INDEX [username] ON [#__users]; + +CREATE UNIQUE INDEX [idx_username] ON [#__users] +( + [username] ASC +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.19-2020-06-01.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.19-2020-06-01.sql new file mode 100644 index 0000000000000..b16190b2ffac4 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.19-2020-06-01.sql @@ -0,0 +1,2 @@ +INSERT INTO [#__postinstall_messages] ([extension_id], [title_key], [description_key], [action_key], [language_extension], [language_client_id], [type], [action_file], [action], [condition_file], [condition_method], [version_introduced], [enabled]) +SELECT 700, 'COM_CPANEL_MSG_TEXTFILTER3919_TITLE', 'COM_CPANEL_MSG_TEXTFILTER3919_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/textfilter3919.php', 'admin_postinstall_textfilter3919_condition', '3.9.19', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.21-2020-08-02.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.21-2020-08-02.sql new file mode 100644 index 0000000000000..d3a8c2f279c9c --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.21-2020-08-02.sql @@ -0,0 +1,2 @@ +INSERT INTO [#__postinstall_messages] ([extension_id], [title_key], [description_key], [action_key], [language_extension], [language_client_id], [type], [action_file], [action], [condition_file], [condition_method], [version_introduced], [enabled]) +SELECT 700, 'COM_CPANEL_MSG_HTACCESSSVG_TITLE', 'COM_CPANEL_MSG_HTACCESSSVG_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/htaccesssvg.php', 'admin_postinstall_htaccesssvg_condition', '3.9.21', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.22-2020-09-16.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.22-2020-09-16.sql new file mode 100644 index 0000000000000..e27617ffbdf1c --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.22-2020-09-16.sql @@ -0,0 +1,3 @@ +INSERT INTO [#__postinstall_messages] ([extension_id], [title_key], [description_key], [action_key], [language_extension], [language_client_id], [type], [version_introduced], [enabled]) +VALUES +(700, 'COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_HTACCESS_AUTOINDEX_DESCRIPTION', '', 'com_admin', 1, 'message', '3.9.22', 1); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.26-2021-04-07.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.26-2021-04-07.sql new file mode 100644 index 0000000000000..a6bef6c2516ec --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.26-2021-04-07.sql @@ -0,0 +1,3 @@ +INSERT INTO [#__postinstall_messages] ([extension_id], [title_key], [description_key], [action_key], [language_extension], [language_client_id], [type], [version_introduced], [enabled], [condition_file], [condition_method], [action_file], [action]) +VALUES +(700, 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_DESCRIPTION', 'COM_ADMIN_POSTINSTALL_MSG_BEHIND_LOAD_BALANCER_ACTION', 'com_admin', 1, 'action', '3.9.26', 1, 'admin://components/com_admin/postinstall/behindproxy.php', 'admin_postinstall_behindproxy_condition', 'admin://components/com_admin/postinstall/behindproxy.php', 'behindproxy_postinstall_action'); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.27-2021-04-20.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.27-2021-04-20.sql new file mode 100644 index 0000000000000..8b9b981e1f75a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.27-2021-04-20.sql @@ -0,0 +1,3 @@ +INSERT INTO [#__postinstall_messages] ([extension_id], [title_key], [description_key], [language_extension], [language_client_id], [type], [version_introduced], [enabled]) +VALUES +(700, 'COM_ADMIN_POSTINSTALL_MSG_FLOC_BLOCKER_TITLE', 'COM_ADMIN_POSTINSTALL_MSG_FLOC_BLOCKER_DESCRIPTION', 'com_admin', 1, 'message', '3.9.27', 1); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.3-2019-01-12.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.3-2019-01-12.sql new file mode 100644 index 0000000000000..6f02ce0c8fba2 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.3-2019-01-12.sql @@ -0,0 +1,10 @@ +UPDATE "#__extensions" +SET "params" = REPLACE("params", '"com_categories",', '"com_categories","com_checkin",') +WHERE "name" = 'com_actionlogs'; + +SET IDENTITY_INSERT #__extensions ON; + +INSERT INTO "#__action_logs_extensions" ("extension") VALUES +('com_checkin'); + +SET IDENTITY_INSERT #__extensions OFF; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.3-2019-02-07.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.3-2019-02-07.sql new file mode 100644 index 0000000000000..1704cc72f4c4e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.3-2019-02-07.sql @@ -0,0 +1,2 @@ +INSERT INTO [#__postinstall_messages] ([extension_id], [title_key], [description_key], [action_key], [language_extension], [language_client_id], [type], [action_file], [action], [condition_file], [condition_method], [version_introduced], [enabled]) +SELECT 700, 'COM_CPANEL_MSG_ADDNOSNIFF_TITLE', 'COM_CPANEL_MSG_ADDNOSNIFF_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/addnosniff.php', 'admin_postinstall_addnosniff_condition', '3.9.3', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.4-2019-03-06.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.4-2019-03-06.sql new file mode 100644 index 0000000000000..c6a4f62a92d95 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.4-2019-03-06.sql @@ -0,0 +1,3 @@ +UPDATE "#__extensions" SET "element" = 'contact', "folder" = 'privacy' WHERE "name" = 'plg_privacy_contact'; +UPDATE "#__extensions" SET "element" = 'content', "folder" = 'privacy' WHERE "name" = 'plg_privacy_content'; +UPDATE "#__extensions" SET "element" = 'message', "folder" = 'privacy' WHERE "name" = 'plg_privacy_message'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.7-2019-04-23.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.7-2019-04-23.sql new file mode 100644 index 0000000000000..bcbd0ef4e0187 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.7-2019-04-23.sql @@ -0,0 +1,5 @@ +CREATE NONCLUSTERED INDEX [idx_client_id_guest] ON [#__session] +( + [client_id] ASC, + [guest] ASC +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.7-2019-04-26.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.7-2019-04-26.sql new file mode 100644 index 0000000000000..e76f02ae398bf --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.7-2019-04-26.sql @@ -0,0 +1 @@ +UPDATE [#__content_types] SET [content_history_options] = REPLACE([content_history_options], '\"ignoreChanges\":[\"modified_by\", \"modified\", \"checked_out\", \"checked_out_time\", \"version\", \"hits\"]', '\"ignoreChanges\":[\"modified_by\", \"modified\", \"checked_out\", \"checked_out_time\", \"version\", \"hits\", \"ordering\"]'); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.7-2019-05-16.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.7-2019-05-16.sql new file mode 100644 index 0000000000000..e03422239c89e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.7-2019-05-16.sql @@ -0,0 +1 @@ +# Query removed, see https://github.com/joomla/joomla-cms/pull/25177 diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.8-2019-06-11.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.8-2019-06-11.sql new file mode 100644 index 0000000000000..caefb45bd147d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.8-2019-06-11.sql @@ -0,0 +1 @@ +UPDATE [#__users] SET [params] = REPLACE([params], '",,"', '","'); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.9.8-2019-06-15.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.9.8-2019-06-15.sql new file mode 100644 index 0000000000000..67aef81054044 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.9.8-2019-06-15.sql @@ -0,0 +1,12 @@ +DROP INDEX [idx_home] ON [#__template_styles]; +# Query removed, see https://github.com/joomla/joomla-cms/pull/25484 +CREATE NONCLUSTERED INDEX [idx_client_id] ON [#__template_styles] +( + [client_id] ASC +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); +CREATE NONCLUSTERED INDEX [idx_client_id_home] ON [#__template_styles] +( + [client_id] ASC, + [home] ASC +)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); +ALTER TABLE [#__template_styles] ADD DEFAULT (0) FOR [home]; diff --git a/administrator/components/com_admin/views/help/tmpl/default.php b/administrator/components/com_admin/views/help/tmpl/default.php index 35b6122941db2..4dc5f63fc91df 100644 --- a/administrator/components/com_admin/views/help/tmpl/default.php +++ b/administrator/components/com_admin/views/help/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -21,7 +21,7 @@
  • latest_version_check, JText::_('COM_ADMIN_LATEST_VERSION_CHECK'), array('target' => 'helpFrame')); ?>
  • 'helpFrame')); ?>
  • 'helpFrame')); ?>
  • -
    +
  • toc as $k => $v) : ?>
  • @@ -33,7 +33,7 @@
    - +
    diff --git a/administrator/components/com_admin/views/help/tmpl/langforum.php b/administrator/components/com_admin/views/help/tmpl/langforum.php new file mode 100644 index 0000000000000..d69cf8fe755f5 --- /dev/null +++ b/administrator/components/com_admin/views/help/tmpl/langforum.php @@ -0,0 +1,23 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JFactory::getLanguage()->load('mod_menu', JPATH_ADMINISTRATOR, null, false, true); + +$forumId = (int) JText::_('MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM_VALUE'); + +if (empty($forumId)) +{ + $forumId = 511; +} + +$forum_url = 'https://forum.joomla.org/viewforum.php?f=' . $forumId; + +JFactory::getApplication()->redirect($forum_url); diff --git a/administrator/components/com_admin/views/help/view.html.php b/administrator/components/com_admin/views/help/view.html.php index f872b010e0ea4..a5bab31cca4f7 100644 --- a/administrator/components/com_admin/views/help/view.html.php +++ b/administrator/components/com_admin/views/help/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/views/profile/tmpl/edit.php b/administrator/components/com_admin/views/profile/tmpl/edit.php index bf342abc3c7b3..d312055eb50b3 100644 --- a/administrator/components/com_admin/views/profile/tmpl/edit.php +++ b/administrator/components/com_admin/views/profile/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -22,55 +22,88 @@ Joomla.submitform(task, document.getElementById("profile-form")); } }; + Joomla.twoFactorMethodChange = function(e) + { + var selectedPane = "com_admin_twofactor_" + jQuery("#jform_twofactor_method").val(); + + jQuery.each(jQuery("#com_admin_twofactor_forms_container>div"), function(i, el) + { + if (el.id != selectedPane) + { + jQuery("#" + el.id).hide(0); + } + else + { + jQuery("#" + el.id).show(0); + } + }); + } '); // Load chosen.css JHtml::_('formbehavior.chosen', 'select'); -// Get the form fieldsets. -$fieldsets = $this->form->getFieldsets(); +// Fieldsets to not automatically render by /layouts/joomla/edit/params.php +$this->ignore_fieldsets = array('user_details'); ?> 'account')); ?> - form->getFieldset('user_details') as $field) : ?> -
    -
    label; ?>
    -
    - fieldname == 'password2') : ?> - - - input; ?> -
    -
    + fieldname === 'password2') : ?> + + + + renderField(); ?> - - - name == 'user_details') - { - continue; - } - ?> - name, JText::_($fieldset->label)); ?> - form->getFieldset($fieldset->name) as $field) : ?> - hidden) : ?> -
    -
    input; ?>
    + twofactormethods) > 1) : ?> + +
    +
    +
    +
    - -
    -
    label; ?>
    -
    input; ?>
    +
    + twofactormethods, 'jform[twofactor][method]', array('onchange' => 'Joomla.twoFactorMethodChange()'), 'value', 'text', $this->otpConfig->method, 'jform_twofactor_method', false); ?> +
    +
    +
    + twofactorform as $form) : ?> + otpConfig->method ? 'display: block' : 'display: none'; ?> +
    + +
    + +
    +
    +
    + + + +
    + +
    + otpConfig->otep)) : ?> +
    +
    + + otpConfig->otep as $otep) : ?> + + --- + + +
    - +
    - - + + diff --git a/administrator/components/com_admin/views/profile/view.html.php b/administrator/components/com_admin/views/profile/view.html.php index fbe3e3747f3cd..f071951b91935 100644 --- a/administrator/components/com_admin/views/profile/view.html.php +++ b/administrator/components/com_admin/views/profile/view.html.php @@ -3,12 +3,14 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +JLoader::register('UsersHelper', JPATH_ADMINISTRATOR . '/components/com_users/helpers/users.php'); + /** * View class to allow users edit their own profile. * @@ -51,9 +53,15 @@ class AdminViewProfile extends JViewLegacy */ public function display($tpl = null) { - $this->form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + $this->twofactorform = $this->get('Twofactorform'); + $this->twofactormethods = UsersHelper::getTwoFactorMethods(); + $this->otpConfig = $this->get('OtpConfig'); + + // Load the language strings for the 2FA + JFactory::getLanguage()->load('com_users', JPATH_ADMINISTRATOR); // Check for errors. if (count($errors = $this->get('Errors'))) diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default.php b/administrator/components/com_admin/views/sysinfo/tmpl/default.php index 02589ee91b18e..26d951bafb332 100644 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default.php +++ b/administrator/components/com_admin/views/sysinfo/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_config.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_config.php index 4510e23390421..982719efb4752 100644 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_config.php +++ b/administrator/components/com_admin/views/sysinfo/tmpl/default_config.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_directory.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_directory.php index 07fe5a24437c8..723defcf3b16d 100644 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_directory.php +++ b/administrator/components/com_admin/views/sysinfo/tmpl/default_directory.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpinfo.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_phpinfo.php index 28909428f0ce8..16af021c1da8c 100644 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpinfo.php +++ b/administrator/components/com_admin/views/sysinfo/tmpl/default_phpinfo.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php index d17f2869a1ac0..04383677511fc 100644 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php +++ b/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -157,14 +157,6 @@ php_settings['iconv']); ?> - - - - - - php_settings['mcrypt']); ?> - - diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_system.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_system.php index 4e1f1ab2df9a4..ee8bacd643fbf 100644 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_system.php +++ b/administrator/components/com_admin/views/sysinfo/tmpl/default_system.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -36,6 +36,14 @@ info['php']; ?> + + + + + + info['dbserver']; ?> + + diff --git a/administrator/components/com_admin/views/sysinfo/view.html.php b/administrator/components/com_admin/views/sysinfo/view.html.php index b406ed27f8885..60a9cd7037860 100644 --- a/administrator/components/com_admin/views/sysinfo/view.html.php +++ b/administrator/components/com_admin/views/sysinfo/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -92,6 +92,7 @@ public function display($tpl = null) * * @since 1.6 * @note Necessary for Hathor compatibility + * @deprecated 4.0 To be removed with Hathor */ protected function _setSubMenu() { @@ -116,8 +117,14 @@ protected function _setSubMenu() protected function addToolbar() { JToolbarHelper::title(JText::_('COM_ADMIN_SYSTEM_INFORMATION'), 'info-2 systeminfo'); - JToolbarHelper::link(JRoute::_('index.php?option=com_admin&view=sysinfo&format=text'), 'COM_ADMIN_DOWNLOAD_SYSTEM_INFORMATION_TEXT', 'download'); - JToolbarHelper::link(JRoute::_('index.php?option=com_admin&view=sysinfo&format=json'), 'COM_ADMIN_DOWNLOAD_SYSTEM_INFORMATION_JSON', 'download'); + JToolbarHelper::link( + JRoute::_('index.php?option=com_admin&view=sysinfo&format=text&' . JSession::getFormToken() . '=1'), + 'COM_ADMIN_DOWNLOAD_SYSTEM_INFORMATION_TEXT', 'download' + ); + JToolbarHelper::link( + JRoute::_('index.php?option=com_admin&view=sysinfo&format=json&' . JSession::getFormToken() . '=1'), + 'COM_ADMIN_DOWNLOAD_SYSTEM_INFORMATION_JSON', 'download' + ); JToolbarHelper::help('JHELP_SITE_SYSTEM_INFORMATION'); } } diff --git a/administrator/components/com_admin/views/sysinfo/view.json.php b/administrator/components/com_admin/views/sysinfo/view.json.php index 4d7a9b7c08eed..604abe2de86b3 100644 --- a/administrator/components/com_admin/views/sysinfo/view.json.php +++ b/administrator/components/com_admin/views/sysinfo/view.json.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_admin/views/sysinfo/view.text.php b/administrator/components/com_admin/views/sysinfo/view.text.php index d90a045be1c35..435cd4996e426 100644 --- a/administrator/components/com_admin/views/sysinfo/view.text.php +++ b/administrator/components/com_admin/views/sysinfo/view.text.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_ajax/ajax.php b/administrator/components/com_ajax/ajax.php index 665c30efbadeb..40e35cd18f9d4 100644 --- a/administrator/components/com_ajax/ajax.php +++ b/administrator/components/com_ajax/ajax.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_ajax * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_ajax/ajax.xml b/administrator/components/com_ajax/ajax.xml index 4f75361049219..31493b599e47f 100644 --- a/administrator/components/com_ajax/ajax.xml +++ b/administrator/components/com_ajax/ajax.xml @@ -3,7 +3,7 @@ com_ajax Joomla! Project August 2013 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2013 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_associations/associations.php b/administrator/components/com_associations/associations.php index 2426f4960053c..43b884a56dfb8 100644 --- a/administrator/components/com_associations/associations.php +++ b/administrator/components/com_associations/associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_associations/associations.xml b/administrator/components/com_associations/associations.xml index 877f5c615526b..25af3b15ddc01 100644 --- a/administrator/components/com_associations/associations.xml +++ b/administrator/components/com_associations/associations.xml @@ -2,8 +2,8 @@ com_associations Joomla! Project - Januar 2017 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + January 2017 + (C) 2017 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_associations/controller.php b/administrator/components/com_associations/controller.php index d81bbcf51204f..497ad1d074d59 100644 --- a/administrator/components/com_associations/controller.php +++ b/administrator/components/com_associations/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_associations/controllers/association.php b/administrator/components/com_associations/controllers/association.php index 60d5234559b58..047d918efe9f7 100644 --- a/administrator/components/com_associations/controllers/association.php +++ b/administrator/components/com_associations/controllers/association.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -58,7 +58,7 @@ public function edit($key = null, $urlVar = null) */ public function cancel($key = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); list($extensionName, $typeName) = explode('.', $this->input->get('itemtype', '', 'string')); diff --git a/administrator/components/com_associations/controllers/associations.php b/administrator/components/com_associations/controllers/associations.php index 23cbb6d04908e..59608e69e8cbd 100644 --- a/administrator/components/com_associations/controllers/associations.php +++ b/administrator/components/com_associations/controllers/associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -34,7 +34,7 @@ class AssociationsControllerAssociations extends JControllerAdmin * @param string $prefix The class prefix. Optional. * @param array $config The array of possible config values. Optional. * - * @return JModel|bool + * @return JModel|boolean * * @since 3.7.0 */ @@ -52,6 +52,8 @@ public function getModel($name = 'Associations', $prefix = 'AssociationsModel', */ public function purge() { + $this->checkToken(); + $this->getModel('associations')->purge(); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); } @@ -65,6 +67,8 @@ public function purge() */ public function clean() { + $this->checkToken(); + $this->getModel('associations')->clean(); $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); } diff --git a/administrator/components/com_associations/helpers/associations.php b/administrator/components/com_associations/helpers/associations.php index 38b9193b8a2cf..0aa7605ba31c7 100644 --- a/administrator/components/com_associations/helpers/associations.php +++ b/administrator/components/com_associations/helpers/associations.php @@ -3,13 +3,14 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; +use Joomla\CMS\Language\LanguageHelper; /** * Associations component helper. @@ -111,7 +112,7 @@ public static function getItem($extensionName, $typeName, $itemId) * * @param string $extensionName The extension name with com_ * - * @return bool + * @return boolean * * @since 3.7.0 */ @@ -130,7 +131,7 @@ public static function hasSupport($extensionName) * * @param string $extensionName The extension name with com_ * - * @return bool + * @return boolean * * @since 3.7.0 */ @@ -177,7 +178,7 @@ public static function getAssociationHtmlList($extensionName, $typeName, $itemId $titleFieldName = self::getTypeFieldName($extensionName, $typeName, 'title'); // Get all content languages. - $languages = self::getContentLanguages(); + $languages = LanguageHelper::getContentLanguages(array(0, 1)); $canEditReference = self::allowEdit($extensionName, $typeName, $itemId); $canCreate = self::allowAdd($extensionName, $typeName); @@ -284,6 +285,7 @@ public static function getAssociationHtmlList($extensionName, $typeName, $itemId } JHtml::_('bootstrap.popover'); + return JLayoutHelper::render('joomla.content.associations', $items); } @@ -444,18 +446,7 @@ private static function getEnabledExtensions() */ public static function getContentLanguages() { - $db = JFactory::getDbo(); - - // Get all content languages. - $query = $db->getQuery(true) - ->select($db->quoteName(array('sef', 'lang_code', 'image', 'title', 'published'))) - ->from($db->quoteName('#__languages')) - ->where($db->quoteName('published') . ' != -2') - ->order($db->quoteName('ordering') . ' ASC'); - - $db->setQuery($query); - - return $db->loadObjectList('lang_code'); + return LanguageHelper::getContentLanguages(array(0, 1)); } /** @@ -465,7 +456,7 @@ public static function getContentLanguages() * @param string $typeName The item type * @param int $itemId The id of item for which we need the associated items * - * @return bool + * @return boolean * * @since 3.7.0 */ @@ -477,7 +468,7 @@ public static function allowEdit($extensionName, $typeName, $itemId) } // Get the extension specific helper method - $helper= self::getExtensionHelper($extensionName); + $helper = self::getExtensionHelper($extensionName); if (method_exists($helper, 'allowEdit')) { @@ -505,7 +496,7 @@ public static function allowAdd($extensionName, $typeName) } // Get the extension specific helper method - $helper= self::getExtensionHelper($extensionName); + $helper = self::getExtensionHelper($extensionName); if (method_exists($helper, 'allowAdd')) { @@ -645,7 +636,7 @@ public static function getTypeFieldName($extensionName, $typeName, $fieldName) /** * Gets the language filter system plugin extension id. * - * @return int The language filter system plugin extension id. + * @return integer The language filter system plugin extension id. * * @since 3.7.2 */ diff --git a/administrator/components/com_associations/layouts/joomla/searchtools/default/bar.php b/administrator/components/com_associations/layouts/joomla/searchtools/default/bar.php index 1f6761abd74ec..aa483329f2819 100644 --- a/administrator/components/com_associations/layouts/joomla/searchtools/default/bar.php +++ b/administrator/components/com_associations/layouts/joomla/searchtools/default/bar.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; $data = $displayData; diff --git a/administrator/components/com_associations/models/association.php b/administrator/components/com_associations/models/association.php index 10fdac9c8e4cc..fb7cf4bd4b215 100644 --- a/administrator/components/com_associations/models/association.php +++ b/administrator/components/com_associations/models/association.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_associations/models/associations.php b/administrator/components/com_associations/models/associations.php index 67114f93fbcf0..e4cb48a2ca492 100644 --- a/administrator/components/com_associations/models/associations.php +++ b/administrator/components/com_associations/models/associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -60,7 +60,7 @@ public function __construct($config = array()) * * @return void * - * @since 3.7.0 + * @since 3.7.0 */ protected function populateState($ordering = 'ordering', $direction = 'asc') { @@ -144,7 +144,7 @@ protected function getStoreId($id = '') /** * Build an SQL query to load the list data. * - * @return JDatabaseQuery|bool + * @return JDatabaseQuery|boolean * * @since 3.7.0 */ @@ -395,7 +395,8 @@ protected function getListQuery() { $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); $query->where('(' . $db->qn($fields['title']) . ' LIKE ' . $search - . ' OR ' . $db->qn($fields['alias']) . ' LIKE ' . $search . ')'); + . ' OR ' . $db->qn($fields['alias']) . ' LIKE ' . $search . ')' + ); } } diff --git a/administrator/components/com_associations/models/fields/itemlanguage.php b/administrator/components/com_associations/models/fields/itemlanguage.php index 459a91a7c2c6f..186e64993c926 100644 --- a/administrator/components/com_associations/models/fields/itemlanguage.php +++ b/administrator/components/com_associations/models/fields/itemlanguage.php @@ -3,13 +3,14 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Language\LanguageHelper; JLoader::register('AssociationsHelper', JPATH_ADMINISTRATOR . '/components/com_associations/helpers/associations.php'); JFormHelper::loadFieldClass('list'); @@ -57,7 +58,7 @@ protected function getOptions() $canCreate = AssociationsHelper::allowAdd($extensionName, $typeName); // Gets existing languages. - $existingLanguages = AssociationsHelper::getContentLanguages(); + $existingLanguages = LanguageHelper::getContentLanguages(array(0, 1)); $options = array(); @@ -79,7 +80,7 @@ protected function getOptions() $itemId = (int) $associations[$language->lang_code]['id']; $options[$langCode]->value = $language->lang_code . ':' . $itemId . ':edit'; - // Check if user does have permission to edit the associated item. + // Check if user does have permission to edit the associated item. $canEdit = AssociationsHelper::allowEdit($extensionName, $typeName, $itemId); // Check if item can be checked out diff --git a/administrator/components/com_associations/models/fields/itemtype.php b/administrator/components/com_associations/models/fields/itemtype.php index 6ec671a3ec042..c03a1c133e3e7 100644 --- a/administrator/components/com_associations/models/fields/itemtype.php +++ b/administrator/components/com_associations/models/fields/itemtype.php @@ -3,10 +3,10 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JLoader::register('AssociationsHelper', JPATH_ADMINISTRATOR . '/components/com_associations/helpers/associations.php'); JFormHelper::loadFieldClass('groupedlist'); @@ -26,7 +26,7 @@ class JFormFieldItemType extends JFormFieldGroupedList * @since 3.7.0 */ protected $type = 'ItemType'; - + /** * Method to get the field input markup. * diff --git a/administrator/components/com_associations/models/fields/modalassociation.php b/administrator/components/com_associations/models/fields/modalassociation.php index 5f2278dc70b5f..615b275c919d1 100644 --- a/administrator/components/com_associations/models/fields/modalassociation.php +++ b/administrator/components/com_associations/models/fields/modalassociation.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; /** * Supports a modal item picker. @@ -61,25 +61,26 @@ protected function getInput() $urlSelect = $linkAssociations . '&' . JSession::getFormToken() . '=1'; // Select custom association button - $html[] = '' + . ' data-target="#associationSelect' . $this->id . 'Modal">' . '' . '' - . ''; + . ''; // Clear association button $html[] = '' - . '' . JText::_('JCLEAR') - . ''; + . ' type="button"' + . ' class="btn' . ($value ? '' : ' hidden') . '"' + . ' onclick="return Joomla.submitbutton(\'undo-association\');"' + . ' id="remove-assoc">' + . '' . JText::_('JCLEAR') + . ''; $html[] = ''; @@ -95,8 +96,8 @@ protected function getInput() 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', + 'footer' => '', ) ); diff --git a/administrator/components/com_associations/models/forms/filter_associations.xml b/administrator/components/com_associations/models/forms/filter_associations.xml index 9563de4489650..11280a318744a 100644 --- a/administrator/components/com_associations/models/forms/filter_associations.xml +++ b/administrator/components/com_associations/models/forms/filter_associations.xml @@ -26,6 +26,7 @@ diff --git a/administrator/components/com_associations/views/association/tmpl/edit.php b/administrator/components/com_associations/views/association/tmpl/edit.php index d4e6b689a5c78..f7303015415eb 100644 --- a/administrator/components/com_associations/views/association/tmpl/edit.php +++ b/administrator/components/com_associations/views/association/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -32,12 +32,14 @@

    - @@ -50,12 +52,13 @@ form->getInput('modalassociation'); ?> form->getInput('itemlanguage'); ?>
    - diff --git a/administrator/components/com_associations/views/association/view.html.php b/administrator/components/com_associations/views/association/view.html.php index 00bdcb4467b72..d1776c5c19ab5 100644 --- a/administrator/components/com_associations/views/association/view.html.php +++ b/administrator/components/com_associations/views/association/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -109,7 +109,9 @@ public function display($tpl = null) $referenceId = $input->get('id', 0, 'int'); $reference = ArrayHelper::fromObject(AssociationsHelper::getItem($extensionName, $typeName, $referenceId)); - $this->referenceLanguage = $reference[$languageField]; + $this->referenceLanguage = $reference[$languageField]; + $this->referenceTitle = AssociationsHelper::getTypeFieldName($extensionName, $typeName, 'title'); + $this->referenceTitleValue = $reference[$this->referenceTitle]; $options = array( 'option' => $typeName === 'category' ? 'com_categories' : $extensionName, @@ -126,6 +128,7 @@ public function display($tpl = null) $this->targetLanguage = ''; $this->defaultTargetSrc = ''; $this->targetAction = ''; + $this->targetTitle = ''; if ($target = $input->get('target', '', 'string')) { @@ -133,38 +136,18 @@ public function display($tpl = null) $this->targetAction = $matches[2]; $this->targetId = $matches[1]; $this->targetLanguage = $matches[0]; + $this->targetTitle = AssociationsHelper::getTypeFieldName($extensionName, $typeName, 'title'); $task = $typeName . '.' . $this->targetAction; - $this->defaultTargetSrc = JRoute::_($this->editUri . '&task=' . $task . '&id=' . (int) $this->targetId); - $this->form->setValue('itemlanguage', '', $this->targetLanguage . ':' . $this->targetId . ':' . $this->targetAction); - } - - /* - * @todo Review later - */ - // We don't need toolbar in the modal window. - if ($this->getLayout() !== 'modal') - { - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); + /* Let's put the target src into a variable to use in the javascript code + * to avoid race conditions when the reference iframe loads. + */ + $document = JFactory::getDocument(); + $document->addScriptOptions('targetSrc', JRoute::_($this->editUri . '&task=' . $task . '&id=' . (int) $this->targetId)); + $this->form->setValue('itemlanguage', '', $this->targetLanguage . ':' . $this->targetId . ':' . $this->targetAction); } - else - { - // In article associations modal we need to remove language filter if forcing a language. - // We also need to change the category filter to show show categories with All or the forced language. - if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) - { - // If the language is forced we can't allow to select the language, so transform the language selector filter into an hidden field. - $languageXml = new SimpleXMLElement(''); - $this->filterForm->setField($languageXml, 'filter', true); - - // Also, unset the active language filter so the search tools is not open by default with this filter. - unset($this->activeFilters['language']); - // One last changes needed is to change the category filter to just show categories with All language or with the forced language. - $this->filterForm->setFieldAttribute('category_id', 'language', '*,' . $forcedLanguage, 'filter'); - } - } + $this->addToolbar(); parent::display($tpl); } diff --git a/administrator/components/com_associations/views/associations/tmpl/default.php b/administrator/components/com_associations/views/associations/tmpl/default.php index b00dd9f74f10c..729f6722de46f 100644 --- a/administrator/components/com_associations/views/associations/tmpl/default.php +++ b/administrator/components/com_associations/views/associations/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -120,33 +120,35 @@ - - id); ?> - level)) : ?> - $item->level)); ?> - - - editor, $item->checked_out_time, 'associations.'); ?> - - - editor, $item->checked_out_time, 'associations.', $canCheckin); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - typeFields['alias'])) : ?> - - escape($item->alias)); ?> - - - typeFields['catid'])) : ?> -
    - escape($item->category_title); ?> -
    - + +
    + id); ?> + level)) : ?> + $item->level)); ?> + + + editor, $item->checked_out_time, 'associations.'); ?> + + + editor, $item->checked_out_time, 'associations.', $canCheckin); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + typeFields['alias'])) : ?> + + escape($item->alias)); ?> + + + typeFields['catid'])) : ?> +
    + escape($item->category_title); ?> +
    + +
    diff --git a/administrator/components/com_associations/views/associations/tmpl/default.xml b/administrator/components/com_associations/views/associations/tmpl/default.xml new file mode 100644 index 0000000000000..d2dc27b12bdf2 --- /dev/null +++ b/administrator/components/com_associations/views/associations/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/administrator/components/com_associations/views/associations/tmpl/modal.php b/administrator/components/com_associations/views/associations/tmpl/modal.php index f4315e6e38c24..22e6a579d8691 100644 --- a/administrator/components/com_associations/views/associations/tmpl/modal.php +++ b/administrator/components/com_associations/views/associations/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -46,8 +46,8 @@ });" ); ?> - + sidebar)) : ?>
    diff --git a/administrator/components/com_associations/views/associations/view.html.php b/administrator/components/com_associations/views/associations/view.html.php index ce481471ab11a..f4d3dd045b545 100644 --- a/administrator/components/com_associations/views/associations/view.html.php +++ b/administrator/components/com_associations/views/associations/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_associations * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -129,21 +129,25 @@ public function display($tpl = null) unset($this->activeFilters['state']); $this->filterForm->removeField('state', 'filter'); } + if (empty($support['category'])) { unset($this->activeFilters['category_id']); $this->filterForm->removeField('category_id', 'filter'); } + if ($extensionName !== 'com_menus') { unset($this->activeFilters['menutype']); $this->filterForm->removeField('menutype', 'filter'); } + if (empty($support['level'])) { unset($this->activeFilters['level']); $this->filterForm->removeField('level', 'filter'); } + if (empty($support['acl'])) { unset($this->activeFilters['access']); @@ -154,6 +158,15 @@ public function display($tpl = null) if (empty($support['catid'])) { $this->filterForm->setFieldAttribute('category_id', 'extension', $extensionName, 'filter'); + + if ($this->getLayout() == 'modal') + { + // We need to change the category filter to only show categories tagged to All or to the forced language. + if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) + { + $this->filterForm->setFieldAttribute('category_id', 'language', '*,' . $forcedLanguage, 'filter'); + } + } } $this->items = $this->get('Items'); @@ -222,6 +235,7 @@ protected function addToolbar() JToolbarHelper::custom('associations.purge', 'purge', 'purge', 'COM_ASSOCIATIONS_PURGE', false, false); JToolbarHelper::custom('associations.clean', 'refresh', 'refresh', 'COM_ASSOCIATIONS_DELETE_ORPHANS', false, false); } + JToolbarHelper::preferences('com_associations'); } diff --git a/administrator/components/com_banners/banners.php b/administrator/components/com_banners/banners.php index f1afc76b48e61..2d66b81b46176 100644 --- a/administrator/components/com_banners/banners.php +++ b/administrator/components/com_banners/banners.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/banners.xml b/administrator/components/com_banners/banners.xml index 13ebc6bea19a9..a8c70c9513849 100644 --- a/administrator/components/com_banners/banners.xml +++ b/administrator/components/com_banners/banners.xml @@ -3,7 +3,7 @@ com_banners Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_banners/config.xml b/administrator/components/com_banners/config.xml index 74e81cb77c9ee..76d5a2d39bf3c 100644 --- a/administrator/components/com_banners/config.xml +++ b/administrator/components/com_banners/config.xml @@ -33,6 +33,18 @@ + + + + + * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/controllers/banner.php b/administrator/components/com_banners/controllers/banner.php index 170c03d201f37..3b6e249867c18 100644 --- a/administrator/components/com_banners/controllers/banner.php +++ b/administrator/components/com_banners/controllers/banner.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -97,7 +97,7 @@ protected function allowEdit($data = array(), $key = 'id') */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Set the model $model = $this->getModel('Banner', '', array()); diff --git a/administrator/components/com_banners/controllers/banners.php b/administrator/components/com_banners/controllers/banners.php index 59c3d33e38de0..3314a9f9af04a 100644 --- a/administrator/components/com_banners/controllers/banners.php +++ b/administrator/components/com_banners/controllers/banners.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -67,7 +67,7 @@ public function getModel($name = 'Banner', $prefix = 'BannersModel', $config = a public function sticky_publish() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $ids = $this->input->get('cid', array(), 'array'); $values = array('sticky_publish' => 1, 'sticky_unpublish' => 0); diff --git a/administrator/components/com_banners/controllers/client.php b/administrator/components/com_banners/controllers/client.php index 3e5272e9b2d30..586285bc331ef 100644 --- a/administrator/components/com_banners/controllers/client.php +++ b/administrator/components/com_banners/controllers/client.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/controllers/clients.php b/administrator/components/com_banners/controllers/clients.php index 9cae8d477439e..1c8fc4cc33a6c 100644 --- a/administrator/components/com_banners/controllers/clients.php +++ b/administrator/components/com_banners/controllers/clients.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/controllers/tracks.php b/administrator/components/com_banners/controllers/tracks.php index d6fb9bc7b15cd..b8297c6c253a8 100644 --- a/administrator/components/com_banners/controllers/tracks.php +++ b/administrator/components/com_banners/controllers/tracks.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -50,7 +50,7 @@ public function getModel($name = 'Tracks', $prefix = 'BannersModel', $config = a public function delete() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Get the model. /** @var BannersModelTracks $model */ diff --git a/administrator/components/com_banners/controllers/tracks.raw.php b/administrator/components/com_banners/controllers/tracks.raw.php index ebf4970d56bf2..5bfc863306954 100644 --- a/administrator/components/com_banners/controllers/tracks.raw.php +++ b/administrator/components/com_banners/controllers/tracks.raw.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -53,6 +53,9 @@ public function getModel($name = 'Tracks', $prefix = 'BannersModel', $config = a */ public function display($cachable = false, $urlparams = array()) { + // Check for request forgeries. + $this->checkToken('GET'); + // Get the document object. $vName = 'tracks'; diff --git a/administrator/components/com_banners/helpers/banners.php b/administrator/components/com_banners/helpers/banners.php index b73dcfa3c50ff..f52ebb8ff288c 100644 --- a/administrator/components/com_banners/helpers/banners.php +++ b/administrator/components/com_banners/helpers/banners.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -188,7 +188,7 @@ public static function getClientOptions() /** * Adds Count Items for Category Manager. * - * @param stdClass[] &$items The banner category objects + * @param stdClass[] &$items The category objects * * @return stdClass[] * @@ -196,104 +196,13 @@ public static function getClientOptions() */ public static function countItems(&$items) { - $db = JFactory::getDbo(); - - foreach ($items as $item) - { - $item->count_trashed = 0; - $item->count_archived = 0; - $item->count_unpublished = 0; - $item->count_published = 0; - $query = $db->getQuery(true); - $query->select('state, count(*) AS count') - ->from($db->qn('#__banners')) - ->where('catid = ' . (int) $item->id) - ->group('state'); - $db->setQuery($query); - $banners = $db->loadObjectList(); - - foreach ($banners as $banner) - { - if ($banner->state == 1) - { - $item->count_published = $banner->count; - } - - if ($banner->state == 0) - { - $item->count_unpublished = $banner->count; - } - - if ($banner->state == 2) - { - $item->count_archived = $banner->count; - } - - if ($banner->state == -2) - { - $item->count_trashed = $banner->count; - } - } - } - - return $items; - } - - /** - * Adds Count Items for Tag Manager. - * - * @param stdClass[] &$items The banner tag objects - * @param string $extension The name of the active view. - * - * @return stdClass[] - * - * @since 3.6 - */ - public static function countTagItems(&$items, $extension) - { - $db = JFactory::getDbo(); - - foreach ($items as $item) - { - $item->count_trashed = 0; - $item->count_archived = 0; - $item->count_unpublished = 0; - $item->count_published = 0; - $query = $db->getQuery(true); - $query->select('published as state, count(*) AS count') - ->from($db->qn('#__contentitem_tag_map') . 'AS ct ') - ->where('ct.tag_id = ' . (int) $item->id) - ->where('ct.type_alias =' . $db->q($extension)) - ->join('LEFT', $db->qn('#__categories') . ' AS c ON ct.content_item_id=c.id') - ->group('state'); - - $db->setQuery($query); - $banners = $db->loadObjectList(); - - foreach ($banners as $banner) - { - if ($banner->state == 1) - { - $item->count_published = $banner->count; - } - - if ($banner->state == 0) - { - $item->count_unpublished = $banner->count; - } - - if ($banner->state == 2) - { - $item->count_archived = $banner->count; - } - - if ($banner->state == -2) - { - $item->count_trashed = $banner->count; - } - } - } + $config = (object) array( + 'related_tbl' => 'banners', + 'state_col' => 'state', + 'group_col' => 'catid', + 'relation_type' => 'category_or_group', + ); - return $items; + return parent::countRelations($items, $config); } } diff --git a/administrator/components/com_banners/helpers/html/banner.php b/administrator/components/com_banners/helpers/html/banner.php index fe5b52cf9cfba..8e9d14283396a 100644 --- a/administrator/components/com_banners/helpers/html/banner.php +++ b/administrator/components/com_banners/helpers/html/banner.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; /** * Banner HTML class. diff --git a/administrator/components/com_banners/models/banner.php b/administrator/components/com_banners/models/banner.php index 37a07e9d101d7..e91c39b62d0a6 100644 --- a/administrator/components/com_banners/models/banner.php +++ b/administrator/components/com_banners/models/banner.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -96,155 +96,46 @@ protected function batchClient($value, $pks, $contexts) } /** - * Batch copy items to a new category or current. + * Method to test whether a record can be deleted. * - * @param integer $value The new category. - * @param array $pks An array of row IDs. - * @param array $contexts An array of item contexts. + * @param object $record A record object. * - * @return mixed An array of new IDs on success, boolean false on failure. + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. * - * @since 2.5 + * @since 1.6 */ - protected function batchCopy($value, $pks, $contexts) + protected function canDelete($record) { - $categoryId = (int) $value; - - /** @var BannersTableBanner $table */ - $table = $this->getTable(); - $newIds = array(); - - // Check that the category exists - if ($categoryId) + if (empty($record->id) || $record->state != -2) { - $categoryTable = JTable::getInstance('Category'); - - if (!$categoryTable->load($categoryId)) - { - if ($error = $categoryTable->getError()) - { - // Fatal error - $this->setError($error); - - return false; - } - - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); - - return false; - } - } - - if (empty($categoryId)) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); - return false; } - // Check that the user has create permission for the component - if (!JFactory::getUser()->authorise('core.create', 'com_banners.category.' . $categoryId)) + if (!empty($record->catid)) { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); - - return false; + return JFactory::getUser()->authorise('core.delete', 'com_banners.category.' . (int) $record->catid); } - // Parent exists so we let's proceed - while (!empty($pks)) - { - // Pop the first ID off the stack - $pk = array_shift($pks); - - $table->reset(); - - // Check that the row actually exists - if (!$table->load($pk)) - { - if ($error = $table->getError()) - { - // Fatal error - $this->setError($error); - - return false; - } - - // Not fatal error - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); - continue; - } - - // Alter the title & alias - $data = $this->generateNewTitle($categoryId, $table->alias, $table->name); - $table->name = $data['0']; - $table->alias = $data['1']; - - // Reset the ID because we are making a copy - $table->id = 0; - - // New category ID - $table->catid = $categoryId; - - // Unpublish because we are making a copy - $table->state = 0; - - // TODO: Deal with ordering? - // $table->ordering = 1; - - // Check the row. - if (!$table->check()) - { - $this->setError($table->getError()); - - return false; - } - - // Store the row. - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - - // Get the new item ID - $newId = $table->get('id'); - - // Add the new ID to the array - $newIds[$pk] = $newId; - } - - // Clean the cache - $this->cleanCache(); - - return $newIds; + return parent::canDelete($record); } /** - * Method to test whether a record can be deleted. + * A method to preprocess generating a new title in order to allow tables with alternative names + * for alias and title to use the batch move and copy methods * - * @param object $record A record object. + * @param integer $categoryId The target category id + * @param JTable $table The JTable within which move or copy is taking place * - * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * @return void * - * @since 1.6 + * @since 3.8.12 */ - protected function canDelete($record) + public function generateTitle($categoryId, $table) { - if (!empty($record->id)) - { - if ($record->state != -2) - { - return false; - } - - if (!empty($record->catid)) - { - return JFactory::getUser()->authorise('core.delete', 'com_banners.category.' . (int) $record->catid); - } - - return parent::canDelete($record); - } + // Alter the title & alias + $data = $this->generateNewTitle($categoryId, $table->alias, $table->name); + $table->name = $data['0']; + $table->alias = $data['1']; } /** @@ -373,7 +264,7 @@ protected function loadFormData() /** * Method to stick records. * - * @param array &$pks The ids of the items to publish. + * @param array $pks The ids of the items to publish. * @param integer $value The value of the published state * * @return boolean True on success. @@ -489,6 +380,9 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') if ($this->canCreateCategory()) { $form->setFieldAttribute('catid', 'allowAdd', 'true'); + + // Add a prefix for categories created on the fly. + $form->setFieldAttribute('catid', 'customPrefix', '#new#'); } parent::preprocessForm($form, $data, $group); @@ -509,20 +403,22 @@ public function save($data) JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - // Cast catid to integer for comparison - $catid = (int) $data['catid']; + // Create new category, if needed. + $createCategory = true; - // Check if New Category exists - if ($catid > 0) + // If category ID is provided, check if it's valid. + if (is_numeric($data['catid']) && $data['catid']) { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_banners'); + $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_banners'); } // Save New Category - if ($catid == 0 && $this->canCreateCategory()) + if ($createCategory && $this->canCreateCategory()) { $table = array(); - $table['title'] = $data['catid']; + + // Remove #new# prefix, if exists. + $table['title'] = strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid']; $table['parent_id'] = 1; $table['extension'] = 'com_banners'; $table['language'] = $data['language']; @@ -562,7 +458,7 @@ public function save($data) /** * Is the user allowed to create an on the fly category? * - * @return bool + * @return boolean * * @since 3.6.1 */ @@ -570,4 +466,31 @@ private function canCreateCategory() { return JFactory::getUser()->authorise('core.create', 'com_banners'); } + + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.25 + */ + public function validate($form, $data, $group = null) + { + // Don't allow to change the users if not allowed to access com_users. + if (!JFactory::getUser()->authorise('core.manage', 'com_users')) + { + if (isset($data['created_by'])) + { + unset($data['created_by']); + } + } + + return parent::validate($form, $data, $group); + } } diff --git a/administrator/components/com_banners/models/banners.php b/administrator/components/com_banners/models/banners.php index e2e9495da0b26..5ddf9fc9bb7d2 100644 --- a/administrator/components/com_banners/models/banners.php +++ b/administrator/components/com_banners/models/banners.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/models/client.php b/administrator/components/com_banners/models/client.php index 9d14c0d348479..630f6e13a743b 100644 --- a/administrator/components/com_banners/models/client.php +++ b/administrator/components/com_banners/models/client.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -35,22 +35,17 @@ class BannersModelClient extends JModelAdmin */ protected function canDelete($record) { - if (!empty($record->id)) + if (empty($record->id) || $record->state != -2) { - if ($record->state != -2) - { - return false; - } - - $user = JFactory::getUser(); - - if (!empty($record->catid)) - { - return $user->authorise('core.delete', 'com_banners.category.' . (int) $record->catid); - } + return false; + } - return $user->authorise('core.delete', 'com_banners'); + if (!empty($record->catid)) + { + return JFactory::getUser()->authorise('core.delete', 'com_banners.category.' . (int) $record->catid); } + + return parent::canDelete($record); } /** diff --git a/administrator/components/com_banners/models/clients.php b/administrator/components/com_banners/models/clients.php index 380c72b34dbb9..b8e848c3c7860 100644 --- a/administrator/components/com_banners/models/clients.php +++ b/administrator/components/com_banners/models/clients.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -201,7 +201,7 @@ public function getItems() // Load the list items. $items = parent::getItems(); - // If emtpy or an error, just return. + // If empty or an error, just return. if (empty($items)) { return array(); diff --git a/administrator/components/com_banners/models/download.php b/administrator/components/com_banners/models/download.php index c01de0b0e29f7..6d86ba7a233a0 100644 --- a/administrator/components/com_banners/models/download.php +++ b/administrator/components/com_banners/models/download.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -72,7 +72,7 @@ public function getForm($data = array(), $loadData = true) */ protected function loadFormData() { - $data = array( + $data = (object) array( 'basename' => $this->getState('basename'), 'compressed' => $this->getState('compressed'), ); diff --git a/administrator/components/com_banners/models/fields/bannerclient.php b/administrator/components/com_banners/models/fields/bannerclient.php index b7e2c46fc2c90..5893cd909bf8d 100644 --- a/administrator/components/com_banners/models/fields/bannerclient.php +++ b/administrator/components/com_banners/models/fields/bannerclient.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JLoader::register('BannersHelper', JPATH_ADMINISTRATOR . '/components/com_banners/helpers/banners.php'); diff --git a/administrator/components/com_banners/models/fields/clicks.php b/administrator/components/com_banners/models/fields/clicks.php index d3d9166eba712..a7f08abbfad6e 100644 --- a/administrator/components/com_banners/models/fields/clicks.php +++ b/administrator/components/com_banners/models/fields/clicks.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; /** * Clicks field. diff --git a/administrator/components/com_banners/models/fields/impmade.php b/administrator/components/com_banners/models/fields/impmade.php index da6e26889ce30..21beb2bffd802 100644 --- a/administrator/components/com_banners/models/fields/impmade.php +++ b/administrator/components/com_banners/models/fields/impmade.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; /** * Impressions field. diff --git a/administrator/components/com_banners/models/fields/imptotal.php b/administrator/components/com_banners/models/fields/imptotal.php index ec5afcdc2067a..4dea19573bb84 100644 --- a/administrator/components/com_banners/models/fields/imptotal.php +++ b/administrator/components/com_banners/models/fields/imptotal.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; /** * Total Impressions field. diff --git a/administrator/components/com_banners/models/forms/banner.xml b/administrator/components/com_banners/models/forms/banner.xml index 0276b64f55858..4734a899b3d8c 100644 --- a/administrator/components/com_banners/models/forms/banner.xml +++ b/administrator/components/com_banners/models/forms/banner.xml @@ -4,7 +4,7 @@
  • @@ -342,7 +343,7 @@ diff --git a/administrator/components/com_banners/models/forms/filter_clients.xml b/administrator/components/com_banners/models/forms/filter_clients.xml index 1552335b63704..587d9ae7564a8 100644 --- a/administrator/components/com_banners/models/forms/filter_clients.xml +++ b/administrator/components/com_banners/models/forms/filter_clients.xml @@ -4,6 +4,7 @@ diff --git a/administrator/components/com_banners/models/forms/filter_tracks.xml b/administrator/components/com_banners/models/forms/filter_tracks.xml index 449c4e574b1f7..f50c700cd49d7 100644 --- a/administrator/components/com_banners/models/forms/filter_tracks.xml +++ b/administrator/components/com_banners/models/forms/filter_tracks.xml @@ -4,6 +4,7 @@
    @@ -87,6 +86,7 @@ description="JGLOBAL_SORT_BY" onchange="this.form.submit();" default="b.name ASC" + validate="options" > diff --git a/administrator/components/com_banners/models/tracks.php b/administrator/components/com_banners/models/tracks.php index e7af9c2c18bc3..60715a51a8bf8 100644 --- a/administrator/components/com_banners/models/tracks.php +++ b/administrator/components/com_banners/models/tracks.php @@ -3,12 +3,15 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\Archive\Archive; +use Joomla\String\StringHelper; + JLoader::register('BannersHelper', JPATH_ADMINISTRATOR . '/components/com_banners/helpers/banners.php'); /** @@ -165,7 +168,7 @@ protected function getListQuery() if (!empty($search)) { - $search = $db->quote('%' . strtolower($search) . '%'); + $search = $db->quote('%' . StringHelper::strtolower($search) . '%'); $query->where('(LOWER(b.name) LIKE ' . $search . ' OR LOWER(cl.name) LIKE ' . $search . ')'); } @@ -226,7 +229,7 @@ public function delete() $query->where('track_date <= ' . $db->quote($end)); } - $where = '1'; + $where = '1 = 1'; // Filter by client $clientId = $this->getState('filter.client_id'); @@ -399,9 +402,9 @@ protected function getCategoryName() } /** - * Get the category name + * Get the client name * - * @return string The category name. + * @return string The client name. * * @since 1.6 */ @@ -516,7 +519,9 @@ public function getContent() } } - if (!$packager = JArchive::getAdapter('zip')) + $archive = new Archive; + + if (!$packager = $archive->getAdapter('zip')) { $this->setError(JText::_('COM_BANNERS_ERR_ZIP_ADAPTER_FAILURE')); diff --git a/administrator/components/com_banners/sql/install.mysql.utf8.sql b/administrator/components/com_banners/sql/install.mysql.utf8.sql index b74a76ddd798d..48f4ad2014fea 100644 --- a/administrator/components/com_banners/sql/install.mysql.utf8.sql +++ b/administrator/components/com_banners/sql/install.mysql.utf8.sql @@ -3,40 +3,40 @@ -- CREATE TABLE IF NOT EXISTS `#__banners` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `cid` int(11) NOT NULL DEFAULT 0, - `type` int(11) NOT NULL DEFAULT 0, + `id` int NOT NULL AUTO_INCREMENT, + `cid` int NOT NULL DEFAULT 0, + `type` int NOT NULL DEFAULT 0, `name` varchar(255) NOT NULL DEFAULT '', `alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '', - `imptotal` int(11) NOT NULL DEFAULT 0, - `impmade` int(11) NOT NULL DEFAULT 0, - `clicks` int(11) NOT NULL DEFAULT 0, + `imptotal` int NOT NULL DEFAULT 0, + `impmade` int NOT NULL DEFAULT 0, + `clicks` int NOT NULL DEFAULT 0, `clickurl` varchar(200) NOT NULL DEFAULT '', - `state` tinyint(3) NOT NULL DEFAULT 0, - `catid` int(10) unsigned NOT NULL DEFAULT 0, + `state` tinyint NOT NULL DEFAULT 0, + `catid` int unsigned NOT NULL DEFAULT 0, `description` text NOT NULL, `custombannercode` varchar(2048) NOT NULL, - `sticky` tinyint(1) unsigned NOT NULL DEFAULT 0, - `ordering` int(11) NOT NULL DEFAULT 0, + `sticky` tinyint unsigned NOT NULL DEFAULT 0, + `ordering` int NOT NULL DEFAULT 0, `metakey` text NOT NULL, `params` text NOT NULL, - `own_prefix` tinyint(1) NOT NULL DEFAULT 0, + `own_prefix` tinyint NOT NULL DEFAULT 0, `metakey_prefix` varchar(400) NOT NULL DEFAULT '', - `purchase_type` tinyint(4) NOT NULL DEFAULT -1, - `track_clicks` tinyint(4) NOT NULL DEFAULT -1, - `track_impressions` tinyint(4) NOT NULL DEFAULT -1, - `checked_out` int(10) unsigned NOT NULL DEFAULT 0, + `purchase_type` tinyint NOT NULL DEFAULT -1, + `track_clicks` tinyint NOT NULL DEFAULT -1, + `track_impressions` tinyint NOT NULL DEFAULT -1, + `checked_out` int unsigned NOT NULL DEFAULT 0, `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `publish_up` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `publish_down` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `reset` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `language` char(7) NOT NULL DEFAULT '', - `created_by` int(10) unsigned NOT NULL DEFAULT 0, + `created_by` int unsigned NOT NULL DEFAULT 0, `created_by_alias` varchar(255) NOT NULL DEFAULT '', `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `modified_by` int(10) unsigned NOT NULL DEFAULT 0, - `version` int(10) unsigned NOT NULL DEFAULT 1, + `modified_by` int unsigned NOT NULL DEFAULT 0, + `version` int unsigned NOT NULL DEFAULT 1, PRIMARY KEY (`id`), KEY `idx_state` (`state`), KEY `idx_own_prefix` (`own_prefix`), @@ -50,20 +50,20 @@ CREATE TABLE IF NOT EXISTS `#__banners` ( -- CREATE TABLE IF NOT EXISTS `#__banner_clients` ( - `id` int(11) NOT NULL AUTO_INCREMENT, + `id` int NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL DEFAULT '', `contact` varchar(255) NOT NULL DEFAULT '', `email` varchar(255) NOT NULL DEFAULT '', `extrainfo` text NOT NULL, - `state` tinyint(3) NOT NULL DEFAULT 0, - `checked_out` int(10) unsigned NOT NULL DEFAULT 0, + `state` tinyint NOT NULL DEFAULT 0, + `checked_out` int unsigned NOT NULL DEFAULT 0, `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `metakey` text NOT NULL, - `own_prefix` tinyint(4) NOT NULL DEFAULT 0, + `own_prefix` tinyint NOT NULL DEFAULT 0, `metakey_prefix` varchar(400) NOT NULL DEFAULT '', - `purchase_type` tinyint(4) NOT NULL DEFAULT -1, - `track_clicks` tinyint(4) NOT NULL DEFAULT -1, - `track_impressions` tinyint(4) NOT NULL DEFAULT -1, + `purchase_type` tinyint NOT NULL DEFAULT -1, + `track_clicks` tinyint NOT NULL DEFAULT -1, + `track_impressions` tinyint NOT NULL DEFAULT -1, PRIMARY KEY (`id`), KEY `idx_own_prefix` (`own_prefix`), KEY `idx_metakey_prefix` (`metakey_prefix`(100)) @@ -75,9 +75,9 @@ CREATE TABLE IF NOT EXISTS `#__banner_clients` ( CREATE TABLE IF NOT EXISTS `#__banner_tracks` ( `track_date` datetime NOT NULL, - `track_type` int(10) unsigned NOT NULL, - `banner_id` int(10) unsigned NOT NULL, - `count` int(10) unsigned NOT NULL DEFAULT 0, + `track_type` int unsigned NOT NULL, + `banner_id` int unsigned NOT NULL, + `count` int unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`track_date`,`track_type`,`banner_id`), KEY `idx_track_date` (`track_date`), KEY `idx_track_type` (`track_type`), diff --git a/administrator/components/com_banners/tables/banner.php b/administrator/components/com_banners/tables/banner.php index 3bc75e59e20b8..7fc4dea66d951 100644 --- a/administrator/components/com_banners/tables/banner.php +++ b/administrator/components/com_banners/tables/banner.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -22,7 +22,7 @@ class BannersTableBanner extends JTable /** * Constructor * - * @param JDatabaseDriver &$db Database connector object + * @param JDatabaseDriver $db Database connector object * * @since 1.5 */ @@ -150,8 +150,8 @@ public function bind($array, $ignore = array()) $height = abs((int) $registry->get('height', 0)); // Sets the width and height to an empty string if = 0 - $registry->set('width', ($width ? $width : '')); - $registry->set('height', ($height ? $height : '')); + $registry->set('width', $width ?: ''); + $registry->set('height', $height ?: ''); $array['params'] = (string) $registry; } @@ -173,6 +173,8 @@ public function bind($array, $ignore = array()) */ public function store($updateNulls = false) { + $db = $this->getDbo(); + if (empty($this->id)) { $purchaseType = $this->purchase_type; @@ -180,7 +182,7 @@ public function store($updateNulls = false) if ($purchaseType < 0 && $this->cid) { /** @var BannersTableClient $client */ - $client = JTable::getInstance('Client', 'BannersTable'); + $client = JTable::getInstance('Client', 'BannersTable', array('dbo' => $db)); $client->load($this->cid); $purchaseType = $client->purchase_type; } @@ -220,7 +222,7 @@ public function store($updateNulls = false) { // Get the old row /** @var BannersTableBanner $oldrow */ - $oldrow = JTable::getInstance('Banner', 'BannersTable'); + $oldrow = JTable::getInstance('Banner', 'BannersTable', array('dbo' => $db)); if (!$oldrow->load($this->id) && $oldrow->getError()) { @@ -229,7 +231,7 @@ public function store($updateNulls = false) // Verify that the alias is unique /** @var BannersTableBanner $table */ - $table = JTable::getInstance('Banner', 'BannersTable'); + $table = JTable::getInstance('Banner', 'BannersTable', array('dbo' => $db)); if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) { diff --git a/administrator/components/com_banners/tables/client.php b/administrator/components/com_banners/tables/client.php index fea12f8715da8..1cc08cc0bf404 100644 --- a/administrator/components/com_banners/tables/client.php +++ b/administrator/components/com_banners/tables/client.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -21,7 +21,7 @@ class BannersTableClient extends JTable /** * Constructor * - * @param JDatabaseDriver &$db Database connector object + * @param JDatabaseDriver $db Database connector object * * @since 1.5 */ @@ -30,6 +30,8 @@ public function __construct(&$db) $this->checked_out_time = $db->getNullDate(); parent::__construct('#__banner_clients', 'id', $db); + $this->setColumnAlias('published', 'state'); + JTableObserverContenthistory::createObserver($this, array('typeAlias' => 'com_banners.client')); } diff --git a/administrator/components/com_banners/views/banner/tmpl/edit.php b/administrator/components/com_banners/views/banner/tmpl/edit.php index dc07733319e0f..cb06826ef2188 100644 --- a/administrator/components/com_banners/views/banner/tmpl/edit.php +++ b/administrator/components/com_banners/views/banner/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/views/banner/view.html.php b/administrator/components/com_banners/views/banner/view.html.php index 56d98cf202f4c..f6a3f5dedde04 100644 --- a/administrator/components/com_banners/views/banner/view.html.php +++ b/administrator/components/com_banners/views/banner/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -48,7 +48,7 @@ class BannersViewBanner extends JViewLegacy */ public function display($tpl = null) { - // Initialiase variables. + // Initialize variables. $this->form = $this->get('Form'); $this->item = $this->get('Item'); $this->state = $this->get('State'); diff --git a/administrator/components/com_banners/views/banners/tmpl/default.php b/administrator/components/com_banners/views/banners/tmpl/default.php index eb41195812754..57a01df5a72ae 100644 --- a/administrator/components/com_banners/views/banners/tmpl/default.php +++ b/administrator/components/com_banners/views/banners/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -130,8 +130,8 @@ ?> - -
    + +
    checked_out) : ?> editor, $item->checked_out_time, 'banners.', $canCheckin); ?> @@ -141,7 +141,7 @@ escape($item->name); ?> - + escape($item->alias)); ?>
    @@ -156,7 +156,7 @@ client_name; ?> - impmade, $item->imptotal ? $item->imptotal : JText::_('COM_BANNERS_UNLIMITED')); ?> + impmade, $item->imptotal ?: JText::_('COM_BANNERS_UNLIMITED')); ?> clicks; ?> - diff --git a/administrator/components/com_banners/views/banners/tmpl/default_batch_body.php b/administrator/components/com_banners/views/banners/tmpl/default_batch_body.php index 128cc76b9834d..e04d44b63f9c3 100644 --- a/administrator/components/com_banners/views/banners/tmpl/default_batch_body.php +++ b/administrator/components/com_banners/views/banners/tmpl/default_batch_body.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/views/banners/tmpl/default_batch_footer.php b/administrator/components/com_banners/views/banners/tmpl/default_batch_footer.php index df299bbf7ba60..0931fd103d230 100644 --- a/administrator/components/com_banners/views/banners/tmpl/default_batch_footer.php +++ b/administrator/components/com_banners/views/banners/tmpl/default_batch_footer.php @@ -3,15 +3,15 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - + + diff --git a/administrator/components/com_banners/views/banners/view.html.php b/administrator/components/com_banners/views/banners/view.html.php index 90db42f7bbc9c..204a17a235478 100644 --- a/administrator/components/com_banners/views/banners/view.html.php +++ b/administrator/components/com_banners/views/banners/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -101,7 +101,7 @@ protected function addToolbar() JToolbarHelper::addNew('banner.add'); } - if (($canDo->get('core.edit'))) + if ($canDo->get('core.edit')) { JToolbarHelper::editList('banner.edit'); } diff --git a/administrator/components/com_banners/views/client/tmpl/edit.php b/administrator/components/com_banners/views/client/tmpl/edit.php index e2e84a0cef1bf..8a70642dae955 100644 --- a/administrator/components/com_banners/views/client/tmpl/edit.php +++ b/administrator/components/com_banners/views/client/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/views/client/view.html.php b/administrator/components/com_banners/views/client/view.html.php index f4f0005104af4..4bbd28767a9cc 100644 --- a/administrator/components/com_banners/views/client/view.html.php +++ b/administrator/components/com_banners/views/client/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/views/clients/tmpl/default.php b/administrator/components/com_banners/views/clients/tmpl/default.php index ef63cdba1779f..9c43bce819d79 100644 --- a/administrator/components/com_banners/views/clients/tmpl/default.php +++ b/administrator/components/com_banners/views/clients/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -27,7 +27,7 @@ $userId = $user->get('id'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); -$params = (isset($this->state->params)) ? $this->state->params : new JObject; +$params = isset($this->state->params) ? $this->state->params : new JObject; ?>
    diff --git a/administrator/components/com_banners/views/clients/view.html.php b/administrator/components/com_banners/views/clients/view.html.php index ae0034b9a35b9..0a4d026704177 100644 --- a/administrator/components/com_banners/views/clients/view.html.php +++ b/administrator/components/com_banners/views/clients/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/views/download/tmpl/default.php b/administrator/components/com_banners/views/download/tmpl/default.php index 3698048b51409..ef26124331974 100644 --- a/administrator/components/com_banners/views/download/tmpl/default.php +++ b/administrator/components/com_banners/views/download/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,7 +16,7 @@ class="form-horizontal form-validate" id="download-form" name="adminForm" - action="" + action="" method="post"> form->getFieldset() as $field) : ?> diff --git a/administrator/components/com_banners/views/download/view.html.php b/administrator/components/com_banners/views/download/view.html.php index a963d6ec1a5aa..f327c04beaf48 100644 --- a/administrator/components/com_banners/views/download/view.html.php +++ b/administrator/components/com_banners/views/download/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/views/tracks/tmpl/default.php b/administrator/components/com_banners/views/tracks/tmpl/default.php index f815f4bddadf6..8e7d87de46885 100644 --- a/administrator/components/com_banners/views/tracks/tmpl/default.php +++ b/administrator/components/com_banners/views/tracks/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -76,7 +76,7 @@ count; ?> - track_date, JText::_('DATE_FORMAT_LC4') . ' H:i'); ?> + track_date, JText::_('DATE_FORMAT_LC5')); ?> @@ -94,10 +94,10 @@ 'height' => '370px', 'width' => '300px', 'modalWidth' => '40', - 'footer' => ' '', ) diff --git a/administrator/components/com_banners/views/tracks/view.html.php b/administrator/components/com_banners/views/tracks/view.html.php index cd93b888975f6..27490fe1ee755 100644 --- a/administrator/components/com_banners/views/tracks/view.html.php +++ b/administrator/components/com_banners/views/tracks/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_banners/views/tracks/view.raw.php b/administrator/components/com_banners/views/tracks/view.raw.php index f9babb40b0596..8e50a97a5793b 100644 --- a/administrator/components/com_banners/views/tracks/view.raw.php +++ b/administrator/components/com_banners/views/tracks/view.raw.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_banners * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_cache/access.xml b/administrator/components/com_cache/access.xml new file mode 100644 index 0000000000000..e40c7101c90c8 --- /dev/null +++ b/administrator/components/com_cache/access.xml @@ -0,0 +1,7 @@ + + +
    + + +
    +
    diff --git a/administrator/components/com_cache/cache.php b/administrator/components/com_cache/cache.php index b78b099d45938..8706aa4521d38 100644 --- a/administrator/components/com_cache/cache.php +++ b/administrator/components/com_cache/cache.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cache * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_cache/cache.xml b/administrator/components/com_cache/cache.xml index 613d151756345..95ecb6bcac4f5 100644 --- a/administrator/components/com_cache/cache.xml +++ b/administrator/components/com_cache/cache.xml @@ -3,7 +3,7 @@ com_cache Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_cache/config.xml b/administrator/components/com_cache/config.xml index 76186ee8c3f1d..692b89a61db12 100644 --- a/administrator/components/com_cache/config.xml +++ b/administrator/components/com_cache/config.xml @@ -12,15 +12,6 @@ filter="rules" validate="rules" component="com_cache" - section="component"> - - - + section="component" /> diff --git a/administrator/components/com_cache/controller.php b/administrator/components/com_cache/controller.php index 9b2e404a20b8d..7fbaa34e86610 100644 --- a/administrator/components/com_cache/controller.php +++ b/administrator/components/com_cache/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cache * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -72,7 +72,7 @@ public function display($cachable = false, $urlparams = false) public function delete() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $cid = $this->input->post->get('cid', array(), 'array'); @@ -107,7 +107,7 @@ public function delete() public function deleteAll() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $model = $this->getModel('cache'); @@ -138,6 +138,7 @@ public function deleteAll() $app->enqueueMessage(JText::_('COM_CACHE_MSG_SOME_CACHE_GROUPS_CLEARED'), 'warning'); } + $app->triggerEvent('onAfterPurge', array()); $this->setRedirect('index.php?option=com_cache&view=cache'); } @@ -149,7 +150,7 @@ public function deleteAll() public function purge() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); if (!$this->getModel('cache')->purge()) { diff --git a/administrator/components/com_cache/helpers/cache.php b/administrator/components/com_cache/helpers/cache.php index f4e1c6c2b262b..68c290f9defd6 100644 --- a/administrator/components/com_cache/helpers/cache.php +++ b/administrator/components/com_cache/helpers/cache.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cache * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_cache/models/cache.php b/administrator/components/com_cache/models/cache.php index e1647f05bb18a..66516a01d4d5b 100644 --- a/administrator/components/com_cache/models/cache.php +++ b/administrator/components/com_cache/models/cache.php @@ -3,12 +3,13 @@ * @package Joomla.Administrator * @subpackage com_cache * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\CMS\Factory; use Joomla\Utilities\ArrayHelper; /** @@ -54,7 +55,7 @@ public function __construct($config = array()) 'group', 'count', 'size', - 'cliend_id', + 'client_id', ); } @@ -251,7 +252,7 @@ public function clean($group = '') { try { - return $this->getCache()->clean($group); + $this->getCache()->clean($group); } catch (JCacheExceptionConnecting $exception) { @@ -261,6 +262,10 @@ public function clean($group = '') { return false; } + + Factory::getApplication()->triggerEvent('onAfterPurge', array($group)); + + return true; } /** @@ -294,7 +299,7 @@ public function purge() { try { - return JFactory::getCache('')->gc(); + JFactory::getCache('')->gc(); } catch (JCacheExceptionConnecting $exception) { @@ -304,5 +309,9 @@ public function purge() { return false; } + + Factory::getApplication()->triggerEvent('onAfterPurge', array()); + + return true; } } diff --git a/administrator/components/com_cache/models/forms/filter_cache.xml b/administrator/components/com_cache/models/forms/filter_cache.xml index 9e83948eaf031..8a97b98ea29d1 100644 --- a/administrator/components/com_cache/models/forms/filter_cache.xml +++ b/administrator/components/com_cache/models/forms/filter_cache.xml @@ -13,6 +13,7 @@ diff --git a/administrator/components/com_cache/views/cache/tmpl/default.php b/administrator/components/com_cache/views/cache/tmpl/default.php index 06a4a60cbe608..1689dcc4d8d99 100644 --- a/administrator/components/com_cache/views/cache/tmpl/default.php +++ b/administrator/components/com_cache/views/cache/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cache * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -56,11 +56,11 @@ foreach ($this->data as $folder => $item) : ?> - + diff --git a/administrator/components/com_cache/views/cache/view.html.php b/administrator/components/com_cache/views/cache/view.html.php index d61cb7927463d..ad2805a276628 100644 --- a/administrator/components/com_cache/views/cache/view.html.php +++ b/administrator/components/com_cache/views/cache/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cache * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -76,7 +76,7 @@ protected function addToolbar() } JToolbarHelper::custom('delete', 'delete.png', 'delete_f2.png', 'JTOOLBAR_DELETE', true); - JToolbarHelper::custom('deleteAll', 'delete.png', 'delete_f2.png', 'JTOOLBAR_DELETE_ALL', false); + JToolbarHelper::custom('deleteAll', 'remove.png', 'delete_f2.png', 'JTOOLBAR_DELETE_ALL', false); JToolbarHelper::divider(); if (JFactory::getUser()->authorise('core.admin', 'com_cache')) diff --git a/administrator/components/com_cache/views/purge/tmpl/default.php b/administrator/components/com_cache/views/purge/tmpl/default.php index 4000dab735b57..b5ee11409f675 100644 --- a/administrator/components/com_cache/views/purge/tmpl/default.php +++ b/administrator/components/com_cache/views/purge/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cache * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_cache/views/purge/view.html.php b/administrator/components/com_cache/views/purge/view.html.php index 1e3736bf2b3b4..9df07991f7db1 100644 --- a/administrator/components/com_cache/views/purge/view.html.php +++ b/administrator/components/com_cache/views/purge/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cache * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/categories.php b/administrator/components/com_categories/categories.php index 764b293b3058b..00a708b0b52b0 100644 --- a/administrator/components/com_categories/categories.php +++ b/administrator/components/com_categories/categories.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/categories.xml b/administrator/components/com_categories/categories.xml index 8d003a387d258..537e9b1e697bd 100644 --- a/administrator/components/com_categories/categories.xml +++ b/administrator/components/com_categories/categories.xml @@ -3,7 +3,7 @@ com_categories Joomla! Project December 2007 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2007 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_categories/controller.php b/administrator/components/com_categories/controller.php index 8e815de2ec1c9..51ad737e2af58 100644 --- a/administrator/components/com_categories/controller.php +++ b/administrator/components/com_categories/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/controllers/ajax.json.php b/administrator/components/com_categories/controllers/ajax.json.php new file mode 100644 index 0000000000000..6b5b5bef544cf --- /dev/null +++ b/administrator/components/com_categories/controllers/ajax.json.php @@ -0,0 +1,88 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\LanguageHelper; + +/** + * The categories controller for ajax requests + * + * @since 3.9.0 + */ +class CategoriesControllerAjax extends JControllerLegacy +{ + /** + * Method to fetch associations of a category + * + * The method assumes that the following http parameters are passed in an Ajax Get request: + * token: the form token + * assocId: the id of the category whose associations are to be returned + * excludeLang: the association for this language is to be excluded + * + * @return null + * + * @since 3.9.0 + */ + public function fetchAssociations() + { + if (!JSession::checkToken('get')) + { + echo new JResponseJson(null, JText::_('JINVALID_TOKEN'), true); + } + else + { + $input = JFactory::getApplication()->input; + $extension = $input->get('extension'); + + $assocId = $input->getInt('assocId', 0); + + if ($assocId == 0) + { + echo new JResponseJson(null, JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'assocId'), true); + + return; + } + + $excludeLang = $input->get('excludeLang', '', 'STRING'); + + $associations = JLanguageAssociations::getAssociations($extension, '#__categories', 'com_categories.item', (int) $assocId, 'id', 'alias', ''); + + unset($associations[$excludeLang]); + + // Add the title to each of the associated records + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables'); + $categoryTable = JTable::getInstance('Category', 'JTable'); + + foreach ($associations as $lang => $association) + { + $categoryTable->load($association->id); + $associations[$lang]->title = $categoryTable->title; + } + + $countContentLanguages = count(LanguageHelper::getContentLanguages(array(0, 1))); + + if (count($associations) == 0) + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE'); + } + elseif ($countContentLanguages > count($associations) + 2) + { + $tags = implode(', ', array_keys($associations)); + $message = JText::sprintf('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME', $tags); + } + else + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL'); + } + + echo new JResponseJson($associations, $message); + } + } +} diff --git a/administrator/components/com_categories/controllers/categories.php b/administrator/components/com_categories/controllers/categories.php index e64ab88d4291b..97e7d12e5fe10 100644 --- a/administrator/components/com_categories/controllers/categories.php +++ b/administrator/components/com_categories/controllers/categories.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -37,13 +37,13 @@ public function getModel($name = 'Category', $prefix = 'CategoriesModel', $confi /** * Rebuild the nested set tree. * - * @return bool False on failure or error, true on success. + * @return boolean False on failure or error, true on success. * * @since 1.6 */ public function rebuild() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $extension = $this->input->get('extension'); $this->setRedirect(JRoute::_('index.php?option=com_categories&view=categories&extension=' . $extension, false)); @@ -68,7 +68,7 @@ public function rebuild() /** * Save the manual order inputs from the categories list page. * - * @return void + * @return boolean True on success * * @since 1.6 * @see JControllerAdmin::saveorder() @@ -76,7 +76,7 @@ public function rebuild() */ public function saveorder() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); try { @@ -114,7 +114,7 @@ public function saveorder() */ public function delete() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Get items to remove from the request. $cid = $this->input->get('cid', array(), 'array'); diff --git a/administrator/components/com_categories/controllers/category.php b/administrator/components/com_categories/controllers/category.php index 79fecc0742acd..efa2914aa3132 100644 --- a/administrator/components/com_categories/controllers/category.php +++ b/administrator/components/com_categories/controllers/category.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -105,6 +105,47 @@ protected function allowEdit($data = array(), $key = 'parent_id') return false; } + /** + * Override parent save method to store form data with right key as expected by edit category page + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean True if successful, false otherwise. + * + * @since 3.10.3 + */ + public function save($key = null, $urlVar = null) + { + $result = parent::save($key, $urlVar); + + $oldKey = $this->option . '.edit.category.data'; + $newKey = $this->option . '.edit.category.' . substr($this->extension, 4) . '.data'; + $app = JFactory::getApplication(); + $app->setUserState($newKey, $app->getUserState($oldKey)); + + return $result; + } + + /** + * Override cancel method to clear form data for a failed edit action + * + * @param string $key The name of the primary key of the URL variable. + * + * @return boolean True if access level checks pass, false otherwise. + * + * @since 3.10.3 + */ + public function cancel($key = null) + { + $result = parent::cancel($key); + + $newKey = $this->option . '.edit.category.' . substr($this->extension, 4) . '.data'; + JFactory::getApplication()->setUserState($newKey, null); + + return $result; + } + /** * Method to run batch operations. * @@ -116,7 +157,7 @@ protected function allowEdit($data = array(), $key = 'parent_id') */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Set the model /** @var CategoriesModelCategory $model */ diff --git a/administrator/components/com_categories/helpers/association.php b/administrator/components/com_categories/helpers/association.php index ddda743cd1a95..99b5a6d831a32 100644 --- a/administrator/components/com_categories/helpers/association.php +++ b/administrator/components/com_categories/helpers/association.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -25,12 +25,13 @@ abstract class CategoryHelperAssociation * * @param integer $id Id of the item * @param string $extension Name of the component + * @param string $layout Category layout * * @return array Array of associations for the component categories * * @since 3.0 */ - public static function getCategoryAssociations($id = 0, $extension = 'com_content') + public static function getCategoryAssociations($id = 0, $extension = 'com_content', $layout = null) { $return = array(); @@ -46,11 +47,13 @@ public static function getCategoryAssociations($id = 0, $extension = 'com_conten { if (class_exists($helperClassname) && is_callable(array($helperClassname, 'getCategoryRoute'))) { - $return[$tag] = $helperClassname::getCategoryRoute($item, $tag); + $return[$tag] = $helperClassname::getCategoryRoute($item, $tag, $layout); } else { - $return[$tag] = 'index.php?option=' . $extension . '&view=category&id=' . $item; + $viewLayout = $layout ? '&layout=' . $layout : ''; + + $return[$tag] = 'index.php?option=' . $extension . '&view=category&id=' . $item . $viewLayout; } } } diff --git a/administrator/components/com_categories/helpers/categories.php b/administrator/components/com_categories/helpers/categories.php index 3103328d8b8a7..3fb77c182dd38 100644 --- a/administrator/components/com_categories/helpers/categories.php +++ b/administrator/components/com_categories/helpers/categories.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -111,11 +111,30 @@ public static function getActions($extension, $categoryId = 0) public static function getAssociations($pk, $extension = 'com_content') { $langAssociations = JLanguageAssociations::getAssociations($extension, '#__categories', 'com_categories.item', $pk, 'id', 'alias', ''); - $associations = array(); + $associations = array(); + $user = JFactory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); foreach ($langAssociations as $langAssociation) { - $associations[$langAssociation->language] = $langAssociation->id; + // Include only published categories with user access + $arrId = explode(':', $langAssociation->id); + $assocId = $arrId[0]; + + $db = \JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select($db->qn('published')) + ->from($db->qn('#__categories')) + ->where('access IN (' . $groups . ')') + ->where($db->qn('id') . ' = ' . (int) $assocId); + + $result = (int) $db->setQuery($query)->loadResult(); + + if ($result === 1) + { + $associations[$langAssociation->language] = $langAssociation->id; + } } return $associations; @@ -127,7 +146,7 @@ public static function getAssociations($pk, $extension = 'com_content') * @param mixed $catid Name or ID of category. * @param string $extension Extension that triggers this function * - * @return int $catid Category ID. + * @return integer $catid Category ID. */ public static function validateCategoryId($catid, $extension) { diff --git a/administrator/components/com_categories/helpers/html/categoriesadministrator.php b/administrator/components/com_categories/helpers/html/categoriesadministrator.php index 3f2bdc464ef90..fec1ae091f649 100644 --- a/administrator/components/com_categories/helpers/html/categoriesadministrator.php +++ b/administrator/components/com_categories/helpers/html/categoriesadministrator.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -49,6 +49,7 @@ public static function association($catid, $extension = 'com_content') ->select('l.lang_code') ->from('#__categories as c') ->where('c.id IN (' . implode(',', array_values($associations)) . ')') + ->where('c.id != ' . $catid) ->join('LEFT', '#__languages as l ON c.language=l.lang_code') ->select('l.image') ->select('l.title as language_title'); diff --git a/administrator/components/com_categories/models/categories.php b/administrator/components/com_categories/models/categories.php index 061603e82d62d..a03039599ecad 100644 --- a/administrator/components/com_categories/models/categories.php +++ b/administrator/components/com_categories/models/categories.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,6 +16,14 @@ */ class CategoriesModelCategories extends JModelList { + /** + * Does an association exist? Caches the result of getAssoc(). + * + * @var boolean|null + * @since 3.10.4 + */ + private $hasAssociation; + /** * Constructor. * @@ -47,6 +55,11 @@ public function __construct($config = array()) ); } + if (JLanguageAssociations::isEnabled()) + { + $config['filter_fields'][] = 'association'; + } + parent::__construct($config); } @@ -178,9 +191,9 @@ protected function getListQuery() ->join('LEFT', '#__users AS ua ON ua.id = a.created_user_id'); // Join over the associations. - $assoc = $this->getAssoc(); + $this->hasAssociation = $this->getAssoc(); - if ($assoc) + if ($this->hasAssociation) { $query->select('COUNT(asso2.id)>1 as association') ->join('LEFT', '#__associations AS asso ON asso.id = a.id AND asso.context=' . $db->quote('com_categories.item')) @@ -308,33 +321,31 @@ protected function getListQuery() */ public function getAssoc() { - static $assoc = null; - - if (!is_null($assoc)) + if (!is_null($this->hasAssociation)) { - return $assoc; + return $this->hasAssociation; } $extension = $this->getState('filter.extension'); - $assoc = JLanguageAssociations::isEnabled(); + $this->hasAssociation = JLanguageAssociations::isEnabled(); $extension = explode('.', $extension); $component = array_shift($extension); $cname = str_replace('com_', '', $component); - if (!$assoc || !$component || !$cname) + if (!$this->hasAssociation || !$component || !$cname) { - $assoc = false; + $this->hasAssociation = false; } else { $hname = $cname . 'HelperAssociation'; JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); - $assoc = class_exists($hname) && !empty($hname::$category_association); + $this->hasAssociation = class_exists($hname) && !empty($hname::$category_association); } - return $assoc; + return $this->hasAssociation; } /** @@ -342,7 +353,7 @@ public function getAssoc() * * @return mixed An array of data items on success, false on failure. * - * @since 12.2 + * @since 3.0.1 */ public function getItems() { @@ -361,7 +372,7 @@ public function getItems() /** * Method to load the countItems method from the extensions * - * @param stdClass[] &$items The category items + * @param stdClass[] $items The category items * @param string $extension The category extension * * @return void diff --git a/administrator/components/com_categories/models/category.php b/administrator/components/com_categories/models/category.php index a684032c74d4c..6b2b076474e35 100644 --- a/administrator/components/com_categories/models/category.php +++ b/administrator/components/com_categories/models/category.php @@ -3,12 +3,13 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\CMS\Factory; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; @@ -44,6 +45,14 @@ class CategoriesModelCategory extends JModelAdmin */ protected $associationsContext = 'com_categories.item'; + /** + * Does an association exist? Caches the result of getAssoc(). + * + * @var boolean|null + * @since 3.10.4 + */ + private $hasAssociation; + /** * Override parent constructor. * @@ -57,6 +66,9 @@ public function __construct($config = array()) parent::__construct($config); $extension = JFactory::getApplication()->input->get('extension', 'com_content'); $this->typeAlias = $extension . '.category'; + + // Add a new batch command + $this->batch_commands['flip_ordering'] = 'batchFlipordering'; } /** @@ -182,31 +194,6 @@ public function getItem($pk = null) $registry = new Registry($result->metadata); $result->metadata = $registry->toArray(); - // Convert the created and modified dates to local user time for display in the form. - $tz = new DateTimeZone(JFactory::getApplication()->get('offset')); - - if ((int) $result->created_time) - { - $date = new JDate($result->created_time); - $date->setTimezone($tz); - $result->created_time = $date->toSql(true); - } - else - { - $result->created_time = null; - } - - if ((int) $result->modified_time) - { - $date = new JDate($result->modified_time); - $date->setTimezone($tz); - $result->modified_time = $date->toSql(true); - } - else - { - $result->modified_time = null; - } - if (!empty($result->id)) { $result->tags = new JHelperTags; @@ -349,6 +336,41 @@ protected function loadFormData() return $data; } + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.23 + */ + public function validate($form, $data, $group = null) + { + // Don't allow to change the users if not allowed to access com_users. + if (!JFactory::getUser()->authorise('core.manage', 'com_users')) + { + if (isset($data['created_user_id'])) + { + unset($data['created_user_id']); + } + } + + if (!JFactory::getUser()->authorise('core.admin', $data['extension'])) + { + if (isset($data['rules'])) + { + unset($data['rules']); + } + } + + return parent::validate($form, $data, $group); + } + /** * Method to preprocess the form. * @@ -356,7 +378,7 @@ protected function loadFormData() * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import. * - * @return void + * @return mixed * * @see JFormField * @since 1.6 @@ -452,6 +474,7 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $field->addAttribute('new', 'true'); $field->addAttribute('edit', 'true'); $field->addAttribute('clear', 'true'); + $field->addAttribute('propagate', 'true'); } $form->load($addform, false); @@ -480,7 +503,7 @@ public function save($data) $isNew = true; $context = $this->option . '.' . $this->name; - if ((!empty($data['tags']) && $data['tags'][0] != '')) + if (!empty($data['tags']) && $data['tags'][0] != '') { $table->newTags = $data['tags']; } @@ -683,6 +706,11 @@ public function save($data) $this->setState($this->getName() . '.id', $table->id); + if (Factory::getApplication()->input->get('task') == 'editAssociations') + { + return $this->redirectToAssociations($data); + } + // Clear the cache $this->cleanCache(); @@ -692,7 +720,7 @@ public function save($data) /** * Method to change the published state of one or more records. * - * @param array &$pks A list of the primary keys to change. + * @param array $pks A list of the primary keys to change. * @param integer $value The value of the published state. * * @return boolean True on success. @@ -746,19 +774,19 @@ public function rebuild() * First we save the new order values in the lft values of the changed ids. * Then we invoke the table rebuild to implement the new ordering. * - * @param array $idArray An array of primary key ids. - * @param integer $lft_array The lft value + * @param array $idArray An array of primary key ids. + * @param integer $lftArray The lft value * * @return boolean False on failure or error, True otherwise * * @since 1.6 */ - public function saveorder($idArray = null, $lft_array = null) + public function saveorder($idArray = null, $lftArray = null) { // Get an instance of the table object. $table = $this->getTable(); - if (!$table->saveorder($idArray, $lft_array)) + if (!$table->saveorder($idArray, $lftArray)) { $this->setError($table->getError()); @@ -819,6 +847,56 @@ protected function batchTag($value, $pks, $contexts) return true; } + /** + * Batch flip category ordering. + * + * @param integer $value The new category. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return mixed An array of new IDs on success, boolean false on failure. + * + * @since 3.6.3 + */ + protected function batchFlipordering($value, $pks, $contexts) + { + $successful = array(); + + $db = $this->getDbo(); + $query = $db->getQuery(true); + + /** + * For each category get the max ordering value + * Re-order with max - ordering + */ + foreach ($pks as $id) + { + $query->select('MAX(ordering)') + ->from('#__content') + ->where($db->qn('catid') . ' = ' . $db->q($id)); + + $db->setQuery($query); + + $max = (int) $db->loadresult(); + $max++; + + $query->clear(); + + $query->update('#__content') + ->set($db->qn('ordering') . ' = ' . $max . ' - ' . $db->qn('ordering')) + ->where($db->qn('catid') . ' = ' . $db->q($id)); + + $db->setQuery($query); + + if ($db->execute()) + { + $successful[] = $id; + } + } + + return empty($successful) ? false : $successful; + } + /** * Batch copy categories to a new category. * @@ -964,9 +1042,10 @@ protected function batchCopy($value, $pks, $contexts) } } - // Make a copy of the old ID and Parent ID - $oldId = $this->table->id; + // Make a copy of the old ID, Parent ID and Asset ID + $oldId = $this->table->id; $oldParentId = $this->table->parent_id; + $oldAssetId = $this->table->asset_id; // Reset the id because we are making a copy. $this->table->id = 0; @@ -1009,6 +1088,16 @@ protected function batchCopy($value, $pks, $contexts) // Add the new ID to the array $newIds[$pk] = $newId; + // Copy rules + $query->clear() + ->update($db->quoteName('#__assets', 't')) + ->join('INNER', $db->quoteName('#__assets', 's') . + ' ON ' . $db->quoteName('s.id') . ' = ' . $oldAssetId + ) + ->set($db->quoteName('t.rules') . ' = ' . $db->quoteName('s.rules')) + ->where($db->quoteName('t.id') . ' = ' . $this->table->asset_id); + $db->setQuery($query)->execute(); + // Now we log the old 'parent' to the new 'parent' $parents[$oldId] = $this->table->id; $count--; @@ -1188,14 +1277,14 @@ protected function batchMove($value, $pks, $contexts) /** * Custom clean the cache of com_content and content modules * - * @param string $group Cache group name. - * @param integer $client_id Application client id. + * @param string $group Cache group name. + * @param integer $clientId Application client id. * * @return void * * @since 1.6 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { $extension = JFactory::getApplication()->input->get('extension'); @@ -1219,20 +1308,20 @@ protected function cleanCache($group = null, $client_id = 0) /** * Method to change the title & alias. * - * @param integer $parent_id The id of the parent. - * @param string $alias The alias. - * @param string $title The title. + * @param integer $parentId The id of the parent. + * @param string $alias The alias. + * @param string $title The title. * * @return array Contains the modified title and alias. * * @since 1.7 */ - protected function generateNewTitle($parent_id, $alias, $title) + protected function generateNewTitle($parentId, $alias, $title) { // Alter the title & alias $table = $this->getTable(); - while ($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) + while ($table->load(array('alias' => $alias, 'parent_id' => $parentId))) { $title = StringHelper::increment($title); $alias = StringHelper::increment($alias, 'dash'); @@ -1248,32 +1337,30 @@ protected function generateNewTitle($parent_id, $alias, $title) */ public function getAssoc() { - static $assoc = null; - - if (!is_null($assoc)) + if (!is_null($this->hasAssociation)) { - return $assoc; + return $this->hasAssociation; } $extension = $this->getState('category.extension'); - $assoc = JLanguageAssociations::isEnabled(); + $this->hasAssociation = JLanguageAssociations::isEnabled(); $extension = explode('.', $extension); $component = array_shift($extension); $cname = str_replace('com_', '', $component); - if (!$assoc || !$component || !$cname) + if (!$this->hasAssociation || !$component || !$cname) { - $assoc = false; + $this->hasAssociation = false; } else { $hname = $cname . 'HelperAssociation'; JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); - $assoc = class_exists($hname) && !empty($hname::$category_association); + $this->hasAssociation = class_exists($hname) && !empty($hname::$category_association); } - return $assoc; + return $this->hasAssociation; } } diff --git a/administrator/components/com_categories/models/fields/categoryedit.php b/administrator/components/com_categories/models/fields/categoryedit.php index a972f26ddd396..e1b06ff3cd834 100644 --- a/administrator/components/com_categories/models/fields/categoryedit.php +++ b/administrator/components/com_categories/models/fields/categoryedit.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; use Joomla\Utilities\ArrayHelper; @@ -28,6 +28,14 @@ class JFormFieldCategoryEdit extends JFormFieldList */ protected $allowAdd; + /** + * Optional prefix for new categories. + * + * @var string + * @since 3.9.11 + */ + protected $customPrefix; + /** * A flexible category list that respects access controls * @@ -57,6 +65,7 @@ public function setup(SimpleXMLElement $element, $value, $group = null) if ($return) { $this->allowAdd = isset($this->element['allowAdd']) ? $this->element['allowAdd'] : ''; + $this->customPrefix = (string) $this->element['customPrefix']; } return $return; @@ -65,7 +74,7 @@ public function setup(SimpleXMLElement $element, $value, $group = null) /** * Method to get certain otherwise inaccessible properties from the form field object. * - * @param string $name The property name for which to the the value. + * @param string $name The property name for which to get the value. * * @return mixed The property value or null. * @@ -76,6 +85,7 @@ public function __get($name) switch ($name) { case 'allowAdd': + case 'customPrefix': return $this->$name; } @@ -85,7 +95,7 @@ public function __get($name) /** * Method to set certain otherwise inaccessible properties of the form field object. * - * @param string $name The property name for which to the the value. + * @param string $name The property name for which to set the value. * @param mixed $value The value of the property. * * @return void @@ -102,6 +112,9 @@ public function __set($name, $value) $value = (string) $value; $this->$name = ($value === 'true' || $value === $name || $value === '1'); break; + case 'customPrefix': + $this->$name = (string) $value; + break; default: parent::__set($name, $value); } @@ -119,7 +132,7 @@ public function __set($name, $value) protected function getOptions() { $options = array(); - $published = $this->element['published'] ? $this->element['published'] : array(0, 1); + $published = $this->element['published'] ? explode(',', (string) $this->element['published']) : array(0, 1); $name = (string) $this->element['name']; // Let's get the id for the current item, either category or content item. @@ -141,24 +154,26 @@ protected function getOptions() $extension = $this->element['extension'] ? (string) $this->element['extension'] : (string) $jinput->get('option', 'com_content'); } + // Account for case that a submitted form has a multi-value category id field (e.g. a filtering form), just use the first category + $oldCat = is_array($oldCat) + ? (int) reset($oldCat) + : (int) $oldCat; + $db = JFactory::getDbo(); $user = JFactory::getUser(); - $groups = implode(',', $user->getAuthorisedViewLevels()); $query = $db->getQuery(true) - ->select('DISTINCT a.id AS value, a.title AS text, a.level, a.published, a.lft'); - $subQuery = $db->getQuery(true) - ->select('id,title,level,published,parent_id,extension,lft,rgt') - ->from('#__categories'); + ->select('a.id AS value, a.title AS text, a.level, a.published, a.lft, a.language') + ->from('#__categories AS a'); // Filter by the extension type if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') { - $subQuery->where('(extension = ' . $db->quote($extension) . ' OR parent_id = 0)'); + $query->where('(a.extension = ' . $db->quote($extension) . ' OR a.parent_id = 0)'); } else { - $subQuery->where('(extension = ' . $db->quote($extension) . ')'); + $query->where('(a.extension = ' . $db->quote($extension) . ')'); } // Filter language @@ -172,24 +187,21 @@ protected function getOptions() { $language = $db->quote($this->element['language']); } - $subQuery->where($db->quoteName('language') . ' IN (' . $language . ')'); + + $query->where($db->quoteName('a.language') . ' IN (' . $language . ')'); } // Filter on the published state - if (is_numeric($published)) - { - $subQuery->where('published = ' . (int) $published); - } - elseif (is_array($published)) - { - $subQuery->where('published IN (' . implode(',', ArrayHelper::toInteger($published)) . ')'); - } + $query->where('a.published IN (' . implode(',', ArrayHelper::toInteger($published)) . ')'); // Filter categories on User Access Level - $subQuery->where('access IN (' . $groups . ')'); + // Filter by access level on categories. + if (!$user->authorise('core.admin')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } - $query->from('(' . (string) $subQuery . ') AS a') - ->join('LEFT', $db->quoteName('#__categories') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); $query->order('a.lft ASC'); // If parent isn't explicitly stated but we are in com_categories assume we want parents @@ -232,34 +244,22 @@ protected function getOptions() } } - // Displays language code if not set to All - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('language')) - ->where($db->quoteName('id') . '=' . (int) $options[$i]->value) - ->from($db->quoteName('#__categories')); - - $db->setQuery($query); - $language = $db->loadResult(); - if ($options[$i]->published == 1) { - $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; + $options[$i]->text = str_repeat('- ', !$options[$i]->level ? 0 : $options[$i]->level - 1) . $options[$i]->text; } else { - $options[$i]->text = str_repeat('- ', $options[$i]->level) . '[' . $options[$i]->text . ']'; + $options[$i]->text = str_repeat('- ', !$options[$i]->level ? 0 : $options[$i]->level - 1) . '[' . $options[$i]->text . ']'; } - if ($language !== '*') + // Displays language code if not set to All + if ($options[$i]->language !== '*') { - $options[$i]->text = $options[$i]->text . ' (' . $language . ')'; + $options[$i]->text = $options[$i]->text . ' (' . $options[$i]->language . ')'; } } - // Get the current user object. - $user = JFactory::getUser(); - // For new items we want a list of categories you are allowed to create in. if ($oldCat == 0) { @@ -293,7 +293,7 @@ protected function getOptions() continue; } - if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.edit.state', $assetKey)) + if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.edit.state', $assetKey)) { unset($options[$i]); continue; @@ -311,7 +311,7 @@ protected function getOptions() continue; } - if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.create', $assetKey)) + if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.create', $assetKey)) { unset($options[$i]); continue; @@ -362,6 +362,11 @@ protected function getInput() $attr .= ' data-custom_group_text="' . $customGroupText . '" ' . 'data-no_results_text="' . JText::_('JGLOBAL_ADD_CUSTOM_CATEGORY') . '" ' . 'data-placeholder="' . JText::_('JGLOBAL_TYPE_OR_SELECT_CATEGORY') . '" '; + + if ($this->customPrefix !== '') + { + $attr .= 'data-custom_value_prefix="' . $this->customPrefix . '" '; + } } if ($class) @@ -413,8 +418,19 @@ protected function getInput() } } else - // Create a regular list. { + // Create a regular list. + if (count($options) === 0) + { + // All Categories have been deleted, so we need a new category (This will create on save if selected). + $options[0] = new stdClass; + $options[0]->value = 'Uncategorised'; + $options[0]->text = 'Uncategorised'; + $options[0]->level = '1'; + $options[0]->published = '1'; + $options[0]->lft = '1'; + } + $html[] = JHtml::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id); } diff --git a/administrator/components/com_categories/models/fields/categoryparent.php b/administrator/components/com_categories/models/fields/categoryparent.php index 2ea6216327d38..2e272272f459f 100644 --- a/administrator/components/com_categories/models/fields/categoryparent.php +++ b/administrator/components/com_categories/models/fields/categoryparent.php @@ -3,18 +3,19 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JFormHelper::loadFieldClass('list'); /** * Category Parent field. * - * @since 1.6 + * @since 1.6 + * @deprecated 4.0 Use categoryedit instead. */ class JFormFieldCategoryParent extends JFormFieldList { diff --git a/administrator/components/com_categories/models/fields/modal/category.php b/administrator/components/com_categories/models/fields/modal/category.php index 09ff66d9806a1..72734275cef36 100644 --- a/administrator/components/com_categories/models/fields/modal/category.php +++ b/administrator/components/com_categories/models/fields/modal/category.php @@ -3,11 +3,13 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; + +use Joomla\CMS\Language\LanguageHelper; /** * Supports a modal category picker. @@ -42,10 +44,13 @@ protected function getInput() $extension = (string) JFactory::getApplication()->input->get('extension', 'com_content'); } - $allowNew = ((string) $this->element['new'] == 'true'); - $allowEdit = ((string) $this->element['edit'] == 'true'); - $allowClear = ((string) $this->element['clear'] != 'false'); - $allowSelect = ((string) $this->element['select'] != 'false'); + $allowNew = ((string) $this->element['new'] == 'true'); + $allowEdit = ((string) $this->element['edit'] == 'true'); + $allowClear = ((string) $this->element['clear'] != 'false'); + $allowSelect = ((string) $this->element['select'] != 'false'); + $allowPropagate = ((string) $this->element['propagate'] == 'true'); + + $languages = LanguageHelper::getContentLanguages(array(0, 1)); // Load language. JFactory::getLanguage()->load('com_categories', JPATH_ADMINISTRATOR); @@ -78,6 +83,8 @@ function jSelectCategory_" . $this->id . "(id, title, object) { } "); + JText::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED'); + $scriptSelect[$this->id] = true; } } @@ -128,55 +135,72 @@ function jSelectCategory_" . $this->id . "(id, title, object) { // Select category button. if ($allowSelect) { - $html .= '' . ' ' . JText::_('JSELECT') - . ''; + . ''; } // New category button. if ($allowNew) { - $html .= '' . ' ' . JText::_('JACTION_CREATE') - . ''; + . ''; } // Edit category button. if ($allowEdit) { - $html .= '' . ' ' . JText::_('JACTION_EDIT') - . ''; + . ''; } // Clear category button. if ($allowClear) { - $html .= '' . '' . JText::_('JCLEAR') - . ''; + . ''; + } + + // Propagate category button + if ($allowPropagate && count($languages) > 2) + { + // Strip off language tag at the end + $tagLength = (int) strlen($this->element['language']); + $callbackFunctionStem = substr("jSelectCategory_" . $this->id, 0, -$tagLength); + + $html .= '' + . '' . JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_BUTTON') + . ''; } $html .= ''; @@ -194,7 +218,7 @@ function jSelectCategory_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', + 'footer' => '', ) ); } @@ -215,15 +239,15 @@ function jSelectCategory_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } @@ -244,15 +268,15 @@ function jSelectCategory_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } diff --git a/administrator/components/com_categories/models/forms/category.xml b/administrator/components/com_categories/models/forms/category.xml index cad1b4196ca5b..6b8679d5221c4 100644 --- a/administrator/components/com_categories/models/forms/category.xml +++ b/administrator/components/com_categories/models/forms/category.xml @@ -3,7 +3,7 @@ - - - - - + + + + diff --git a/administrator/components/com_categories/models/forms/filter_categories.xml b/administrator/components/com_categories/models/forms/filter_categories.xml index 3dd53359d3527..c17e564e1cd16 100644 --- a/administrator/components/com_categories/models/forms/filter_categories.xml +++ b/administrator/components/com_categories/models/forms/filter_categories.xml @@ -6,6 +6,7 @@ @@ -88,6 +90,8 @@ + + diff --git a/administrator/components/com_categories/tables/category.php b/administrator/components/com_categories/tables/category.php index 066540fcf078d..3be718533205d 100644 --- a/administrator/components/com_categories/tables/category.php +++ b/administrator/components/com_categories/tables/category.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/views/categories/tmpl/default.php b/administrator/components/com_categories/views/categories/tmpl/default.php index 0da6e777eec0e..c51a1cd6ccaec 100644 --- a/administrator/components/com_categories/views/categories/tmpl/default.php +++ b/administrator/components/com_categories/views/categories/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -128,7 +128,6 @@ items as $i => $item) : ?> id, $this->ordering[$item->parent_id]); $canEdit = $user->authorise('core.edit', $extension . '.category.' . $item->id); $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; $canEditOwn = $user->authorise('core.edit.own', $extension . '.category.' . $item->id) && $item->created_user_id == $userId; @@ -177,7 +176,7 @@ - + @@ -220,25 +219,25 @@ items[0]) && property_exists($this->items[0], 'count_published')) : ?> - + count_published; ?> items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> - + count_unpublished; ?> items[0]) && property_exists($this->items[0], 'count_archived')) : ?> - + count_archived; ?> items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> - + count_trashed; ?> diff --git a/administrator/components/com_categories/views/categories/tmpl/default_batch_body.php b/administrator/components/com_categories/views/categories/tmpl/default_batch_body.php index 4110990f81b7b..d147a9c6e9dc3 100644 --- a/administrator/components/com_categories/views/categories/tmpl/default_batch_body.php +++ b/administrator/components/com_categories/views/categories/tmpl/default_batch_body.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -12,7 +12,7 @@ JHtml::_('select.option', 'c', JText::_('JLIB_HTML_BATCH_COPY')), JHtml::_('select.option', 'm', JText::_('JLIB_HTML_BATCH_MOVE')) ); -$published = $this->state->get('filter.published'); +$published = (int) $this->state->get('filter.published'); $extension = $this->escape($this->state->get('filter.extension')); ?> @@ -38,8 +38,8 @@
    @@ -55,4 +55,17 @@
    + +
    +
    +
    + + +
    +
    +
    + + diff --git a/administrator/components/com_categories/views/categories/tmpl/default_batch_footer.php b/administrator/components/com_categories/views/categories/tmpl/default_batch_footer.php index 173c85e9ee790..c847c3f434f93 100644 --- a/administrator/components/com_categories/views/categories/tmpl/default_batch_footer.php +++ b/administrator/components/com_categories/views/categories/tmpl/default_batch_footer.php @@ -3,15 +3,15 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - + + \ No newline at end of file + diff --git a/administrator/components/com_categories/views/categories/tmpl/modal.php b/administrator/components/com_categories/views/categories/tmpl/modal.php index 5c6dc125540d2..d08170fead13d 100644 --- a/administrator/components/com_categories/views/categories/tmpl/modal.php +++ b/administrator/components/com_categories/views/categories/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -23,6 +23,7 @@ JHtml::_('behavior.core'); JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); JHtml::_('formbehavior.chosen', 'select'); // Special case for the search field tooltip. @@ -112,8 +113,14 @@ $item->level)); ?> - escape($item->title); ?> - + escape($item->title); ?> + + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + + escape($item->access_level); ?> diff --git a/administrator/components/com_categories/views/categories/view.html.php b/administrator/components/com_categories/views/categories/view.html.php index 5f0c39fb1a715..c6ab6bb85d1b1 100644 --- a/administrator/components/com_categories/views/categories/view.html.php +++ b/administrator/components/com_categories/views/categories/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -118,7 +118,7 @@ public function display($tpl = null) // In article associations modal we need to remove language filter if forcing a language. if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) { - // If the language is forced we can't allow to select the language, so transform the language selector filter into an hidden field. + // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. $languageXml = new SimpleXMLElement(''); $this->filterForm->setField($languageXml, 'filter', true); @@ -184,7 +184,7 @@ protected function addToolbar() // Prepare the toolbar. JToolbarHelper::title($title, 'folder categories ' . substr($component, 4) . ($section ? "-$section" : '') . '-categories'); - if ($canDo->get('core.create') || (count($user->getAuthorisedCategories($component, 'core.create'))) > 0) + if ($canDo->get('core.create') || count($user->getAuthorisedCategories($component, 'core.create')) > 0) { JToolbarHelper::addNew('category.add'); } diff --git a/administrator/components/com_categories/views/category/tmpl/edit.php b/administrator/components/com_categories/views/category/tmpl/edit.php index fb033124e9bd4..d13d00df48363 100644 --- a/administrator/components/com_categories/views/category/tmpl/edit.php +++ b/administrator/components/com_categories/views/category/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -14,6 +14,7 @@ JHtml::_('behavior.formvalidator'); JHtml::_('behavior.keepalive'); +JHtml::_('formbehavior.chosen', '#jform_tags', null, array('placeholder_text_multiple' => JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_TAGS'))); JHtml::_('formbehavior.chosen', 'select'); $app = JFactory::getApplication(); diff --git a/administrator/components/com_categories/views/category/tmpl/edit_associations.php b/administrator/components/com_categories/views/category/tmpl/edit_associations.php index 54f4fb1d3791a..a9438c74e63ba 100644 --- a/administrator/components/com_categories/views/category/tmpl/edit_associations.php +++ b/administrator/components/com_categories/views/category/tmpl/edit_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/views/category/tmpl/edit_metadata.php b/administrator/components/com_categories/views/category/tmpl/edit_metadata.php index b5a7e8d257264..e2bc0282a3b21 100644 --- a/administrator/components/com_categories/views/category/tmpl/edit_metadata.php +++ b/administrator/components/com_categories/views/category/tmpl/edit_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/views/category/tmpl/modal.php b/administrator/components/com_categories/views/category/tmpl/modal.php index 685c65d39fa6e..a4aa546974fd7 100644 --- a/administrator/components/com_categories/views/category/tmpl/modal.php +++ b/administrator/components/com_categories/views/category/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/views/category/tmpl/modal_associations.php b/administrator/components/com_categories/views/category/tmpl/modal_associations.php index 54f4fb1d3791a..2c9a79bcc7715 100644 --- a/administrator/components/com_categories/views/category/tmpl/modal_associations.php +++ b/administrator/components/com_categories/views/category/tmpl/modal_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/views/category/tmpl/modal_extrafields.php b/administrator/components/com_categories/views/category/tmpl/modal_extrafields.php index a1e64b1bae479..f8a1dbb970075 100644 --- a/administrator/components/com_categories/views/category/tmpl/modal_extrafields.php +++ b/administrator/components/com_categories/views/category/tmpl/modal_extrafields.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/views/category/tmpl/modal_metadata.php b/administrator/components/com_categories/views/category/tmpl/modal_metadata.php index b5a7e8d257264..110b02af1eb90 100644 --- a/administrator/components/com_categories/views/category/tmpl/modal_metadata.php +++ b/administrator/components/com_categories/views/category/tmpl/modal_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/views/category/tmpl/modal_options.php b/administrator/components/com_categories/views/category/tmpl/modal_options.php index cfb84b04f1fcf..66bec43e5b6bb 100644 --- a/administrator/components/com_categories/views/category/tmpl/modal_options.php +++ b/administrator/components/com_categories/views/category/tmpl/modal_options.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_categories/views/category/view.html.php b/administrator/components/com_categories/views/category/view.html.php index 22fd60d296c98..ff7aa821de454 100644 --- a/administrator/components/com_categories/views/category/view.html.php +++ b/administrator/components/com_categories/views/category/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_categories * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -207,6 +207,11 @@ protected function addToolbar() JToolbarHelper::versions($typeAlias, $this->item->id); } + if (JLanguageAssociations::isEnabled() && JComponentHelper::isEnabled('com_associations')) + { + JToolbarHelper::custom('category.editAssociations', 'contract', 'contract', 'JTOOLBAR_ASSOCIATIONS', false, false); + } + JToolbarHelper::cancel('category.cancel', 'JTOOLBAR_CLOSE'); } diff --git a/administrator/components/com_checkin/checkin.php b/administrator/components/com_checkin/checkin.php index f0f4a61bc1567..ecabd28da8a60 100644 --- a/administrator/components/com_checkin/checkin.php +++ b/administrator/components/com_checkin/checkin.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_checkin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_checkin/checkin.xml b/administrator/components/com_checkin/checkin.xml index 8aabfb76e4763..38bd515e71a0e 100644 --- a/administrator/components/com_checkin/checkin.xml +++ b/administrator/components/com_checkin/checkin.xml @@ -3,7 +3,7 @@ com_checkin Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_checkin/controller.php b/administrator/components/com_checkin/controller.php index 035ee20e2d54c..a422d2750d2d0 100644 --- a/administrator/components/com_checkin/controller.php +++ b/administrator/components/com_checkin/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_checkin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -40,7 +40,7 @@ public function display($cachable = false, $urlparams = array()) public function checkin() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $ids = $this->input->get('cid', array(), 'array'); diff --git a/administrator/components/com_checkin/models/checkin.php b/administrator/components/com_checkin/models/checkin.php index a1e30fee3980b..d9ea57ea0804a 100644 --- a/administrator/components/com_checkin/models/checkin.php +++ b/administrator/components/com_checkin/models/checkin.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_checkin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -94,6 +94,8 @@ public function checkin($ids = array()) // This int will hold the checked item count. $results = 0; + $dispatcher = \JEventDispatcher::getInstance(); + foreach ($ids as $tn) { // Make sure we get the right tables based on prefix. @@ -111,15 +113,16 @@ public function checkin($ids = array()) $query = $db->getQuery(true) ->update($db->quoteName($tn)) - ->set('checked_out = 0') - ->set('checked_out_time = ' . $db->quote($nullDate)) - ->where('checked_out > 0'); + ->set($db->quoteName('checked_out') . ' = DEFAULT') + ->set($db->quoteName('checked_out_time') . ' = ' . $db->quote($nullDate)) + ->where($db->quoteName('checked_out') . ' > 0'); $db->setQuery($query); if ($db->execute()) { $results = $results + $db->getAffectedRows(); + $dispatcher->trigger('onAfterCheckin', array($tn)); } } diff --git a/administrator/components/com_checkin/models/forms/filter_checkin.xml b/administrator/components/com_checkin/models/forms/filter_checkin.xml index e203f51ae1af2..91d43db0d6a28 100644 --- a/administrator/components/com_checkin/models/forms/filter_checkin.xml +++ b/administrator/components/com_checkin/models/forms/filter_checkin.xml @@ -4,6 +4,7 @@ - + * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_checkin/views/checkin/view.html.php b/administrator/components/com_checkin/views/checkin/view.html.php index 2943c79484d5e..1e385b000fe57 100644 --- a/administrator/components/com_checkin/views/checkin/view.html.php +++ b/administrator/components/com_checkin/views/checkin/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_checkin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/config.php b/administrator/components/com_config/config.php index 8b53654a73aee..2bb1a44e52be1 100644 --- a/administrator/components/com_config/config.php +++ b/administrator/components/com_config/config.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/config.xml b/administrator/components/com_config/config.xml index 025af553fc887..828720f8abdaa 100644 --- a/administrator/components/com_config/config.xml +++ b/administrator/components/com_config/config.xml @@ -3,7 +3,7 @@ com_config Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_config/controller.php b/administrator/components/com_config/controller.php index 3ed2386416717..8496d04ff940e 100644 --- a/administrator/components/com_config/controller.php +++ b/administrator/components/com_config/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -12,15 +12,13 @@ /** * Config Component Controller * - * @since 1.5 - * @deprecated 4.0 + * @since 1.5 */ class ConfigController extends JControllerLegacy { /** * @var string The default view. * @since 1.6 - * @deprecated 4.0 */ protected $default_view = 'application'; @@ -33,26 +31,12 @@ class ConfigController extends JControllerLegacy * @return ConfigController This object to support chaining. * * @since 1.5 - * @deprecated 4.0 */ public function display($cachable = false, $urlparams = array()) { // Set the default view name and format from the Request. $vName = $this->input->get('view', 'application'); - try - { - JLog::add( - sprintf('%s is deprecated. Use ConfigControllerApplicationDisplay or ConfigControllerComponentDisplay instead.', __CLASS__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - if (ucfirst($vName) == 'Application') { $controller = new ConfigControllerApplicationDisplay; diff --git a/administrator/components/com_config/controller/application/cancel.php b/administrator/components/com_config/controller/application/cancel.php index 217eef0c04cb8..075a37b18516b 100644 --- a/administrator/components/com_config/controller/application/cancel.php +++ b/administrator/components/com_config/controller/application/cancel.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/controller/application/display.php b/administrator/components/com_config/controller/application/display.php index c4a6b5b9774fc..7903447ff5512 100644 --- a/administrator/components/com_config/controller/application/display.php +++ b/administrator/components/com_config/controller/application/display.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/controller/application/removeroot.php b/administrator/components/com_config/controller/application/removeroot.php index 98806f6d60f6f..2aa1e67136afe 100644 --- a/administrator/components/com_config/controller/application/removeroot.php +++ b/administrator/components/com_config/controller/application/removeroot.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_config/controller/application/save.php b/administrator/components/com_config/controller/application/save.php index 4e999538f1ec8..f680775f06732 100644 --- a/administrator/components/com_config/controller/application/save.php +++ b/administrator/components/com_config/controller/application/save.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -46,6 +46,9 @@ public function execute() $this->app->redirect('index.php'); } + // Clear the data from the session. + $this->app->setUserState('com_config.config.global.data', null); + // Set FTP credentials, if given. JClientHelper::setCredentialsFromRequest('ftp'); @@ -54,6 +57,7 @@ public function execute() // Complete data array if needed $oldData = $model->getData(); + $data = array_replace($oldData, $data); // Get request type @@ -62,7 +66,17 @@ public function execute() // Handle service requests if ($saveFormat == 'json') { - return $model->save($data); + $form = $model->getForm(); + $return = $model->validate($form, $data); + + if ($return === false) + { + $this->app->setHeader('Status', 422, true); + + return false; + } + + return $model->save($return); } // Must load after serving service-requests @@ -71,9 +85,6 @@ public function execute() // Validate the posted data. $return = $model->validate($form, $data); - // Save the posted data in the session. - $this->app->setUserState('com_config.config.global.data', $data); - // Check for validation errors. if ($return === false) { @@ -81,6 +92,9 @@ public function execute() * The validate method enqueued all messages for us, so we just need to redirect back. */ + // Save the posted data in the session. + $this->app->setUserState('com_config.config.global.data', $data); + // Redirect back to the edit screen. $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.application', false)); } @@ -89,9 +103,6 @@ public function execute() $data = $return; $return = $model->save($data); - // Save the validated data in the session. - $this->app->setUserState('com_config.config.global.data', $data); - // Check the return value. if ($return === false) { @@ -99,6 +110,9 @@ public function execute() * The save method enqueued all messages for us, so we just need to redirect back. */ + // Save the validated data in the session. + $this->app->setUserState('com_config.config.global.data', $data); + // Save failed, go back to the screen and display a notice. $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.application', false)); } diff --git a/administrator/components/com_config/controller/application/sendtestmail.php b/administrator/components/com_config/controller/application/sendtestmail.php index b4636df201912..47ae8f2d0c2f1 100644 --- a/administrator/components/com_config/controller/application/sendtestmail.php +++ b/administrator/components/com_config/controller/application/sendtestmail.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -30,7 +30,7 @@ public function execute() $this->app->sendHeaders(); // Check if user token is valid. - if (!JSession::checkToken('get')) + if (!JSession::checkToken()) { $this->app->enqueueMessage(JText::_('JINVALID_TOKEN'), 'error'); echo new JResponseJson; diff --git a/administrator/components/com_config/controller/application/store.php b/administrator/components/com_config/controller/application/store.php index ef588f3ebc8fc..470ed9c8450c7 100644 --- a/administrator/components/com_config/controller/application/store.php +++ b/administrator/components/com_config/controller/application/store.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_config/controller/component/cancel.php b/administrator/components/com_config/controller/component/cancel.php index ec42372327829..348694a608815 100644 --- a/administrator/components/com_config/controller/component/cancel.php +++ b/administrator/components/com_config/controller/component/cancel.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/controller/component/display.php b/administrator/components/com_config/controller/component/display.php index c0d7aed521f19..0359535fdf349 100644 --- a/administrator/components/com_config/controller/component/display.php +++ b/administrator/components/com_config/controller/component/display.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/controller/component/save.php b/administrator/components/com_config/controller/component/save.php index f5dd80b954ae5..37ba0fd07a780 100644 --- a/administrator/components/com_config/controller/component/save.php +++ b/administrator/components/com_config/controller/component/save.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -50,6 +50,15 @@ public function execute() $option = $this->input->get('component'); $user = JFactory::getUser(); + // Make sure com_joomlaupdate and com_privacy can only be accessed by SuperUser + if (in_array(strtolower($option), array('com_joomlaupdate', 'com_privacy')) + && !JFactory::getUser()->authorise('core.admin')) + { + $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); + + return; + } + // Check if the user is authorised to do this. if (!$user->authorise('core.admin', $option) && !$user->authorise('core.options', $option)) { @@ -120,6 +129,7 @@ public function execute() break; case 'save': + $this->app->enqueueMessage(JText::_('COM_CONFIG_SAVE_SUCCESS'), 'message'); default: $redirect = 'index.php?option=' . $option; diff --git a/administrator/components/com_config/controllers/application.php b/administrator/components/com_config/controllers/application.php index 03af706a4eac4..1e60cf853f22f 100644 --- a/administrator/components/com_config/controllers/application.php +++ b/administrator/components/com_config/controllers/application.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -36,7 +36,7 @@ public function __construct($config = array()) /** * Method to save the configuration. * - * @return bool True on success, false on failure. + * @return boolean True on success, false on failure. * * @since 1.5 * @deprecated 4.0 Use ConfigControllerApplicationSave instead. @@ -91,7 +91,7 @@ public function cancel() /** * Method to remove the root property from the configuration. * - * @return bool True on success, false on failure. + * @return boolean True on success, false on failure. * * @since 1.5 * @deprecated 4.0 Use ConfigControllerApplicationRemoveroot instead. diff --git a/administrator/components/com_config/controllers/component.php b/administrator/components/com_config/controllers/component.php index 7255f0ec903ae..4910aa694b5e2 100644 --- a/administrator/components/com_config/controllers/component.php +++ b/administrator/components/com_config/controllers/component.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/helper/config.php b/administrator/components/com_config/helper/config.php index 50b9e1f7838c2..ea0daace052f2 100644 --- a/administrator/components/com_config/helper/config.php +++ b/administrator/components/com_config/helper/config.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/model/application.php b/administrator/components/com_config/model/application.php index 17fc3f0fad3da..b3e9643654f6f 100644 --- a/administrator/components/com_config/model/application.php +++ b/administrator/components/com_config/model/application.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -19,6 +19,14 @@ */ class ConfigModelApplication extends ConfigModelForm { + /** + * Array of protected password fields from the configuration.php + * + * @var array + * @since 3.9.23 + */ + private $protectedConfigurationFields = array('password', 'secret', 'ftp_pass', 'smtppass', 'redis_server_auth', 'session_redis_server_auth'); + /** * Method to get a form object. * @@ -49,7 +57,7 @@ public function getForm($data = array(), $loadData = true) * JConfig. If configuration data has been saved in the session, that * data will be merged into the original data, overwriting it. * - * @return array An array containg all global config data. + * @return array An array containing all global config data. * * @since 1.6 */ @@ -59,6 +67,9 @@ public function getData() $config = new JConfig; $data = ArrayHelper::fromObject($config); + // Get the correct driver at runtime + $data['dbtype'] = JFactory::getDbo()->getName(); + // Prime the asset_id for the rules. $data['asset_id'] = 1; @@ -79,6 +90,12 @@ public function getData() // Merge in the session data. if (!empty($temp)) { + // $temp can sometimes be an object, and we need it to be an array + if (is_object($temp)) + { + $temp = ArrayHelper::fromObject($temp); + } + $data = array_merge($data, $temp); } @@ -97,13 +114,24 @@ public function getData() public function save($data) { $app = JFactory::getApplication(); + $dispatcher = JEventDispatcher::getInstance(); + $config = JFactory::getConfig(); + + // Try to load the values from the configuration file + foreach ($this->protectedConfigurationFields as $fieldKey) + { + if (!isset($data[$fieldKey])) + { + $data[$fieldKey] = $config->get($fieldKey); + } + } // Check that we aren't setting wrong database configuration $options = array( 'driver' => $data['dbtype'], 'host' => $data['host'], 'user' => $data['user'], - 'password' => JFactory::getConfig()->get('password'), + 'password' => $data['password'], 'database' => $data['db'], 'prefix' => $data['dbprefix'] ); @@ -184,7 +212,7 @@ public function save($data) if (!$asset->check() || !$asset->store()) { - $app->enqueueMessage(JText::_('SOME_ERROR_CODE'), 'error'); + $app->enqueueMessage($asset->getError(), 'error'); return; } @@ -215,7 +243,7 @@ public function save($data) if (!$extension->check() || !$extension->store()) { - $app->enqueueMessage(JText::_('SOME_ERROR_CODE'), 'error'); + $app->enqueueMessage($extension->getError(), 'error'); return; } @@ -394,8 +422,21 @@ public function save($data) $this->cleanCache('_system', 0); $this->cleanCache('_system', 1); + $result = $dispatcher->trigger('onApplicationBeforeSave', array($config)); + + // Store the data. + if (in_array(false, $result, true)) + { + throw new RuntimeException(JText::_('COM_CONFIG_ERROR_UNKNOWN_BEFORE_SAVING')); + } + // Write the configuration file. - return $this->writeConfigFile($config); + $result = $this->writeConfigFile($config); + + // Trigger the after save event. + $dispatcher->trigger('onApplicationAfterSave', array($config)); + + return $result; } /** @@ -410,6 +451,8 @@ public function save($data) */ public function removeroot() { + $dispatcher = JEventDispatcher::getInstance(); + // Get the previous configuration. $prev = new JConfig; $prev = ArrayHelper::fromObject($prev); @@ -418,8 +461,21 @@ public function removeroot() unset($prev['root_user']); $config = new Registry($prev); + $result = $dispatcher->trigger('onApplicationBeforeSave', array($config)); + + // Store the data. + if (in_array(false, $result, true)) + { + throw new RuntimeException(JText::_('COM_CONFIG_ERROR_UNKNOWN_BEFORE_SAVING')); + } + // Write the configuration file. - return $this->writeConfigFile($config); + $result = $this->writeConfigFile($config); + + // Trigger the after save event. + $dispatcher->trigger('onApplicationAfterSave', array($config)); + + return $result; } /** @@ -459,7 +515,13 @@ private function writeConfigFile(Registry $config) throw new RuntimeException(JText::_('COM_CONFIG_ERROR_WRITE_FAILED')); } - // Attempt to make the file unwriteable if using FTP. + // Invalidates the cached configuration file + if (function_exists('opcache_invalidate')) + { + opcache_invalidate($file); + } + + // Attempt to make the file unwriteable if NOT using FTP. if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0444')) { $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'), 'notice'); @@ -659,7 +721,6 @@ public function storePermissions($permission = null) return false; } - // All checks done. $result = array( 'text' => '', @@ -779,21 +840,21 @@ public function storePermissions($permission = null) $result['text'] = JText::_('JLIB_RULES_ALLOWED_INHERITED'); } - // Second part: Overwrite the calculated permissions labels if there is an explicity permission in the current group. + // Second part: Overwrite the calculated permissions labels if there is an explicit permission in the current group. /** - * @to do: incorect info + * @todo: incorrect info * If a component has a permission that doesn't exists in global config (ex: frontend editing in com_modules) by default * we get "Not Allowed (Inherited)" when we should get "Not Allowed (Default)". */ - // If there is an explicity permission "Not Allowed". Calculated permission is "Not Allowed". + // If there is an explicit permission "Not Allowed". Calculated permission is "Not Allowed". if ($assetRule === false) { $result['class'] = 'label label-important'; $result['text'] = JText::_('JLIB_RULES_NOT_ALLOWED'); } - // If there is an explicity permission is "Allowed". Calculated permission is "Allowed". + // If there is an explicit permission is "Allowed". Calculated permission is "Allowed". elseif ($assetRule === true) { $result['class'] = 'label label-success'; @@ -847,12 +908,12 @@ public function storePermissions($permission = null) public function sendTestMail() { // Set the new values to test with the current settings - $app = JFactory::getApplication(); - $input = $app->input; + $app = JFactory::getApplication(); + $input = $app->input; + $smtppass = $input->get('smtppass', null, 'RAW'); $app->set('smtpauth', $input->get('smtpauth')); $app->set('smtpuser', $input->get('smtpuser', '', 'STRING')); - $app->set('smtppass', $input->get('smtppass', '', 'RAW')); $app->set('smtphost', $input->get('smtphost')); $app->set('smtpsecure', $input->get('smtpsecure')); $app->set('smtpport', $input->get('smtpport')); @@ -861,6 +922,12 @@ public function sendTestMail() $app->set('mailer', $input->get('mailer')); $app->set('mailonline', $input->get('mailonline')); + // Use smtppass only if it was submitted + if ($smtppass !== null) + { + $app->set('smtppass', $smtppass); + } + $mail = JFactory::getMailer(); // Prepare email and send try to send it diff --git a/administrator/components/com_config/model/component.php b/administrator/components/com_config/model/component.php index 120533f97735b..6d2c1793f7d25 100644 --- a/administrator/components/com_config/model/component.php +++ b/administrator/components/com_config/model/component.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -153,6 +153,11 @@ public function save($data) // Save the rules. if (isset($data['params']) && isset($data['params']['rules'])) { + if (!JFactory::getUser()->authorise('core.admin', $data['option'])) + { + throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + } + $rules = new JAccessRules($data['params']['rules']); $asset = JTable::getInstance('asset'); diff --git a/administrator/components/com_config/model/field/configcomponents.php b/administrator/components/com_config/model/field/configcomponents.php index 2e3f66a59cfe9..439e18c8e9d7a 100644 --- a/administrator/components/com_config/model/field/configcomponents.php +++ b/administrator/components/com_config/model/field/configcomponents.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; use Joomla\Utilities\ArrayHelper; diff --git a/administrator/components/com_config/model/field/filters.php b/administrator/components/com_config/model/field/filters.php index a2ee15192b8d8..8c665b18905dd 100644 --- a/administrator/components/com_config/model/field/filters.php +++ b/administrator/components/com_config/model/field/filters.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; /** * Text Filters form field. @@ -35,6 +35,48 @@ class JFormFieldFilters extends JFormField */ protected function getInput() { + // Load Framework + JHtml::_('jquery.framework'); + + // Add translation string for notification + JText::script('COM_CONFIG_TEXT_FILTERS_NOTE'); + + // Add Javascript + $doc = JFactory::getDocument(); + $doc->addScriptDeclaration(' + jQuery( document ).ready(function( $ ) { + $("#filter-config select").change(function() { + var currentFilter = $(this).children("option:selected").val(); + + if($(this).children("option:selected").val() === "NONE") { + var child = $("#filter-config select[data-parent=" + $(this).attr("data-id") + "]"); + + while(child.length !== 0) { + if(child.children("option:selected").val() !== "NONE") { + alert(Joomla.JText._("COM_CONFIG_TEXT_FILTERS_NOTE")); + break; + } + + child = $("#filter-config select[data-parent=" + child.attr("data-id") + "]"); + } + + return; + } + + var parent = $("#filter-config select[data-id=" + $(this).attr("data-parent") + "]"); + + while(parent.length !== 0) { + if(parent.children("option:selected").val() === "NONE") { + alert(Joomla.JText._("COM_CONFIG_TEXT_FILTERS_NOTE")); + break; + } + + parent = $("#filter-config select[data-id=" + parent.attr("data-parent") + "]") + } + }); + }); + '); + // Get the available user groups. $groups = $this->getUserGroups(); @@ -51,16 +93,13 @@ protected function getInput() $html[] = ' ' . JText::_('JGLOBAL_FILTER_GROUPS_LABEL') . ''; $html[] = ' '; $html[] = ' '; - $html[] = ' ' - . JText::_('JGLOBAL_FILTER_TYPE_LABEL') . ''; + $html[] = ' ' . JText::_('JGLOBAL_FILTER_TYPE_LABEL') . ''; $html[] = ' '; $html[] = ' '; - $html[] = ' ' - . JText::_('JGLOBAL_FILTER_TAGS_LABEL') . ''; + $html[] = ' ' . JText::_('JGLOBAL_FILTER_TAGS_LABEL') . ''; $html[] = ' '; $html[] = ' '; - $html[] = ' ' - . JText::_('JGLOBAL_FILTER_ATTRIBUTES_LABEL') . ''; + $html[] = ' ' . JText::_('JGLOBAL_FILTER_ATTRIBUTES_LABEL') . ''; $html[] = ' '; $html[] = ' '; $html[] = ' '; @@ -88,6 +127,8 @@ protected function getInput() $html[] = ' '; $html[] = ' + + + + +
    @@ -382,6 +408,7 @@ showon="ftp_enable:1" autocomplete="off" size="25" + lock="true" /> + + + + +
    @@ -598,7 +639,6 @@ hint="25" validate="number" filter="integer" - required="true" size="5" /> @@ -650,6 +690,7 @@ filter="raw" autocomplete="off" size="30" + lock="true" /> @@ -685,10 +726,10 @@ description="JFIELD_METADATA_ROBOTS_DESC" default="" > - - - - + + + + + + + + + + + + + + + + - -
    * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/models/component.php b/administrator/components/com_config/models/component.php index b6c2b8f7819c1..a65afde093faa 100644 --- a/administrator/components/com_config/models/component.php +++ b/administrator/components/com_config/models/component.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/html.php b/administrator/components/com_config/view/application/html.php index 6b656087528c2..d8ce53cca4f4c 100644 --- a/administrator/components/com_config/view/application/html.php +++ b/administrator/components/com_config/view/application/html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/json.php b/administrator/components/com_config/view/application/json.php index 9e4b212957a89..11cc517aa7194 100644 --- a/administrator/components/com_config/view/application/json.php +++ b/administrator/components/com_config/view/application/json.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default.php b/administrator/components/com_config/view/application/tmpl/default.php index b0cf7d1113527..fb1e53e6f3962 100644 --- a/administrator/components/com_config/view/application/tmpl/default.php +++ b/administrator/components/com_config/view/application/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_cache.php b/administrator/components/com_config/view/application/tmpl/default_cache.php index 801303c25b1a4..b65ef93ee40ee 100644 --- a/administrator/components/com_config/view/application/tmpl/default_cache.php +++ b/administrator/components/com_config/view/application/tmpl/default_cache.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_cookie.php b/administrator/components/com_config/view/application/tmpl/default_cookie.php index 1a12b54946010..9ef7ba048858a 100644 --- a/administrator/components/com_config/view/application/tmpl/default_cookie.php +++ b/administrator/components/com_config/view/application/tmpl/default_cookie.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_database.php b/administrator/components/com_config/view/application/tmpl/default_database.php index 9361dea9bf596..4825985047613 100644 --- a/administrator/components/com_config/view/application/tmpl/default_database.php +++ b/administrator/components/com_config/view/application/tmpl/default_database.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_debug.php b/administrator/components/com_config/view/application/tmpl/default_debug.php index d6a72c9578e62..4af1dfb71ebcf 100644 --- a/administrator/components/com_config/view/application/tmpl/default_debug.php +++ b/administrator/components/com_config/view/application/tmpl/default_debug.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_filters.php b/administrator/components/com_config/view/application/tmpl/default_filters.php index f6126af0ecc3f..e66b720d0803b 100644 --- a/administrator/components/com_config/view/application/tmpl/default_filters.php +++ b/administrator/components/com_config/view/application/tmpl/default_filters.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -12,4 +12,4 @@ $this->name = JText::_('COM_CONFIG_TEXT_FILTER_SETTINGS'); $this->fieldsname = 'filters'; $this->description = JText::_('COM_CONFIG_TEXT_FILTERS_DESC'); -echo JLayoutHelper::render('joomla.content.options_default', $this); +echo JLayoutHelper::render('joomla.content.text_filters', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_ftp.php b/administrator/components/com_config/view/application/tmpl/default_ftp.php index a0fffe48ecc0e..0c46bd8665081 100644 --- a/administrator/components/com_config/view/application/tmpl/default_ftp.php +++ b/administrator/components/com_config/view/application/tmpl/default_ftp.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_ftplogin.php b/administrator/components/com_config/view/application/tmpl/default_ftplogin.php index 18695365451c1..5b80539fb27fa 100644 --- a/administrator/components/com_config/view/application/tmpl/default_ftplogin.php +++ b/administrator/components/com_config/view/application/tmpl/default_ftplogin.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_locale.php b/administrator/components/com_config/view/application/tmpl/default_locale.php index 1774bb3828194..cfea3dce4ec71 100644 --- a/administrator/components/com_config/view/application/tmpl/default_locale.php +++ b/administrator/components/com_config/view/application/tmpl/default_locale.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_mail.php b/administrator/components/com_config/view/application/tmpl/default_mail.php index 8b7342ebebb68..92451eada8b08 100644 --- a/administrator/components/com_config/view/application/tmpl/default_mail.php +++ b/administrator/components/com_config/view/application/tmpl/default_mail.php @@ -3,12 +3,13 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +JHtml::_('jquery.token'); JHtml::_('script', 'system/sendtestmail.js', array('version' => 'auto', 'relative' => true)); // Load JavaScript message titles @@ -25,7 +26,7 @@ JText::script('JLIB_JS_AJAX_ERROR_TIMEOUT'); // Ajax request data. -$ajaxUri = JRoute::_('index.php?option=com_config&task=config.sendtestmail.application&format=json&' . JSession::getFormToken() . '=1'); +$ajaxUri = JRoute::_('index.php?option=com_config&task=config.sendtestmail.application&format=json'); $this->name = JText::_('COM_CONFIG_MAIL_SETTINGS'); $this->fieldsname = 'mail'; diff --git a/administrator/components/com_config/view/application/tmpl/default_metadata.php b/administrator/components/com_config/view/application/tmpl/default_metadata.php index 3a55cf5d20c02..0850dd815826a 100644 --- a/administrator/components/com_config/view/application/tmpl/default_metadata.php +++ b/administrator/components/com_config/view/application/tmpl/default_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_navigation.php b/administrator/components/com_config/view/application/tmpl/default_navigation.php index 5c1224f168844..c6ef2d1667515 100644 --- a/administrator/components/com_config/view/application/tmpl/default_navigation.php +++ b/administrator/components/com_config/view/application/tmpl/default_navigation.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_permissions.php b/administrator/components/com_config/view/application/tmpl/default_permissions.php index 0110c017863ca..dc6f159601603 100644 --- a/administrator/components/com_config/view/application/tmpl/default_permissions.php +++ b/administrator/components/com_config/view/application/tmpl/default_permissions.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_proxy.php b/administrator/components/com_config/view/application/tmpl/default_proxy.php index 528025e522c76..d5d15fa58b8eb 100644 --- a/administrator/components/com_config/view/application/tmpl/default_proxy.php +++ b/administrator/components/com_config/view/application/tmpl/default_proxy.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2014 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_seo.php b/administrator/components/com_config/view/application/tmpl/default_seo.php index 7a65e47626868..d645c5d2623f1 100644 --- a/administrator/components/com_config/view/application/tmpl/default_seo.php +++ b/administrator/components/com_config/view/application/tmpl/default_seo.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_server.php b/administrator/components/com_config/view/application/tmpl/default_server.php index 1fab0987b7a0e..2f495179eb663 100644 --- a/administrator/components/com_config/view/application/tmpl/default_server.php +++ b/administrator/components/com_config/view/application/tmpl/default_server.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_session.php b/administrator/components/com_config/view/application/tmpl/default_session.php index c34c46f51138b..c067b36fbd07d 100644 --- a/administrator/components/com_config/view/application/tmpl/default_session.php +++ b/administrator/components/com_config/view/application/tmpl/default_session.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_site.php b/administrator/components/com_config/view/application/tmpl/default_site.php index 5cd4d6cfbc01d..c8cfdbff2796b 100644 --- a/administrator/components/com_config/view/application/tmpl/default_site.php +++ b/administrator/components/com_config/view/application/tmpl/default_site.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/application/tmpl/default_system.php b/administrator/components/com_config/view/application/tmpl/default_system.php index 91cc59ded441f..4f96a677aea50 100644 --- a/administrator/components/com_config/view/application/tmpl/default_system.php +++ b/administrator/components/com_config/view/application/tmpl/default_system.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/component/html.php b/administrator/components/com_config/view/component/html.php index c6e0f5f06e9ed..d18e9688dd57e 100644 --- a/administrator/components/com_config/view/component/html.php +++ b/administrator/components/com_config/view/component/html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -98,6 +98,11 @@ protected function addToolbar() JToolbarHelper::divider(); JToolbarHelper::cancel('config.cancel.component'); JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_COMPONENTS_' . $this->currentComponent . '_OPTIONS'); + + $helpUrl = $this->form->getData()->get('helpURL'); + $helpKey = (string) $this->form->getXml()->config->help['key']; + $helpKey = $helpKey ?: 'JHELP_COMPONENTS_' . strtoupper($this->currentComponent) . '_OPTIONS'; + + JToolbarHelper::help($helpKey, (boolean) $helpUrl, null, $this->currentComponent); } } diff --git a/administrator/components/com_config/view/component/tmpl/default.php b/administrator/components/com_config/view/component/tmpl/default.php index 5b0d347e7a98d..b04c1c6c9130c 100644 --- a/administrator/components/com_config/view/component/tmpl/default.php +++ b/administrator/components/com_config/view/component/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_config/view/component/tmpl/default_navigation.php b/administrator/components/com_config/view/component/tmpl/default_navigation.php index cc4ca57a43c1c..e9875ea40655a 100644 --- a/administrator/components/com_config/view/component/tmpl/default_navigation.php +++ b/administrator/components/com_config/view/component/tmpl/default_navigation.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_config * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/config.xml b/administrator/components/com_contact/config.xml index 3bc8da197b319..9d2c4f19d1f3f 100644 --- a/administrator/components/com_contact/config.xml +++ b/administrator/components/com_contact/config.xml @@ -45,7 +45,7 @@ @@ -121,6 +122,7 @@ description="COM_CONTACT_FIELD_PARAMS_CONTACT_POSITION_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -133,6 +135,7 @@ description="COM_CONTACT_FIELD_PARAMS_CONTACT_E_MAIL_DESC" default="0" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -144,7 +147,7 @@ label="COM_CONTACT_FIELD_PARAMS_ADD_MAILTO_LINK_LABEL" description="COM_CONTACT_FIELD_PARAMS_ADD_MAILTO_LINK_DESC" class="btn-group btn-group-yesno" - showon="show_email:1" + showon="show_info:1[AND]show_email:1" default="1" > @@ -158,6 +161,7 @@ description="COM_CONTACT_FIELD_PARAMS_STREET_ADDRESS_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -170,6 +174,7 @@ description="COM_CONTACT_FIELD_PARAMS_TOWN-SUBURB_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -182,6 +187,7 @@ description="COM_CONTACT_FIELD_PARAMS_STATE-COUNTY_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -194,6 +200,7 @@ description="COM_CONTACT_FIELD_PARAMS_POST-ZIP_CODE_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -206,6 +213,7 @@ description="COM_CONTACT_FIELD_PARAMS_COUNTRY_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -218,6 +226,7 @@ description="COM_CONTACT_FIELD_PARAMS_TELEPHONE_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -230,6 +239,7 @@ description="COM_CONTACT_FIELD_PARAMS_MOBILE_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -242,6 +252,7 @@ description="COM_CONTACT_FIELD_PARAMS_FAX_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -254,6 +265,7 @@ description="COM_CONTACT_FIELD_PARAMS_WEBPAGE_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > @@ -266,11 +278,21 @@ description="COM_CONTACT_FIELD_PARAMS_SHOW_IMAGE_DESC" default="1" class="btn-group btn-group-yesno" + showon="show_info:1" > + + JHIDE - - @@ -909,11 +922,10 @@ type="plugins" label="COM_CONTACT_FIELD_CAPTCHA_LABEL" description="COM_CONTACT_FIELD_CAPTCHA_DESC" - default="" folder="captcha" filter="cmd" + useglobal="true" > - @@ -934,7 +946,7 @@ type="radio" label="COM_CONTACT_FIELD_EMAIL_EMAIL_COPY_LABEL" description="COM_CONTACT_FIELD_EMAIL_EMAIL_COPY_DESC" - default="1" + default="0" class="btn-group btn-group-yesno" showon="show_email_form:1" > @@ -1019,6 +1031,12 @@ description="COM_CONTACT_CONFIG_INTEGRATION_SETTINGS_DESC" > + + JHIDE + + + + + + + + + + + + + + * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/contact.xml b/administrator/components/com_contact/contact.xml index bf820c75eead8..b5fe70cc5d5fc 100644 --- a/administrator/components/com_contact/contact.xml +++ b/administrator/components/com_contact/contact.xml @@ -3,7 +3,7 @@ com_contact Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -24,7 +24,6 @@ contact.php controller.php - metadata.xml router.php helpers models @@ -52,7 +51,6 @@ contact.php controller.php controllers - elements helpers models tables diff --git a/administrator/components/com_contact/controller.php b/administrator/components/com_contact/controller.php index 963f05abc8b64..031d3907bcc1f 100644 --- a/administrator/components/com_contact/controller.php +++ b/administrator/components/com_contact/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/controllers/ajax.json.php b/administrator/components/com_contact/controllers/ajax.json.php new file mode 100644 index 0000000000000..d7896a4197c8e --- /dev/null +++ b/administrator/components/com_contact/controllers/ajax.json.php @@ -0,0 +1,87 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\LanguageHelper; + +/** + * The contact controller for ajax requests + * + * @since 3.9.0 + */ +class ContactControllerAjax extends JControllerLegacy +{ + /** + * Method to fetch associations of a contact + * + * The method assumes that the following http parameters are passed in an Ajax Get request: + * token: the form token + * assocId: the id of the contact whose associations are to be returned + * excludeLang: the association for this language is to be excluded + * + * @return null + * + * @since 3.9.0 + */ + public function fetchAssociations() + { + if (!JSession::checkToken('get')) + { + echo new JResponseJson(null, JText::_('JINVALID_TOKEN'), true); + } + else + { + $input = JFactory::getApplication()->input; + + $assocId = $input->getInt('assocId', 0); + + if ($assocId == 0) + { + echo new JResponseJson(null, JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'assocId'), true); + + return; + } + + $excludeLang = $input->get('excludeLang', '', 'STRING'); + + $associations = JLanguageAssociations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', (int) $assocId); + + unset($associations[$excludeLang]); + + // Add the title to each of the associated records + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_contact/tables'); + $contactTable = JTable::getInstance('Contact', 'ContactTable'); + + foreach ($associations as $lang => $association) + { + $contactTable->load($association->id); + $associations[$lang]->title = $contactTable->name; + } + + $countContentLanguages = count(LanguageHelper::getContentLanguages(array(0, 1))); + + if (count($associations) == 0) + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE'); + } + elseif ($countContentLanguages > count($associations) + 2) + { + $tags = implode(', ', array_keys($associations)); + $message = JText::sprintf('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME', $tags); + } + else + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL'); + } + + echo new JResponseJson($associations, $message); + } + } +} diff --git a/administrator/components/com_contact/controllers/contact.php b/administrator/components/com_contact/controllers/contact.php index 088f51b5b4958..988aacea7b754 100644 --- a/administrator/components/com_contact/controllers/contact.php +++ b/administrator/components/com_contact/controllers/contact.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -40,7 +40,7 @@ protected function allowAdd($data = array()) if ($allow === null) { - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return parent::allowAdd($data); } @@ -96,7 +96,7 @@ protected function allowEdit($data = array(), $key = 'id') */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Set the model /** @var ContactModelContact $model */ diff --git a/administrator/components/com_contact/controllers/contacts.php b/administrator/components/com_contact/controllers/contacts.php index c8c63f1231763..5e387224bd472 100644 --- a/administrator/components/com_contact/controllers/contacts.php +++ b/administrator/components/com_contact/controllers/contacts.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -43,7 +43,7 @@ public function __construct($config = array()) public function featured() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $ids = $this->input->get('cid', array(), 'array'); $values = array('featured' => 1, 'unfeatured' => 0); diff --git a/administrator/components/com_contact/helpers/associations.php b/administrator/components/com_contact/helpers/associations.php index c2070d843b2ac..0af7dd66ae863 100644 --- a/administrator/components/com_contact/helpers/associations.php +++ b/administrator/components/com_contact/helpers/associations.php @@ -3,13 +3,13 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Association\AssociationExtensionHelper; JTable::addIncludePath(__DIR__ . '/../tables'); @@ -18,7 +18,7 @@ * * @since 3.7.0 */ -class ContactAssociationsHelper extends JAssociationExtensionHelper +class ContactAssociationsHelper extends AssociationExtensionHelper { /** * The extension name diff --git a/administrator/components/com_contact/helpers/contact.php b/administrator/components/com_contact/helpers/contact.php index ccdec780130c5..abf1a99e22a97 100644 --- a/administrator/components/com_contact/helpers/contact.php +++ b/administrator/components/com_contact/helpers/contact.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -57,7 +57,7 @@ public static function addSubmenu($vName) /** * Adds Count Items for Category Manager. * - * @param stdClass[] &$items The contact category objects + * @param stdClass[] &$items The category objects * * @return stdClass[] * @@ -65,53 +65,20 @@ public static function addSubmenu($vName) */ public static function countItems(&$items) { - $db = JFactory::getDbo(); - - foreach ($items as $item) - { - $item->count_trashed = 0; - $item->count_archived = 0; - $item->count_unpublished = 0; - $item->count_published = 0; - $query = $db->getQuery(true); - $query->select('published AS state, count(*) AS count') - ->from($db->qn('#__contact_details')) - ->where('catid = ' . (int) $item->id) - ->group('published'); - $db->setQuery($query); - $contacts = $db->loadObjectList(); - - foreach ($contacts as $contact) - { - if ($contact->state == 1) - { - $item->count_published = $contact->count; - } - - if ($contact->state == 0) - { - $item->count_unpublished = $contact->count; - } - - if ($contact->state == 2) - { - $item->count_archived = $contact->count; - } - - if ($contact->state == -2) - { - $item->count_trashed = $contact->count; - } - } - } + $config = (object) array( + 'related_tbl' => 'contact_details', + 'state_col' => 'published', + 'group_col' => 'catid', + 'relation_type' => 'category_or_group', + ); - return $items; + return parent::countRelations($items, $config); } /** * Adds Count Items for Tag Manager. * - * @param stdClass[] &$items The banner tag objects + * @param stdClass[] &$items The tag objects * @param string $extension The name of the active view. * * @return stdClass[] @@ -120,60 +87,18 @@ public static function countItems(&$items) */ public static function countTagItems(&$items, $extension) { - $db = JFactory::getDbo(); - $parts = explode('.', $extension); - $section = null; - if (count($parts) > 1) - { - $section = $parts[1]; - } - $join = $db->qn('#__contact_details') . ' AS c ON ct.content_item_id=c.id'; - if ($section === 'category') - { - $join = $db->qn('#__categories') . ' AS c ON ct.content_item_id=c.id'; - } - foreach ($items as $item) - { - $item->count_trashed = 0; - $item->count_archived = 0; - $item->count_unpublished = 0; - $item->count_published = 0; - $query = $db->getQuery(true); - $query->select('published as state, count(*) AS count') - ->from($db->qn('#__contentitem_tag_map') . 'AS ct ') - ->where('ct.tag_id = ' . (int) $item->id) - ->where('ct.type_alias =' . $db->q($extension)) - ->join('LEFT', $join) - ->group('published'); - - $db->setQuery($query); - $contacts = $db->loadObjectList(); - - foreach ($contacts as $contact) - { - if ($contact->state == 1) - { - $item->count_published = $contact->count; - } - - if ($contact->state == 0) - { - $item->count_unpublished = $contact->count; - } - - if ($contact->state == 2) - { - $item->count_archived = $contact->count; - } - - if ($contact->state == -2) - { - $item->count_trashed = $contact->count; - } - } - } + $parts = explode('.', $extension); + $section = count($parts) > 1 ? $parts[1] : null; + + $config = (object) array( + 'related_tbl' => ($section === 'category' ? 'categories' : 'contact_details'), + 'state_col' => 'published', + 'group_col' => 'tag_id', + 'extension' => $extension, + 'relation_type' => 'tag_assigments', + ); - return $items; + return parent::countRelations($items, $config); } /** @@ -195,6 +120,12 @@ public static function validateSection($section, $item) $section = 'mail'; } + if (JFactory::getApplication()->isClient('site') && $section == 'category') + { + // The contact form needs to be the mail section + $section = 'contact'; + } + if ($section != 'mail' && $section != 'contact') { // We don't know other sections diff --git a/administrator/components/com_contact/helpers/html/contact.php b/administrator/components/com_contact/helpers/html/contact.php index 52a9814fd53df..43ffdf6300442 100644 --- a/administrator/components/com_contact/helpers/html/contact.php +++ b/administrator/components/com_contact/helpers/html/contact.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -51,6 +51,7 @@ public static function association($contactid) ->select('cat.title as category_title') ->join('LEFT', '#__categories as cat ON cat.id=c.catid') ->where('c.id IN (' . implode(',', array_values($associations)) . ')') + ->where('c.id != ' . $contactid) ->join('LEFT', '#__languages as l ON c.language=l.lang_code') ->select('l.image') ->select('l.title as language_title'); @@ -100,7 +101,7 @@ public static function association($contactid) * * @since 1.6 */ - public static function featured($value = 0, $i, $canChange = true) + public static function featured($value = 0, $i = 0, $canChange = true) { // Array of image, task, title, action diff --git a/administrator/components/com_contact/models/contact.php b/administrator/components/com_contact/models/contact.php index 8795988f3aa3e..b1a2ac78e9745 100644 --- a/administrator/components/com_contact/models/contact.php +++ b/administrator/components/com_contact/models/contact.php @@ -3,14 +3,13 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Registry\Registry; -use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; JLoader::register('ContactHelper', JPATH_ADMINISTRATOR . '/components/com_contact/helpers/contact.php'); @@ -57,101 +56,6 @@ class ContactModelContact extends JModelAdmin 'user_id' => 'batchUser', ); - /** - * Batch copy items to a new category or current. - * - * @param integer $value The new category. - * @param array $pks An array of row IDs. - * @param array $contexts An array of item contexts. - * - * @return mixed An array of new IDs on success, boolean false on failure. - * - * @since 11.1 - */ - protected function batchCopy($value, $pks, $contexts) - { - $categoryId = (int) $value; - - $newIds = array(); - - if (!parent::checkCategoryId($categoryId)) - { - return false; - } - - // Parent exists so we proceed - while (!empty($pks)) - { - // Pop the first ID off the stack - $pk = array_shift($pks); - - $this->table->reset(); - - // Check that the row actually exists - if (!$this->table->load($pk)) - { - if ($error = $this->table->getError()) - { - // Fatal error - $this->setError($error); - - return false; - } - else - { - // Not fatal error - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); - continue; - } - } - - // Alter the title & alias - $data = $this->generateNewTitle($categoryId, $this->table->alias, $this->table->name); - $this->table->name = $data['0']; - $this->table->alias = $data['1']; - - // Reset the ID because we are making a copy - $this->table->id = 0; - - // New category ID - $this->table->catid = $categoryId; - - // Unpublish because we are making a copy - $this->table->published = 0; - - // TODO: Deal with ordering? - - // Check the row. - if (!$this->table->check()) - { - $this->setError($this->table->getError()); - - return false; - } - - $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); - - // Store the row. - if (!$this->table->store()) - { - $this->setError($this->table->getError()); - - return false; - } - - // Get the new item ID - $newId = $this->table->get('id'); - - // Add the new ID to the array - $newIds[$pk] = $newId; - } - - // Clean the cache - $this->cleanCache(); - - return $newIds; - } - /** * Batch change a linked user. * @@ -207,15 +111,12 @@ protected function batchUser($value, $pks, $contexts) */ protected function canDelete($record) { - if (!empty($record->id)) + if (empty($record->id) || $record->published != -2) { - if ($record->published != -2) - { - return false; - } - - return JFactory::getUser()->authorise('core.delete', 'com_contact.category.' . (int) $record->catid); + return false; } + + return JFactory::getUser()->authorise('core.delete', 'com_contact.category.' . (int) $record->catid); } /** @@ -267,7 +168,7 @@ public function getTable($type = 'Contact', $prefix = 'ContactTable', $config = */ public function getForm($data = array(), $loadData = true) { - JForm::addFieldPath('JPATH_ADMINISTRATOR/components/com_users/models/fields'); + JForm::addFieldPath(JPATH_ADMINISTRATOR . '/components/com_users/models/fields'); // Get the form. $form = $this->loadForm('com_contact.contact', 'contact', array('control' => 'jform', 'load_data' => $loadData)); @@ -386,20 +287,22 @@ public function save($data) JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - // Cast catid to integer for comparison - $catid = (int) $data['catid']; + // Create new category, if needed. + $createCategory = true; - // Check if New Category exists - if ($catid > 0) + // If category ID is provided, check if it's valid. + if (is_numeric($data['catid']) && $data['catid']) { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_contact'); + $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_contact'); } // Save New Category - if ($catid == 0 && $this->canCreateCategory()) + if ($createCategory && $this->canCreateCategory()) { $table = array(); - $table['title'] = $data['catid']; + + // Remove #new# prefix, if exists. + $table['title'] = strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid']; $table['parent_id'] = 1; $table['extension'] = 'com_contact'; $table['language'] = $data['language']; @@ -533,6 +436,9 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') if ($this->canCreateCategory()) { $form->setFieldAttribute('catid', 'allowAdd', 'true'); + + // Add a prefix for categories created on the fly. + $form->setFieldAttribute('catid', 'customPrefix', '#new#'); } // Association contact items @@ -560,6 +466,7 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $field->addAttribute('new', 'true'); $field->addAttribute('edit', 'true'); $field->addAttribute('clear', 'true'); + $field->addAttribute('propagate', 'true'); } $form->load($addform, false); @@ -621,43 +528,41 @@ public function featured($pks, $value = 0) } /** - * Method to change the title & alias. - * - * @param integer $category_id The id of the parent. - * @param string $alias The alias. - * @param string $name The title. + * Is the user allowed to create an on the fly category? * - * @return array Contains the modified title and alias. + * @return boolean * - * @since 3.1 + * @since 3.6.1 */ - protected function generateNewTitle($category_id, $alias, $name) + private function canCreateCategory() { - // Alter the title & alias - $table = $this->getTable(); - - while ($table->load(array('alias' => $alias, 'catid' => $category_id))) - { - if ($name == $table->name) - { - $name = StringHelper::increment($name); - } - - $alias = StringHelper::increment($alias, 'dash'); - } - - return array($name, $alias); + return JFactory::getUser()->authorise('core.create', 'com_contact'); } /** - * Is the user allowed to create an on the fly category? + * Method to validate the form data. * - * @return boolean + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. * - * @since 3.6.1 + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.25 */ - private function canCreateCategory() + public function validate($form, $data, $group = null) { - return JFactory::getUser()->authorise('core.create', 'com_contact'); + // Don't allow to change the users if not allowed to access com_users. + if (!JFactory::getUser()->authorise('core.manage', 'com_users')) + { + if (isset($data['created_by'])) + { + unset($data['created_by']); + } + } + + return parent::validate($form, $data, $group); } } diff --git a/administrator/components/com_contact/models/contacts.php b/administrator/components/com_contact/models/contacts.php index 4604a36f46674..cf77f3b554080 100644 --- a/administrator/components/com_contact/models/contacts.php +++ b/administrator/components/com_contact/models/contacts.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -131,7 +131,7 @@ protected function getStoreId($id = '') // Compile the store id. $id .= ':' . $this->getState('filter.search'); $id .= ':' . $this->getState('filter.published'); - $id .= ':' . $this->getState('filter.category_id'); + $id .= ':' . serialize($this->getState('filter.category_id')); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.language'); $id .= ':' . $this->getState('filter.tag'); @@ -214,46 +214,18 @@ protected function getListQuery() if ($assoc) { - $query->select('COUNT(' . $db->quoteName('asso2.id') . ') > 1 as ' . $db->quoteName('association')) - ->join( - 'LEFT', - $db->quoteName('#__associations', 'asso') . ' ON ' . $db->quoteName('asso.id') . ' = ' . $db->quoteName('a.id') - . ' AND ' . $db->quoteName('asso.context') . ' = ' . $db->quote('com_contact.item') - ) - ->join( - 'LEFT', - $db->quoteName('#__associations', 'asso2') . ' ON ' . $db->quoteName('asso2.key') . ' = ' . $db->quoteName('asso.key') - ) - ->group( - $db->quoteName( - array( - 'a.id', - 'a.name', - 'a.alias', - 'a.checked_out', - 'a.checked_out_time', - 'a.catid', - 'a.user_id', - 'a.published', - 'a.access', - 'a.created', - 'a.created_by', - 'a.ordering', - 'a.featured', - 'a.language', - 'a.publish_up', - 'a.publish_down', - 'ul.name' , - 'ul.email', - 'l.title' , - 'l.image' , - 'uc.name' , - 'ag.title' , - 'c.title', - 'c.level' - ) + $subQuery = $db->getQuery(true) + ->select('COUNT(' . $db->quoteName('asso1.id') . ') > 1') + ->from($db->quoteName('#__associations', 'asso1')) + ->join('INNER', $db->quoteName('#__associations', 'asso2') . ' ON ' . $db->quoteName('asso1.key') . ' = ' . $db->quoteName('asso2.key')) + ->where( + array( + $db->quoteName('asso1.id') . ' = ' . $db->quoteName('a.id'), + $db->quoteName('asso1.context') . ' = ' . $db->quote('com_contact.item'), ) ); + + $query->select('(' . $subQuery . ') AS ' . $db->quoteName('association')); } // Filter by access level. @@ -281,18 +253,6 @@ protected function getListQuery() $query->where('(' . $db->quoteName('a.published') . ' = 0 OR ' . $db->quoteName('a.published') . ' = 1)'); } - // Filter by a single or group of categories. - $categoryId = $this->getState('filter.category_id'); - - if (is_numeric($categoryId)) - { - $query->where($db->quoteName('a.catid') . ' = ' . (int) $categoryId); - } - elseif (is_array($categoryId)) - { - $query->where($db->quoteName('a.catid') . ' IN (' . implode(',', ArrayHelper::toInteger($categoryId)) . ')'); - } - // Filter by search in name. $search = $this->getState('filter.search'); @@ -331,8 +291,36 @@ protected function getListQuery() ); } - // Filter on the level. - if ($level = $this->getState('filter.level')) + // Filter by categories and by level + $categoryId = $this->getState('filter.category_id', array()); + $level = $this->getState('filter.level'); + + if (!is_array($categoryId)) + { + $categoryId = $categoryId ? array($categoryId) : array(); + } + + // Case: Using both categories filter and by level filter + if (count($categoryId)) + { + $categoryId = ArrayHelper::toInteger($categoryId); + $categoryTable = JTable::getInstance('Category', 'JTable'); + $subCatItemsWhere = array(); + + foreach ($categoryId as $filter_catid) + { + $categoryTable->load($filter_catid); + $subCatItemsWhere[] = '(' . + ($level ? 'c.level <= ' . ((int) $level + (int) $categoryTable->level - 1) . ' AND ' : '') . + 'c.lft >= ' . (int) $categoryTable->lft . ' AND ' . + 'c.rgt <= ' . (int) $categoryTable->rgt . ')'; + } + + $query->where('(' . implode(' OR ', $subCatItemsWhere) . ')'); + } + + // Case: Using only the by level filter + elseif ($level) { $query->where('c.level <= ' . (int) $level); } diff --git a/administrator/components/com_contact/models/fields/modal/contact.php b/administrator/components/com_contact/models/fields/modal/contact.php index b8f84ccc75fef..d93c1a63437c5 100644 --- a/administrator/components/com_contact/models/fields/modal/contact.php +++ b/administrator/components/com_contact/models/fields/modal/contact.php @@ -3,11 +3,13 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; + +use Joomla\CMS\Language\LanguageHelper; /** * Supports a modal contact picker. @@ -33,10 +35,13 @@ class JFormFieldModal_Contact extends JFormField */ protected function getInput() { - $allowNew = ((string) $this->element['new'] == 'true'); - $allowEdit = ((string) $this->element['edit'] == 'true'); - $allowClear = ((string) $this->element['clear'] != 'false'); - $allowSelect = ((string) $this->element['select'] != 'false'); + $allowNew = ((string) $this->element['new'] == 'true'); + $allowEdit = ((string) $this->element['edit'] == 'true'); + $allowClear = ((string) $this->element['clear'] != 'false'); + $allowSelect = ((string) $this->element['select'] != 'false'); + $allowPropagate = ((string) $this->element['propagate'] == 'true'); + + $languages = LanguageHelper::getContentLanguages(array(0, 1)); // Load language JFactory::getLanguage()->load('com_contact', JPATH_ADMINISTRATOR); @@ -69,6 +74,8 @@ function jSelectContact_" . $this->id . "(id, title, object) { } "); + JText::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED'); + $scriptSelect[$this->id] = true; } } @@ -117,55 +124,72 @@ function jSelectContact_" . $this->id . "(id, title, object) { // Select contact button if ($allowSelect) { - $html .= '' . ' ' . JText::_('JSELECT') - . ''; + . ''; } // New contact button if ($allowNew) { - $html .= '' . ' ' . JText::_('JACTION_CREATE') - . ''; + . ''; } // Edit contact button if ($allowEdit) { - $html .= '' . ' ' . JText::_('JACTION_EDIT') - . ''; + . ''; } // Clear contact button if ($allowClear) { - $html .= '' . '' . JText::_('JCLEAR') - . ''; + . ''; + } + + // Propagate contact button + if ($allowPropagate && count($languages) > 2) + { + // Strip off language tag at the end + $tagLength = (int) strlen($this->element['language']); + $callbackFunctionStem = substr("jSelectContact_" . $this->id, 0, -$tagLength); + + $html .= '' + . '' . JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_BUTTON') + . ''; } $html .= ''; @@ -183,7 +207,7 @@ function jSelectContact_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', + 'footer' => '', ) ); } @@ -204,18 +228,18 @@ function jSelectContact_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } @@ -236,18 +260,18 @@ function jSelectContact_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } diff --git a/administrator/components/com_contact/models/forms/contact.xml b/administrator/components/com_contact/models/forms/contact.xml index 397a2099dd30d..6d663fbe39821 100644 --- a/administrator/components/com_contact/models/forms/contact.xml +++ b/administrator/components/com_contact/models/forms/contact.xml @@ -5,7 +5,7 @@ - - @@ -513,6 +508,7 @@ description="COM_CONTACT_FIELD_PARAMS_CONTACT_POSITION_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -525,6 +521,7 @@ description="COM_CONTACT_FIELD_PARAMS_CONTACT_E_MAIL_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -537,6 +534,7 @@ description="COM_CONTACT_FIELD_PARAMS_ADD_MAILTO_LINK_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -549,6 +547,7 @@ description="COM_CONTACT_FIELD_PARAMS_STREET_ADDRESS_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -561,6 +560,7 @@ description="COM_CONTACT_FIELD_PARAMS_TOWN-SUBURB_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -573,6 +573,7 @@ description="COM_CONTACT_FIELD_PARAMS_STATE-COUNTY_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -585,6 +586,7 @@ description="COM_CONTACT_FIELD_PARAMS_POST-ZIP_CODE_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -597,6 +599,7 @@ description="COM_CONTACT_FIELD_PARAMS_COUNTRY_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -609,6 +612,7 @@ description="COM_CONTACT_FIELD_PARAMS_TELEPHONE_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -621,6 +625,7 @@ description="COM_CONTACT_FIELD_PARAMS_MOBILE_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -633,6 +638,7 @@ description="COM_CONTACT_FIELD_PARAMS_FAX_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -645,6 +651,7 @@ description="COM_CONTACT_FIELD_PARAMS_WEBPAGE_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -657,6 +664,7 @@ description="COM_CONTACT_FIELD_PARAMS_SHOW_IMAGE_DESC" class="chzn-color" useglobal="true" + showon="show_info:1" > @@ -733,7 +741,7 @@ - + JSHOW - - - - - - - - - - + + + + diff --git a/administrator/components/com_contact/sql/install.mysql.utf8.sql b/administrator/components/com_contact/sql/install.mysql.utf8.sql index 73a79307d0370..2ef7da446398d 100644 --- a/administrator/components/com_contact/sql/install.mysql.utf8.sql +++ b/administrator/components/com_contact/sql/install.mysql.utf8.sql @@ -3,49 +3,49 @@ -- CREATE TABLE IF NOT EXISTS `#__contact_details` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL DEFAULT '', - `alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '', - `con_position` varchar(255) DEFAULT NULL, + `id` int NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL, + `con_position` varchar(255), `address` text, - `suburb` varchar(100) DEFAULT NULL, - `state` varchar(100) DEFAULT NULL, - `country` varchar(100) DEFAULT NULL, - `postcode` varchar(100) DEFAULT NULL, - `telephone` varchar(255) DEFAULT NULL, - `fax` varchar(255) DEFAULT NULL, + `suburb` varchar(100), + `state` varchar(100), + `country` varchar(100), + `postcode` varchar(100), + `telephone` varchar(255), + `fax` varchar(255), `misc` mediumtext, - `image` varchar(255) DEFAULT NULL, - `email_to` varchar(255) DEFAULT NULL, - `default_con` tinyint(1) unsigned NOT NULL DEFAULT 0, - `published` tinyint(1) NOT NULL DEFAULT 0, - `checked_out` int(10) unsigned NOT NULL DEFAULT 0, + `image` varchar(255), + `email_to` varchar(255), + `default_con` tinyint unsigned NOT NULL DEFAULT 0, + `published` tinyint NOT NULL DEFAULT 0, + `checked_out` int unsigned NOT NULL DEFAULT 0, `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `ordering` int(11) NOT NULL DEFAULT 0, + `ordering` int NOT NULL DEFAULT 0, `params` text NOT NULL, - `user_id` int(11) NOT NULL DEFAULT 0, - `catid` int(11) NOT NULL DEFAULT 0, - `access` int(10) unsigned NOT NULL DEFAULT 0, + `user_id` int NOT NULL DEFAULT 0, + `catid` int NOT NULL DEFAULT 0, + `access` int unsigned NOT NULL DEFAULT 0, `mobile` varchar(255) NOT NULL DEFAULT '', `webpage` varchar(255) NOT NULL DEFAULT '', - `sortname1` varchar(255) NOT NULL, - `sortname2` varchar(255) NOT NULL, - `sortname3` varchar(255) NOT NULL, - `language` char(7) NOT NULL, + `sortname1` varchar(255) NOT NULL DEFAULT '', + `sortname2` varchar(255) NOT NULL DEFAULT '', + `sortname3` varchar(255) NOT NULL DEFAULT '', + `language` varchar(7) NOT NULL, `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_by` int(10) unsigned NOT NULL DEFAULT 0, + `created_by` int unsigned NOT NULL DEFAULT 0, `created_by_alias` varchar(255) NOT NULL DEFAULT '', `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `modified_by` int(10) unsigned NOT NULL DEFAULT 0, + `modified_by` int unsigned NOT NULL DEFAULT 0, `metakey` text NOT NULL, `metadesc` text NOT NULL, `metadata` text NOT NULL, - `featured` tinyint(3) unsigned NOT NULL DEFAULT 0 COMMENT 'Set if contact is featured.', - `xreference` varchar(50) NOT NULL COMMENT 'A reference to enable linkages to external data sets.', + `featured` tinyint unsigned NOT NULL DEFAULT 0 COMMENT 'Set if contact is featured.', + `xreference` varchar(50) NOT NULL DEFAULT '' COMMENT 'A reference to enable linkages to external data sets.', `publish_up` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `publish_down` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `version` int(10) unsigned NOT NULL DEFAULT 1, - `hits` int(10) unsigned NOT NULL DEFAULT 0, + `version` int unsigned NOT NULL DEFAULT 1, + `hits` int unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `idx_access` (`access`), KEY `idx_checkout` (`checked_out`), diff --git a/administrator/components/com_contact/tables/contact.php b/administrator/components/com_contact/tables/contact.php index 556baa184e63a..c1a800effdccf 100644 --- a/administrator/components/com_contact/tables/contact.php +++ b/administrator/components/com_contact/tables/contact.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -30,7 +30,7 @@ class ContactTableContact extends JTable /** * Constructor * - * @param JDatabaseDriver &$db Database connector object + * @param JDatabaseDriver $db Database connector object * * @since 1.0 */ @@ -38,6 +38,8 @@ public function __construct(&$db) { parent::__construct('#__contact_details', 'id', $db); + $this->setColumnAlias('title', 'name'); + JTableObserverTags::createObserver($this, array('typeAlias' => 'com_contact.contact')); JTableObserverContenthistory::createObserver($this, array('typeAlias' => 'com_contact.contact')); } @@ -110,7 +112,7 @@ public function store($updateNulls = false) $this->webpage = JStringPunycode::urlToPunycode($this->webpage); // Verify that the alias is unique - $table = JTable::getInstance('Contact', 'ContactTable'); + $table = JTable::getInstance('Contact', 'ContactTable', array('dbo' => $this->_db)); if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) { @@ -161,7 +163,7 @@ public function check() } // Sanity check for user_id - if (!($this->user_id)) + if (!$this->user_id) { $this->user_id = 0; } diff --git a/administrator/components/com_contact/views/contact/tmpl/edit.php b/administrator/components/com_contact/views/contact/tmpl/edit.php index 0c3cb3a790324..0f290799475c8 100644 --- a/administrator/components/com_contact/views/contact/tmpl/edit.php +++ b/administrator/components/com_contact/views/contact/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -15,6 +15,7 @@ JHtml::_('behavior.formvalidator'); JHtml::_('behavior.keepalive'); JHtml::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0 )); +JHtml::_('formbehavior.chosen', '#jform_tags', null, array('placeholder_text_multiple' => JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_TAGS'))); JHtml::_('formbehavior.chosen', 'select'); $app = JFactory::getApplication(); @@ -58,7 +59,7 @@ item->id) ? JText::_('COM_CONTACT_NEW_CONTACT') : JText::_('COM_CONTACT_EDIT_CONTACT')); ?>
    -
    +
    form->renderField('user_id'); ?> form->renderField('image'); ?> diff --git a/administrator/components/com_contact/views/contact/tmpl/edit_associations.php b/administrator/components/com_contact/views/contact/tmpl/edit_associations.php index 152abcd82c017..acfb21a59caa3 100644 --- a/administrator/components/com_contact/views/contact/tmpl/edit_associations.php +++ b/administrator/components/com_contact/views/contact/tmpl/edit_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/views/contact/tmpl/edit_metadata.php b/administrator/components/com_contact/views/contact/tmpl/edit_metadata.php index 3e815e20f2dc2..babb921e95f7c 100644 --- a/administrator/components/com_contact/views/contact/tmpl/edit_metadata.php +++ b/administrator/components/com_contact/views/contact/tmpl/edit_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/views/contact/tmpl/edit_params.php b/administrator/components/com_contact/views/contact/tmpl/edit_params.php index 92115983f4213..5650727df6932 100644 --- a/administrator/components/com_contact/views/contact/tmpl/edit_params.php +++ b/administrator/components/com_contact/views/contact/tmpl/edit_params.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/views/contact/tmpl/modal.php b/administrator/components/com_contact/views/contact/tmpl/modal.php index 50bee08bf17b0..70cdfbb8e3d3a 100644 --- a/administrator/components/com_contact/views/contact/tmpl/modal.php +++ b/administrator/components/com_contact/views/contact/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/views/contact/tmpl/modal_associations.php b/administrator/components/com_contact/views/contact/tmpl/modal_associations.php index 152abcd82c017..acfb21a59caa3 100644 --- a/administrator/components/com_contact/views/contact/tmpl/modal_associations.php +++ b/administrator/components/com_contact/views/contact/tmpl/modal_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/views/contact/tmpl/modal_metadata.php b/administrator/components/com_contact/views/contact/tmpl/modal_metadata.php index 3e815e20f2dc2..893a5fb2476d4 100644 --- a/administrator/components/com_contact/views/contact/tmpl/modal_metadata.php +++ b/administrator/components/com_contact/views/contact/tmpl/modal_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/views/contact/tmpl/modal_params.php b/administrator/components/com_contact/views/contact/tmpl/modal_params.php index 92115983f4213..3c2dec0feacf8 100644 --- a/administrator/components/com_contact/views/contact/tmpl/modal_params.php +++ b/administrator/components/com_contact/views/contact/tmpl/modal_params.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contact/views/contact/view.html.php b/administrator/components/com_contact/views/contact/view.html.php index 57d367bf16b4a..42f0d0843aebb 100644 --- a/administrator/components/com_contact/views/contact/view.html.php +++ b/administrator/components/com_contact/views/contact/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -139,6 +139,11 @@ protected function addToolbar() JToolbarHelper::versions('com_contact.contact', $this->item->id); } + if (JLanguageAssociations::isEnabled() && JComponentHelper::isEnabled('com_associations')) + { + JToolbarHelper::custom('contact.editAssociations', 'contract', 'contract', 'JTOOLBAR_ASSOCIATIONS', false, false); + } + JToolbarHelper::cancel('contact.cancel', 'JTOOLBAR_CLOSE'); } diff --git a/administrator/components/com_contact/views/contacts/tmpl/default.php b/administrator/components/com_contact/views/contacts/tmpl/default.php index 0883511d7035e..2e1a9ae1a195e 100644 --- a/administrator/components/com_contact/views/contacts/tmpl/default.php +++ b/administrator/components/com_contact/views/contacts/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -135,8 +135,8 @@ ?>
    - -
    + +
    checked_out) : ?> editor, $item->checked_out_time, 'contacts.', $canCheckin); ?> diff --git a/administrator/components/com_contact/views/contacts/tmpl/default_batch.php b/administrator/components/com_contact/views/contacts/tmpl/default_batch.php index 0d3e882454412..c7a2d5feb36e3 100644 --- a/administrator/components/com_contact/views/contacts/tmpl/default_batch.php +++ b/administrator/components/com_contact/views/contacts/tmpl/default_batch.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -13,7 +13,9 @@ ?> diff --git a/administrator/components/com_contact/views/contacts/tmpl/default_batch_body.php b/administrator/components/com_contact/views/contacts/tmpl/default_batch_body.php index 68ad1a9ef8a20..eb940822057b9 100644 --- a/administrator/components/com_contact/views/contacts/tmpl/default_batch_body.php +++ b/administrator/components/com_contact/views/contacts/tmpl/default_batch_body.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_contact/views/contacts/tmpl/default_batch_footer.php b/administrator/components/com_contact/views/contacts/tmpl/default_batch_footer.php index 50b3ec588949c..6db30657854b3 100644 --- a/administrator/components/com_contact/views/contacts/tmpl/default_batch_footer.php +++ b/administrator/components/com_contact/views/contacts/tmpl/default_batch_footer.php @@ -3,15 +3,15 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - + + \ No newline at end of file + diff --git a/administrator/components/com_contact/views/contacts/tmpl/modal.php b/administrator/components/com_contact/views/contacts/tmpl/modal.php index 0553535534f84..f9f002d97af92 100644 --- a/administrator/components/com_contact/views/contacts/tmpl/modal.php +++ b/administrator/components/com_contact/views/contacts/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -22,6 +22,7 @@ JHtml::_('behavior.core'); JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); JHtml::_('formbehavior.chosen', 'select'); JHtml::_('behavior.polyfill', array('event'), 'lt IE 9'); JHtml::_('script', 'com_contact/admin-contacts-modal.min.js', array('version' => 'auto', 'relative' => true)); @@ -45,7 +46,7 @@ ?>
    - + $this)); ?> @@ -119,10 +120,10 @@ - + escape($item->name); ?> - escape($item->name); ?> + escape($item->name); ?>
    escape($item->category_title); ?>
    diff --git a/administrator/components/com_contact/views/contacts/view.html.php b/administrator/components/com_contact/views/contacts/view.html.php index d7e5150a3b256..d9a3be72784f5 100644 --- a/administrator/components/com_contact/views/contacts/view.html.php +++ b/administrator/components/com_contact/views/contacts/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contact * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -104,7 +104,7 @@ public function display($tpl = null) // We also need to change the category filter to show show categories with All or the forced language. if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) { - // If the language is forced we can't allow to select the language, so transform the language selector filter into an hidden field. + // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. $languageXml = new SimpleXMLElement(''); $this->filterForm->setField($languageXml, 'filter', true); @@ -133,12 +133,12 @@ protected function addToolbar() JToolbarHelper::title(JText::_('COM_CONTACT_MANAGER_CONTACTS'), 'address contact'); - if ($canDo->get('core.create') || (count($user->getAuthorisedCategories('com_contact', 'core.create'))) > 0) + if ($canDo->get('core.create') || count($user->getAuthorisedCategories('com_contact', 'core.create')) > 0) { JToolbarHelper::addNew('contact.add'); } - if (($canDo->get('core.edit')) || ($canDo->get('core.edit.own'))) + if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) { JToolbarHelper::editList('contact.edit'); } diff --git a/administrator/components/com_content/config.xml b/administrator/components/com_content/config.xml index 01b5110bf3dda..c2f716c05033c 100644 --- a/administrator/components/com_content/config.xml +++ b/administrator/components/com_content/config.xml @@ -276,7 +276,7 @@ JHIDE + + + + + @@ -385,11 +398,10 @@ type="plugins" label="COM_CONTENT_FIELD_CAPTCHA_LABEL" description="COM_CONTENT_FIELD_CAPTCHA_DESC" - default="" folder="captcha" filter="cmd" + useglobal="true" > - @@ -431,7 +443,7 @@ JAUTHOR + @@ -940,9 +954,10 @@ @@ -986,6 +1001,7 @@ + @@ -1050,6 +1066,12 @@ description="COM_CONTENT_CONFIG_INTEGRATION_SETTINGS_DESC" > + + JHIDE + + + + + + + + + + + + + + * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_content/content.xml b/administrator/components/com_content/content.xml index 472164a470eeb..a7b68bf30b1c7 100644 --- a/administrator/components/com_content/content.xml +++ b/administrator/components/com_content/content.xml @@ -3,7 +3,7 @@ com_content Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_content/controller.php b/administrator/components/com_content/controller.php index 34d876074484e..14150e9a4b27e 100644 --- a/administrator/components/com_content/controller.php +++ b/administrator/components/com_content/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_content/controllers/ajax.json.php b/administrator/components/com_content/controllers/ajax.json.php new file mode 100644 index 0000000000000..2a8e4d2960043 --- /dev/null +++ b/administrator/components/com_content/controllers/ajax.json.php @@ -0,0 +1,86 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\LanguageHelper; + +/** + * The article controller for ajax requests + * + * @since 3.9.0 + */ +class ContentControllerAjax extends JControllerLegacy +{ + /** + * Method to fetch associations of an article + * + * The method assumes that the following http parameters are passed in an Ajax Get request: + * token: the form token + * assocId: the id of the article whose associations are to be returned + * excludeLang: the association for this language is to be excluded + * + * @return null + * + * @since 3.9.0 + */ + public function fetchAssociations() + { + if (!JSession::checkToken('get')) + { + echo new JResponseJson(null, JText::_('JINVALID_TOKEN'), true); + } + else + { + $input = JFactory::getApplication()->input; + + $assocId = $input->getInt('assocId', 0); + + if ($assocId == 0) + { + echo new JResponseJson(null, JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'assocId'), true); + + return; + } + + $excludeLang = $input->get('excludeLang', '', 'STRING'); + + $associations = JLanguageAssociations::getAssociations('com_content', '#__content', 'com_content.item', (int) $assocId); + + unset($associations[$excludeLang]); + + // Add the title to each of the associated records + $contentTable = JTable::getInstance('Content', 'JTable'); + + foreach ($associations as $lang => $association) + { + $contentTable->load($association->id); + $associations[$lang]->title = $contentTable->title; + } + + $countContentLanguages = count(LanguageHelper::getContentLanguages(array(0, 1))); + + if (count($associations) == 0) + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE'); + } + elseif ($countContentLanguages > count($associations) + 2) + { + $tags = implode(', ', array_keys($associations)); + $message = JText::sprintf('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME', $tags); + } + else + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL'); + } + + echo new JResponseJson($associations, $message); + } + } +} diff --git a/administrator/components/com_content/controllers/article.php b/administrator/components/com_content/controllers/article.php index 705584b51db57..1f7bad28278c4 100644 --- a/administrator/components/com_content/controllers/article.php +++ b/administrator/components/com_content/controllers/article.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -60,7 +60,7 @@ protected function allowAdd($data = array()) if ($allow === null) { - // In the absense of better information, revert to the component permissions. + // In the absence of better information, revert to the component permissions. return parent::allowAdd(); } @@ -123,7 +123,7 @@ protected function allowEdit($data = array(), $key = 'id') */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Set the model /** @var ContentModelArticle $model */ diff --git a/administrator/components/com_content/controllers/articles.php b/administrator/components/com_content/controllers/articles.php index 82ae9ccbcd184..d5c5178291591 100644 --- a/administrator/components/com_content/controllers/articles.php +++ b/administrator/components/com_content/controllers/articles.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -50,7 +50,7 @@ public function __construct($config = array()) public function featured() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $user = JFactory::getUser(); $ids = $this->input->get('cid', array(), 'array'); diff --git a/administrator/components/com_content/controllers/featured.php b/administrator/components/com_content/controllers/featured.php index e3ef401689e91..fb3e3f7687bfa 100644 --- a/administrator/components/com_content/controllers/featured.php +++ b/administrator/components/com_content/controllers/featured.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -28,7 +28,7 @@ class ContentControllerFeatured extends ContentControllerArticles public function delete() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $user = JFactory::getUser(); $ids = $this->input->get('cid', array(), 'array'); diff --git a/administrator/components/com_content/helpers/associations.php b/administrator/components/com_content/helpers/associations.php index b5352e9e0fc36..2454ffe423d24 100644 --- a/administrator/components/com_content/helpers/associations.php +++ b/administrator/components/com_content/helpers/associations.php @@ -3,20 +3,20 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Association\AssociationExtensionHelper; /** * Content associations helper. * * @since 3.7.0 */ -class ContentAssociationsHelper extends JAssociationExtensionHelper +class ContentAssociationsHelper extends AssociationExtensionHelper { /** * The extension name @@ -141,7 +141,6 @@ public function getType($typeName = '') if (in_array($typeName, $this->itemTypes)) { - switch ($typeName) { case 'article': diff --git a/administrator/components/com_content/helpers/content.php b/administrator/components/com_content/helpers/content.php index be806fc1782e1..ed95fc6ddcdcf 100644 --- a/administrator/components/com_content/helpers/content.php +++ b/administrator/components/com_content/helpers/content.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -91,7 +91,7 @@ public static function filterText($text) /** * Adds Count Items for Category Manager. * - * @param stdClass[] &$items The banner category objects + * @param stdClass[] &$items The category objects * * @return stdClass[] * @@ -99,53 +99,20 @@ public static function filterText($text) */ public static function countItems(&$items) { - $db = JFactory::getDbo(); - - foreach ($items as $item) - { - $item->count_trashed = 0; - $item->count_archived = 0; - $item->count_unpublished = 0; - $item->count_published = 0; - $query = $db->getQuery(true); - $query->select('state, count(*) AS count') - ->from($db->qn('#__content')) - ->where('catid = ' . (int) $item->id) - ->group('state'); - $db->setQuery($query); - $articles = $db->loadObjectList(); - - foreach ($articles as $article) - { - if ($article->state == 1) - { - $item->count_published = $article->count; - } - - if ($article->state == 0) - { - $item->count_unpublished = $article->count; - } - - if ($article->state == 2) - { - $item->count_archived = $article->count; - } - - if ($article->state == -2) - { - $item->count_trashed = $article->count; - } - } - } + $config = (object) array( + 'related_tbl' => 'content', + 'state_col' => 'state', + 'group_col' => 'catid', + 'relation_type' => 'category_or_group', + ); - return $items; + return parent::countRelations($items, $config); } /** * Adds Count Items for Tag Manager. * - * @param stdClass[] &$items The content objects + * @param stdClass[] &$items The tag objects * @param string $extension The name of the active view. * * @return stdClass[] @@ -154,65 +121,18 @@ public static function countItems(&$items) */ public static function countTagItems(&$items, $extension) { - $db = JFactory::getDbo(); - $parts = explode('.', $extension); - $section = null; - - if (count($parts) > 1) - { - $section = $parts[1]; - } - - $join = $db->qn('#__content') . ' AS c ON ct.content_item_id=c.id'; - $state = 'state'; - - if ($section === 'category') - { - $join = $db->qn('#__categories') . ' AS c ON ct.content_item_id=c.id'; - $state = 'published as state'; - } - - foreach ($items as $item) - { - $item->count_trashed = 0; - $item->count_archived = 0; - $item->count_unpublished = 0; - $item->count_published = 0; - $query = $db->getQuery(true); - $query->select($state . ', count(*) AS count') - ->from($db->qn('#__contentitem_tag_map') . 'AS ct ') - ->where('ct.tag_id = ' . (int) $item->id) - ->where('ct.type_alias =' . $db->q($extension)) - ->join('LEFT', $join) - ->group('state'); - $db->setQuery($query); - $contents = $db->loadObjectList(); - - foreach ($contents as $content) - { - if ($content->state == 1) - { - $item->count_published = $content->count; - } - - if ($content->state == 0) - { - $item->count_unpublished = $content->count; - } - - if ($content->state == 2) - { - $item->count_archived = $content->count; - } - - if ($content->state == -2) - { - $item->count_trashed = $content->count; - } - } - } + $parts = explode('.', $extension); + $section = count($parts) > 1 ? $parts[1] : null; + + $config = (object) array( + 'related_tbl' => ($section === 'category' ? 'categories' : 'content'), + 'state_col' => ($section === 'category' ? 'published' : 'state'), + 'group_col' => 'tag_id', + 'extension' => $extension, + 'relation_type' => 'tag_assigments', + ); - return $items; + return parent::countRelations($items, $config); } /** diff --git a/administrator/components/com_content/helpers/html/contentadministrator.php b/administrator/components/com_content/helpers/html/contentadministrator.php index f5e8da1c34520..a4af494973f63 100644 --- a/administrator/components/com_content/helpers/html/contentadministrator.php +++ b/administrator/components/com_content/helpers/html/contentadministrator.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -52,6 +52,7 @@ public static function association($articleid) ->select('cat.title as category_title') ->join('LEFT', '#__categories as cat ON cat.id=c.catid') ->where('c.id IN (' . implode(',', array_values($associations)) . ')') + ->where('c.id != ' . $articleid) ->join('LEFT', '#__languages as l ON c.language=l.lang_code') ->select('l.image') ->select('l.title as language_title'); @@ -99,7 +100,7 @@ public static function association($articleid) * * @return string HTML code */ - public static function featured($value = 0, $i, $canChange = true) + public static function featured($value = 0, $i = 0, $canChange = true) { JHtml::_('bootstrap.tooltip'); diff --git a/administrator/components/com_content/models/article.php b/administrator/components/com_content/models/article.php index b6dba4d0cfefe..8717315555a82 100644 --- a/administrator/components/com_content/models/article.php +++ b/administrator/components/com_content/models/article.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -46,34 +46,96 @@ class ContentModelArticle extends JModelAdmin protected $associationsContext = 'com_content.item'; /** - * Batch copy items to a new category or current. + * Function that can be overridden to do any data cleanup after batch copying data * - * @param integer $value The new category. + * @param \JTableInterface $table The table object containing the newly created item + * @param integer $newId The id of the new item + * @param integer $oldId The original item id + * + * @return void + * + * @since 3.8.12 + */ + protected function cleanupPostBatchCopy(\JTableInterface $table, $newId, $oldId) + { + // Check if the article was featured and update the #__content_frontpage table + if ($table->featured == 1) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->insert($db->quoteName('#__content_frontpage')) + ->values($newId . ', 0'); + $db->setQuery($query); + $db->execute(); + } + + // Register FieldsHelper + JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php'); + + $oldItem = $this->getTable(); + $oldItem->load($oldId); + $fields = FieldsHelper::getFields('com_content.article', $oldItem, true); + + $fieldsData = array(); + + if (!empty($fields)) + { + $fieldsData['com_fields'] = array(); + + foreach ($fields as $field) + { + $fieldsData['com_fields'][$field->name] = $field->rawvalue; + } + } + + JEventDispatcher::getInstance()->trigger('onContentAfterSave', array('com_content.article', &$this->table, true, $fieldsData)); + } + + /** + * Batch move categories to a new category. + * + * @param integer $value The new category ID. * @param array $pks An array of row IDs. * @param array $contexts An array of item contexts. * - * @return mixed An array of new IDs on success, boolean false on failure. + * @return boolean True on success. * - * @since 11.1 + * @since 3.8.6 */ - protected function batchCopy($value, $pks, $contexts) + protected function batchMove($value, $pks, $contexts) { - $categoryId = (int) $value; + if (empty($this->batchSet)) + { + // Set some needed variables. + $this->user = JFactory::getUser(); + $this->table = $this->getTable(); + $this->tableClassName = get_class($this->table); + $this->contentType = new JUcmType; + $this->type = $this->contentType->getTypeByTable($this->tableClassName); + } - $newIds = array(); + $categoryId = (int) $value; if (!$this->checkCategoryId($categoryId)) { return false; } - // Parent exists so we let's proceed - while (!empty($pks)) + JPluginHelper::importPlugin('system'); + $dispatcher = JEventDispatcher::getInstance(); + + // Register FieldsHelper + JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php'); + + // Parent exists so we proceed + foreach ($pks as $pk) { - // Pop the first ID off the stack - $pk = array_shift($pks); + if (!$this->user->authorise('core.edit', $contexts[$pk])) + { + $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); - $this->table->reset(); + return false; + } // Check that the row actually exists if (!$this->table->load($pk)) @@ -93,29 +155,22 @@ protected function batchCopy($value, $pks, $contexts) } } - // Alter the title & alias - $data = $this->generateNewTitle($categoryId, $this->table->alias, $this->table->title); - $this->table->title = $data['0']; - $this->table->alias = $data['1']; - - // Reset the ID because we are making a copy - $this->table->id = 0; + $fields = FieldsHelper::getFields('com_content.article', $this->table, true); + $fieldsData = array(); - // Reset hits because we are making a copy - $this->table->hits = 0; + if (!empty($fields)) + { + $fieldsData['com_fields'] = array(); - // Unpublish because we are making a copy - $this->table->state = 0; + foreach ($fields as $field) + { + $fieldsData['com_fields'][$field->name] = $field->rawvalue; + } + } - // New category ID + // Set the new category ID $this->table->catid = $categoryId; - // TODO: Deal with ordering? - // $table->ordering = 1; - - // Get the featured state - $featured = $this->table->featured; - // Check the row. if (!$this->table->check()) { @@ -124,7 +179,10 @@ protected function batchCopy($value, $pks, $contexts) return false; } - $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); + if (!empty($this->type)) + { + $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); + } // Store the row. if (!$this->table->store()) @@ -134,28 +192,14 @@ protected function batchCopy($value, $pks, $contexts) return false; } - // Get the new item ID - $newId = $this->table->get('id'); - - // Add the new ID to the array - $newIds[$pk] = $newId; - - // Check if the article was featured and update the #__content_frontpage table - if ($featured == 1) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->insert($db->quoteName('#__content_frontpage')) - ->values($newId . ', 0'); - $db->setQuery($query); - $db->execute(); - } + // Run event for moved article + $dispatcher->trigger('onContentAfterSave', array('com_content.article', &$this->table, false, $fieldsData)); } // Clean the cache $this->cleanCache(); - return $newIds; + return true; } /** @@ -169,17 +213,12 @@ protected function batchCopy($value, $pks, $contexts) */ protected function canDelete($record) { - if (!empty($record->id)) + if (empty($record->id) || $record->state != -2) { - if ($record->state != -2) - { - return false; - } - - return JFactory::getUser()->authorise('core.delete', 'com_content.article.' . (int) $record->id); + return false; } - return false; + return JFactory::getUser()->authorise('core.delete', 'com_content.article.' . (int) $record->id); } /** @@ -208,7 +247,7 @@ protected function canEditState($record) } // Default to component settings if neither article nor category known. - return parent::canEditState(); + return parent::canEditState($record); } /** @@ -326,6 +365,9 @@ public function getItem($pk = null) */ public function getForm($data = array(), $loadData = true) { + $app = JFactory::getApplication(); + $user = JFactory::getUser(); + // Get the form. $form = $this->loadForm('com_content.article', 'article', array('control' => 'jform', 'load_data' => $loadData)); @@ -340,18 +382,30 @@ public function getForm($data = array(), $loadData = true) * The front end calls this model and uses a_id to avoid id clashes so we need to check for that first. * The back end uses id so we use that the rest of the time and set it to 0 by default. */ - $id = $jinput->get('a_id', $jinput->get('id', 0)); + $id = (int) $jinput->get('a_id', $jinput->get('id', 0)); // Determine correct permissions to check. - if ($this->getState('article.id')) + if ($id = $this->getState('article.id', $id)) { - $id = $this->getState('article.id'); - // Existing record. Can only edit in selected categories. $form->setFieldAttribute('catid', 'action', 'core.edit'); // Existing record. Can only edit own articles in selected categories. - $form->setFieldAttribute('catid', 'action', 'core.edit.own'); + if ($app->isClient('administrator')) + { + $form->setFieldAttribute('catid', 'action', 'core.edit.own'); + } + else + // Existing record. We can't edit the category in frontend if not edit.state. + { + if ($id != 0 && (!$user->authorise('core.edit.state', 'com_content.article.' . (int) $id)) + || ($id == 0 && !$user->authorise('core.edit.state', 'com_content'))) + { + $form->setFieldAttribute('catid', 'readonly', 'true'); + $form->setFieldAttribute('catid', 'required', 'false'); + $form->setFieldAttribute('catid', 'filter', 'unset'); + } + } } else { @@ -359,12 +413,33 @@ public function getForm($data = array(), $loadData = true) $form->setFieldAttribute('catid', 'action', 'core.create'); } - $user = JFactory::getUser(); + // Object uses for checking edit state permission of article + $record = new stdClass; + $record->id = $id; + + // Get the category which the article is being added to + if (!empty($data['catid'])) + { + $catId = (int) $data['catid']; + } + else + { + $catIds = $form->getValue('catid'); + + $catId = is_array($catIds) + ? (int) reset($catIds) + : (int) $catIds; + + if (!$catId) + { + $catId = (int) $form->getFieldAttribute('catid', 'default', 0); + } + } + + $record->catid = $catId; - // Check for existing article. // Modify the form based on Edit State access controls. - if ($id != 0 && (!$user->authorise('core.edit.state', 'com_content.article.' . (int) $id)) - || ($id == 0 && !$user->authorise('core.edit.state', 'com_content'))) + if (!$this->canEditState($record)) { // Disable fields for display. $form->setFieldAttribute('featured', 'disabled', 'true'); @@ -383,7 +458,6 @@ public function getForm($data = array(), $loadData = true) } // Prevent messing with article language and category when editing existing article with associations - $app = JFactory::getApplication(); $assoc = JLanguageAssociations::isEnabled(); // Check if article is associated @@ -467,16 +541,19 @@ protected function loadFormData() public function validate($form, $data, $group = null) { // Don't allow to change the users if not allowed to access com_users. - if (JFactory::getApplication()->isClient('administrator') && !JFactory::getUser()->authorise('core.manage', 'com_users')) + if (!JFactory::getUser()->authorise('core.manage', 'com_users')) { if (isset($data['created_by'])) { unset($data['created_by']); } + } - if (isset($data['modified_by'])) + if (!JFactory::getUser()->authorise('core.admin', 'com_content')) + { + if (isset($data['rules'])) { - unset($data['modified_by']); + unset($data['rules']); } } @@ -516,20 +593,22 @@ public function save($data) JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - // Cast catid to integer for comparison - $catid = (int) $data['catid']; + // Create new category, if needed. + $createCategory = true; - // Check if New Category exists - if ($catid > 0) + // If category ID is provided, check if it's valid. + if (is_numeric($data['catid']) && $data['catid']) { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_content'); + $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_content'); } - // Save New Categoryg - if ($catid == 0 && $this->canCreateCategory()) + // Save New Category + if ($createCategory && $this->canCreateCategory()) { $table = array(); - $table['title'] = $data['catid']; + + // Remove #new# prefix, if exists. + $table['title'] = strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid']; $table['parent_id'] = 1; $table['extension'] = 'com_content'; $table['language'] = $data['language']; @@ -753,6 +832,9 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') if ($this->canCreateCategory()) { $form->setFieldAttribute('catid', 'allowAdd', 'true'); + + // Add a prefix for categories created on the fly. + $form->setFieldAttribute('catid', 'customPrefix', '#new#'); } // Association content items @@ -780,6 +862,7 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $field->addAttribute('new', 'true'); $field->addAttribute('edit', 'true'); $field->addAttribute('clear', 'true'); + $field->addAttribute('propagate', 'true'); } $form->load($addform, false); @@ -792,14 +875,14 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') /** * Custom clean the cache of com_content and content modules * - * @param string $group The cache group - * @param integer $client_id The ID of the client + * @param string $group The cache group + * @param integer $clientId The ID of the client * * @return void * * @since 1.6 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { parent::cleanCache('com_content'); parent::cleanCache('mod_articles_archive'); @@ -837,7 +920,7 @@ private function canCreateCategory() /** * Delete #__content_frontpage items if the deleted articles was featured * - * @param object &$pks The primary key related to the contents that was deleted. + * @param object $pks The primary key related to the contents that was deleted. * * @return boolean * @@ -850,7 +933,7 @@ public function delete(&$pks) if ($return) { // Now check to see if this articles was featured if so delete it from the #__content_frontpage table - $db = JFactory::getDbo(); + $db = $this->getDbo(); $query = $db->getQuery(true) ->delete($db->quoteName('#__content_frontpage')) ->where('content_id IN (' . implode(',', $pks) . ')'); diff --git a/administrator/components/com_content/models/articles.php b/administrator/components/com_content/models/articles.php index 40cbfc45263a1..d2cfe7b344f32 100644 --- a/administrator/components/com_content/models/articles.php +++ b/administrator/components/com_content/models/articles.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -99,26 +99,36 @@ protected function populateState($ordering = 'a.id', $direction = 'desc') $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); - $access = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access'); - $this->setState('filter.access', $access); - - $authorId = $app->getUserStateFromRequest($this->context . '.filter.author_id', 'filter_author_id'); - $this->setState('filter.author_id', $authorId); - $published = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', ''); $this->setState('filter.published', $published); - $categoryId = $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id'); - $this->setState('filter.category_id', $categoryId); - $level = $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level'); $this->setState('filter.level', $level); $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); $this->setState('filter.language', $language); - $tag = $this->getUserStateFromRequest($this->context . '.filter.tag', 'filter_tag', ''); - $this->setState('filter.tag', $tag); + $formSubmited = $app->input->post->get('form_submited'); + + $access = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access'); + $authorId = $this->getUserStateFromRequest($this->context . '.filter.author_id', 'filter_author_id'); + $categoryId = $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id'); + $tag = $this->getUserStateFromRequest($this->context . '.filter.tag', 'filter_tag', ''); + + if ($formSubmited) + { + $access = $app->input->post->get('access'); + $this->setState('filter.access', $access); + + $authorId = $app->input->post->get('author_id'); + $this->setState('filter.author_id', $authorId); + + $categoryId = $app->input->post->get('category_id'); + $this->setState('filter.category_id', $categoryId); + + $tag = $app->input->post->get('tag'); + $this->setState('filter.tag', $tag); + } // List state information. parent::populateState($ordering, $direction); @@ -148,11 +158,12 @@ protected function getStoreId($id = '') { // Compile the store id. $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.access'); + $id .= ':' . serialize($this->getState('filter.access')); $id .= ':' . $this->getState('filter.published'); - $id .= ':' . $this->getState('filter.category_id'); - $id .= ':' . $this->getState('filter.author_id'); + $id .= ':' . serialize($this->getState('filter.category_id')); + $id .= ':' . serialize($this->getState('filter.author_id')); $id .= ':' . $this->getState('filter.language'); + $id .= ':' . serialize($this->getState('filter.tag')); return parent::getStoreId($id); } @@ -167,17 +178,17 @@ protected function getStoreId($id = '') protected function getListQuery() { // Create a new query object. - $db = $this->getDbo(); + $db = $this->getDbo(); $query = $db->getQuery(true); - $user = JFactory::getUser(); + $user = JFactory::getUser(); // Select the required fields from the table. $query->select( $this->getState( 'list.select', 'a.id, a.title, a.alias, a.checked_out, a.checked_out_time, a.catid' . - ', a.state, a.access, a.created, a.created_by, a.created_by_alias, a.modified, a.ordering, a.featured, a.language, a.hits' . - ', a.publish_up, a.publish_down' + ', a.state, a.access, a.created, a.created_by, a.created_by_alias, a.modified, a.ordering, a.featured, a.language, a.hits' . + ', a.publish_up, a.publish_down, a.note' ) ); $query->from('#__content AS a'); @@ -195,20 +206,22 @@ protected function getListQuery() ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); // Join over the categories. - $query->select('c.title AS category_title') + $query->select('c.title AS category_title, c.created_user_id AS category_uid, c.level AS category_level') ->join('LEFT', '#__categories AS c ON c.id = a.catid'); + // Join over the parent categories. + $query->select('parent.title AS parent_category_title, parent.id AS parent_category_id, + parent.created_user_id AS parent_category_uid, parent.level AS parent_category_level') + ->join('LEFT', '#__categories AS parent ON parent.id = c.parent_id'); + // Join over the users for the author. $query->select('ua.name AS author_name') ->join('LEFT', '#__users AS ua ON ua.id = a.created_by'); // Join on voting table - $assogroup = 'a.id, l.title, l.image, uc.name, ag.title, c.title, ua.name'; - if (JPluginHelper::isEnabled('content', 'vote')) { - $assogroup .= ', v.rating_sum, v.rating_count'; - $query->select('COALESCE(NULLIF(ROUND(v.rating_sum / v.rating_count, 0), 0), 0) AS rating, + $query->select('COALESCE(NULLIF(ROUND(v.rating_sum / v.rating_count, 0), 0), 0) AS rating, COALESCE(NULLIF(v.rating_count, 0), 0) as rating_count') ->join('LEFT', '#__content_rating AS v ON a.id = v.content_id'); } @@ -216,17 +229,33 @@ protected function getListQuery() // Join over the associations. if (JLanguageAssociations::isEnabled()) { - $query->select('COUNT(asso2.id)>1 as association') - ->join('LEFT', '#__associations AS asso ON asso.id = a.id AND asso.context=' . $db->quote('com_content.item')) - ->join('LEFT', '#__associations AS asso2 ON asso2.key = asso.key') - ->group($assogroup); + $subQuery = $db->getQuery(true) + ->select('COUNT(' . $db->quoteName('asso1.id') . ') > 1') + ->from($db->quoteName('#__associations', 'asso1')) + ->join('INNER', $db->quoteName('#__associations', 'asso2') . ' ON ' . $db->quoteName('asso1.key') . ' = ' . $db->quoteName('asso2.key')) + ->where( + array( + $db->quoteName('asso1.id') . ' = ' . $db->quoteName('a.id'), + $db->quoteName('asso1.context') . ' = ' . $db->quote('com_content.item'), + ) + ); + + $query->select('(' . $subQuery . ') AS ' . $db->quoteName('association')); } // Filter by access level. - if ($access = $this->getState('filter.access')) + $access = $this->getState('filter.access'); + + if (is_numeric($access)) { $query->where('a.access = ' . (int) $access); } + elseif (is_array($access)) + { + $access = ArrayHelper::toInteger($access); + $access = implode(',', $access); + $query->where('a.access IN (' . $access . ')'); + } // Filter by access level on categories. if (!$user->authorise('core.admin')) @@ -248,29 +277,38 @@ protected function getListQuery() $query->where('(a.state = 0 OR a.state = 1)'); } - // Filter by a single or group of categories. - $baselevel = 1; - $categoryId = $this->getState('filter.category_id'); + // Filter by categories and by level + $categoryId = $this->getState('filter.category_id', array()); + $level = $this->getState('filter.level'); - if (is_numeric($categoryId)) + if (!is_array($categoryId)) { - $categoryTable= JTable::getInstance('Category', 'JTable'); - $categoryTable->load($categoryId); - $rgt = $categoryTable->rgt; - $lft = $categoryTable->lft; - $baselevel = (int) $categoryTable->level; - $query->where('c.lft >= ' . (int) $lft) - ->where('c.rgt <= ' . (int) $rgt); + $categoryId = $categoryId ? array($categoryId) : array(); } - elseif (is_array($categoryId)) + + // Case: Using both categories filter and by level filter + if (count($categoryId)) { - $query->where('a.catid IN (' . implode(',', ArrayHelper::toInteger($categoryId)) . ')'); + $categoryId = ArrayHelper::toInteger($categoryId); + $categoryTable = JTable::getInstance('Category', 'JTable'); + $subCatItemsWhere = array(); + + foreach ($categoryId as $filter_catid) + { + $categoryTable->load($filter_catid); + $subCatItemsWhere[] = '(' . + ($level ? 'c.level <= ' . ((int) $level + (int) $categoryTable->level - 1) . ' AND ' : '') . + 'c.lft >= ' . (int) $categoryTable->lft . ' AND ' . + 'c.rgt <= ' . (int) $categoryTable->rgt . ')'; + } + + $query->where('(' . implode(' OR ', $subCatItemsWhere) . ')'); } - // Filter on the level. - if ($level = $this->getState('filter.level')) + // Case: Using only the by level filter + elseif ($level) { - $query->where('c.level <= ' . ((int) $level + (int) $baselevel - 1)); + $query->where('c.level <= ' . (int) $level); } // Filter by author @@ -281,6 +319,12 @@ protected function getListQuery() $type = $this->getState('filter.author_id.include', true) ? '= ' : '<>'; $query->where('a.created_by ' . $type . (int) $authorId); } + elseif (is_array($authorId)) + { + $authorId = ArrayHelper::toInteger($authorId); + $authorId = implode(',', $authorId); + $query->where('a.created_by IN (' . $authorId . ')'); + } // Filter by search in title. $search = $this->getState('filter.search'); @@ -296,10 +340,15 @@ protected function getListQuery() $search = $db->quote('%' . $db->escape(substr($search, 7), true) . '%'); $query->where('(ua.name LIKE ' . $search . ' OR ua.username LIKE ' . $search . ')'); } + elseif (stripos($search, 'content:') === 0) + { + $search = $db->quote('%' . $db->escape(substr($search, 8), true) . '%'); + $query->where('(a.introtext LIKE ' . $search . ' OR a.fulltext LIKE ' . $search . ')'); + } else { $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ')'); + $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); } } @@ -309,17 +358,46 @@ protected function getListQuery() $query->where('a.language = ' . $db->quote($language)); } - // Filter by a single tag. - $tagId = $this->getState('filter.tag'); + $tag = $this->getState('filter.tag'); - if (is_numeric($tagId)) + // Run simplified query when filtering by one tag. + if (\is_array($tag) && \count($tag) === 1) { - $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId) - ->join( - 'LEFT', - $db->quoteName('#__contentitem_tag_map', 'tagmap') + $tag = $tag[0]; + } + + if ($tag && \is_array($tag)) + { + $tag = ArrayHelper::toInteger($tag); + + $subQuery = $db->getQuery(true) + ->select('DISTINCT ' . $db->quoteName('content_item_id')) + ->from($db->quoteName('#__contentitem_tag_map')) + ->where( + array( + $db->quoteName('tag_id') . ' IN (' . implode(',', $tag) . ')', + $db->quoteName('type_alias') . ' = ' . $db->quote('com_content.article'), + ) + ); + + $query->join( + 'INNER', + '(' . $subQuery . ') AS ' . $db->quoteName('tagmap') + . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') + ); + } + elseif ($tag = (int) $tag) + { + $query->join( + 'INNER', + $db->quoteName('#__contentitem_tag_map', 'tagmap') . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') - . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_content.article') + ) + ->where( + array( + $db->quoteName('tagmap.tag_id') . ' = ' . $tag, + $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_content.article'), + ) ); } @@ -327,6 +405,11 @@ protected function getListQuery() $orderCol = $this->state->get('list.ordering', 'a.id'); $orderDirn = $this->state->get('list.direction', 'DESC'); + if ($orderCol == 'a.ordering' || $orderCol == 'category_title') + { + $orderCol = $db->quoteName('c.title') . ' ' . $orderDirn . ', ' . $db->quoteName('a.ordering'); + } + $query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn)); return $query; @@ -338,11 +421,13 @@ protected function getListQuery() * @return stdClass * * @since 1.6 + * + * @deprecated 4.0 To be removed with Hathor */ public function getAuthors() { // Create a new query object. - $db = $this->getDbo(); + $db = $this->getDbo(); $query = $db->getQuery(true); // Construct the query @@ -358,33 +443,4 @@ public function getAuthors() // Return the result return $db->loadObjectList(); } - - /** - * Method to get a list of articles. - * Overridden to add a check for access levels. - * - * @return mixed An array of data items on success, false on failure. - * - * @since 1.6.1 - */ - public function getItems() - { - $items = parent::getItems(); - - if (JFactory::getApplication()->isClient('site')) - { - $groups = JFactory::getUser()->getAuthorisedViewLevels(); - - for ($x = 0, $count = count($items); $x < $count; $x++) - { - // Check the access level. Remove articles the user shouldn't see - if (!in_array($items[$x]->access, $groups)) - { - unset($items[$x]); - } - } - } - - return $items; - } } diff --git a/administrator/components/com_content/models/feature.php b/administrator/components/com_content/models/feature.php index 69fe1346bcc27..61b957a7276cf 100644 --- a/administrator/components/com_content/models/feature.php +++ b/administrator/components/com_content/models/feature.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_content/models/featured.php b/administrator/components/com_content/models/featured.php index c66dc0921f4f4..debab364c6492 100644 --- a/administrator/components/com_content/models/featured.php +++ b/administrator/components/com_content/models/featured.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -82,7 +82,7 @@ protected function getListQuery() $this->getState( 'list.select', 'a.id, a.title, a.alias, a.checked_out, a.checked_out_time, a.catid, a.state, a.access, a.created, a.hits,' . - 'a.featured, a.language, a.created_by_alias, a.publish_up, a.publish_down' + 'a.created_by, a.featured, a.language, a.created_by_alias, a.publish_up, a.publish_down, a.note' ) ); $query->from('#__content AS a'); @@ -104,9 +104,14 @@ protected function getListQuery() ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); // Join over the categories. - $query->select('c.title AS category_title') + $query->select('c.title AS category_title, c.created_user_id AS category_uid, c.level AS category_level') ->join('LEFT', '#__categories AS c ON c.id = a.catid'); + // Join over the parent categories. + $query->select('parent.title AS parent_category_title, parent.id AS parent_category_id, + parent.created_user_id AS parent_category_uid, parent.level AS parent_category_level') + ->join('LEFT', '#__categories AS parent ON parent.id = c.parent_id'); + // Join over the users for the author. $query->select('ua.name AS author_name') ->join('LEFT', '#__users AS ua ON ua.id = a.created_by'); @@ -114,21 +119,30 @@ protected function getListQuery() // Join on voting table if (JPluginHelper::isEnabled('content', 'vote')) { - $query->select('COALESCE(NULLIF(ROUND(v.rating_sum / v.rating_count, 0), 0), 0) AS rating, + $query->select('COALESCE(NULLIF(ROUND(v.rating_sum / v.rating_count, 0), 0), 0) AS rating, COALESCE(NULLIF(v.rating_count, 0), 0) as rating_count') ->join('LEFT', '#__content_rating AS v ON a.id = v.content_id'); } // Filter by access level. - if ($access = $this->getState('filter.access')) + $access = $this->getState('filter.access'); + + if (is_numeric($access)) { $query->where('a.access = ' . (int) $access); } + elseif (is_array($access)) + { + $access = ArrayHelper::toInteger($access); + $access = implode(',', $access); + $query->where('a.access IN (' . $access . ')'); + } // Filter by access level on categories. if (!$user->authorise('core.admin')) { $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); $query->where('c.access IN (' . $groups . ')'); } @@ -148,10 +162,10 @@ protected function getListQuery() $baselevel = 1; $categoryId = $this->getState('filter.category_id'); - if (is_numeric($categoryId)) + if (is_array($categoryId) && count($categoryId) === 1) { $cat_tbl = JTable::getInstance('Category', 'JTable'); - $cat_tbl->load($categoryId); + $cat_tbl->load($categoryId[0]); $rgt = $cat_tbl->rgt; $lft = $cat_tbl->lft; $baselevel = (int) $cat_tbl->level; @@ -178,6 +192,12 @@ protected function getListQuery() $type = $this->getState('filter.author_id.include', true) ? '= ' : '<>'; $query->where('a.created_by ' . $type . (int) $authorId); } + elseif (is_array($authorId)) + { + $authorId = ArrayHelper::toInteger($authorId); + $authorId = implode(',', $authorId); + $query->where('a.created_by IN (' . $authorId . ')'); + } // Filter by search in title. $search = $this->getState('filter.search'); @@ -193,10 +213,15 @@ protected function getListQuery() $search = $db->quote('%' . $db->escape(substr($search, 7), true) . '%'); $query->where('(ua.name LIKE ' . $search . ' OR ua.username LIKE ' . $search . ')'); } + elseif (stripos($search, 'content:') === 0) + { + $search = $db->quote('%' . $db->escape(substr($search, 8), true) . '%'); + $query->where('(a.introtext LIKE ' . $search . ' OR a.fulltext LIKE ' . $search . ')'); + } else { $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search); + $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); } } @@ -206,18 +231,38 @@ protected function getListQuery() $query->where('a.language = ' . $db->quote($language)); } - // Filter by a single tag. + // Filter by a single or group of tags. $tagId = $this->getState('filter.tag'); - if (is_numeric($tagId)) + if (is_array($tagId) && count($tagId) === 1) + { + $tagId = current($tagId); + } + + if (is_array($tagId)) { - $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId) - ->join( - 'LEFT', - $db->quoteName('#__contentitem_tag_map', 'tagmap') - . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') - . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_content.article') - ); + $tagId = implode(',', ArrayHelper::toInteger($tagId)); + + if ($tagId) + { + $subQuery = $db->getQuery(true) + ->select('DISTINCT content_item_id') + ->from($db->quoteName('#__contentitem_tag_map')) + ->where('tag_id IN (' . $tagId . ')') + ->where('type_alias = ' . $db->quote('com_content.article')); + + $query->join('INNER', '(' . (string) $subQuery . ') AS tagmap ON tagmap.content_item_id = a.id'); + } + } + elseif ($tagId) + { + $query->join( + 'INNER', + $db->quoteName('#__contentitem_tag_map', 'tagmap') + . ' ON tagmap.tag_id = ' . (int) $tagId + . ' AND tagmap.content_item_id = a.id' + . ' AND tagmap.type_alias = ' . $db->quote('com_content.article') + ); } // Add the list ordering clause. diff --git a/administrator/components/com_content/models/fields/modal/article.php b/administrator/components/com_content/models/fields/modal/article.php index 639db98ed1c5c..77f4e427e0dcb 100644 --- a/administrator/components/com_content/models/fields/modal/article.php +++ b/administrator/components/com_content/models/fields/modal/article.php @@ -3,11 +3,13 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; + +use Joomla\CMS\Language\LanguageHelper; /** * Supports a modal article picker. @@ -33,10 +35,13 @@ class JFormFieldModal_Article extends JFormField */ protected function getInput() { - $allowNew = ((string) $this->element['new'] == 'true'); - $allowEdit = ((string) $this->element['edit'] == 'true'); - $allowClear = ((string) $this->element['clear'] != 'false'); - $allowSelect = ((string) $this->element['select'] != 'false'); + $allowNew = ((string) $this->element['new'] == 'true'); + $allowEdit = ((string) $this->element['edit'] == 'true'); + $allowClear = ((string) $this->element['clear'] != 'false'); + $allowSelect = ((string) $this->element['select'] != 'false'); + $allowPropagate = ((string) $this->element['propagate'] == 'true'); + + $languages = LanguageHelper::getContentLanguages(array(0, 1)); // Load language JFactory::getLanguage()->load('com_content', JPATH_ADMINISTRATOR); @@ -69,6 +74,8 @@ function jSelectArticle_" . $this->id . "(id, title, catid, object, url, languag } "); + JText::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED'); + $scriptSelect[$this->id] = true; } } @@ -120,55 +127,72 @@ function jSelectArticle_" . $this->id . "(id, title, catid, object, url, languag // Select article button if ($allowSelect) { - $html .= '' . ' ' . JText::_('JSELECT') - . ''; + . ''; } // New article button if ($allowNew) { - $html .= '' . ' ' . JText::_('JACTION_CREATE') - . ''; + . ''; } // Edit article button if ($allowEdit) { - $html .= '' . ' ' . JText::_('JACTION_EDIT') - . ''; + . ''; } // Clear article button if ($allowClear) { - $html .= '' . '' . JText::_('JCLEAR') - . ''; + . ''; + } + + // Propagate article button + if ($allowPropagate && count($languages) > 2) + { + // Strip off language tag at the end + $tagLength = (int) strlen($this->element['language']); + $callbackFunctionStem = substr("jSelectArticle_" . $this->id, 0, -$tagLength); + + $html .= '' + . '' . JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_BUTTON') + . ''; } $html .= ''; @@ -186,7 +210,7 @@ function jSelectArticle_" . $this->id . "(id, title, catid, object, url, languag 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', + 'footer' => '', ) ); } @@ -207,15 +231,15 @@ function jSelectArticle_" . $this->id . "(id, title, catid, object, url, languag 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } @@ -236,15 +260,15 @@ function jSelectArticle_" . $this->id . "(id, title, catid, object, url, languag 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } @@ -253,7 +277,7 @@ function jSelectArticle_" . $this->id . "(id, title, catid, object, url, languag $class = $this->required ? ' class="required modal-value"' : ''; $html .= ''; + . '" data-text="' . htmlspecialchars(JText::_('COM_CONTENT_SELECT_AN_ARTICLE'), ENT_COMPAT, 'UTF-8') . '" value="' . $value . '" />'; return $html; } diff --git a/administrator/components/com_content/models/fields/votelist.php b/administrator/components/com_content/models/fields/votelist.php deleted file mode 100644 index c116dbcb8ee28..0000000000000 --- a/administrator/components/com_content/models/fields/votelist.php +++ /dev/null @@ -1,43 +0,0 @@ - + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JFormHelper::loadFieldClass('radio'); + +/** + * Voteradio Field class. + * + * @since 3.8.0 + */ +class JFormFieldVoteradio extends JFormFieldRadio +{ + /** + * The form field type. + * + * @var string + * @since 3.7.1 + */ + protected $type = 'Voteradio'; + + /** + * Method to get the field Label. + * + * @return array The field label objects. + * + * @throws \Exception + * + * @since 3.8.2 + */ + public function getLabel() + { + // Requires vote plugin enabled + return JPluginHelper::isEnabled('content', 'vote') ? parent::getLabel() : null; + } + + /** + * Method to get the field options. + * + * @return array The field option objects. + * + * @throws \Exception + * + * @since 3.7.1 + */ + public function getOptions() + { + // Requires vote plugin enabled + return JPluginHelper::isEnabled('content', 'vote') ? parent::getOptions() : array(); + } +} diff --git a/administrator/components/com_content/models/forms/article.xml b/administrator/components/com_content/models/forms/article.xml index c41a0dad11589..70cafe44b1856 100644 --- a/administrator/components/com_content/models/forms/article.xml +++ b/administrator/components/com_content/models/forms/article.xml @@ -1,45 +1,55 @@
    - - - - - + + - - @@ -72,7 +82,7 @@ - - - - - - - - - - - - - - - - - - JNO - @@ -272,13 +282,13 @@
    - @@ -306,7 +316,7 @@ - JHIDE - - -
    @@ -662,7 +672,7 @@ description="JGLOBAL_LINKED_TITLES_DESC" /> - - -
    - @@ -813,9 +823,9 @@ name="image_intro" type="media" label="COM_CONTENT_FIELD_INTRO_LABEL" - description="COM_CONTENT_FIELD_INTRO_DESC" + description="COM_CONTENT_FIELD_INTRO_DESC" /> - + COM_CONTENT_LEFT - - - COM_CONTENT_NONE - - - - - - - - - - + + + + - - -
    - - diff --git a/administrator/components/com_content/models/forms/filter_articles.xml b/administrator/components/com_content/models/forms/filter_articles.xml index e41c8d0d5e00f..5424ca76a8133 100644 --- a/administrator/components/com_content/models/forms/filter_articles.xml +++ b/administrator/components/com_content/models/forms/filter_articles.xml @@ -4,6 +4,7 @@ - - + /> - - + /> - + - - + /> - +
    + @@ -96,6 +100,7 @@ description="COM_CONTENT_LIST_FULL_ORDERING_DESC" onchange="this.form.submit();" default="a.id DESC" + validate="options" > diff --git a/administrator/components/com_content/models/forms/filter_featured.xml b/administrator/components/com_content/models/forms/filter_featured.xml index fe5b19b2a7155..f35655df012f3 100644 --- a/administrator/components/com_content/models/forms/filter_featured.xml +++ b/administrator/components/com_content/models/forms/filter_featured.xml @@ -4,6 +4,7 @@ + + - + - - + /> - + - - - - - - + /> @@ -95,6 +98,7 @@ description="COM_CONTENT_LIST_FULL_ORDERING_DESC" onchange="this.form.submit();" default="a.title ASC" + validate="options" > diff --git a/administrator/components/com_content/tables/featured.php b/administrator/components/com_content/tables/featured.php index b472a692d7d38..f2547a995fdde 100644 --- a/administrator/components/com_content/tables/featured.php +++ b/administrator/components/com_content/tables/featured.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -19,7 +19,7 @@ class ContentTableFeatured extends JTable /** * Constructor * - * @param JDatabaseDriver &$db Database connector object + * @param JDatabaseDriver $db Database connector object * * @since 1.6 */ diff --git a/administrator/components/com_content/views/article/tmpl/edit.php b/administrator/components/com_content/views/article/tmpl/edit.php index 0c556a40c7d60..67a315f61a7e8 100644 --- a/administrator/components/com_content/views/article/tmpl/edit.php +++ b/administrator/components/com_content/views/article/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -17,6 +17,7 @@ JHtml::_('behavior.formvalidator'); JHtml::_('behavior.keepalive'); JHtml::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0 )); +JHtml::_('formbehavior.chosen', '#jform_tags', null, array('placeholder_text_multiple' => JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_TAGS'))); JHtml::_('formbehavior.chosen', 'select'); $this->configFieldsets = array('editorConfig'); @@ -24,7 +25,7 @@ $this->ignore_fieldsets = array('jmetadata', 'item_associations'); // Create shortcut to parameters. -$params = clone($this->state->get('params')); +$params = clone $this->state->get('params'); $params->merge(new Registry($this->item->attribs)); $app = JFactory::getApplication(); @@ -136,7 +137,7 @@ - +
    diff --git a/administrator/components/com_content/views/article/tmpl/edit_associations.php b/administrator/components/com_content/views/article/tmpl/edit_associations.php index 76cd3dd2e934f..0e7c8da50b876 100644 --- a/administrator/components/com_content/views/article/tmpl/edit_associations.php +++ b/administrator/components/com_content/views/article/tmpl/edit_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_content/views/article/tmpl/edit_metadata.php b/administrator/components/com_content/views/article/tmpl/edit_metadata.php index 8560b8731de23..7429d10eb29b6 100644 --- a/administrator/components/com_content/views/article/tmpl/edit_metadata.php +++ b/administrator/components/com_content/views/article/tmpl/edit_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_content/views/article/tmpl/modal.php b/administrator/components/com_content/views/article/tmpl/modal.php index 84b0775f5a2a0..10adcfdf5a507 100644 --- a/administrator/components/com_content/views/article/tmpl/modal.php +++ b/administrator/components/com_content/views/article/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_content/views/article/tmpl/modal_associations.php b/administrator/components/com_content/views/article/tmpl/modal_associations.php index 76cd3dd2e934f..cdc27f6ce3c93 100644 --- a/administrator/components/com_content/views/article/tmpl/modal_associations.php +++ b/administrator/components/com_content/views/article/tmpl/modal_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_content/views/article/tmpl/modal_metadata.php b/administrator/components/com_content/views/article/tmpl/modal_metadata.php index 8560b8731de23..650cc2571fd27 100644 --- a/administrator/components/com_content/views/article/tmpl/modal_metadata.php +++ b/administrator/components/com_content/views/article/tmpl/modal_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_content/views/article/tmpl/pagebreak.php b/administrator/components/com_content/views/article/tmpl/pagebreak.php index 2941fa70722e0..3907fd853b108 100644 --- a/administrator/components/com_content/views/article/tmpl/pagebreak.php +++ b/administrator/components/com_content/views/article/tmpl/pagebreak.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_content/views/article/view.html.php b/administrator/components/com_content/views/article/view.html.php index 299957ef8902a..58ce1d749bd35 100644 --- a/administrator/components/com_content/views/article/view.html.php +++ b/administrator/components/com_content/views/article/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -57,7 +57,6 @@ public function display($tpl = null) { if ($this->getLayout() == 'pagebreak') { - return parent::display($tpl); } @@ -151,6 +150,11 @@ protected function addToolbar() JToolbarHelper::versions('com_content.article', $this->item->id); } + if (JLanguageAssociations::isEnabled() && JComponentHelper::isEnabled('com_associations')) + { + JToolbarHelper::custom('article.editAssociations', 'contract', 'contract', 'JTOOLBAR_ASSOCIATIONS', false, false); + } + JToolbarHelper::cancel('article.cancel', 'JTOOLBAR_CLOSE'); } diff --git a/administrator/components/com_content/views/articles/tmpl/default.php b/administrator/components/com_content/views/articles/tmpl/default.php index 6afa9bef0fa63..0667cd387bcb6 100644 --- a/administrator/components/com_content/views/articles/tmpl/default.php +++ b/administrator/components/com_content/views/articles/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -13,6 +13,10 @@ JHtml::_('bootstrap.tooltip'); JHtml::_('behavior.multiselect'); +JHtml::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG'))); +JHtml::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_CATEGORY'))); +JHtml::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_ACCESS'))); +JHtml::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_AUTHOR'))); JHtml::_('formbehavior.chosen', 'select'); $app = JFactory::getApplication(); @@ -133,6 +137,10 @@ $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; $canEditOwn = $user->authorise('core.edit.own', 'com_content.article.' . $item->id) && $item->created_by == $userId; $canChange = $user->authorise('core.edit.state', 'com_content.article.' . $item->id) && $canCheckin; + $canEditCat = $user->authorise('core.edit', 'com_content.category.' . $item->catid); + $canEditOwnCat = $user->authorise('core.edit.own', 'com_content.category.' . $item->catid) && $item->category_uid == $userId; + $canEditParCat = $user->authorise('core.edit', 'com_content.category.' . $item->parent_category_id); + $canEditOwnParCat = $user->authorise('core.edit.own', 'com_content.category.' . $item->parent_category_id) && $item->parent_category_uid == $userId; ?> @@ -183,10 +191,68 @@ escape($item->title); ?> - escape($item->alias)); ?> + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> +
    - escape($item->category_title); ?> + parent_category_id . '&extension=com_content'); + $CurrentCatUrl = JRoute::_('index.php?option=com_categories&task=category.edit&id=' . $item->catid . '&extension=com_content'); + $EditCatTxt = JText::_('COM_CONTENT_EDIT_CATEGORY'); + + echo JText::_('JCATEGORY') . ': '; + + if ($item->category_level != '1') : + if ($item->parent_category_level != '1') : + echo ' » '; + endif; + endif; + + if (JFactory::getLanguage()->isRtl()) + { + if ($canEditCat || $canEditOwnCat) : + echo ''; + endif; + echo $this->escape($item->category_title); + if ($canEditCat || $canEditOwnCat) : + echo ''; + endif; + + if ($item->category_level != '1') : + echo ' « '; + if ($canEditParCat || $canEditOwnParCat) : + echo ''; + endif; + echo $this->escape($item->parent_category_title); + if ($canEditParCat || $canEditOwnParCat) : + echo ''; + endif; + endif; + } + else + { + if ($item->category_level != '1') : + if ($canEditParCat || $canEditOwnParCat) : + echo ''; + endif; + echo $this->escape($item->parent_category_title); + if ($canEditParCat || $canEditOwnParCat) : + echo ''; + endif; + echo ' » '; + endif; + if ($canEditCat || $canEditOwnCat) : + echo ''; + endif; + echo $this->escape($item->category_title); + if ($canEditCat || $canEditOwnCat) : + echo ''; + endif; + } + ?>
    @@ -201,13 +267,22 @@ - created_by_alias) : ?> - - escape($item->author_name); ?> -
    escape($item->created_by_alias)); ?>
    + created_by != 0) : ?> + created_by_alias) : ?> + + escape($item->author_name); ?> +
    escape($item->created_by_alias)); ?>
    + + + escape($item->author_name); ?> + - - escape($item->author_name); ?> + created_by_alias) : ?> + +
    escape($item->created_by_alias)); ?>
    + + + diff --git a/administrator/components/com_content/views/articles/tmpl/default.xml b/administrator/components/com_content/views/articles/tmpl/default.xml index b3dec7f7be330..2e95d9f9d7823 100755 --- a/administrator/components/com_content/views/articles/tmpl/default.xml +++ b/administrator/components/com_content/views/articles/tmpl/default.xml @@ -5,4 +5,80 @@ + + +
    + + + + + + + + + + + + + + + + + + + +
    +
    + diff --git a/administrator/components/com_content/views/articles/tmpl/default_batch_body.php b/administrator/components/com_content/views/articles/tmpl/default_batch_body.php index 0e4b61a3e5aba..f3e8f971068dd 100644 --- a/administrator/components/com_content/views/articles/tmpl/default_batch_body.php +++ b/administrator/components/com_content/views/articles/tmpl/default_batch_body.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -$published = $this->state->get('filter.published'); +$published = (int) $this->state->get('filter.published'); ?>
    diff --git a/administrator/components/com_content/views/articles/tmpl/default_batch_footer.php b/administrator/components/com_content/views/articles/tmpl/default_batch_footer.php index d31131ee2c927..c234b720af021 100644 --- a/administrator/components/com_content/views/articles/tmpl/default_batch_footer.php +++ b/administrator/components/com_content/views/articles/tmpl/default_batch_footer.php @@ -3,15 +3,15 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - + + \ No newline at end of file + diff --git a/administrator/components/com_content/views/articles/tmpl/modal.php b/administrator/components/com_content/views/articles/tmpl/modal.php index 5f524f1d8f554..bb478ae8fcdbd 100644 --- a/administrator/components/com_content/views/articles/tmpl/modal.php +++ b/administrator/components/com_content/views/articles/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -25,6 +25,12 @@ JHtml::_('behavior.polyfill', array('event'), 'lt IE 9'); JHtml::_('script', 'com_content/admin-articles-modal.min.js', array('version' => 'auto', 'relative' => true)); JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); +JHtml::_('behavior.multiselect'); +JHtml::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG'))); +JHtml::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_CATEGORY'))); +JHtml::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_ACCESS'))); +JHtml::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_AUTHOR'))); JHtml::_('formbehavior.chosen', 'select'); // Special case for the search field tooltip. @@ -124,14 +130,20 @@ escape($onclick) . '"' . ' data-id="' . $item->id . '"' - . ' data-title="' . $this->escape(addslashes($item->title)) . '"' + . ' data-title="' . $this->escape($item->title) . '"' . ' data-cat-id="' . $this->escape($item->catid) . '"' . ' data-uri="' . $this->escape(ContentHelperRoute::getArticleRoute($item->id, $item->catid, $item->language)) . '"' . ' data-language="' . $this->escape($lang) . '"'; ?> > - escape($item->title); ?> - + escape($item->title); ?> + + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + +
    escape($item->category_title); ?>
    diff --git a/administrator/components/com_content/views/articles/view.html.php b/administrator/components/com_content/views/articles/view.html.php index 00a8b867cb439..57d00af537000 100644 --- a/administrator/components/com_content/views/articles/view.html.php +++ b/administrator/components/com_content/views/articles/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -20,6 +20,8 @@ class ContentViewArticles extends JViewLegacy * The item authors * * @var stdClass + * + * @deprecated 4.0 To be removed with Hathor */ protected $authors; @@ -94,6 +96,7 @@ public function display($tpl = null) } // Levels filter - Used in Hathor. + // @deprecated 4.0 To be removed with Hathor $this->f_levels = array( JHtml::_('select.option', '1', JText::_('J1')), JHtml::_('select.option', '2', JText::_('J2')), @@ -119,7 +122,7 @@ public function display($tpl = null) // We also need to change the category filter to show show categories with All or the forced language. if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) { - // If the language is forced we can't allow to select the language, so transform the language selector filter into an hidden field. + // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. $languageXml = new SimpleXMLElement(''); $this->filterForm->setField($languageXml, 'filter', true); @@ -151,12 +154,12 @@ protected function addToolbar() JToolbarHelper::title(JText::_('COM_CONTENT_ARTICLES_TITLE'), 'stack article'); - if ($canDo->get('core.create') || (count($user->getAuthorisedCategories('com_content', 'core.create'))) > 0) + if ($canDo->get('core.create') || count($user->getAuthorisedCategories('com_content', 'core.create')) > 0) { JToolbarHelper::addNew('article.add'); } - if (($canDo->get('core.edit')) || ($canDo->get('core.edit.own'))) + if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) { JToolbarHelper::editList('article.edit'); } diff --git a/administrator/components/com_content/views/featured/tmpl/default.php b/administrator/components/com_content/views/featured/tmpl/default.php index cd7c4ed7ff5c3..345e05d1bacb1 100644 --- a/administrator/components/com_content/views/featured/tmpl/default.php +++ b/administrator/components/com_content/views/featured/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -13,6 +13,10 @@ JHtml::_('bootstrap.tooltip'); JHtml::_('behavior.multiselect'); +JHtml::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_ACCESS'))); +JHtml::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_AUTHOR'))); +JHtml::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_CATEGORY'))); +JHtml::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG'))); JHtml::_('formbehavior.chosen', 'select'); $user = JFactory::getUser(); @@ -116,12 +120,16 @@ items); ?> items as $i => $item) : $item->max_ordering = 0; - $ordering = ($listOrder == 'fp.ordering'); - $assetId = 'com_content.article.' . $item->id; - $canCreate = $user->authorise('core.create', 'com_content.category.' . $item->catid); - $canEdit = $user->authorise('core.edit', 'com_content.article.' . $item->id); - $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; - $canChange = $user->authorise('core.edit.state', 'com_content.article.' . $item->id) && $canCheckin; + $ordering = ($listOrder == 'fp.ordering'); + $assetId = 'com_content.article.' . $item->id; + $canCreate = $user->authorise('core.create', 'com_content.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_content.article.' . $item->id); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_content.article.' . $item->id) && $canCheckin; + $canEditCat = $user->authorise('core.edit', 'com_content.category.' . $item->catid); + $canEditOwnCat = $user->authorise('core.edit.own', 'com_content.category.' . $item->catid) && $item->category_uid == $userId; + $canEditParCat = $user->authorise('core.edit', 'com_content.category.' . $item->parent_category_id); + $canEditOwnParCat = $user->authorise('core.edit.own', 'com_content.category.' . $item->parent_category_id) && $item->parent_category_uid == $userId; ?> @@ -173,10 +181,68 @@ escape($item->title); ?> - escape($item->alias)); ?> - + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + +
    - escape($item->category_title); ?> + parent_category_id . '&extension=com_content'); + $CurrentCatUrl = JRoute::_('index.php?option=com_categories&task=category.edit&id=' . $item->catid . '&extension=com_content'); + $EditCatTxt = JText::_('COM_CONTENT_EDIT_CATEGORY'); + + echo JText::_('JCATEGORY') . ': '; + + if ($item->category_level != '1') : + if ($item->parent_category_level != '1') : + echo ' » '; + endif; + endif; + + if (JFactory::getLanguage()->isRtl()) + { + if ($canEditCat || $canEditOwnCat) : + echo ''; + endif; + echo $this->escape($item->category_title); + if ($canEditCat || $canEditOwnCat) : + echo ''; + endif; + + if ($item->category_level != '1') : + echo ' « '; + if ($canEditParCat || $canEditOwnParCat) : + echo ''; + endif; + echo $this->escape($item->parent_category_title); + if ($canEditParCat || $canEditOwnParCat) : + echo ''; + endif; + endif; + } + else + { + if ($item->category_level != '1') : + if ($canEditParCat || $canEditOwnParCat) : + echo ''; + endif; + echo $this->escape($item->parent_category_title); + if ($canEditParCat || $canEditOwnParCat) : + echo ''; + endif; + echo ' » '; + endif; + if ($canEditCat || $canEditOwnCat) : + echo ''; + endif; + echo $this->escape($item->category_title); + if ($canEditCat || $canEditOwnCat) : + echo ''; + endif; + } + ?>
    @@ -184,11 +250,22 @@ escape($item->access_level); ?> - created_by_alias) : ?> - escape($item->author_name); ?> -

    escape($item->created_by_alias)); ?>

    + created_by != 0) : ?> + created_by_alias) : ?> + + escape($item->author_name); ?> +
    escape($item->created_by_alias)); ?>
    + + + escape($item->author_name); ?> + - escape($item->author_name); ?> + created_by_alias) : ?> + +
    escape($item->created_by_alias)); ?>
    + + + diff --git a/administrator/components/com_content/views/featured/view.html.php b/administrator/components/com_content/views/featured/view.html.php index 9f2529c9c3c12..e74b19ecc1d86 100644 --- a/administrator/components/com_content/views/featured/view.html.php +++ b/administrator/components/com_content/views/featured/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -20,6 +20,8 @@ class ContentViewFeatured extends JViewLegacy * The item authors * * @var stdClass + * + * @deprecated 4.0 To be removed with Hathor */ protected $authors; @@ -91,6 +93,7 @@ public function display($tpl = null) } // Levels filter - Used in Hathor. + // @deprecated 4.0 To be removed with Hathor $this->f_levels = array( JHtml::_('select.option', '1', JText::_('J1')), JHtml::_('select.option', '2', JText::_('J2')), diff --git a/administrator/components/com_contenthistory/contenthistory.php b/administrator/components/com_contenthistory/contenthistory.php index e77df780dbc03..c0e07cc909224 100644 --- a/administrator/components/com_contenthistory/contenthistory.php +++ b/administrator/components/com_contenthistory/contenthistory.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contenthistory/contenthistory.xml b/administrator/components/com_contenthistory/contenthistory.xml index 3053b02441307..23f8b934725b3 100644 --- a/administrator/components/com_contenthistory/contenthistory.xml +++ b/administrator/components/com_contenthistory/contenthistory.xml @@ -3,7 +3,7 @@ com_contenthistory Joomla! Project May 2013 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2013 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_contenthistory/controller.php b/administrator/components/com_contenthistory/controller.php index e7187bb833463..f9cabf44fb278 100644 --- a/administrator/components/com_contenthistory/controller.php +++ b/administrator/components/com_contenthistory/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contenthistory/controllers/history.php b/administrator/components/com_contenthistory/controllers/history.php index a41d010d73ad5..8cd4028dce8c7 100644 --- a/administrator/components/com_contenthistory/controllers/history.php +++ b/administrator/components/com_contenthistory/controllers/history.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -27,7 +27,7 @@ class ContenthistoryControllerHistory extends JControllerAdmin */ public function delete() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Get items to remove from the request. $cid = $this->input->get('cid', array(), 'array'); @@ -89,7 +89,7 @@ public function getModel($name = 'History', $prefix = 'ContenthistoryModel', $co */ public function keep() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Get items to remove from the request. $cid = $this->input->get('cid', array(), 'array'); diff --git a/administrator/components/com_contenthistory/controllers/preview.php b/administrator/components/com_contenthistory/controllers/preview.php index 2d18cbe9ef611..f437d0a85b42c 100644 --- a/administrator/components/com_contenthistory/controllers/preview.php +++ b/administrator/components/com_contenthistory/controllers/preview.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contenthistory/helpers/contenthistory.php b/administrator/components/com_contenthistory/helpers/contenthistory.php index 2b5801ea75710..3a33d5256bed1 100644 --- a/administrator/components/com_contenthistory/helpers/contenthistory.php +++ b/administrator/components/com_contenthistory/helpers/contenthistory.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contenthistory/helpers/html/textdiff.php b/administrator/components/com_contenthistory/helpers/html/textdiff.php index 01906194ec875..b31c799798594 100644 --- a/administrator/components/com_contenthistory/helpers/html/textdiff.php +++ b/administrator/components/com_contenthistory/helpers/html/textdiff.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contenthistory/models/compare.php b/administrator/components/com_contenthistory/models/compare.php index e753b3cc788c7..ab9515769aaad 100644 --- a/administrator/components/com_contenthistory/models/compare.php +++ b/administrator/components/com_contenthistory/models/compare.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -37,6 +37,14 @@ public function getItems() $id1 = $input->getInt('id1'); $id2 = $input->getInt('id2'); + + if (!$id1 || \is_array($id1) || !$id2 || \is_array($id2)) + { + $this->setError(\JText::_('COM_CONTENTHISTORY_ERROR_INVALID_ID')); + + return false; + } + $result = array(); if ($table1->load($id1) && $table2->load($id2)) @@ -48,6 +56,8 @@ public function getItems() if (!$contentTypeTable->load($ucmTypeId)) { + $this->setError(\JText::_('COM_CONTENTHISTORY_ERROR_FAILED_LOADING_CONTENT_TYPE')); + // Assume a failure to load the content type means broken data, abort mission return false; } @@ -76,7 +86,7 @@ public function getItems() $object->version_note = $table->version_note; // Let's use custom calendars when present - $object->save_date = JHtml::_('date', $table->save_date, 'Y-m-d H:i:s'); + $object->save_date = JHtml::_('date', $table->save_date, JText::_('DATE_FORMAT_LC6')); $dateProperties = array ( 'modified_time', @@ -90,9 +100,9 @@ public function getItems() foreach ($dateProperties as $dateProperty) { - if (array_key_exists($dateProperty, $object->data) && $object->data->$dateProperty->value != '0000-00-00 00:00:00') + if (property_exists($object->data, $dateProperty) && $object->data->$dateProperty->value != '0000-00-00 00:00:00') { - $object->data->$dateProperty->value = JHtml::_('date', $object->data->$dateProperty->value, 'Y-m-d H:i:s'); + $object->data->$dateProperty->value = JHtml::_('date', $object->data->$dateProperty->value, JText::_('DATE_FORMAT_LC6')); } } @@ -103,6 +113,8 @@ public function getItems() } } + $this->setError(\JText::_('COM_CONTENTHISTORY_ERROR_VERSION_NOT_FOUND')); + return false; } diff --git a/administrator/components/com_contenthistory/models/history.php b/administrator/components/com_contenthistory/models/history.php index 166b5927cc4dd..7b767bfa800a2 100644 --- a/administrator/components/com_contenthistory/models/history.php +++ b/administrator/components/com_contenthistory/models/history.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -98,13 +98,13 @@ protected function canEdit($record) */ protected function canDelete($record) { - return canEdit($record); + return $this->canEdit($record); } /** * Method to delete one or more records from content history table. * - * @param array &$pks An array of record primary keys. + * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * @@ -120,6 +120,12 @@ public function delete(&$pks) { if ($table->load($pk)) { + if ((int) $table->keep_forever === 1) + { + unset($pks[$i]); + continue; + } + if ($this->canEdit($table)) { if (!$table->delete($pk)) @@ -243,7 +249,7 @@ public function getTable($type = 'Contenthistory', $prefix = 'JTable', $config = /** * Method to toggle on and off the keep forever value for one or more records from content history table. * - * @param array &$pks An array of record primary keys. + * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * diff --git a/administrator/components/com_contenthistory/models/preview.php b/administrator/components/com_contenthistory/models/preview.php index 334da24e88659..b936fecfc1e6d 100644 --- a/administrator/components/com_contenthistory/models/preview.php +++ b/administrator/components/com_contenthistory/models/preview.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -68,7 +68,7 @@ public function getItem() $result->data = ContenthistoryHelper::prepareData($table); // Let's use custom calendars when present - $result->save_date = JHtml::_('date', $table->save_date, 'Y-m-d H:i:s'); + $result->save_date = JHtml::_('date', $table->save_date, JText::_('DATE_FORMAT_LC6')); $dateProperties = array ( 'modified_time', @@ -82,9 +82,9 @@ public function getItem() foreach ($dateProperties as $dateProperty) { - if (array_key_exists($dateProperty, $result->data) && $result->data->$dateProperty->value != '0000-00-00 00:00:00') + if (property_exists($result->data, $dateProperty) && $result->data->$dateProperty->value != '0000-00-00 00:00:00') { - $result->data->$dateProperty->value = JHtml::_('date', $result->data->$dateProperty->value, 'Y-m-d H:i:s'); + $result->data->$dateProperty->value = JHtml::_('date', $result->data->$dateProperty->value, JText::_('DATE_FORMAT_LC6')); } } diff --git a/administrator/components/com_contenthistory/views/compare/tmpl/compare.php b/administrator/components/com_contenthistory/views/compare/tmpl/compare.php index 84fb6ae42a968..98c569acc3b0c 100644 --- a/administrator/components/com_contenthistory/views/compare/tmpl/compare.php +++ b/administrator/components/com_contenthistory/views/compare/tmpl/compare.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contenthistory/views/compare/view.html.php b/administrator/components/com_contenthistory/views/compare/view.html.php index d02063defff09..01216e4618171 100644 --- a/administrator/components/com_contenthistory/views/compare/view.html.php +++ b/administrator/components/com_contenthistory/views/compare/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contenthistory/views/history/tmpl/modal.php b/administrator/components/com_contenthistory/views/history/tmpl/modal.php index ce6de9d985568..71eec94860f05 100644 --- a/administrator/components/com_contenthistory/views/history/tmpl/modal.php +++ b/administrator/components/com_contenthistory/views/history/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -147,7 +147,7 @@ - save_date, 'Y-m-d H:i:s'); ?> + save_date, JText::_('DATE_FORMAT_LC6')); ?> sha1_hash == $hash) : ?>   diff --git a/administrator/components/com_contenthistory/views/history/view.html.php b/administrator/components/com_contenthistory/views/history/view.html.php index c26fcdc291b72..0e2cd0b2ff4a0 100644 --- a/administrator/components/com_contenthistory/views/history/view.html.php +++ b/administrator/components/com_contenthistory/views/history/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contenthistory/views/preview/tmpl/preview.php b/administrator/components/com_contenthistory/views/preview/tmpl/preview.php index 5243c14f14bfb..0b92e59954706 100644 --- a/administrator/components/com_contenthistory/views/preview/tmpl/preview.php +++ b/administrator/components/com_contenthistory/views/preview/tmpl/preview.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_contenthistory/views/preview/view.html.php b/administrator/components/com_contenthistory/views/preview/view.html.php index 84d1932eb2de7..bf2aa9d8eedc2 100644 --- a/administrator/components/com_contenthistory/views/preview/view.html.php +++ b/administrator/components/com_contenthistory/views/preview/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_contenthistory * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_cpanel/controller.php b/administrator/components/com_cpanel/controller.php index 8b6415e5c56d0..59385ed681627 100644 --- a/administrator/components/com_cpanel/controller.php +++ b/administrator/components/com_cpanel/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cpanel * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_cpanel/cpanel.php b/administrator/components/com_cpanel/cpanel.php index 69e7e5853586e..aafa986db7126 100644 --- a/administrator/components/com_cpanel/cpanel.php +++ b/administrator/components/com_cpanel/cpanel.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cpanel * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_cpanel/cpanel.xml b/administrator/components/com_cpanel/cpanel.xml index 4db0bcf6e3ced..1b959245df079 100644 --- a/administrator/components/com_cpanel/cpanel.xml +++ b/administrator/components/com_cpanel/cpanel.xml @@ -2,8 +2,8 @@ com_cpanel Joomla! Project - April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + Jun 2007 + (C) 2007 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_cpanel/views/cpanel/tmpl/default.php b/administrator/components/com_cpanel/views/cpanel/tmpl/default.php index 6250e9d38af30..7fcd767fe4b38 100644 --- a/administrator/components/com_cpanel/views/cpanel/tmpl/default.php +++ b/administrator/components/com_cpanel/views/cpanel/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cpanel * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -28,13 +28,13 @@
    -
    +
    authorise('core.manage', 'com_postinstall') && $this->postinstall_message_count) : ?>
    -

    +

    -

    +

    diff --git a/administrator/components/com_cpanel/views/cpanel/view.html.php b/administrator/components/com_cpanel/views/cpanel/view.html.php index 54e05b29a4da0..7a2cd7a92a7a0 100644 --- a/administrator/components/com_cpanel/views/cpanel/view.html.php +++ b/administrator/components/com_cpanel/views/cpanel/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_cpanel * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_fields/controller.php b/administrator/components/com_fields/controller.php index b3bbeed9ff8ec..6153d24ab5c30 100644 --- a/administrator/components/com_fields/controller.php +++ b/administrator/components/com_fields/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/controllers/field.php b/administrator/components/com_fields/controllers/field.php index d2205e87d837a..e8749631711d4 100644 --- a/administrator/components/com_fields/controllers/field.php +++ b/administrator/components/com_fields/controllers/field.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -46,44 +46,6 @@ public function __construct($config = array()) $this->component = $parts ? $parts[0] : null; } - /** - * Stores the form data into the user state. - * - * @return void - * - * @since 3.7.0 - */ - public function storeform() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $data = $this->input->get($this->input->get('formcontrol', 'jform'), array(), 'array'); - - $parts = FieldsHelper::extract($this->input->getCmd('context')); - - if ($parts) - { - $app->setUserState($parts[0] . '.edit.' . $parts[1] . '.data', $data); - } - - if ($this->input->get('userstatevariable')) - { - $app->setUserState($this->input->get('userstatevariable'), $data); - } - - $redirectUrl = base64_decode($this->input->get->getBase64('return')); - - // Don't redirect to an external URL. - If (!JUri::isInternal($redirectUrl)) - { - $redirectUrl = 'index.php'; - } - - $app->redirect($redirectUrl); - $app->close(); - } - /** * Method override to check if you can add a new record. * @@ -111,12 +73,12 @@ protected function allowAdd($data = array()) protected function allowEdit($data = array(), $key = 'id') { $recordId = (int) isset($data[$key]) ? $data[$key] : 0; - $user = JFactory::getUser(); + $user = JFactory::getUser(); - // Check general edit permission first. - if ($user->authorise('core.edit', $this->component)) + // Zero record (id:0), return component edit permission by calling parent controller method + if (!$recordId) { - return true; + return parent::allowEdit($data, $key); } // Check edit on the record asset (explicit or inherited) @@ -137,7 +99,7 @@ protected function allowEdit($data = array(), $key = 'id') } // Grant if current user is owner of the record - return $user->id == $record->created_by; + return $user->id == $record->created_user_id; } return false; @@ -154,7 +116,7 @@ protected function allowEdit($data = array(), $key = 'id') */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Set the model $model = $this->getModel('Field'); diff --git a/administrator/components/com_fields/controllers/fields.php b/administrator/components/com_fields/controllers/fields.php index 5d98d5a14c3b3..c4ca2aa5b5de4 100644 --- a/administrator/components/com_fields/controllers/fields.php +++ b/administrator/components/com_fields/controllers/fields.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/controllers/group.php b/administrator/components/com_fields/controllers/group.php index aa3277e258838..cd5ef8cdbc6c5 100644 --- a/administrator/components/com_fields/controllers/group.php +++ b/administrator/components/com_fields/controllers/group.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -64,7 +64,7 @@ public function __construct($config = array()) */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Set the model $model = $this->getModel('Group'); @@ -104,10 +104,10 @@ protected function allowEdit($data = array(), $key = 'parent_id') $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $user = JFactory::getUser(); - // Check general edit permission first. - if ($user->authorise('core.edit', $this->component)) + // Zero record (parent_id:0), return component edit permission by calling parent controller method + if (!$recordId) { - return true; + return parent::allowEdit($data, $key); } // Check edit on the record asset (explicit or inherited) diff --git a/administrator/components/com_fields/controllers/groups.php b/administrator/components/com_fields/controllers/groups.php index 8b051a1fb13e9..6d4882a5b03f7 100644 --- a/administrator/components/com_fields/controllers/groups.php +++ b/administrator/components/com_fields/controllers/groups.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/fields.php b/administrator/components/com_fields/fields.php index 0b806a0d3d4ca..43cab3c2eb9b4 100644 --- a/administrator/components/com_fields/fields.php +++ b/administrator/components/com_fields/fields.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/fields.xml b/administrator/components/com_fields/fields.xml index 63bdec64a3986..2a3b6e779026b 100644 --- a/administrator/components/com_fields/fields.xml +++ b/administrator/components/com_fields/fields.xml @@ -3,7 +3,7 @@ com_fields Joomla! Project March 2016 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2016 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_fields/helpers/fields.php b/administrator/components/com_fields/helpers/fields.php index aedb4666112b0..da442b4bfd981 100644 --- a/administrator/components/com_fields/helpers/fields.php +++ b/administrator/components/com_fields/helpers/fields.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -79,7 +79,7 @@ public static function extract($contextString, $item = null) * * @param string $context The context of the content passed to the helper * @param stdClass $item item - * @param boolean $prepareValue prepareValue + * @param int|bool $prepareValue (if int is display event): 1 - AfterTitle, 2 - BeforeDisplay, 3 - AfterDisplay, 0 - OFF * @param array $valuesToOverride The values to override * * @return array @@ -90,8 +90,7 @@ public static function getFields($context, $item = null, $prepareValue = false, { if (self::$fieldsCache === null) { - // Load the model - JLoader::import('joomla.application.component.model'); + // Load the model JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_fields/models', 'FieldsModel'); self::$fieldsCache = JModelLegacy::getInstance('Fields', 'FieldsModel', array( @@ -106,11 +105,14 @@ public static function getFields($context, $item = null, $prepareValue = false, { $item = (object) $item; } - if (JLanguageMultilang::isEnabled() && isset($item->language) && $item->language !='*') + + if (JLanguageMultilang::isEnabled() && isset($item->language) && $item->language != '*') { self::$fieldsCache->setState('filter.language', array('*', $item->language)); } + self::$fieldsCache->setState('filter.context', $context); + self::$fieldsCache->setState('filter.assigned_cat_ids', array()); /* * If item has assigned_cat_ids parameter display only fields which @@ -146,7 +148,7 @@ public static function getFields($context, $item = null, $prepareValue = false, } $fieldIds = array_map( - function($f) + function ($f) { return $f->id; }, @@ -185,13 +187,14 @@ function($f) $field->rawvalue = $field->value; - if ($prepareValue) + // If boolean prepare, if int, it is the event type: 1 - After Title, 2 - Before Display, 3 - After Display, 0 - Do not prepare + if ($prepareValue && (is_bool($prepareValue) || $prepareValue === (int) $field->params->get('display', '2'))) { JPluginHelper::importPlugin('fields'); $dispatcher = JEventDispatcher::getInstance(); - // Event allow plugins to modfify the output of the field before it is prepared + // Event allow plugins to modify the output of the field before it is prepared $dispatcher->trigger('onCustomFieldsBeforePrepareField', array($context, $item, &$field)); // Gathering the value for the field @@ -199,10 +202,10 @@ function($f) if (is_array($value)) { - $value = implode($value, ' '); + $value = implode(' ', $value); } - // Event allow plugins to modfify the output of the prepared field + // Event allow plugins to modify the output of the prepared field $dispatcher->trigger('onCustomFieldsAfterPrepareField', array($context, $item, $field, &$value)); // Assign the value @@ -277,6 +280,8 @@ public static function prepareForm($context, JForm $form, $data) return true; } + $context = $parts[0] . '.' . $parts[1]; + // When no fields available return here $fields = self::getFields($parts[0] . '.' . $parts[1], new JObject); @@ -290,6 +295,11 @@ public static function prepareForm($context, JForm $form, $data) $assignedCatids = isset($data->catid) ? $data->catid : (isset($data->fieldscatid) ? $data->fieldscatid : $form->getValue('catid')); + // Account for case that a submitted form has a multi-value category id field (e.g. a filtering form), just use the first category + $assignedCatids = is_array($assignedCatids) + ? (int) reset($assignedCatids) + : (int) $assignedCatids; + if (!$assignedCatids && $formField = $form->getField('catid')) { $assignedCatids = $formField->getAttribute('default', null); @@ -303,6 +313,7 @@ public static function prepareForm($context, JForm $form, $data) { $assignedCatids = $firstChoice->getAttribute('value'); } + $data->fieldscatid = $assignedCatids; } @@ -312,25 +323,6 @@ public static function prepareForm($context, JForm $form, $data) */ if ($form->getField('catid') && $parts[0] != 'com_fields') { - // The uri to submit to - $uri = clone JUri::getInstance('index.php'); - - /* - * Removing the catid parameter from the actual URL and set it as - * return - */ - $returnUri = clone JUri::getInstance(); - $returnUri->setVar('catid', null); - $uri->setVar('return', base64_encode($returnUri->toString())); - - // Setting the options - $uri->setVar('option', 'com_fields'); - $uri->setVar('task', 'field.storeform'); - $uri->setVar('context', $parts[0] . '.' . $parts[1]); - $uri->setVar('formcontrol', $form->getFormControl()); - $uri->setVar('view', null); - $uri->setVar('layout', null); - /* * Setting the onchange event to reload the page when the category * has changed @@ -340,18 +332,18 @@ public static function prepareForm($context, JForm $form, $data) // Preload spindle-wheel when we need to submit form due to category selector changed JFactory::getDocument()->addScriptDeclaration(" function categoryHasChanged(element) { - Joomla.loadingLayer('show'); var cat = jQuery(element); if (cat.val() == '" . $assignedCatids . "')return; - jQuery('input[name=task]').val('field.storeform'); - element.form.action='" . $uri . "'; - element.form.submit(); + Joomla.loadingLayer('show'); + jQuery('input[name=task]').val('" . $section . ".reload'); + Joomla.submitform('" . $section . ".reload', element.form); } jQuery( document ).ready(function() { Joomla.loadingLayer('load'); var formControl = '#" . $form->getFormControl() . "_catid'; if (!jQuery(formControl).val() != '" . $assignedCatids . "'){jQuery(formControl).val('" . $assignedCatids . "');} - });"); + });" + ); } // Getting the fields @@ -403,10 +395,24 @@ function categoryHasChanged(element) { // On the front, sometimes the admin fields path is not included JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_fields/tables'); + $model = JModelLegacy::getInstance('Groups', 'FieldsModel', array('ignore_request' => true)); + $model->setState('filter.context', $context); + + /** + * $model->getItems() would only return existing groups, but we also + * have the 'default' group with id 0 which is not in the database, + * so we create it virtually here. + */ + $defaultGroup = new \stdClass; + $defaultGroup->id = 0; + $defaultGroup->title = ''; + $defaultGroup->description = ''; + $iterateGroups = array_merge(array($defaultGroup), $model->getItems()); + // Looping through the groups - foreach ($fieldsPerGroup as $group_id => $groupFields) + foreach ($iterateGroups as $group) { - if (!$groupFields) + if (empty($fieldsPerGroup[$group->id])) { continue; } @@ -414,49 +420,32 @@ function categoryHasChanged(element) { // Defining the field set /** @var DOMElement $fieldset */ $fieldset = $fieldsNode->appendChild(new DOMElement('fieldset')); - $fieldset->setAttribute('name', 'fields-' . $group_id); + $fieldset->setAttribute('name', 'fields-' . $group->id); $fieldset->setAttribute('addfieldpath', '/administrator/components/' . $component . '/models/fields'); $fieldset->setAttribute('addrulepath', '/administrator/components/' . $component . '/models/rules'); - $label = ''; - $description = ''; + $label = $group->title; + $description = $group->description; - if ($group_id) + if (!$label) { - $group = JTable::getInstance('Group', 'FieldsTable'); - $group->load($group_id); + $key = strtoupper($component . '_FIELDS_' . $section . '_LABEL'); - if ($group->id) + if (!JFactory::getLanguage()->hasKey($key)) { - $label = $group->title; - $description = $group->description; + $key = 'JGLOBAL_FIELDS'; } + + $label = $key; } - if (!$label || !$description) + if (!$description) { - $lang = JFactory::getLanguage(); + $key = strtoupper($component . '_FIELDS_' . $section . '_DESC'); - if (!$label) + if (JFactory::getLanguage()->hasKey($key)) { - $key = strtoupper($component . '_FIELDS_' . $section . '_LABEL'); - - if (!$lang->hasKey($key)) - { - $key = 'JGLOBAL_FIELDS'; - } - - $label = $key; - } - - if (!$description) - { - $key = strtoupper($component . '_FIELDS_' . $section . '_DESC'); - - if ($lang->hasKey($key)) - { - $description = $key; - } + $description = $key; } } @@ -464,11 +453,11 @@ function categoryHasChanged(element) { $fieldset->setAttribute('description', strip_tags($description)); // Looping through the fields for that context - foreach ($groupFields as $field) + foreach ($fieldsPerGroup[$group->id] as $field) { try { - JEventDispatcher::getInstance()->trigger('onCustomFieldsPrepareDom', array($field, $fieldset, $form)); + JFactory::getApplication()->triggerEvent('onCustomFieldsPrepareDom', array($field, $fieldset, $form)); /* * If the field belongs to an assigned_cat_id but the assigned_cat_ids in the data @@ -554,49 +543,49 @@ public static function canEditFieldValue($field) } /** - * Adds Count Items for Category Manager. + * Return a boolean based on field (and field group) display / show_on settings * - * @param stdClass[] &$items The field category objects + * @param stdClass $field The field * - * @return stdClass[] + * @return boolean * - * @since 3.7.0 + * @since 3.8.7 */ - public static function countItems(&$items) + public static function displayFieldOnForm($field) { - $db = JFactory::getDbo(); + $app = JFactory::getApplication(); - foreach ($items as $item) + // Detect if the field should be shown at all + if ($field->params->get('show_on') == 1 && $app->isClient('administrator')) { - $item->count_trashed = 0; - $item->count_archived = 0; - $item->count_unpublished = 0; - $item->count_published = 0; - - $query = $db->getQuery(true); - $query->select('state, count(1) AS count') - ->from($db->quoteName('#__fields')) - ->where('group_id = ' . (int) $item->id) - ->group('state'); - $db->setQuery($query); - - $fields = $db->loadObjectList(); - - $states = array( - '-2' => 'count_trashed', - '0' => 'count_unpublished', - '1' => 'count_published', - '2' => 'count_archived', - ); + return false; + } + elseif ($field->params->get('show_on') == 2 && $app->isClient('site')) + { + return false; + } - foreach ($fields as $field) + if (!self::canEditFieldValue($field)) + { + $fieldDisplayReadOnly = $field->params->get('display_readonly', '2'); + + if ($fieldDisplayReadOnly == '2') { - $property = $states[$field->state]; - $item->$property = $field->count; + // Inherit from field group display read-only setting + $groupModel = JModelLegacy::getInstance('Group', 'FieldsModel', array('ignore_request' => true)); + $groupDisplayReadOnly = $groupModel->getItem($field->group_id)->params->get('display_readonly', '1'); + $fieldDisplayReadOnly = $groupDisplayReadOnly; + } + + if ($fieldDisplayReadOnly == '0') + { + // Do not display field on form when field is read-only + return false; } } - return $items; + // Display field on form + return true; } /** @@ -621,9 +610,9 @@ public static function getAssignedCategoriesTitles($fieldId) $query = $db->getQuery(true); $query->select($db->quoteName('c.title')) - ->from($db->quoteName('#__fields_categories', 'a')) - ->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON a.category_id = c.id') - ->where('field_id = ' . $fieldId); + ->from($db->quoteName('#__fields_categories', 'a')) + ->join('INNER', $db->quoteName('#__categories', 'c') . ' ON a.category_id = c.id') + ->where('field_id = ' . $fieldId); $db->setQuery($query); @@ -633,7 +622,7 @@ public static function getAssignedCategoriesTitles($fieldId) /** * Gets the fields system plugin extension id. * - * @return int The fields system plugin extension id. + * @return integer The fields system plugin extension id. * * @since 3.7.0 */ @@ -641,10 +630,10 @@ public static function getFieldsPluginId() { $db = JFactory::getDbo(); $query = $db->getQuery(true) - ->select($db->quoteName('extension_id')) - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) - ->where($db->quoteName('element') . ' = ' . $db->quote('fields')); + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) + ->where($db->quoteName('element') . ' = ' . $db->quote('fields')); $db->setQuery($query); try @@ -749,4 +738,17 @@ public static function getFieldTypes() return $data; } + + /** + * Clears the internal cache for the custom fields. + * + * @return void + * + * @since 3.8.0 + */ + public static function clearFieldsCache() + { + self::$fieldCache = null; + self::$fieldsCache = null; + } } diff --git a/administrator/components/com_fields/libraries/fieldslistplugin.php b/administrator/components/com_fields/libraries/fieldslistplugin.php index 2074010440035..017a3ae1764da 100644 --- a/administrator/components/com_fields/libraries/fieldslistplugin.php +++ b/administrator/components/com_fields/libraries/fieldslistplugin.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -42,7 +42,7 @@ public function onCustomFieldsPrepareDom($field, DOMElement $parent, JForm $form foreach ($this->getOptionsFromField($field) as $value => $name) { $option = new DOMElement('option', htmlspecialchars($value, ENT_COMPAT, 'UTF-8')); - $option->nodeValue = htmlspecialchars(JText::_($name), ENT_COMPAT, 'UTF-8'); + $option->textContent = htmlspecialchars(JText::_($name), ENT_COMPAT, 'UTF-8'); $element = $fieldNode->appendChild($option); $element->setAttribute('value', $value); @@ -65,7 +65,7 @@ public function getOptionsFromField($field) $data = array(); // Fetch the options from the plugin - $params = clone($this->params); + $params = clone $this->params; $params->merge($field->fieldparams); foreach ($params->get('options', array()) as $option) diff --git a/administrator/components/com_fields/libraries/fieldsplugin.php b/administrator/components/com_fields/libraries/fieldsplugin.php index 84eca9a148988..e901ba39ca27d 100644 --- a/administrator/components/com_fields/libraries/fieldsplugin.php +++ b/administrator/components/com_fields/libraries/fieldsplugin.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -26,6 +26,14 @@ abstract class FieldsPlugin extends JPlugin */ public function onCustomFieldsGetTypes() { + // Cache filesystem access / checks + static $types_cache = array(); + + if (isset($types_cache[$this->_type . $this->_name])) + { + return $types_cache[$this->_type . $this->_name]; + } + $types = array(); // The root of the plugin @@ -84,7 +92,9 @@ public function onCustomFieldsGetTypes() $types[] = $data; } - // Return the data + // Add to cache and return the data + $types_cache[$this->_type . $this->_name] = $types; + return $types; } @@ -114,6 +124,11 @@ public function onCustomFieldsPrepareField($context, $item, $field) // Get the path for the layout file $path = JPluginHelper::getLayoutPath('fields', $field->type, $field->type); + if (!file_exists($path)) + { + $path = JPluginHelper::getLayoutPath('fields', $this->_name, $field->type); + } + // Render the layout ob_start(); include $path; @@ -142,14 +157,8 @@ public function onCustomFieldsPrepareDom($field, DOMElement $parent, JForm $form return null; } - $app = JFactory::getApplication(); - - // Detect if the field should be shown at all - if ($field->params->get('show_on') == 1 && $app->isClient('administrator')) - { - return; - } - elseif ($field->params->get('show_on') == 2 && $app->isClient('site')) + // Detect if the field is configured to be displayed on the form + if (!FieldsHelper::displayFieldOnForm($field)) { return null; } @@ -160,13 +169,19 @@ public function onCustomFieldsPrepareDom($field, DOMElement $parent, JForm $form // Set the attributes $node->setAttribute('name', $field->name); $node->setAttribute('type', $field->type); - $node->setAttribute('default', $field->default_value); $node->setAttribute('label', $field->label); + $node->setAttribute('labelclass', $field->params->get('label_class')); $node->setAttribute('description', $field->description); $node->setAttribute('class', $field->params->get('class')); $node->setAttribute('hint', $field->params->get('hint')); $node->setAttribute('required', $field->required ? 'true' : 'false'); + if ($field->default_value !== '') + { + $defaultNode = $node->appendChild(new DOMElement('default')); + $defaultNode->appendChild(new DOMCdataSection($field->default_value)); + } + // Combine the two params $params = clone $this->params; $params->merge($field->fieldparams); diff --git a/administrator/components/com_fields/models/field.php b/administrator/components/com_fields/models/field.php index 45debf58b2216..05557292e109f 100644 --- a/administrator/components/com_fields/models/field.php +++ b/administrator/components/com_fields/models/field.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -109,7 +109,7 @@ public function save($data) if ($data['title'] == $origTable->title) { - list($title, $name) = $this->generateNewTitle($data['group_id'], $data['alias'], $data['title']); + list($title, $name) = $this->generateNewTitle($data['group_id'], $data['name'], $data['title']); $data['title'] = $title; $data['label'] = $title; $data['name'] = $name; @@ -184,18 +184,28 @@ public function save($data) if (is_object($oldParams) && is_object($newParams) && $oldParams != $newParams) { $names = array(); + foreach ($newParams as $param) { $names[] = $db->q($param['value']); } + $query = $db->getQuery(true); - $query->delete('#__fields_values')->where('field_id = ' . (int) $field->id) - ->where('value NOT IN (' . implode(',', $names) . ')'); + $query->delete('#__fields_values')->where('field_id = ' . (int) $field->id); + + // If new values are set, delete only old values. Otherwise delete all values. + if ($names) + { + $query->where('value NOT IN (' . implode(',', $names) . ')'); + } + $db->setQuery($query); $db->execute(); } } + FieldsHelper::clearFieldsCache(); + return true; } @@ -213,7 +223,7 @@ public function save($data) private function checkDefaultValue($data) { // Empty default values are correct - if (empty($data['default_value'])) + if (empty($data['default_value']) && $data['default_value'] !== '0') { return true; } @@ -324,7 +334,7 @@ public function getItem($pk = null) $result->context = JFactory::getApplication()->input->getCmd('context', $this->getState('field.context')); } - if (property_exists($result, 'fieldparams')) + if (property_exists($result, 'fieldparams') && $result->fieldparams !== null) { $registry = new Registry; $registry->loadString($result->fieldparams); @@ -339,34 +349,6 @@ public function getItem($pk = null) $db->setQuery($query); $result->assigned_cat_ids = $db->loadColumn() ?: array(0); - - // Convert the created and modified dates to local user time for - // display in the form. - $tz = new DateTimeZone(JFactory::getApplication()->get('offset')); - - if ((int) $result->created_time) - { - $date = new JDate($result->created_time); - $date->setTimezone($tz); - - $result->created_time = $date->toSql(true); - } - else - { - $result->created_time = null; - } - - if ((int) $result->modified_time) - { - $date = new JDate($result->modified_time); - $date->setTimezone($tz); - - $result->modified_time = $date->toSql(true); - } - else - { - $result->modified_time = null; - } } return $result; @@ -401,15 +383,15 @@ public function getTable($name = 'Field', $prefix = 'FieldsTable', $options = ar /** * Method to change the title & name. * - * @param integer $category_id The id of the category. - * @param string $name The name. - * @param string $title The title. + * @param integer $categoryId The id of the category. + * @param string $name The name. + * @param string $title The title. * * @return array Contains the modified title and name. * * @since 3.7.0 */ - protected function generateNewTitle($category_id, $name, $title) + protected function generateNewTitle($categoryId, $name, $title) { // Alter the title & name $table = $this->getTable(); @@ -429,7 +411,7 @@ protected function generateNewTitle($category_id, $name, $title) /** * Method to delete one or more records. * - * @param array &$pks An array of record primary keys. + * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * @@ -509,7 +491,7 @@ public function getForm($data = array(), $loadData = true) // Get the form. $form = $this->loadForm( - 'com_fields.field' . $context, 'field', + 'com_fields.field.' . $context, 'field', array( 'control' => 'jform', 'load_data' => true, @@ -545,7 +527,7 @@ public function getForm($data = array(), $loadData = true) } /** - * Setting the value for the gven field id, context and item id. + * Setting the value for the given field id, context and item id. * * @param string $fieldId The field ID. * @param string $itemId The ID of the item. @@ -575,32 +557,26 @@ public function setFieldValue($fieldId, $itemId, $value) $needsInsert = false; $needsUpdate = false; - if ($field->default_value == $value) + $oldValue = $this->getFieldValue($fieldId, $itemId); + $value = (array) $value; + + if ($oldValue === null) { - $needsDelete = true; + // No records available, doing normal insert + $needsInsert = true; + } + elseif (count($value) == 1 && count((array) $oldValue) == 1) + { + // Only a single row value update can be done when not empty + $needsUpdate = is_array($value[0]) ? count($value[0]) : strlen($value[0]); + $needsDelete = !$needsUpdate; } else { - $oldValue = $this->getFieldValue($fieldId, $itemId); - $value = (array) $value; - - if ($oldValue === null) - { - // No records available, doing normal insert - $needsInsert = true; - } - elseif (count($value) == 1 && count((array) $oldValue) == 1) - { - // Only a single row value update can be done - $needsUpdate = true; - } - else - { - // Multiple values, we need to purge the data and do a new - // insert - $needsDelete = true; - $needsInsert = true; - } + // Multiple values, we need to purge the data and do a new + // insert + $needsDelete = true; + $needsInsert = true; } if ($needsDelete) @@ -642,6 +618,7 @@ public function setFieldValue($fieldId, $itemId, $value) } $this->valueCache = array(); + FieldsHelper::clearFieldsCache(); return true; } @@ -773,19 +750,14 @@ public function cleanupValues($context, $itemId) */ protected function canDelete($record) { - if (!empty($record->id)) + if (empty($record->id) || $record->state != -2) { - if ($record->state != -2) - { - return false; - } - - $parts = FieldsHelper::extract($record->context); - - return JFactory::getUser()->authorise('core.delete', $parts[0] . '.field.' . (int) $record->id); + return false; } - return false; + $parts = FieldsHelper::extract($record->context); + + return JFactory::getUser()->authorise('core.delete', $parts[0] . '.field.' . (int) $record->id); } /** @@ -904,6 +876,41 @@ protected function loadFormData() return $data; } + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.23 + */ + public function validate($form, $data, $group = null) + { + // Don't allow to change the users if not allowed to access com_users. + if (!JFactory::getUser()->authorise('core.manage', 'com_users')) + { + if (isset($data['created_user_id'])) + { + unset($data['created_user_id']); + } + } + + if (!JFactory::getUser()->authorise('core.admin', 'com_fields')) + { + if (isset($data['rules'])) + { + unset($data['rules']); + } + } + + return parent::validate($form, $data, $group); + } + /** * Method to allow derived classes to preprocess the form. * @@ -940,24 +947,38 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') // Allow to override the default value label and description through the plugin $key = 'PLG_FIELDS_' . strtoupper($dataObject->type) . '_DEFAULT_VALUE_LABEL'; + if (JFactory::getLanguage()->hasKey($key)) { $form->setFieldAttribute('default_value', 'label', $key); } $key = 'PLG_FIELDS_' . strtoupper($dataObject->type) . '_DEFAULT_VALUE_DESC'; + if (JFactory::getLanguage()->hasKey($key)) { $form->setFieldAttribute('default_value', 'description', $key); } + + // Remove placeholder field on list fields + if ($dataObject->type == 'list') + { + $form->removeField('hint', 'params'); + } } // Setting the context for the category field - $cat = JCategories::getInstance(str_replace('com_', '', $component)); + $cat = JCategories::getInstance(str_replace('com_', '', $component) . '.' . $section); + + // If there is no category for the component and section, so check the component only + if (!$cat) + { + $cat = JCategories::getInstance(str_replace('com_', '', $component)); + } if ($cat && $cat->get('root')->hasChildren()) { - $form->setFieldAttribute('assigned_cat_ids', 'extension', $component); + $form->setFieldAttribute('assigned_cat_ids', 'extension', $cat->getExtension()); } else { @@ -990,14 +1011,14 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') /** * Clean the cache * - * @param string $group The cache group - * @param integer $client_id The ID of the client + * @param string $group The cache group + * @param integer $clientId The ID of the client * * @return void * * @since 3.7.0 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { $context = JFactory::getApplication()->input->get('context'); diff --git a/administrator/components/com_fields/models/fields.php b/administrator/components/com_fields/models/fields.php index 56620b66212b8..dd6af1d408de7 100644 --- a/administrator/components/com_fields/models/fields.php +++ b/administrator/components/com_fields/models/fields.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -44,7 +44,7 @@ public function __construct($config = array()) 'checked_out_time', 'a.checked_out_time', 'created_time', 'a.created_time', 'created_user_id', 'a.created_user_id', - 'category_title', + 'group_title', 'g.title', 'category_id', 'a.category_id', 'group_id', 'a.group_id', 'assigned_cat_ids' @@ -133,7 +133,7 @@ protected function getListQuery() $query->select( $this->getState( 'list.select', - 'a.id, a.title, a.name, a.checked_out, a.checked_out_time, a.note' . + 'DISTINCT a.id, a.title, a.name, a.checked_out, a.checked_out_time, a.note' . ', a.state, a.access, a.created_time, a.created_user_id, a.ordering, a.language' . ', a.fieldparams, a.params, a.type, a.default_value, a.context, a.group_id' . ', a.label, a.description, a.required' @@ -155,7 +155,7 @@ protected function getListQuery() $query->select('ua.name AS author_name')->join('LEFT', '#__users AS ua ON ua.id = a.created_user_id'); // Join over the field groups. - $query->select('g.title AS group_title, g.access as group_access, g.state AS group_state'); + $query->select('g.title AS group_title, g.access as group_access, g.state AS group_state, g.note as group_note'); $query->join('LEFT', '#__fields_groups AS g ON g.id = a.group_id'); // Filter by context @@ -187,7 +187,13 @@ protected function getListQuery() if ($parts) { // Get the category - $cat = JCategories::getInstance(str_replace('com_', '', $parts[0])); + $cat = JCategories::getInstance(str_replace('com_', '', $parts[0]) . '.' . $parts[1]); + + // If there is no category for the component and section, so check the component only + if (!$cat) + { + $cat = JCategories::getInstance(str_replace('com_', '', $parts[0])); + } if ($cat) { @@ -214,8 +220,7 @@ protected function getListQuery() $categories = array_unique($categories); // Join over the assigned categories - $query->join('LEFT', $db->quoteName('#__fields_categories') . ' AS fc ON fc.field_id = a.id') - ->group('a.id, l.title, l.image, uc.name, ag.title, ua.name, g.title, g.access, g.state'); + $query->join('LEFT', $db->quoteName('#__fields_categories') . ' AS fc ON fc.field_id = a.id'); if (in_array('0', $categories)) { @@ -241,6 +246,7 @@ protected function getListQuery() $includeGroupState = !$app->isClient('administrator') || $app->input->get('option') != 'com_fields' || $app->input->get('view') != 'fields'; + if (is_numeric($state)) { $query->where('a.state = ' . (int) $state); @@ -305,7 +311,7 @@ protected function getListQuery() $listOrdering = $this->state->get('list.ordering', 'a.ordering'); $orderDirn = $this->state->get('list.direction', 'ASC'); - $query->order($db->escape($listOrdering) . ' ' . $db->escape($orderDirn)); + $query->order($db->escape($listOrdering) . ' ' . $db->escape($orderDirn)); return $query; } diff --git a/administrator/components/com_fields/models/fields/fieldcontexts.php b/administrator/components/com_fields/models/fields/fieldcontexts.php index 7678f5a99c0d0..993d4ba04e4a5 100644 --- a/administrator/components/com_fields/models/fields/fieldcontexts.php +++ b/administrator/components/com_fields/models/fields/fieldcontexts.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/models/fields/fieldgroups.php b/administrator/components/com_fields/models/fields/fieldgroups.php index 0adac1584a04a..7467b57d3e585 100644 --- a/administrator/components/com_fields/models/fields/fieldgroups.php +++ b/administrator/components/com_fields/models/fields/fieldgroups.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -31,7 +31,7 @@ class JFormFieldFieldgroups extends JFormFieldList protected function getOptions() { $context = (string) $this->element['context']; - $states = $this->element['state'] ? $this->element['state'] : '0,1'; + $states = $this->element['state'] ?: '0,1'; $states = ArrayHelper::toInteger(explode(',', $states)); $user = JFactory::getUser(); @@ -44,6 +44,7 @@ protected function getOptions() $query->where('state IN (' . implode(',', $states) . ')'); $query->where('context = ' . $db->quote($context)); $query->where('access IN (' . implode(',', $viewlevels) . ')'); + $query->order('ordering asc, id asc'); $db->setQuery($query); $options = $db->loadObjectList(); @@ -54,6 +55,7 @@ protected function getOptions() { $option->text = '[' . $option->text . ']'; } + if ($option->state == 2) { $option->text = '{' . $option->text . '}'; diff --git a/administrator/components/com_fields/models/fields/fieldlayout.php b/administrator/components/com_fields/models/fields/fieldlayout.php new file mode 100644 index 0000000000000..e0a549e35ee62 --- /dev/null +++ b/administrator/components/com_fields/models/fields/fieldlayout.php @@ -0,0 +1,166 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +jimport('joomla.filesystem.folder'); + +/** + * Form Field to display a list of the layouts for a field from + * the extension or template overrides. + * + * @since 3.9.0 + */ +class JFormFieldFieldlayout extends JFormField +{ + /** + * The form field type. + * + * @var string + * @since 3.9.0 + */ + protected $type = 'FieldLayout'; + + /** + * Method to get the field input for a field layout field. + * + * @return string The field input. + * + * @since 3.9.0 + */ + protected function getInput() + { + $extension = explode('.', $this->form->getValue('context')); + $extension = $extension[0]; + + if ($extension) + { + // Get the database object and a new query object. + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Build the query. + $query->select('element, name') + ->from('#__extensions') + ->where('client_id = 0') + ->where('type = ' . $db->quote('template')) + ->where('enabled = 1'); + + // Set the query and load the templates. + $db->setQuery($query); + $templates = $db->loadObjectList('element'); + + // Build the search paths for component layouts. + $component_path = JPath::clean(JPATH_SITE . '/components/' . $extension . '/layouts/field'); + + // Prepare array of component layouts + $component_layouts = array(); + + // Prepare the grouped list + $groups = array(); + + // Add "Use Default" + $groups[]['items'][] = JHtml::_('select.option', '', JText::_('JOPTION_USE_DEFAULT')); + + // Add the layout options from the component path. + if (is_dir($component_path) && ($component_layouts = JFolder::files($component_path, '^[^_]*\.php$', false, true))) + { + // Create the group for the component + $groups['_'] = array(); + $groups['_']['id'] = $this->id . '__'; + $groups['_']['text'] = JText::sprintf('JOPTION_FROM_COMPONENT'); + $groups['_']['items'] = array(); + + foreach ($component_layouts as $i => $file) + { + // Add an option to the component group + $value = basename($file, '.php'); + $component_layouts[$i] = $value; + + if ($value === 'render') + { + continue; + } + + $groups['_']['items'][] = JHtml::_('select.option', $value, $value); + } + } + + // Loop on all templates + if ($templates) + { + foreach ($templates as $template) + { + $files = array(); + $template_paths = array( + JPath::clean(JPATH_SITE . '/templates/' . $template->element . '/html/layouts/' . $extension . '/field'), + JPath::clean(JPATH_SITE . '/templates/' . $template->element . '/html/layouts/com_fields/field'), + JPath::clean(JPATH_SITE . '/templates/' . $template->element . '/html/layouts/field'), + ); + + // Add the layout options from the template paths. + foreach ($template_paths as $template_path) + { + if (is_dir($template_path)) + { + $files = array_merge($files, JFolder::files($template_path, '^[^_]*\.php$', false, true)); + } + } + + foreach ($files as $i => $file) + { + $value = basename($file, '.php'); + + // Remove the default "render.php" or layout files that exist in the component folder + if ($value === 'render' || in_array($value, $component_layouts)) + { + unset($files[$i]); + } + } + + if (count($files)) + { + // Create the group for the template + $groups[$template->name] = array(); + $groups[$template->name]['id'] = $this->id . '_' . $template->element; + $groups[$template->name]['text'] = JText::sprintf('JOPTION_FROM_TEMPLATE', $template->name); + $groups[$template->name]['items'] = array(); + + foreach ($files as $file) + { + // Add an option to the template group + $value = basename($file, '.php'); + $groups[$template->name]['items'][] = JHtml::_('select.option', $value, $value); + } + } + } + } + + // Compute attributes for the grouped list + $attr = $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : ''; + $attr .= $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + + // Prepare HTML code + $html = array(); + + // Compute the current selected values + $selected = array($this->value); + + // Add a grouped list + $html[] = JHtml::_( + 'select.groupedlist', $groups, $this->name, + array('id' => $this->id, 'group.id' => 'id', 'list.attr' => $attr, 'list.select' => $selected) + ); + + return implode($html); + } + + return ''; + } +} diff --git a/administrator/components/com_fields/models/fields/section.php b/administrator/components/com_fields/models/fields/section.php index 9532ac633c485..0806bfd84c72f 100644 --- a/administrator/components/com_fields/models/fields/section.php +++ b/administrator/components/com_fields/models/fields/section.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -50,17 +50,18 @@ public function setup(SimpleXMLElement $element, $value, $group = null) * * @since 3.7.0 */ - protected function getInput () + protected function getInput() { // Add the change context function to the document JFactory::getDocument()->addScriptDeclaration( - "function fieldsChangeContext(context) + "function fieldsChangeContext(context) { var regex = new RegExp(\"([?;&])context[^&;]*[;&]?\"); var url = window.location.href; var query = url.replace(regex, \"$1\").replace(/&$/, ''); window.location.href = (query.length > 2 ? query + \"&\" : \"?\") + (context ? \"context=\" + context : ''); - }"); + }" + ); return parent::getInput(); } diff --git a/administrator/components/com_fields/models/fields/type.php b/administrator/components/com_fields/models/fields/type.php index aa24240595cdb..9b159e3e8a14c 100644 --- a/administrator/components/com_fields/models/fields/type.php +++ b/administrator/components/com_fields/models/fields/type.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -68,25 +68,6 @@ function ($a, $b) } ); - // Reload the page when the type changes - $uri = clone JUri::getInstance('index.php'); - - // Removing the catid parameter from the actual URL and set it as - // return - $returnUri = clone JUri::getInstance(); - $returnUri->setVar('catid', null); - $uri->setVar('return', base64_encode($returnUri->toString())); - - // Setting the options - $uri->setVar('option', 'com_fields'); - $uri->setVar('task', 'field.storeform'); - $uri->setVar('context', 'com_fields.field'); - $uri->setVar('formcontrol', $this->form->getFormControl()); - $uri->setVar('userstatevariable', 'com_fields.edit.field.data'); - $uri->setVar('view', null); - $uri->setVar('layout', null); - - JFactory::getDocument()->addScriptDeclaration(" jQuery( document ).ready(function() { Joomla.loadingLayer('load'); @@ -94,11 +75,11 @@ function ($a, $b) function typeHasChanged(element){ Joomla.loadingLayer('show'); var cat = jQuery(element); - jQuery('input[name=task]').val('field.storeform'); - element.form.action='" . $uri . "'; + jQuery('input[name=task]').val('field.reload'); element.form.submit(); } - "); + " + ); return $options; } diff --git a/administrator/components/com_fields/models/forms/field.xml b/administrator/components/com_fields/models/forms/field.xml index 0e2e105937d8c..8ae56cfa9ef6d 100644 --- a/administrator/components/com_fields/models/forms/field.xml +++ b/administrator/components/com_fields/models/forms/field.xml @@ -3,7 +3,7 @@
    + + + + + + + + + + + + + + + - + @@ -263,17 +311,14 @@ - - - - + name="label_render_class" + type="textarea" + label="COM_FIELDS_FIELD_LABEL_RENDER_CLASS_LABEL" + description="COM_FIELDS_FIELD_LABEL_RENDER_CLASS_DESC" + class="input-xxlarge" + size="40" + showon="showlabel:1" + /> COM_FIELDS_FIELD_DISPLAY_AFTER_TITLE + + + + + + + +
    diff --git a/administrator/components/com_fields/models/forms/filter_fields.xml b/administrator/components/com_fields/models/forms/filter_fields.xml index aca47a63e508b..e04207b7a4196 100644 --- a/administrator/components/com_fields/models/forms/filter_fields.xml +++ b/administrator/components/com_fields/models/forms/filter_fields.xml @@ -11,7 +11,9 @@ @@ -67,6 +69,7 @@ statuses="*,0,1,2,-2" onchange="this.form.submit();" default="a.ordering ASC" + validate="options" > diff --git a/administrator/components/com_fields/models/forms/filter_groups.xml b/administrator/components/com_fields/models/forms/filter_groups.xml index 6e18a7daf0b23..b1583bf79928a 100644 --- a/administrator/components/com_fields/models/forms/filter_groups.xml +++ b/administrator/components/com_fields/models/forms/filter_groups.xml @@ -11,6 +11,8 @@ @@ -47,6 +49,7 @@ label="JGLOBAL_SORT_BY" onchange="this.form.submit();" default="a.ordering ASC" + validate="options" > diff --git a/administrator/components/com_fields/models/forms/group.xml b/administrator/components/com_fields/models/forms/group.xml index 575054f15fd23..4ed5c46842c27 100644 --- a/administrator/components/com_fields/models/forms/group.xml +++ b/administrator/components/com_fields/models/forms/group.xml @@ -3,7 +3,7 @@
    -
    + + +
    + + + + +
    +
    diff --git a/administrator/components/com_fields/models/group.php b/administrator/components/com_fields/models/group.php index 70d890db89acd..9e03a6b86d2c5 100644 --- a/administrator/components/com_fields/models/group.php +++ b/administrator/components/com_fields/models/group.php @@ -3,11 +3,13 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\Registry\Registry; + /** * Group Model * @@ -69,6 +71,8 @@ public function save($data) */ public function getTable($name = 'Group', $prefix = 'FieldsTable', $options = array()) { + $this->addTablePath(JPATH_ADMINISTRATOR . '/components/com_fields/tables'); + return JTable::getInstance($name, $prefix, $options); } @@ -220,11 +224,70 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $parts = FieldsHelper::extract($this->state->get('filter.context')); + // Extract the component name + $component = $parts[0]; + + // Extract the optional section name + $section = (count($parts) > 1) ? $parts[1] : null; + if ($parts) { // Set the access control rules field component value. - $form->setFieldAttribute('rules', 'component', $parts[0]); + $form->setFieldAttribute('rules', 'component', $component); + } + + if ($section !== null) + { + // Looking first in the component models/forms folder + $path = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/fieldgroup/' . $section . '.xml'); + + if (file_exists($path)) + { + $lang = JFactory::getLanguage(); + $lang->load($component, JPATH_BASE, null, false, true); + $lang->load($component, JPATH_BASE . '/components/' . $component, null, false, true); + + if (!$form->loadFile($path, false)) + { + throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); + } + } + } + } + + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.23 + */ + public function validate($form, $data, $group = null) + { + // Don't allow to change the users if not allowed to access com_users. + if (!JFactory::getUser()->authorise('core.manage', 'com_users')) + { + if (isset($data['created_by'])) + { + unset($data['created_by']); + } + } + + if (!JFactory::getUser()->authorise('core.admin', 'com_fields')) + { + if (isset($data['rules'])) + { + unset($data['rules']); + } } + + return parent::validate($form, $data, $group); } /** @@ -290,29 +353,9 @@ public function getItem($pk = null) $item->context = $this->getState('filter.context'); } - // Convert the created and modified dates to local user time for display in the form. - $tz = new DateTimeZone(JFactory::getApplication()->get('offset')); - - if ((int) $item->created) - { - $date = new JDate($item->created); - $date->setTimezone($tz); - $item->created = $date->toSql(true); - } - else - { - $item->created = null; - } - - if ((int) $item->modified) - { - $date = new JDate($item->modified); - $date->setTimezone($tz); - $item->modified = $date->toSql(true); - } - else + if (property_exists($item, 'params')) { - $item->modified = null; + $item->params = new Registry($item->params); } } @@ -322,14 +365,14 @@ public function getItem($pk = null) /** * Clean the cache * - * @param string $group The cache group - * @param integer $client_id The ID of the client + * @param string $group The cache group + * @param integer $clientId The ID of the client * * @return void * * @since 3.7.0 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { $context = JFactory::getApplication()->input->get('context'); diff --git a/administrator/components/com_fields/models/groups.php b/administrator/components/com_fields/models/groups.php index beb82f0d2ad4b..740e6962a671e 100644 --- a/administrator/components/com_fields/models/groups.php +++ b/administrator/components/com_fields/models/groups.php @@ -3,11 +3,12 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; /** @@ -121,13 +122,7 @@ protected function getListQuery() $user = JFactory::getUser(); // Select the required fields from the table. - $query->select( - $this->getState( - 'list.select', - 'a.id, a.title, a.checked_out, a.checked_out_time, a.note' . - ', a.state, a.access, a.created, a.created_by, a.ordering, a.language' - ) - ); + $query->select($this->getState('list.select', 'a.*')); $query->from('#__fields_groups AS a'); // Join over the language @@ -219,4 +214,31 @@ protected function getListQuery() return $query; } + + /** + * Gets an array of objects from the results of database query. + * + * @param string $query The query. + * @param integer $limitstart Offset. + * @param integer $limit The number of records. + * + * @return array An array of results. + * + * @since 3.8.7 + * @throws RuntimeException + */ + protected function _getList($query, $limitstart = 0, $limit = 0) + { + $result = parent::_getList($query, $limitstart, $limit); + + if (is_array($result)) + { + foreach ($result as $group) + { + $group->params = new Registry($group->params); + } + } + + return $result; + } } diff --git a/administrator/components/com_fields/tables/field.php b/administrator/components/com_fields/tables/field.php index 452e4398b1fa9..50753cc9f4ed2 100644 --- a/administrator/components/com_fields/tables/field.php +++ b/administrator/components/com_fields/tables/field.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/tables/group.php b/administrator/components/com_fields/tables/group.php index 200231e56a3da..420b5923d2f3a 100644 --- a/administrator/components/com_fields/tables/group.php +++ b/administrator/components/com_fields/tables/group.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/views/field/tmpl/edit.php b/administrator/components/com_fields/views/field/tmpl/edit.php index d3d1f9d528548..932034b81397f 100644 --- a/administrator/components/com_fields/views/field/tmpl/edit.php +++ b/administrator/components/com_fields/views/field/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/views/field/view.html.php b/administrator/components/com_fields/views/field/view.html.php index 8c7940a725a80..6496908f82f8e 100644 --- a/administrator/components/com_fields/views/field/view.html.php +++ b/administrator/components/com_fields/views/field/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/views/fields/tmpl/default.php b/administrator/components/com_fields/views/fields/tmpl/default.php index cb96ce15463ad..c3fa54ea2576e 100644 --- a/administrator/components/com_fields/views/fields/tmpl/default.php +++ b/administrator/components/com_fields/views/fields/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -20,13 +20,20 @@ $userId = $user->get('id'); $context = $this->escape($this->state->get('filter.context')); $component = $this->state->get('filter.component'); +$section = $this->state->get('filter.section'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $ordering = ($listOrder == 'a.ordering'); $saveOrder = ($listOrder == 'a.ordering' && strtolower($listDirn) == 'asc'); // The category object of the component -$category = JCategories::getInstance(str_replace('com_', '', $component)); +$category = JCategories::getInstance(str_replace('com_', '', $component) . '.' . $section); + +// If there is no category for the component and section, so check the component only +if (!$category) +{ + $category = JCategories::getInstance(str_replace('com_', '', $component)); +} if ($saveOrder) { diff --git a/administrator/components/com_fields/views/fields/tmpl/default_batch_body.php b/administrator/components/com_fields/views/fields/tmpl/default_batch_body.php index d60370b64926f..2213d67c55722 100644 --- a/administrator/components/com_fields/views/fields/tmpl/default_batch_body.php +++ b/administrator/components/com_fields/views/fields/tmpl/default_batch_body.php @@ -2,8 +2,8 @@ /** * @package Joomla.Administrator * @subpackage com_fields - * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/views/fields/tmpl/default_batch_footer.php b/administrator/components/com_fields/views/fields/tmpl/default_batch_footer.php index 9192d5745880c..add9c4312758c 100644 --- a/administrator/components/com_fields/views/fields/tmpl/default_batch_footer.php +++ b/administrator/components/com_fields/views/fields/tmpl/default_batch_footer.php @@ -2,16 +2,16 @@ /** * @package Joomla.Administrator * @subpackage com_fields - * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - - \ No newline at end of file + diff --git a/administrator/components/com_fields/views/fields/tmpl/modal.php b/administrator/components/com_fields/views/fields/tmpl/modal.php index 49d63ab82dfeb..4ece418088e5c 100644 --- a/administrator/components/com_fields/views/fields/tmpl/modal.php +++ b/administrator/components/com_fields/views/fields/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,6 +16,7 @@ JHtml::_('behavior.core'); JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); JHtml::_('formbehavior.chosen', 'select'); JHtml::_('script', 'com_fields/admin-fields-modal.js', array('version' => 'auto', 'relative' => true)); @@ -29,7 +30,7 @@ ?>
    -
    + $this)); ?> items)) : ?> @@ -47,7 +48,7 @@ - + @@ -56,7 +57,7 @@ - + diff --git a/administrator/components/com_fields/views/fields/view.html.php b/administrator/components/com_fields/views/fields/view.html.php index da6aa7f407f92..9f73962bbcb48 100644 --- a/administrator/components/com_fields/views/fields/view.html.php +++ b/administrator/components/com_fields/views/fields/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -92,11 +92,10 @@ public function display($tpl = null) if ($this->getLayout() !== 'modal') { $this->addToolbar(); + FieldsHelper::addSubmenu($this->state->get('filter.context'), 'fields'); + $this->sidebar = JHtmlSidebar::render(); } - FieldsHelper::addSubmenu($this->state->get('filter.context'), 'fields'); - $this->sidebar = JHtmlSidebar::render(); - return parent::display($tpl); } @@ -204,7 +203,7 @@ protected function getSortFields() 'a.title' => JText::_('JGLOBAL_TITLE'), 'a.type' => JText::_('COM_FIELDS_FIELD_TYPE_LABEL'), 'a.access' => JText::_('JGRID_HEADING_ACCESS'), - 'language' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), 'a.id' => JText::_('JGRID_HEADING_ID'), ); } diff --git a/administrator/components/com_fields/views/group/tmpl/edit.php b/administrator/components/com_fields/views/group/tmpl/edit.php index 6c40f38bab4f5..1b3780f624e45 100644 --- a/administrator/components/com_fields/views/group/tmpl/edit.php +++ b/administrator/components/com_fields/views/group/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -38,7 +38,6 @@
    form->renderField('label'); ?> - form->renderField('context'); ?> form->renderField('description'); ?>
    diff --git a/administrator/components/com_fields/views/group/view.html.php b/administrator/components/com_fields/views/group/view.html.php index 0b5789c33aace..a499db0f31e86 100644 --- a/administrator/components/com_fields/views/group/view.html.php +++ b/administrator/components/com_fields/views/group/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/views/groups/tmpl/default.php b/administrator/components/com_fields/views/groups/tmpl/default.php index a3006194aa3ab..8a095a6921fb6 100644 --- a/administrator/components/com_fields/views/groups/tmpl/default.php +++ b/administrator/components/com_fields/views/groups/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/views/groups/tmpl/default_batch_body.php b/administrator/components/com_fields/views/groups/tmpl/default_batch_body.php index d42f8af576fbb..e132c56bce6f3 100644 --- a/administrator/components/com_fields/views/groups/tmpl/default_batch_body.php +++ b/administrator/components/com_fields/views/groups/tmpl/default_batch_body.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_fields/views/groups/tmpl/default_batch_footer.php b/administrator/components/com_fields/views/groups/tmpl/default_batch_footer.php index 4a313168175e2..63d1efb123ed2 100644 --- a/administrator/components/com_fields/views/groups/tmpl/default_batch_footer.php +++ b/administrator/components/com_fields/views/groups/tmpl/default_batch_footer.php @@ -2,16 +2,16 @@ /** * @package Joomla.Administrator * @subpackage com_fields - * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - - \ No newline at end of file + diff --git a/administrator/components/com_fields/views/groups/view.html.php b/administrator/components/com_fields/views/groups/view.html.php index 3450e1acec288..6fd9510434561 100644 --- a/administrator/components/com_fields/views/groups/view.html.php +++ b/administrator/components/com_fields/views/groups/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_fields * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_finder/config.xml b/administrator/components/com_finder/config.xml index 20e95a924b43f..869fba3f886ad 100644 --- a/administrator/components/com_finder/config.xml +++ b/administrator/components/com_finder/config.xml @@ -32,9 +32,8 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -43,7 +43,7 @@ public function display($cachable = false, $urlparams = array()) $filterId = $this->input->get('filter_id', null, 'int'); // Check for edit form. - if ($view == 'filter' && $layout == 'edit' && !$this->checkEditId('com_finder.edit.filter', $filterId)) + if ($view === 'filter' && $layout === 'edit' && !$this->checkEditId('com_finder.edit.filter', $filterId)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $filterId)); diff --git a/administrator/components/com_finder/controllers/filter.php b/administrator/components/com_finder/controllers/filter.php index eb321c94336f5..ca66b0c64dd93 100644 --- a/administrator/components/com_finder/controllers/filter.php +++ b/administrator/components/com_finder/controllers/filter.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -31,7 +31,7 @@ class FinderControllerFilter extends JControllerForm public function save($key = null, $urlVar = null) { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $input = $app->input; @@ -70,7 +70,7 @@ public function save($key = null, $urlVar = null) $data[$key] = $recordId; // The save2copy task needs to be handled slightly differently. - if ($task == 'save2copy') + if ($task === 'save2copy') { // Check-in the original row. if ($checkin && $model->checkin($data[$key]) === false) @@ -121,7 +121,7 @@ public function save($key = null, $urlVar = null) // Push up to three validation messages out to the user. for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++) { - if (($errors[$i]) instanceof Exception) + if ($errors[$i] instanceof Exception) { $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); } @@ -185,8 +185,8 @@ public function save($key = null, $urlVar = null) $this->setMessage( JText::_( - (JFactory::getLanguage()->hasKey($this->text_prefix . ($recordId == 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS') - ? $this->text_prefix : 'JLIB_APPLICATION') . ($recordId == 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS' + (JFactory::getLanguage()->hasKey($this->text_prefix . ($recordId === 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS') + ? $this->text_prefix : 'JLIB_APPLICATION') . ($recordId === 0 && $app->isClient('site') ? '_SUBMIT' : '') . '_SAVE_SUCCESS' ) ); diff --git a/administrator/components/com_finder/controllers/filters.php b/administrator/components/com_finder/controllers/filters.php index efd2bac416c2e..d79e570e86076 100644 --- a/administrator/components/com_finder/controllers/filters.php +++ b/administrator/components/com_finder/controllers/filters.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/controllers/index.php b/administrator/components/com_finder/controllers/index.php index 0be6d0054d77d..8bcd4ad0a7ada 100644 --- a/administrator/components/com_finder/controllers/index.php +++ b/administrator/components/com_finder/controllers/index.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -41,7 +41,7 @@ public function getModel($name = 'Index', $prefix = 'FinderModel', $config = arr */ public function purge() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Remove the script time limit. @set_time_limit(0); diff --git a/administrator/components/com_finder/controllers/indexer.json.php b/administrator/components/com_finder/controllers/indexer.json.php index 71683cf008adc..9da6c27f7c752 100644 --- a/administrator/components/com_finder/controllers/indexer.json.php +++ b/administrator/components/com_finder/controllers/indexer.json.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -55,7 +55,7 @@ public function start() $app->setHeader('Pragma', 'no-cache'); // Check for a valid token. If invalid, send a 403 with the error message. - JSession::checkToken('request') or $this->sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); + JSession::checkToken('request') or static::sendResponse(new Exception(JText::_('JINVALID_TOKEN_NOTICE'), 403)); // Put in a buffer to silence noise. ob_start(); @@ -81,12 +81,13 @@ public function start() $state->start = 1; // Send the response. - $this->sendResponse($state); + static::sendResponse($state); } + // Catch an exception and return the response. catch (Exception $e) { - $this->sendResponse($e); + static::sendResponse($e); } } @@ -126,7 +127,7 @@ public function batch() $app->setHeader('Pragma', 'no-cache'); // Check for a valid token. If invalid, send a 403 with the error message. - JSession::checkToken('request') or $this->sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); + JSession::checkToken('request') or static::sendResponse(new Exception(JText::_('JINVALID_TOKEN_NOTICE'), 403)); // Put in a buffer to silence noise. ob_start(); @@ -165,6 +166,8 @@ public function batch() // Get the HTML document. $html = JDocument::getInstance('html', $attributes); + + // Todo: Why is this document fetched and immediately overwritten? $doc = JFactory::getDocument(); // Swap the documents. @@ -178,6 +181,8 @@ public function batch() // Swap the app. $app = JFactory::getApplication(); + + // Todo: Why is the app fetched and immediately overwritten? $app = $site; // Start the indexer. @@ -211,8 +216,9 @@ public function batch() } // Send the response. - $this->sendResponse($state); + static::sendResponse($state); } + // Catch an exception and return the response. catch (Exception $e) { @@ -220,7 +226,7 @@ public function batch() $doc = $raw; // Send the response. - $this->sendResponse($e); + static::sendResponse($e); } } @@ -241,7 +247,7 @@ public function optimize() $app->setHeader('Pragma', 'no-cache'); // Check for a valid token. If invalid, send a 403 with the error message. - JSession::checkToken('request') or $this->sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); + JSession::checkToken('request') or static::sendResponse(new Exception(JText::_('JINVALID_TOKEN_NOTICE'), 403)); // Put in a buffer to silence noise. ob_start(); @@ -260,12 +266,13 @@ public function optimize() $state->complete = 1; // Send the response. - $this->sendResponse($state); + static::sendResponse($state); } + // Catch an exception and return the response. catch (Exception $e) { - $this->sendResponse($e); + static::sendResponse($e); } } diff --git a/administrator/components/com_finder/controllers/maps.php b/administrator/components/com_finder/controllers/maps.php index 24b4413fcda6f..17676fc4be649 100644 --- a/administrator/components/com_finder/controllers/maps.php +++ b/administrator/components/com_finder/controllers/maps.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/finder.php b/administrator/components/com_finder/finder.php index fc2aab405eced..ece9b27a16048 100644 --- a/administrator/components/com_finder/finder.php +++ b/administrator/components/com_finder/finder.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/finder.xml b/administrator/components/com_finder/finder.xml index 1b9d4fb7a66fd..4e82d43d0f677 100644 --- a/administrator/components/com_finder/finder.xml +++ b/administrator/components/com_finder/finder.xml @@ -2,7 +2,7 @@ com_finder Joomla! Project - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2011 Open Source Matters, Inc. August 2011 GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org diff --git a/administrator/components/com_finder/helpers/finder.php b/administrator/components/com_finder/helpers/finder.php index d58de10516bfd..951a50ccea7ca 100644 --- a/administrator/components/com_finder/helpers/finder.php +++ b/administrator/components/com_finder/helpers/finder.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -38,24 +38,24 @@ public static function addSubmenu($vName) JHtmlSidebar::addEntry( JText::_('COM_FINDER_SUBMENU_INDEX'), 'index.php?option=com_finder&view=index', - $vName == 'index' + $vName === 'index' ); JHtmlSidebar::addEntry( JText::_('COM_FINDER_SUBMENU_MAPS'), 'index.php?option=com_finder&view=maps', - $vName == 'maps' + $vName === 'maps' ); JHtmlSidebar::addEntry( JText::_('COM_FINDER_SUBMENU_FILTERS'), 'index.php?option=com_finder&view=filters', - $vName == 'filters' + $vName === 'filters' ); } /** * Gets the finder system plugin extension id. * - * @return int The finder system plugin extension id. + * @return integer The finder system plugin extension id. * * @since 3.6.0 */ diff --git a/administrator/components/com_finder/helpers/html/finder.php b/administrator/components/com_finder/helpers/html/finder.php index 1daa519138692..93b41dbe004a0 100644 --- a/administrator/components/com_finder/helpers/html/finder.php +++ b/administrator/components/com_finder/helpers/html/finder.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/helpers/indexer/adapter.php b/administrator/components/com_finder/helpers/indexer/adapter.php index 22f1ab5cc2b01..3da75f6242390 100644 --- a/administrator/components/com_finder/helpers/indexer/adapter.php +++ b/administrator/components/com_finder/helpers/indexer/adapter.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -125,8 +125,8 @@ abstract class FinderIndexerAdapter extends JPlugin /** * Method to instantiate the indexer adapter. * - * @param object &$subject The object to observe. - * @param array $config An array that holds the plugin configuration. + * @param object $subject The object to observe. + * @param array $config An array that holds the plugin configuration. * * @since 2.5 */ @@ -160,7 +160,7 @@ public function __construct(&$subject, $config) /** * Method to get the adapter state and push it into the indexer. * - * @return boolean True on success. + * @return void * * @since 2.5 * @throws Exception on error. @@ -312,7 +312,7 @@ abstract protected function index(FinderIndexerResult $item); * * @param integer $id The ID of the item to reindex. * - * @return boolean True on success. + * @return void * * @since 2.5 * @throws Exception on database error. @@ -902,12 +902,9 @@ protected function pluginDisable($pks) protected function translateState($item, $category = null) { // If category is present, factor in its states as well - if ($category !== null) + if ($category !== null && $category == 0) { - if ($category == 0) - { - $item = 0; - } + $item = 0; } // Translate the state diff --git a/administrator/components/com_finder/helpers/indexer/driver/mysql.php b/administrator/components/com_finder/helpers/indexer/driver/mysql.php index c4149f41b106e..4fd35d15e1cb5 100644 --- a/administrator/components/com_finder/helpers/indexer/driver/mysql.php +++ b/administrator/components/com_finder/helpers/indexer/driver/mysql.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -41,7 +41,7 @@ public function index($item, $format = 'html') { // Mark beforeIndexing in the profiler. static::$profiler ? static::$profiler->mark('beforeIndexing') : null; - $db = JFactory::getDbo(); + $db = $this->db; $nd = $db->getNullDate(); // Check if the item is in the database. @@ -125,24 +125,24 @@ public function index($item, $format = 'html') ->insert($db->quoteName('#__finder_links')) ->columns($columnsArray) ->values( - $db->quote($item->url) . ', ' - . $db->quote($item->route) . ', ' - . $db->quote($item->title) . ', ' - . $db->quote($item->description) . ', ' - . $query->currentTimestamp() . ', ' - . '1, ' - . (int) $item->state . ', ' - . (int) $item->access . ', ' - . $db->quote($item->language) . ', ' - . (int) $item->type_id . ', ' - . $db->quote(serialize($item)) . ', ' - . $db->quote($item->publish_start_date) . ', ' - . $db->quote($item->publish_end_date) . ', ' - . $db->quote($item->start_date) . ', ' - . $db->quote($item->end_date) . ', ' - . (double) ($item->list_price ? $item->list_price : 0) . ', ' - . (double) ($item->sale_price ? $item->sale_price : 0) - ); + $db->quote($item->url) . ', ' + . $db->quote($item->route) . ', ' + . $db->quote($item->title) . ', ' + . $db->quote($item->description) . ', ' + . $query->currentTimestamp() . ', ' + . '1, ' + . (int) $item->state . ', ' + . (int) $item->access . ', ' + . $db->quote($item->language) . ', ' + . (int) $item->type_id . ', ' + . $db->quote(serialize($item)) . ', ' + . $db->quote($item->publish_start_date) . ', ' + . $db->quote($item->publish_end_date) . ', ' + . $db->quote($item->start_date) . ', ' + . $db->quote($item->end_date) . ', ' + . (double) ($item->list_price ?: 0) . ', ' + . (double) ($item->sale_price ?: 0) + ); $db->setQuery($query); $db->execute(); @@ -167,8 +167,8 @@ public function index($item, $format = 'html') ->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date)) ->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date)) ->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date)) - ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ? $item->list_price : 0)) - ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ? $item->sale_price : 0)) + ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ?: 0)) + ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ?: 0)) ->where('link_id = ' . (int) $linkId); $db->setQuery($query); $db->execute(); @@ -216,8 +216,7 @@ public function index($item, $format = 'html') if ($group === static::PATH_CONTEXT) { $ip = JFile::stripExt($ip); - $ip = str_replace('/', ' ', $ip); - $ip = str_replace('-', ' ', $ip); + $ip = str_replace(array('/', '-'), ' ', $ip); } // Tokenize a string of content and add it to the database. @@ -270,9 +269,6 @@ public function index($item, $format = 'html') // Add the link => node map. FinderIndexerTaxonomy::addMap($linkId, $nodeId); - - // Tokenize the node title and add them to the database. - $count += $this->tokenizeToDb($node->title, static::META_CONTEXT, $item->language, $format); } } @@ -287,30 +283,30 @@ public function index($item, $format = 'html') * table. */ $query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') . - ' (' . $db->quoteName('term_id') . - ', ' . $db->quoteName('map_suffix') . + ' (' . $db->quoteName('term_id') . + ', ' . $db->quoteName('map_suffix') . ', ' . $db->quoteName('term') . - ', ' . $db->quoteName('stem') . - ', ' . $db->quoteName('common') . - ', ' . $db->quoteName('phrase') . - ', ' . $db->quoteName('term_weight') . - ', ' . $db->quoteName('context') . - ', ' . $db->quoteName('context_weight') . - ', ' . $db->quoteName('total_weight') . + ', ' . $db->quoteName('stem') . + ', ' . $db->quoteName('common') . + ', ' . $db->quoteName('phrase') . + ', ' . $db->quoteName('term_weight') . + ', ' . $db->quoteName('context') . + ', ' . $db->quoteName('context_weight') . + ', ' . $db->quoteName('total_weight') . ', ' . $db->quoteName('language') . ')' . - ' SELECT' . - ' COALESCE(t.term_id, 0), \'\', t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' . - ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, 0, t1.language' . - ' FROM (' . - ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . - ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' . - ' WHERE t1.context = %d' . - ' ) AS t1' . - ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' . - ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' . - ' WHERE t2.context = %d' . - ' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . - ' ORDER BY t1.term DESC'; + ' SELECT' . + ' COALESCE(t.term_id, 0), \'\', t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' . + ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, 0, t1.language' . + ' FROM (' . + ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . + ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' . + ' WHERE t1.context = %d' . + ' ) AS t1' . + ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' . + ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' . + ' WHERE t2.context = %d' . + ' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . + ' ORDER BY t1.term DESC'; // Iterate through the contexts and aggregate the tokens per context. foreach ($state->weights as $context => $multiplier) @@ -426,9 +422,11 @@ public function index($item, $format = 'html') static::$profiler ? static::$profiler->mark('afterMapping') : null; // Update the signature. + $object = serialize($item); $query->clear() ->update($db->quoteName('#__finder_links')) ->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig)) + ->set($db->quoteName('object') . ' = ' . $db->quote($object)) ->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId)); $db->setQuery($query); $db->execute(); @@ -451,64 +449,6 @@ public function index($item, $format = 'html') return $linkId; } - /** - * Method to remove a link from the index. - * - * @param integer $linkId The id of the link. - * - * @return boolean True on success. - * - * @since 2.5 - * @throws Exception on database error. - */ - public function remove($linkId) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - // Update the link counts and remove the mapping records. - for ($i = 0; $i <= 15; $i++) - { - // Update the link counts for the terms. - $query->clear() - ->update($db->quoteName('#__finder_terms') . ' AS t') - ->join('INNER', $db->quoteName('#__finder_links_terms' . dechex($i)) . ' AS m ON m.term_id = t.term_id') - ->set('t.links = t.links - 1') - ->where('m.link_id = ' . $db->quote((int) $linkId)); - $db->setQuery($query); - $db->execute(); - - // Remove all records from the mapping tables. - $query->clear() - ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) - ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); - $db->setQuery($query); - $db->execute(); - } - - // Delete all orphaned terms. - $query->clear() - ->delete($db->quoteName('#__finder_terms')) - ->where($db->quoteName('links') . ' <= 0'); - $db->setQuery($query); - $db->execute(); - - // Delete the link from the index. - $query->clear() - ->delete($db->quoteName('#__finder_links')) - ->where($db->quoteName('link_id') . ' = ' . $db->quote((int) $linkId)); - $db->setQuery($query); - $db->execute(); - - // Remove the taxonomy maps. - FinderIndexerTaxonomy::removeMaps($linkId); - - // Remove the orphaned taxonomy nodes. - FinderIndexerTaxonomy::removeOrphanNodes(); - - return true; - } - /** * Method to optimize the index. We use this method to remove unused terms * and any other optimizations that might be necessary. @@ -521,7 +461,7 @@ public function remove($linkId) public function optimize() { // Get the database object. - $db = JFactory::getDbo(); + $db = $this->db; $query = $db->getQuery(true); // Delete all orphaned terms. @@ -567,63 +507,6 @@ public function optimize() return true; } - /** - * Method to add a set of tokens to the database. - * - * @param mixed $tokens An array or single FinderIndexerToken object. - * @param mixed $context The context of the tokens. See context constants. [optional] - * - * @return integer The number of tokens inserted into the database. - * - * @since 3.0 - * @throws Exception on database error. - */ - protected function addTokensToDb($tokens, $context = '') - { - // Get the database object. - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - // Force tokens to an array. - $tokens = is_array($tokens) ? $tokens : array($tokens); - - // Count the number of token values. - $values = 0; - - // Insert the tokens into the database. - $query->insert($db->quoteName('#__finder_tokens')) - ->columns( - array( - $db->quoteName('term'), - $db->quoteName('stem'), - $db->quoteName('common'), - $db->quoteName('phrase'), - $db->quoteName('weight'), - $db->quoteName('context'), - $db->quoteName('language') - ) - ); - - // Iterate through the tokens to create SQL value sets. - foreach ($tokens as $token) - { - $query->values( - $db->quote($token->term) . ', ' - . $db->quote($token->stem) . ', ' - . (int) $token->common . ', ' - . (int) $token->phrase . ', ' - . (float) $token->weight . ', ' - . (int) $context . ', ' - . $db->quote($token->language) - ); - $values++; - } - - $db->setQuery($query); - $db->execute(); - - return $values; - } /** * Method to switch the token tables from Memory tables to MyISAM tables @@ -641,7 +524,7 @@ protected function toggleTables($memory) static $state; // Get the database adapter. - $db = JFactory::getDbo(); + $db = $this->db; // Check if we are setting the tables to the Memory engine. if ($memory === true && $state !== true) diff --git a/administrator/components/com_finder/helpers/indexer/driver/postgresql.php b/administrator/components/com_finder/helpers/indexer/driver/postgresql.php index 25b89c537892c..2e6de22799a53 100644 --- a/administrator/components/com_finder/helpers/indexer/driver/postgresql.php +++ b/administrator/components/com_finder/helpers/indexer/driver/postgresql.php @@ -3,12 +3,15 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\CMS\Factory; +use Joomla\String\StringHelper; + jimport('joomla.filesystem.file'); /** @@ -33,7 +36,7 @@ public function index($item, $format = 'html') { // Mark beforeIndexing in the profiler. static::$profiler ? static::$profiler->mark('beforeIndexing') : null; - $db = JFactory::getDbo(); + $db = $this->db; $nd = $db->getNullDate(); // Check if the item is in the database. @@ -58,7 +61,7 @@ public function index($item, $format = 'html') $isNew = empty($link->link_id) ? true : false; // Check the signatures. If they match, the item is up to date. - if (!$isNew && $curSig == $oldSig) + if (!$isNew && $curSig === $oldSig) { return $linkId; } @@ -102,68 +105,37 @@ public function index($item, $format = 'html') * Otherwise, we need to use an INSERT to get the link id back. */ + $entry = new stdClass; + $entry->url = $item->url; + $entry->route = $item->route; + $entry->title = $item->title; + + // We are shortening the description in order to not run into length issues with this field + $entry->description = StringHelper::substr($item->description, 0, 32000); + $entry->indexdate = Factory::getDate()->toSql(); + $entry->state = (int) $item->state; + $entry->access = (int) $item->access; + $entry->language = $item->language; + $entry->type_id = (int) $item->type_id; + $entry->object = ''; + $entry->publish_start_date = $item->publish_start_date; + $entry->publish_end_date = $item->publish_end_date; + $entry->start_date = $item->start_date; + $entry->end_date = $item->end_date; + $entry->list_price = (double) ($item->list_price ?: 0); + $entry->sale_price = (double) ($item->sale_price ?: 0); + if ($isNew) { - $columnsArray = array( - $db->quoteName('url'), $db->quoteName('route'), $db->quoteName('title'), $db->quoteName('description'), - $db->quoteName('indexdate'), $db->quoteName('published'), $db->quoteName('state'), $db->quoteName('access'), - $db->quoteName('language'), $db->quoteName('type_id'), $db->quoteName('object'), $db->quoteName('publish_start_date'), - $db->quoteName('publish_end_date'), $db->quoteName('start_date'), $db->quoteName('end_date'), $db->quoteName('list_price'), - $db->quoteName('sale_price') - ); - - // Insert the link. - $query->clear() - ->insert($db->quoteName('#__finder_links')) - ->columns($columnsArray) - ->values( - $db->quote($item->url) . ', ' - . $db->quote($item->route) . ', ' - . $db->quote($item->title) . ', ' - . $db->quote($item->description) . ', ' - . $query->currentTimestamp() . ', ' - . '1, ' - . (int) $item->state . ', ' - . (int) $item->access . ', ' - . $db->quote($item->language) . ', ' - . (int) $item->type_id . ', ' - . $db->quote(serialize($item)) . ', ' - . $db->quote($item->publish_start_date) . ', ' - . $db->quote($item->publish_end_date) . ', ' - . $db->quote($item->start_date) . ', ' - . $db->quote($item->end_date) . ', ' - . (double) ($item->list_price ? $item->list_price : 0) . ', ' - . (double) ($item->sale_price ? $item->sale_price : 0) - ); - $db->setQuery($query); - $db->execute(); - - // Get the link id. + // Insert the link and get its id. + $db->insertObject('#__finder_links', $entry); $linkId = (int) $db->insertid(); } else { // Update the link. - $query->clear() - ->update($db->quoteName('#__finder_links')) - ->set($db->quoteName('route') . ' = ' . $db->quote($item->route)) - ->set($db->quoteName('title') . ' = ' . $db->quote($item->title)) - ->set($db->quoteName('description') . ' = ' . $db->quote($item->description)) - ->set($db->quoteName('indexdate') . ' = ' . $query->currentTimestamp()) - ->set($db->quoteName('state') . ' = ' . (int) $item->state) - ->set($db->quoteName('access') . ' = ' . (int) $item->access) - ->set($db->quoteName('language') . ' = ' . $db->quote($item->language)) - ->set($db->quoteName('type_id') . ' = ' . (int) $item->type_id) - ->set($db->quoteName('object') . ' = ' . $db->quote(serialize($item))) - ->set($db->quoteName('publish_start_date') . ' = ' . $db->quote($item->publish_start_date)) - ->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date)) - ->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date)) - ->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date)) - ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ? $item->list_price : 0)) - ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ? $item->sale_price : 0)) - ->where('link_id = ' . (int) $linkId); - $db->setQuery($query); - $db->execute(); + $entry->link_id = $linkId; + $db->updateObject('#__finder_links', $entry, 'link_id'); } // Set up the variables we will need during processing. @@ -208,8 +180,7 @@ public function index($item, $format = 'html') if ($group === static::PATH_CONTEXT) { $ip = JFile::stripExt($ip); - $ip = str_replace('/', ' ', $ip); - $ip = str_replace('-', ' ', $ip); + $ip = str_replace(array('/', '-'), ' ', $ip); } // Tokenize a string of content and add it to the database. @@ -262,9 +233,6 @@ public function index($item, $format = 'html') // Add the link => node map. FinderIndexerTaxonomy::addMap($linkId, $nodeId); - - // Tokenize the node title and add them to the database. - $count += $this->tokenizeToDb($node->title, static::META_CONTEXT, $item->language, $format); } } @@ -279,28 +247,30 @@ public function index($item, $format = 'html') * table. */ $query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') . - ' (' . $db->quoteName('term_id') . - ', ' . $db->quoteName('term') . - ', ' . $db->quoteName('stem') . - ', ' . $db->quoteName('common') . - ', ' . $db->quoteName('phrase') . - ', ' . $db->quoteName('term_weight') . - ', ' . $db->quoteName('context') . - ', ' . $db->quoteName('context_weight') . - ', ' . $db->quoteName('language') . ')' . - ' SELECT' . - ' t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' . - ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, t1.language' . - ' FROM (' . - ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . - ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' . - ' WHERE t1.context = %d' . - ' ) AS t1' . - ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term' . - ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term' . - ' WHERE t2.context = %d AND t.term_id IS NOT NULL' . - ' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . - ' ORDER BY t1.term DESC'; + ' (' . $db->quoteName('term_id') . + ', ' . $db->quoteName('map_suffix') . + ', ' . $db->quoteName('term') . + ', ' . $db->quoteName('stem') . + ', ' . $db->quoteName('common') . + ', ' . $db->quoteName('phrase') . + ', ' . $db->quoteName('term_weight') . + ', ' . $db->quoteName('context') . + ', ' . $db->quoteName('context_weight') . + ', ' . $db->quoteName('total_weight') . + ', ' . $db->quoteName('language') . ')' . + ' SELECT' . + ' COALESCE(t.term_id, 0), \'\', t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' . + ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, 0, t1.language' . + ' FROM (' . + ' SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . + ' FROM ' . $db->quoteName('#__finder_tokens') . ' AS t1' . + ' WHERE t1.context = %d' . + ' ) AS t1' . + ' JOIN ' . $db->quoteName('#__finder_tokens') . ' AS t2 ON t2.term = t1.term AND t2.language = t1.language' . + ' LEFT JOIN ' . $db->quoteName('#__finder_terms') . ' AS t ON t.term = t1.term ' . + ' WHERE t2.context = %d' . + ' GROUP BY t1.term, t.term_id, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' . + ' ORDER BY t1.term DESC'; // Iterate through the contexts and aggregate the tokens per context. foreach ($state->weights as $context => $multiplier) @@ -320,31 +290,21 @@ public function index($item, $format = 'html') * table have a term of 0, then no term record exists for that * term so we need to add it to the terms table. */ - /* Emulation of IGNORE INTO behaviour */ $db->setQuery( - ' SELECT ta.term' . + 'INSERT INTO ' . $db->quoteName('#__finder_terms') . + ' (' . $db->quoteName('term') . + ', ' . $db->quoteName('stem') . + ', ' . $db->quoteName('common') . + ', ' . $db->quoteName('phrase') . + ', ' . $db->quoteName('weight') . + ', ' . $db->quoteName('soundex') . + ', ' . $db->quoteName('language') . ')' . + ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' . ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . - ' WHERE ta.term_id = 0' + ' WHERE ta.term_id = 0' . + ' GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' ); - - if ($db->loadRow() == null) - { - $db->setQuery( - 'INSERT INTO ' . $db->quoteName('#__finder_terms') . - ' (' . $db->quoteName('term') . - ', ' . $db->quoteName('stem') . - ', ' . $db->quoteName('common') . - ', ' . $db->quoteName('phrase') . - ', ' . $db->quoteName('weight') . - ', ' . $db->quoteName('soundex') . - ', ' . $db->quoteName('language') . ')' . - ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' . - ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . - ' WHERE ta.term_id = 0' . - ' GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' - ); - $db->execute(); - } + $db->execute(); /* * Now, we just inserted a bunch of new records into the terms table @@ -426,9 +386,11 @@ public function index($item, $format = 'html') static::$profiler ? static::$profiler->mark('afterMapping') : null; // Update the signature. + $object = serialize($item); $query->clear() ->update($db->quoteName('#__finder_links')) ->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig)) + ->set($db->quoteName('object') . ' = ' . $db->quote(pg_escape_bytea($object))) ->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId)); $db->setQuery($query); $db->execute(); @@ -451,64 +413,6 @@ public function index($item, $format = 'html') return $linkId; } - /** - * Method to remove a link from the index. - * - * @param integer $linkId The id of the link. - * - * @return boolean True on success. - * - * @since 2.5 - * @throws Exception on database error. - */ - public function remove($linkId) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - // Update the link counts and remove the mapping records. - for ($i = 0; $i <= 15; $i++) - { - // Update the link counts for the terms. - $query->clear() - ->update($db->quoteName('#__finder_terms') . ' AS t') - ->join('INNER', $db->quoteName('#__finder_links_terms' . dechex($i)) . ' AS m ON m.term_id = t.term_id') - ->set('links = t.links - 1') - ->where('m.link_id = ' . $db->quote((int) $linkId)); - $db->setQuery($query); - $db->execute(); - - // Remove all records from the mapping tables. - $query->clear() - ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) - ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); - $db->setQuery($query); - $db->execute(); - } - - // Delete all orphaned terms. - $query->clear() - ->delete($db->quoteName('#__finder_terms')) - ->where($db->quoteName('links') . ' <= 0'); - $db->setQuery($query); - $db->execute(); - - // Delete the link from the index. - $query->clear() - ->delete($db->quoteName('#__finder_links')) - ->where($db->quoteName('link_id') . ' = ' . $db->quote((int) $linkId)); - $db->setQuery($query); - $db->execute(); - - // Remove the taxonomy maps. - FinderIndexerTaxonomy::removeMaps($linkId); - - // Remove the orphaned taxonomy nodes. - FinderIndexerTaxonomy::removeOrphanNodes(); - - return true; - } - /** * Method to optimize the index. We use this method to remove unused terms * and any other optimizations that might be necessary. @@ -521,7 +425,7 @@ public function remove($linkId) public function optimize() { // Get the database object. - $db = JFactory::getDbo(); + $db = $this->db; $query = $db->getQuery(true); // Delete all orphaned terms. @@ -552,7 +456,7 @@ public function optimize() // Optimize the terms common table. $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_terms_common')); $db->execute(); - + // Optimize the types table. $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_types')); $db->execute(); @@ -570,78 +474,4 @@ public function optimize() return true; } - - /** - * Method to add a set of tokens to the database. - * - * @param mixed $tokens An array or single FinderIndexerToken object. - * @param mixed $context The context of the tokens. See context constants. [optional] - * - * @return integer The number of tokens inserted into the database. - * - * @since 2.5 - * @throws Exception on database error. - */ - protected function addTokensToDb($tokens, $context = '') - { - // Get the database object. - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - // Force tokens to an array. - $tokens = is_array($tokens) ? $tokens : array($tokens); - - // Count the number of token values. - $values = 0; - - // Insert the tokens into the database. - $query->insert($db->quoteName('#__finder_tokens')) - ->columns( - array( - $db->quoteName('term'), - $db->quoteName('stem'), - $db->quoteName('common'), - $db->quoteName('phrase'), - $db->quoteName('weight'), - $db->quoteName('context'), - $db->quoteName('language') - ) - ); - - // Iterate through the tokens to create SQL value sets. - foreach ($tokens as $token) - { - $query->values( - $db->quote($token->term) . ', ' - . $db->quote($token->stem) . ', ' - . (int) $token->common . ', ' - . (int) $token->phrase . ', ' - . (float) $token->weight . ', ' - . (int) $context . ', ' - . $db->quote($token->language) - ); - $values++; - } - - $db->setQuery($query); - $db->execute(); - - return $values; - } - - /** - * Method to switch the token tables from Memory tables to MyISAM tables - * when they are close to running out of memory. - * - * @param boolean $memory Flag to control how they should be toggled. - * - * @return boolean True on success. - * - * @since 2.5 - * @throws Exception on database error. - */ - protected function toggleTables($memory) - { - return true; - } } diff --git a/administrator/components/com_finder/helpers/indexer/driver/sqlsrv.php b/administrator/components/com_finder/helpers/indexer/driver/sqlsrv.php index 4598d173892c9..470630df45ad7 100644 --- a/administrator/components/com_finder/helpers/indexer/driver/sqlsrv.php +++ b/administrator/components/com_finder/helpers/indexer/driver/sqlsrv.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -41,7 +41,7 @@ public function index($item, $format = 'html') { // Mark beforeIndexing in the profiler. static::$profiler ? static::$profiler->mark('beforeIndexing') : null; - $db = JFactory::getDbo(); + $db = $this->db; $nd = $db->getNullDate(); // Check if the item is in the database. @@ -66,7 +66,7 @@ public function index($item, $format = 'html') $isNew = empty($link->link_id) ? true : false; // Check the signatures. If they match, the item is up to date. - if (!$isNew && $curSig == $oldSig) + if (!$isNew && $curSig === $oldSig) { return $linkId; } @@ -125,24 +125,24 @@ public function index($item, $format = 'html') ->insert($db->quoteName('#__finder_links')) ->columns($columnsArray) ->values( - $db->quote($item->url) . ', ' - . $db->quote($item->route) . ', ' - . $db->quote($item->title) . ', ' - . $db->quote($item->description) . ', ' - . $query->currentTimestamp() . ', ' - . '1, ' - . (int) $item->state . ', ' - . (int) $item->access . ', ' - . $db->quote($item->language) . ', ' - . (int) $item->type_id . ', ' - . $db->quote(serialize($item)) . ', ' - . $db->quote($item->publish_start_date) . ', ' - . $db->quote($item->publish_end_date) . ', ' - . $db->quote($item->start_date) . ', ' - . $db->quote($item->end_date) . ', ' - . (double) ($item->list_price ? $item->list_price : 0) . ', ' - . (double) ($item->sale_price ? $item->sale_price : 0) - ); + $db->quote($item->url) . ', ' + . $db->quote($item->route) . ', ' + . $db->quote($item->title) . ', ' + . $db->quote($item->description) . ', ' + . $query->currentTimestamp() . ', ' + . '1, ' + . (int) $item->state . ', ' + . (int) $item->access . ', ' + . $db->quote($item->language) . ', ' + . (int) $item->type_id . ', ' + . $db->quote(serialize($item)) . ', ' + . $db->quote($item->publish_start_date) . ', ' + . $db->quote($item->publish_end_date) . ', ' + . $db->quote($item->start_date) . ', ' + . $db->quote($item->end_date) . ', ' + . (double) ($item->list_price ?: 0) . ', ' + . (double) ($item->sale_price ?: 0) + ); $db->setQuery($query); $db->execute(); @@ -167,8 +167,8 @@ public function index($item, $format = 'html') ->set($db->quoteName('publish_end_date') . ' = ' . $db->quote($item->publish_end_date)) ->set($db->quoteName('start_date') . ' = ' . $db->quote($item->start_date)) ->set($db->quoteName('end_date') . ' = ' . $db->quote($item->end_date)) - ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ? $item->list_price : 0)) - ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ? $item->sale_price : 0)) + ->set($db->quoteName('list_price') . ' = ' . (double) ($item->list_price ?: 0)) + ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ?: 0)) ->where('link_id = ' . (int) $linkId); $db->setQuery($query); $db->execute(); @@ -216,8 +216,7 @@ public function index($item, $format = 'html') if ($group === static::PATH_CONTEXT) { $ip = JFile::stripExt($ip); - $ip = str_replace('/', ' ', $ip); - $ip = str_replace('-', ' ', $ip); + $ip = str_replace(array('/', '-'), ' ', $ip); } // Tokenize a string of content and add it to the database. @@ -270,9 +269,6 @@ public function index($item, $format = 'html') // Add the link => node map. FinderIndexerTaxonomy::addMap($linkId, $nodeId); - - // Tokenize the node title and add them to the database. - $count += $this->tokenizeToDb($node->title, static::META_CONTEXT, $item->language, $format); } } @@ -458,7 +454,7 @@ public function index($item, $format = 'html') */ public function remove($linkId) { - $db = JFactory::getDbo(); + $db = $this->db; $query = $db->getQuery(true); // Update the link counts and remove the mapping records. @@ -514,7 +510,7 @@ public function remove($linkId) public function optimize() { // Get the database object. - $db = JFactory::getDbo(); + $db = $this->db; $query = $db->getQuery(true); // Delete all orphaned terms. @@ -528,101 +524,4 @@ public function optimize() return true; } - - /** - * Method to add a set of tokens to the database. - * - * @param mixed $tokens An array or single FinderIndexerToken object. - * @param mixed $context The context of the tokens. See context constants. [optional] - * - * @return integer The number of tokens inserted into the database. - * - * @since 3.1 - * @throws Exception on database error. - */ - protected function addTokensToDb($tokens, $context = '') - { - // Get the database object. - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - // Force tokens to an array. - $tokens = is_array($tokens) ? $tokens : array($tokens); - - // Count the number of token values. - $values = 0; - - // Set some variables to count the iterations - $totalTokens = count($tokens); - $remaining = $totalTokens; - $iterations = 0; - $loop = true; - - do - { - // Shift the token off the array - $token = array_shift($tokens); - - $query->values( - $db->quote($token->term) . ', ' - . $db->quote($token->stem) . ', ' - . (int) $token->common . ', ' - . (int) $token->phrase . ', ' - . (float) $token->weight . ', ' - . (int) $context . ', ' - . $db->quote($token->language) - ); - $values++; - $iterations++; - $remaining--; - - // Run the query if we've reached 1000 iterations or there are no tokens remaining - if ($iterations == 1000 || $remaining == 0) - { - // Insert the tokens into the database. - $query->insert($db->quoteName('#__finder_tokens')) - ->columns( - array( - $db->quoteName('term'), - $db->quoteName('stem'), - $db->quoteName('common'), - $db->quoteName('phrase'), - $db->quoteName('weight'), - $db->quoteName('context'), - $db->quoteName('language') - ) - ); - $db->setQuery($query); - $db->execute(); - - // Reset the query - $query->clear(); - } - - // If there's nothing remaining, we're done looping - if ($remaining == 0) - { - $loop = false; - } - } - while ($loop == true); - - return $values; - } - - /** - * Method to switch the token tables from Memory tables to MyISAM tables - * when they are close to running out of memory. - * - * @param boolean $memory Flag to control how they should be toggled. - * - * @return boolean True on success. - * - * @since 3.1 - * @throws Exception on database error. - */ - protected function toggleTables($memory) - { - return true; - } } diff --git a/administrator/components/com_finder/helpers/indexer/helper.php b/administrator/components/com_finder/helpers/indexer/helper.php index e46e9d3803f3c..ea40bf776bf89 100644 --- a/administrator/components/com_finder/helpers/indexer/helper.php +++ b/administrator/components/com_finder/helpers/indexer/helper.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -64,7 +64,7 @@ public static function parse($input, $format = 'html') * @param string $lang The language of the input. * @param boolean $phrase Flag to indicate whether input could be a phrase. [optional] * - * @return array An array of FinderIndexerToken objects. + * @return array|FinderIndexerToken An array of FinderIndexerToken objects or a single FinderIndexerToken object. * * @since 2.5 */ @@ -124,14 +124,14 @@ public static function tokenize($input, $lang, $phrase = false) for ($i = 0, $n = count($terms); $i < $n; $i++) { $charMatches = array(); - $charCount = preg_match_all('#[\p{Han}]#mui', $terms[$i], $charMatches); + $charCount = preg_match_all('#[\p{Han}]#mui', $terms[$i], $charMatches); // Split apart any groups of Chinese characters. for ($j = 0; $j < $charCount; $j++) { $tSplit = StringHelper::str_ireplace($charMatches[0][$j], '', $terms[$i], false); - if (!empty($tSplit)) + if ((bool) $tSplit) { $terms[$i] = $tSplit; } @@ -177,7 +177,12 @@ public static function tokenize($input, $lang, $phrase = false) if ($i2 < $n && isset($tokens[$i2])) { // Tokenize the two word phrase. - $token = new FinderIndexerToken(array($tokens[$i]->term, $tokens[$i2]->term), $lang, $lang === 'zh' ? '' : ' '); + $token = new FinderIndexerToken( + array( + $tokens[$i]->term, + $tokens[$i2]->term + ), $lang, $lang === 'zh' ? '' : ' ' + ); $token->derived = true; // Add the token to the stack. @@ -188,7 +193,13 @@ public static function tokenize($input, $lang, $phrase = false) if ($i3 < $n && isset($tokens[$i3])) { // Tokenize the three word phrase. - $token = new FinderIndexerToken(array($tokens[$i]->term, $tokens[$i2]->term, $tokens[$i3]->term), $lang, $lang === 'zh' ? '' : ' '); + $token = new FinderIndexerToken( + array( + $tokens[$i]->term, + $tokens[$i2]->term, + $tokens[$i3]->term + ), $lang, $lang === 'zh' ? '' : ' ' + ); $token->derived = true; // Add the token to the stack. @@ -265,7 +276,7 @@ public static function addContentType($title, $mime = null) { static $types; - $db = JFactory::getDbo(); + $db = JFactory::getDbo(); $query = $db->getQuery(true); // Check if the types are loaded. @@ -311,15 +322,25 @@ public static function addContentType($title, $mime = null) public static function isCommon($token, $lang) { static $data; + static $default; + + $langCode = $lang; + + // If language requested is wildcard, use the default language. + if ($default === null && $lang === '*') + { + $default = strstr(self::getDefaultLanguage(), '-', true); + $langCode = $default; + } // Load the common tokens for the language if necessary. - if (!isset($data[$lang])) + if (!isset($data[$langCode])) { - $data[$lang] = self::getCommonWords($lang); + $data[$langCode] = self::getCommonWords($langCode); } // Check if the token is in the common array. - return in_array($token, $data[$lang], true); + return in_array($token, $data[$langCode], true); } /** @@ -406,7 +427,8 @@ public static function getPrimaryLanguage($lang) * * @return string The path for the content item. * - * @since 2.5 + * @since 2.5 + * @deprecated 4.0 */ public static function getContentPath($url) { @@ -422,7 +444,7 @@ public static function getContentPath($url) } // Build the relative route. - $uri = $router->build($url); + $uri = $router->build($url); $route = $uri->toString(array('path', 'query', 'fragment')); $route = str_replace(JUri::base(true) . '/', '', $route); @@ -433,14 +455,14 @@ public static function getContentPath($url) * Method to get extra data for a content before being indexed. This is how * we add Comments, Tags, Labels, etc. that should be available to Finder. * - * @param FinderIndexerResult &$item The item to index as an FinderIndexerResult object. + * @param FinderIndexerResult $item The item to index as a FinderIndexerResult object. * * @return boolean True on success, false on failure. * * @since 2.5 * @throws Exception on database error. */ - public static function getContentExtras(FinderIndexerResult &$item) + public static function getContentExtras(FinderIndexerResult $item) { // Get the event dispatcher. $dispatcher = JEventDispatcher::getInstance(); @@ -464,14 +486,15 @@ public static function getContentExtras(FinderIndexerResult &$item) /** * Method to process content text using the onContentPrepare event trigger. * - * @param string $text The content to process. - * @param Registry $params The parameters object. [optional] + * @param string $text The content to process. + * @param Registry $params The parameters object. [optional] + * @param FinderIndexerResult $item The item which get prepared. [optional] * * @return string The processed content. * * @since 2.5 */ - public static function prepareContent($text, $params = null) + public static function prepareContent($text, $params = null, FinderIndexerResult $item = null) { static $loaded; @@ -493,9 +516,20 @@ public static function prepareContent($text, $params = null) } // Create a mock content object. - $content = JTable::getInstance('Content'); + $content = JTable::getInstance('Content'); $content->text = $text; + if ($item) + { + $content->bind((array) $item); + $content->bind($item->getElements()); + } + + if ($item && !empty($item->context)) + { + $content->context = $item->context; + } + // Fire the onContentPrepare event. $dispatcher->trigger('onContentPrepare', array('com_finder.indexer', &$content, &$params, 0)); diff --git a/administrator/components/com_finder/helpers/indexer/indexer.php b/administrator/components/com_finder/helpers/indexer/indexer.php index e62907ec87767..e8ae10b7e6e96 100644 --- a/administrator/components/com_finder/helpers/indexer/indexer.php +++ b/administrator/components/com_finder/helpers/indexer/indexer.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -90,6 +90,51 @@ abstract class FinderIndexer */ public static $profiler; + /** + * Database driver cache. + * + * @var JDatabaseDriver + * @since 3.8.0 + */ + protected $db; + + /** + * Reusable Query Template. To be used with clone. + * + * @var JDatabaseQuery + * @since 3.8.0 + */ + protected $addTokensToDbQueryTemplate; + + /** + * FinderIndexer constructor. + * + * @since 3.8.0 + */ + public function __construct() + { + $this->db = JFactory::getDbo(); + + $db = $this->db; + + /** + * Set up query template for addTokensToDb, we will be cloning this template when needed. + * This is about twice as fast as calling the clear function or setting up a new object. + */ + $this->addTokensToDbQueryTemplate = $db->getQuery(true)->insert($db->quoteName('#__finder_tokens')) + ->columns( + array( + $db->quoteName('term'), + $db->quoteName('stem'), + $db->quoteName('common'), + $db->quoteName('phrase'), + $db->quoteName('weight'), + $db->quoteName('context'), + $db->quoteName('language') + ) + ); + } + /** * Returns a reference to the FinderIndexer object. * @@ -135,7 +180,7 @@ public static function getInstance() public static function getState() { // First, try to load from the internal state. - if (!empty(static::$state)) + if ((bool) static::$state) { return static::$state; } @@ -254,7 +299,51 @@ abstract public function index($item, $format = 'html'); * @since 2.5 * @throws Exception on database error. */ - abstract public function remove($linkId); + public function remove($linkId) + { + $db = $this->db; + $query = $db->getQuery(true); + + // Update the link counts and remove the mapping records. + for ($i = 0; $i <= 15; $i++) + { + // Update the link counts for the terms. + $query->clear() + ->update($db->quoteName('#__finder_terms', 't')) + ->join('INNER', $db->quoteName('#__finder_links_terms' . dechex($i), 'm') . + ' ON ' . $db->quoteName('m.term_id') . ' = ' . $db->quoteName('t.term_id') + ) + ->set($db->quoteName('links') . ' = ' . $db->quoteName('links') . ' - 1') + ->where($db->quoteName('m.link_id') . ' = ' . (int) $linkId); + $db->setQuery($query)->execute(); + + // Remove all records from the mapping tables. + $query->clear() + ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) + ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); + $db->setQuery($query)->execute(); + } + + // Delete all orphaned terms. + $query->clear() + ->delete($db->quoteName('#__finder_terms')) + ->where($db->quoteName('links') . ' <= 0'); + $db->setQuery($query)->execute(); + + // Delete the link from the index. + $query->clear() + ->delete($db->quoteName('#__finder_links')) + ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); + $db->setQuery($query)->execute(); + + // Remove the taxonomy maps. + FinderIndexerTaxonomy::removeMaps($linkId); + + // Remove the orphaned taxonomy nodes. + FinderIndexerTaxonomy::removeOrphanNodes(); + + return true; + } /** * Method to optimize the index. We use this method to remove unused terms @@ -340,7 +429,7 @@ protected function tokenizeToDb($input, $context, $lang, $format) $string = substr($buffer, 0, $ls); // Adjust the buffer based on the last space for the next iteration and trim. - $buffer = JString::trim(substr($buffer, $ls)); + $buffer = StringHelper::trim(substr($buffer, $ls)); } // No space character was found. else @@ -357,8 +446,7 @@ protected function tokenizeToDb($input, $context, $lang, $format) // Parse, tokenise and add tokens to the database. $count = $this->tokenizeToDbShort($string, $context, $lang, $format, $count); - unset($string); - unset($tokens); + unset($string, $tokens); } return $count; @@ -379,7 +467,7 @@ protected function tokenizeToDb($input, $context, $lang, $format) * @param string $format The format of the input. * @param integer $count The number of tokens processed so far. * - * @return integer Cummulative number of tokens extracted from the input so far. + * @return integer Cumulative number of tokens extracted from the input so far. * * @since 3.7.0 */ @@ -420,11 +508,57 @@ private function tokenizeToDbShort($input, $context, $lang, $format, $count) * @since 2.5 * @throws Exception on database error. */ - abstract protected function addTokensToDb($tokens, $context = ''); + protected function addTokensToDb($tokens, $context = '') + { + // Get the database object. + $db = $this->db; + + $query = clone $this->addTokensToDbQueryTemplate; + + // Check if a single FinderIndexerToken object was given and make it to be an array of FinderIndexerToken objects + $tokens = is_array($tokens) ? $tokens : array($tokens); + + // Count the number of token values. + $values = 0; + + // Break into chunks of no more than 1000 items + $chunks = array_chunk($tokens, 128); + + foreach ($chunks as $tokens) + { + $query->clear('values'); + + // Iterate through the tokens to create SQL value sets. + foreach ($tokens as $token) + { + $query->values( + $db->quote($token->term) . ', ' + . $db->quote($token->stem) . ', ' + . (int) $token->common . ', ' + . (int) $token->phrase . ', ' + . $db->escape((float) $token->weight) . ', ' + . (int) $context . ', ' + . $db->quote($token->language) + ); + ++$values; + } + + $db->setQuery($query)->execute(); + + // Check if we're approaching the memory limit of the token table. + if ($values > static::$state->options->get('memory_table_limit', 10000)) + { + $this->toggleTables(false); + } + } + + return $values; + } /** - * Method to switch the token tables from Memory tables to MyISAM tables + * Method to switch the token tables from Memory tables to Disk tables * when they are close to running out of memory. + * Since this is not supported/implemented in all DB-drivers, the default is a stub method, which simply returns true. * * @param boolean $memory Flag to control how they should be toggled. * @@ -433,5 +567,8 @@ abstract protected function addTokensToDb($tokens, $context = ''); * @since 2.5 * @throws Exception on database error. */ - abstract protected function toggleTables($memory); + protected function toggleTables($memory) + { + return true; + } } diff --git a/administrator/components/com_finder/helpers/indexer/parser.php b/administrator/components/com_finder/helpers/indexer/parser.php index 04cd9614586f6..be5b7b2070b07 100644 --- a/administrator/components/com_finder/helpers/indexer/parser.php +++ b/administrator/components/com_finder/helpers/indexer/parser.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/helpers/indexer/parser/html.php b/administrator/components/com_finder/helpers/indexer/parser/html.php index bb0fb1bd7f067..1ead1d358d4eb 100644 --- a/administrator/components/com_finder/helpers/indexer/parser/html.php +++ b/administrator/components/com_finder/helpers/indexer/parser/html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -60,9 +60,14 @@ public function parse($input) // Convert entities equivalent to spaces to actual spaces. $input = str_replace(array(' ', ' '), ' ', $input); - // This fixes issues such as '

    Title

    Paragraph

    ' - // being transformed into 'TitleParagraph' with no space. - $input = str_replace('>', '> ', $input); + // Add a space before both the OPEN and CLOSE tags of BLOCK and LINE BREAKING elements, + // e.g. 'all

    mobile List

    ' will become 'all mobile List' + $input = preg_replace('/(<|<\/)(' . + 'address|article|aside|blockquote|br|canvas|dd|div|dl|dt|' . + 'fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|li|' . + 'main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video' . + ')\b/i', ' $1$2', $input + ); // Strip HTML tags. $input = strip_tags($input); @@ -98,6 +103,8 @@ protected function process($input) * @param string $endTag String representing the end tag. * * @return string with blocks removed. + * + * @since 3.4 */ private function removeBlocks($input, $startTag, $endTag) { diff --git a/administrator/components/com_finder/helpers/indexer/parser/rtf.php b/administrator/components/com_finder/helpers/indexer/parser/rtf.php index e230608085775..d894aed5854d8 100644 --- a/administrator/components/com_finder/helpers/indexer/parser/rtf.php +++ b/administrator/components/com_finder/helpers/indexer/parser/rtf.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -30,12 +30,12 @@ class FinderIndexerParserRtf extends FinderIndexerParser protected function process($input) { // Remove embedded pictures. - $input = preg_replace('#{\\\pict[^}]*}#mis', '', $input); + $input = preg_replace('#{\\\pict[^}]*}#mi', '', $input); // Remove control characters. $input = str_replace(array('{', '}', "\\\n"), array(' ', ' ', "\n"), $input); - $input = preg_replace('#\\\([^;]+?);#mis', ' ', $input); - $input = preg_replace('#\\\[\'a-zA-Z0-9]+#mis', ' ', $input); + $input = preg_replace('#\\\([^;]+?);#m', ' ', $input); + $input = preg_replace('#\\\[\'a-zA-Z0-9]+#mi', ' ', $input); return $input; } diff --git a/administrator/components/com_finder/helpers/indexer/parser/txt.php b/administrator/components/com_finder/helpers/indexer/parser/txt.php index 15a11387858ef..f3f52b83f2b67 100644 --- a/administrator/components/com_finder/helpers/indexer/parser/txt.php +++ b/administrator/components/com_finder/helpers/indexer/parser/txt.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/helpers/indexer/query.php b/administrator/components/com_finder/helpers/indexer/query.php index d4d6522d8b7fa..ad3f60f4aba29 100644 --- a/administrator/components/com_finder/helpers/indexer/query.php +++ b/administrator/components/com_finder/helpers/indexer/query.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -172,7 +172,7 @@ class FinderIndexerQuery public function __construct($options) { // Get the input string. - $this->input = isset($options['input']) ? $options['input'] : null; + $this->input = isset($options['input']) ? $options['input'] : ''; // Get the empty query setting. $this->empty = isset($options['empty']) ? (bool) $options['empty'] : false; @@ -188,34 +188,34 @@ public function __construct($options) $this->dates = new Registry; // Populate the temporary date storage. - if (isset($options['date1']) && !empty($options['date1'])) + if (!empty($options['date1'])) { $this->dates->set('date1', $options['date1']); } - if (isset($options['date2']) && !empty($options['date1'])) + if (!empty($options['date2'])) { $this->dates->set('date2', $options['date2']); } - if (isset($options['when1']) && !empty($options['date1'])) + if (!empty($options['when1'])) { $this->dates->set('when1', $options['when1']); } - if (isset($options['when2']) && !empty($options['date1'])) + if (!empty($options['when2'])) { $this->dates->set('when2', $options['when2']); } // Process the static taxonomy filters. - if (isset($options['filter']) && !empty($options['filter'])) + if (!empty($options['filter'])) { $this->processStaticTaxonomy($options['filter']); } // Process the dynamic taxonomy filters. - if (isset($options['filters']) && !empty($options['filters'])) + if (!empty($options['filters'])) { $this->processDynamicTaxonomy($options['filters']); } @@ -244,9 +244,8 @@ public function __construct($options) // Remove the temporary date storage. unset($this->dates); - /* - * Lastly, determine whether this query can return a result set. - */ + // Lastly, determine whether this query can return a result set. + // Check if we have a query string. if (!empty($this->input)) { @@ -273,10 +272,10 @@ public function __construct($options) * * @since 2.5 */ - public function toUri($base = null) + public function toUri($base = '') { // Set the base if not specified. - if (empty($base)) + if ($base === '') { $base = 'index.php?option=com_finder&view=search'; } @@ -285,7 +284,7 @@ public function toUri($base = null) $uri = JUri::getInstance($base); // Add the static taxonomy filter if present. - if (!empty($this->filter)) + if ((bool) $this->filter) { $uri->setVar('f', $this->filter); } @@ -294,7 +293,7 @@ public function toUri($base = null) $t = JFactory::getApplication()->input->request->get('t', array(), 'array'); // Add the dynamic taxonomy filters if present. - if (!empty($this->filters)) + if ((bool) $this->filters) { foreach ($this->filters as $nodes) { @@ -523,7 +522,7 @@ protected function processStaticTaxonomy($filterId) $filters = ArrayHelper::toInteger($filters); // Remove any values of zero. - if (array_search(0, $filters, true) !== false) + if (in_array(0, $filters, true) !== false) { unset($filters[array_search(0, $filters, true)]); } @@ -586,7 +585,7 @@ protected function processDynamicTaxonomy($filters) $filters = ArrayHelper::toInteger($filters); // Remove any values of zero. - if (array_search(0, $filters, true) !== false) + if (in_array(0, $filters, true) !== false) { unset($filters[array_search(0, $filters, true)]); } @@ -599,6 +598,7 @@ protected function processDynamicTaxonomy($filters) // Get the database object. $db = JFactory::getDbo(); + $query = $db->getQuery(true); /* @@ -634,7 +634,7 @@ protected function processDynamicTaxonomy($filters) foreach ($results as $result) { // Check if the branch has been cleared. - if (!in_array($result->branch, $cleared)) + if (!in_array($result->branch, $cleared, true)) { // Clear the branch. $this->filters[$result->branch] = array(); @@ -691,7 +691,7 @@ protected function processDates($date1, $date2, $when1, $when2) { // Set the date filter. $this->date1 = $date->toSql(); - $this->when1 = in_array($when1, $whens) ? $when1 : 'before'; + $this->when1 = in_array($when1, $whens, true) ? $when1 : 'before'; } // The value of 'today' is a special case that we need to handle. @@ -708,7 +708,7 @@ protected function processDates($date1, $date2, $when1, $when2) { // Set the date filter. $this->date2 = $date->toSql(); - $this->when2 = in_array($when2, $whens) ? $when2 : 'before'; + $this->when2 = in_array($when2, $whens, true) ? $when2 : 'before'; } return true; @@ -815,7 +815,7 @@ protected function processString($input, $lang, $mode) { // Set the date filter. $this->date1 = $date->toSql(); - $this->when1 = in_array($modifier, $whens) ? $modifier : 'before'; + $this->when1 = in_array($modifier, $whens, true) ? $modifier : 'before'; } break; @@ -823,7 +823,7 @@ protected function processString($input, $lang, $mode) // Handle a taxonomy branch filter. default: - { + { // Try to find the node id. $return = FinderIndexerTaxonomy::getNodeByTitle($modifier, $value); @@ -831,7 +831,7 @@ protected function processString($input, $lang, $mode) if ($return) { // Check if the branch has been cleared. - if (!in_array($modifier, $cleared)) + if (!in_array($modifier, $cleared, true)) { // Clear the branch. $this->filters[$modifier] = array(); @@ -845,7 +845,7 @@ protected function processString($input, $lang, $mode) } break; - } + } } // Clean up the input string again. @@ -864,7 +864,7 @@ protected function processString($input, $lang, $mode) $matches = array(); // Extract the tokens enclosed in double quotes. - if (preg_match_all('#\"([^"]+)\"#mi', $input, $matches)) + if (preg_match_all('#\"([^"]+)\"#m', $input, $matches)) { /* * One or more phrases were found so we need to iterate through @@ -942,7 +942,7 @@ protected function processString($input, $lang, $mode) if (count($chunk)) { $phrases[] = implode(' ', $chunk); - $terms[] = implode(' ', $chunk); + $terms[] = implode(' ', $chunk); } } } @@ -950,14 +950,14 @@ protected function processString($input, $lang, $mode) { // The phrase is <= 3 words so we can use it as is. $phrases[] = $match; - $terms[] = $match; + $terms[] = $match; } } } } // Add the remaining terms if present. - if (!empty($input)) + if ((bool) $input) { $terms = array_merge($terms, explode(' ', $input)); } @@ -973,7 +973,7 @@ protected function processString($input, $lang, $mode) if (JDEBUG) { $debugStrings = array('**', '??'); - $operators = str_replace($debugStrings, '', $operators); + $operators = str_replace($debugStrings, '', $operators); } /* @@ -984,16 +984,18 @@ protected function processString($input, $lang, $mode) for ($i = 0, $c = count($terms); $i < $c; $i++) { // Check if the term is followed by an operator that we understand. - if (isset($terms[$i + 1]) && in_array($terms[$i + 1], $operators)) + if (isset($terms[$i + 1]) && in_array($terms[$i + 1], $operators, true)) { // Get the operator mode. - $op = array_search($terms[$i + 1], $operators); + $op = array_search($terms[$i + 1], $operators, true); // Handle the AND operator. if ($op === 'AND' && isset($terms[$i + 2])) { // Tokenize the current term. $token = FinderIndexerHelper::tokenize($terms[$i], $lang, true); + + // Todo: The previous function call may return an array, which seems not to be handled by the next one, which expects an object $token = $this->getTokenData($token); // Set the required flag. @@ -1001,7 +1003,7 @@ protected function processString($input, $lang, $mode) // Add the current token to the stack. $this->included[] = $token; - $this->highlight = array_merge($this->highlight, array_keys($token->matches)); + $this->highlight = array_merge($this->highlight, array_keys($token->matches)); // Skip the next token (the mode operator). $this->operators[] = $terms[$i + 1]; @@ -1015,23 +1017,21 @@ protected function processString($input, $lang, $mode) // Add the token after the next token to the stack. $this->included[] = $other; - $this->highlight = array_merge($this->highlight, array_keys($other->matches)); + $this->highlight = array_merge($this->highlight, array_keys($other->matches)); // Remove the processed phrases if possible. - if (($pk = array_search($terms[$i], $phrases)) !== false) + if (($pk = array_search($terms[$i], $phrases, true)) !== false) { unset($phrases[$pk]); } - if (($pk = array_search($terms[$i + 2], $phrases)) !== false) + if (($pk = array_search($terms[$i + 2], $phrases, true)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. - unset($terms[$i]); - unset($terms[$i + 1]); - unset($terms[$i + 2]); + unset($terms[$i], $terms[$i + 1], $terms[$i + 2]); // Adjust the loop. $i += 2; @@ -1048,10 +1048,10 @@ protected function processString($input, $lang, $mode) $token->required = false; // Add the current token to the stack. - if (count($token->matches)) + if ((bool) $token->matches) { $this->included[] = $token; - $this->highlight = array_merge($this->highlight, array_keys($token->matches)); + $this->highlight = array_merge($this->highlight, array_keys($token->matches)); } else { @@ -1069,10 +1069,10 @@ protected function processString($input, $lang, $mode) $other->required = false; // Add the token after the next token to the stack. - if (count($other->matches)) + if ((bool) $other->matches) { $this->included[] = $other; - $this->highlight = array_merge($this->highlight, array_keys($other->matches)); + $this->highlight = array_merge($this->highlight, array_keys($other->matches)); } else { @@ -1080,20 +1080,18 @@ protected function processString($input, $lang, $mode) } // Remove the processed phrases if possible. - if (($pk = array_search($terms[$i], $phrases)) !== false) + if (($pk = array_search($terms[$i], $phrases, true)) !== false) { unset($phrases[$pk]); } - if (($pk = array_search($terms[$i + 2], $phrases)) !== false) + if (($pk = array_search($terms[$i + 2], $phrases, true)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. - unset($terms[$i]); - unset($terms[$i + 1]); - unset($terms[$i + 2]); + unset($terms[$i], $terms[$i + 1], $terms[$i + 2]); // Adjust the loop. $i += 2; @@ -1101,7 +1099,7 @@ protected function processString($input, $lang, $mode) } } // Handle an orphaned OR operator. - elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators) === 'OR') + elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators, true) === 'OR') { // Skip the next token (the mode operator). $this->operators[] = $terms[$i]; @@ -1114,10 +1112,10 @@ protected function processString($input, $lang, $mode) $other->required = false; // Add the token after the next token to the stack. - if (count($other->matches)) + if ((bool) $other->matches) { $this->included[] = $other; - $this->highlight = array_merge($this->highlight, array_keys($other->matches)); + $this->highlight = array_merge($this->highlight, array_keys($other->matches)); } else { @@ -1125,21 +1123,20 @@ protected function processString($input, $lang, $mode) } // Remove the processed phrase if possible. - if (($pk = array_search($terms[$i + 1], $phrases)) !== false) + if (($pk = array_search($terms[$i + 1], $phrases, true)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. - unset($terms[$i]); - unset($terms[$i + 1]); + unset($terms[$i], $terms[$i + 1]); // Adjust the loop. $i++; continue; } // Handle the NOT operator. - elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators) === 'NOT') + elseif (isset($terms[$i + 1]) && array_search($terms[$i], $operators, true) === 'NOT') { // Skip the next token (the mode operator). $this->operators[] = $terms[$i]; @@ -1152,7 +1149,7 @@ protected function processString($input, $lang, $mode) $other->required = false; // Add the next token to the stack. - if (count($other->matches)) + if ((bool) $other->matches) { $this->excluded[] = $other; } @@ -1162,14 +1159,13 @@ protected function processString($input, $lang, $mode) } // Remove the processed phrase if possible. - if (($pk = array_search($terms[$i + 1], $phrases)) !== false) + if (($pk = array_search($terms[$i + 1], $phrases, true)) !== false) { unset($phrases[$pk]); } // Remove the processed terms. - unset($terms[$i]); - unset($terms[$i + 1]); + unset($terms[$i], $terms[$i + 1]); // Adjust the loop. $i++; @@ -1193,10 +1189,10 @@ protected function processString($input, $lang, $mode) // Add the current token to the stack. $this->included[] = $token; - $this->highlight = array_merge($this->highlight, array_keys($token->matches)); + $this->highlight = array_merge($this->highlight, array_keys($token->matches)); // Remove the processed term if possible. - if (($pk = array_search($phrases[$i], $terms)) !== false) + if (($pk = array_search($phrases[$i], $terms, true)) !== false) { unset($terms[$pk]); } @@ -1208,10 +1204,10 @@ protected function processString($input, $lang, $mode) /* * Handle any remaining tokens using the standard processing mechanism. */ - if (!empty($terms)) + if ((bool) $terms) { // Tokenize the terms. - $terms = implode(' ', $terms); + $terms = implode(' ', $terms); $tokens = FinderIndexerHelper::tokenize($terms, $lang, false); // Make sure we are working with an array. @@ -1224,13 +1220,13 @@ protected function processString($input, $lang, $mode) $token = $this->getTokenData($token); // Set the required flag for the token. - $token->required = $mode === 'AND' ? ($token->phrase ? false : true) : false; + $token->required = $mode === 'AND' ? (!$token->phrase) : false; // Add the token to the appropriate stack. - if (count($token->matches) || $token->required) + if ($token->required || (bool) $token->matches) { $this->included[] = $token; - $this->highlight = array_merge($this->highlight, array_keys($token->matches)); + $this->highlight = array_merge($this->highlight, array_keys($token->matches)); } else { @@ -1300,11 +1296,8 @@ protected function getTokenData($token) $db->setQuery($query); $matches = $db->loadObjectList(); - // Setup the container. - $token->matches = array(); - // Check the matching terms. - if (!empty($matches)) + if ((bool) $matches) { // Add the matches to the token. for ($i = 0, $c = count($matches); $i < $c; $i++) @@ -1356,7 +1349,7 @@ protected function getTokenData($token) // Get the closest match. $keys = array_keys($suggestions); - $key = $keys[0]; + $key = $keys[0]; // Add the suggested term. $token->suggestion = $results[$key]->term; diff --git a/administrator/components/com_finder/helpers/indexer/result.php b/administrator/components/com_finder/helpers/indexer/result.php index 25b5c5d517d2b..bd40ee003adda 100644 --- a/administrator/components/com_finder/helpers/indexer/result.php +++ b/administrator/components/com_finder/helpers/indexer/result.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -272,6 +272,18 @@ public function getElement($name) return null; } + /** + * Method to retrieve all elements. + * + * @return array The elements + * + * @since 3.8.3 + */ + public function getElements() + { + return $this->elements; + } + /** * Method to set additional element values in the elements array. * @@ -312,14 +324,11 @@ public function getInstructions() public function addInstruction($group, $property) { // Check if the group exists. We can't add instructions for unknown groups. - if (array_key_exists($group, $this->instructions)) + // Check if the property exists in the group. + if (array_key_exists($group, $this->instructions) && !in_array($property, $this->instructions[$group], true)) { - // Check if the property exists in the group. - if (!in_array($property, $this->instructions[$group])) - { - // Add the property to the group. - $this->instructions[$group][] = $property; - } + // Add the property to the group. + $this->instructions[$group][] = $property; } } diff --git a/administrator/components/com_finder/helpers/indexer/stemmer.php b/administrator/components/com_finder/helpers/indexer/stemmer.php index cf96686c45c8a..63dc0538f94df 100644 --- a/administrator/components/com_finder/helpers/indexer/stemmer.php +++ b/administrator/components/com_finder/helpers/indexer/stemmer.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/helpers/indexer/stemmer/fr.php b/administrator/components/com_finder/helpers/indexer/stemmer/fr.php index f857bf3279cc2..6de9b151ed721 100644 --- a/administrator/components/com_finder/helpers/indexer/stemmer/fr.php +++ b/administrator/components/com_finder/helpers/indexer/stemmer/fr.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -27,7 +27,7 @@ class FinderIndexerStemmerFr extends FinderIndexerStemmer * @var array * @since 3.0 */ - private static $stemRules = null; + private static $stemRules; /** * Method to stem a token and return the root. @@ -48,7 +48,7 @@ public function stem($token, $lang) } // Check if the language is French or All. - if ($lang !== 'fr' && $lang != '*') + if ($lang !== 'fr' && $lang !== '*') { return $token; } @@ -144,26 +144,26 @@ protected static function getStemRules() * that can be applied to the given reversed input. * returns -1 if no rule can be applied, ie the stem has been found * - * @param string $reversed_input The input to check in reversed order - * @param integer $rule_number The rule number to check + * @param string $reversedInput The input to check in reversed order + * @param integer $ruleNumber The rule number to check * * @return integer Number of the first rule * * @since 3.0 */ - private static function getFirstRule($reversed_input, $rule_number) + private static function getFirstRule($reversedInput, $ruleNumber) { $vars = static::getStemRules(); $nb_rules = count($vars['rules']); - for ($i = $rule_number; $i < $nb_rules; $i++) + for ($i = $ruleNumber; $i < $nb_rules; $i++) { // Gets the letters from the current rule $rule = $vars['rules'][$i]; $rule = preg_replace($vars['rule_pattern'], "\\1", $rule); - if (strncasecmp(utf8_decode($rule), $reversed_input, strlen(utf8_decode($rule))) == 0) + if (strncasecmp(utf8_decode($rule), $reversedInput, strlen(utf8_decode($rule))) == 0) { return $i; } @@ -175,31 +175,31 @@ private static function getFirstRule($reversed_input, $rule_number) /** * Check the acceptability of a stem for French language * - * @param string $reversed_stem The stem to check in reverse form + * @param string $reversedStem The stem to check in reverse form * * @return boolean True if stem is acceptable * * @since 3.0 */ - private static function check($reversed_stem) + private static function check($reversedStem) { $vars = static::getStemRules(); - if (preg_match('/[' . $vars['vowels'] . ']$/', utf8_encode($reversed_stem))) + if (preg_match('/[' . $vars['vowels'] . ']$/', utf8_encode($reversedStem))) { // If the form starts with a vowel then at least two letters must remain after stemming (e.g.: "etaient" --> "et") - return (strlen($reversed_stem) > 2); + return (strlen($reversedStem) > 2); } else { // If the reversed stem starts with a consonant then at least two letters must remain after stemming - if (strlen($reversed_stem) <= 2) + if (strlen($reversedStem) <= 2) { return false; } // And at least one of these must be a vowel or "y" - return (preg_match('/[' . $vars['vowels'] . ']/', utf8_encode($reversed_stem))); + return preg_match('/[' . $vars['vowels'] . ']/', utf8_encode($reversedStem)); } } @@ -216,7 +216,6 @@ private static function getStem($input) { $vars = static::getStemRules(); - $intact = true; $reversed_input = strrev(utf8_decode($input)); $rule_number = 0; @@ -225,7 +224,7 @@ private static function getStem($input) { $rule_number = self::getFirstRule($reversed_input, $rule_number); - if ($rule_number == -1) + if ($rule_number === -1) { // No other rule can be applied => the stem has been found break; @@ -234,23 +233,15 @@ private static function getStem($input) $rule = $vars['rules'][$rule_number]; preg_match($vars['rule_pattern'], $rule, $matches); - if (($matches[2] != '*') || ($intact)) - { - $reversed_stem = utf8_decode($matches[4]) . substr($reversed_input, $matches[3], strlen($reversed_input) - $matches[3]); + $reversed_stem = utf8_decode($matches[4]) . substr($reversed_input, $matches[3]); - if (self::check($reversed_stem)) - { - $reversed_input = $reversed_stem; + if (self::check($reversed_stem)) + { + $reversed_input = $reversed_stem; - if ($matches[5] == '.') - { - break; - } - } - else + if ($matches[5] === '.') { - // Go to another rule - $rule_number++; + break; } } else diff --git a/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php b/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php index 4be1b8e4a498b..276bf5d6599a9 100644 --- a/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php +++ b/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -56,7 +56,7 @@ public function stem($token, $lang) } // Check if the language is English or All. - if ($lang !== 'en' && $lang != '*') + if ($lang !== 'en' && $lang !== '*') { return $token; } @@ -92,16 +92,16 @@ public function stem($token, $lang) private static function step1ab($word) { // Part a - if (substr($word, -1) == 's') + if (substr($word, -1) === 's') { self::replace($word, 'sses', 'ss') - or self::replace($word, 'ies', 'i') - or self::replace($word, 'ss', 'ss') - or self::replace($word, 's', ''); + || self::replace($word, 'ies', 'i') + || self::replace($word, 'ss', 'ss') + || self::replace($word, 's', ''); } // Part b - if (substr($word, -2, 1) != 'e' or !self::replace($word, 'eed', 'ee', 0)) + if (substr($word, -2, 1) !== 'e' || !self::replace($word, 'eed', 'ee', 0)) { // First rule $v = self::$regex_vowel; @@ -109,17 +109,19 @@ private static function step1ab($word) // Words ending with ing and ed // Note use of && and OR, for precedence reasons if (preg_match("#$v+#", substr($word, 0, -3)) && self::replace($word, 'ing', '') - or preg_match("#$v+#", substr($word, 0, -2)) && self::replace($word, 'ed', '')) + || preg_match("#$v+#", substr($word, 0, -2)) && self::replace($word, 'ed', '')) { // If one of above two test successful - if (!self::replace($word, 'at', 'ate') and !self::replace($word, 'bl', 'ble') and !self::replace($word, 'iz', 'ize')) + if (!self::replace($word, 'at', 'ate') && !self::replace($word, 'bl', 'ble') && !self::replace($word, 'iz', 'ize')) { // Double consonant ending - if (self::doubleConsonant($word) and substr($word, -2) != 'll' and substr($word, -2) != 'ss' and substr($word, -2) != 'zz') + $wordSubStr = substr($word, -2); + + if ($wordSubStr !== 'll' && $wordSubStr !== 'ss' && $wordSubStr !== 'zz' && self::doubleConsonant($word)) { $word = substr($word, 0, -1); } - elseif (self::m($word) == 1 and self::cvc($word)) + elseif (self::m($word) === 1 && self::cvc($word)) { $word .= 'e'; } @@ -143,7 +145,7 @@ private static function step1c($word) { $v = self::$regex_vowel; - if (substr($word, -1) == 'y' && preg_match("#$v+#", substr($word, 0, -1))) + if (substr($word, -1) === 'y' && preg_match("#$v+#", substr($word, 0, -1))) { self::replace($word, 'y', 'i'); } @@ -166,11 +168,11 @@ private static function step2($word) { case 'a': self::replace($word, 'ational', 'ate', 0) - or self::replace($word, 'tional', 'tion', 0); + || self::replace($word, 'tional', 'tion', 0); break; case 'c': self::replace($word, 'enci', 'ence', 0) - or self::replace($word, 'anci', 'ance', 0); + || self::replace($word, 'anci', 'ance', 0); break; case 'e': self::replace($word, 'izer', 'ize', 0); @@ -180,26 +182,26 @@ private static function step2($word) break; case 'l': self::replace($word, 'entli', 'ent', 0) - or self::replace($word, 'ousli', 'ous', 0) - or self::replace($word, 'alli', 'al', 0) - or self::replace($word, 'bli', 'ble', 0) - or self::replace($word, 'eli', 'e', 0); + || self::replace($word, 'ousli', 'ous', 0) + || self::replace($word, 'alli', 'al', 0) + || self::replace($word, 'bli', 'ble', 0) + || self::replace($word, 'eli', 'e', 0); break; case 'o': self::replace($word, 'ization', 'ize', 0) - or self::replace($word, 'ation', 'ate', 0) - or self::replace($word, 'ator', 'ate', 0); + || self::replace($word, 'ation', 'ate', 0) + || self::replace($word, 'ator', 'ate', 0); break; case 's': self::replace($word, 'iveness', 'ive', 0) - or self::replace($word, 'fulness', 'ful', 0) - or self::replace($word, 'ousness', 'ous', 0) - or self::replace($word, 'alism', 'al', 0); + || self::replace($word, 'fulness', 'ful', 0) + || self::replace($word, 'ousness', 'ous', 0) + || self::replace($word, 'alism', 'al', 0); break; case 't': self::replace($word, 'biliti', 'ble', 0) - or self::replace($word, 'aliti', 'al', 0) - or self::replace($word, 'iviti', 'ive', 0); + || self::replace($word, 'aliti', 'al', 0) + || self::replace($word, 'iviti', 'ive', 0); break; } @@ -227,7 +229,7 @@ private static function step3($word) break; case 't': self::replace($word, 'icate', 'ic', 0) - or self::replace($word, 'iciti', 'ic', 0); + || self::replace($word, 'iciti', 'ic', 0); break; case 'u': self::replace($word, 'ful', '', 0); @@ -260,8 +262,8 @@ private static function step4($word) self::replace($word, 'al', '', 1); break; case 'c': - self::replace($word, 'ance', '', 1) - or self::replace($word, 'ence', '', 1); + self::replace($word, 'ance', '', 1) + || self::replace($word, 'ence', '', 1); break; case 'e': self::replace($word, 'er', '', 1); @@ -271,16 +273,18 @@ private static function step4($word) break; case 'l': self::replace($word, 'able', '', 1) - or self::replace($word, 'ible', '', 1); + || self::replace($word, 'ible', '', 1); break; case 'n': self::replace($word, 'ant', '', 1) - or self::replace($word, 'ement', '', 1) - or self::replace($word, 'ment', '', 1) - or self::replace($word, 'ent', '', 1); + || self::replace($word, 'ement', '', 1) + || self::replace($word, 'ment', '', 1) + || self::replace($word, 'ent', '', 1); break; case 'o': - if (substr($word, -4) == 'tion' or substr($word, -4) == 'sion') + $wordSubStr = substr($word, -4); + + if ($wordSubStr === 'tion' || $wordSubStr === 'sion') { self::replace($word, 'ion', '', 1); } @@ -293,8 +297,8 @@ private static function step4($word) self::replace($word, 'ism', '', 1); break; case 't': - self::replace($word, 'ate', '', 1) - or self::replace($word, 'iti', '', 1); + self::replace($word, 'ate', '', 1) + || self::replace($word, 'iti', '', 1); break; case 'u': self::replace($word, 'ous', '', 1); @@ -322,13 +326,13 @@ private static function step4($word) private static function step5($word) { // Part a - if (substr($word, -1) == 'e') + if (substr($word, -1) === 'e') { if (self::m(substr($word, 0, -1)) > 1) { self::replace($word, 'e', ''); } - elseif (self::m(substr($word, 0, -1)) == 1) + elseif (self::m(substr($word, 0, -1)) === 1) { if (!self::cvc(substr($word, 0, -1))) { @@ -338,7 +342,7 @@ private static function step5($word) } // Part b - if (self::m($word) > 1 and self::doubleConsonant($word) and substr($word, -1) == 'l') + if (self::m($word) > 1 && self::doubleConsonant($word) && substr($word, -1) === 'l') { $word = substr($word, 0, -1); } @@ -350,7 +354,7 @@ private static function step5($word) * Replaces the first string with the second, at the end of the string. If third * arg is given, then the preceding string must match that m count at least. * - * @param string &$str String to check + * @param string $str String to check * @param string $check Ending to check for * @param string $repl Replacement string * @param integer $m Optional minimum number of m() to meet @@ -365,11 +369,11 @@ private static function replace(&$str, $check, $repl, $m = null) { $len = 0 - strlen($check); - if (substr($str, $len) == $check) + if (substr($str, $len) === $check) { $substr = substr($str, 0, $len); - if (is_null($m) or self::m($substr) > $m) + if ($m === null || self::m($substr) > $m) { $str = $substr . $repl; } @@ -423,7 +427,7 @@ private static function doubleConsonant($str) { $c = self::$regex_consonant; - return preg_match("#$c{2}$#", $str, $matches) and $matches[0]{0} == $matches[0]{1}; + return preg_match("#$c{2}$#", $str, $matches) && $matches[0][0] === $matches[0][1]; } /** @@ -440,7 +444,7 @@ private static function cvc($str) $c = self::$regex_consonant; $v = self::$regex_vowel; - return preg_match("#($c$v$c)$#", $str, $matches) and strlen($matches[1]) == 3 and $matches[1]{2} != 'w' and $matches[1]{2} != 'x' - and $matches[1]{2} != 'y'; + return preg_match("#($c$v$c)$#", $str, $matches) && strlen($matches[1]) === 3 && $matches[1][2] !== 'w' && $matches[1][2] !== 'x' + && $matches[1][2] !== 'y'; } } diff --git a/administrator/components/com_finder/helpers/indexer/stemmer/snowball.php b/administrator/components/com_finder/helpers/indexer/stemmer/snowball.php index 7c2f77243881f..b1f44e1b1822d 100644 --- a/administrator/components/com_finder/helpers/indexer/stemmer/snowball.php +++ b/administrator/components/com_finder/helpers/indexer/stemmer/snowball.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -34,7 +34,7 @@ public function stem($token, $lang) static $defaultLang = ''; // If language is All then try to get site default language. - if ($lang == '*' && $defaultLang == '') + if ($lang === '*' && $defaultLang === '') { $languages = JLanguageHelper::getLanguages(); $defaultLang = isset($languages[0]->sef) ? $languages[0]->sef : '*'; diff --git a/administrator/components/com_finder/helpers/indexer/taxonomy.php b/administrator/components/com_finder/helpers/indexer/taxonomy.php index 75b7a40529f76..864de20192e62 100644 --- a/administrator/components/com_finder/helpers/indexer/taxonomy.php +++ b/administrator/components/com_finder/helpers/indexer/taxonomy.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -65,7 +65,7 @@ public static function addBranch($title, $state = 1, $access = 1) $result = $db->loadObject(); // Check if the database matches the input data. - if (!empty($result) && $result->state == $state && $result->access == $access) + if ((bool) $result && $result->state == $state && $result->access == $access) { // The data matches, add the item to the cache. static::$branches[$title] = $result; @@ -145,7 +145,7 @@ public static function addNode($branch, $title, $state = 1, $access = 1) $result = $db->loadObject(); // Check if the database matches the input data. - if (!empty($result) && $result->state == $state && $result->access == $access) + if ((bool) $result && $result->state == $state && $result->access == $access) { // The data matches, add the item to the cache. static::$nodes[$branch][$title] = $result; @@ -329,23 +329,29 @@ public static function removeOrphanNodes() { // Delete all orphaned nodes. $db = JFactory::getDbo(); - $query = $db->getQuery(true); - $subquery = $db->getQuery(true); - $subquery1 = $db->getQuery(true); - $subquery1->select($db->quoteName('t.id')) + $query = $db->getQuery(true) + ->select($db->quoteName('t.id')) ->from($db->quoteName('#__finder_taxonomy', 't')) ->join('LEFT', $db->quoteName('#__finder_taxonomy_map', 'm') . ' ON ' . $db->quoteName('m.node_id') . '=' . $db->quoteName('t.id')) ->where($db->quoteName('t.parent_id') . ' > 1 ') ->where($db->quoteName('m.link_id') . ' IS NULL'); - $subquery->select($db->quoteName('id')) - ->from('(' . $subquery1 . ') temp'); + $db->setQuery($query); + + $ids = $db->loadColumn(); + + if (empty($ids)) + { + return 0; + } - $query->delete($db->quoteName('#__finder_taxonomy')) - ->where($db->quoteName('id') . ' IN (' . $subquery . ')'); + $query->clear() + ->delete($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('id') . ' IN (' . implode(',', $ids) . ')'); $db->setQuery($query); + $db->execute(); return $db->getAffectedRows(); diff --git a/administrator/components/com_finder/helpers/indexer/token.php b/administrator/components/com_finder/helpers/indexer/token.php index f5602e34717f6..d943236799db0 100644 --- a/administrator/components/com_finder/helpers/indexer/token.php +++ b/administrator/components/com_finder/helpers/indexer/token.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -87,6 +87,30 @@ class FinderIndexerToken */ public $language; + /** + * The container for matches. + * + * @var array + * @since 3.8.12 + */ + public $matches = array(); + + /** + * Is derived token (from individual words) + * + * @var boolean + * @since 3.8.12 + */ + public $derived; + + /** + * The suggested term + * + * @var string + * @since 3.8.12 + */ + public $suggestion; + /** * Method to construct the token object. * @@ -138,9 +162,9 @@ public function __construct($term, $lang, $spacer = ' ') * 3. If numeric, multiply weight by 1.5. * 4. Round weight to 4 decimal points. */ - $this->weight = (($this->length >= 15 ? 15 : $this->length) / 15); - $this->weight = ($this->common == true ? $this->weight / 8 : $this->weight); - $this->weight = ($this->numeric == true ? $this->weight * 1.5 : $this->weight); + $this->weight = ($this->length >= 15 ? 15 : $this->length) / 15; + $this->weight = $this->common === true ? $this->weight / 8 : $this->weight; + $this->weight = $this->numeric === true ? $this->weight * 1.5 : $this->weight; $this->weight = round($this->weight, 4); } } diff --git a/administrator/components/com_finder/helpers/language.php b/administrator/components/com_finder/helpers/language.php index 169dc710cd41f..c31b89c3e3f55 100644 --- a/administrator/components/com_finder/helpers/language.php +++ b/administrator/components/com_finder/helpers/language.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -29,7 +29,7 @@ public static function branchPlural($branchName) { $return = preg_replace('/[^a-zA-Z0-9]+/', '_', strtoupper($branchName)); - if ($return != '_') + if ($return !== '_') { return 'PLG_FINDER_QUERY_FILTER_BRANCH_P_' . $return; } @@ -66,13 +66,14 @@ public static function branchLanguageTitle($branchName) { $title = $branchName; - if ($branchName == '*') + if ($branchName === '*') { $title = JText::_('JALL_LANGUAGE'); } else { $languages = JLanguageHelper::getLanguages('lang_code'); + if (isset($languages[$branchName])) { $title = $languages[$branchName]->title; diff --git a/administrator/components/com_finder/models/fields/branches.php b/administrator/components/com_finder/models/fields/branches.php index dcf416f0cfe9f..2592f47cbf5f6 100644 --- a/administrator/components/com_finder/models/fields/branches.php +++ b/administrator/components/com_finder/models/fields/branches.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/models/fields/contentmap.php b/administrator/components/com_finder/models/fields/contentmap.php index 3e12dacff3a5c..dea189aa64973 100644 --- a/administrator/components/com_finder/models/fields/contentmap.php +++ b/administrator/components/com_finder/models/fields/contentmap.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -93,7 +93,7 @@ protected function getGroups() { $levelPrefix = str_repeat('- ', max(0, $branch->level - 1)); - if (trim($name, '**') == 'Language') + if (trim($name, '**') === 'Language') { $text = FinderHelperLanguage::branchLanguageTitle($branch->text); } diff --git a/administrator/components/com_finder/models/fields/contenttypes.php b/administrator/components/com_finder/models/fields/contenttypes.php index dee0f1cc8af98..e5e3e2e9816d7 100644 --- a/administrator/components/com_finder/models/fields/contenttypes.php +++ b/administrator/components/com_finder/models/fields/contenttypes.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/models/fields/directories.php b/administrator/components/com_finder/models/fields/directories.php index fdb24125d3c81..e557f2dce8f8a 100644 --- a/administrator/components/com_finder/models/fields/directories.php +++ b/administrator/components/com_finder/models/fields/directories.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -17,7 +17,8 @@ /** * Renders a list of directories. * - * @since 2.5 + * @since 2.5 + * @deprecated 4.0 Use JFormFieldFolderlist */ class JFormFieldDirectories extends JFormFieldList { diff --git a/administrator/components/com_finder/models/fields/searchfilter.php b/administrator/components/com_finder/models/fields/searchfilter.php index d4a36094ba2f0..a6e93d6bb7b60 100644 --- a/administrator/components/com_finder/models/fields/searchfilter.php +++ b/administrator/components/com_finder/models/fields/searchfilter.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/models/filter.php b/administrator/components/com_finder/models/filter.php index 17e1d6fe0d1a2..9a2608667df34 100644 --- a/administrator/components/com_finder/models/filter.php +++ b/administrator/components/com_finder/models/filter.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -35,16 +35,16 @@ class FinderModelFilter extends JModelAdmin /** * Custom clean cache method. * - * @param string $group The component name. [optional] - * @param integer $client_id The client ID. [optional] + * @param string $group The component name. [optional] + * @param integer $clientId The client ID. [optional] * * @return void * * @since 2.5 */ - protected function cleanCache($group = 'com_finder', $client_id = 1) + protected function cleanCache($group = 'com_finder', $clientId = 1) { - parent::cleanCache($group, $client_id); + parent::cleanCache($group, $clientId); } /** @@ -163,13 +163,11 @@ protected function loadFormData() */ public function getTotal() { - $db = JFactory::getDbo(); + $db = JFactory::getDbo(); $query = $db->getQuery(true) ->select('MAX(link_id)') ->from('#__finder_links'); - $db->setQuery($query); - $total = $db->loadResult(); - return $total; + return $db->setQuery($query)->loadResult(); } } diff --git a/administrator/components/com_finder/models/filters.php b/administrator/components/com_finder/models/filters.php index 470091e572bfe..48eb6d17413bb 100644 --- a/administrator/components/com_finder/models/filters.php +++ b/administrator/components/com_finder/models/filters.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/models/forms/filter_filters.xml b/administrator/components/com_finder/models/forms/filter_filters.xml index f5ea1528f992b..d930402675dbd 100644 --- a/administrator/components/com_finder/models/forms/filter_filters.xml +++ b/administrator/components/com_finder/models/forms/filter_filters.xml @@ -4,6 +4,7 @@ diff --git a/administrator/components/com_finder/models/forms/filter_index.xml b/administrator/components/com_finder/models/forms/filter_index.xml index 0e38017706479..e32889898b6e0 100644 --- a/administrator/components/com_finder/models/forms/filter_index.xml +++ b/administrator/components/com_finder/models/forms/filter_index.xml @@ -4,6 +4,7 @@ diff --git a/administrator/components/com_finder/models/forms/filter_maps.xml b/administrator/components/com_finder/models/forms/filter_maps.xml index 312d66aa9a85e..b73933166b39c 100644 --- a/administrator/components/com_finder/models/forms/filter_maps.xml +++ b/administrator/components/com_finder/models/forms/filter_maps.xml @@ -4,6 +4,7 @@ diff --git a/administrator/components/com_finder/models/index.php b/administrator/components/com_finder/models/index.php index 04e2560dbe9db..029d52218dc5a 100644 --- a/administrator/components/com_finder/models/index.php +++ b/administrator/components/com_finder/models/index.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -89,7 +89,7 @@ protected function canEditState($record) /** * Method to delete one or more records. * - * @param array &$pks An array of record primary keys. + * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * @@ -225,7 +225,7 @@ protected function getListQuery() $listOrder = $this->getState('list.ordering', 'l.title'); $listDir = $this->getState('list.direction', 'ASC'); - if ($listOrder == 't.title') + if ($listOrder === 't.title') { $ordering = $db->quoteName('t.title') . ' ' . $db->escape($listDir) . ', ' . $db->quoteName('l.title') . ' ' . $db->escape($listDir); } @@ -287,7 +287,7 @@ protected function getStoreId($id = '') /** * Gets the total of indexed items. * - * @return int The total of indexed items. + * @return integer The total of indexed items. * * @since 3.6.0 */ @@ -395,7 +395,7 @@ protected function populateState($ordering = 'l.title', $direction = 'asc') /** * Method to change the published state of one or more records. * - * @param array &$pks A list of the primary keys to change. + * @param array $pks A list of the primary keys to change. * @param integer $value The value of the published state. [optional] * * @return boolean True on success. @@ -417,16 +417,13 @@ public function publish(&$pks, $value = 1) { $table->reset(); - if ($table->load($pk)) + if ($table->load($pk) && !$this->canEditState($table)) { - if (!$this->canEditState($table)) - { - // Prune items that you can't change. - unset($pks[$i]); - $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + // Prune items that you can't change. + unset($pks[$i]); + $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - return false; - } + return false; } } diff --git a/administrator/components/com_finder/models/indexer.php b/administrator/components/com_finder/models/indexer.php index 2a7bd531a9343..3cc2179700683 100644 --- a/administrator/components/com_finder/models/indexer.php +++ b/administrator/components/com_finder/models/indexer.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/models/maps.php b/administrator/components/com_finder/models/maps.php index 6b25455578a99..13e67010c4548 100644 --- a/administrator/components/com_finder/models/maps.php +++ b/administrator/components/com_finder/models/maps.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -71,7 +71,7 @@ protected function canEditState($record) /** * Method to delete one or more records. * - * @param array &$pks An array of record primary keys. + * @param array $pks An array of record primary keys. * * @return boolean True if successful, false if an error occurs. * @@ -225,11 +225,11 @@ protected function getListQuery() $listOrdering = $this->getState('list.ordering', 'd.branch_title'); $listDirn = $this->getState('list.direction', 'ASC'); - if ($listOrdering == 'd.branch_title') + if ($listOrdering === 'd.branch_title') { $query->order("branch_title $listDirn, level ASC, a.title $listDirn"); } - elseif ($listOrdering == 'a.state') + elseif ($listOrdering === 'a.state') { $query->order("a.state $listDirn, branch_title $listDirn, level ASC"); } @@ -323,7 +323,7 @@ protected function populateState($ordering = 'd.branch_title', $direction = 'ASC /** * Method to change the published state of one or more records. * - * @param array &$pks A list of the primary keys to change. + * @param array $pks A list of the primary keys to change. * @param integer $value The value of the published state. [optional] * * @return boolean True on success. @@ -345,16 +345,13 @@ public function publish(&$pks, $value = 1) { $table->reset(); - if ($table->load($pk)) + if ($table->load($pk) && !$this->canEditState($table)) { - if (!$this->canEditState($table)) - { - // Prune items that you can't change. - unset($pks[$i]); - $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + // Prune items that you can't change. + unset($pks[$i]); + $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - return false; - } + return false; } } @@ -401,8 +398,7 @@ public function purge() $db->execute(); $query->clear() - ->delete($db->quoteName('#__finder_taxonomy_map')) - ->where('1'); + ->delete($db->quoteName('#__finder_taxonomy_map')); $db->setQuery($query); $db->execute(); diff --git a/administrator/components/com_finder/models/statistics.php b/administrator/components/com_finder/models/statistics.php index d9e3a304d03f8..9241cc6f64764 100644 --- a/administrator/components/com_finder/models/statistics.php +++ b/administrator/components/com_finder/models/statistics.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/sql/install.mysql.sql b/administrator/components/com_finder/sql/install.mysql.sql index 4207fa2111075..4b8d85a4fcb95 100644 --- a/administrator/components/com_finder/sql/install.mysql.sql +++ b/administrator/components/com_finder/sql/install.mysql.sql @@ -3,18 +3,18 @@ -- CREATE TABLE IF NOT EXISTS `#__finder_filters` ( - `filter_id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `filter_id` int unsigned NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `alias` varchar(255) NOT NULL, - `state` tinyint(1) NOT NULL DEFAULT 1, + `state` tinyint NOT NULL DEFAULT 1, `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_by` int(10) unsigned NOT NULL, + `created_by` int unsigned NOT NULL, `created_by_alias` varchar(255) NOT NULL, `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `modified_by` int(10) unsigned NOT NULL DEFAULT 0, - `checked_out` int(10) unsigned NOT NULL DEFAULT 0, + `modified_by` int unsigned NOT NULL DEFAULT 0, + `checked_out` int unsigned NOT NULL DEFAULT 0, `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `map_count` int(10) unsigned NOT NULL DEFAULT 0, + `map_count` int unsigned NOT NULL DEFAULT 0, `data` text NOT NULL, `params` mediumtext, PRIMARY KEY (`filter_id`) @@ -25,16 +25,16 @@ CREATE TABLE IF NOT EXISTS `#__finder_filters` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links` ( - `link_id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `link_id` int unsigned NOT NULL AUTO_INCREMENT, `url` varchar(255) NOT NULL, `route` varchar(255) NOT NULL, `title` varchar(400) DEFAULT NULL, `description` varchar(255) DEFAULT NULL, `indexdate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `md5sum` varchar(32) DEFAULT NULL, - `published` tinyint(1) NOT NULL DEFAULT 1, - `state` int(5) DEFAULT 1, - `access` int(5) DEFAULT 0, + `published` tinyint NOT NULL DEFAULT 1, + `state` int DEFAULT 1, + `access` int DEFAULT 0, `language` varchar(8) NOT NULL, `publish_start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `publish_end_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', @@ -42,7 +42,7 @@ CREATE TABLE IF NOT EXISTS `#__finder_links` ( `end_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `list_price` double unsigned NOT NULL DEFAULT 0, `sale_price` double unsigned NOT NULL DEFAULT 0, - `type_id` int(11) NOT NULL, + `type_id` int NOT NULL, `object` mediumblob NOT NULL, PRIMARY KEY (`link_id`), KEY `idx_type` (`type_id`), @@ -58,8 +58,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -71,8 +71,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms1` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -84,8 +84,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms1` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms2` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -97,8 +97,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms2` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms3` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -110,8 +110,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms3` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms4` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -123,8 +123,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms4` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms5` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -136,8 +136,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms5` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms6` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -149,8 +149,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms6` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms7` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -162,8 +162,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms7` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms8` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -175,8 +175,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms8` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_terms9` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -188,8 +188,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms9` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsa` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -201,8 +201,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsa` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsb` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -214,8 +214,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsb` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsc` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -227,8 +227,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsc` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsd` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -240,8 +240,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsd` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_termse` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -253,8 +253,8 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termse` ( -- CREATE TABLE IF NOT EXISTS `#__finder_links_termsf` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `weight` float unsigned NOT NULL, PRIMARY KEY (`link_id`,`term_id`), KEY `idx_term_weight` (`term_id`,`weight`), @@ -266,12 +266,12 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_termsf` ( -- CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `parent_id` int(10) unsigned NOT NULL DEFAULT 0, + `id` int unsigned NOT NULL AUTO_INCREMENT, + `parent_id` int unsigned NOT NULL DEFAULT 0, `title` varchar(255) NOT NULL, - `state` tinyint(1) unsigned NOT NULL DEFAULT 1, - `access` tinyint(1) unsigned NOT NULL DEFAULT 0, - `ordering` tinyint(1) unsigned NOT NULL DEFAULT 0, + `state` tinyint unsigned NOT NULL DEFAULT 1, + `access` tinyint unsigned NOT NULL DEFAULT 0, + `ordering` tinyint unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `parent_id` (`parent_id`), KEY `state` (`state`), @@ -292,8 +292,8 @@ REPLACE INTO `#__finder_taxonomy` (`id`, `parent_id`, `title`, `state`, `access` -- CREATE TABLE IF NOT EXISTS `#__finder_taxonomy_map` ( - `link_id` int(10) unsigned NOT NULL, - `node_id` int(10) unsigned NOT NULL, + `link_id` int unsigned NOT NULL, + `node_id` int unsigned NOT NULL, PRIMARY KEY (`link_id`,`node_id`), KEY `link_id` (`link_id`), KEY `node_id` (`node_id`) @@ -304,14 +304,14 @@ CREATE TABLE IF NOT EXISTS `#__finder_taxonomy_map` ( -- CREATE TABLE IF NOT EXISTS `#__finder_terms` ( - `term_id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `term_id` int unsigned NOT NULL AUTO_INCREMENT, `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, - `common` tinyint(1) unsigned NOT NULL DEFAULT 0, - `phrase` tinyint(1) unsigned NOT NULL DEFAULT 0, + `common` tinyint unsigned NOT NULL DEFAULT 0, + `phrase` tinyint unsigned NOT NULL DEFAULT 0, `weight` float unsigned NOT NULL DEFAULT 0, `soundex` varchar(75) NOT NULL, - `links` int(10) NOT NULL DEFAULT 0, + `links` int NOT NULL DEFAULT 0, `language` char(3) NOT NULL DEFAULT '', PRIMARY KEY (`term_id`), UNIQUE KEY `idx_term` (`term`), @@ -454,10 +454,10 @@ REPLACE INTO `#__finder_terms_common` (`term`, `language`) VALUES CREATE TABLE IF NOT EXISTS `#__finder_tokens` ( `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, - `common` tinyint(1) unsigned NOT NULL DEFAULT 0, - `phrase` tinyint(1) unsigned NOT NULL DEFAULT 0, + `common` tinyint unsigned NOT NULL DEFAULT 0, + `phrase` tinyint unsigned NOT NULL DEFAULT 0, `weight` float unsigned NOT NULL DEFAULT 1, - `context` tinyint(1) unsigned NOT NULL DEFAULT 2, + `context` tinyint unsigned NOT NULL DEFAULT 2, `language` char(3) NOT NULL DEFAULT '', KEY `idx_word` (`term`), KEY `idx_context` (`context`) @@ -468,14 +468,14 @@ CREATE TABLE IF NOT EXISTS `#__finder_tokens` ( -- CREATE TABLE IF NOT EXISTS `#__finder_tokens_aggregate` ( - `term_id` int(10) unsigned NOT NULL, + `term_id` int unsigned NOT NULL, `map_suffix` char(1) NOT NULL, `term` varchar(75) NOT NULL, `stem` varchar(75) NOT NULL, - `common` tinyint(1) unsigned NOT NULL DEFAULT 0, - `phrase` tinyint(1) unsigned NOT NULL DEFAULT 0, + `common` tinyint unsigned NOT NULL DEFAULT 0, + `phrase` tinyint unsigned NOT NULL DEFAULT 0, `term_weight` float unsigned NOT NULL, - `context` tinyint(1) unsigned NOT NULL DEFAULT 2, + `context` tinyint unsigned NOT NULL DEFAULT 2, `context_weight` float unsigned NOT NULL, `total_weight` float unsigned NOT NULL, `language` char(3) NOT NULL DEFAULT '', @@ -488,7 +488,7 @@ CREATE TABLE IF NOT EXISTS `#__finder_tokens_aggregate` ( -- CREATE TABLE IF NOT EXISTS `#__finder_types` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id` int unsigned NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL, `mime` varchar(100) NOT NULL, PRIMARY KEY (`id`), diff --git a/administrator/components/com_finder/tables/filter.php b/administrator/components/com_finder/tables/filter.php index 6ca4b0cd73490..a7b672030bee3 100644 --- a/administrator/components/com_finder/tables/filter.php +++ b/administrator/components/com_finder/tables/filter.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -22,13 +22,15 @@ class FinderTableFilter extends JTable /** * Constructor * - * @param JDatabaseDriver &$db JDatabaseDriver connector object. + * @param JDatabaseDriver $db JDatabaseDriver connector object. * * @since 2.5 */ public function __construct(&$db) { parent::__construct('#__finder_filters', 'filter_id', $db); + + $this->setColumnAlias('published', 'state'); } /** @@ -67,14 +69,14 @@ public function bind($array, $ignore = '') */ public function check() { - if (trim($this->alias) == '') + if (trim($this->alias) === '') { $this->alias = $this->title; } $this->alias = JApplicationHelper::stringURLSafe($this->alias); - if (trim(str_replace('-', '', $this->alias)) == '') + if (trim(str_replace('-', '', $this->alias)) === '') { $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); } @@ -168,12 +170,12 @@ public function publish($pks = null, $state = 1, $userId = 0) } // If checkin is supported and all rows were adjusted, check them in. - if ($checkin && (count($pks) == $this->_db->getAffectedRows())) + if ($checkin && count($pks) === $this->_db->getAffectedRows()) { // Checkin the rows. foreach ($pks as $pk) { - $this->checkin($pk); + $this->checkIn($pk); } } @@ -240,7 +242,7 @@ public function store($updateNulls = false) } // Verify that the alias is unique - $table = JTable::getInstance('Filter', 'FinderTable'); + $table = JTable::getInstance('Filter', 'FinderTable', array('dbo' => $this->_db)); if ($table->load(array('alias' => $this->alias)) && ($table->filter_id != $this->filter_id || $this->filter_id == 0)) { diff --git a/administrator/components/com_finder/tables/link.php b/administrator/components/com_finder/tables/link.php index 640de31a4590f..ad0160c51ee2c 100644 --- a/administrator/components/com_finder/tables/link.php +++ b/administrator/components/com_finder/tables/link.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -19,7 +19,7 @@ class FinderTableLink extends JTable /** * Constructor * - * @param JDatabaseDriver &$db JDatabaseDriver connector object. + * @param JDatabaseDriver $db JDatabaseDriver connector object. * * @since 2.5 */ diff --git a/administrator/components/com_finder/tables/map.php b/administrator/components/com_finder/tables/map.php index 492e864dfdc7e..b5e215330c2c5 100644 --- a/administrator/components/com_finder/tables/map.php +++ b/administrator/components/com_finder/tables/map.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -21,7 +21,7 @@ class FinderTableMap extends JTable /** * Constructor * - * @param JDatabaseDriver &$db JDatabaseDriver connector object. + * @param JDatabaseDriver $db JDatabaseDriver connector object. * * @since 2.5 */ diff --git a/administrator/components/com_finder/views/filter/tmpl/edit.php b/administrator/components/com_finder/views/filter/tmpl/edit.php index f9aa2e68b5b16..4161caf2058df 100644 --- a/administrator/components/com_finder/views/filter/tmpl/edit.php +++ b/administrator/components/com_finder/views/filter/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -98,6 +98,6 @@
    - + diff --git a/administrator/components/com_finder/views/filter/view.html.php b/administrator/components/com_finder/views/filter/view.html.php index 702ab8076a1a3..33492254173ca 100644 --- a/administrator/components/com_finder/views/filter/view.html.php +++ b/administrator/components/com_finder/views/filter/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -20,6 +20,8 @@ class FinderViewFilter extends JViewLegacy * The filter object * * @var FinderTableFilter + * + * @since 3.6.2 */ protected $filter; @@ -27,23 +29,38 @@ class FinderViewFilter extends JViewLegacy * The JForm object * * @var JForm + * + * @since 3.6.2 */ protected $form; /** * The active item * - * @var object + * @var JObject|boolean + * + * @since 3.6.2 */ protected $item; /** * The model state * - * @var object + * @var mixed + * + * @since 3.6.2 */ protected $state; + /** + * The total indexed items + * + * @var integer + * + * @since 3.8.0 + */ + protected $total; + /** * Method to display the view. * @@ -114,19 +131,16 @@ protected function addToolbar() else { // Can't save the record if it's checked out. - if (!$checkedOut) + // Since it's an existing record, check the edit permission. + if (!$checkedOut && $canDo->get('core.edit')) { - // Since it's an existing record, check the edit permission. - if ($canDo->get('core.edit')) + JToolbarHelper::apply('filter.apply'); + JToolbarHelper::save('filter.save'); + + // We can save this record, but check the create permission to see if we can return to make a new one. + if ($canDo->get('core.create')) { - JToolbarHelper::apply('filter.apply'); - JToolbarHelper::save('filter.save'); - - // We can save this record, but check the create permission to see if we can return to make a new one. - if ($canDo->get('core.create')) - { - JToolbarHelper::save2new('filter.save2new'); - } + JToolbarHelper::save2new('filter.save2new'); } } diff --git a/administrator/components/com_finder/views/filters/tmpl/default.php b/administrator/components/com_finder/views/filters/tmpl/default.php index a20978f774370..d2ad5555508bf 100644 --- a/administrator/components/com_finder/views/filters/tmpl/default.php +++ b/administrator/components/com_finder/views/filters/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -88,43 +88,47 @@ authorise('core.create', 'com_finder'); + $canEdit = $user->authorise('core.edit', 'com_finder'); + $userAuthoriseCoreManage = $user->authorise('core.manage', 'com_checkin'); + $userAuthoriseCoreEditState = $user->authorise('core.edit.state', 'com_finder'); + $userId = $user->get('id'); foreach ($this->items as $i => $item) : - $canCreate = $user->authorise('core.create', 'com_finder'); - $canEdit = $user->authorise('core.edit', 'com_finder'); - $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; - $canChange = $user->authorise('core.edit.state', 'com_finder') && $canCheckin; - ?> - - - filter_id); ?> - - - state, $i, 'filters.', $canChange); ?> - - - checked_out) : ?> - editor, $item->checked_out_time, 'filters.', $canCheckin); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - - - created_by_alias ? $item->created_by_alias : $item->user_name; ?> - - - created, JText::_('DATE_FORMAT_LC4')); ?> - - - map_count; ?> - - - filter_id; ?> - - + $canCheckIn = $userAuthoriseCoreManage || $item->checked_out == $userId || $item->checked_out == 0; + $canChange = $userAuthoriseCoreEditState && $canCheckIn; + $escapedTitle = $this->escape($item->title); + ?> + + + filter_id); ?> + + + state, $i, 'filters.', $canChange); ?> + + + checked_out) : ?> + editor, $item->checked_out_time, 'filters.', $canCheckIn); ?> + + + + + + + + + + created_by_alias ?: $item->user_name; ?> + + + created, JText::_('DATE_FORMAT_LC4')); ?> + + + map_count; ?> + + + filter_id; ?> + + diff --git a/administrator/components/com_finder/views/filters/view.html.php b/administrator/components/com_finder/views/filters/view.html.php index f65859ba4fd6b..4e8db872c2625 100644 --- a/administrator/components/com_finder/views/filters/view.html.php +++ b/administrator/components/com_finder/views/filters/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -20,6 +20,8 @@ class FinderViewFilters extends JViewLegacy * An array of items * * @var array + * + * @since 3.6.1 */ protected $items; @@ -27,6 +29,8 @@ class FinderViewFilters extends JViewLegacy * The pagination object * * @var JPagination + * + * @since 3.6.1 */ protected $pagination; @@ -34,20 +38,26 @@ class FinderViewFilters extends JViewLegacy * The HTML markup for the sidebar * * @var string + * + * @since 3.6.1 */ protected $sidebar; /** * The model state * - * @var object + * @var mixed + * + * @since 3.6.1 */ protected $state; /** * The total number of items * - * @var object + * @var integer + * + * @since 3.6.1 */ protected $total; diff --git a/administrator/components/com_finder/views/index/tmpl/default.php b/administrator/components/com_finder/views/index/tmpl/default.php index 7b2a066403c8a..263969f9a05c3 100644 --- a/administrator/components/com_finder/views/index/tmpl/default.php +++ b/administrator/components/com_finder/views/index/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -118,7 +118,7 @@ indexdate, JText::_('DATE_FORMAT_LC4')); ?> - publish_start_date) or intval($item->publish_end_date) or intval($item->start_date) or intval($item->end_date)) : ?> + publish_start_date || (int) $item->publish_end_date || (int) $item->start_date || (int) $item->end_date) : ?> publish_start_date, $item->publish_end_date, $item->start_date, $item->end_date); ?> diff --git a/administrator/components/com_finder/views/index/view.html.php b/administrator/components/com_finder/views/index/view.html.php index 880a696e19094..c3095ca3c968b 100644 --- a/administrator/components/com_finder/views/index/view.html.php +++ b/administrator/components/com_finder/views/index/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -22,6 +22,8 @@ class FinderViewIndex extends JViewLegacy * An array of items * * @var array + * + * @since 3.6.1 */ protected $items; @@ -29,6 +31,8 @@ class FinderViewIndex extends JViewLegacy * The pagination object * * @var JPagination + * + * @since 3.6.1 */ protected $pagination; @@ -36,6 +40,8 @@ class FinderViewIndex extends JViewLegacy * The state of core Smart Search plugins * * @var array + * + * @since 3.6.1 */ protected $pluginState; @@ -43,20 +49,26 @@ class FinderViewIndex extends JViewLegacy * The HTML markup for the sidebar * * @var string + * + * @since 3.6.1 */ protected $sidebar; /** * The model state * - * @var object + * @var mixed + * + * @since 3.6.1 */ protected $state; /** * The total number of items * - * @var object + * @var integer + * + * @since 3.6.1 */ protected $total; diff --git a/administrator/components/com_finder/views/indexer/tmpl/default.php b/administrator/components/com_finder/views/indexer/tmpl/default.php index 20ef8c7e2e994..f6dbe91ffcca1 100644 --- a/administrator/components/com_finder/views/indexer/tmpl/default.php +++ b/administrator/components/com_finder/views/indexer/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/views/indexer/view.html.php b/administrator/components/com_finder/views/indexer/view.html.php index fb12941060b7a..95a8f4dda5d2b 100644 --- a/administrator/components/com_finder/views/indexer/view.html.php +++ b/administrator/components/com_finder/views/indexer/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_finder/views/maps/tmpl/default.php b/administrator/components/com_finder/views/maps/tmpl/default.php index 5835f81048dae..904a132223930 100644 --- a/administrator/components/com_finder/views/maps/tmpl/default.php +++ b/administrator/components/com_finder/views/maps/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -99,7 +99,7 @@ parent_title, '**') == 'Language') + if (trim($item->parent_title, '**') === 'Language') { $title = FinderHelperLanguage::branchLanguageTitle($item->title); } @@ -115,7 +115,7 @@ - escape(trim($title, '**')) == 'Language' && JLanguageMultilang::isEnabled()) : ?> + escape(trim($title, '**')) === 'Language' && JLanguageMultilang::isEnabled()) : ?> diff --git a/administrator/components/com_finder/views/maps/view.html.php b/administrator/components/com_finder/views/maps/view.html.php index 9a5cdfe4495bc..53e1777a4b83e 100644 --- a/administrator/components/com_finder/views/maps/view.html.php +++ b/administrator/components/com_finder/views/maps/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -22,6 +22,8 @@ class FinderViewMaps extends JViewLegacy * An array of items * * @var array + * + * @since 3.6.1 */ protected $items; @@ -29,6 +31,8 @@ class FinderViewMaps extends JViewLegacy * The pagination object * * @var JPagination + * + * @since 3.6.1 */ protected $pagination; @@ -36,6 +40,8 @@ class FinderViewMaps extends JViewLegacy * The HTML markup for the sidebar * * @var string + * + * @since 3.6.1 */ protected $sidebar; @@ -43,6 +49,8 @@ class FinderViewMaps extends JViewLegacy * The model state * * @var object + * + * @since 3.6.1 */ protected $state; @@ -50,6 +58,8 @@ class FinderViewMaps extends JViewLegacy * The total number of items * * @var object + * + * @since 3.6.1 */ protected $total; diff --git a/administrator/components/com_finder/views/statistics/tmpl/default.php b/administrator/components/com_finder/views/statistics/tmpl/default.php index f5597fffa26fa..e97ed9af7b3d4 100644 --- a/administrator/components/com_finder/views/statistics/tmpl/default.php +++ b/administrator/components/com_finder/views/statistics/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -34,7 +34,7 @@ type_title); $lang_string = JText::_($lang_key); - echo ($lang_string == $lang_key) ? $type->type_title : $lang_string; + echo $lang_string === $lang_key ? $type->type_title : $lang_string; ?> diff --git a/administrator/components/com_finder/views/statistics/view.html.php b/administrator/components/com_finder/views/statistics/view.html.php index a938942bb7450..4abb2c0fa8e6a 100644 --- a/administrator/components/com_finder/views/statistics/view.html.php +++ b/administrator/components/com_finder/views/statistics/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_finder * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -20,6 +20,8 @@ class FinderViewStatistics extends JViewLegacy * The index statistics * * @var JObject + * + * @since 3.6.1 */ protected $data; diff --git a/administrator/components/com_installer/controller.php b/administrator/components/com_installer/controller.php index da48efd484fd4..6a5992829a210 100644 --- a/administrator/components/com_installer/controller.php +++ b/administrator/components/com_installer/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/controllers/database.php b/administrator/components/com_installer/controllers/database.php index bd549005d683e..16dd470d1ca9f 100644 --- a/administrator/components/com_installer/controllers/database.php +++ b/administrator/components/com_installer/controllers/database.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -26,6 +26,9 @@ class InstallerControllerDatabase extends JControllerLegacy */ public function fix() { + // Check for request forgeries. + $this->checkToken(); + $model = $this->getModel('database'); $model->fix(); diff --git a/administrator/components/com_installer/controllers/discover.php b/administrator/components/com_installer/controllers/discover.php index 2d2ca5473c4a5..410cd4c075aaf 100644 --- a/administrator/components/com_installer/controllers/discover.php +++ b/administrator/components/com_installer/controllers/discover.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -25,6 +25,8 @@ class InstallerControllerDiscover extends JControllerLegacy */ public function refresh() { + $this->checkToken(); + $model = $this->getModel('discover'); $model->discover(); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false)); @@ -39,6 +41,8 @@ public function refresh() */ public function install() { + $this->checkToken(); + $this->getModel('discover')->discover_install(); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false)); } @@ -52,6 +56,8 @@ public function install() */ public function purge() { + $this->checkToken(); + $model = $this->getModel('discover'); $model->purge(); $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false), $model->_message); diff --git a/administrator/components/com_installer/controllers/install.php b/administrator/components/com_installer/controllers/install.php index 8289990361a2e..b437c62d185ef 100644 --- a/administrator/components/com_installer/controllers/install.php +++ b/administrator/components/com_installer/controllers/install.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -26,7 +26,12 @@ class InstallerControllerInstall extends JControllerLegacy public function install() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); + + if (!JFactory::getUser()->authorise('core.admin')) + { + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } /** @var InstallerModelInstall $model */ $model = $this->getModel('install'); @@ -39,7 +44,7 @@ public function install() if (!$redirect_url) { - $redirect_url = base64_decode($app->input->get('return')); + $redirect_url = base64_decode($app->input->get('return', null, 'BASE64')); } // Don't redirect to an external URL. @@ -74,6 +79,14 @@ public function install() */ public function ajax_upload() { + // Check for request forgeries. + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + if (!JFactory::getUser()->authorise('core.admin')) + { + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } + $app = JFactory::getApplication(); $message = $app->getUserState('com_installer.message'); diff --git a/administrator/components/com_installer/controllers/manage.php b/administrator/components/com_installer/controllers/manage.php index e4f01a2ca237e..a230e356b5749 100644 --- a/administrator/components/com_installer/controllers/manage.php +++ b/administrator/components/com_installer/controllers/manage.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -44,7 +44,7 @@ public function __construct($config = array()) public function publish() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $ids = $this->input->get('cid', array(), 'array'); $values = array('publish' => 1, 'unpublish' => 0); @@ -94,7 +94,7 @@ public function publish() public function remove() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $eid = $this->input->get('cid', array(), 'array'); @@ -118,7 +118,7 @@ public function remove() public function refresh() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $uid = $this->input->get('cid', array(), 'array'); $model = $this->getModel('manage'); diff --git a/administrator/components/com_installer/controllers/update.php b/administrator/components/com_installer/controllers/update.php index c691e5c144de1..4f399d87a8d52 100644 --- a/administrator/components/com_installer/controllers/update.php +++ b/administrator/components/com_installer/controllers/update.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -28,7 +28,7 @@ class InstallerControllerUpdate extends JControllerLegacy public function update() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); /** @var InstallerModelUpdate $model */ $model = $this->getModel('update'); @@ -39,7 +39,7 @@ public function update() // Get the minimum stability. $component = JComponentHelper::getComponent('com_installer'); $params = $component->params; - $minimum_stability = $params->get('minimum_stability', JUpdater::STABILITY_STABLE, 'int'); + $minimum_stability = (int) $params->get('minimum_stability', JUpdater::STABILITY_STABLE); $model->update($uid, $minimum_stability); @@ -76,16 +76,16 @@ public function update() */ public function find() { - (JSession::checkToken() or JSession::checkToken('get')) or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken('request'); // Get the caching duration. $component = JComponentHelper::getComponent('com_installer'); $params = $component->params; - $cache_timeout = $params->get('cachetimeout', 6, 'int'); + $cache_timeout = (int) $params->get('cachetimeout', 6); $cache_timeout = 3600 * $cache_timeout; // Get the minimum stability. - $minimum_stability = $params->get('minimum_stability', JUpdater::STABILITY_STABLE, 'int'); + $minimum_stability = (int) $params->get('minimum_stability', JUpdater::STABILITY_STABLE); // Find updates. /** @var InstallerModelUpdate $model */ @@ -113,7 +113,7 @@ public function find() public function purge() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $model = $this->getModel('update'); $model->purge(); @@ -142,7 +142,7 @@ public function ajax() { $app->setHeader('status', 403, true); $app->sendHeaders(); - echo JText::_('JINVALID_TOKEN'); + echo JText::_('JINVALID_TOKEN_NOTICE'); $app->close(); } @@ -156,13 +156,13 @@ public function ajax() if ($cache_timeout == 0) { - $cache_timeout = $params->get('cachetimeout', 6, 'int'); + $cache_timeout = (int) $params->get('cachetimeout', 6); $cache_timeout = 3600 * $cache_timeout; } if ($minimum_stability < 0) { - $minimum_stability = $params->get('minimum_stability', JUpdater::STABILITY_STABLE, 'int'); + $minimum_stability = (int) $params->get('minimum_stability', JUpdater::STABILITY_STABLE); } /** @var InstallerModelUpdate $model */ diff --git a/administrator/components/com_installer/controllers/updatesites.php b/administrator/components/com_installer/controllers/updatesites.php index cb32710e6efac..ac7dc45f23d7c 100644 --- a/administrator/components/com_installer/controllers/updatesites.php +++ b/administrator/components/com_installer/controllers/updatesites.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2014 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -50,7 +50,7 @@ public function __construct($config = array()) public function publish() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $ids = $this->input->get('cid', array(), 'array'); $values = array('publish' => 1, 'unpublish' => 0); @@ -90,7 +90,7 @@ public function publish() public function delete() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $ids = $this->input->get('cid', array(), 'array'); @@ -115,7 +115,7 @@ public function delete() public function rebuild() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Rebuild the update sites. $this->getModel('Updatesites')->rebuild(); diff --git a/administrator/components/com_installer/helpers/html/manage.php b/administrator/components/com_installer/helpers/html/manage.php index 0ac6b08b7e35a..a48d4b91af5b9 100644 --- a/administrator/components/com_installer/helpers/html/manage.php +++ b/administrator/components/com_installer/helpers/html/manage.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/helpers/html/updatesites.php b/administrator/components/com_installer/helpers/html/updatesites.php index 93667774a9845..a06b8a3cf3e11 100644 --- a/administrator/components/com_installer/helpers/html/updatesites.php +++ b/administrator/components/com_installer/helpers/html/updatesites.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/helpers/installer.php b/administrator/components/com_installer/helpers/installer.php index 654c3757a9f3c..8fa13046700d3 100644 --- a/administrator/components/com_installer/helpers/installer.php +++ b/administrator/components/com_installer/helpers/installer.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -25,11 +25,14 @@ class InstallerHelper */ public static function addSubmenu($vName = 'install') { - JHtmlSidebar::addEntry( - JText::_('COM_INSTALLER_SUBMENU_INSTALL'), - 'index.php?option=com_installer', - $vName == 'install' - ); + if (JFactory::getUser()->authorise('core.admin')) + { + JHtmlSidebar::addEntry( + JText::_('COM_INSTALLER_SUBMENU_INSTALL'), + 'index.php?option=com_installer&view=install', + $vName == 'install' + ); + } JHtmlSidebar::addEntry( JText::_('COM_INSTALLER_SUBMENU_UPDATE'), 'index.php?option=com_installer&view=update', @@ -51,15 +54,20 @@ public static function addSubmenu($vName = 'install') $vName == 'database' ); JHtmlSidebar::addEntry( - JText::_('COM_INSTALLER_SUBMENU_WARNINGS'), + JText::_('COM_INSTALLER_SUBMENU_WARNINGS'), 'index.php?option=com_installer&view=warnings', $vName == 'warnings' ); - JHtmlSidebar::addEntry( - JText::_('COM_INSTALLER_SUBMENU_LANGUAGES'), - 'index.php?option=com_installer&view=languages', - $vName == 'languages' - ); + + if (JFactory::getUser()->authorise('core.admin')) + { + JHtmlSidebar::addEntry( + JText::_('COM_INSTALLER_SUBMENU_LANGUAGES'), + 'index.php?option=com_installer&view=languages', + $vName == 'languages' + ); + } + JHtmlSidebar::addEntry( JText::_('COM_INSTALLER_SUBMENU_UPDATESITES'), 'index.php?option=com_installer&view=updatesites', diff --git a/administrator/components/com_installer/installer.php b/administrator/components/com_installer/installer.php index 74e07d27a0157..a59d445a10764 100644 --- a/administrator/components/com_installer/installer.php +++ b/administrator/components/com_installer/installer.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/installer.xml b/administrator/components/com_installer/installer.xml index 8fb20c27e6fb4..e6edd2c45e08b 100644 --- a/administrator/components/com_installer/installer.xml +++ b/administrator/components/com_installer/installer.xml @@ -3,7 +3,7 @@ com_installer Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_installer/models/database.php b/administrator/components/com_installer/models/database.php index bd6a3e013498f..f7e1a2083decd 100644 --- a/administrator/components/com_installer/models/database.php +++ b/administrator/components/com_installer/models/database.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -70,7 +70,7 @@ public function fix() /* * Finally, if the schema updates succeeded, make sure the database is - * converted to utf8mb4 or, if not suported by the server, compatible to it. + * converted to utf8mb4 or, if not supported by the server, compatible to it. */ $statusArray = $changeSet->getStatus(); @@ -99,6 +99,7 @@ public function getItems() return false; } + return $changeSet; } @@ -107,7 +108,7 @@ public function getItems() * * @return boolean * - * @since 12.2 + * @since 3.0.1 */ public function getPagination() { @@ -286,7 +287,7 @@ private function prepareUtf8mb4StatusTable() } $creaTabSql = 'CREATE TABLE IF NOT EXISTS ' . $db->quoteName('#__utf8_conversion') - . ' (' . $db->quoteName('converted') . ' tinyint(4) NOT NULL DEFAULT 0' + . ' (' . $db->quoteName('converted') . ' tinyint NOT NULL DEFAULT 0' . ') ENGINE=InnoDB'; if ($db->hasUTF8mb4Support()) @@ -309,16 +310,18 @@ private function prepareUtf8mb4StatusTable() if ($count > 1) { // Table messed up somehow, clear it - $db->setQuery('DELETE FROM ' . $db->quoteName('#__utf8_conversion') - . ';')->execute(); + $db->setQuery('DELETE FROM ' . $db->quoteName('#__utf8_conversion') . ';') + ->execute(); $db->setQuery('INSERT INTO ' . $db->quoteName('#__utf8_conversion') - . ' (' . $db->quoteName('converted') . ') VALUES (0);')->execute(); + . ' (' . $db->quoteName('converted') . ') VALUES (0);' + )->execute(); } elseif ($count == 0) { // Record missing somehow, fix this $db->setQuery('INSERT INTO ' . $db->quoteName('#__utf8_conversion') - . ' (' . $db->quoteName('converted') . ') VALUES (0);')->execute(); + . ' (' . $db->quoteName('converted') . ') VALUES (0);' + )->execute(); } } } diff --git a/administrator/components/com_installer/models/discover.php b/administrator/components/com_installer/models/discover.php index 1403e816f4e93..9602625b78eb6 100644 --- a/administrator/components/com_installer/models/discover.php +++ b/administrator/components/com_installer/models/discover.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -228,7 +228,7 @@ public function discover_install() /** * Cleans out the list of discovered extensions. * - * @return bool True on success + * @return boolean True on success * * @since 1.6 */ diff --git a/administrator/components/com_installer/models/extension.php b/administrator/components/com_installer/models/extension.php index cdeaa1e63601b..01132b2e124f2 100644 --- a/administrator/components/com_installer/models/extension.php +++ b/administrator/components/com_installer/models/extension.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -92,6 +92,7 @@ protected function _getList($query, $limitstart = 0, $limit = 0) { // Check if search string exists in any of the fields to be searched. $found = 0; + foreach ($searchFields as $key => $field) { if (!$found && preg_match('/' . $escapedSearchString . '/i', $item->{$field})) @@ -109,20 +110,20 @@ protected function _getList($query, $limitstart = 0, $limit = 0) } // Process ordering. - // Sort array object by selected ordering and selected direction. Sort is case insensative and using locale sorting. + // Sort array object by selected ordering and selected direction. Sort is case insensitive and using locale sorting. $result = ArrayHelper::sortObjects($result, $listOrder, strtolower($listDirn) == 'desc' ? -1 : 1, false, true); // Process pagination. $total = count($result); $this->cache[$this->getStoreId('getTotal')] = $total; - if ($total < $limitstart) + if ($total <= $limitstart) { $limitstart = 0; - $this->setState('list.start', 0); + $this->setState('list.limitstart', 0); } - return array_slice($result, $limitstart, $limit ? $limit : null); + return array_slice($result, $limitstart, $limit ?: null); } // Process searching, ordering and pagination for regular database fields. @@ -136,7 +137,7 @@ protected function _getList($query, $limitstart = 0, $limit = 0) /** * Translate a list of objects * - * @param array &$items The array of objects + * @param array $items The array of objects * * @return array The array of translated objects */ @@ -181,8 +182,15 @@ protected function translate(&$items) $lang->load("$extension.sys", JPATH_SITE, null, false, true); break; case 'library': - $extension = 'lib_' . $item->element; - $lang->load("$extension.sys", JPATH_SITE, null, false, true); + $parts = explode('/', $item->element); + $vendor = (isset($parts[1]) ? $parts[0] : null); + $extension = 'lib_' . ($vendor ? implode('_', $parts) : $item->element); + + if (!$lang->load("$extension.sys", $path, null, false, true)) + { + $source = $path . '/libraries/' . ($vendor ? $vendor . '/' . $parts[1] : $item->element); + $lang->load("$extension.sys", $source, null, false, true); + } break; case 'module': $extension = $item->element; diff --git a/administrator/components/com_installer/models/fields/extensionstatus.php b/administrator/components/com_installer/models/fields/extensionstatus.php index ce8afbc5fc58c..402c9a88b4ac6 100644 --- a/administrator/components/com_installer/models/fields/extensionstatus.php +++ b/administrator/components/com_installer/models/fields/extensionstatus.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/models/fields/folder.php b/administrator/components/com_installer/models/fields/folder.php index 013423dd0ec35..9d248d5569958 100644 --- a/administrator/components/com_installer/models/fields/folder.php +++ b/administrator/components/com_installer/models/fields/folder.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/models/fields/location.php b/administrator/components/com_installer/models/fields/location.php index f5b7023b5b755..e40f7112758bb 100644 --- a/administrator/components/com_installer/models/fields/location.php +++ b/administrator/components/com_installer/models/fields/location.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/models/fields/type.php b/administrator/components/com_installer/models/fields/type.php index 5d0c28722963a..0eb80beef224b 100644 --- a/administrator/components/com_installer/models/fields/type.php +++ b/administrator/components/com_installer/models/fields/type.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -14,7 +14,7 @@ JFormHelper::loadFieldClass('list'); /** - * Type field. + * Form field for a list of extension types. * * @since 3.5 */ diff --git a/administrator/components/com_installer/models/forms/filter_discover.xml b/administrator/components/com_installer/models/forms/filter_discover.xml index b11e1f2dd4379..8ed813e457202 100644 --- a/administrator/components/com_installer/models/forms/filter_discover.xml +++ b/administrator/components/com_installer/models/forms/filter_discover.xml @@ -6,6 +6,7 @@ diff --git a/administrator/components/com_installer/models/forms/filter_languages.xml b/administrator/components/com_installer/models/forms/filter_languages.xml index bf4211730915a..28d4ef1c55615 100644 --- a/administrator/components/com_installer/models/forms/filter_languages.xml +++ b/administrator/components/com_installer/models/forms/filter_languages.xml @@ -4,6 +4,7 @@ diff --git a/administrator/components/com_installer/models/forms/filter_manage.xml b/administrator/components/com_installer/models/forms/filter_manage.xml index c6553e2e1b989..a0648a45b6cc9 100644 --- a/administrator/components/com_installer/models/forms/filter_manage.xml +++ b/administrator/components/com_installer/models/forms/filter_manage.xml @@ -6,6 +6,7 @@ diff --git a/administrator/components/com_installer/models/forms/filter_update.xml b/administrator/components/com_installer/models/forms/filter_update.xml index 27493b8e90ee4..75299870de653 100644 --- a/administrator/components/com_installer/models/forms/filter_update.xml +++ b/administrator/components/com_installer/models/forms/filter_update.xml @@ -6,6 +6,7 @@ diff --git a/administrator/components/com_installer/models/forms/filter_updatesites.xml b/administrator/components/com_installer/models/forms/filter_updatesites.xml index ec17aeec0647d..66fa00e61477a 100644 --- a/administrator/components/com_installer/models/forms/filter_updatesites.xml +++ b/administrator/components/com_installer/models/forms/filter_updatesites.xml @@ -6,6 +6,7 @@ diff --git a/administrator/components/com_installer/models/install.php b/administrator/components/com_installer/models/install.php index 539730ae91198..add5110f0e08a 100644 --- a/administrator/components/com_installer/models/install.php +++ b/administrator/components/com_installer/models/install.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -135,6 +135,14 @@ public function install() return false; } + // Check if package was uploaded successfully. + if (!\is_array($package)) + { + $app->enqueueMessage(JText::_('COM_INSTALLER_UNABLE_TO_FIND_INSTALL_PACKAGE'), 'error'); + + return false; + } + // Get an installer instance. $installer = JInstaller::getInstance(); @@ -145,7 +153,7 @@ public function install() * This must be done before the unpacked check because JInstallerHelper::detectType() returns a boolean false since the manifest * can't be found in the expected location. */ - if (is_array($package) && isset($package['dir']) && is_dir($package['dir'])) + if (isset($package['dir']) && is_dir($package['dir'])) { $installer->setPath('source', $package['dir']); @@ -171,14 +179,14 @@ public function install() } // Was the package unpacked? - if (!$package || !$package['type']) + if (empty($package['type'])) { if (in_array($installType, array('upload', 'url'))) { JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); } - $app->enqueueMessage(JText::_('COM_INSTALLER_UNABLE_TO_FIND_INSTALL_PACKAGE'), 'error'); + $app->enqueueMessage(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST'), 'error'); return false; } @@ -377,6 +385,16 @@ protected function _getPackageFromUrl() return false; } + // We only allow http & https here + $uri = new JUri($url); + + if (!in_array($uri->getScheme(), array('http', 'https'))) + { + JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_INVALID_URL_SCHEME')); + + return false; + } + // Handle updater XML file case: if (preg_match('/\.xml\s*$/', $url)) { diff --git a/administrator/components/com_installer/models/languages.php b/administrator/components/com_installer/models/languages.php index 5c742dd97b3e0..7221547038e07 100644 --- a/administrator/components/com_installer/models/languages.php +++ b/administrator/components/com_installer/models/languages.php @@ -2,7 +2,7 @@ /** * @package Joomla.Administrator * @subpackage com_installer - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -113,6 +113,14 @@ protected function getLanguages() { $updateSite = $this->getUpdateSite(); + // Check whether the updateserver is found + if (empty($updateSite)) + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNING_NO_LANGUAGES_UPDATESERVER'), 'warning'); + + return; + } + $http = new JHttp; try @@ -126,7 +134,7 @@ protected function getLanguages() if ($response === null || $response->code !== 200) { - JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNING_NO_LANGUAGES_UPDATESERVER'), 'warning'); + JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_INSTALLER_MSG_ERROR_CANT_CONNECT_TO_UPDATESERVER', $updateSite), 'error'); return; } @@ -141,7 +149,7 @@ protected function getLanguages() foreach ($extension->attributes() as $key => $value) { - $language->$key = (string) $value; + $language->$key = (string) $value; } if ($search) diff --git a/administrator/components/com_installer/models/manage.php b/administrator/components/com_installer/models/manage.php index f6f6f492ecd3a..3dc4529704db3 100644 --- a/administrator/components/com_installer/models/manage.php +++ b/administrator/components/com_installer/models/manage.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -79,7 +79,7 @@ protected function populateState($ordering = 'name', $direction = 'asc') /** * Enable/Disable an extension. * - * @param array &$eid Extension ids to un/publish + * @param array $eid Extension ids to un/publish * @param int $value Publish value * * @return boolean True on success @@ -138,6 +138,10 @@ public function publish(&$eid = array(), $value = 1) { $table->enabled = $value; } + + $context = $this->option . '.' . $this->name; + JPluginHelper::importPlugin('extension'); + JEventDispatcher::getInstance()->trigger('onExtensionChangeState', array($context, $eid, $value)); if (!$table->store()) { diff --git a/administrator/components/com_installer/models/update.php b/administrator/components/com_installer/models/update.php index 15e5113b61126..443682e8b4b90 100644 --- a/administrator/components/com_installer/models/update.php +++ b/administrator/components/com_installer/models/update.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -12,6 +12,7 @@ jimport('joomla.updater.update'); use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Installer\InstallerHelper; /** * Installer Update Model @@ -154,7 +155,7 @@ protected function getListQuery() /** * Translate a list of objects * - * @param array &$items The array of objects + * @param array $items The array of objects * * @return array The array of translated objects * @@ -168,7 +169,7 @@ protected function translate(&$items) $manifest = json_decode($item->manifest_cache); $item->current_version = isset($manifest->version) ? $manifest->version : JText::_('JLIB_UNKNOWN'); $item->type_translated = JText::_('COM_INSTALLER_TYPE_' . strtoupper($item->type)); - $item->folder_translated = $item->folder ? $item->folder : JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); + $item->folder_translated = $item->folder ?: JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); $item->install_type = $item->extension_id ? JText::_('COM_INSTALLER_MSG_UPDATE_UPDATE') : JText::_('COM_INSTALLER_NEW_INSTALL'); } @@ -207,7 +208,7 @@ protected function _getList($query, $limitstart = 0, $limit = 0) $this->setState('list.start', 0); } - return array_slice($result, $limitstart, $limit ? $limit : null); + return array_slice($result, $limitstart, $limit ?: null); } else { @@ -244,20 +245,17 @@ public function getDisabledUpdateSites() /** * Finds updates for an extension. * - * @param int $eid Extension identifier to look for - * @param int $cache_timeout Cache timout - * @param int $minimum_stability Minimum stability for updates {@see JUpdater} (0=dev, 1=alpha, 2=beta, 3=rc, 4=stable) + * @param int $eid Extension identifier to look for + * @param int $cacheTimeout Cache timeout + * @param int $minimumStability Minimum stability for updates {@see JUpdater} (0=dev, 1=alpha, 2=beta, 3=rc, 4=stable) * * @return boolean Result * * @since 1.6 */ - public function findUpdates($eid = 0, $cache_timeout = 0, $minimum_stability = JUpdater::STABILITY_STABLE) + public function findUpdates($eid = 0, $cacheTimeout = 0, $minimumStability = JUpdater::STABILITY_STABLE) { - // Purge the updates list - $this->purge(); - - JUpdater::getInstance()->findUpdates($eid, $cache_timeout, $minimum_stability); + JUpdater::getInstance()->findUpdates($eid, $cacheTimeout, $minimumStability); return true; } @@ -294,6 +292,10 @@ public function purge() ->set($db->quoteName('last_check_timestamp') . ' = ' . $db->quote(0)); $db->setQuery($query); $db->execute(); + + // Clear the administrator cache + $this->cleanCache('_system', 1); + $this->_message = JText::_('JLIB_INSTALLER_PURGED_UPDATES'); return true; @@ -339,14 +341,14 @@ public function enableSites() * * Sets the "result" state with the result of the operation. * - * @param array $uids Array[int] List of updates to apply - * @param int $minimum_stability The minimum allowed stability for installed updates {@see JUpdater} + * @param array $uids Array[int] List of updates to apply + * @param int $minimumStability The minimum allowed stability for installed updates {@see JUpdater} * * @return void * * @since 1.6 */ - public function update($uids, $minimum_stability = JUpdater::STABILITY_STABLE) + public function update($uids, $minimumStability = JUpdater::STABILITY_STABLE) { $result = true; @@ -355,8 +357,16 @@ public function update($uids, $minimum_stability = JUpdater::STABILITY_STABLE) $update = new JUpdate; $instance = JTable::getInstance('update'); $instance->load($uid); - $update->loadFromXml($instance->detailsurl, $minimum_stability); - $update->set('extra_query', $instance->extra_query); + $update->loadFromXml($instance->detailsurl, $minimumStability); + + // Find and use extra_query from update_site if available + $updateSiteInstance = JTable::getInstance('Updatesite'); + $updateSiteInstance->load($instance->update_site_id); + + if ($updateSiteInstance->extra_query) + { + $update->set('extra_query', $updateSiteInstance->extra_query); + } $this->preparePreUpdate($update, $instance); @@ -405,7 +415,8 @@ private function install($update) return false; } - $url = $update->downloadurl->_data; + $url = trim($update->downloadurl->_data); + $sources = $update->get('downloadSources', array()); if ($extra_query = $update->get('extra_query')) { @@ -413,7 +424,21 @@ private function install($update) $url .= $extra_query; } - $p_file = JInstallerHelper::downloadPackage($url); + $mirror = 0; + + while (!($p_file = InstallerHelper::downloadPackage($url)) && isset($sources[$mirror])) + { + $name = $sources[$mirror]; + $url = trim($name->url); + + if ($extra_query) + { + $url .= (strpos($url, '?') === false) ? '?' : '&'; + $url .= $extra_query; + } + + $mirror++; + } // Was the package downloaded? if (!$p_file) @@ -427,32 +452,54 @@ private function install($update) $tmp_dest = $config->get('tmp_path'); // Unpack the downloaded package file - $package = JInstallerHelper::unpack($tmp_dest . '/' . $p_file); + $package = InstallerHelper::unpack($tmp_dest . '/' . $p_file); + + if (empty($package)) + { + $app->enqueueMessage(JText::sprintf('COM_INSTALLER_UNPACK_ERROR', $p_file), 'error'); + + return false; + } // Get an installer instance $installer = JInstaller::getInstance(); $update->set('type', $package['type']); + // Check the package + $check = InstallerHelper::isChecksumValid($package['packagefile'], $update); + + // The validation was not successful. Just a warning for now. + // TODO: In Joomla 4 this will abort the installation + if ($check === InstallerHelper::HASH_NOT_VALIDATED) + { + $app->enqueueMessage(JText::_('COM_INSTALLER_INSTALL_CHECKSUM_WRONG'), 'error'); + } + // Install the package if (!$installer->update($package['dir'])) { // There was an error updating the package - $msg = JText::sprintf('COM_INSTALLER_MSG_UPDATE_ERROR', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); + $app->enqueueMessage( + JText::sprintf('COM_INSTALLER_MSG_UPDATE_ERROR', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type'])) + ), 'error' + ); $result = false; } else { // Package updated successfully - $msg = JText::sprintf('COM_INSTALLER_MSG_UPDATE_SUCCESS', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); + $app->enqueueMessage( + JText::sprintf('COM_INSTALLER_MSG_UPDATE_SUCCESS', + JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type'])) + ) + ); $result = true; } // Quick change $this->type = $package['type']; - // Set some model state values - $app->enqueueMessage($msg); - // TODO: Reconfigure this code when you have more battery life left $this->setState('name', $installer->get('name')); $this->setState('result', $result); @@ -466,7 +513,7 @@ private function install($update) $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; } - JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); return $result; } @@ -495,6 +542,7 @@ public function getForm($data = array(), $loadData = true) return false; } + // Check the session for previously entered form data. $data = $this->loadFormData(); diff --git a/administrator/components/com_installer/models/updatesites.php b/administrator/components/com_installer/models/updatesites.php index 2ac0445b33b5a..1ae54cf8868a7 100644 --- a/administrator/components/com_installer/models/updatesites.php +++ b/administrator/components/com_installer/models/updatesites.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2014 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -73,7 +73,7 @@ protected function populateState($ordering = 'name', $direction = 'asc') /** * Enable/Disable an extension. * - * @param array &$eid Extension ids to un/publish + * @param array $eid Extension ids to un/publish * @param int $value Publish value * * @return boolean True on success @@ -275,6 +275,13 @@ public function rebuild() // Gets Joomla core update sites Ids. $joomlaUpdateSitesIds = implode(', ', $this->getJoomlaUpdateSitesIds(0)); + // First backup any custom extra_query for the sites + $query = $db->getQuery(true) + ->select('TRIM(' . $db->quoteName('location') . ') AS ' . $db->quoteName('location') . ', ' . $db->quoteName('extra_query')) + ->from($db->quoteName('#__update_sites')); + $db->setQuery($query); + $backupExtraQuerys = $db->loadAssocList('location'); + // Delete from all tables (except joomla core update sites). $query = $db->getQuery(true) ->delete($db->quoteName('#__update_sites')) @@ -324,11 +331,14 @@ public function rebuild() if (!is_null($manifest)) { - // Search if the extension exists in the extensions table. Excluding joomla core extensions (id < 10000) and discovered extensions. + // Search if the extension exists in the extensions table. Excluding joomla core extensions and discovered but not yet installed extensions. $query = $db->getQuery(true) ->select($db->quoteName('extension_id')) ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('name') . ' = ' . $db->quote($manifest->name)) + ->where('(' + . $db->quoteName('name') . ' = ' . $db->quote($manifest->name) + . ' OR ' . $db->quoteName('name') . ' = ' . $db->quote($manifest->packagename) + . ')' ) ->where($db->quoteName('type') . ' = ' . $db->quote($manifest['type'])) ->where($db->quoteName('extension_id') . ' NOT IN (' . $joomlaCoreExtensionIds . ')') ->where($db->quoteName('state') . ' != -1'); @@ -342,6 +352,16 @@ public function rebuild() $tmpInstaller->manifest = $manifest; $tmpInstaller->setPath('manifest', $file); + // Remove last extra_query as we are in a foreach + $tmpInstaller->extraQuery = ''; + + if ($tmpInstaller->manifest->updateservers + && $tmpInstaller->manifest->updateservers->server + && isset($backupExtraQuerys[trim((string) $tmpInstaller->manifest->updateservers->server)])) + { + $tmpInstaller->extraQuery = $backupExtraQuerys[trim((string) $tmpInstaller->manifest->updateservers->server)]['extra_query']; + } + // Load the extension plugin (if not loaded yet). JPluginHelper::importPlugin('extension', 'joomla'); @@ -363,6 +383,9 @@ public function rebuild() { $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_MESSAGE'), 'message'); } + + // Flush the system cache to ensure extra_query is correctly loaded next time. + $this->cleanCache('_system', 1); } /** @@ -388,8 +411,9 @@ protected function getJoomlaUpdateSitesIds($column = 0) . '(' . $db->qn('e.type') . ' = ' . $db->quote('file') . ' AND ' . $db->qn('e.element') . ' = ' . $db->quote('joomla') . ')' . ' OR (' . $db->qn('e.type') . ' = ' . $db->quote('package') . ' AND ' . $db->qn('e.element') . ' = ' . $db->quote('pkg_en-GB') . ')' . ' OR (' . $db->qn('e.type') . ' = ' . $db->quote('component') . ' AND ' . $db->qn('e.element') . ' = ' . $db->quote('com_joomlaupdate') . ')' - . ')'); - + . ')' + ); + $db->setQuery($query); return $db->loadColumn($column); @@ -412,6 +436,7 @@ protected function getListQuery() 's.type AS update_site_type', 's.location', 's.enabled', + 's.extra_query', 'e.extension_id', 'e.name', 'e.type', diff --git a/administrator/components/com_installer/models/warnings.php b/administrator/components/com_installer/models/warnings.php index d3427ae6ceb7a..f2d16dd3030c8 100644 --- a/administrator/components/com_installer/models/warnings.php +++ b/administrator/components/com_installer/models/warnings.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/database/tmpl/default.php b/administrator/components/com_installer/views/database/tmpl/default.php index e16680737ec15..d8eb5b0651042 100644 --- a/administrator/components/com_installer/views/database/tmpl/default.php +++ b/administrator/components/com_installer/views/database/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -44,9 +44,9 @@ queryType; $msgs = $error->msgElements; $file = basename($error->file); - $msg0 = (isset($msgs[0])) ? $msgs[0] : ' '; - $msg1 = (isset($msgs[1])) ? $msgs[1] : ' '; - $msg2 = (isset($msgs[2])) ? $msgs[2] : ' '; + $msg0 = isset($msgs[0]) ? $msgs[0] : ' '; + $msg1 = isset($msgs[1]) ? $msgs[1] : ' '; + $msg2 = isset($msgs[2]) ? $msgs[2] : ' '; $message = JText::sprintf($key, $file, $msg0, $msg1, $msg2); ?>
  • diff --git a/administrator/components/com_installer/views/database/view.html.php b/administrator/components/com_installer/views/database/view.html.php index d51d79eb0a660..30d1aa6840779 100644 --- a/administrator/components/com_installer/views/database/view.html.php +++ b/administrator/components/com_installer/views/database/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -40,8 +40,8 @@ public function display($tpl = null) $this->schemaVersion = $this->get('SchemaVersion'); $this->updateVersion = $this->get('UpdateVersion'); $this->filterParams = $this->get('DefaultTextFilters'); - $this->schemaVersion = ($this->schemaVersion) ? $this->schemaVersion : JText::_('JNONE'); - $this->updateVersion = ($this->updateVersion) ? $this->updateVersion : JText::_('JNONE'); + $this->schemaVersion = $this->schemaVersion ?: JText::_('JNONE'); + $this->updateVersion = $this->updateVersion ?: JText::_('JNONE'); $this->pagination = $this->get('Pagination'); $this->errorCount = count($this->errors); diff --git a/administrator/components/com_installer/views/default/tmpl/default_ftp.php b/administrator/components/com_installer/views/default/tmpl/default_ftp.php index d493627a810fe..a6e5dfa3cef60 100644 --- a/administrator/components/com_installer/views/default/tmpl/default_ftp.php +++ b/administrator/components/com_installer/views/default/tmpl/default_ftp.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/default/tmpl/default_message.php b/administrator/components/com_installer/views/default/tmpl/default_message.php index 7a3d9aa04c45a..552c6fe4f0920 100644 --- a/administrator/components/com_installer/views/default/tmpl/default_message.php +++ b/administrator/components/com_installer/views/default/tmpl/default_message.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/default/view.php b/administrator/components/com_installer/views/default/view.php index 07f98082d83ba..aedc72210b405 100644 --- a/administrator/components/com_installer/views/default/view.php +++ b/administrator/components/com_installer/views/default/view.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/discover/tmpl/default.php b/administrator/components/com_installer/views/discover/tmpl/default.php index d2918e86ce134..35a4b9888ad80 100644 --- a/administrator/components/com_installer/views/discover/tmpl/default.php +++ b/administrator/components/com_installer/views/discover/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/discover/tmpl/default_item.php b/administrator/components/com_installer/views/discover/tmpl/default_item.php index 89104377d76e9..59f0ab1e5b93b 100644 --- a/administrator/components/com_installer/views/discover/tmpl/default_item.php +++ b/administrator/components/com_installer/views/discover/tmpl/default_item.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/discover/view.html.php b/administrator/components/com_installer/views/discover/view.html.php index 2ce9baabd6a78..877936dd9eeb2 100644 --- a/administrator/components/com_installer/views/discover/view.html.php +++ b/administrator/components/com_installer/views/discover/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/install/tmpl/default.php b/administrator/components/com_installer/views/install/tmpl/default.php index 69787c48ce18a..b3d4fe178f361 100644 --- a/administrator/components/com_installer/views/install/tmpl/default.php +++ b/administrator/components/com_installer/views/install/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -116,7 +116,7 @@ ' . str_replace('"', '"', JText::_('COM_INSTALLER_SHOW_JED_INFORMATION_TOOLTIP')) . '', 'class="alert-options hasTooltip icon-options" data-dismiss="alert" title="' . str_replace('"', '"', JText::_('COM_INSTALLER_SHOW_JED_INFORMATION_TOOLTIP')) . '"' ); ?> diff --git a/administrator/components/com_installer/views/install/view.html.php b/administrator/components/com_installer/views/install/view.html.php index 6e2c0b06862bd..3066086139d30 100644 --- a/administrator/components/com_installer/views/install/view.html.php +++ b/administrator/components/com_installer/views/install/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -29,6 +29,11 @@ class InstallerViewInstall extends InstallerViewDefault */ public function display($tpl = null) { + if (!JFactory::getUser()->authorise('core.admin')) + { + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } + $paths = new stdClass; $paths->first = ''; $state = $this->get('state'); diff --git a/administrator/components/com_installer/views/languages/tmpl/default.php b/administrator/components/com_installer/views/languages/tmpl/default.php index 4a92616ee53a2..9cd96767b2c31 100644 --- a/administrator/components/com_installer/views/languages/tmpl/default.php +++ b/administrator/components/com_installer/views/languages/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -80,8 +80,9 @@ code; ?> + - version, 0, 3) != $version::RELEASE || substr($language->version, 0, 5) != $currentShortVersion) : ?> + version, $minorVersion) !== 0 || strpos($language->version, $currentShortVersion) !== 0) : ?> version; ?> version; ?> diff --git a/administrator/components/com_installer/views/languages/view.html.php b/administrator/components/com_installer/views/languages/view.html.php index 36ab4bb8e9e0a..e73722d243ece 100644 --- a/administrator/components/com_installer/views/languages/view.html.php +++ b/administrator/components/com_installer/views/languages/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -42,6 +42,11 @@ class InstallerViewLanguages extends InstallerViewDefault */ public function display($tpl = null) { + if (!JFactory::getUser()->authorise('core.admin')) + { + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); + } + // Get data from the model. $this->state = $this->get('State'); $this->items = $this->get('Items'); diff --git a/administrator/components/com_installer/views/manage/tmpl/default.php b/administrator/components/com_installer/views/manage/tmpl/default.php index ccc6bff0c7c25..b88989c488286 100644 --- a/administrator/components/com_installer/views/manage/tmpl/default.php +++ b/administrator/components/com_installer/views/manage/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/manage/view.html.php b/administrator/components/com_installer/views/manage/view.html.php index b8891f18d7c32..341e0f93e746a 100644 --- a/administrator/components/com_installer/views/manage/view.html.php +++ b/administrator/components/com_installer/views/manage/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/update/tmpl/default.php b/administrator/components/com_installer/views/update/tmpl/default.php index 7d470a2154ccc..ea1e271d8164c 100644 --- a/administrator/components/com_installer/views/update/tmpl/default.php +++ b/administrator/components/com_installer/views/update/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -93,7 +93,7 @@ diff --git a/administrator/components/com_installer/views/update/view.html.php b/administrator/components/com_installer/views/update/view.html.php index 09f0e58de07e3..6d0cfaabef1f3 100644 --- a/administrator/components/com_installer/views/update/view.html.php +++ b/administrator/components/com_installer/views/update/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -64,7 +64,7 @@ public function display($tpl = null) if (count($this->items) > 0) { - JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNINGS_UPDATE_NOTICE'), 'notice'); + JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNINGS_UPDATE_NOTICE'), 'warning'); } parent::display($tpl); diff --git a/administrator/components/com_installer/views/updatesites/tmpl/default.php b/administrator/components/com_installer/views/updatesites/tmpl/default.php index 5f54c2a268805..76298613473d6 100644 --- a/administrator/components/com_installer/views/updatesites/tmpl/default.php +++ b/administrator/components/com_installer/views/updatesites/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2014 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -88,6 +88,9 @@
    escape($item->location); ?> + extra_query): ?> +
    extra_query; ?>
    +
    diff --git a/administrator/components/com_installer/views/updatesites/view.html.php b/administrator/components/com_installer/views/updatesites/view.html.php index 75f957ec11cc6..91c2928ca828a 100644 --- a/administrator/components/com_installer/views/updatesites/view.html.php +++ b/administrator/components/com_installer/views/updatesites/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2014 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/warnings/tmpl/default.php b/administrator/components/com_installer/views/warnings/tmpl/default.php index 45b6d5d2847ae..dad235adba2ba 100644 --- a/administrator/components/com_installer/views/warnings/tmpl/default.php +++ b/administrator/components/com_installer/views/warnings/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_installer/views/warnings/view.html.php b/administrator/components/com_installer/views/warnings/view.html.php index 1b9a8dcc8ed52..c90f945fcd1ad 100644 --- a/administrator/components/com_installer/views/warnings/view.html.php +++ b/administrator/components/com_installer/views/warnings/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_installer * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_joomlaupdate/access.xml b/administrator/components/com_joomlaupdate/access.xml deleted file mode 100644 index c8c9f3dd739df..0000000000000 --- a/administrator/components/com_joomlaupdate/access.xml +++ /dev/null @@ -1,10 +0,0 @@ - - -
    - - - - - -
    -
    diff --git a/administrator/components/com_joomlaupdate/config.xml b/administrator/components/com_joomlaupdate/config.xml index 0253763b333d3..d4b814bcba382 100644 --- a/administrator/components/com_joomlaupdate/config.xml +++ b/administrator/components/com_joomlaupdate/config.xml @@ -22,6 +22,21 @@
    + + + + + + + +
    - -
    - - - -
    diff --git a/administrator/components/com_joomlaupdate/controller.php b/administrator/components/com_joomlaupdate/controller.php index 28748ee9b1f0e..e12927d9cf9fb 100644 --- a/administrator/components/com_joomlaupdate/controller.php +++ b/administrator/components/com_joomlaupdate/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_joomlaupdate/controllers/update.php b/administrator/components/com_joomlaupdate/controllers/update.php index 9330ad6dd7ee2..247f22dd659b5 100644 --- a/administrator/components/com_joomlaupdate/controllers/update.php +++ b/administrator/components/com_joomlaupdate/controllers/update.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -25,7 +25,7 @@ class JoomlaupdateControllerUpdate extends JControllerLegacy */ public function download() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'joomla_update.php'; @@ -44,12 +44,29 @@ public function download() $this->_applyCredentials(); /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('Default'); - $file = $model->download(); - - $message = null; + $model = $this->getModel('Default'); + $result = $model->download(); + $file = $result['basename']; + $message = null; $messageType = null; + // The validation was not successful for now just a warning. + // TODO: In Joomla 4 this will abort the installation + if ($result['check'] === false) + { + $message = JText::_('COM_JOOMLAUPDATE_VIEW_UPDATE_CHECKSUM_WRONG'); + $messageType = 'warning'; + + try + { + JLog::add($message, JLog::INFO, 'Update'); + } + catch (RuntimeException $exception) + { + // Informational log only + } + } + if ($file) { JFactory::getApplication()->setUserState('com_joomlaupdate.file', $file); @@ -84,7 +101,8 @@ public function download() */ public function install() { - JSession::checkToken('get') or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken('get'); + JFactory::getApplication()->setUserState('com_joomlaupdate.oldversion', JVERSION); $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'joomla_update.php'; @@ -217,7 +235,7 @@ public function cleanup() public function purge() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Purge updates /** @var JoomlaupdateModelDefault $model */ @@ -238,7 +256,7 @@ public function purge() public function upload() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? JFactory::getUser()->authorise('core.admin') or jexit(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); @@ -256,6 +274,8 @@ public function upload() { $url = 'index.php?option=com_joomlaupdate'; $this->setRedirect($url, $e->getMessage(), 'error'); + + return; } $token = JSession::getFormToken(); @@ -273,7 +293,7 @@ public function upload() public function captive() { // Check for request forgeries - JSession::checkToken('get') or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken('get'); // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? if (!JFactory::getUser()->authorise('core.admin')) @@ -307,7 +327,7 @@ public function captive() public function confirm() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? if (!JFactory::getUser()->authorise('core.admin')) @@ -421,7 +441,7 @@ protected function _applyCredentials() // Add credentials to the session if (!JClientHelper::setCredentials('ftp', $user, $pass)) { - JError::raiseWarning('SOME_ERROR_CODE', JText::_('JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED')); + JError::raiseWarning(500, JText::_('JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED')); } } } @@ -437,7 +457,7 @@ protected function _applyCredentials() public function finaliseconfirm() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Did a non Super User try do this? if (!JFactory::getUser()->authorise('core.admin')) @@ -470,4 +490,117 @@ public function finaliseconfirm() // Redirect back to the actual finalise page $this->setRedirect('index.php?option=com_joomlaupdate&task=update.finalise&' . JFactory::getSession()->getFormToken() . '=1'); } + + /** + * Fetch Extension update XML proxy. Used to prevent Access-Control-Allow-Origin errors. + * Prints a JSON string. + * Called from JS. + * + * @since 3.10.0 + * + * @return void + */ + public function fetchExtensionCompatibility() + { + $extensionID = $this->input->get('extension-id', '', 'DEFAULT'); + $joomlaTargetVersion = $this->input->get('joomla-target-version', '', 'DEFAULT'); + $joomlaCurrentVersion = $this->input->get('joomla-current-version', '', JVERSION); + $extensionVersion = $this->input->get('extension-version', '', 'DEFAULT'); + + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('default'); + $upgradeCompatibilityStatus = $model->fetchCompatibility($extensionID, $joomlaTargetVersion); + $currentCompatibilityStatus = $model->fetchCompatibility($extensionID, $joomlaCurrentVersion); + $upgradeUpdateVersion = false; + $currentUpdateVersion = false; + + $upgradeWarning = 0; + + if ($upgradeCompatibilityStatus->state == 1 && !empty($upgradeCompatibilityStatus->compatibleVersions)) + { + $upgradeUpdateVersion = end($upgradeCompatibilityStatus->compatibleVersions); + } + + if ($currentCompatibilityStatus->state == 1 && !empty($currentCompatibilityStatus->compatibleVersions)) + { + $currentUpdateVersion = end($currentCompatibilityStatus->compatibleVersions); + } + + if ($upgradeUpdateVersion !== false) + { + $upgradeOldestVersion = $upgradeCompatibilityStatus->compatibleVersions[0]; + + if ($currentUpdateVersion !== false) + { + // If there are updates compatible with both CMS versions use these + $bothCompatibleVersions = array_values( + array_intersect($upgradeCompatibilityStatus->compatibleVersions, $currentCompatibilityStatus->compatibleVersions) + ); + + if (!empty($bothCompatibleVersions)) + { + $upgradeOldestVersion = $bothCompatibleVersions[0]; + $upgradeUpdateVersion = end($bothCompatibleVersions); + } + } + + if (version_compare($upgradeOldestVersion, $extensionVersion, '>')) + { + // Installed version is empty or older than the oldest compatible update: Update required + $resultGroup = 2; + } + else + { + // Current version is compatible + $resultGroup = 3; + } + + if ($currentUpdateVersion !== false && version_compare($upgradeUpdateVersion, $currentUpdateVersion, '<')) + { + // Special case warning when version compatible with target is lower than current + $upgradeWarning = 2; + } + } + elseif ($currentUpdateVersion !== false) + { + // No compatible version for target version but there is a compatible version for current version + $resultGroup = 1; + } + else + { + // No update server available + $resultGroup = 1; + } + + // Do we need to capture + $combinedCompatibilityStatus = array( + 'upgradeCompatibilityStatus' => (object) array( + 'state' => $upgradeCompatibilityStatus->state, + 'compatibleVersion' => $upgradeUpdateVersion + ), + 'currentCompatibilityStatus' => (object) array( + 'state' => $currentCompatibilityStatus->state, + 'compatibleVersion' => $currentUpdateVersion + ), + 'resultGroup' => $resultGroup, + 'upgradeWarning' => $upgradeWarning, + ); + + $this->app = JFactory::getApplication(); + $this->app->mimeType = 'application/json'; + $this->app->charSet = 'utf-8'; + $this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet); + $this->app->sendHeaders(); + + try + { + echo new JResponseJson($combinedCompatibilityStatus); + } + catch (Exception $e) + { + echo $e; + } + + $this->app->close(); + } } diff --git a/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php b/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php index 1cb10fd75679c..993d6456d1217 100644 --- a/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php +++ b/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_joomlaupdate/helpers/select.php b/administrator/components/com_joomlaupdate/helpers/select.php index d23f68281af6f..82afcb068c405 100644 --- a/administrator/components/com_joomlaupdate/helpers/select.php +++ b/administrator/components/com_joomlaupdate/helpers/select.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_joomlaupdate/joomlaupdate.php b/administrator/components/com_joomlaupdate/joomlaupdate.php index 51371547a32ce..a2a215a00b032 100644 --- a/administrator/components/com_joomlaupdate/joomlaupdate.php +++ b/administrator/components/com_joomlaupdate/joomlaupdate.php @@ -3,13 +3,13 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -if (!JFactory::getUser()->authorise('core.manage', 'com_joomlaupdate')) +if (!JFactory::getUser()->authorise('core.admin')) { throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); } diff --git a/administrator/components/com_joomlaupdate/joomlaupdate.xml b/administrator/components/com_joomlaupdate/joomlaupdate.xml index 0376ba843a86f..71c11701e7f96 100644 --- a/administrator/components/com_joomlaupdate/joomlaupdate.xml +++ b/administrator/components/com_joomlaupdate/joomlaupdate.xml @@ -3,11 +3,11 @@ com_joomlaupdate Joomla! Project February 2012 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2012 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org - 3.6.2 + 3.10.1 COM_JOOMLAUPDATE_XML_DESCRIPTION js @@ -15,7 +15,6 @@ com_joomlaupdate - access.xml config.xml controller.php joomlaupdate.php diff --git a/administrator/components/com_joomlaupdate/models/default.php b/administrator/components/com_joomlaupdate/models/default.php index ba19761a61b1c..1c3b0293e5745 100644 --- a/administrator/components/com_joomlaupdate/models/default.php +++ b/administrator/components/com_joomlaupdate/models/default.php @@ -3,12 +3,17 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\CMS\Extension\ExtensionHelper; +use Joomla\CMS\Filter\InputFilter; +use Joomla\CMS\Http\HttpFactory; +use Joomla\Registry\Registry; + jimport('joomla.filesystem.folder'); jimport('joomla.filesystem.file'); @@ -19,6 +24,14 @@ */ class JoomlaupdateModelDefault extends JModelLegacy { + /** + * @var array $updateInformation null + * Holds the update information evaluated in getUpdateInformation. + * + * @since 3.10.0 + */ + private $updateInformation = null; + /** * Detects if the Joomla! update site currently in use matches the one * configured in this component. If they don't match, it changes it. @@ -35,7 +48,6 @@ public function applyUpdateSite() switch ($params->get('updatesource', 'nochange')) { // "Minor & Patch Release for Current version AND Next Major Release". - case 'sts': case 'next': $updateURL = 'https://update.joomla.org/core/sts/list_sts.xml'; break; @@ -63,6 +75,7 @@ public function applyUpdateSite() * The commented "case" below are for documenting where 'default' and legacy options falls * case 'default': * case 'lts': + * case 'sts': (It's shown as "Default" because that option does not exist any more) * case 'nochange': */ default: @@ -114,12 +127,17 @@ public function refreshUpdates($force = false) } else { - $update_params = JComponentHelper::getParams('com_installer'); - $cache_timeout = $update_params->get('cachetimeout', 6, 'int'); - $cache_timeout = 3600 * $cache_timeout; + $cache_timeout = 3600 * JComponentHelper::getParams('com_installer')->get('cachetimeout', 6, 'int'); } - $updater = JUpdater::getInstance(); + $updater = JUpdater::getInstance(); + $minimumStability = JUpdater::STABILITY_STABLE; + $comJoomlaupdateParams = JComponentHelper::getParams('com_joomlaupdate'); + + if (in_array($comJoomlaupdateParams->get('updatesource', 'nochange'), array('testing', 'custom'))) + { + $minimumStability = $comJoomlaupdateParams->get('minimum_stability', JUpdater::STABILITY_STABLE); + } $reflection = new ReflectionObject($updater); $reflectionMethod = $reflection->getMethod('findUpdates'); @@ -128,11 +146,11 @@ public function refreshUpdates($force = false) if (count($methodParameters) >= 4) { // Reinstall support is available in JUpdater - $updater->findUpdates(700, $cache_timeout, JUpdater::STABILITY_STABLE, true); + $updater->findUpdates(700, $cache_timeout, $minimumStability, true); } else { - $updater->findUpdates(700, $cache_timeout, JUpdater::STABILITY_STABLE); + $updater->findUpdates(700, $cache_timeout, $minimumStability); } } @@ -145,12 +163,17 @@ public function refreshUpdates($force = false) */ public function getUpdateInformation() { + if ($this->updateInformation) + { + return $this->updateInformation; + } + // Initialise the return array. - $ret = array( + $this->updateInformation = array( 'installed' => JVERSION, 'latest' => null, 'object' => null, - 'hasUpdate' => false + 'hasUpdate' => false, ); // Fetch the update information from the database. @@ -164,22 +187,45 @@ public function getUpdateInformation() if (is_null($updateObject)) { - $ret['latest'] = JVERSION; + $this->updateInformation['latest'] = JVERSION; + + return $this->updateInformation; + } + + // Check whether this is a valid update or not + if (version_compare($updateObject->version, JVERSION, '<')) + { + // This update points to an outdated version we should not offer to update to this + $this->updateInformation['latest'] = JVERSION; + + return $this->updateInformation; + } + + $this->updateInformation['latest'] = $updateObject->version; + $this->updateInformation['current'] = JVERSION; - return $ret; + // Check whether this is an update or not. + if (version_compare($updateObject->version, JVERSION, '>')) + { + $this->updateInformation['hasUpdate'] = true; } - $ret['latest'] = $updateObject->version; - $ret['hasUpdate'] = $updateObject->version != JVERSION; + $minimumStability = JUpdater::STABILITY_STABLE; + $comJoomlaupdateParams = JComponentHelper::getParams('com_joomlaupdate'); + + if (in_array($comJoomlaupdateParams->get('updatesource', 'nochange'), array('testing', 'custom'))) + { + $minimumStability = $comJoomlaupdateParams->get('minimum_stability', JUpdater::STABILITY_STABLE); + } // Fetch the full update details from the update details URL. jimport('joomla.updater.update'); $update = new JUpdate; - $update->loadFromXML($updateObject->detailsurl); + $update->loadFromXML($updateObject->detailsurl, $minimumStability); - $ret['object'] = $update; + $this->updateInformation['object'] = $update; - return $ret; + return $this->updateInformation; } /** @@ -214,16 +260,18 @@ public function purge() { $db = $this->getDbo(); - // Modify the database record - $update_site = new stdClass; - $update_site->last_check_timestamp = 0; - $update_site->enabled = 1; - $update_site->update_site_id = 1; - $db->updateObject('#__update_sites', $update_site, 'update_site_id'); + // Reset the last update check timestamp + $query = $db->getQuery(true) + ->update($db->quoteName('#__update_sites')) + ->set($db->quoteName('last_check_timestamp') . ' = 0'); + $db->setQuery($query); + $db->execute(); + // We should delete all core updates here $query = $db->getQuery(true) ->delete($db->quoteName('#__updates')) - ->where($db->quoteName('update_site_id') . ' = ' . $db->quote('1')); + ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')) + ->where($db->quoteName('type') . ' = ' . $db->quote('file')); $db->setQuery($query); if ($db->execute()) @@ -243,21 +291,48 @@ public function purge() /** * Downloads the update package to the site. * - * @return bool|string False on failure, basename of the file in any other case. + * @return boolean|string False on failure, basename of the file in any other case. * * @since 2.5.4 */ public function download() { $updateInfo = $this->getUpdateInformation(); - $packageURL = $updateInfo['object']->downloadurl->_data; - $headers = get_headers($packageURL, 1); + $packageURL = trim($updateInfo['object']->downloadurl->_data); + $sources = $updateInfo['object']->get('downloadSources', array()); + + // We have to manually follow the redirects here so we set the option to false. + $httpOptions = new Registry; + $httpOptions->set('follow_location', false); + + try + { + $head = HttpFactory::getHttp($httpOptions)->head($packageURL); + } + catch (RuntimeException $e) + { + // Passing false here -> download failed message + $response['basename'] = false; + + return $response; + } // Follow the Location headers until the actual download URL is known - while (isset($headers['Location'])) + while (isset($head->headers['location'])) { - $packageURL = $headers['Location']; - $headers = get_headers($packageURL, 1); + $packageURL = $head->headers['location']; + + try + { + $head = HttpFactory::getHttp($httpOptions)->head($packageURL); + } + catch (RuntimeException $e) + { + // Passing false here -> download failed message + $response['basename'] = false; + + return $response; + } } // Remove protocol, path and query string from URL @@ -269,9 +344,10 @@ public function download() } // Find the path to the temp directory and the local package. - $config = JFactory::getConfig(); - $tempdir = $config->get('tmp_path'); - $target = $tempdir . '/' . $basename; + $config = JFactory::getConfig(); + $tempdir = (string) InputFilter::getInstance(array(), array(), 1, 1)->clean($config->get('tmp_path'), 'path'); + $target = $tempdir . '/' . $basename; + $response = array(); // Do we have a cached file? $exists = JFile::exists($target); @@ -279,7 +355,16 @@ public function download() if (!$exists) { // Not there, let's fetch it. - return $this->downloadPackage($packageURL, $target); + $mirror = 0; + + while (!($download = $this->downloadPackage($packageURL, $target)) && isset($sources[$mirror])) + { + $name = $sources[$mirror]; + $packageURL = trim($name->url); + $mirror++; + } + + $response['basename'] = $download; } else { @@ -288,12 +373,61 @@ public function download() if (empty($filesize)) { - return $this->downloadPackage($packageURL, $target); + $mirror = 0; + + while (!($download = $this->downloadPackage($packageURL, $target)) && isset($sources[$mirror])) + { + $name = $sources[$mirror]; + $packageURL = trim($name->url); + $mirror++; + } + + $response['basename'] = $download; } // Yes, it's there, skip downloading. - return $basename; + $response['basename'] = $basename; + } + + $response['check'] = $this->isChecksumValid($target, $updateInfo['object']); + + return $response; + } + + /** + * Return the result of the checksum of a package with the SHA256/SHA384/SHA512 tags in the update server manifest + * + * @param string $packagefile Location of the package to be installed + * @param JUpdate $updateObject The Update Object + * + * @return boolean False in case the validation did not work; true in any other case. + * + * @note This method has been forked from (JInstallerHelper::isChecksumValid) so it + * does not depend on an up-to-date InstallerHelper at the update time + * + * @since 3.9.0 + */ + private function isChecksumValid($packagefile, $updateObject) + { + $hashes = array('sha256', 'sha384', 'sha512'); + + foreach ($hashes as $hash) + { + if ($updateObject->get($hash, false)) + { + $hashPackage = hash_file($hash, $packagefile); + $hashRemote = $updateObject->$hash->_data; + + if ($hashPackage !== $hashRemote) + { + // Return false in case the hash did not match + return false; + } + } } + + // Well nothing was provided or all worked + return true; } /** @@ -335,7 +469,14 @@ protected function downloadPackage($url, $target) JFile::delete($target); // Download the package - $result = $http->get($url); + try + { + $result = $http->get($url); + } + catch (RuntimeException $e) + { + return false; + } if (!$result || ($result->code != 200 && $result->code != 310)) { @@ -399,7 +540,9 @@ public function createRestorationFile($basename = null) 'kickstart.setup.destdir' => '$siteroot', 'kickstart.setup.restoreperms' => '0', 'kickstart.setup.filetype' => 'zip', - 'kickstart.setup.dryrun' => '0' + 'kickstart.setup.dryrun' => '0', + 'kickstart.setup.renamefiles' => array(), + 'kickstart.setup.postrenamefiles' => false ENDDATA; if ($method != 'direct') @@ -823,6 +966,11 @@ public function cleanUp() // Unset the update filename from the session. JFactory::getApplication()->setUserState('com_joomlaupdate.file', null); + $oldVersion = JFactory::getApplication()->getUserState('com_joomlaupdate.oldversion'); + + // Trigger event after joomla update. + JFactory::getApplication()->triggerEvent('onJoomlaAfterUpdate', array($oldVersion)); + JFactory::getApplication()->setUserState('com_joomlaupdate.oldversion', null); } /** @@ -849,7 +997,7 @@ public function upload() // Make sure that zlib is loaded so that the package can be unpacked. if (!extension_loaded('zlib')) { - throw new RuntimeException(('COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB'), 500); + throw new RuntimeException('COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB', 500); } // If there is no uploaded file, we have a problem... @@ -914,7 +1062,7 @@ public function upload() * * @param array $credentials The credentials to authenticate the user with * - * @return bool + * @return boolean * * @since 3.6.0 */ @@ -929,7 +1077,7 @@ public function captiveLogin($credentials) return false; } - // Make sure the user we're authorising is a Super User + // Make sure the user is authorised if (!$user->authorise('core.admin')) { return false; @@ -950,7 +1098,7 @@ public function captiveLogin($credentials) /** * Does the captive (temporary) file we uploaded before still exist? * - * @return bool + * @return boolean * * @since 3.6.0 */ @@ -995,4 +1143,747 @@ public function removePackageFiles() } } } + + /** + * Gets PHP options. + * TODO: Outsource, build common code base for pre install and pre update check + * + * @return array Array of PHP config options + * + * @since 3.10.0 + */ + public function getPhpOptions() + { + $options = array(); + + /* + * Check the PHP Version. It is already checked in JUpdate. + * A Joomla! Update which is not supported by current PHP + * version is not shown. So this check is actually unnecessary. + */ + $option = new stdClass; + $option->label = JText::sprintf('INSTL_PHP_VERSION_NEWER', $this->getTargetMinimumPHPVersion()); + $option->state = $this->isPhpVersionSupported(); + $option->notice = null; + $options[] = $option; + + // Only check if required PHP version is less than 7. + if (version_compare($this->getTargetMinimumPHPVersion(), '7', '<')) + { + // Check for magic quotes gpc. + $option = new stdClass; + $option->label = JText::_('INSTL_MAGIC_QUOTES_GPC'); + $option->state = (ini_get('magic_quotes_gpc') == false); + $option->notice = null; + $options[] = $option; + + // Check for register globals. + $option = new stdClass; + $option->label = JText::_('INSTL_REGISTER_GLOBALS'); + $option->state = (ini_get('register_globals') == false); + $option->notice = null; + $options[] = $option; + } + + // Check for zlib support. + $option = new stdClass; + $option->label = JText::_('INSTL_ZLIB_COMPRESSION_SUPPORT'); + $option->state = extension_loaded('zlib'); + $option->notice = null; + $options[] = $option; + + // Check for XML support. + $option = new stdClass; + $option->label = JText::_('INSTL_XML_SUPPORT'); + $option->state = extension_loaded('xml'); + $option->notice = null; + $options[] = $option; + + // Check for mbstring options. + if (extension_loaded('mbstring')) + { + // Check for default MB language. + $option = new stdClass; + $option->label = JText::_('INSTL_MB_LANGUAGE_IS_DEFAULT'); + $option->state = strtolower(ini_get('mbstring.language')) === 'neutral'; + $option->notice = $option->state ? null : JText::_('INSTL_NOTICEMBLANGNOTDEFAULT'); + $options[] = $option; + + // Check for MB function overload. + $option = new stdClass; + $option->label = JText::_('INSTL_MB_STRING_OVERLOAD_OFF'); + $option->state = ini_get('mbstring.func_overload') == 0; + $option->notice = $option->state ? null : JText::_('INSTL_NOTICEMBSTRINGOVERLOAD'); + $options[] = $option; + } + + // Check for a missing native parse_ini_file implementation. + $option = new stdClass; + $option->label = JText::_('INSTL_PARSE_INI_FILE_AVAILABLE'); + $option->state = $this->getIniParserAvailability(); + $option->notice = null; + $options[] = $option; + + // Check for missing native json_encode / json_decode support. + $option = new stdClass; + $option->label = JText::_('INSTL_JSON_SUPPORT_AVAILABLE'); + $option->state = function_exists('json_encode') && function_exists('json_decode'); + $option->notice = null; + $options[] = $option; + + $updateInformation = $this->getUpdateInformation(); + + // Check if configured database is compatible with Joomla 4 + if (version_compare($updateInformation['latest'], '4', '>=')) + { + $option = new stdClass; + $option->label = JText::sprintf('INSTL_DATABASE_SUPPORTED', $this->getConfiguredDatabaseType()); + $option->state = $this->isDatabaseTypeSupported(); + $option->notice = null; + $options[] = $option; + } + + // Check if database structure is up to date + $option = new stdClass; + $option->label = JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_DATABASE_STRUCTURE_TITLE'); + $option->state = $this->getDatabaseSchemaCheck(); + $option->notice = $option->state ? null : JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_DATABASE_STRUCTURE_NOTICE'); + $options[] = $option; + + return $options; + } + + /** + * Gets PHP Settings. + * TODO: Outsource, build common code base for pre install and pre update check + * + * @return array + * + * @since 3.10.0 + */ + public function getPhpSettings() + { + $settings = array(); + + // Check for display errors. + $setting = new stdClass; + $setting->label = JText::_('INSTL_DISPLAY_ERRORS'); + $setting->state = (bool) ini_get('display_errors'); + $setting->recommended = false; + $settings[] = $setting; + + // Check for file uploads. + $setting = new stdClass; + $setting->label = JText::_('INSTL_FILE_UPLOADS'); + $setting->state = (bool) ini_get('file_uploads'); + $setting->recommended = true; + $settings[] = $setting; + + // Only check if required PHP version is less than 7. + if (version_compare($this->getTargetMinimumPHPVersion(), '7', '<')) + { + // Check for magic quotes runtimes. + $setting = new stdClass; + $setting->label = JText::_('INSTL_MAGIC_QUOTES_RUNTIME'); + $setting->state = (bool) ini_get('magic_quotes_runtime'); + $setting->recommended = false; + $settings[] = $setting; + + // Check for safe mode. + $setting = new stdClass; + $setting->label = JText::_('INSTL_SAFE_MODE'); + $setting->state = (bool) ini_get('safe_mode'); + $setting->recommended = false; + $settings[] = $setting; + } + + // Check for output buffering. + $setting = new stdClass; + $setting->label = JText::_('INSTL_OUTPUT_BUFFERING'); + $setting->state = (int) ini_get('output_buffering') !== 0; + $setting->recommended = false; + $settings[] = $setting; + + // Check for session auto-start. + $setting = new stdClass; + $setting->label = JText::_('INSTL_SESSION_AUTO_START'); + $setting->state = (bool) ini_get('session.auto_start'); + $setting->recommended = false; + $settings[] = $setting; + + // Check for native ZIP support. + $setting = new stdClass; + $setting->label = JText::_('INSTL_ZIP_SUPPORT_AVAILABLE'); + $setting->state = function_exists('zip_open') && function_exists('zip_read'); + $setting->recommended = true; + $settings[] = $setting; + + return $settings; + } + + /** + * Returns the configured database type id (mysqli or sqlsrv or ...) + * + * @return string + * + * @since 3.10.0 + */ + private function getConfiguredDatabaseType() + { + return JFactory::getApplication()->get('dbtype'); + } + + /** + * Returns true, if J! version is < 4 or current configured + * database type is compatible with the update. + * + * @return boolean + * + * @since 3.10.0 + */ + public function isDatabaseTypeSupported() + { + $updateInformation = $this->getUpdateInformation(); + + // Check if configured database is compatible with Joomla 4 + if (version_compare($updateInformation['latest'], '4', '>=')) + { + $unsupportedDatabaseTypes = array('sqlsrv', 'sqlazure'); + $currentDatabaseType = $this->getConfiguredDatabaseType(); + + return !in_array($currentDatabaseType, $unsupportedDatabaseTypes); + } + + return true; + } + + + /** + * Returns true, if current installed php version is compatible with the update. + * + * @return boolean + * + * @since 3.10.0 + */ + public function isPhpVersionSupported() + { + return version_compare(PHP_VERSION, $this->getTargetMinimumPHPVersion(), '>='); + } + + /** + * Returns the PHP minimum version for the update. + * Returns JOOMLA_MINIMUM_PHP, if there is no information given. + * + * @return string + * + * @since 3.10.0 + */ + private function getTargetMinimumPHPVersion() + { + $updateInformation = $this->getUpdateInformation(); + + return isset($updateInformation['object']->php_minimum) ? + $updateInformation['object']->php_minimum->_data : + JOOMLA_MINIMUM_PHP; + } + + /** + * Checks the availability of the parse_ini_file and parse_ini_string functions. + * TODO: Outsource, build common code base for pre install and pre update check + * + * @return boolean True if the method exists. + * + * @since 3.10.0 + */ + public function getIniParserAvailability() + { + $disabledFunctions = ini_get('disable_functions'); + + if (!empty($disabledFunctions)) + { + // Attempt to detect them in the disable_functions blacklist. + $disabledFunctions = explode(',', trim($disabledFunctions)); + $numberOfDisabledFunctions = count($disabledFunctions); + + for ($i = 0; $i < $numberOfDisabledFunctions; $i++) + { + $disabledFunctions[$i] = trim($disabledFunctions[$i]); + } + + $result = !in_array('parse_ini_string', $disabledFunctions); + } + else + { + // Attempt to detect their existence; even pure PHP implementations of them will trigger a positive response, though. + $result = function_exists('parse_ini_string'); + } + + return $result; + } + + + /** + * Check if database structure is up to date + * + * @return boolean True if ok, false if not. + * + * @since 3.10.0 + */ + private function getDatabaseSchemaCheck() + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_installer/models', 'InstallerModel'); + + // Get the database model + $model = JModelLegacy::getInstance('Database', 'InstallerModel'); + + // Check if no default text filters found + if (!$model->getDefaultTextFilters()) + { + return false; + } + + // Check if database update version does not match CMS version + if (version_compare($model->getUpdateVersion(), JVERSION) != 0) + { + return false; + } + + // Get the schema change set + $changeSet = $model->getItems(); + + $changeSetCheck = $changeSet->check(); + + // Check if schema errors found + if (!empty($changeSetCheck)) + { + return false; + } + + // Check if database schema version does not match CMS version + if ($model->getSchemaVersion() != $changeSet->getSchema()) + { + return false; + } + + // No database problems found + return true; + } + + /** + * Gets an array containing all installed extensions, that are not core extensions. + * + * @return array name,version,updateserver + * + * @since 3.10.0 + */ + public function getNonCoreExtensions() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query->select( + $db->qn('ex.name') . ', ' . + $db->qn('ex.extension_id') . ', ' . + $db->qn('ex.manifest_cache') . ', ' . + $db->qn('ex.type') . ', ' . + $db->qn('ex.folder') . ', ' . + $db->qn('ex.element') . ', ' . + $db->qn('ex.client_id') + )->from( + $db->qn('#__extensions', 'ex') + )->where( + $db->qn('ex.package_id') . ' = 0' + ); + + $db->setQuery($query); + $rows = $db->loadObjectList(); + $rows = array_filter($rows, 'JoomlaupdateModelDefault::isNonCoreExtension'); + + foreach ($rows as $extension) + { + $decode = json_decode($extension->manifest_cache); + + // Remove unused fields so they do not cause javascript errors during pre-update check + unset($decode->description); + unset($decode->copyright); + unset($decode->creationDate); + + $this->translateExtensionName($extension); + $extension->version = isset($decode->version) + ? $decode->version + : JText::_('COM_JOOMLAUPDATE_PREUPDATE_UNKNOWN_EXTENSION_MANIFESTCACHE_VERSION'); + unset($extension->manifest_cache); + $extension->manifest_cache = $decode; + } + + return $rows; + } + + /** + * Checks if extension is non core extension. + * + * @param object $extension The extension to be checked + * + * @return bool true if extension is not a core extension + * + * @since 3.10.0 + */ + private static function isNonCoreExtension($extension) + { + return !\JExtensionHelper::checkIfCoreExtension($extension->type, $extension->element, $extension->client_id, $extension->folder); + } + + /** + * Gets an array containing all installed and enabled plugins, that are not core plugins. + * + * @param array $folderFilter Limit the list of plugins to a specific set of folder values + * + * @return array name,version,updateserver + * + * @since 3.10.0 + */ + public function getNonCorePlugins($folderFilter = array()) + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query->select( + $db->qn('ex.name') . ', ' . + $db->qn('ex.extension_id') . ', ' . + $db->qn('ex.manifest_cache') . ', ' . + $db->qn('ex.type') . ', ' . + $db->qn('ex.folder') . ', ' . + $db->qn('ex.element') . ', ' . + $db->qn('ex.client_id') . ', ' . + $db->qn('ex.package_id') + )->from( + $db->qn('#__extensions', 'ex') + )->where( + $db->qn('ex.type') . ' = ' . $db->quote('plugin') + )->where( + $db->qn('ex.enabled') . ' = 1' + ); + + if (count($folderFilter) > 0) + { + $folderFilter = array_map(array($db, 'quote'), $folderFilter); + + $query->where($db->qn('folder') . ' IN (' . implode(',', $folderFilter) . ')'); + } + + $db->setQuery($query); + $rows = $db->loadObjectList(); + $rows = array_filter($rows, 'JoomlaupdateModelDefault::isNonCoreExtension'); + + foreach ($rows as $plugin) + { + $decode = json_decode($plugin->manifest_cache); + + // Remove unused fields so they do not cause javascript errors during pre-update check + unset($decode->description); + unset($decode->copyright); + unset($decode->creationDate); + + $this->translateExtensionName($plugin); + $plugin->version = isset($decode->version) + ? $decode->version + : JText::_('COM_JOOMLAUPDATE_PREUPDATE_UNKNOWN_EXTENSION_MANIFESTCACHE_VERSION'); + unset($plugin->manifest_cache); + $plugin->manifest_cache = $decode; + } + + return $rows; + } + + /** + * Called by controller's fetchExtensionCompatibility, which is called via AJAX. + * + * @param string $extensionID The ID of the checked extension + * @param string $joomlaTargetVersion Target version of Joomla + * + * @return object + * + * @since 3.10.0 + */ + public function fetchCompatibility($extensionID, $joomlaTargetVersion) + { + $updateSites = $this->getUpdateSitesInfo($extensionID); + + if (empty($updateSites)) + { + return (object) array('state' => 2); + } + + foreach ($updateSites as $updateSite) + { + if ($updateSite['type'] === 'collection') + { + $updateFileUrls = $this->getCollectionDetailsUrls($updateSite, $joomlaTargetVersion); + + foreach ($updateFileUrls as $updateFileUrl) + { + $compatibleVersions = $this->checkCompatibility($updateFileUrl, $joomlaTargetVersion); + + // Return the compatible versions + return (object) array('state' => 1, 'compatibleVersions' => $compatibleVersions); + } + } + else + { + $compatibleVersions = $this->checkCompatibility($updateSite['location'], $joomlaTargetVersion); + + // Return the compatible versions + return (object) array('state' => 1, 'compatibleVersions' => $compatibleVersions); + } + } + + // In any other case we mark this extension as not compatible + return (object) array('state' => 0); + } + + /** + * Returns records with update sites and extension information for a given extension ID. + * + * @param int $extensionID The extension ID + * + * @return array + * + * @since 3.10.0 + */ + private function getUpdateSitesInfo($extensionID) + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query->select( + $db->qn('us.type') . ', ' . + $db->qn('us.location') . ', ' . + $db->qn('e.element') . ' AS ' . $db->qn('ext_element') . ', ' . + $db->qn('e.type') . ' AS ' . $db->qn('ext_type') . ', ' . + $db->qn('e.folder') . ' AS ' . $db->qn('ext_folder') + )->from( + $db->qn('#__update_sites', 'us') + )->leftJoin( + $db->qn('#__update_sites_extensions', 'ue') + . ' ON ' . $db->qn('ue.update_site_id') . ' = ' . $db->qn('us.update_site_id') + )->leftJoin( + $db->qn('#__extensions', 'e') + . ' ON ' . $db->qn('e.extension_id') . ' = ' . $db->qn('ue.extension_id') + )->where($db->qn('e.extension_id') . ' = ' . (int) $extensionID); + + $db->setQuery($query); + + $result = $db->loadAssocList(); + + if (!is_array($result)) + { + return array(); + } + + return $result; + } + + /** + * Method to get details URLs from a colletion update site for given extension and Joomla target version. + * + * @param array $updateSiteInfo The update site and extension information record to process + * @param string $joomlaTargetVersion The Joomla! version to test against, + * + * @return array An array of URLs. + * + * @since 3.10.0 + */ + private function getCollectionDetailsUrls($updateSiteInfo, $joomlaTargetVersion) + { + $return = array(); + + $http = new JHttp; + + try + { + $response = $http->get($updateSiteInfo['location']); + } + catch (RuntimeException $e) + { + $response = null; + } + + if ($response === null || $response->code !== 200) + { + return $return; + } + + $updateSiteXML = simplexml_load_string($response->body); + + foreach ($updateSiteXML->extension as $extension) + { + $attribs = new stdClass; + + $attribs->element = ''; + $attribs->type = ''; + $attribs->folder = ''; + $attribs->targetplatformversion = ''; + + foreach ($extension->attributes() as $key => $value) + { + $attribs->$key = (string) $value; + } + + if ($attribs->element === $updateSiteInfo['ext_element'] + && $attribs->type === $updateSiteInfo['ext_type'] + && $attribs->folder === $updateSiteInfo['ext_folder'] + && preg_match('/^' . $attribs->targetplatformversion . '/', $joomlaTargetVersion)) + { + $return[] = (string) $extension['detailsurl']; + } + } + + return $return; + } + + /** + * Method to check non core extensions for compatibility. + * + * @param string $updateFileUrl The items update XML url. + * @param string $joomlaTargetVersion The Joomla! version to test against + * + * @return array An array of strings with compatible version numbers + * + * @since 3.10.0 + */ + private function checkCompatibility($updateFileUrl, $joomlaTargetVersion) + { + // Get the minimum stability information from com_installer + $minimumStability = JComponentHelper::getParams('com_installer')->get('minimum_stability', JUpdater::STABILITY_STABLE); + + $update = new JUpdate; + $update->set('jversion.full', $joomlaTargetVersion); + $update->loadFromXML($updateFileUrl, $minimumStability); + + $compatibleVersions = $update->get('compatibleVersions'); + + // Check if old version of the updater library + if (!isset($compatibleVersions)) + { + $downloadUrl = $update->get('downloadurl'); + $updateVersion = $update->get('version'); + + return empty($downloadUrl) || empty($downloadUrl->_data) || empty($updateVersion) ? array() : array($updateVersion->_data); + } + + usort($compatibleVersions, 'version_compare'); + + return $compatibleVersions; + } + + /** + * Translates an extension name + * + * @param object &$item The extension of which the name needs to be translated + * + * @return void + * + * @since 3.10.0 + */ + protected function translateExtensionName(&$item) + { + // ToDo: Cleanup duplicated code. from com_installer/models/extension.php + $lang = JFactory::getLanguage(); + $path = $item->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE; + + $extension = $item->element; + $source = JPATH_SITE; + + switch ($item->type) + { + case 'component': + $extension = $item->element; + $source = $path . '/components/' . $extension; + break; + case 'module': + $extension = $item->element; + $source = $path . '/modules/' . $extension; + break; + case 'file': + $extension = 'files_' . $item->element; + break; + case 'library': + $extension = 'lib_' . $item->element; + break; + case 'plugin': + $extension = 'plg_' . $item->folder . '_' . $item->element; + $source = JPATH_PLUGINS . '/' . $item->folder . '/' . $item->element; + break; + case 'template': + $extension = 'tpl_' . $item->element; + $source = $path . '/templates/' . $item->element; + } + + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + $lang->load($extension, JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($extension, $source, null, false, true); + + // Translate the extension name if possible + $item->name = strip_tags(JText::_($item->name)); + } + + /** + * Checks whether a given template is active + * + * @param string $template The template name to be checked + * + * @return boolean + * + * @since 3.10.4 + */ + public function isTemplateActive($template) + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query->select( + $db->qn( + array( + 'id', + 'home' + ) + ) + )->from( + $db->qn('#__template_styles') + )->where( + $db->qn('template') . ' = ' . $db->q($template) + ); + + $templates = $db->setQuery($query)->loadObjectList(); + + $home = array_filter( + $templates, + function($value) + { + return $value->home > 0; + } + ); + + $ids = JArrayHelper::getColumn($templates, 'id'); + + $menu = false; + + if (count($ids)) + { + $query = $db->getQuery(true); + + $query->select( + 'COUNT(*)' + )->from( + $db->qn('#__menu') + )->where( + $db->qn('template_style_id') . ' IN(' . implode(',', $ids) . ')' + ); + + $menu = $db->setQuery($query)->loadResult() > 0; + } + + return $home || $menu; + } } diff --git a/administrator/components/com_joomlaupdate/restore.php b/administrator/components/com_joomlaupdate/restore.php index 093e9d815d7b8..cca291cfb3ab2 100644 --- a/administrator/components/com_joomlaupdate/restore.php +++ b/administrator/components/com_joomlaupdate/restore.php @@ -1,13 +1,12 @@ _errors); } } + $this->_errors[] = $error; } @@ -403,16 +388,6 @@ protected function setWarningsQueueSize($newSize = 0) } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * The superclass of all Akeeba Kickstart parts. The "parts" are intelligent stateful * classes which perform a single procedure and have preparation, running and @@ -492,9 +467,9 @@ abstract class AKAbstractPart extends AKAbstractObject /** * The public interface to an engine part. This method takes care for * calling the correct method in order to perform the initialisation - - * run - finalisation cycle of operation and return a proper reponse array. + * run - finalisation cycle of operation and return a proper response array. * - * @return array A Reponse Array + * @return array A Response Array */ final public function tick() { @@ -505,8 +480,6 @@ final public function tick() $this->_prepare(); break; case "prepared": - $this->_run(); - break; case "running": $this->_run(); break; @@ -558,6 +531,9 @@ final public function getState() { return "finished"; } + + // Unknown internal state. This should never happen. + return "error"; } /** @@ -729,13 +705,13 @@ function attach(AKAbstractPartObserver $obs) } /** - * Dettaches an observer object + * Detaches an observer object * * @param AKAbstractPartObserver $obs */ function detach(AKAbstractPartObserver $obs) { - delete($this->observers["$obs"]); + unset($this->observers["$obs"]); } /** @@ -776,16 +752,6 @@ protected function notify($message) } } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * The base class of unarchiver classes */ @@ -833,20 +799,12 @@ abstract class AKAbstractUnarchiver extends AKAbstractPart /** @var array Unwriteable files in these directories are always ignored and do not cause errors when not extracted */ protected $ignoreDirectories = array(); - /** - * Public constructor - */ - public function __construct() - { - parent::__construct(); - } - /** * Wakeup function, called whenever the class is unserialized */ public function __wakeup() { - if ($this->currentPartNumber >= 0) + if ($this->currentPartNumber >= 0 && !empty($this->archiveList[$this->currentPartNumber])) { $this->fp = @fopen($this->archiveList[$this->currentPartNumber], 'rb'); if ((is_resource($this->fp)) && ($this->currentPartOffset > 0)) @@ -899,8 +857,6 @@ public function isIgnoredDirectory($shortFilename) */ final protected function _prepare() { - parent::__construct(); - if (count($this->_parametersArray) > 0) { foreach ($this->_parametersArray as $key => $value) @@ -941,7 +897,7 @@ final protected function _prepare() // Should I use FTP? case 'post_proc': - $this->postProcEngine = AKFactory::getpostProc($value); + $this->postProcEngine = AKFactory::getPostProc($value); break; // Path to add in the beginning @@ -1119,18 +1075,18 @@ protected function _run() if ($status) { // Send start of file notification - $message = new stdClass; - $message->type = 'startfile'; - $message->content = new stdClass; + $message = new stdClass; + $message->type = 'startfile'; + $message->content = new stdClass; + $message->content->realfile = $this->fileHeader->file; + $message->content->file = $this->fileHeader->file; + $message->content->uncompressed = $this->fileHeader->uncompressed; + if (array_key_exists('realfile', get_object_vars($this->fileHeader))) { $message->content->realfile = $this->fileHeader->realFile; } - else - { - $message->content->realfile = $this->fileHeader->file; - } - $message->content->file = $this->fileHeader->file; + if (array_key_exists('compressed', get_object_vars($this->fileHeader))) { $message->content->compressed = $this->fileHeader->compressed; @@ -1139,7 +1095,6 @@ protected function _run() { $message->content->compressed = 0; } - $message->content->uncompressed = $this->fileHeader->uncompressed; debugMsg(__CLASS__ . '::_run() - Preparing to extract ' . $message->content->realfile); @@ -1196,7 +1151,7 @@ protected function _run() $this->notify($message); } $this->runState = AK_STATE_NOFILE; - continue; + break; } } @@ -1218,7 +1173,7 @@ protected function _run() /** * Concrete classes must use this method to read the file header * - * @return bool True if reading the file was successful, false if an error occured or we reached end of archive + * @return bool True if reading the file was successful, false if an error occurred or we reached end of archive */ protected abstract function readFileHeader(); @@ -1226,7 +1181,7 @@ protected abstract function readFileHeader(); * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when * it's finished processing the file data. * - * @return bool True if processing the file data was successful, false if an error occured + * @return bool True if processing the file data was successful, false if an error occurred */ protected abstract function processFileData(); @@ -1328,7 +1283,7 @@ protected function setCorrectPermissions($path) if ($directory != $rootDir) { // Is this an unwritable directory? - if (!is_writeable($directory)) + if (!is_writable($directory)) { $this->postProcEngine->chmod($directory, 0755); } @@ -1398,16 +1353,6 @@ protected function removePath($path) } } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * File post processor engines base class */ @@ -1455,17 +1400,6 @@ abstract public function rmdir($directory); abstract public function rename($from, $to); } - -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * Descendants of this class can be used in the unarchiver's observer methods (attach, detach and notify) * @@ -1477,17 +1411,6 @@ abstract class AKAbstractPartObserver abstract public function update($object, $message); } - -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * Direct file writer */ @@ -1516,6 +1439,11 @@ public function process() @touch($this->filename, $this->timestamp); } + if (substr($this->filename, -4) === '.php') + { + $this->clearFileInOPCache($this->filename); + } + return true; } @@ -1569,6 +1497,7 @@ public function createDirRecursive($dirName, $perms) // Is this a file instead of a directory? if (is_file($root . $path)) { + $this->clearFileInOPCache($root . $path); @unlink($root . $path); $ret = @mkdir($root . $path); } @@ -1598,6 +1527,8 @@ public function chmod($file, $perms) public function unlink($file) { + $this->clearFileInOPCache($file); + return @unlink($file); } @@ -1608,3872 +1539,1118 @@ public function rmdir($directory) public function rename($from, $to) { - return @rename($from, $to); + $this->clearFileInOPCache($from); + $ret = @rename($from, $to); + $this->clearFileInOPCache($to); + + return $ret; } -} + public function clearFileInOPCache($file){ + if (ini_get('opcache.enable') + && function_exists('opcache_invalidate') + && (!ini_get('opcache.restrict_api') || stripos(realpath($_SERVER['SCRIPT_FILENAME']), ini_get('opcache.restrict_api')) === 0)) + { + \opcache_invalidate($file, true); + } + } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ +} /** - * FTP file writer + * JPA archive extraction class */ -class AKPostprocFTP extends AKAbstractPostproc +class AKUnarchiverJPA extends AKAbstractUnarchiver { - /** @var bool Should I use FTP over implicit SSL? */ - public $useSSL = false; - /** @var bool use Passive mode? */ - public $passive = true; - /** @var string FTP host name */ - public $host = ''; - /** @var int FTP port */ - public $port = 21; - /** @var string FTP user name */ - public $user = ''; - /** @var string FTP password */ - public $pass = ''; - /** @var string FTP initial directory */ - public $dir = ''; - /** @var resource The FTP handle */ - private $handle = null; - /** @var string The temporary directory where the data will be stored */ - private $tempDir = ''; + protected $archiveHeaderData = array(); - public function __construct() + protected function readArchiveHeader() { - parent::__construct(); + debugMsg('Preparing to read archive header'); + // Initialize header data array + $this->archiveHeaderData = new stdClass(); + + // Open the first part + debugMsg('Opening the first part'); + $this->nextFile(); - $this->useSSL = AKFactory::get('kickstart.ftp.ssl', false); - $this->passive = AKFactory::get('kickstart.ftp.passive', true); - $this->host = AKFactory::get('kickstart.ftp.host', ''); - $this->port = AKFactory::get('kickstart.ftp.port', 21); - if (trim($this->port) == '') + // Fail for unreadable files + if ($this->fp === false) { - $this->port = 21; + debugMsg('Could not open the first part'); + + return false; } - $this->user = AKFactory::get('kickstart.ftp.user', ''); - $this->pass = AKFactory::get('kickstart.ftp.pass', ''); - $this->dir = AKFactory::get('kickstart.ftp.dir', ''); - $this->tempDir = AKFactory::get('kickstart.ftp.tempdir', ''); - $connected = $this->connect(); + // Read the signature + $sig = fread($this->fp, 3); - if ($connected) + if ($sig != 'JPA') { - if (!empty($this->tempDir)) - { - $tempDir = rtrim($this->tempDir, '/\\') . '/'; - $writable = $this->isDirWritable($tempDir); - } - else - { - $tempDir = ''; - $writable = false; - } + // Not a JPA file + debugMsg('Invalid archive signature'); + $this->setError(AKText::_('ERR_NOT_A_JPA_FILE')); - if (!$writable) - { - // Default temporary directory is the current root - $tempDir = KSROOTDIR; - if (empty($tempDir)) - { - // Oh, we have no directory reported! - $tempDir = '.'; - } - $absoluteDirToHere = $tempDir; - $tempDir = rtrim(str_replace('\\', '/', $tempDir), '/'); - if (!empty($tempDir)) - { - $tempDir .= '/'; - } - $this->tempDir = $tempDir; - // Is this directory writable? - $writable = $this->isDirWritable($tempDir); - } + return false; + } - if (!$writable) - { - // Nope. Let's try creating a temporary directory in the site's root. - $tempDir = $absoluteDirToHere . '/kicktemp'; - $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos - $this->createDirRecursive($tempDir, $trustMeIKnowWhatImDoing); - // Try making it writable... - $this->fixPermissions($tempDir); - $writable = $this->isDirWritable($tempDir); - } + // Read and parse header length + $header_length_array = unpack('v', fread($this->fp, 2)); + $header_length = $header_length_array[1]; - // Was the new directory writable? - if (!$writable) - { - // Let's see if the user has specified one - $userdir = AKFactory::get('kickstart.ftp.tempdir', ''); - if (!empty($userdir)) - { - // Is it an absolute or a relative directory? - $absolute = false; - $absolute = $absolute || (substr($userdir, 0, 1) == '/'); - $absolute = $absolute || (substr($userdir, 1, 1) == ':'); - $absolute = $absolute || (substr($userdir, 2, 1) == ':'); - if (!$absolute) - { - // Make absolute - $tempDir = $absoluteDirToHere . $userdir; - } - else - { - // it's already absolute - $tempDir = $userdir; - } - // Does the directory exist? - if (is_dir($tempDir)) - { - // Yeah. Is it writable? - $writable = $this->isDirWritable($tempDir); - } - } - } - $this->tempDir = $tempDir; + // Read and parse the known portion of header data (14 bytes) + $bin_data = fread($this->fp, 14); + $header_data = unpack('Cmajor/Cminor/Vcount/Vuncsize/Vcsize', $bin_data); - if (!$writable) - { - // No writable directory found!!! - $this->setError(AKText::_('FTP_TEMPDIR_NOT_WRITABLE')); - } - else - { - AKFactory::set('kickstart.ftp.tempdir', $tempDir); - $this->tempDir = $tempDir; - } - } - } + // Load any remaining header data (forward compatibility) + $rest_length = $header_length - 19; - public function connect() - { - // Connect to server, using SSL if so required - if ($this->useSSL) + if ($rest_length > 0) { - $this->handle = @ftp_ssl_connect($this->host, $this->port); + $junk = fread($this->fp, $rest_length); } else { - $this->handle = @ftp_connect($this->host, $this->port); - } - if ($this->handle === false) - { - $this->setError(AKText::_('WRONG_FTP_HOST')); - - return false; + $junk = ''; } - // Login - if (!@ftp_login($this->handle, $this->user, $this->pass)) - { - $this->setError(AKText::_('WRONG_FTP_USER')); - @ftp_close($this->handle); - - return false; - } + // Temporary array with all the data we read + $temp = array( + 'signature' => $sig, + 'length' => $header_length, + 'major' => $header_data['major'], + 'minor' => $header_data['minor'], + 'filecount' => $header_data['count'], + 'uncompressedsize' => $header_data['uncsize'], + 'compressedsize' => $header_data['csize'], + 'unknowndata' => $junk + ); - // Change to initial directory - if (!@ftp_chdir($this->handle, $this->dir)) + // Array-to-object conversion + foreach ($temp as $key => $value) { - $this->setError(AKText::_('WRONG_FTP_PATH1')); - @ftp_close($this->handle); - - return false; + $this->archiveHeaderData->{$key} = $value; } - // Enable passive mode if the user requested it - if ($this->passive) - { - @ftp_pasv($this->handle, true); - } - else - { - @ftp_pasv($this->handle, false); - } + debugMsg('Header data:'); + debugMsg('Length : ' . $header_length); + debugMsg('Major : ' . $header_data['major']); + debugMsg('Minor : ' . $header_data['minor']); + debugMsg('File count : ' . $header_data['count']); + debugMsg('Uncompressed size : ' . $header_data['uncsize']); + debugMsg('Compressed size : ' . $header_data['csize']); - // Try to download ourselves - $testFilename = defined('KSSELFNAME') ? KSSELFNAME : basename(__FILE__); - $tempHandle = fopen('php://temp', 'r+'); - if (@ftp_fget($this->handle, $tempHandle, $testFilename, FTP_ASCII, 0) === false) - { - $this->setError(AKText::_('WRONG_FTP_PATH2')); - @ftp_close($this->handle); - fclose($tempHandle); + $this->currentPartOffset = @ftell($this->fp); - return false; - } - fclose($tempHandle); + $this->dataReadLength = 0; return true; } - private function isDirWritable($dir) + /** + * Concrete classes must use this method to read the file header + * + * @return bool True if reading the file was successful, false if an error occurred or we reached end of archive + */ + protected function readFileHeader() { - $fp = @fopen($dir . '/kickstart.dat', 'wb'); - if ($fp === false) + // If the current part is over, proceed to the next part please + if ($this->isEOF(true)) { - return false; + debugMsg('Archive part EOF; moving to next file'); + $this->nextFile(); } - else - { - @fclose($fp); - unlink($dir . '/kickstart.dat'); - return true; - } - } + $this->currentPartOffset = ftell($this->fp); - public function createDirRecursive($dirName, $perms) - { - // Strip absolute filesystem path to website's root - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) - { - // UNIXize the paths - $removePath = str_replace('\\', '/', $removePath); - $dirName = str_replace('\\', '/', $dirName); - // Make sure they both end in a slash - $removePath = rtrim($removePath, '/\\') . '/'; - $dirName = rtrim($dirName, '/\\') . '/'; - // Process the path removal - $left = substr($dirName, 0, strlen($removePath)); - if ($left == $removePath) - { - $dirName = substr($dirName, strlen($removePath)); - } - } - if (empty($dirName)) - { - $dirName = ''; - } // 'cause the substr() above may return FALSE. + debugMsg("Reading file signature; part $this->currentPartNumber, offset $this->currentPartOffset"); + // Get and decode Entity Description Block + $signature = fread($this->fp, 3); - $check = '/' . trim($this->dir, '/') . '/' . trim($dirName, '/'); - if ($this->is_dir($check)) - { - return true; - } + $this->fileHeader = new stdClass(); + $this->fileHeader->timestamp = 0; - $alldirs = explode('/', $dirName); - $previousDir = '/' . trim($this->dir); - foreach ($alldirs as $curdir) + // Check signature + if ($signature != 'JPF') { - $check = $previousDir . '/' . $curdir; - if (!$this->is_dir($check)) + if ($this->isEOF(true)) { - // Proactively try to delete a file by the same name - @ftp_delete($this->handle, $check); + // This file is finished; make sure it's the last one + $this->nextFile(); - if (@ftp_mkdir($this->handle, $check) === false) + if (!$this->isEOF(false)) { - // If we couldn't create the directory, attempt to fix the permissions in the PHP level and retry! - $this->fixPermissions($removePath . $check); - if (@ftp_mkdir($this->handle, $check) === false) - { - // Can we fall back to pure PHP mode, sire? - if (!@mkdir($check)) - { - $this->setError(AKText::sprintf('FTP_CANT_CREATE_DIR', $check)); + debugMsg('Invalid file signature before end of archive encountered'); + $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); - return false; - } - else - { - // Since the directory was built by PHP, change its permissions - $trustMeIKnowWhatImDoing = - 500 + 10 + 1; // working around overzealous scanners written by bozos - @chmod($check, $trustMeIKnowWhatImDoing); - - return true; - } - } + return false; } - @ftp_chmod($this->handle, $perms, $check); - } - $previousDir = $check; - } - - return true; - } - - private function is_dir($dir) - { - return @ftp_chdir($this->handle, $dir); - } - - private function fixPermissions($path) - { - // Turn off error reporting - if (!defined('KSDEBUG')) - { - $oldErrorReporting = @error_reporting(E_NONE); - } - // Get UNIX style paths - $relPath = str_replace('\\', '/', $path); - $basePath = rtrim(str_replace('\\', '/', KSROOTDIR), '/'); - $basePath = rtrim($basePath, '/'); - if (!empty($basePath)) - { - $basePath .= '/'; - } - // Remove the leading relative root - if (substr($relPath, 0, strlen($basePath)) == $basePath) - { - $relPath = substr($relPath, strlen($basePath)); - } - $dirArray = explode('/', $relPath); - $pathBuilt = rtrim($basePath, '/'); - foreach ($dirArray as $dir) - { - if (empty($dir)) - { - continue; - } - $oldPath = $pathBuilt; - $pathBuilt .= '/' . $dir; - if (is_dir($oldPath . $dir)) - { - $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos - @chmod($oldPath . $dir, $trustMeIKnowWhatImDoing); + // We're just finished + return false; } else { - $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos - if (@chmod($oldPath . $dir, $trustMeIKnowWhatImDoing) === false) + $screwed = true; + + if (AKFactory::get('kickstart.setup.ignoreerrors', false)) { - @unlink($oldPath . $dir); + debugMsg('Invalid file block signature; launching heuristic file block signature scanner'); + $screwed = !$this->heuristicFileHeaderLocator(); + + if (!$screwed) + { + $signature = 'JPF'; + } + else + { + debugMsg('Heuristics failed. Brace yourself for the imminent crash.'); + } } - } - } - // Restore error reporting - if (!defined('KSDEBUG')) - { - @error_reporting($oldErrorReporting); + if ($screwed) + { + debugMsg('Invalid file block signature'); + // This is not a file block! The archive is corrupt. + $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); + + return false; + } + } } - } + // This a JPA Entity Block. Process the header. - function __wakeup() - { - $this->connect(); - } + $isBannedFile = false; - public function process() - { - if (is_null($this->tempFilename)) + // Read length of EDB and of the Entity Path Data + $length_array = unpack('vblocksize/vpathsize', fread($this->fp, 4)); + // Read the path data + if ($length_array['pathsize'] > 0) { - // If an empty filename is passed, it means that we shouldn't do any post processing, i.e. - // the entity was a directory or symlink - return true; + $file = fread($this->fp, $length_array['pathsize']); } - - $remotePath = dirname($this->filename); - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) + else { - $removePath = ltrim($removePath, "/"); - $remotePath = ltrim($remotePath, "/"); - $left = substr($remotePath, 0, strlen($removePath)); - if ($left == $removePath) - { - $remotePath = substr($remotePath, strlen($removePath)); - } + $file = ''; } - $absoluteFSPath = dirname($this->filename); - $relativeFTPPath = trim($remotePath, '/'); - $absoluteFTPPath = '/' . trim($this->dir, '/') . '/' . trim($remotePath, '/'); - $onlyFilename = basename($this->filename); - - $remoteName = $absoluteFTPPath . '/' . $onlyFilename; - - $ret = @ftp_chdir($this->handle, $absoluteFTPPath); - if ($ret === false) + // Handle file renaming + $isRenamed = false; + if (is_array($this->renameFiles) && (count($this->renameFiles) > 0)) { - $ret = $this->createDirRecursive($absoluteFSPath, 0755); - if ($ret === false) - { - $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); - - return false; - } - $ret = @ftp_chdir($this->handle, $absoluteFTPPath); - if ($ret === false) + if (array_key_exists($file, $this->renameFiles)) { - $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); - - return false; + $file = $this->renameFiles[$file]; + $isRenamed = true; } } - $ret = @ftp_put($this->handle, $remoteName, $this->tempFilename, FTP_BINARY); - if ($ret === false) + // Handle directory renaming + $isDirRenamed = false; + if (is_array($this->renameDirs) && (count($this->renameDirs) > 0)) { - // If we couldn't create the file, attempt to fix the permissions in the PHP level and retry! - $this->fixPermissions($this->filename); - $this->unlink($this->filename); - - $fp = @fopen($this->tempFilename, 'rb'); - if ($fp !== false) - { - $ret = @ftp_fput($this->handle, $remoteName, $fp, FTP_BINARY); - @fclose($fp); - } - else + if (array_key_exists(dirname($file), $this->renameDirs)) { - $ret = false; + $file = rtrim($this->renameDirs[dirname($file)], '/') . '/' . basename($file); + $isRenamed = true; + $isDirRenamed = true; } } - @unlink($this->tempFilename); - if ($ret === false) - { - $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); + // Read and parse the known data portion + $bin_data = fread($this->fp, 14); + $header_data = unpack('Ctype/Ccompression/Vcompsize/Vuncompsize/Vperms', $bin_data); + // Read any unknown data + $restBytes = $length_array['blocksize'] - (21 + $length_array['pathsize']); - return false; - } - $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); - if ($restorePerms) - { - @ftp_chmod($this->_handle, $this->perms, $remoteName); - } - else + if ($restBytes > 0) { - @ftp_chmod($this->_handle, 0644, $remoteName); - } + // Start reading the extra fields + while ($restBytes >= 4) + { + $extra_header_data = fread($this->fp, 4); + $extra_header = unpack('vsignature/vlength', $extra_header_data); + $restBytes -= 4; + $extra_header['length'] -= 4; - return true; - } + switch ($extra_header['signature']) + { + case 256: + // File modified timestamp + if ($extra_header['length'] > 0) + { + $bindata = fread($this->fp, $extra_header['length']); + $restBytes -= $extra_header['length']; + $timestamps = unpack('Vmodified', substr($bindata, 0, 4)); + $filectime = $timestamps['modified']; + $this->fileHeader->timestamp = $filectime; + } + break; - /* - * Tries to fix directory/file permissions in the PHP level, so that - * the FTP operation doesn't fail. - * @param $path string The full path to a directory or file - */ + default: + // Unknown field + if ($extra_header['length'] > 0) + { + $junk = fread($this->fp, $extra_header['length']); + $restBytes -= $extra_header['length']; + } + break; + } + } - public function unlink($file) - { - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) - { - $left = substr($file, 0, strlen($removePath)); - if ($left == $removePath) + if ($restBytes > 0) { - $file = substr($file, strlen($removePath)); + $junk = fread($this->fp, $restBytes); } } - $check = '/' . trim($this->dir, '/') . '/' . trim($file, '/'); + $compressionType = $header_data['compression']; - return @ftp_delete($this->handle, $check); - } + // Populate the return array + $this->fileHeader->file = $file; + $this->fileHeader->compressed = $header_data['compsize']; + $this->fileHeader->uncompressed = $header_data['uncompsize']; - public function processFilename($filename, $perms = 0755) - { - // Catch some error conditions... - if ($this->getError()) + switch ($header_data['type']) { - return false; - } + case 0: + $this->fileHeader->type = 'dir'; + break; - // If a null filename is passed, it means that we shouldn't do any post processing, i.e. - // the entity was a directory or symlink - if (is_null($filename)) - { - $this->filename = null; - $this->tempFilename = null; + case 1: + $this->fileHeader->type = 'file'; + break; - return null; + case 2: + $this->fileHeader->type = 'link'; + break; } - // Strip absolute filesystem path to website's root - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) + switch ($compressionType) { - $left = substr($filename, 0, strlen($removePath)); - if ($left == $removePath) - { - $filename = substr($filename, strlen($removePath)); - } + case 0: + $this->fileHeader->compression = 'none'; + break; + case 1: + $this->fileHeader->compression = 'gzip'; + break; + case 2: + $this->fileHeader->compression = 'bzip2'; + break; } - // Trim slash on the left - $filename = ltrim($filename, '/'); - - $this->filename = $filename; - $this->tempFilename = tempnam($this->tempDir, 'kickstart-'); - $this->perms = $perms; + $this->fileHeader->permissions = $header_data['perms']; - if (empty($this->tempFilename)) + // Find hard-coded banned files + if ((basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..")) { - // Oops! Let's try something different - $this->tempFilename = $this->tempDir . '/kickstart-' . time() . '.dat'; + $isBannedFile = true; } - return $this->tempFilename; - } - - public function close() - { - @ftp_close($this->handle); - } - - public function chmod($file, $perms) - { - return @ftp_chmod($this->handle, $perms, $file); - } - - public function rmdir($directory) - { - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) + // Also try to find banned files passed in class configuration + if ((count($this->skipFiles) > 0) && (!$isRenamed)) { - $left = substr($directory, 0, strlen($removePath)); - if ($left == $removePath) + if (in_array($this->fileHeader->file, $this->skipFiles)) { - $directory = substr($directory, strlen($removePath)); + $isBannedFile = true; } } - $check = '/' . trim($this->dir, '/') . '/' . trim($directory, '/'); - - return @ftp_rmdir($this->handle, $check); - } - - public function rename($from, $to) - { - $originalFrom = $from; - $originalTo = $to; - - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) + // If we have a banned file, let's skip it + if ($isBannedFile) { - $left = substr($from, 0, strlen($removePath)); - if ($left == $removePath) + debugMsg('Skipping file ' . $this->fileHeader->file); + // Advance the file pointer, skipping exactly the size of the compressed data + $seekleft = $this->fileHeader->compressed; + while ($seekleft > 0) { - $from = substr($from, strlen($removePath)); + // Ensure that we can seek past archive part boundaries + $curSize = @filesize($this->archiveList[$this->currentPartNumber]); + $curPos = @ftell($this->fp); + $canSeek = $curSize - $curPos; + if ($canSeek > $seekleft) + { + $canSeek = $seekleft; + } + @fseek($this->fp, $canSeek, SEEK_CUR); + $seekleft -= $canSeek; + if ($seekleft) + { + $this->nextFile(); + } } - } - $from = '/' . trim($this->dir, '/') . '/' . trim($from, '/'); - if (!empty($removePath)) - { - $left = substr($to, 0, strlen($removePath)); - if ($left == $removePath) - { - $to = substr($to, strlen($removePath)); - } - } - $to = '/' . trim($this->dir, '/') . '/' . trim($to, '/'); + $this->currentPartOffset = @ftell($this->fp); + $this->runState = AK_STATE_DONE; - $result = @ftp_rename($this->handle, $from, $to); - if ($result !== true) - { - return @rename($from, $to); - } - else - { return true; } - } -} + // Remove the removePath, if any + $this->fileHeader->file = $this->removePath($this->fileHeader->file); + // Last chance to prepend a path to the filename + if (!empty($this->addPath) && !$isDirRenamed) + { + $this->fileHeader->file = $this->addPath . $this->fileHeader->file; + } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - -/** - * FTP file writer - */ -class AKPostprocSFTP extends AKAbstractPostproc -{ - /** @var bool Should I use FTP over implicit SSL? */ - public $useSSL = false; - /** @var bool use Passive mode? */ - public $passive = true; - /** @var string FTP host name */ - public $host = ''; - /** @var int FTP port */ - public $port = 21; - /** @var string FTP user name */ - public $user = ''; - /** @var string FTP password */ - public $pass = ''; - /** @var string FTP initial directory */ - public $dir = ''; - - /** @var resource SFTP resource handle */ - private $handle = null; - - /** @var resource SSH2 connection resource handle */ - private $_connection = null; - - /** @var string Current remote directory, including the remote directory string */ - private $_currentdir; - - /** @var string The temporary directory where the data will be stored */ - private $tempDir = ''; - - public function __construct() - { - parent::__construct(); - - $this->host = AKFactory::get('kickstart.ftp.host', ''); - $this->port = AKFactory::get('kickstart.ftp.port', 22); - - if (trim($this->port) == '') - { - $this->port = 22; - } - - $this->user = AKFactory::get('kickstart.ftp.user', ''); - $this->pass = AKFactory::get('kickstart.ftp.pass', ''); - $this->dir = AKFactory::get('kickstart.ftp.dir', ''); - $this->tempDir = AKFactory::get('kickstart.ftp.tempdir', ''); - - $connected = $this->connect(); - - if ($connected) + // Get the translated path name + $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); + if ($this->fileHeader->type == 'file') { - if (!empty($this->tempDir)) + // Regular file; ask the postproc engine to process its filename + if ($restorePerms) { - $tempDir = rtrim($this->tempDir, '/\\') . '/'; - $writable = $this->isDirWritable($tempDir); + $this->fileHeader->realFile = + $this->postProcEngine->processFilename($this->fileHeader->file, $this->fileHeader->permissions); } else { - $tempDir = ''; - $writable = false; - } - - if (!$writable) - { - // Default temporary directory is the current root - $tempDir = KSROOTDIR; - if (empty($tempDir)) - { - // Oh, we have no directory reported! - $tempDir = '.'; - } - $absoluteDirToHere = $tempDir; - $tempDir = rtrim(str_replace('\\', '/', $tempDir), '/'); - if (!empty($tempDir)) - { - $tempDir .= '/'; - } - $this->tempDir = $tempDir; - // Is this directory writable? - $writable = $this->isDirWritable($tempDir); - } - - if (!$writable) - { - // Nope. Let's try creating a temporary directory in the site's root. - $tempDir = $absoluteDirToHere . '/kicktemp'; - $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos - $this->createDirRecursive($tempDir, $trustMeIKnowWhatImDoing); - // Try making it writable... - $this->fixPermissions($tempDir); - $writable = $this->isDirWritable($tempDir); - } - - // Was the new directory writable? - if (!$writable) - { - // Let's see if the user has specified one - $userdir = AKFactory::get('kickstart.ftp.tempdir', ''); - if (!empty($userdir)) - { - // Is it an absolute or a relative directory? - $absolute = false; - $absolute = $absolute || (substr($userdir, 0, 1) == '/'); - $absolute = $absolute || (substr($userdir, 1, 1) == ':'); - $absolute = $absolute || (substr($userdir, 2, 1) == ':'); - if (!$absolute) - { - // Make absolute - $tempDir = $absoluteDirToHere . $userdir; - } - else - { - // it's already absolute - $tempDir = $userdir; - } - // Does the directory exist? - if (is_dir($tempDir)) - { - // Yeah. Is it writable? - $writable = $this->isDirWritable($tempDir); - } - } + $this->fileHeader->realFile = $this->postProcEngine->processFilename($this->fileHeader->file); } - $this->tempDir = $tempDir; + } + elseif ($this->fileHeader->type == 'dir') + { + $dir = $this->fileHeader->file; - if (!$writable) + // Directory; just create it + if ($restorePerms) { - // No writable directory found!!! - $this->setError(AKText::_('SFTP_TEMPDIR_NOT_WRITABLE')); + $this->postProcEngine->createDirRecursive($this->fileHeader->file, $this->fileHeader->permissions); } else { - AKFactory::set('kickstart.ftp.tempdir', $tempDir); - $this->tempDir = $tempDir; + $this->postProcEngine->createDirRecursive($this->fileHeader->file, 0755); } + $this->postProcEngine->processFilename(null); } - } - - public function connect() - { - $this->_connection = false; - - if (!function_exists('ssh2_connect')) + else { - $this->setError(AKText::_('SFTP_NO_SSH2')); - - return false; + // Symlink; do not post-process + $this->postProcEngine->processFilename(null); } - $this->_connection = @ssh2_connect($this->host, $this->port); - - if (!@ssh2_auth_password($this->_connection, $this->user, $this->pass)) - { - $this->setError(AKText::_('SFTP_WRONG_USER')); - - $this->_connection = false; + $this->createDirectory(); - return false; - } + // Header is read + $this->runState = AK_STATE_HEADER; - $this->handle = @ssh2_sftp($this->_connection); + $this->dataReadLength = 0; - // I must have an absolute directory - if (!$this->dir) - { - $this->setError(AKText::_('SFTP_WRONG_STARTING_DIR')); + return true; + } - return false; - } + protected function heuristicFileHeaderLocator() + { + $ret = false; + $fullEOF = false; - // Change to initial directory - if (!$this->sftp_chdir('/')) + while (!$ret && !$fullEOF) { - $this->setError(AKText::_('SFTP_WRONG_STARTING_DIR')); - - unset($this->_connection); - unset($this->handle); - - return false; - } + $this->currentPartOffset = @ftell($this->fp); - // Try to download ourselves - $testFilename = defined('KSSELFNAME') ? KSSELFNAME : basename(__FILE__); - $basePath = '/' . trim($this->dir, '/'); + if ($this->isEOF(true)) + { + $this->nextFile(); + } - if (@fopen("ssh2.sftp://{$this->handle}$basePath/$testFilename", 'r+') === false) - { - $this->setError(AKText::_('SFTP_WRONG_STARTING_DIR')); + if ($this->isEOF(false)) + { + $fullEOF = true; + continue; + } - unset($this->_connection); - unset($this->handle); + // Read 512Kb + $chunk = fread($this->fp, 524288); + $size_read = mb_strlen($chunk, '8bit'); + //$pos = strpos($chunk, 'JPF'); + $pos = mb_strpos($chunk, 'JPF', 0, '8bit'); - return false; + if ($pos !== false) + { + // We found it! + $this->currentPartOffset += $pos + 3; + @fseek($this->fp, $this->currentPartOffset, SEEK_SET); + $ret = true; + } + else + { + // Not yet found :( + $this->currentPartOffset = @ftell($this->fp); + } } - return true; + return $ret; } /** - * Changes to the requested directory in the remote server. You give only the - * path relative to the initial directory and it does all the rest by itself, - * including doing nothing if the remote directory is the one we want. - * - * @param string $dir The (realtive) remote directory - * - * @return bool True if successful, false otherwise. + * Creates the directory this file points to */ - private function sftp_chdir($dir) + protected function createDirectory() { - // Strip absolute filesystem path to website's root - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) - { - // UNIXize the paths - $removePath = str_replace('\\', '/', $removePath); - $dir = str_replace('\\', '/', $dir); - - // Make sure they both end in a slash - $removePath = rtrim($removePath, '/\\') . '/'; - $dir = rtrim($dir, '/\\') . '/'; - - // Process the path removal - $left = substr($dir, 0, strlen($removePath)); - - if ($left == $removePath) - { - $dir = substr($dir, strlen($removePath)); - } - } - - if (empty($dir)) - { - // Because the substr() above may return FALSE. - $dir = ''; - } - - // Calculate "real" (absolute) SFTP path - $realdir = substr($this->dir, -1) == '/' ? substr($this->dir, 0, strlen($this->dir) - 1) : $this->dir; - $realdir .= '/' . $dir; - $realdir = substr($realdir, 0, 1) == '/' ? $realdir : '/' . $realdir; - - if ($this->_currentdir == $realdir) + if (AKFactory::get('kickstart.setup.dryrun', '0')) { - // Already there, do nothing return true; } - $result = @ssh2_sftp_stat($this->handle, $realdir); - - if ($result === false) + // Do we need to create a directory? + if (empty($this->fileHeader->realFile)) { - return false; + $this->fileHeader->realFile = $this->fileHeader->file; } - else - { - // Update the private "current remote directory" variable - $this->_currentdir = $realdir; - return true; - } - } + $lastSlash = strrpos($this->fileHeader->realFile, '/'); + $dirName = substr($this->fileHeader->realFile, 0, $lastSlash); + $perms = $this->flagRestorePermissions ? $this->fileHeader->permissions : 0755; + $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($dirName); - private function isDirWritable($dir) - { - if (@fopen("ssh2.sftp://{$this->handle}$dir/kickstart.dat", 'wb') === false) + if (($this->postProcEngine->createDirRecursive($dirName, $perms) == false) && (!$ignore)) { + $this->setError(AKText::sprintf('COULDNT_CREATE_DIR', $dirName)); + return false; } else { - @ssh2_sftp_unlink($this->handle, $dir . '/kickstart.dat'); - return true; } } - public function createDirRecursive($dirName, $perms) + /** + * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when + * it's finished processing the file data. + * + * @return bool True if processing the file data was successful, false if an error occurred + */ + protected function processFileData() { - // Strip absolute filesystem path to website's root - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) - { - // UNIXize the paths - $removePath = str_replace('\\', '/', $removePath); - $dirName = str_replace('\\', '/', $dirName); - // Make sure they both end in a slash - $removePath = rtrim($removePath, '/\\') . '/'; - $dirName = rtrim($dirName, '/\\') . '/'; - // Process the path removal - $left = substr($dirName, 0, strlen($removePath)); - if ($left == $removePath) - { - $dirName = substr($dirName, strlen($removePath)); - } - } - if (empty($dirName)) - { - $dirName = ''; - } // 'cause the substr() above may return FALSE. - - $check = '/' . trim($this->dir, '/ ') . '/' . trim($dirName, '/'); - - if ($this->is_dir($check)) - { - return true; - } - - $alldirs = explode('/', $dirName); - $previousDir = '/' . trim($this->dir, '/ '); - - foreach ($alldirs as $curdir) + switch ($this->fileHeader->type) { - if (!$curdir) - { - continue; - } - - $check = $previousDir . '/' . $curdir; + case 'dir': + return $this->processTypeDir(); + break; - if (!$this->is_dir($check)) - { - // Proactively try to delete a file by the same name - @ssh2_sftp_unlink($this->handle, $check); + case 'link': + return $this->processTypeLink(); + break; - if (@ssh2_sftp_mkdir($this->handle, $check) === false) + case 'file': + switch ($this->fileHeader->compression) { - // If we couldn't create the directory, attempt to fix the permissions in the PHP level and retry! - $this->fixPermissions($check); - - if (@ssh2_sftp_mkdir($this->handle, $check) === false) - { - // Can we fall back to pure PHP mode, sire? - if (!@mkdir($check)) - { - $this->setError(AKText::sprintf('FTP_CANT_CREATE_DIR', $check)); + case 'none': + return $this->processTypeFileUncompressed(); + break; - return false; - } - else - { - // Since the directory was built by PHP, change its permissions - $trustMeIKnowWhatImDoing = - 500 + 10 + 1; // working around overzealous scanners written by bozos - @chmod($check, $trustMeIKnowWhatImDoing); + case 'gzip': + case 'bzip2': + return $this->processTypeFileCompressedSimple(); + break; - return true; - } - } } + break; - @ssh2_sftp_chmod($this->handle, $check, $perms); - } - - $previousDir = $check; + default: + debugMsg('Unknown file type ' . $this->fileHeader->type); + break; } + // Unknown file type. Play dumb. return true; } - private function is_dir($dir) + /** + * Process the file data of a directory entry + * + * @return bool + */ + private function processTypeDir() { - return $this->sftp_chdir($dir); + // Directory entries in the JPA do not have file data, therefore we're done processing the entry + $this->runState = AK_STATE_DATAREAD; + + return true; } - private function fixPermissions($path) + /** + * Process the file data of a link entry + * + * @return bool + */ + private function processTypeLink() { - // Turn off error reporting - if (!defined('KSDEBUG')) + $readBytes = 0; + $toReadBytes = 0; + $leftBytes = $this->fileHeader->compressed; + $data = ''; + + while ($leftBytes > 0) { - $oldErrorReporting = @error_reporting(E_NONE); - } + $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; + $mydata = $this->fread($this->fp, $toReadBytes); + $reallyReadBytes = akstringlen($mydata); + $data .= $mydata; + $leftBytes -= $reallyReadBytes; - // Get UNIX style paths - $relPath = str_replace('\\', '/', $path); - $basePath = rtrim(str_replace('\\', '/', KSROOTDIR), '/'); - $basePath = rtrim($basePath, '/'); + if ($reallyReadBytes < $toReadBytes) + { + // We read less than requested! Why? Did we hit local EOF? + if ($this->isEOF(true) && !$this->isEOF(false)) + { + // Yeap. Let's go to the next file + $this->nextFile(); + } + else + { + debugMsg('End of local file before reading all data with no more parts left. The archive is corrupt or truncated.'); + // Nope. The archive is corrupt + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - if (!empty($basePath)) - { - $basePath .= '/'; + return false; + } + } } - // Remove the leading relative root - if (substr($relPath, 0, strlen($basePath)) == $basePath) - { - $relPath = substr($relPath, strlen($basePath)); - } + $filename = isset($this->fileHeader->realFile) ? $this->fileHeader->realFile : $this->fileHeader->file; - $dirArray = explode('/', $relPath); - $pathBuilt = rtrim($basePath, '/'); - - foreach ($dirArray as $dir) + if (!AKFactory::get('kickstart.setup.dryrun', '0')) { - if (empty($dir)) + // Try to remove an existing file or directory by the same name + if (file_exists($filename)) { - continue; + @unlink($filename); + @rmdir($filename); } - $oldPath = $pathBuilt; - $pathBuilt .= '/' . $dir; - - if (is_dir($oldPath . '/' . $dir)) - { - $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos - @chmod($oldPath . '/' . $dir, $trustMeIKnowWhatImDoing); - } - else + // Remove any trailing slash + if (substr($filename, -1) == '/') { - $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos - if (@chmod($oldPath . '/' . $dir, $trustMeIKnowWhatImDoing) === false) - { - @unlink($oldPath . $dir); - } + $filename = substr($filename, 0, -1); } + // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :( + @symlink($data, $filename); } - // Restore error reporting - if (!defined('KSDEBUG')) - { - @error_reporting($oldErrorReporting); - } - } + $this->runState = AK_STATE_DATAREAD; - function __wakeup() - { - $this->connect(); + return true; // No matter if the link was created! } - /* - * Tries to fix directory/file permissions in the PHP level, so that - * the FTP operation doesn't fail. - * @param $path string The full path to a directory or file - */ - - public function process() + private function processTypeFileUncompressed() { - if (is_null($this->tempFilename)) + // Uncompressed files are being processed in small chunks, to avoid timeouts + if (($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun', '0')) { - // If an empty filename is passed, it means that we shouldn't do any post processing, i.e. - // the entity was a directory or symlink - return true; + // Before processing file data, ensure permissions are adequate + $this->setCorrectPermissions($this->fileHeader->file); } - $remotePath = dirname($this->filename); - $absoluteFSPath = dirname($this->filename); - $absoluteFTPPath = '/' . trim($this->dir, '/') . '/' . trim($remotePath, '/'); - $onlyFilename = basename($this->filename); - - $remoteName = $absoluteFTPPath . '/' . $onlyFilename; - - $ret = $this->sftp_chdir($absoluteFTPPath); - - if ($ret === false) + // Open the output file + if (!AKFactory::get('kickstart.setup.dryrun', '0')) { - $ret = $this->createDirRecursive($absoluteFSPath, 0755); + $ignore = + AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); - if ($ret === false) + if ($this->dataReadLength == 0) { - $this->setError(AKText::sprintf('SFTP_COULDNT_UPLOAD', $this->filename)); - - return false; + $outfp = @fopen($this->fileHeader->realFile, 'wb'); + } + else + { + $outfp = @fopen($this->fileHeader->realFile, 'ab'); } - $ret = $this->sftp_chdir($absoluteFTPPath); - - if ($ret === false) + // Can we write to the file? + if (($outfp === false) && (!$ignore)) { - $this->setError(AKText::sprintf('SFTP_COULDNT_UPLOAD', $this->filename)); + // An error occurred + debugMsg('Could not write to output file'); + $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); return false; } } - // Create the file - $ret = $this->write($this->tempFilename, $remoteName); - - // If I got a -1 it means that I wasn't able to open the file, so I have to stop here - if ($ret === -1) - { - $this->setError(AKText::sprintf('SFTP_COULDNT_UPLOAD', $this->filename)); - - return false; - } - - if ($ret === false) - { - // If we couldn't create the file, attempt to fix the permissions in the PHP level and retry! - $this->fixPermissions($this->filename); - $this->unlink($this->filename); - - $ret = $this->write($this->tempFilename, $remoteName); - } - - @unlink($this->tempFilename); - - if ($ret === false) - { - $this->setError(AKText::sprintf('SFTP_COULDNT_UPLOAD', $this->filename)); - - return false; - } - $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); - - if ($restorePerms) - { - $this->chmod($remoteName, $this->perms); - } - else - { - $this->chmod($remoteName, 0644); - } - - return true; - } - - private function write($local, $remote) - { - $fp = @fopen("ssh2.sftp://{$this->handle}$remote", 'w'); - $localfp = @fopen($local, 'rb'); - - if ($fp === false) - { - return -1; - } - - if ($localfp === false) - { - @fclose($fp); - - return -1; - } - - $res = true; - - while (!feof($localfp) && ($res !== false)) - { - $buffer = @fread($localfp, 65567); - $res = @fwrite($fp, $buffer); - } - - @fclose($fp); - @fclose($localfp); - - return $res; - } - - public function unlink($file) - { - $check = '/' . trim($this->dir, '/') . '/' . trim($file, '/'); - - return @ssh2_sftp_unlink($this->handle, $check); - } - - public function chmod($file, $perms) - { - return @ssh2_sftp_chmod($this->handle, $file, $perms); - } - - public function processFilename($filename, $perms = 0755) - { - // Catch some error conditions... - if ($this->getError()) - { - return false; - } - - // If a null filename is passed, it means that we shouldn't do any post processing, i.e. - // the entity was a directory or symlink - if (is_null($filename)) - { - $this->filename = null; - $this->tempFilename = null; - - return null; - } - - // Strip absolute filesystem path to website's root - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) + // Does the file have any data, at all? + if ($this->fileHeader->compressed == 0) { - $left = substr($filename, 0, strlen($removePath)); - if ($left == $removePath) + // No file data! + if (!AKFactory::get('kickstart.setup.dryrun', '0') && is_resource($outfp)) { - $filename = substr($filename, strlen($removePath)); + @fclose($outfp); } - } - - // Trim slash on the left - $filename = ltrim($filename, '/'); - - $this->filename = $filename; - $this->tempFilename = tempnam($this->tempDir, 'kickstart-'); - $this->perms = $perms; - - if (empty($this->tempFilename)) - { - // Oops! Let's try something different - $this->tempFilename = $this->tempDir . '/kickstart-' . time() . '.dat'; - } - - return $this->tempFilename; - } - - public function close() - { - unset($this->_connection); - unset($this->handle); - } - - public function rmdir($directory) - { - $check = '/' . trim($this->dir, '/') . '/' . trim($directory, '/'); - - return @ssh2_sftp_rmdir($this->handle, $check); - } - public function rename($from, $to) - { - $from = '/' . trim($this->dir, '/') . '/' . trim($from, '/'); - $to = '/' . trim($this->dir, '/') . '/' . trim($to, '/'); - - $result = @ssh2_sftp_rename($this->handle, $from, $to); + $this->runState = AK_STATE_DATAREAD; - if ($result !== true) - { - return @rename($from, $to); - } - else - { return true; } - } - -} - - -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - -/** - * Hybrid direct / FTP mode file writer - */ -class AKPostprocHybrid extends AKAbstractPostproc -{ - - /** @var bool Should I use the FTP layer? */ - public $useFTP = false; - - /** @var bool Should I use FTP over implicit SSL? */ - public $useSSL = false; - - /** @var bool use Passive mode? */ - public $passive = true; - - /** @var string FTP host name */ - public $host = ''; - - /** @var int FTP port */ - public $port = 21; - - /** @var string FTP user name */ - public $user = ''; - - /** @var string FTP password */ - public $pass = ''; - - /** @var string FTP initial directory */ - public $dir = ''; - - /** @var resource The FTP handle */ - private $handle = null; - - /** @var string The temporary directory where the data will be stored */ - private $tempDir = ''; - - /** @var null The FTP connection handle */ - private $_handle = null; - - /** - * Public constructor. Tries to connect to the FTP server. - */ - public function __construct() - { - parent::__construct(); - - $this->useFTP = true; - $this->useSSL = AKFactory::get('kickstart.ftp.ssl', false); - $this->passive = AKFactory::get('kickstart.ftp.passive', true); - $this->host = AKFactory::get('kickstart.ftp.host', ''); - $this->port = AKFactory::get('kickstart.ftp.port', 21); - $this->user = AKFactory::get('kickstart.ftp.user', ''); - $this->pass = AKFactory::get('kickstart.ftp.pass', ''); - $this->dir = AKFactory::get('kickstart.ftp.dir', ''); - $this->tempDir = AKFactory::get('kickstart.ftp.tempdir', ''); - - if (trim($this->port) == '') - { - $this->port = 21; - } - - // If FTP is not configured, skip it altogether - if (empty($this->host) || empty($this->user) || empty($this->pass)) - { - $this->useFTP = false; - } - // Try to connect to the FTP server - $connected = $this->connect(); + // Reference to the global timer + $timer = AKFactory::getTimer(); - // If the connection fails, skip FTP altogether - if (!$connected) - { - $this->useFTP = false; - } + $toReadBytes = 0; + $leftBytes = $this->fileHeader->compressed - $this->dataReadLength; - if ($connected) + // Loop while there's data to read and enough time to do it + while (($leftBytes > 0) && ($timer->getTimeLeft() > 0)) { - if (!empty($this->tempDir)) - { - $tempDir = rtrim($this->tempDir, '/\\') . '/'; - $writable = $this->isDirWritable($tempDir); - } - else - { - $tempDir = ''; - $writable = false; - } + $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; + $data = $this->fread($this->fp, $toReadBytes); + $reallyReadBytes = akstringlen($data); + $leftBytes -= $reallyReadBytes; + $this->dataReadLength += $reallyReadBytes; - if (!$writable) + if ($reallyReadBytes < $toReadBytes) { - // Default temporary directory is the current root - $tempDir = KSROOTDIR; - if (empty($tempDir)) + // We read less than requested! Why? Did we hit local EOF? + if ($this->isEOF(true) && !$this->isEOF(false)) { - // Oh, we have no directory reported! - $tempDir = '.'; + // Yeap. Let's go to the next file + $this->nextFile(); } - $absoluteDirToHere = $tempDir; - $tempDir = rtrim(str_replace('\\', '/', $tempDir), '/'); - if (!empty($tempDir)) + else { - $tempDir .= '/'; - } - $this->tempDir = $tempDir; - // Is this directory writable? - $writable = $this->isDirWritable($tempDir); - } + // Nope. The archive is corrupt + debugMsg('Not enough data in file. The archive is truncated or corrupt.'); + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - if (!$writable) - { - // Nope. Let's try creating a temporary directory in the site's root. - $tempDir = $absoluteDirToHere . '/kicktemp'; - $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos - $this->createDirRecursive($tempDir, $trustMeIKnowWhatImDoing); - // Try making it writable... - $this->fixPermissions($tempDir); - $writable = $this->isDirWritable($tempDir); + return false; + } } - // Was the new directory writable? - if (!$writable) + if (!AKFactory::get('kickstart.setup.dryrun', '0')) { - // Let's see if the user has specified one - $userdir = AKFactory::get('kickstart.ftp.tempdir', ''); - if (!empty($userdir)) + if (is_resource($outfp)) { - // Is it an absolute or a relative directory? - $absolute = false; - $absolute = $absolute || (substr($userdir, 0, 1) == '/'); - $absolute = $absolute || (substr($userdir, 1, 1) == ':'); - $absolute = $absolute || (substr($userdir, 2, 1) == ':'); - if (!$absolute) - { - // Make absolute - $tempDir = $absoluteDirToHere . $userdir; - } - else - { - // it's already absolute - $tempDir = $userdir; - } - // Does the directory exist? - if (is_dir($tempDir)) - { - // Yeah. Is it writable? - $writable = $this->isDirWritable($tempDir); - } + @fwrite($outfp, $data); } } - $this->tempDir = $tempDir; - - if (!$writable) - { - // No writable directory found!!! - $this->setError(AKText::_('FTP_TEMPDIR_NOT_WRITABLE')); - } - else - { - AKFactory::set('kickstart.ftp.tempdir', $tempDir); - $this->tempDir = $tempDir; - } } - } - /** - * Tries to connect to the FTP server - * - * @return bool - */ - public function connect() - { - if (!$this->useFTP) + // Close the file pointer + if (!AKFactory::get('kickstart.setup.dryrun', '0')) { - return false; + if (is_resource($outfp)) + { + @fclose($outfp); + } } - // Connect to server, using SSL if so required - if ($this->useSSL) + // Was this a pre-timeout bail out? + if ($leftBytes > 0) { - $this->handle = @ftp_ssl_connect($this->host, $this->port); + $this->runState = AK_STATE_DATA; } else { - $this->handle = @ftp_connect($this->host, $this->port); - } - if ($this->handle === false) - { - $this->setError(AKText::_('WRONG_FTP_HOST')); - - return false; + // Oh! We just finished! + $this->runState = AK_STATE_DATAREAD; + $this->dataReadLength = 0; } - // Login - if (!@ftp_login($this->handle, $this->user, $this->pass)) - { - $this->setError(AKText::_('WRONG_FTP_USER')); - @ftp_close($this->handle); - - return false; - } - - // Change to initial directory - if (!@ftp_chdir($this->handle, $this->dir)) - { - $this->setError(AKText::_('WRONG_FTP_PATH1')); - @ftp_close($this->handle); - - return false; - } - - // Enable passive mode if the user requested it - if ($this->passive) - { - @ftp_pasv($this->handle, true); - } - else - { - @ftp_pasv($this->handle, false); - } - - // Try to download ourselves - $testFilename = defined('KSSELFNAME') ? KSSELFNAME : basename(__FILE__); - $tempHandle = fopen('php://temp', 'r+'); - - if (@ftp_fget($this->handle, $tempHandle, $testFilename, FTP_ASCII, 0) === false) - { - $this->setError(AKText::_('WRONG_FTP_PATH2')); - @ftp_close($this->handle); - fclose($tempHandle); - - return false; - } - - fclose($tempHandle); - - return true; - } - - /** - * Is the directory writeable? - * - * @param string $dir The directory ti check - * - * @return bool - */ - private function isDirWritable($dir) - { - $fp = @fopen($dir . '/kickstart.dat', 'wb'); - - if ($fp === false) - { - return false; - } - - @fclose($fp); - unlink($dir . '/kickstart.dat'); - - return true; - } - - /** - * Create a directory, recursively - * - * @param string $dirName The directory to create - * @param int $perms The permissions to give to the directory - * - * @return bool - */ - public function createDirRecursive($dirName, $perms) - { - // Strip absolute filesystem path to website's root - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - - if (!empty($removePath)) - { - // UNIXize the paths - $removePath = str_replace('\\', '/', $removePath); - $dirName = str_replace('\\', '/', $dirName); - // Make sure they both end in a slash - $removePath = rtrim($removePath, '/\\') . '/'; - $dirName = rtrim($dirName, '/\\') . '/'; - // Process the path removal - $left = substr($dirName, 0, strlen($removePath)); - - if ($left == $removePath) - { - $dirName = substr($dirName, strlen($removePath)); - } - } - - // 'cause the substr() above may return FALSE. - if (empty($dirName)) - { - $dirName = ''; - } - - $check = '/' . trim($this->dir, '/') . '/' . trim($dirName, '/'); - $checkFS = $removePath . trim($dirName, '/'); - - if ($this->is_dir($check)) - { - return true; - } - - $alldirs = explode('/', $dirName); - $previousDir = '/' . trim($this->dir); - $previousDirFS = rtrim($removePath, '/\\'); - - foreach ($alldirs as $curdir) - { - $check = $previousDir . '/' . $curdir; - $checkFS = $previousDirFS . '/' . $curdir; - - if (!is_dir($checkFS) && !$this->is_dir($check)) - { - // Proactively try to delete a file by the same name - if (!@unlink($checkFS) && $this->useFTP) - { - @ftp_delete($this->handle, $check); - } - - $createdDir = @mkdir($checkFS, 0755); - - if (!$createdDir && $this->useFTP) - { - $createdDir = @ftp_mkdir($this->handle, $check); - } - - if ($createdDir === false) - { - // If we couldn't create the directory, attempt to fix the permissions in the PHP level and retry! - $this->fixPermissions($checkFS); - - $createdDir = @mkdir($checkFS, 0755); - if (!$createdDir && $this->useFTP) - { - $createdDir = @ftp_mkdir($this->handle, $check); - } - - if ($createdDir === false) - { - $this->setError(AKText::sprintf('FTP_CANT_CREATE_DIR', $check)); - - return false; - } - } - - if (!@chmod($checkFS, $perms) && $this->useFTP) - { - @ftp_chmod($this->handle, $perms, $check); - } - } - - $previousDir = $check; - $previousDirFS = $checkFS; - } - - return true; - } - - private function is_dir($dir) - { - if ($this->useFTP) - { - return @ftp_chdir($this->handle, $dir); - } - - return false; - } - - /** - * Tries to fix directory/file permissions in the PHP level, so that - * the FTP operation doesn't fail. - * - * @param $path string The full path to a directory or file - */ - private function fixPermissions($path) - { - // Turn off error reporting - if (!defined('KSDEBUG')) - { - $oldErrorReporting = @error_reporting(E_NONE); - } - - // Get UNIX style paths - $relPath = str_replace('\\', '/', $path); - $basePath = rtrim(str_replace('\\', '/', KSROOTDIR), '/'); - $basePath = rtrim($basePath, '/'); - - if (!empty($basePath)) - { - $basePath .= '/'; - } - - // Remove the leading relative root - if (substr($relPath, 0, strlen($basePath)) == $basePath) - { - $relPath = substr($relPath, strlen($basePath)); - } - - $dirArray = explode('/', $relPath); - $pathBuilt = rtrim($basePath, '/'); - - foreach ($dirArray as $dir) - { - if (empty($dir)) - { - continue; - } - - $oldPath = $pathBuilt; - $pathBuilt .= '/' . $dir; - - if (is_dir($oldPath . $dir)) - { - $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos - @chmod($oldPath . $dir, $trustMeIKnowWhatImDoing); - } - else - { - $trustMeIKnowWhatImDoing = 500 + 10 + 1; // working around overzealous scanners written by bozos - if (@chmod($oldPath . $dir, $trustMeIKnowWhatImDoing) === false) - { - @unlink($oldPath . $dir); - } - } - } - - // Restore error reporting - if (!defined('KSDEBUG')) - { - @error_reporting($oldErrorReporting); - } - } - - /** - * Called after unserialisation, tries to reconnect to FTP - */ - function __wakeup() - { - if ($this->useFTP) - { - $this->connect(); - } - } - - function __destruct() - { - if (!$this->useFTP) - { - @ftp_close($this->handle); - } - } - - /** - * Post-process an extracted file, using FTP or direct file writes to move it - * - * @return bool - */ - public function process() - { - if (is_null($this->tempFilename)) - { - // If an empty filename is passed, it means that we shouldn't do any post processing, i.e. - // the entity was a directory or symlink - return true; - } - - $remotePath = dirname($this->filename); - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - $root = rtrim($removePath, '/\\'); - - if (!empty($removePath)) - { - $removePath = ltrim($removePath, "/"); - $remotePath = ltrim($remotePath, "/"); - $left = substr($remotePath, 0, strlen($removePath)); - - if ($left == $removePath) - { - $remotePath = substr($remotePath, strlen($removePath)); - } - } - - $absoluteFSPath = dirname($this->filename); - $relativeFTPPath = trim($remotePath, '/'); - $absoluteFTPPath = '/' . trim($this->dir, '/') . '/' . trim($remotePath, '/'); - $onlyFilename = basename($this->filename); - - $remoteName = $absoluteFTPPath . '/' . $onlyFilename; - - // Does the directory exist? - if (!is_dir($root . '/' . $absoluteFSPath)) - { - $ret = $this->createDirRecursive($absoluteFSPath, 0755); - - if (($ret === false) && ($this->useFTP)) - { - $ret = @ftp_chdir($this->handle, $absoluteFTPPath); - } - - if ($ret === false) - { - $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); - - return false; - } - } - - if ($this->useFTP) - { - $ret = @ftp_chdir($this->handle, $absoluteFTPPath); - } - - // Try copying directly - $ret = @copy($this->tempFilename, $root . '/' . $this->filename); - - if ($ret === false) - { - $this->fixPermissions($this->filename); - $this->unlink($this->filename); - - $ret = @copy($this->tempFilename, $root . '/' . $this->filename); - } - - if ($this->useFTP && ($ret === false)) - { - $ret = @ftp_put($this->handle, $remoteName, $this->tempFilename, FTP_BINARY); - - if ($ret === false) - { - // If we couldn't create the file, attempt to fix the permissions in the PHP level and retry! - $this->fixPermissions($this->filename); - $this->unlink($this->filename); - - $fp = @fopen($this->tempFilename, 'rb'); - if ($fp !== false) - { - $ret = @ftp_fput($this->handle, $remoteName, $fp, FTP_BINARY); - @fclose($fp); - } - else - { - $ret = false; - } - } - } - - @unlink($this->tempFilename); - - if ($ret === false) - { - $this->setError(AKText::sprintf('FTP_COULDNT_UPLOAD', $this->filename)); - - return false; - } - - $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); - $perms = $restorePerms ? $this->perms : 0644; - - $ret = @chmod($root . '/' . $this->filename, $perms); - - if ($this->useFTP && ($ret === false)) - { - @ftp_chmod($this->_handle, $perms, $remoteName); - } - - return true; - } - - public function unlink($file) - { - $ret = @unlink($file); - - if (!$ret && $this->useFTP) - { - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) - { - $left = substr($file, 0, strlen($removePath)); - if ($left == $removePath) - { - $file = substr($file, strlen($removePath)); - } - } - - $check = '/' . trim($this->dir, '/') . '/' . trim($file, '/'); - - $ret = @ftp_delete($this->handle, $check); - } - - return $ret; - } - - /** - * Create a temporary filename - * - * @param string $filename The original filename - * @param int $perms The file permissions - * - * @return string - */ - public function processFilename($filename, $perms = 0755) - { - // Catch some error conditions... - if ($this->getError()) - { - return false; - } - - // If a null filename is passed, it means that we shouldn't do any post processing, i.e. - // the entity was a directory or symlink - if (is_null($filename)) - { - $this->filename = null; - $this->tempFilename = null; - - return null; - } - - // Strip absolute filesystem path to website's root - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - - if (!empty($removePath)) - { - $left = substr($filename, 0, strlen($removePath)); - - if ($left == $removePath) - { - $filename = substr($filename, strlen($removePath)); - } - } - - // Trim slash on the left - $filename = ltrim($filename, '/'); - - $this->filename = $filename; - $this->tempFilename = tempnam($this->tempDir, 'kickstart-'); - $this->perms = $perms; - - if (empty($this->tempFilename)) - { - // Oops! Let's try something different - $this->tempFilename = $this->tempDir . '/kickstart-' . time() . '.dat'; - } - - return $this->tempFilename; - } - - /** - * Closes the FTP connection - */ - public function close() - { - if (!$this->useFTP) - { - @ftp_close($this->handle); - } - } - - public function chmod($file, $perms) - { - if (AKFactory::get('kickstart.setup.dryrun', '0')) - { - return true; - } - - $ret = @chmod($file, $perms); - - if (!$ret && $this->useFTP) - { - // Strip absolute filesystem path to website's root - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - - if (!empty($removePath)) - { - $left = substr($file, 0, strlen($removePath)); - - if ($left == $removePath) - { - $file = substr($file, strlen($removePath)); - } - } - - // Trim slash on the left - $file = ltrim($file, '/'); - - $ret = @ftp_chmod($this->handle, $perms, $file); - } - - return $ret; - } - - public function rmdir($directory) - { - $ret = @rmdir($directory); - - if (!$ret && $this->useFTP) - { - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) - { - $left = substr($directory, 0, strlen($removePath)); - if ($left == $removePath) - { - $directory = substr($directory, strlen($removePath)); - } - } - - $check = '/' . trim($this->dir, '/') . '/' . trim($directory, '/'); - - $ret = @ftp_rmdir($this->handle, $check); - } - - return $ret; - } - - public function rename($from, $to) - { - $ret = @rename($from, $to); - - if (!$ret && $this->useFTP) - { - $originalFrom = $from; - $originalTo = $to; - - $removePath = AKFactory::get('kickstart.setup.destdir', ''); - if (!empty($removePath)) - { - $left = substr($from, 0, strlen($removePath)); - if ($left == $removePath) - { - $from = substr($from, strlen($removePath)); - } - } - $from = '/' . trim($this->dir, '/') . '/' . trim($from, '/'); - - if (!empty($removePath)) - { - $left = substr($to, 0, strlen($removePath)); - if ($left == $removePath) - { - $to = substr($to, strlen($removePath)); - } - } - $to = '/' . trim($this->dir, '/') . '/' . trim($to, '/'); - - $ret = @ftp_rename($this->handle, $from, $to); - } - - return $ret; - } -} - -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - -/** - * JPA archive extraction class - */ -class AKUnarchiverJPA extends AKAbstractUnarchiver -{ - protected $archiveHeaderData = array(); - - protected function readArchiveHeader() - { - debugMsg('Preparing to read archive header'); - // Initialize header data array - $this->archiveHeaderData = new stdClass(); - - // Open the first part - debugMsg('Opening the first part'); - $this->nextFile(); - - // Fail for unreadable files - if ($this->fp === false) - { - debugMsg('Could not open the first part'); - - return false; - } - - // Read the signature - $sig = fread($this->fp, 3); - - if ($sig != 'JPA') - { - // Not a JPA file - debugMsg('Invalid archive signature'); - $this->setError(AKText::_('ERR_NOT_A_JPA_FILE')); - - return false; - } - - // Read and parse header length - $header_length_array = unpack('v', fread($this->fp, 2)); - $header_length = $header_length_array[1]; - - // Read and parse the known portion of header data (14 bytes) - $bin_data = fread($this->fp, 14); - $header_data = unpack('Cmajor/Cminor/Vcount/Vuncsize/Vcsize', $bin_data); - - // Load any remaining header data (forward compatibility) - $rest_length = $header_length - 19; - - if ($rest_length > 0) - { - $junk = fread($this->fp, $rest_length); - } - else - { - $junk = ''; - } - - // Temporary array with all the data we read - $temp = array( - 'signature' => $sig, - 'length' => $header_length, - 'major' => $header_data['major'], - 'minor' => $header_data['minor'], - 'filecount' => $header_data['count'], - 'uncompressedsize' => $header_data['uncsize'], - 'compressedsize' => $header_data['csize'], - 'unknowndata' => $junk - ); - - // Array-to-object conversion - foreach ($temp as $key => $value) - { - $this->archiveHeaderData->{$key} = $value; - } - - debugMsg('Header data:'); - debugMsg('Length : ' . $header_length); - debugMsg('Major : ' . $header_data['major']); - debugMsg('Minor : ' . $header_data['minor']); - debugMsg('File count : ' . $header_data['count']); - debugMsg('Uncompressed size : ' . $header_data['uncsize']); - debugMsg('Compressed size : ' . $header_data['csize']); - - $this->currentPartOffset = @ftell($this->fp); - - $this->dataReadLength = 0; - - return true; - } - - /** - * Concrete classes must use this method to read the file header - * - * @return bool True if reading the file was successful, false if an error occured or we reached end of archive - */ - protected function readFileHeader() - { - // If the current part is over, proceed to the next part please - if ($this->isEOF(true)) - { - debugMsg('Archive part EOF; moving to next file'); - $this->nextFile(); - } - - $this->currentPartOffset = ftell($this->fp); - - debugMsg("Reading file signature; part {$this->currentPartNumber}, offset {$this->currentPartOffset}"); - // Get and decode Entity Description Block - $signature = fread($this->fp, 3); - - $this->fileHeader = new stdClass(); - $this->fileHeader->timestamp = 0; - - // Check signature - if ($signature != 'JPF') - { - if ($this->isEOF(true)) - { - // This file is finished; make sure it's the last one - $this->nextFile(); - - if (!$this->isEOF(false)) - { - debugMsg('Invalid file signature before end of archive encountered'); - $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); - - return false; - } - - // We're just finished - return false; - } - else - { - $screwed = true; - - if (AKFactory::get('kickstart.setup.ignoreerrors', false)) - { - debugMsg('Invalid file block signature; launching heuristic file block signature scanner'); - $screwed = !$this->heuristicFileHeaderLocator(); - - if (!$screwed) - { - $signature = 'JPF'; - } - else - { - debugMsg('Heuristics failed. Brace yourself for the imminent crash.'); - } - } - - if ($screwed) - { - debugMsg('Invalid file block signature'); - // This is not a file block! The archive is corrupt. - $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); - - return false; - } - } - } - // This a JPA Entity Block. Process the header. - - $isBannedFile = false; - - // Read length of EDB and of the Entity Path Data - $length_array = unpack('vblocksize/vpathsize', fread($this->fp, 4)); - // Read the path data - if ($length_array['pathsize'] > 0) - { - $file = fread($this->fp, $length_array['pathsize']); - } - else - { - $file = ''; - } - - // Handle file renaming - $isRenamed = false; - if (is_array($this->renameFiles) && (count($this->renameFiles) > 0)) - { - if (array_key_exists($file, $this->renameFiles)) - { - $file = $this->renameFiles[$file]; - $isRenamed = true; - } - } - - // Handle directory renaming - $isDirRenamed = false; - if (is_array($this->renameDirs) && (count($this->renameDirs) > 0)) - { - if (array_key_exists(dirname($file), $this->renameDirs)) - { - $file = rtrim($this->renameDirs[dirname($file)], '/') . '/' . basename($file); - $isRenamed = true; - $isDirRenamed = true; - } - } - - // Read and parse the known data portion - $bin_data = fread($this->fp, 14); - $header_data = unpack('Ctype/Ccompression/Vcompsize/Vuncompsize/Vperms', $bin_data); - // Read any unknown data - $restBytes = $length_array['blocksize'] - (21 + $length_array['pathsize']); - - if ($restBytes > 0) - { - // Start reading the extra fields - while ($restBytes >= 4) - { - $extra_header_data = fread($this->fp, 4); - $extra_header = unpack('vsignature/vlength', $extra_header_data); - $restBytes -= 4; - $extra_header['length'] -= 4; - - switch ($extra_header['signature']) - { - case 256: - // File modified timestamp - if ($extra_header['length'] > 0) - { - $bindata = fread($this->fp, $extra_header['length']); - $restBytes -= $extra_header['length']; - $timestamps = unpack('Vmodified', substr($bindata, 0, 4)); - $filectime = $timestamps['modified']; - $this->fileHeader->timestamp = $filectime; - } - break; - - default: - // Unknown field - if ($extra_header['length'] > 0) - { - $junk = fread($this->fp, $extra_header['length']); - $restBytes -= $extra_header['length']; - } - break; - } - } - - if ($restBytes > 0) - { - $junk = fread($this->fp, $restBytes); - } - } - - $compressionType = $header_data['compression']; - - // Populate the return array - $this->fileHeader->file = $file; - $this->fileHeader->compressed = $header_data['compsize']; - $this->fileHeader->uncompressed = $header_data['uncompsize']; - - switch ($header_data['type']) - { - case 0: - $this->fileHeader->type = 'dir'; - break; - - case 1: - $this->fileHeader->type = 'file'; - break; - - case 2: - $this->fileHeader->type = 'link'; - break; - } - - switch ($compressionType) - { - case 0: - $this->fileHeader->compression = 'none'; - break; - case 1: - $this->fileHeader->compression = 'gzip'; - break; - case 2: - $this->fileHeader->compression = 'bzip2'; - break; - } - - $this->fileHeader->permissions = $header_data['perms']; - - // Find hard-coded banned files - if ((basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..")) - { - $isBannedFile = true; - } - - // Also try to find banned files passed in class configuration - if ((count($this->skipFiles) > 0) && (!$isRenamed)) - { - if (in_array($this->fileHeader->file, $this->skipFiles)) - { - $isBannedFile = true; - } - } - - // If we have a banned file, let's skip it - if ($isBannedFile) - { - debugMsg('Skipping file ' . $this->fileHeader->file); - // Advance the file pointer, skipping exactly the size of the compressed data - $seekleft = $this->fileHeader->compressed; - while ($seekleft > 0) - { - // Ensure that we can seek past archive part boundaries - $curSize = @filesize($this->archiveList[$this->currentPartNumber]); - $curPos = @ftell($this->fp); - $canSeek = $curSize - $curPos; - if ($canSeek > $seekleft) - { - $canSeek = $seekleft; - } - @fseek($this->fp, $canSeek, SEEK_CUR); - $seekleft -= $canSeek; - if ($seekleft) - { - $this->nextFile(); - } - } - - $this->currentPartOffset = @ftell($this->fp); - $this->runState = AK_STATE_DONE; - - return true; - } - - // Remove the removePath, if any - $this->fileHeader->file = $this->removePath($this->fileHeader->file); - - // Last chance to prepend a path to the filename - if (!empty($this->addPath) && !$isDirRenamed) - { - $this->fileHeader->file = $this->addPath . $this->fileHeader->file; - } - - // Get the translated path name - $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); - if ($this->fileHeader->type == 'file') - { - // Regular file; ask the postproc engine to process its filename - if ($restorePerms) - { - $this->fileHeader->realFile = - $this->postProcEngine->processFilename($this->fileHeader->file, $this->fileHeader->permissions); - } - else - { - $this->fileHeader->realFile = $this->postProcEngine->processFilename($this->fileHeader->file); - } - } - elseif ($this->fileHeader->type == 'dir') - { - $dir = $this->fileHeader->file; - - // Directory; just create it - if ($restorePerms) - { - $this->postProcEngine->createDirRecursive($this->fileHeader->file, $this->fileHeader->permissions); - } - else - { - $this->postProcEngine->createDirRecursive($this->fileHeader->file, 0755); - } - $this->postProcEngine->processFilename(null); - } - else - { - // Symlink; do not post-process - $this->postProcEngine->processFilename(null); - } - - $this->createDirectory(); - - // Header is read - $this->runState = AK_STATE_HEADER; - - $this->dataReadLength = 0; - - return true; - } - - protected function heuristicFileHeaderLocator() - { - $ret = false; - $fullEOF = false; - - while (!$ret && !$fullEOF) - { - $this->currentPartOffset = @ftell($this->fp); - - if ($this->isEOF(true)) - { - $this->nextFile(); - } - - if ($this->isEOF(false)) - { - $fullEOF = true; - continue; - } - - // Read 512Kb - $chunk = fread($this->fp, 524288); - $size_read = mb_strlen($chunk, '8bit'); - //$pos = strpos($chunk, 'JPF'); - $pos = mb_strpos($chunk, 'JPF', 0, '8bit'); - - if ($pos !== false) - { - // We found it! - $this->currentPartOffset += $pos + 3; - @fseek($this->fp, $this->currentPartOffset, SEEK_SET); - $ret = true; - } - else - { - // Not yet found :( - $this->currentPartOffset = @ftell($this->fp); - } - } - - return $ret; - } - - /** - * Creates the directory this file points to - */ - protected function createDirectory() - { - if (AKFactory::get('kickstart.setup.dryrun', '0')) - { - return true; - } - - // Do we need to create a directory? - if (empty($this->fileHeader->realFile)) - { - $this->fileHeader->realFile = $this->fileHeader->file; - } - - $lastSlash = strrpos($this->fileHeader->realFile, '/'); - $dirName = substr($this->fileHeader->realFile, 0, $lastSlash); - $perms = $this->flagRestorePermissions ? $this->fileHeader->permissions : 0755; - $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($dirName); - - if (($this->postProcEngine->createDirRecursive($dirName, $perms) == false) && (!$ignore)) - { - $this->setError(AKText::sprintf('COULDNT_CREATE_DIR', $dirName)); - - return false; - } - else - { - return true; - } - } - - /** - * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when - * it's finished processing the file data. - * - * @return bool True if processing the file data was successful, false if an error occured - */ - protected function processFileData() - { - switch ($this->fileHeader->type) - { - case 'dir': - return $this->processTypeDir(); - break; - - case 'link': - return $this->processTypeLink(); - break; - - case 'file': - switch ($this->fileHeader->compression) - { - case 'none': - return $this->processTypeFileUncompressed(); - break; - - case 'gzip': - case 'bzip2': - return $this->processTypeFileCompressedSimple(); - break; - - } - break; - - default: - debugMsg('Unknown file type ' . $this->fileHeader->type); - break; - } - } - - /** - * Process the file data of a directory entry - * - * @return bool - */ - private function processTypeDir() - { - // Directory entries in the JPA do not have file data, therefore we're done processing the entry - $this->runState = AK_STATE_DATAREAD; - - return true; - } - - /** - * Process the file data of a link entry - * - * @return bool - */ - private function processTypeLink() - { - $readBytes = 0; - $toReadBytes = 0; - $leftBytes = $this->fileHeader->compressed; - $data = ''; - - while ($leftBytes > 0) - { - $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; - $mydata = $this->fread($this->fp, $toReadBytes); - $reallyReadBytes = akstringlen($mydata); - $data .= $mydata; - $leftBytes -= $reallyReadBytes; - - if ($reallyReadBytes < $toReadBytes) - { - // We read less than requested! Why? Did we hit local EOF? - if ($this->isEOF(true) && !$this->isEOF(false)) - { - // Yeap. Let's go to the next file - $this->nextFile(); - } - else - { - debugMsg('End of local file before reading all data with no more parts left. The archive is corrupt or truncated.'); - // Nope. The archive is corrupt - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; - } - } - } - - $filename = isset($this->fileHeader->realFile) ? $this->fileHeader->realFile : $this->fileHeader->file; - - if (!AKFactory::get('kickstart.setup.dryrun', '0')) - { - // Try to remove an existing file or directory by the same name - if (file_exists($filename)) - { - @unlink($filename); - @rmdir($filename); - } - - // Remove any trailing slash - if (substr($filename, -1) == '/') - { - $filename = substr($filename, 0, -1); - } - // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :( - @symlink($data, $filename); - } - - $this->runState = AK_STATE_DATAREAD; - - return true; // No matter if the link was created! - } - - private function processTypeFileUncompressed() - { - // Uncompressed files are being processed in small chunks, to avoid timeouts - if (($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun', '0')) - { - // Before processing file data, ensure permissions are adequate - $this->setCorrectPermissions($this->fileHeader->file); - } - - // Open the output file - if (!AKFactory::get('kickstart.setup.dryrun', '0')) - { - $ignore = - AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); - - if ($this->dataReadLength == 0) - { - $outfp = @fopen($this->fileHeader->realFile, 'wb'); - } - else - { - $outfp = @fopen($this->fileHeader->realFile, 'ab'); - } - - // Can we write to the file? - if (($outfp === false) && (!$ignore)) - { - // An error occured - debugMsg('Could not write to output file'); - $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); - - return false; - } - } - - // Does the file have any data, at all? - if ($this->fileHeader->compressed == 0) - { - // No file data! - if (!AKFactory::get('kickstart.setup.dryrun', '0') && is_resource($outfp)) - { - @fclose($outfp); - } - - $this->runState = AK_STATE_DATAREAD; - - return true; - } - - // Reference to the global timer - $timer = AKFactory::getTimer(); - - $toReadBytes = 0; - $leftBytes = $this->fileHeader->compressed - $this->dataReadLength; - - // Loop while there's data to read and enough time to do it - while (($leftBytes > 0) && ($timer->getTimeLeft() > 0)) - { - $toReadBytes = ($leftBytes > $this->chunkSize) ? $this->chunkSize : $leftBytes; - $data = $this->fread($this->fp, $toReadBytes); - $reallyReadBytes = akstringlen($data); - $leftBytes -= $reallyReadBytes; - $this->dataReadLength += $reallyReadBytes; - - if ($reallyReadBytes < $toReadBytes) - { - // We read less than requested! Why? Did we hit local EOF? - if ($this->isEOF(true) && !$this->isEOF(false)) - { - // Yeap. Let's go to the next file - $this->nextFile(); - } - else - { - // Nope. The archive is corrupt - debugMsg('Not enough data in file. The archive is truncated or corrupt.'); - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; - } - } - - if (!AKFactory::get('kickstart.setup.dryrun', '0')) - { - if (is_resource($outfp)) - { - @fwrite($outfp, $data); - } - } - } - - // Close the file pointer - if (!AKFactory::get('kickstart.setup.dryrun', '0')) - { - if (is_resource($outfp)) - { - @fclose($outfp); - } - } - - // Was this a pre-timeout bail out? - if ($leftBytes > 0) - { - $this->runState = AK_STATE_DATA; - } - else - { - // Oh! We just finished! - $this->runState = AK_STATE_DATAREAD; - $this->dataReadLength = 0; - } - - return true; - } - - private function processTypeFileCompressedSimple() - { - if (!AKFactory::get('kickstart.setup.dryrun', '0')) - { - // Before processing file data, ensure permissions are adequate - $this->setCorrectPermissions($this->fileHeader->file); - - // Open the output file - $outfp = @fopen($this->fileHeader->realFile, 'wb'); - - // Can we write to the file? - $ignore = - AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); - - if (($outfp === false) && (!$ignore)) - { - // An error occured - debugMsg('Could not write to output file'); - $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); - - return false; - } - } - - // Does the file have any data, at all? - if ($this->fileHeader->compressed == 0) - { - // No file data! - if (!AKFactory::get('kickstart.setup.dryrun', '0')) - { - if (is_resource($outfp)) - { - @fclose($outfp); - } - } - $this->runState = AK_STATE_DATAREAD; - - return true; - } - - // Simple compressed files are processed as a whole; we can't do chunk processing - $zipData = $this->fread($this->fp, $this->fileHeader->compressed); - while (akstringlen($zipData) < $this->fileHeader->compressed) - { - // End of local file before reading all data, but have more archive parts? - if ($this->isEOF(true) && !$this->isEOF(false)) - { - // Yeap. Read from the next file - $this->nextFile(); - $bytes_left = $this->fileHeader->compressed - akstringlen($zipData); - $zipData .= $this->fread($this->fp, $bytes_left); - } - else - { - debugMsg('End of local file before reading all data with no more parts left. The archive is corrupt or truncated.'); - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; - } - } - - if ($this->fileHeader->compression == 'gzip') - { - $unzipData = gzinflate($zipData); - } - elseif ($this->fileHeader->compression == 'bzip2') - { - $unzipData = bzdecompress($zipData); - } - unset($zipData); - - // Write to the file. - if (!AKFactory::get('kickstart.setup.dryrun', '0') && is_resource($outfp)) - { - @fwrite($outfp, $unzipData, $this->fileHeader->uncompressed); - @fclose($outfp); - } - unset($unzipData); - - $this->runState = AK_STATE_DATAREAD; - - return true; - } -} - -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - -/** - * ZIP archive extraction class - * - * Since the file data portion of ZIP and JPA are similarly structured (it's empty for dirs, - * linked node name for symlinks, dumped binary data for no compressions and dumped gzipped - * binary data for gzip compression) we just have to subclass AKUnarchiverJPA and change the - * header reading bits. Reusable code ;) - */ -class AKUnarchiverZIP extends AKUnarchiverJPA -{ - var $expectDataDescriptor = false; - - protected function readArchiveHeader() - { - debugMsg('Preparing to read archive header'); - // Initialize header data array - $this->archiveHeaderData = new stdClass(); - - // Open the first part - debugMsg('Opening the first part'); - $this->nextFile(); - - // Fail for unreadable files - if ($this->fp === false) - { - debugMsg('The first part is not readable'); - - return false; - } - - // Read a possible multipart signature - $sigBinary = fread($this->fp, 4); - $headerData = unpack('Vsig', $sigBinary); - - // Roll back if it's not a multipart archive - if ($headerData['sig'] == 0x04034b50) - { - debugMsg('The archive is not multipart'); - fseek($this->fp, -4, SEEK_CUR); - } - else - { - debugMsg('The archive is multipart'); - } - - $multiPartSigs = array( - 0x08074b50, // Multi-part ZIP - 0x30304b50, // Multi-part ZIP (alternate) - 0x04034b50 // Single file - ); - if (!in_array($headerData['sig'], $multiPartSigs)) - { - debugMsg('Invalid header signature ' . dechex($headerData['sig'])); - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; - } - - $this->currentPartOffset = @ftell($this->fp); - debugMsg('Current part offset after reading header: ' . $this->currentPartOffset); - - $this->dataReadLength = 0; - - return true; - } - - /** - * Concrete classes must use this method to read the file header - * - * @return bool True if reading the file was successful, false if an error occured or we reached end of archive - */ - protected function readFileHeader() - { - // If the current part is over, proceed to the next part please - if ($this->isEOF(true)) - { - debugMsg('Opening next archive part'); - $this->nextFile(); - } - - $this->currentPartOffset = ftell($this->fp); - - if ($this->expectDataDescriptor) - { - // The last file had bit 3 of the general purpose bit flag set. This means that we have a - // 12 byte data descriptor we need to skip. To make things worse, there might also be a 4 - // byte optional data descriptor header (0x08074b50). - $junk = @fread($this->fp, 4); - $junk = unpack('Vsig', $junk); - if ($junk['sig'] == 0x08074b50) - { - // Yes, there was a signature - $junk = @fread($this->fp, 12); - debugMsg('Data descriptor (w/ header) skipped at ' . (ftell($this->fp) - 12)); - } - else - { - // No, there was no signature, just read another 8 bytes - $junk = @fread($this->fp, 8); - debugMsg('Data descriptor (w/out header) skipped at ' . (ftell($this->fp) - 8)); - } - - // And check for EOF, too - if ($this->isEOF(true)) - { - debugMsg('EOF before reading header'); - - $this->nextFile(); - } - } - - // Get and decode Local File Header - $headerBinary = fread($this->fp, 30); - $headerData = - unpack('Vsig/C2ver/vbitflag/vcompmethod/vlastmodtime/vlastmoddate/Vcrc/Vcompsize/Vuncomp/vfnamelen/veflen', $headerBinary); - - // Check signature - if (!($headerData['sig'] == 0x04034b50)) - { - debugMsg('Not a file signature at ' . (ftell($this->fp) - 4)); - - // The signature is not the one used for files. Is this a central directory record (i.e. we're done)? - if ($headerData['sig'] == 0x02014b50) - { - debugMsg('EOCD signature at ' . (ftell($this->fp) - 4)); - // End of ZIP file detected. We'll just skip to the end of file... - while ($this->nextFile()) - { - }; - @fseek($this->fp, 0, SEEK_END); // Go to EOF - return false; - } - else - { - debugMsg('Invalid signature ' . dechex($headerData['sig']) . ' at ' . ftell($this->fp)); - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; - } - } - - // If bit 3 of the bitflag is set, expectDataDescriptor is true - $this->expectDataDescriptor = ($headerData['bitflag'] & 4) == 4; - - $this->fileHeader = new stdClass(); - $this->fileHeader->timestamp = 0; - - // Read the last modified data and time - $lastmodtime = $headerData['lastmodtime']; - $lastmoddate = $headerData['lastmoddate']; - - if ($lastmoddate && $lastmodtime) - { - // ----- Extract time - $v_hour = ($lastmodtime & 0xF800) >> 11; - $v_minute = ($lastmodtime & 0x07E0) >> 5; - $v_seconde = ($lastmodtime & 0x001F) * 2; - - // ----- Extract date - $v_year = (($lastmoddate & 0xFE00) >> 9) + 1980; - $v_month = ($lastmoddate & 0x01E0) >> 5; - $v_day = $lastmoddate & 0x001F; - - // ----- Get UNIX date format - $this->fileHeader->timestamp = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); - } - - $isBannedFile = false; - - $this->fileHeader->compressed = $headerData['compsize']; - $this->fileHeader->uncompressed = $headerData['uncomp']; - $nameFieldLength = $headerData['fnamelen']; - $extraFieldLength = $headerData['eflen']; - - // Read filename field - $this->fileHeader->file = fread($this->fp, $nameFieldLength); - - // Handle file renaming - $isRenamed = false; - if (is_array($this->renameFiles) && (count($this->renameFiles) > 0)) - { - if (array_key_exists($this->fileHeader->file, $this->renameFiles)) - { - $this->fileHeader->file = $this->renameFiles[$this->fileHeader->file]; - $isRenamed = true; - } - } - - // Handle directory renaming - $isDirRenamed = false; - if (is_array($this->renameDirs) && (count($this->renameDirs) > 0)) - { - if (array_key_exists(dirname($this->fileHeader->file), $this->renameDirs)) - { - $file = - rtrim($this->renameDirs[dirname($this->fileHeader->file)], '/') . '/' . basename($this->fileHeader->file); - $isRenamed = true; - $isDirRenamed = true; - } - } - - // Read extra field if present - if ($extraFieldLength > 0) - { - $extrafield = fread($this->fp, $extraFieldLength); - } - - debugMsg('*' . ftell($this->fp) . ' IS START OF ' . $this->fileHeader->file . ' (' . $this->fileHeader->compressed . ' bytes)'); - - - // Decide filetype -- Check for directories - $this->fileHeader->type = 'file'; - if (strrpos($this->fileHeader->file, '/') == strlen($this->fileHeader->file) - 1) - { - $this->fileHeader->type = 'dir'; - } - // Decide filetype -- Check for symbolic links - if (($headerData['ver1'] == 10) && ($headerData['ver2'] == 3)) - { - $this->fileHeader->type = 'link'; - } - - switch ($headerData['compmethod']) - { - case 0: - $this->fileHeader->compression = 'none'; - break; - case 8: - $this->fileHeader->compression = 'gzip'; - break; - } - - // Find hard-coded banned files - if ((basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..")) - { - $isBannedFile = true; - } - - // Also try to find banned files passed in class configuration - if ((count($this->skipFiles) > 0) && (!$isRenamed)) - { - if (in_array($this->fileHeader->file, $this->skipFiles)) - { - $isBannedFile = true; - } - } - - // If we have a banned file, let's skip it - if ($isBannedFile) - { - // Advance the file pointer, skipping exactly the size of the compressed data - $seekleft = $this->fileHeader->compressed; - while ($seekleft > 0) - { - // Ensure that we can seek past archive part boundaries - $curSize = @filesize($this->archiveList[$this->currentPartNumber]); - $curPos = @ftell($this->fp); - $canSeek = $curSize - $curPos; - if ($canSeek > $seekleft) - { - $canSeek = $seekleft; - } - @fseek($this->fp, $canSeek, SEEK_CUR); - $seekleft -= $canSeek; - if ($seekleft) - { - $this->nextFile(); - } - } - - $this->currentPartOffset = @ftell($this->fp); - $this->runState = AK_STATE_DONE; - - return true; - } - - // Remove the removePath, if any - $this->fileHeader->file = $this->removePath($this->fileHeader->file); - - // Last chance to prepend a path to the filename - if (!empty($this->addPath) && !$isDirRenamed) - { - $this->fileHeader->file = $this->addPath . $this->fileHeader->file; - } - - // Get the translated path name - if ($this->fileHeader->type == 'file') - { - $this->fileHeader->realFile = $this->postProcEngine->processFilename($this->fileHeader->file); - } - elseif ($this->fileHeader->type == 'dir') - { - $this->fileHeader->timestamp = 0; - - $dir = $this->fileHeader->file; - - $this->postProcEngine->createDirRecursive($this->fileHeader->file, 0755); - $this->postProcEngine->processFilename(null); - } - else - { - // Symlink; do not post-process - $this->fileHeader->timestamp = 0; - $this->postProcEngine->processFilename(null); - } - - $this->createDirectory(); - - // Header is read - $this->runState = AK_STATE_HEADER; - - return true; - } - -} - -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - -/** - * JPS archive extraction class - */ -class AKUnarchiverJPS extends AKUnarchiverJPA -{ - protected $archiveHeaderData = array(); - - protected $password = ''; - - public function __construct() - { - parent::__construct(); - - $this->password = AKFactory::get('kickstart.jps.password', ''); - } - - protected function readArchiveHeader() - { - // Initialize header data array - $this->archiveHeaderData = new stdClass(); - - // Open the first part - $this->nextFile(); - - // Fail for unreadable files - if ($this->fp === false) - { - return false; - } - - // Read the signature - $sig = fread($this->fp, 3); - - if ($sig != 'JPS') - { - // Not a JPA file - $this->setError(AKText::_('ERR_NOT_A_JPS_FILE')); - - return false; - } - - // Read and parse the known portion of header data (5 bytes) - $bin_data = fread($this->fp, 5); - $header_data = unpack('Cmajor/Cminor/cspanned/vextra', $bin_data); - - // Load any remaining header data (forward compatibility) - $rest_length = $header_data['extra']; - if ($rest_length > 0) - { - $junk = fread($this->fp, $rest_length); - } - else - { - $junk = ''; - } - - // Temporary array with all the data we read - $temp = array( - 'signature' => $sig, - 'major' => $header_data['major'], - 'minor' => $header_data['minor'], - 'spanned' => $header_data['spanned'] - ); - // Array-to-object conversion - foreach ($temp as $key => $value) - { - $this->archiveHeaderData->{$key} = $value; - } - - $this->currentPartOffset = @ftell($this->fp); - - $this->dataReadLength = 0; - return true; } - /** - * Concrete classes must use this method to read the file header - * - * @return bool True if reading the file was successful, false if an error occured or we reached end of archive - */ - protected function readFileHeader() + private function processTypeFileCompressedSimple() { - // If the current part is over, proceed to the next part please - if ($this->isEOF(true)) - { - $this->nextFile(); - } - - $this->currentPartOffset = ftell($this->fp); - - // Get and decode Entity Description Block - $signature = fread($this->fp, 3); - - // Check for end-of-archive siganture - if ($signature == 'JPE') - { - $this->setState('postrun'); - - return true; - } - - $this->fileHeader = new stdClass(); - $this->fileHeader->timestamp = 0; - - // Check signature - if ($signature != 'JPF') - { - if ($this->isEOF(true)) - { - // This file is finished; make sure it's the last one - $this->nextFile(); - if (!$this->isEOF(false)) - { - $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); - - return false; - } - - // We're just finished - return false; - } - else - { - fseek($this->fp, -6, SEEK_CUR); - $signature = fread($this->fp, 3); - if ($signature == 'JPE') - { - return false; - } - - $this->setError(AKText::sprintf('INVALID_FILE_HEADER', $this->currentPartNumber, $this->currentPartOffset)); - - return false; - } - } - // This a JPA Entity Block. Process the header. - - $isBannedFile = false; - - // Read and decrypt the header - $edbhData = fread($this->fp, 4); - $edbh = unpack('vencsize/vdecsize', $edbhData); - $bin_data = fread($this->fp, $edbh['encsize']); - - // Decrypt and truncate - $bin_data = AKEncryptionAES::AESDecryptCBC($bin_data, $this->password, 128); - $bin_data = substr($bin_data, 0, $edbh['decsize']); - - // Read length of EDB and of the Entity Path Data - $length_array = unpack('vpathsize', substr($bin_data, 0, 2)); - // Read the path data - $file = substr($bin_data, 2, $length_array['pathsize']); - - // Handle file renaming - $isRenamed = false; - if (is_array($this->renameFiles) && (count($this->renameFiles) > 0)) - { - if (array_key_exists($file, $this->renameFiles)) - { - $file = $this->renameFiles[$file]; - $isRenamed = true; - } - } - - // Handle directory renaming - $isDirRenamed = false; - if (is_array($this->renameDirs) && (count($this->renameDirs) > 0)) - { - if (array_key_exists(dirname($file), $this->renameDirs)) - { - $file = rtrim($this->renameDirs[dirname($file)], '/') . '/' . basename($file); - $isRenamed = true; - $isDirRenamed = true; - } - } - - // Read and parse the known data portion - $bin_data = substr($bin_data, 2 + $length_array['pathsize']); - $header_data = unpack('Ctype/Ccompression/Vuncompsize/Vperms/Vfilectime', $bin_data); - - $this->fileHeader->timestamp = $header_data['filectime']; - $compressionType = $header_data['compression']; - - // Populate the return array - $this->fileHeader->file = $file; - $this->fileHeader->uncompressed = $header_data['uncompsize']; - switch ($header_data['type']) + if (!AKFactory::get('kickstart.setup.dryrun', '0')) { - case 0: - $this->fileHeader->type = 'dir'; - break; - - case 1: - $this->fileHeader->type = 'file'; - break; + // Before processing file data, ensure permissions are adequate + $this->setCorrectPermissions($this->fileHeader->file); - case 2: - $this->fileHeader->type = 'link'; - break; - } - switch ($compressionType) - { - case 0: - $this->fileHeader->compression = 'none'; - break; - case 1: - $this->fileHeader->compression = 'gzip'; - break; - case 2: - $this->fileHeader->compression = 'bzip2'; - break; - } - $this->fileHeader->permissions = $header_data['perms']; + // Open the output file + $outfp = @fopen($this->fileHeader->realFile, 'wb'); - // Find hard-coded banned files - if ((basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..")) - { - $isBannedFile = true; - } + // Can we write to the file? + $ignore = + AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); - // Also try to find banned files passed in class configuration - if ((count($this->skipFiles) > 0) && (!$isRenamed)) - { - if (in_array($this->fileHeader->file, $this->skipFiles)) + if (($outfp === false) && (!$ignore)) { - $isBannedFile = true; + // An error occurred + debugMsg('Could not write to output file'); + $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); + + return false; } } - // If we have a banned file, let's skip it - if ($isBannedFile) + // Does the file have any data, at all? + if ($this->fileHeader->compressed == 0) { - $done = false; - while (!$done) + // No file data! + if (!AKFactory::get('kickstart.setup.dryrun', '0')) { - // Read the Data Chunk Block header - $binMiniHead = fread($this->fp, 8); - if (in_array(substr($binMiniHead, 0, 3), array('JPF', 'JPE'))) - { - // Not a Data Chunk Block header, I am done skipping the file - @fseek($this->fp, -8, SEEK_CUR); // Roll back the file pointer - $done = true; // Mark as done - continue; // Exit loop - } - else + if (is_resource($outfp)) { - // Skip forward by the amount of compressed data - $miniHead = unpack('Vencsize/Vdecsize', $binMiniHead); - @fseek($this->fp, $miniHead['encsize'], SEEK_CUR); + @fclose($outfp); } } - - $this->currentPartOffset = @ftell($this->fp); - $this->runState = AK_STATE_DONE; + $this->runState = AK_STATE_DATAREAD; return true; } - // Remove the removePath, if any - $this->fileHeader->file = $this->removePath($this->fileHeader->file); - - // Last chance to prepend a path to the filename - if (!empty($this->addPath) && !$isDirRenamed) - { - $this->fileHeader->file = $this->addPath . $this->fileHeader->file; - } - - // Get the translated path name - $restorePerms = AKFactory::get('kickstart.setup.restoreperms', false); - if ($this->fileHeader->type == 'file') + // Simple compressed files are processed as a whole; we can't do chunk processing + $zipData = $this->fread($this->fp, $this->fileHeader->compressed); + while (akstringlen($zipData) < $this->fileHeader->compressed) { - // Regular file; ask the postproc engine to process its filename - if ($restorePerms) + // End of local file before reading all data, but have more archive parts? + if ($this->isEOF(true) && !$this->isEOF(false)) { - $this->fileHeader->realFile = - $this->postProcEngine->processFilename($this->fileHeader->file, $this->fileHeader->permissions); + // Yeap. Read from the next file + $this->nextFile(); + $bytes_left = $this->fileHeader->compressed - akstringlen($zipData); + $zipData .= $this->fread($this->fp, $bytes_left); } else { - $this->fileHeader->realFile = $this->postProcEngine->processFilename($this->fileHeader->file); + debugMsg('End of local file before reading all data with no more parts left. The archive is corrupt or truncated.'); + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + + return false; } } - elseif ($this->fileHeader->type == 'dir') - { - $dir = $this->fileHeader->file; - $this->fileHeader->realFile = $dir; - // Directory; just create it - if ($restorePerms) - { - $this->postProcEngine->createDirRecursive($this->fileHeader->file, $this->fileHeader->permissions); - } - else - { - $this->postProcEngine->createDirRecursive($this->fileHeader->file, 0755); - } - $this->postProcEngine->processFilename(null); + if ($this->fileHeader->compression == 'gzip') + { + $unzipData = gzinflate($zipData); } - else + elseif ($this->fileHeader->compression == 'bzip2') { - // Symlink; do not post-process - $this->postProcEngine->processFilename(null); + $unzipData = bzdecompress($zipData); } + unset($zipData); - $this->createDirectory(); - - // Header is read - $this->runState = AK_STATE_HEADER; + // Write to the file. + if (!AKFactory::get('kickstart.setup.dryrun', '0') && is_resource($outfp)) + { + @fwrite($outfp, $unzipData, $this->fileHeader->uncompressed); + @fclose($outfp); + } + unset($unzipData); - $this->dataReadLength = 0; + $this->runState = AK_STATE_DATAREAD; return true; } +} - /** - * Creates the directory this file points to - */ - protected function createDirectory() +/** + * ZIP archive extraction class + * + * Since the file data portion of ZIP and JPA are similarly structured (it's empty for dirs, + * linked node name for symlinks, dumped binary data for no compressions and dumped gzipped + * binary data for gzip compression) we just have to subclass AKUnarchiverJPA and change the + * header reading bits. Reusable code ;) + */ +class AKUnarchiverZIP extends AKUnarchiverJPA +{ + var $expectDataDescriptor = false; + + protected function readArchiveHeader() { - if (AKFactory::get('kickstart.setup.dryrun', '0')) - { - return true; - } + debugMsg('Preparing to read archive header'); + // Initialize header data array + $this->archiveHeaderData = new stdClass(); - // Do we need to create a directory? - $lastSlash = strrpos($this->fileHeader->realFile, '/'); - $dirName = substr($this->fileHeader->realFile, 0, $lastSlash); - $perms = $this->flagRestorePermissions ? $retArray['permissions'] : 0755; - $ignore = AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($dirName); - if (($this->postProcEngine->createDirRecursive($dirName, $perms) == false) && (!$ignore)) + // Open the first part + debugMsg('Opening the first part'); + $this->nextFile(); + + // Fail for unreadable files + if ($this->fp === false) { - $this->setError(AKText::sprintf('COULDNT_CREATE_DIR', $dirName)); + debugMsg('The first part is not readable'); return false; } + + // Read a possible multipart signature + $sigBinary = fread($this->fp, 4); + $headerData = unpack('Vsig', $sigBinary); + + // Roll back if it's not a multipart archive + if ($headerData['sig'] == 0x04034b50) + { + debugMsg('The archive is not multipart'); + fseek($this->fp, -4, SEEK_CUR); + } else { - return true; + debugMsg('The archive is multipart'); } - } - /** - * Concrete classes must use this method to process file data. It must set $runState to AK_STATE_DATAREAD when - * it's finished processing the file data. - * - * @return bool True if processing the file data was successful, false if an error occured - */ - protected function processFileData() - { - switch ($this->fileHeader->type) + $multiPartSigs = array( + 0x08074b50, // Multi-part ZIP + 0x30304b50, // Multi-part ZIP (alternate) + 0x04034b50 // Single file + ); + if (!in_array($headerData['sig'], $multiPartSigs)) { - case 'dir': - return $this->processTypeDir(); - break; - - case 'link': - return $this->processTypeLink(); - break; - - case 'file': - switch ($this->fileHeader->compression) - { - case 'none': - return $this->processTypeFileUncompressed(); - break; - - case 'gzip': - case 'bzip2': - return $this->processTypeFileCompressedSimple(); - break; + debugMsg('Invalid header signature ' . dechex($headerData['sig'])); + $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - } - break; + return false; } - } - /** - * Process the file data of a directory entry - * - * @return bool - */ - private function processTypeDir() - { - // Directory entries in the JPA do not have file data, therefore we're done processing the entry - $this->runState = AK_STATE_DATAREAD; + $this->currentPartOffset = @ftell($this->fp); + debugMsg('Current part offset after reading header: ' . $this->currentPartOffset); + + $this->dataReadLength = 0; return true; } /** - * Process the file data of a link entry + * Concrete classes must use this method to read the file header * - * @return bool + * @return bool True if reading the file was successful, false if an error occurred or we reached end of archive */ - private function processTypeLink() + protected function readFileHeader() { - - // Does the file have any data, at all? - if ($this->fileHeader->uncompressed == 0) + // If the current part is over, proceed to the next part please + if ($this->isEOF(true)) { - // No file data! - $this->runState = AK_STATE_DATAREAD; - - return true; + debugMsg('Opening next archive part'); + $this->nextFile(); } - // Read the mini header - $binMiniHeader = fread($this->fp, 8); - $reallyReadBytes = akstringlen($binMiniHeader); - if ($reallyReadBytes < 8) + $this->currentPartOffset = ftell($this->fp); + + if ($this->expectDataDescriptor) { - // We read less than requested! Why? Did we hit local EOF? - if ($this->isEOF(true) && !$this->isEOF(false)) + // The last file had bit 3 of the general purpose bit flag set. This means that we have a + // 12 byte data descriptor we need to skip. To make things worse, there might also be a 4 + // byte optional data descriptor header (0x08074b50). + $junk = @fread($this->fp, 4); + $junk = unpack('Vsig', $junk); + if ($junk['sig'] == 0x08074b50) { - // Yeap. Let's go to the next file - $this->nextFile(); - // Retry reading the header - $binMiniHeader = fread($this->fp, 8); - $reallyReadBytes = akstringlen($binMiniHeader); - // Still not enough data? If so, the archive is corrupt or missing parts. - if ($reallyReadBytes < 8) - { - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; - } + // Yes, there was a signature + $junk = @fread($this->fp, 12); + debugMsg('Data descriptor (w/ header) skipped at ' . (ftell($this->fp) - 12)); } else { - // Nope. The archive is corrupt - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); + // No, there was no signature, just read another 8 bytes + $junk = @fread($this->fp, 8); + debugMsg('Data descriptor (w/out header) skipped at ' . (ftell($this->fp) - 8)); + } - return false; + // And check for EOF, too + if ($this->isEOF(true)) + { + debugMsg('EOF before reading header'); + + $this->nextFile(); } } - // Read the encrypted data - $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader); - $toReadBytes = $miniHeader['encsize']; - $data = $this->fread($this->fp, $toReadBytes); - $reallyReadBytes = akstringlen($data); - if ($reallyReadBytes < $toReadBytes) + // Get and decode Local File Header + $headerBinary = fread($this->fp, 30); + $headerData = + unpack('Vsig/C2ver/vbitflag/vcompmethod/vlastmodtime/vlastmoddate/Vcrc/Vcompsize/Vuncomp/vfnamelen/veflen', $headerBinary); + + // Check signature + if (!($headerData['sig'] == 0x04034b50)) { - // We read less than requested! Why? Did we hit local EOF? - if ($this->isEOF(true) && !$this->isEOF(false)) + debugMsg('Not a file signature at ' . (ftell($this->fp) - 4)); + + // The signature is not the one used for files. Is this a central directory record (i.e. we're done)? + if ($headerData['sig'] == 0x02014b50) { - // Yeap. Let's go to the next file - $this->nextFile(); - // Read the rest of the data - $toReadBytes -= $reallyReadBytes; - $restData = $this->fread($this->fp, $toReadBytes); - $reallyReadBytes = akstringlen($data); - if ($reallyReadBytes < $toReadBytes) + debugMsg('EOCD signature at ' . (ftell($this->fp) - 4)); + // End of ZIP file detected. We'll just skip to the end of file... + while ($this->nextFile()) { - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; } - $data .= $restData; + @fseek($this->fp, 0, SEEK_END); // Go to EOF + return false; } else { - // Nope. The archive is corrupt + debugMsg('Invalid signature ' . dechex($headerData['sig']) . ' at ' . ftell($this->fp)); $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); return false; } } - // Decrypt the data - $data = AKEncryptionAES::AESDecryptCBC($data, $this->password, 128); - - // Is the length of the decrypted data less than expected? - $data_length = akstringlen($data); - if ($data_length < $miniHeader['decsize']) - { - $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD')); + // If bit 3 of the bitflag is set, expectDataDescriptor is true + $this->expectDataDescriptor = ($headerData['bitflag'] & 4) == 4; - return false; - } + $this->fileHeader = new stdClass(); + $this->fileHeader->timestamp = 0; - // Trim the data - $data = substr($data, 0, $miniHeader['decsize']); + // Read the last modified data and time + $lastmodtime = $headerData['lastmodtime']; + $lastmoddate = $headerData['lastmoddate']; - if (!AKFactory::get('kickstart.setup.dryrun', '0')) + if ($lastmoddate && $lastmodtime) { - // Try to remove an existing file or directory by the same name - if (file_exists($this->fileHeader->file)) - { - @unlink($this->fileHeader->file); - @rmdir($this->fileHeader->file); - } - // Remove any trailing slash - if (substr($this->fileHeader->file, -1) == '/') - { - $this->fileHeader->file = substr($this->fileHeader->file, 0, -1); - } - // Create the symlink - only possible within PHP context. There's no support built in the FTP protocol, so no postproc use is possible here :( - @symlink($data, $this->fileHeader->file); + // ----- Extract time + $v_hour = ($lastmodtime & 0xF800) >> 11; + $v_minute = ($lastmodtime & 0x07E0) >> 5; + $v_seconde = ($lastmodtime & 0x001F) * 2; + + // ----- Extract date + $v_year = (($lastmoddate & 0xFE00) >> 9) + 1980; + $v_month = ($lastmoddate & 0x01E0) >> 5; + $v_day = $lastmoddate & 0x001F; + + // ----- Get UNIX date format + $this->fileHeader->timestamp = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); } - $this->runState = AK_STATE_DATAREAD; + $isBannedFile = false; - return true; // No matter if the link was created! - } + $this->fileHeader->compressed = $headerData['compsize']; + $this->fileHeader->uncompressed = $headerData['uncomp']; + $nameFieldLength = $headerData['fnamelen']; + $extraFieldLength = $headerData['eflen']; - private function processTypeFileUncompressed() - { - // Uncompressed files are being processed in small chunks, to avoid timeouts - if (($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun', '0')) - { - // Before processing file data, ensure permissions are adequate - $this->setCorrectPermissions($this->fileHeader->file); - } + // Read filename field + $this->fileHeader->file = fread($this->fp, $nameFieldLength); - // Open the output file - if (!AKFactory::get('kickstart.setup.dryrun', '0')) + // Handle file renaming + $isRenamed = false; + if (is_array($this->renameFiles) && (count($this->renameFiles) > 0)) { - $ignore = - AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); - if ($this->dataReadLength == 0) - { - $outfp = @fopen($this->fileHeader->realFile, 'wb'); - } - else - { - $outfp = @fopen($this->fileHeader->realFile, 'ab'); - } - - // Can we write to the file? - if (($outfp === false) && (!$ignore)) + if (array_key_exists($this->fileHeader->file, $this->renameFiles)) { - // An error occured - $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); - - return false; + $this->fileHeader->file = $this->renameFiles[$this->fileHeader->file]; + $isRenamed = true; } } - // Does the file have any data, at all? - if ($this->fileHeader->uncompressed == 0) + // Handle directory renaming + $isDirRenamed = false; + if (is_array($this->renameDirs) && (count($this->renameDirs) > 0)) { - // No file data! - if (!AKFactory::get('kickstart.setup.dryrun', '0') && is_resource($outfp)) + if (array_key_exists(dirname($this->fileHeader->file), $this->renameDirs)) { - @fclose($outfp); + $file = + rtrim($this->renameDirs[dirname($this->fileHeader->file)], '/') . '/' . basename($this->fileHeader->file); + $isRenamed = true; + $isDirRenamed = true; } - $this->runState = AK_STATE_DATAREAD; - - return true; } - else - { - $this->setError('An uncompressed file was detected; this is not supported by this archive extraction utility'); - return false; + // Read extra field if present + if ($extraFieldLength > 0) + { + $extrafield = fread($this->fp, $extraFieldLength); } - return true; - } + debugMsg('*' . ftell($this->fp) . ' IS START OF ' . $this->fileHeader->file . ' (' . $this->fileHeader->compressed . ' bytes)'); - private function processTypeFileCompressedSimple() - { - $timer = AKFactory::getTimer(); - // Files are being processed in small chunks, to avoid timeouts - if (($this->dataReadLength == 0) && !AKFactory::get('kickstart.setup.dryrun', '0')) + // Decide filetype -- Check for directories + $this->fileHeader->type = 'file'; + if (strrpos($this->fileHeader->file, '/') == strlen($this->fileHeader->file) - 1) { - // Before processing file data, ensure permissions are adequate - $this->setCorrectPermissions($this->fileHeader->file); + $this->fileHeader->type = 'dir'; } - - // Open the output file - if (!AKFactory::get('kickstart.setup.dryrun', '0')) + // Decide filetype -- Check for symbolic links + if (($headerData['ver1'] == 10) && ($headerData['ver2'] == 3)) { - // Open the output file - $outfp = @fopen($this->fileHeader->realFile, 'wb'); + $this->fileHeader->type = 'link'; + } - // Can we write to the file? - $ignore = - AKFactory::get('kickstart.setup.ignoreerrors', false) || $this->isIgnoredDirectory($this->fileHeader->file); - if (($outfp === false) && (!$ignore)) - { - // An error occured - $this->setError(AKText::sprintf('COULDNT_WRITE_FILE', $this->fileHeader->realFile)); + switch ($headerData['compmethod']) + { + case 0: + $this->fileHeader->compression = 'none'; + break; + case 8: + $this->fileHeader->compression = 'gzip'; + break; + } - return false; - } + // Find hard-coded banned files + if ((basename($this->fileHeader->file) == ".") || (basename($this->fileHeader->file) == "..")) + { + $isBannedFile = true; } - // Does the file have any data, at all? - if ($this->fileHeader->uncompressed == 0) + // Also try to find banned files passed in class configuration + if ((count($this->skipFiles) > 0) && (!$isRenamed)) { - // No file data! - if (!AKFactory::get('kickstart.setup.dryrun', '0')) + if (in_array($this->fileHeader->file, $this->skipFiles)) { - if (is_resource($outfp)) - { - @fclose($outfp); - } + $isBannedFile = true; } - $this->runState = AK_STATE_DATAREAD; - - return true; } - $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength; - - // Loop while there's data to write and enough time to do it - while (($leftBytes > 0) && ($timer->getTimeLeft() > 0)) + // If we have a banned file, let's skip it + if ($isBannedFile) { - // Read the mini header - $binMiniHeader = fread($this->fp, 8); - $reallyReadBytes = akstringlen($binMiniHeader); - if ($reallyReadBytes < 8) + // Advance the file pointer, skipping exactly the size of the compressed data + $seekleft = $this->fileHeader->compressed; + while ($seekleft > 0) { - // We read less than requested! Why? Did we hit local EOF? - if ($this->isEOF(true) && !$this->isEOF(false)) - { - // Yeap. Let's go to the next file - $this->nextFile(); - // Retry reading the header - $binMiniHeader = fread($this->fp, 8); - $reallyReadBytes = akstringlen($binMiniHeader); - // Still not enough data? If so, the archive is corrupt or missing parts. - if ($reallyReadBytes < 8) - { - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; - } - } - else + // Ensure that we can seek past archive part boundaries + $curSize = @filesize($this->archiveList[$this->currentPartNumber]); + $curPos = @ftell($this->fp); + $canSeek = $curSize - $curPos; + if ($canSeek > $seekleft) { - // Nope. The archive is corrupt - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; + $canSeek = $seekleft; } - } - - // Read the encrypted data - $miniHeader = unpack('Vencsize/Vdecsize', $binMiniHeader); - $toReadBytes = $miniHeader['encsize']; - $data = $this->fread($this->fp, $toReadBytes); - $reallyReadBytes = akstringlen($data); - if ($reallyReadBytes < $toReadBytes) - { - // We read less than requested! Why? Did we hit local EOF? - if ($this->isEOF(true) && !$this->isEOF(false)) + @fseek($this->fp, $canSeek, SEEK_CUR); + $seekleft -= $canSeek; + if ($seekleft) { - // Yeap. Let's go to the next file $this->nextFile(); - // Read the rest of the data - $toReadBytes -= $reallyReadBytes; - $restData = $this->fread($this->fp, $toReadBytes); - $reallyReadBytes = akstringlen($restData); - if ($reallyReadBytes < $toReadBytes) - { - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; - } - if (akstringlen($data) == 0) - { - $data = $restData; - } - else - { - $data .= $restData; - } - } - else - { - // Nope. The archive is corrupt - $this->setError(AKText::_('ERR_CORRUPT_ARCHIVE')); - - return false; } } - // Decrypt the data - $data = AKEncryptionAES::AESDecryptCBC($data, $this->password, 128); - - // Is the length of the decrypted data less than expected? - $data_length = akstringlen($data); - if ($data_length < $miniHeader['decsize']) - { - $this->setError(AKText::_('ERR_INVALID_JPS_PASSWORD')); - - return false; - } - - // Trim the data - $data = substr($data, 0, $miniHeader['decsize']); + $this->currentPartOffset = @ftell($this->fp); + $this->runState = AK_STATE_DONE; - // Decompress - $data = gzinflate($data); - $unc_len = akstringlen($data); + return true; + } - // Write the decrypted data - if (!AKFactory::get('kickstart.setup.dryrun', '0')) - { - if (is_resource($outfp)) - { - @fwrite($outfp, $data, akstringlen($data)); - } - } + // Remove the removePath, if any + $this->fileHeader->file = $this->removePath($this->fileHeader->file); - // Update the read length - $this->dataReadLength += $unc_len; - $leftBytes = $this->fileHeader->uncompressed - $this->dataReadLength; + // Last chance to prepend a path to the filename + if (!empty($this->addPath) && !$isDirRenamed) + { + $this->fileHeader->file = $this->addPath . $this->fileHeader->file; } - // Close the file pointer - if (!AKFactory::get('kickstart.setup.dryrun', '0')) + // Get the translated path name + if ($this->fileHeader->type == 'file') { - if (is_resource($outfp)) - { - @fclose($outfp); - } + $this->fileHeader->realFile = $this->postProcEngine->processFilename($this->fileHeader->file); } - - // Was this a pre-timeout bail out? - if ($leftBytes > 0) + elseif ($this->fileHeader->type == 'dir') { - $this->runState = AK_STATE_DATA; + $this->fileHeader->timestamp = 0; + + $dir = $this->fileHeader->file; + + $this->postProcEngine->createDirRecursive($this->fileHeader->file, 0755); + $this->postProcEngine->processFilename(null); } else { - // Oh! We just finished! - $this->runState = AK_STATE_DATAREAD; - $this->dataReadLength = 0; + // Symlink; do not post-process + $this->fileHeader->timestamp = 0; + $this->postProcEngine->processFilename(null); } + $this->createDirectory(); + + // Header is read + $this->runState = AK_STATE_HEADER; + return true; } -} -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ +} /** * Timer class @@ -5488,13 +2665,9 @@ class AKCoreTimer extends AKAbstractObject /** * Public constructor, creates the timer object and calculates the execution time limits - * - * @return AECoreTimer */ public function __construct() { - parent::__construct(); - // Initialize start time $this->start_time = $this->microtime_float(); @@ -5654,17 +2827,15 @@ public function resetTime() { $this->start_time = $this->microtime_float(); } -} -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ + /** + * @param int $max_exec_time + */ + public function setMaxExecTime($max_exec_time) + { + $this->max_exec_time = $max_exec_time; + } +} /** * A filesystem scanner which uses opendir() @@ -5762,16 +2933,6 @@ public function &getFolders($folder, $pattern = '*') } } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * A simple INI-based i18n engine */ @@ -5783,112 +2944,13 @@ class AKText extends AKAbstractObject * @var array */ private $default_translation = array( - 'AUTOMODEON' => 'Auto-mode enabled', 'ERR_NOT_A_JPA_FILE' => 'The file is not a JPA archive', 'ERR_CORRUPT_ARCHIVE' => 'The archive file is corrupt, truncated or archive parts are missing', 'ERR_INVALID_LOGIN' => 'Invalid login', 'COULDNT_CREATE_DIR' => 'Could not create %s folder', 'COULDNT_WRITE_FILE' => 'Could not open %s for writing.', - 'WRONG_FTP_HOST' => 'Wrong FTP host or port', - 'WRONG_FTP_USER' => 'Wrong FTP username or password', - 'WRONG_FTP_PATH1' => 'Wrong FTP initial directory - the directory doesn\'t exist', - 'FTP_CANT_CREATE_DIR' => 'Could not create directory %s', - 'FTP_TEMPDIR_NOT_WRITABLE' => 'Could not find or create a writable temporary directory', - 'SFTP_TEMPDIR_NOT_WRITABLE' => 'Could not find or create a writable temporary directory', - 'FTP_COULDNT_UPLOAD' => 'Could not upload %s', - 'THINGS_HEADER' => 'Things you should know about Akeeba Kickstart', - 'THINGS_01' => 'Kickstart is not an installer. It is an archive extraction tool. The actual installer was put inside the archive file at backup time.', - 'THINGS_02' => 'Kickstart is not the only way to extract the backup archive. You can use Akeeba eXtract Wizard and upload the extracted files using FTP instead.', - 'THINGS_03' => 'Kickstart is bound by your server\'s configuration. As such, it may not work at all.', - 'THINGS_04' => 'You should download and upload your archive files using FTP in Binary transfer mode. Any other method could lead to a corrupt backup archive and restoration failure.', - 'THINGS_05' => 'Post-restoration site load errors are usually caused by .htaccess or php.ini directives. You should understand that blank pages, 404 and 500 errors can usually be worked around by editing the aforementioned files. It is not our job to mess with your configuration files, because this could be dangerous for your site.', - 'THINGS_06' => 'Kickstart overwrites files without a warning. If you are not sure that you are OK with that do not continue.', - 'THINGS_07' => 'Trying to restore to the temporary URL of a cPanel host (e.g. http://1.2.3.4/~username) will lead to restoration failure and your site will appear to be not working. This is normal and it\'s just how your server and CMS software work.', - 'THINGS_08' => 'You are supposed to read the documentation before using this software. Most issues can be avoided, or easily worked around, by understanding how this software works.', - 'THINGS_09' => 'This text does not imply that there is a problem detected. It is standard text displayed every time you launch Kickstart.', - 'CLOSE_LIGHTBOX' => 'Click here or press ESC to close this message', - 'SELECT_ARCHIVE' => 'Select a backup archive', - 'ARCHIVE_FILE' => 'Archive file:', - 'SELECT_EXTRACTION' => 'Select an extraction method', - 'WRITE_TO_FILES' => 'Write to files:', - 'WRITE_HYBRID' => 'Hybrid (use FTP only if needed)', - 'WRITE_DIRECTLY' => 'Directly', - 'WRITE_FTP' => 'Use FTP for all files', - 'WRITE_SFTP' => 'Use SFTP for all files', - 'FTP_HOST' => '(S)FTP host name:', - 'FTP_PORT' => '(S)FTP port:', - 'FTP_FTPS' => 'Use FTP over SSL (FTPS)', - 'FTP_PASSIVE' => 'Use FTP Passive Mode', - 'FTP_USER' => '(S)FTP user name:', - 'FTP_PASS' => '(S)FTP password:', - 'FTP_DIR' => '(S)FTP directory:', - 'FTP_TEMPDIR' => 'Temporary directory:', - 'FTP_CONNECTION_OK' => 'FTP Connection Established', - 'SFTP_CONNECTION_OK' => 'SFTP Connection Established', - 'FTP_CONNECTION_FAILURE' => 'The FTP Connection Failed', - 'SFTP_CONNECTION_FAILURE' => 'The SFTP Connection Failed', - 'FTP_TEMPDIR_WRITABLE' => 'The temporary directory is writable.', - 'FTP_TEMPDIR_UNWRITABLE' => 'The temporary directory is not writable. Please check the permissions.', - 'FTPBROWSER_ERROR_HOSTNAME' => "Invalid FTP host or port", - 'FTPBROWSER_ERROR_USERPASS' => "Invalid FTP username or password", - 'FTPBROWSER_ERROR_NOACCESS' => "Directory doesn't exist or you don't have enough permissions to access it", - 'FTPBROWSER_ERROR_UNSUPPORTED' => "Sorry, your FTP server doesn't support our FTP directory browser.", - 'FTPBROWSER_LBL_GOPARENT' => "<up one level>", - 'FTPBROWSER_LBL_INSTRUCTIONS' => 'Click on a directory to navigate into it. Click on OK to select that directory, Cancel to abort the procedure.', - 'FTPBROWSER_LBL_ERROR' => 'An error occurred', - 'SFTP_NO_SSH2' => 'Your web server does not have the SSH2 PHP module, therefore can not connect to SFTP servers.', - 'SFTP_NO_FTP_SUPPORT' => 'Your SSH server does not allow SFTP connections', - 'SFTP_WRONG_USER' => 'Wrong SFTP username or password', - 'SFTP_WRONG_STARTING_DIR' => 'You must supply a valid absolute path', - 'SFTPBROWSER_ERROR_NOACCESS' => "Directory doesn't exist or you don't have enough permissions to access it", - 'SFTP_COULDNT_UPLOAD' => 'Could not upload %s', - 'SFTP_CANT_CREATE_DIR' => 'Could not create directory %s', - 'UI-ROOT' => '<root>', - 'CONFIG_UI_FTPBROWSER_TITLE' => 'FTP Directory Browser', - 'FTP_BROWSE' => 'Browse', - 'BTN_CHECK' => 'Check', - 'BTN_RESET' => 'Reset', - 'BTN_TESTFTPCON' => 'Test FTP connection', - 'BTN_TESTSFTPCON' => 'Test SFTP connection', - 'BTN_GOTOSTART' => 'Start over', - 'FINE_TUNE' => 'Fine tune', - 'BTN_SHOW_FINE_TUNE' => 'Show advanced options (for experts)', - 'MIN_EXEC_TIME' => 'Minimum execution time:', - 'MAX_EXEC_TIME' => 'Maximum execution time:', - 'SECONDS_PER_STEP' => 'seconds per step', - 'EXTRACT_FILES' => 'Extract files', - 'BTN_START' => 'Start', - 'EXTRACTING' => 'Extracting', - 'DO_NOT_CLOSE_EXTRACT' => 'Do not close this window while the extraction is in progress', - 'RESTACLEANUP' => 'Restoration and Clean Up', - 'BTN_RUNINSTALLER' => 'Run the Installer', - 'BTN_CLEANUP' => 'Clean Up', - 'BTN_SITEFE' => 'Visit your site\'s front-end', - 'BTN_SITEBE' => 'Visit your site\'s back-end', - 'WARNINGS' => 'Extraction Warnings', - 'ERROR_OCCURED' => 'An error occured', - 'STEALTH_MODE' => 'Stealth mode', - 'STEALTH_URL' => 'HTML file to show to web visitors', - 'ERR_NOT_A_JPS_FILE' => 'The file is not a JPA archive', - 'ERR_INVALID_JPS_PASSWORD' => 'The password you gave is wrong or the archive is corrupt', - 'JPS_PASSWORD' => 'Archive Password (for JPS files)', 'INVALID_FILE_HEADER' => 'Invalid header in archive file, part %s, offset %s', - 'NEEDSOMEHELPKS' => 'Want some help to use this tool? Read this first:', - 'QUICKSTART' => 'Quick Start Guide', - 'CANTGETITTOWORK' => 'Can\'t get it to work? Click me!', - 'NOARCHIVESCLICKHERE' => 'No archives detected. Click here for troubleshooting instructions.', - 'POSTRESTORATIONTROUBLESHOOTING' => 'Something not working after the restoration? Click here for troubleshooting instructions.', - 'UPDATE_HEADER' => 'An updated version of Akeeba Kickstart (unknown) is available!', - 'UPDATE_NOTICE' => 'You are advised to always use the latest version of Akeeba Kickstart available. Older versions may be subject to bugs and will not be supported.', - 'UPDATE_DLNOW' => 'Download now', - 'UPDATE_MOREINFO' => 'More information', - 'IGNORE_MOST_ERRORS' => 'Ignore most errors', - 'WRONG_FTP_PATH2' => 'Wrong FTP initial directory - the directory doesn\'t correspond to your site\'s web root', - 'ARCHIVE_DIRECTORY' => 'Archive directory:', - 'RELOAD_ARCHIVES' => 'Reload', - 'CONFIG_UI_SFTPBROWSER_TITLE' => 'SFTP Directory Browser', 'ERR_COULD_NOT_OPEN_ARCHIVE_PART' => 'Could not open archive part file %s for reading. Check that the file exists, is readable by the web server and is not in a directory made out of reach by chroot, open_basedir restrictions or any other restriction put in place by your host.', - 'RENAME_FILES' => 'Rename server configuration files' ); /** @@ -6013,7 +3075,7 @@ public static function parse_ini_file($file, $process_sections = false, $raw_dat } // Sections - if ($line{0} == '[') + if ($line[0] == '[') { $tmp = explode(']', $line); $sections[] = trim(substr($tmp[0], 1)); @@ -6030,7 +3092,7 @@ public static function parse_ini_file($file, $process_sections = false, $raw_dat $tmp = explode(';', $value); if (count($tmp) == 2) { - if ((($value{0} != '"') && ($value{0} != "'")) || + if ((($value[0] != '"') && ($value[0] != "'")) || preg_match('/^".*"\s*;/', $value) || preg_match('/^".*;[^"]*$/', $value) || preg_match("/^'.*'\s*;/", $value) || preg_match("/^'.*;[^']*$/", $value) ) @@ -6040,11 +3102,11 @@ public static function parse_ini_file($file, $process_sections = false, $raw_dat } else { - if ($value{0} == '"') + if ($value[0] == '"') { $value = preg_replace('/^"(.*)".*/', '$1', $value); } - elseif ($value{0} == "'") + elseif ($value[0] == "'") { $value = preg_replace("/^'(.*)'.*/", '$1', $value); } @@ -6183,10 +3245,6 @@ public function getBrowserLanguage() { $this->language = $languageStruct[0]; } - else - { - - } } } else @@ -6309,29 +3367,22 @@ public function addDefaultLanguageStrings($stringList = array()) } } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * The Akeeba Kickstart Factory class * This class is reponssible for instanciating all Akeeba Kicsktart classes */ class AKFactory { - /** @var array A list of instanciated objects */ + /** @var array A list of instantiated objects */ private $objectlist = array(); - /** @var array Simple hash data storage */ + /** @var array Simple hash data storage */ private $varlist = array(); - /** Private constructor makes sure we can't directly instanciate the class */ + /** @var self Static instance */ + private static $instance = null; + + /** Private constructor makes sure we can't directly instantiate the class */ private function __construct() { } @@ -6476,6 +3527,7 @@ public static function &getUnarchiver($configOverride = null) public static function get($key, $default = null) { $self = self::getInstance(); + if (array_key_exists($key, $self->varlist)) { return $self->varlist[$key]; @@ -6495,20 +3547,19 @@ public static function get($key, $default = null) */ protected static function &getInstance($serialized_data = null) { - static $myInstance; - if (!is_object($myInstance) || !is_null($serialized_data)) + if (!is_object(self::$instance) || !is_null($serialized_data)) { if (!is_null($serialized_data)) { - $myInstance = unserialize($serialized_data); + self::$instance = unserialize($serialized_data); } else { - $myInstance = new self(); + self::$instance = new self(); } } - return $myInstance; + return self::$instance; } /** @@ -6522,6 +3573,7 @@ protected static function &getInstance($serialized_data = null) protected static function &getClassInstance($class_name) { $self = self::getInstance(); + if (!isset($self->objectlist[$class_name])) { $self->objectlist[$class_name] = new $class_name; @@ -6553,12 +3605,7 @@ public static function unserialize($serialized_data) */ public static function nuke() { - $self = self::getInstance(); - foreach ($self->objectlist as $key => $object) - { - $self->objectlist[$key] = null; - } - $self->objectlist = array(); + self::$instance = null; } // ======================================================================== @@ -6598,21 +3645,12 @@ public static function &getPostProc($proc_engine = null) */ public static function &getTimer() { + /** @noinspection PhpIncompatibleReturnTypeInspection */ return self::getClassInstance('AKCoreTimer'); } } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * Interface for AES encryption adapters */ @@ -6643,16 +3681,6 @@ public function getBlockSize(); public function isSupported(); } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * Abstract AES encryption class */ @@ -6731,16 +3759,6 @@ protected function getZeroPadding($string, $blockSize) } } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - class Mcrypt extends AKEncryptionAESAdapterAbstract implements AKEncryptionAESAdapterInterface { protected $cipherType = MCRYPT_RIJNDAEL_128; @@ -6833,16 +3851,6 @@ public function getBlockSize() } } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - class OpenSSL extends AKEncryptionAESAdapterAbstract implements AKEncryptionAESAdapterInterface { /** @@ -6938,16 +3946,6 @@ public function getBlockSize() } } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - /** * AES implementation in PHP (c) Chris Veness 2005-2016. * Right to use and adapt is granted for under a simple creative commons attribution @@ -6993,6 +3991,34 @@ class AKEncryptionAES protected static $passwords = array(); + /** + * The algorithm to use for PBKDF2. Must be a supported hash_hmac algorithm. Default: sha1 + * + * @var string + */ + private static $pbkdf2Algorithm = 'sha1'; + + /** + * Number of iterations to use for PBKDF2 + * + * @var int + */ + private static $pbkdf2Iterations = 1000; + + /** + * Should we use a static salt for PBKDF2? + * + * @var int + */ + private static $pbkdf2UseStaticSalt = 0; + + /** + * The static salt to use for PBKDF2 + * + * @var string + */ + private static $pbkdf2StaticSalt = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + /** * Encrypt a text using AES encryption in Counter mode of operation * - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf @@ -7419,22 +4445,50 @@ public static function AESDecryptCBC($ciphertext, $password) return false; } - // Get the expanded key from the password - $key = self::expandKey($password); - // Read the data size $data_size = unpack('V', substr($ciphertext, -4)); + // Do I have a PBKDF2 salt? + $salt = substr($ciphertext, -92, 68); + $rightStringLimit = -4; + + $params = self::getKeyDerivationParameters(); + $keySizeBytes = $params['keySize']; + $algorithm = $params['algorithm']; + $iterations = $params['iterations']; + $useStaticSalt = $params['useStaticSalt']; + + if (substr($salt, 0, 4) == 'JPST') + { + // We have a stored salt. Retrieve it and tell decrypt to process the string minus the last 44 bytes + // (4 bytes for JPST, 16 bytes for the salt, 4 bytes for JPIV, 16 bytes for the IV, 4 bytes for the + // uncompressed string length - note that using PBKDF2 means we're also using a randomized IV per the + // format specification). + $salt = substr($salt, 4); + $rightStringLimit -= 68; + + $key = self::pbkdf2($password, $salt, $algorithm, $iterations, $keySizeBytes); + } + elseif ($useStaticSalt) + { + // We have a static salt. Use it for PBKDF2. + $key = self::getStaticSaltExpandedKey($password); + } + else + { + // Get the expanded key from the password. THIS USES THE OLD, INSECURE METHOD. + $key = self::expandKey($password); + } + // Try to get the IV from the data $iv = substr($ciphertext, -24, 20); - $rightStringLimit = -4; if (substr($iv, 0, 4) == 'JPIV') { // We have a stored IV. Retrieve it and tell mdecrypt to process the string minus the last 24 bytes // (4 bytes for JPIV, 16 bytes for the IV, 4 bytes for the uncompressed string length) $iv = substr($iv, 4); - $rightStringLimit = -24; + $rightStringLimit -= 20; } else { @@ -7455,7 +4509,7 @@ public static function AESDecryptCBC($ciphertext, $password) } /** - * That's the old way of craeting an IV that's definitely not cryptographically sound. + * That's the old way of creating an IV that's definitely not cryptographically sound. * * DO NOT USE, EVER, UNLESS YOU WANT TO DECRYPT LEGACY DATA * @@ -7565,17 +4619,171 @@ public static function getAdapter() return $adapter; } -} -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ + /** + * @return string + */ + public static function getPbkdf2Algorithm() + { + return self::$pbkdf2Algorithm; + } + + /** + * @param string $pbkdf2Algorithm + * @return void + */ + public static function setPbkdf2Algorithm($pbkdf2Algorithm) + { + self::$pbkdf2Algorithm = $pbkdf2Algorithm; + } + + /** + * @return int + */ + public static function getPbkdf2Iterations() + { + return self::$pbkdf2Iterations; + } + + /** + * @param int $pbkdf2Iterations + * @return void + */ + public static function setPbkdf2Iterations($pbkdf2Iterations) + { + self::$pbkdf2Iterations = $pbkdf2Iterations; + } + + /** + * @return int + */ + public static function getPbkdf2UseStaticSalt() + { + return self::$pbkdf2UseStaticSalt; + } + + /** + * @param int $pbkdf2UseStaticSalt + * @return void + */ + public static function setPbkdf2UseStaticSalt($pbkdf2UseStaticSalt) + { + self::$pbkdf2UseStaticSalt = $pbkdf2UseStaticSalt; + } + + /** + * @return string + */ + public static function getPbkdf2StaticSalt() + { + return self::$pbkdf2StaticSalt; + } + + /** + * @param string $pbkdf2StaticSalt + * @return void + */ + public static function setPbkdf2StaticSalt($pbkdf2StaticSalt) + { + self::$pbkdf2StaticSalt = $pbkdf2StaticSalt; + } + + /** + * Get the parameters fed into PBKDF2 to expand the user password into an encryption key. These are the static + * parameters (key size, hashing algorithm and number of iterations). A new salt is used for each encryption block + * to minimize the risk of attacks against the password. + * + * @return array + */ + public static function getKeyDerivationParameters() + { + return array( + 'keySize' => 16, + 'algorithm' => self::$pbkdf2Algorithm, + 'iterations' => self::$pbkdf2Iterations, + 'useStaticSalt' => self::$pbkdf2UseStaticSalt, + 'staticSalt' => self::$pbkdf2StaticSalt, + ); + } + + /** + * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt + * + * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt + * + * This implementation of PBKDF2 was originally created by https://defuse.ca + * With improvements by http://www.variations-of-shadow.com + * Modified for Akeeba Engine by Akeeba Ltd (removed unnecessary checks to make it faster) + * + * @param string $password The password. + * @param string $salt A salt that is unique to the password. + * @param string $algorithm The hash algorithm to use. Default is sha1. + * @param int $count Iteration count. Higher is better, but slower. Default: 1000. + * @param int $key_length The length of the derived key in bytes. + * + * @return string A string of $key_length bytes + */ + public static function pbkdf2($password, $salt, $algorithm = 'sha1', $count = 1000, $key_length = 16) + { + if (function_exists("hash_pbkdf2")) + { + return hash_pbkdf2($algorithm, $password, $salt, $count, $key_length, true); + } + + $hash_length = akstringlen(hash($algorithm, "", true)); + $block_count = ceil($key_length / $hash_length); + + $output = ""; + + for ($i = 1; $i <= $block_count; $i++) + { + // $i encoded as 4 bytes, big endian. + $last = $salt . pack("N", $i); + + // First iteration + $xorResult = hash_hmac($algorithm, $last, $password, true); + $last = $xorResult; + + // Perform the other $count - 1 iterations + for ($j = 1; $j < $count; $j++) + { + $last = hash_hmac($algorithm, $last, $password, true); + $xorResult ^= $last; + } + + $output .= $xorResult; + } + + return aksubstr($output, 0, $key_length); + } + + /** + * Get the expanded key from the user supplied password using a static salt. The results are cached for performance + * reasons. + * + * @param string $password The user-supplied password, UTF-8 encoded. + * + * @return string The expanded key + */ + private static function getStaticSaltExpandedKey($password) + { + $params = self::getKeyDerivationParameters(); + $keySizeBytes = $params['keySize']; + $algorithm = $params['algorithm']; + $iterations = $params['iterations']; + $staticSalt = $params['staticSalt']; + + $lookupKey = "PBKDF2-$algorithm-$iterations-" . md5($password . $staticSalt); + + if (!array_key_exists($lookupKey, self::$passwords)) + { + self::$passwords[$lookupKey] = self::pbkdf2($password, $staticSalt, $algorithm, $iterations, $keySizeBytes); + } + + return self::$passwords[$lookupKey]; + } + +} /** * The Master Setup will read the configuration parameters from restoration.php or @@ -7591,51 +4799,33 @@ function masterSetup() $ini_data = null; - // In restore.php mode, require restoration.php or fail - if (!defined('KICKSTART')) - { - // This is the standalone mode, used by Akeeba Backup Professional. It looks for a restoration.php - // file to perform its magic. If the file is not there, we will abort. - $setupFile = 'restoration.php'; - - if (!file_exists($setupFile)) - { - AKFactory::set('kickstart.enabled', false); - - return false; - } + // Require restoration.php or fail + $setupFile = 'restoration.php'; - // Load restoration.php. It creates a global variable named $restoration_setup - require_once $setupFile; + if (!file_exists($setupFile)) + { + AKFactory::set('kickstart.enabled', false); - $ini_data = $restoration_setup; + return false; + } - if (empty($ini_data)) - { - // No parameters fetched. Darn, how am I supposed to work like that?! - AKFactory::set('kickstart.enabled', false); + // Load restoration.php. It creates a global variable named $restoration_setup + require_once $setupFile; - return false; - } + /** @var array $restoration_setup This is defined in the restoration.php file */ + $ini_data = $restoration_setup; - AKFactory::set('kickstart.enabled', true); - } - else + if (empty($ini_data)) { - // Maybe we have $restoration_setup defined in the head of kickstart.php - global $restoration_setup; + // No parameters fetched. Darn, how am I supposed to work like that?! + AKFactory::set('kickstart.enabled', false); - if (!empty($restoration_setup) && !is_array($restoration_setup)) - { - $ini_data = AKText::parse_ini_file($restoration_setup, false, true); - } - elseif (is_array($restoration_setup)) - { - $ini_data = $restoration_setup; - } + return false; } - // Import any data from $restoration_setup + AKFactory::set('kickstart.enabled', true); + + // Import any data from the $restoration_setup array read from restoration.php if (!empty($ini_data)) { foreach ($ini_data as $key => $value) @@ -7732,49 +4922,9 @@ function masterSetup() return true; } - // ------------------------------------------------------------ - // 4. Try the configuration variable for Kickstart - // ------------------------------------------------------------ - if (defined('KICKSTART')) - { - $configuration = getQueryParam('configuration'); - - if (!is_null($configuration)) - { - // Let's decode the configuration from JSON to array - $ini_data = json_decode($configuration, true); - } - else - { - // Neither exists. Enable Kickstart's interface anyway. - $ini_data = array('kickstart.enabled' => true); - } - - // Import any INI data we might have from other sources - if (!empty($ini_data)) - { - foreach ($ini_data as $key => $value) - { - AKFactory::set($key, $value); - } - - AKFactory::set('kickstart.enabled', true); - - return true; - } - } + return AKFactory::get('kickstart.enabled', false); } -/** - * Akeeba Restore - * A JSON-powered JPA, JPS and ZIP archive extraction library - * - * @copyright 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. - * @license GNU GPL v2 or - at your option - any later version - * @package akeebabackup - * @subpackage kickstart - */ - // Mini-controller for restore.php if (!defined('KICKSTART')) { @@ -7829,16 +4979,21 @@ public function __toString() switch ($task) { case 'ping': - // ping task - realy does nothing! + // ping task - really does nothing! $timer = AKFactory::getTimer(); $timer->enforce_min_exec_time(); break; + /** + * There are two separate steps here since we were using an inefficient restoration intialization method in + * the past. Now both startRestore and stepRestore are identical. The difference in behavior depends + * exclusively on the calling Javascript. If no serialized factory was passed in the request then we start a + * new restoration. If a serialized factory was passed in the request then the restoration is resumed. For + * this reason we should NEVER call AKFactory::nuke() in startRestore anymore: that would simply reset the + * extraction engine configuration which was done in masterSetup() leading to an error about the file being + * invalid (since no file is found). + */ case 'startRestore': - AKFactory::nuke(); // Reset the factory - - // Let the control flow to the next step (the rest of the code is common!!) - case 'stepRestore': $engine = AKFactory::getUnarchiver(); // Get the engine $observer = new RestorationObserver(); // Create a new observer @@ -7878,24 +5033,32 @@ public function __toString() $postproc = AKFactory::getPostProc(); - // Rename htaccess.bak to .htaccess - if (file_exists($root . '/htaccess.bak')) + /** + * Should I rename the htaccess.bak and web.config.bak files back to their live filenames...? + */ + $renameFiles = AKFactory::get('kickstart.setup.postrenamefiles', true); + + if ($renameFiles) { - if (file_exists($root . '/.htaccess')) + // Rename htaccess.bak to .htaccess + if (file_exists($root . '/htaccess.bak')) { - $postproc->unlink($root . '/.htaccess'); + if (file_exists($root . '/.htaccess')) + { + $postproc->unlink($root . '/.htaccess'); + } + $postproc->rename($root . '/htaccess.bak', $root . '/.htaccess'); } - $postproc->rename($root . '/htaccess.bak', $root . '/.htaccess'); - } - // Rename htaccess.bak to .htaccess - if (file_exists($root . '/web.config.bak')) - { - if (file_exists($root . '/web.config')) + // Rename htaccess.bak to .htaccess + if (file_exists($root . '/web.config.bak')) { - $postproc->unlink($root . '/web.config'); + if (file_exists($root . '/web.config')) + { + $postproc->unlink($root . '/web.config'); + } + $postproc->rename($root . '/web.config.bak', $root . '/web.config'); } - $postproc->rename($root . '/web.config.bak', $root . '/web.config'); } // Remove restoration.php @@ -7911,18 +5074,21 @@ public function __toString() $filename = dirname(__FILE__) . '/restore_finalisation.php'; if (file_exists($filename)) { - // opcode cache busting before including the filename - if (function_exists('opcache_invalidate')) + // We cannot use the Filesystem API here. + if (ini_get('opcache.enable') + && function_exists('opcache_invalidate') + && (!ini_get('opcache.restrict_api') || stripos(realpath($_SERVER['SCRIPT_FILENAME']), ini_get('opcache.restrict_api')) === 0) + ) { - opcache_invalidate($filename); + \opcache_invalidate($filename, true); } if (function_exists('apc_compile_file')) { - apc_compile_file($filename); + \apc_compile_file($filename); } if (function_exists('wincache_refresh_if_changed')) { - wincache_refresh_if_changed(array($filename)); + \wincache_refresh_if_changed(array($filename)); } if (function_exists('xcache_asm')) { diff --git a/administrator/components/com_joomlaupdate/restore_finalisation.php b/administrator/components/com_joomlaupdate/restore_finalisation.php index fd702319997b1..3ac9887b4125d 100644 --- a/administrator/components/com_joomlaupdate/restore_finalisation.php +++ b/administrator/components/com_joomlaupdate/restore_finalisation.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -26,7 +26,7 @@ * * @return boolean True on success. * - * @since 11.1 + * @since 3.5.1 */ function jimport($path, $base = null) { @@ -49,7 +49,7 @@ abstract class JFile * * @param string $fileName The path to the file to be checked * - * @return bool + * @return boolean * * @since 3.5.1 */ @@ -63,7 +63,7 @@ public static function exists($fileName) * * @param string $fileName The path to the file to be deleted * - * @return bool + * @return boolean * * @since 3.5.1 */ @@ -90,7 +90,7 @@ abstract class JFolder * * @param string $folderName The path to the folder to be checked * - * @return bool + * @return boolean * * @since 3.5.1 */ @@ -164,13 +164,13 @@ function finalizeRestore($siteRoot, $restorePath) if (file_exists($filePath)) { - require_once ($filePath); + require_once $filePath; } // Make sure Joomla!'s code can figure out which files exist and need be removed clearstatcache(); - // Remove obsolete files - prevents errors occuring in some system plugins + // Remove obsolete files - prevents errors occurring in some system plugins if (class_exists('JoomlaInstallerScript')) { $script = new JoomlaInstallerScript; diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php b/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php index 446f5b7b83457..0cc791adbf811 100644 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default.php index f418e632ce4a5..f1b593ade1084 100644 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default.php +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -13,10 +13,26 @@ JHtml::_('jquery.framework'); JHtml::_('bootstrap.tooltip'); +JHtml::_('bootstrap.popover'); JHtml::_('formbehavior.chosen', 'select'); JHtml::_('script', 'com_joomlaupdate/default.js', array('version' => 'auto', 'relative' => true)); -JFactory::getDocument()->addScriptDeclaration(" +JText::script('JYES'); +JText::script('JNO'); +JText::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_NO_COMPATIBILITY_INFORMATION'); +JText::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_WARNING_UNKNOWN'); +JText::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_SERVER_ERROR'); +JText::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_POTENTIALLY_DANGEROUS_PLUGIN'); +JText::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_POTENTIALLY_DANGEROUS_PLUGIN_DESC'); +JText::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_POTENTIALLY_DANGEROUS_PLUGIN_LIST'); +JText::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_POTENTIALLY_DANGEROUS_PLUGIN_CONFIRM_MESSAGE'); +JText::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_HELP'); + +$latestJoomlaVersion = $this->updateInfo['latest']; +$currentJoomlaVersion = isset($this->updateInfo['current']) ? $this->updateInfo['current'] : JVERSION; + +JFactory::getDocument()->addScriptDeclaration( +<<
    - showUploadAndUpdate) : ?> - 'online-update')); ?> + $this->shouldDisplayPreUpdateCheck() ? 'pre-update-check' : 'online-update')); ?> + shouldDisplayPreUpdateCheck()) : ?> + + loadTemplate('preupdatecheck'); ?> + + @@ -45,11 +71,16 @@ enqueueMessage(JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALL_SELF_UPDATE_FIRST'), 'error'); ?> loadTemplate('updatemefirst'); ?> - updateInfo['object']->downloadurl->_data) && $this->updateInfo['installed'] < $this->updateInfo['latest']) : ?> - + updateInfo['object']->downloadurl->_data) + && !$this->updateInfo['hasUpdate']) + || !$this->getModel()->isDatabaseTypeSupported() + || !$this->getModel()->isPhpVersionSupported()) : ?> + + loadTemplate('noupdate'); ?> + updateInfo['object']->downloadurl->_data)) : ?> loadTemplate('nodownload'); ?> updateInfo['hasUpdate']) : ?> - + loadTemplate('reinstall'); ?> diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php index 0e2153d2dba76..88b026f7c0e6e 100644 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -12,10 +12,30 @@ ?>
    - - - -

    - updateInfo['latest']); ?> -

    + getModel()->isDatabaseTypeSupported()) : ?> + + + +

    + updateInfo['latest']); ?> +

    + + getModel()->isPhpVersionSupported()) : ?> + + + +

    + updateInfo['latest']); ?> +

    + + updateInfo['object']->downloadurl->_data) && $this->updateInfo['installed'] < $this->updateInfo['latest'] && $this->getModel()->isPhpVersionSupported() && $this->getModel()->isDatabaseTypeSupported()) : ?> + + + +

    + updateInfo['latest']); ?> +

    + + +
    diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_noupdate.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_noupdate.php new file mode 100644 index 0000000000000..75a73b539683d --- /dev/null +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/default_noupdate.php @@ -0,0 +1,24 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** @var JoomlaupdateViewDefault $this */ +?> +
    + + + +

    + langKey, $this->updateSourceKey); ?> +

    +
    + +
    +
    diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_preupdatecheck.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_preupdatecheck.php new file mode 100644 index 0000000000000..9b5ffcf18a0fd --- /dev/null +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/default_preupdatecheck.php @@ -0,0 +1,261 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** @var JoomlaupdateViewDefault $this */ + +// JText::script doesn't have a sprintf equivalent so work around this +JFactory::getDocument()->addScriptDeclaration("var COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_SHOW_MORE_COMPATIBILITY_INFORMATION = '" . JText::sprintf('COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_SHOW_MORE_COMPATIBILITY_INFORMATION', '', true) . "';"); +JFactory::getDocument()->addScriptDeclaration("var COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_SHOW_LESS_COMPATIBILITY_INFORMATION = '" . JText::sprintf('COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_SHOW_LESS_COMPATIBILITY_INFORMATION', '', true) . "';"); +JFactory::getDocument()->addScriptOptions('nonCoreCriticalPlugins', array_values($this->nonCoreCriticalPlugins)); + +$compatibilityTypes = array( + 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_RUNNING_PRE_UPDATE_CHECKS' => array( + 'class' => 'label-default', + 'notes' => 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_RUNNING_PRE_UPDATE_CHECKS_NOTES', + 'group' => 0 + ), + 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_PRE_UPDATE_CHECKS_FAILED' => array( + 'class' => 'label-important', + 'notes' => 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_PRE_UPDATE_CHECKS_FAILED_NOTES', + 'group' => 4 + ), + 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_UPDATE_SERVER_OFFERS_NO_COMPATIBLE_VERSION' => array( + 'class' => 'label-important', + 'notes' => 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_UPDATE_SERVER_OFFERS_NO_COMPATIBLE_VERSION_NOTES', + 'group' => 1 + ), + 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_REQUIRING_UPDATES_TO_BE_COMPATIBLE' => array( + 'class' => 'label-warning', + 'notes' => 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_REQUIRING_UPDATES_TO_BE_COMPATIBLE_NOTES', + 'group' => 2 + ), + 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_PROBABLY_COMPATIBLE' => array( + 'class' => 'label-success', + 'notes' => 'COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS_PROBABLY_COMPATIBLE_NOTES', + 'group' => 3 + ) +); + +if (version_compare($this->updateInfo['latest'], '4', '>=') && $this->isBackendTemplateIsis === false) +{ + JFactory::getApplication()->enqueueMessage( + JText::_( + 'COM_JOOMLAUPDATE_VIEW_DEFAULT_NON_CORE_BACKEND_TEMPLATE_USED_NOTICE' + ), + 'info' + ); +} + +?> +

    + updateInfo['latest']); ?> +

    +

    + +

    +
    +
    + + phpOptions as $option) : ?> + state) : ?> + + + + + +

    + +
    + ' + ); ?> +
    +

    +
    + +
    +
    + + phpSettings as $setting) : ?> + state !== $setting->recommended) : ?> + + + + + +

    + +
    + ' + ); ?> +
    +

    +
    + +
    +
    +nonCoreExtensions)) : ?> +
    +

    + +

    + $compatibilityData) : ?> + + + +
    + +

    + +
    + ' + ); ?> +
    + + +

    +
    +
    + +
    + + + + + + + + + + + + + + nonCoreExtensions as $extension) : ?> + + + + + + + + + +
    + + + +
    + name); ?> + + type)); ?> +
    +
    + +
    + +
    +
    +

    + +

    +
    + +
    +
    +
    + diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php index dd9ae2ab87e7c..c4093d14a1bbe 100644 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -31,8 +31,10 @@ - + updateInfo['object']->downloadurl->_data; ?> + + @@ -43,8 +45,10 @@ - + updateInfo['object']->get('infourl')->title; ?> + + diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php index 416d11ddb9e1e..81708df651fda 100644 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -26,7 +26,7 @@ - updateInfo['installed']; ?> + updateInfo['installed']; ?> @@ -34,7 +34,7 @@ - updateInfo['latest']; ?> + updateInfo['latest']; ?> @@ -42,8 +42,10 @@ - + updateInfo['object']->downloadurl->_data; ?> + + @@ -54,68 +56,193 @@ - + updateInfo['object']->get('infourl')->title; ?> + + - - - - - - methodSelect; ?> - - - ftpFieldsDisplay; ?>> - - - - - + + updateInfo['latest'], '4', '<')) : ?> + + + + + + methodSelect; ?> + + + ftpFieldsDisplay; ?>> + + + + + + + + ftpFieldsDisplay; ?>> + + + + + + + + ftpFieldsDisplay; ?>> + + + + + + + + ftpFieldsDisplay; ?>> + + + + + + + + ftpFieldsDisplay; ?>> + + + + + + + + + + + + +
    +

    + +

    +
    +
    + +
    +
    +
    - ftpFieldsDisplay; ?>> - - - - - + + +
    +

    + +

    +
    +
    + +
    +
    +
    - ftpFieldsDisplay; ?>> - - - - - + + + - ftpFieldsDisplay; ?>> - - - - - + + + + + + + + + + + nonCoreCriticalPlugins as $nonCoreCriticalPlugin) : ?> + + + package_id > 0) : ?> + nonCoreExtensions as $nonCoreExtension) : ?> + package_id == $nonCoreExtension->extension_id) : ?> + + + + + + + + + + + + + +
    + + + + + + + +
    + name); ?> + + name; ?> + + + + manifest_cache->author)) : ?> + manifest_cache->author); ?> + package_id > 0) : ?> + nonCoreExtensions as $nonCoreExtension) : ?> + package_id == $nonCoreExtension->extension_id) : ?> + + name; ?> + + + manifest_cache->authorUrl)) : ?> + manifest_cache->authorUrl; ?> + package_id > 0) : ?> + nonCoreExtensions as $nonCoreExtension) : ?> + package_id == $nonCoreExtension->extension_id) : ?> + manifest_cache->authorUrl; ?> + + + + + + + + + + + + +
    - ftpFieldsDisplay; ?>> + - + - + - - +   - diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php index 9087ce8098cdd..bca28511bfefb 100644 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php index e46fb4eb56917..f91d1c85508c0 100644 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php +++ b/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -12,6 +12,8 @@ /** @var JoomlaupdateViewDefault $this */ $errSelectPackage = JText::_('COM_INSTALLER_MSG_INSTALL_PLEASE_SELECT_A_PACKAGE', true); +$errPackageTooBig = JText::_('COM_INSTALLER_MSG_WARNINGS_UPLOADFILETOOBIG', true); +$txtPackageSize = JText::_('JGLOBAL_SELECTED_UPLOAD_FILE_SIZE', true); $js = <<< JS Joomla.submitbuttonUpload = function() { var form = document.getElementById("uploadForm"); @@ -20,6 +22,9 @@ if (form.install_package.value == "") { alert("$errSelectPackage"); } + else if (form.install_package.files[0].size > form.max_upload_size.value) { + alert("$errPackageTooBig"); + } else { jQuery("#loading").css("display", "block"); @@ -28,6 +33,30 @@ } }; + Joomla.installpackageChange = function() { + var form = document.getElementById('uploadForm'); + var fileSize = form.install_package.files[0].size; + var fileSizeMB = fileSize * 1.0 / 1024.0 / 1024.0; + var fileSizeText = "$txtPackageSize"; + var fileSizeElement = document.getElementById('file_size'); + var warningElement = document.getElementById('max_upload_size_warn'); + + if (form.install_package.value == '') { + fileSizeElement.classList.add('hidden'); + warningElement .classList.add('hidden'); + } + else if (fileSize) { + fileSizeElement.classList.remove('hidden'); + fileSizeElement.innerHTML = fileSizeText.replace('%s', fileSizeMB.toFixed(2) + ' MB'); + + if (fileSize > form.max_upload_size.value) { + warningElement .classList.remove('hidden'); + } else { + warningElement .classList.add('hidden'); + } + } + }; + // Add spindle-wheel for installations: jQuery(document).ready(function($) { var outerDiv = $("#joomlaupdate-wrapper"); @@ -96,9 +125,15 @@ -
    - - +
    + + + +
    + + @@ -109,6 +144,14 @@ methodSelectUpload; ?> + ftpFieldsDisplay; ?>> + + + + + + + ftpFieldsDisplay; ?>> diff --git a/administrator/components/com_joomlaupdate/views/default/view.html.php b/administrator/components/com_joomlaupdate/views/default/view.html.php index 5fdd89881c021..e2d896ef0dbf2 100644 --- a/administrator/components/com_joomlaupdate/views/default/view.html.php +++ b/administrator/components/com_joomlaupdate/views/default/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -43,6 +43,33 @@ class JoomlaupdateViewDefault extends JViewLegacy */ protected $methodSelectUpload = null; + /** + * PHP options. + * + * @var array Array of PHP config options + * + * @since 3.10.0 + */ + protected $phpOptions = null; + + /** + * PHP settings. + * + * @var array Array of PHP settings + * + * @since 3.10.0 + */ + protected $phpSettings = null; + + /** + * Non Core Extensions. + * + * @var array Array of Non-Core-Extensions + * + * @since 3.10.0 + */ + protected $nonCoreExtensions = null; + /** * Renders the view * @@ -63,21 +90,33 @@ public function display($tpl = null) $this->loadHelper('select'); // Assign view variables. - $ftp = $model->getFTPOptions(); - $defaultMethod = $ftp['enabled'] ? 'hybrid' : 'direct'; + $this->ftp = $model->getFTPOptions(); + $defaultMethod = $this->ftp['enabled'] ? 'hybrid' : 'direct'; $this->updateInfo = $model->getUpdateInformation(); $this->methodSelect = JoomlaupdateHelperSelect::getMethods($defaultMethod); $this->methodSelectUpload = JoomlaupdateHelperSelect::getMethods($defaultMethod, 'method', 'upload_method'); + // Get results of pre update check evaluations + $this->phpOptions = $model->getPhpOptions(); + $this->phpSettings = $model->getPhpSettings(); + $this->nonCoreExtensions = $model->getNonCoreExtensions(); + $this->isBackendTemplateIsis = (bool) $model->isTemplateActive('isis'); + + // Disable the critical plugins check for non-major updates. + $this->nonCoreCriticalPlugins = array(); + + if (version_compare($this->updateInfo['latest'], '4', '>=')) + { + $this->nonCoreCriticalPlugins = $model->getNonCorePlugins(array('system','user','authentication','actionlog','twofactorauth')); + } + // Set the toolbar information. JToolbarHelper::title(JText::_('COM_JOOMLAUPDATE_OVERVIEW'), 'loop install'); JToolbarHelper::custom('update.purge', 'loop', 'loop', 'COM_JOOMLAUPDATE_TOOLBAR_CHECK', false); // Add toolbar buttons. - $user = JFactory::getUser(); - - if ($user->authorise('core.admin', 'com_joomlaupdate') || $user->authorise('core.options', 'com_joomlaupdate')) + if (JFactory::getUser()->authorise('core.admin')) { JToolbarHelper::preferences('com_joomlaupdate'); } @@ -88,7 +127,7 @@ public function display($tpl = null) if (!is_null($this->updateInfo['object'])) { // Show the message if an update is found. - JFactory::getApplication()->enqueueMessage(JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATE_NOTICE'), 'notice'); + JFactory::getApplication()->enqueueMessage(JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATE_NOTICE'), 'warning'); } $this->ftpFieldsDisplay = $this->ftp['enabled'] ? '' : 'style = "display: none"'; @@ -97,7 +136,6 @@ public function display($tpl = null) switch ($params->get('updatesource', 'default')) { // "Minor & Patch Release for Current version AND Next Major Release". - case 'sts': case 'next': $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_NEXT'; $this->updateSourceKey = JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_NEXT'); @@ -120,6 +158,7 @@ public function display($tpl = null) * The commented "case" below are for documenting where 'default' and legacy options falls * case 'default': * case 'lts': + * case 'sts': * case 'nochange': */ default: @@ -184,7 +223,7 @@ private function checkForSelfUpdate() // Try the update only if we have an extension id if ($joomlaUpdateComponentId != 0) { - // Allways force to check for an update! + // Always force to check for an update! $cache_timeout = 0; $updater = JUpdater::getInstance(); @@ -217,4 +256,29 @@ private function checkForSelfUpdate() return true; } } + + /** + * Returns true, if the pre update check should be displayed. + * This logic is not hardcoded in tmpl files, because it is + * used by the Hathor tmpl too. + * + * @return boolean + * + * @since 3.10.0 + */ + public function shouldDisplayPreUpdateCheck() + { + // When the download URL is not found there is no core upgrade path + if (!isset($this->updateInfo['object']->downloadurl->_data)) + { + return false; + } + + $nextMinor = JVersion::MAJOR_VERSION . '.' . (JVersion::MINOR_VERSION + 1); + + // Show only when we found a download URL, we have an update and when we update to the next minor or greater. + return $this->updateInfo['hasUpdate'] + && version_compare($this->updateInfo['latest'], $nextMinor, '>='); + } } + diff --git a/administrator/components/com_joomlaupdate/views/update/tmpl/default.php b/administrator/components/com_joomlaupdate/views/update/tmpl/default.php index 1289724fe5aba..0f3f4007ced3b 100644 --- a/administrator/components/com_joomlaupdate/views/update/tmpl/default.php +++ b/administrator/components/com_joomlaupdate/views/update/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php b/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php index 1aefb29f08ce8..5c076486d315d 100644 --- a/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php +++ b/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -65,7 +65,7 @@ - + @@ -92,4 +92,4 @@
    - \ No newline at end of file + diff --git a/administrator/components/com_joomlaupdate/views/update/view.html.php b/administrator/components/com_joomlaupdate/views/update/view.html.php index a9067ece2dba2..a70ca23e312f3 100644 --- a/administrator/components/com_joomlaupdate/views/update/view.html.php +++ b/administrator/components/com_joomlaupdate/views/update/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -21,22 +21,14 @@ class JoomlaupdateViewUpdate extends JViewLegacy * * @param string $tpl Template name. * - * @return void + * @return void */ - public function display($tpl=null) + public function display($tpl = null) { + JFactory::getApplication()->input->set('hidemainmenu', true); + // Set the toolbar information. JToolbarHelper::title(JText::_('COM_JOOMLAUPDATE_OVERVIEW'), 'loop install'); - JToolBarHelper::divider(); - JToolBarHelper::help('JHELP_COMPONENTS_JOOMLA_UPDATE'); - - // Add toolbar buttons. - $user = JFactory::getUser(); - - if ($user->authorise('core.admin', 'com_joomlaupdate') || $user->authorise('core.options', 'com_joomlaupdate')) - { - JToolbarHelper::preferences('com_joomlaupdate'); - } // Import com_login's model JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_login/models', 'LoginModel'); diff --git a/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php b/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php index 5e39bf2b18188..a10e2c9581f92 100644 --- a/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php +++ b/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -64,7 +64,7 @@ - + diff --git a/administrator/components/com_joomlaupdate/views/upload/view.html.php b/administrator/components/com_joomlaupdate/views/upload/view.html.php index bc720d4c355d2..6cac9405b7418 100644 --- a/administrator/components/com_joomlaupdate/views/upload/view.html.php +++ b/administrator/components/com_joomlaupdate/views/upload/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_joomlaupdate * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/config.xml b/administrator/components/com_languages/config.xml index fb9bbac94a23d..1662ae7c83c93 100644 --- a/administrator/components/com_languages/config.xml +++ b/administrator/components/com_languages/config.xml @@ -2,14 +2,14 @@
    * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -17,7 +17,7 @@ class LanguagesController extends JControllerLegacy { /** - * @var string The default view. + * @var string The default view. * @since 1.6 */ protected $default_view = 'installed'; diff --git a/administrator/components/com_languages/controllers/installed.php b/administrator/components/com_languages/controllers/installed.php index f8998bdab9c98..3a0765717b7cf 100644 --- a/administrator/components/com_languages/controllers/installed.php +++ b/administrator/components/com_languages/controllers/installed.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -24,7 +24,7 @@ class LanguagesControllerInstalled extends JControllerLegacy public function setDefault() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $cid = $this->input->get('cid', ''); $model = $this->getModel('installed'); @@ -62,13 +62,19 @@ public function setDefault() public function switchAdminLanguage() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $cid = $this->input->get('cid', ''); $model = $this->getModel('installed'); - // Fetching the language name from the xx-XX.xml + // Fetching the language name from the xx-XX.xml or langmetadata.xml respectively. $file = JPATH_ADMINISTRATOR . '/language/' . $cid . '/' . $cid . '.xml'; + + if (!is_file($file)) + { + $file = JPATH_ADMINISTRATOR . '/language/' . $cid . '/langmetadata.xml'; + } + $info = JInstaller::parseXMLInstallFile($file); $languageName = $info['name']; diff --git a/administrator/components/com_languages/controllers/language.php b/administrator/components/com_languages/controllers/language.php index 33cd0293b7068..a6a1b8d64ff86 100644 --- a/administrator/components/com_languages/controllers/language.php +++ b/administrator/components/com_languages/controllers/language.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/controllers/languages.php b/administrator/components/com_languages/controllers/languages.php index 25d89f20ab4d5..5bcd6557ae494 100644 --- a/administrator/components/com_languages/controllers/languages.php +++ b/administrator/components/com_languages/controllers/languages.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -43,6 +43,9 @@ public function getModel($name = 'Language', $prefix = 'LanguagesModel', $config */ public function saveOrderAjax() { + // Check for request forgeries. + $this->checkToken(); + $pks = $this->input->post->get('cid', array(), 'array'); $order = $this->input->post->get('order', array(), 'array'); diff --git a/administrator/components/com_languages/controllers/override.php b/administrator/components/com_languages/controllers/override.php index 98fc5f2ce1b71..9f6c5be54dea7 100644 --- a/administrator/components/com_languages/controllers/override.php +++ b/administrator/components/com_languages/controllers/override.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -65,7 +65,7 @@ public function edit($key = null, $urlVar = null) public function save($key = null, $urlVar = null) { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $model = $this->getModel(); @@ -195,7 +195,7 @@ public function save($key = null, $urlVar = null) */ public function cancel($key = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $context = "$this->option.edit.$this->context"; diff --git a/administrator/components/com_languages/controllers/overrides.php b/administrator/components/com_languages/controllers/overrides.php index fda713a126d52..5bfd5e1213e73 100644 --- a/administrator/components/com_languages/controllers/overrides.php +++ b/administrator/components/com_languages/controllers/overrides.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -29,14 +29,14 @@ class LanguagesControllerOverrides extends JControllerAdmin * * @return void * - * @since 2.5 + * @since 2.5 */ public function delete() { // Check for request forgeries. - JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + $this->checkToken(); - // Get items to dlete from the request. + // Get items to delete from the request. $cid = $this->input->get('cid', array(), 'array'); if (!is_array($cid) || count($cid) < 1) @@ -71,6 +71,9 @@ public function delete() */ public function purge() { + // Check for request forgeries. + $this->checkToken(); + $model = $this->getModel('overrides'); $model->purge(); $this->setRedirect(JRoute::_('index.php?option=com_languages&view=overrides', false)); diff --git a/administrator/components/com_languages/controllers/strings.json.php b/administrator/components/com_languages/controllers/strings.json.php index 9fbd30259c699..4441ae714fc65 100644 --- a/administrator/components/com_languages/controllers/strings.json.php +++ b/administrator/components/com_languages/controllers/strings.json.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -21,7 +21,7 @@ class LanguagesControllerStrings extends JControllerAdmin * * @return void * - * @since 2.5 + * @since 2.5 */ public function refresh() { @@ -33,7 +33,7 @@ public function refresh() * * @return void * - * @since 2.5 + * @since 2.5 */ public function search() { diff --git a/administrator/components/com_languages/helpers/html/languages.php b/administrator/components/com_languages/helpers/html/languages.php index d69e3ae945053..d68258e281f03 100644 --- a/administrator/components/com_languages/helpers/html/languages.php +++ b/administrator/components/com_languages/helpers/html/languages.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/helpers/jsonresponse.php b/administrator/components/com_languages/helpers/jsonresponse.php index 861c4d835ba8b..fa973869e34c2 100644 --- a/administrator/components/com_languages/helpers/jsonresponse.php +++ b/administrator/components/com_languages/helpers/jsonresponse.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/helpers/languages.php b/administrator/components/com_languages/helpers/languages.php index 34e4b6c60eb0e..ec04f612c34c9 100644 --- a/administrator/components/com_languages/helpers/languages.php +++ b/administrator/components/com_languages/helpers/languages.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -75,29 +75,16 @@ public static function getActions() /** * Method for parsing ini files. * - * @param string $filename Path and name of the ini file to parse. + * @param string $fileName Path and name of the ini file to parse. * * @return array Array of strings found in the file, the array indices will be the keys. On failure an empty array will be returned. * * @since 2.5 + * @deprecated 3.9.0 Use JLanguageHelper::parseIniFile() instead. */ - public static function parseFile($filename) + public static function parseFile($fileName) { - if (!is_file($filename)) - { - return array(); - } - - $contents = file_get_contents($filename); - $contents = str_replace('_QQ_', '"\""', $contents); - $strings = @parse_ini_string($contents); - - if ($strings === false) - { - return array(); - } - - return $strings; + return JLanguageHelper::parseIniFile($fileName); } /** diff --git a/administrator/components/com_languages/helpers/multilangstatus.php b/administrator/components/com_languages/helpers/multilangstatus.php index c4c3c798a7e25..87c614c06e3e4 100644 --- a/administrator/components/com_languages/helpers/multilangstatus.php +++ b/administrator/components/com_languages/helpers/multilangstatus.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -209,17 +209,17 @@ public static function getContacts() foreach ($warnings as $index => $warn) { - if (($warn->alang == 1) && ($warn->slang == 0)) + if ($warn->alang == 1 && $warn->slang == 0) { unset($warnings[$index]); } - if (($warn->alang == 0) && (($warn->slang == 0) && (empty($warn->mlang)))) + if ($warn->alang == 0 && $warn->slang == 0 && empty($warn->mlang)) { unset($warnings[$index]); } - if (($warn->alang == 0) && (($warn->slang == $languages) && (empty($warn->mlang)))) + if ($warn->alang == 0 && $warn->slang == $languages && empty($warn->mlang)) { unset($warnings[$index]); } diff --git a/administrator/components/com_languages/languages.php b/administrator/components/com_languages/languages.php index 3a07360d932b5..567ab7644760f 100644 --- a/administrator/components/com_languages/languages.php +++ b/administrator/components/com_languages/languages.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/languages.xml b/administrator/components/com_languages/languages.xml index bf364005ef39c..0560f90182eaa 100644 --- a/administrator/components/com_languages/languages.xml +++ b/administrator/components/com_languages/languages.xml @@ -3,7 +3,7 @@ com_languages Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_languages/layouts/joomla/searchtools/default/bar.php b/administrator/components/com_languages/layouts/joomla/searchtools/default/bar.php new file mode 100644 index 0000000000000..2c05627a10bc6 --- /dev/null +++ b/administrator/components/com_languages/layouts/joomla/searchtools/default/bar.php @@ -0,0 +1,24 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +$data = $displayData; + +if ($data['view'] instanceof LanguagesViewOverrides) +{ + // We will get the language_client filter & remove it from the form filters + $langClient = $data['view']->filterForm->getField('language_client'); ?> +
    + input; ?> +
    + 'none')); ?> diff --git a/administrator/components/com_languages/models/fields/languageclient.php b/administrator/components/com_languages/models/fields/languageclient.php new file mode 100644 index 0000000000000..2b416f5c1770e --- /dev/null +++ b/administrator/components/com_languages/models/fields/languageclient.php @@ -0,0 +1,76 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JFormHelper::loadFieldClass('list'); + +/** + * Client Language List field. + * + * @since 3.9.0 + */ +class JFormFieldLanguageclient extends JFormFieldList +{ + /** + * The form field type. + * + * @var string + * @since 3.9.0 + */ + protected $type = 'Languageclient'; + + /** + * Cached form field options. + * + * @var array + * @since 3.9.0 + */ + protected $cache = array(); + + /** + * Method to get the field options. + * + * @return array The field option objects. + * + * @since 3.9.0 + */ + protected function getOptions() + { + // Try to load the data from our mini-cache. + if (!empty($this->cache)) + { + return $this->cache; + } + + // Get all languages of frontend and backend. + $languages = array(); + $site_languages = JLanguageHelper::getKnownLanguages(JPATH_SITE); + $admin_languages = JLanguageHelper::getKnownLanguages(JPATH_ADMINISTRATOR); + + // Create a single array of them. + foreach ($site_languages as $tag => $language) + { + $languages[$tag . '0'] = JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], JText::_('JSITE')); + } + + foreach ($admin_languages as $tag => $language) + { + $languages[$tag . '1'] = JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], JText::_('JADMINISTRATOR')); + } + + // Sort it by language tag and by client after that. + ksort($languages); + + // Add the languages to the internal cache. + $this->cache = array_merge(parent::getOptions(), $languages); + + return $this->cache; + } +} diff --git a/administrator/components/com_languages/models/forms/filter_installed.xml b/administrator/components/com_languages/models/forms/filter_installed.xml index 2ab9f1e90cc89..e25de546e9320 100644 --- a/administrator/components/com_languages/models/forms/filter_installed.xml +++ b/administrator/components/com_languages/models/forms/filter_installed.xml @@ -13,6 +13,7 @@ diff --git a/administrator/components/com_languages/models/forms/filter_languages.xml b/administrator/components/com_languages/models/forms/filter_languages.xml index b770f5b0e76d1..6a92abe7bec46 100644 --- a/administrator/components/com_languages/models/forms/filter_languages.xml +++ b/administrator/components/com_languages/models/forms/filter_languages.xml @@ -4,6 +4,7 @@ diff --git a/administrator/components/com_languages/models/forms/filter_overrides.xml b/administrator/components/com_languages/models/forms/filter_overrides.xml new file mode 100644 index 0000000000000..347a1677a72a6 --- /dev/null +++ b/administrator/components/com_languages/models/forms/filter_overrides.xml @@ -0,0 +1,33 @@ + +
    + + + + + + + + + + + +
    diff --git a/administrator/components/com_languages/models/forms/language.xml b/administrator/components/com_languages/models/forms/language.xml index afe244ed84ab7..61e900bc6844e 100644 --- a/administrator/components/com_languages/models/forms/language.xml +++ b/administrator/components/com_languages/models/forms/language.xml @@ -60,7 +60,6 @@ directory="media/mod_languages/images/" hide_none="1" hide_default="1" - required="false" filter="\.gif$" size="10" > diff --git a/administrator/components/com_languages/models/installed.php b/administrator/components/com_languages/models/installed.php index 97811176d0326..2f53b96babe55 100644 --- a/administrator/components/com_languages/models/installed.php +++ b/administrator/components/com_languages/models/installed.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -30,7 +30,7 @@ class LanguagesModelInstalled extends JModelList protected $user = null; /** - * @var boolean|JExeption True, if FTP settings should be shown, or an exeption + * @var boolean|JExeption True, if FTP settings should be shown, or an exception */ protected $ftp = null; @@ -45,12 +45,12 @@ class LanguagesModelInstalled extends JModelList protected $data = null; /** - * @var int total number pf languages + * @var int total number of languages */ protected $total = null; /** - * @var int total number pf languages installed + * @var int total number of languages installed * @deprecated 4.0 */ protected $langlist = null; @@ -83,7 +83,7 @@ public function __construct($config = array()) 'author', 'authorEmail', 'extension_id', - 'cliend_id', + 'client_id', ); } @@ -280,6 +280,7 @@ public function getData() if ($limit !== 0) { $start = (int) $this->getState('list.start', 0); + return array_slice($installedLanguages, $start, $limit); } diff --git a/administrator/components/com_languages/models/language.php b/administrator/components/com_languages/models/language.php index 5b221e58c2beb..d0313061830ec 100644 --- a/administrator/components/com_languages/models/language.php +++ b/administrator/components/com_languages/models/language.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -203,6 +203,14 @@ public function save($data) $data['sef'] = str_replace($spaces, '', $data['sef']); $data['sef'] = JApplicationHelper::stringURLSafe($data['sef']); + // Prevent saving an empty url language code + if ($data['sef'] === '') + { + $this->setError(JText::_('COM_LANGUAGES_ERROR_SEF')); + + return false; + } + // Bind the data. if (!$table->bind($data)) { @@ -252,14 +260,14 @@ public function save($data) /** * Custom clean cache method. * - * @param string $group Optional cache group name. - * @param integer $client_id Application client id. + * @param string $group Optional cache group name. + * @param integer $clientId Application client id. * * @return void * * @since 1.6 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { parent::cleanCache('_system'); parent::cleanCache('com_languages'); diff --git a/administrator/components/com_languages/models/languages.php b/administrator/components/com_languages/models/languages.php index 09fb317bb669d..21576a67809af 100644 --- a/administrator/components/com_languages/models/languages.php +++ b/administrator/components/com_languages/models/languages.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -205,14 +205,14 @@ public function delete($pks) /** * Custom clean cache method, 2 places for 2 clients. * - * @param string $group Optional cache group name. - * @param integer $client_id Application client id. + * @param string $group Optional cache group name. + * @param integer $clientId Application client id. * * @return void * * @since 1.6 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { parent::cleanCache('_system'); parent::cleanCache('com_languages'); diff --git a/administrator/components/com_languages/models/override.php b/administrator/components/com_languages/models/override.php index e76c752057425..88ce41fec68be 100644 --- a/administrator/components/com_languages/models/override.php +++ b/administrator/components/com_languages/models/override.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -42,7 +42,7 @@ public function getForm($data = array(), $loadData = true) if (!$langName) { - // If a language only exists in frontend, it's meta data cannot be + // If a language only exists in frontend, its metadata cannot be // loaded in backend at the moment, so fall back to the language tag. $langName = $language; } @@ -87,13 +87,11 @@ protected function loadFormData() */ public function getItem($pk = null) { - JLoader::register('LanguagesHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/languages.php'); - $input = JFactory::getApplication()->input; - $pk = (!empty($pk)) ? $pk : $input->get('id'); - $filename = constant('JPATH_' . strtoupper($this->getState('filter.client'))) + $pk = !empty($pk) ? $pk : $input->get('id'); + $fileName = constant('JPATH_' . strtoupper($this->getState('filter.client'))) . '/language/overrides/' . $this->getState('filter.language', 'en-GB') . '.override.ini'; - $strings = LanguagesHelper::parseFile($filename); + $strings = JLanguageHelper::parseIniFile($fileName); $result = new stdClass; $result->key = ''; @@ -105,10 +103,10 @@ public function getItem($pk = null) $result->override = $strings[$pk]; } - $opposite_filename = constant('JPATH_' . strtoupper($this->getState('filter.client') == 'site' ? 'administrator' : 'site')) + $oppositeFileName = constant('JPATH_' . strtoupper($this->getState('filter.client') == 'site' ? 'administrator' : 'site')) . '/language/overrides/' . $this->getState('filter.language', 'en-GB') . '.override.ini'; - $opposite_strings = LanguagesHelper::parseFile($opposite_filename); - $result->both = isset($opposite_strings[$pk]) && ($opposite_strings[$pk] == $strings[$pk]); + $oppositeStrings = JLanguageHelper::parseIniFile($oppositeFileName); + $result->both = isset($oppositeStrings[$pk]) && ($oppositeStrings[$pk] == $strings[$pk]); return $result; } @@ -116,16 +114,15 @@ public function getItem($pk = null) /** * Method to save the form data. * - * @param array $data The form data. - * @param boolean $opposite_client Indicates whether the override should not be created for the current client. + * @param array $data The form data. + * @param boolean $oppositeClient Indicates whether the override should not be created for the current client. * * @return boolean True on success, false otherwise. * * @since 2.5 */ - public function save($data, $opposite_client = false) + public function save($data, $oppositeClient = false) { - JLoader::register('LanguagesHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/languages.php'); jimport('joomla.filesystem.file'); $app = JFactory::getApplication(); @@ -134,7 +131,7 @@ public function save($data, $opposite_client = false) $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); // If the override should be created for both. - if ($opposite_client) + if ($oppositeClient) { $client = 1 - $client; } @@ -152,8 +149,8 @@ public function save($data, $opposite_client = false) $client = $client ? 'administrator' : 'site'; // Parse the override.ini file in oder to get the keys and strings. - $filename = constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $language . '.override.ini'; - $strings = LanguagesHelper::parseFile($filename); + $fileName = constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $language . '.override.ini'; + $strings = JLanguageHelper::parseIniFile($fileName); if (isset($strings[$data['id']])) { @@ -178,14 +175,14 @@ public function save($data, $opposite_client = false) } // Write override.ini file with the strings. - if (JLanguageHelper::saveToIniFile($filename, $strings) === false) + if (JLanguageHelper::saveToIniFile($fileName, $strings) === false) { return false; } // If the override should be stored for both clients save // it also for the other one and prevent endless recursion. - if (isset($data['both']) && $data['both'] && !$opposite_client) + if (isset($data['both']) && $data['both'] && !$oppositeClient) { return $this->save($data, true); } diff --git a/administrator/components/com_languages/models/overrides.php b/administrator/components/com_languages/models/overrides.php index a30a891923505..9291bd7192e61 100644 --- a/administrator/components/com_languages/models/overrides.php +++ b/administrator/components/com_languages/models/overrides.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -21,7 +21,7 @@ class LanguagesModelOverrides extends JModelList * * @param array $config An optional associative array of configuration settings. * - * @since 2.5 + * @since 2.5 */ public function __construct($config = array()) { @@ -50,16 +50,16 @@ public function getOverrides($all = false) return $this->cache[$store]; } - $client = in_array($this->state->get('filter.client'), array(0, 'site')) ? 'SITE' : 'ADMINISTRATOR'; + $client = strtoupper($this->getState('filter.client')); // Parse the override.ini file in order to get the keys and strings. - $filename = constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; - $strings = LanguagesHelper::parseFile($filename); + $fileName = constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; + $strings = JLanguageHelper::parseIniFile($fileName); // Delete the override.ini file if empty. - if (file_exists($filename) && empty($strings)) + if (file_exists($fileName) && $strings === array()) { - JFile::delete($filename); + JFile::delete($fileName); } // Filter the loaded strings according to the search box. @@ -112,9 +112,9 @@ public function getOverrides($all = false) /** * Method to get the total number of overrides. * - * @return int The total number of overrides. + * @return integer The total number of overrides. * - * @since 2.5 + * @since 2.5 */ public function getTotal() { @@ -147,82 +147,29 @@ public function getTotal() */ protected function populateState($ordering = 'key', $direction = 'asc') { - $app = JFactory::getApplication(); - - // Use default language of frontend for default filter. - $default = JComponentHelper::getParams('com_languages')->get('site') . '0'; + // We call populate state first so that we can then set the filter.client and filter.language properties in afterwards + parent::populateState($ordering, $direction); - $old_language_client = $app->getUserState('com_languages.overrides.filter.language_client', ''); - $language_client = $this->getUserStateFromRequest('com_languages.overrides.filter.language_client', 'filter_language_client', $default, 'cmd'); + $app = JFactory::getApplication(); - if ($old_language_client != $language_client) - { - $client = substr($language_client, -1); - $language = substr($language_client, 0, -1); - } - else - { - $client = $app->getUserState('com_languages.overrides.filter.client', 0); - $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); - } + $language_client = $this->getUserStateFromRequest('com_languages.overrides.language_client', 'language_client', '', 'cmd'); + $client = substr($language_client, -1); + $language = substr($language_client, 0, -1); // Sets the search filter. $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); $this->setState('filter.search', $search); - $this->setState('filter.language_client', $language . $client); + $this->setState('language_client', $language . $client); $this->setState('filter.client', $client ? 'administrator' : 'site'); $this->setState('filter.language', $language); + // Add the 'language_client' value to the session to display a message if none selected + $app->setUserState('com_languages.overrides.language_client', $language . $client); + // Add filters to the session because they won't be stored there by 'getUserStateFromRequest' if they aren't in the current request. $app->setUserState('com_languages.overrides.filter.client', $client); $app->setUserState('com_languages.overrides.filter.language', $language); - - // List state information - parent::populateState($ordering, $direction); - } - - /** - * Method to get all found languages of frontend and backend. - * - * The resulting array has entries of the following style: - * 0|1 => - - * - * @return array Sorted associative array of languages. - * - * @since 2.5 - */ - public function getLanguages() - { - // Try to load the data from internal storage. - if (!empty($this->cache['languages'])) - { - return $this->cache['languages']; - } - - // Get all languages of frontend and backend. - $languages = array(); - $site_languages = JLanguageHelper::getKnownLanguages(JPATH_SITE); - $admin_languages = JLanguageHelper::getKnownLanguages(JPATH_ADMINISTRATOR); - - // Create a single array of them. - foreach ($site_languages as $tag => $language) - { - $languages[$tag . '0'] = JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], JText::_('JSITE')); - } - - foreach ($admin_languages as $tag => $language) - { - $languages[$tag . '1'] = JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], JText::_('JADMINISTRATOR')); - } - - // Sort it by language tag and by client after that. - ksort($languages); - - // Add the languages to the internal cache. - $this->cache['languages'] = $languages; - - return $this->cache['languages']; } /** @@ -230,9 +177,9 @@ public function getLanguages() * * @param array $cids Array of keys to delete. * - * @return integer Number of successfully deleted overrides, boolean false if an error occurred. + * @return integer Number of successfully deleted overrides, boolean false if an error occurred. * - * @since 2.5 + * @since 2.5 */ public function delete($cids) { @@ -245,14 +192,13 @@ public function delete($cids) } jimport('joomla.filesystem.file'); - JLoader::register('LanguagesHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/languages.php'); $filterclient = JFactory::getApplication()->getUserState('com_languages.overrides.filter.client'); $client = $filterclient == 0 ? 'SITE' : 'ADMINISTRATOR'; // Parse the override.ini file in oder to get the keys and strings. - $filename = constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; - $strings = LanguagesHelper::parseFile($filename); + $fileName = constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; + $strings = JLanguageHelper::parseIniFile($fileName); // Unset strings that shall be deleted foreach ($cids as $key) @@ -264,7 +210,7 @@ public function delete($cids) } // Write override.ini file with the strings. - if (JLanguageHelper::saveToIniFile($filename, $strings) === false) + if (JLanguageHelper::saveToIniFile($fileName, $strings) === false) { return false; } @@ -277,7 +223,7 @@ public function delete($cids) /** * Removes all of the cached strings from the table. * - * @return boolean result of operation + * @return boolean result of operation * * @since 3.4.2 */ diff --git a/administrator/components/com_languages/models/strings.php b/administrator/components/com_languages/models/strings.php index f3f7b84d52c0e..65ad26b91c47b 100644 --- a/administrator/components/com_languages/models/strings.php +++ b/administrator/components/com_languages/models/strings.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -44,8 +44,8 @@ public function refresh() // Create the insert query. $query = $this->_db->getQuery(true) - ->insert($this->_db->quoteName('#__overrider')) - ->columns('constant, string, file'); + ->insert($this->_db->quoteName('#__overrider')) + ->columns('constant, string, file'); // Initialize some variables. $client = $app->getUserState('com_languages.overrides.filter.client', 'site') ? 'administrator' : 'site'; @@ -61,20 +61,20 @@ public function refresh() if (is_dir($path)) { - $files = JFolder::files($path, $language . '.*ini$', false, true); + $files = JFolder::files($path, '.*ini$', false, true); } // Parse language directories of components. - $files = array_merge($files, JFolder::files($base . '/components', $language . '.*ini$', 3, true)); + $files = array_merge($files, JFolder::files($base . '/components', '.*ini$', 3, true)); // Parse language directories of modules. - $files = array_merge($files, JFolder::files($base . '/modules', $language . '.*ini$', 3, true)); + $files = array_merge($files, JFolder::files($base . '/modules', '.*ini$', 3, true)); // Parse language directories of templates. - $files = array_merge($files, JFolder::files($base . '/templates', $language . '.*ini$', 3, true)); + $files = array_merge($files, JFolder::files($base . '/templates', '.*ini$', 3, true)); // Parse language directories of plugins. - $files = array_merge($files, JFolder::files(JPATH_PLUGINS, $language . '.*ini$', 3, true)); + $files = array_merge($files, JFolder::files(JPATH_PLUGINS, '.*ini$', 4, true)); // Parse all found ini files and add the strings to the database cache. foreach ($files as $file) @@ -111,7 +111,7 @@ public function refresh() /** * Method for searching language strings. * - * @return array Array of resuls on success, Exception object otherwise. + * @return array Array of results on success, Exception object otherwise. * * @since 2.5 */ @@ -148,7 +148,7 @@ public function search() // Check whether there are more results than already loaded. $query->clear('select')->clear('limit') - ->select('COUNT(id)'); + ->select('COUNT(id)'); $this->_db->setQuery($query); if ($this->_db->loadResult() > $limitstart + 10) diff --git a/administrator/components/com_languages/views/installed/tmpl/default.php b/administrator/components/com_languages/views/installed/tmpl/default.php index 858eaa16ef1c2..524e8c42fb56a 100644 --- a/administrator/components/com_languages/views/installed/tmpl/default.php +++ b/administrator/components/com_languages/views/installed/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -100,8 +100,9 @@ published, $i, 'installed.', !$row->published && $canChange); ?> + - version, 0, 3) != $version::RELEASE || substr($row->version, 0, 5) != $currentShortVersion) : ?> + version, $minorVersion) !== 0 || strpos($row->version, $currentShortVersion) !== 0) : ?> version; ?> version; ?> diff --git a/administrator/components/com_languages/views/installed/view.html.php b/administrator/components/com_languages/views/installed/view.html.php index 725eebe0eccd8..3f6b23aeb4ab7 100644 --- a/administrator/components/com_languages/views/installed/view.html.php +++ b/administrator/components/com_languages/views/installed/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/views/language/tmpl/edit.php b/administrator/components/com_languages/views/language/tmpl/edit.php index e47d89fb8751a..e900b1318a3fb 100644 --- a/administrator/components/com_languages/views/language/tmpl/edit.php +++ b/administrator/components/com_languages/views/language/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/views/language/view.html.php b/administrator/components/com_languages/views/language/view.html.php index 6dca29fbdabfb..b785638595b7a 100644 --- a/administrator/components/com_languages/views/language/view.html.php +++ b/administrator/components/com_languages/views/language/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/views/languages/tmpl/default.php b/administrator/components/com_languages/views/languages/tmpl/default.php index f98dde1fbbc62..f7f55dfb733fa 100644 --- a/administrator/components/com_languages/views/languages/tmpl/default.php +++ b/administrator/components/com_languages/views/languages/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/views/languages/view.html.php b/administrator/components/com_languages/views/languages/view.html.php index f7b455bc278f6..7bdab4a57cc09 100644 --- a/administrator/components/com_languages/views/languages/view.html.php +++ b/administrator/components/com_languages/views/languages/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/views/multilangstatus/tmpl/default.php b/administrator/components/com_languages/views/multilangstatus/tmpl/default.php index 1cf0404029675..4808ebb287fe6 100644 --- a/administrator/components/com_languages/views/multilangstatus/tmpl/default.php +++ b/administrator/components/com_languages/views/multilangstatus/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -84,11 +84,21 @@ + published == -2) : ?> + + + + + + lang_code); ?> + + + listUsersError) : ?> - + - + @@ -195,10 +205,18 @@ - lang_code && $status->published) : ?> + lang_code && $status->published == 1) : ?> + lang_code && $status->published == 0) : ?> + + + + lang_code && $status->published == -2) : ?> + + + @@ -213,7 +231,6 @@ - @@ -242,9 +259,9 @@ + - diff --git a/administrator/components/com_languages/views/multilangstatus/view.html.php b/administrator/components/com_languages/views/multilangstatus/view.html.php index 8f0e95eeaa3fc..1ea2c2923203f 100644 --- a/administrator/components/com_languages/views/multilangstatus/view.html.php +++ b/administrator/components/com_languages/views/multilangstatus/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/views/override/tmpl/edit.php b/administrator/components/com_languages/views/override/tmpl/edit.php index c5509debec431..b46295c528b9d 100644 --- a/administrator/components/com_languages/views/override/tmpl/edit.php +++ b/administrator/components/com_languages/views/override/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_languages/views/override/view.html.php b/administrator/components/com_languages/views/override/view.html.php index 0e33acfd298ff..d1a77d248e65d 100644 --- a/administrator/components/com_languages/views/override/view.html.php +++ b/administrator/components/com_languages/views/override/view.html.php @@ -3,14 +3,14 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** - * View to edit an language override + * View to edit a language override * * @since 2.5 */ @@ -55,6 +55,17 @@ public function display($tpl = null) $this->item = $this->get('Item'); $this->state = $this->get('State'); + $app = JFactory::getApplication(); + + $languageClient = $app->getUserStateFromRequest('com_languages.overrides.language_client', 'language_client'); + + if ($languageClient == null) + { + $app->enqueueMessage(JText::_('COM_LANGUAGES_OVERRIDE_FIRST_SELECT_MESSAGE'), 'warning'); + + $app->redirect('index.php?option=com_languages&view=overrides'); + } + // Check for errors. if (count($errors = $this->get('Errors'))) { diff --git a/administrator/components/com_languages/views/overrides/tmpl/default.php b/administrator/components/com_languages/views/overrides/tmpl/default.php index 5de95f42ae144..6f7c19a936361 100644 --- a/administrator/components/com_languages/views/overrides/tmpl/default.php +++ b/administrator/components/com_languages/views/overrides/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -13,15 +13,15 @@ JHtml::_('bootstrap.tooltip'); JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); -$client = $this->state->get('filter.client') == '0' ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); +$client = $this->state->get('filter.client') == 'site' ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); $language = $this->state->get('filter.language'); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); -$opposite_client = $this->state->get('filter.client') == '1' ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); -$opposite_filename = constant('JPATH_' . strtoupper(1 - $this->state->get('filter.client')? 'administrator' : 'site')) +$oppositeClient = $this->state->get('filter.client') == 'administrator' ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); +$oppositeFileName = constant('JPATH_' . strtoupper($this->state->get('filter.client') === 'site' ? 'administrator' : 'site')) . '/language/overrides/' . $this->state->get('filter.language', 'en-GB') . '.override.ini'; -$opposite_strings = LanguagesHelper::parseFile($opposite_filename); +$oppositeStrings = JLanguageHelper::parseIniFile($oppositeFileName); ?>
    @@ -33,19 +33,8 @@
    -
    - -
    - - -
    -
    - - pagination->getLimitBox(); ?> -
    -
    + $this)); ?> +
    items)) : ?>
    @@ -58,10 +47,10 @@ - + - + @@ -101,9 +90,9 @@ @@ -116,8 +105,6 @@ - -
    diff --git a/administrator/components/com_languages/views/overrides/view.html.php b/administrator/components/com_languages/views/overrides/view.html.php index 1e25e2d295abf..4c3f38492cf39 100644 --- a/administrator/components/com_languages/views/overrides/view.html.php +++ b/administrator/components/com_languages/views/overrides/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_languages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -51,10 +51,12 @@ class LanguagesViewOverrides extends JViewLegacy */ public function display($tpl = null) { - $this->state = $this->get('State'); - $this->items = $this->get('Overrides'); - $this->languages = $this->get('Languages'); - $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->items = $this->get('Overrides'); + $this->languages = $this->get('Languages'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); LanguagesHelper::addSubmenu('overrides'); @@ -112,13 +114,6 @@ protected function addToolbar() JHtmlSidebar::setAction('index.php?option=com_languages&view=overrides'); - JHtmlSidebar::addFilter( - '', - 'filter_language_client', - JHtml::_('select.options', $this->languages, null, 'text', $this->state->get('filter.language_client')), - true - ); - $this->sidebar = JHtmlSidebar::render(); } } diff --git a/administrator/components/com_login/controller.php b/administrator/components/com_login/controller.php index 7c6dc49fbf77b..a1ebb2ab3d4eb 100644 --- a/administrator/components/com_login/controller.php +++ b/administrator/components/com_login/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_login * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -53,7 +53,7 @@ public function display($cachable = false, $urlparams = false) public function login() { // Check for request forgeries. - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken('request'); $app = JFactory::getApplication(); @@ -90,7 +90,7 @@ public function login() */ public function logout() { - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken('request'); $app = JFactory::getApplication(); diff --git a/administrator/components/com_login/login.php b/administrator/components/com_login/login.php index 87665a673dd02..658eec1185968 100644 --- a/administrator/components/com_login/login.php +++ b/administrator/components/com_login/login.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_login * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_login/login.xml b/administrator/components/com_login/login.xml index 0361c09f23bf9..f123edf1cfefc 100644 --- a/administrator/components/com_login/login.xml +++ b/administrator/components/com_login/login.xml @@ -3,7 +3,7 @@ com_login Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_login/models/login.php b/administrator/components/com_login/models/login.php index 360a5525cdfe8..0eaa6bb0bff2c 100644 --- a/administrator/components/com_login/models/login.php +++ b/administrator/components/com_login/models/login.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_login * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -27,20 +27,18 @@ class LoginModelLogin extends JModelLegacy */ protected function populateState() { - $app = JFactory::getApplication(); - - $input = $app->input; - $method = $input->getMethod(); + $input = JFactory::getApplication()->input->getInputForRequestMethod(); $credentials = array( - 'username' => $input->$method->get('username', '', 'USERNAME'), - 'password' => $input->$method->get('passwd', '', 'RAW'), - 'secretkey' => $input->$method->get('secretkey', '', 'RAW'), + 'username' => $input->get('username', '', 'USERNAME'), + 'password' => $input->get('passwd', '', 'RAW'), + 'secretkey' => $input->get('secretkey', '', 'RAW'), ); + $this->setState('credentials', $credentials); // Check for return URL from the request first. - if ($return = $input->$method->get('return', '', 'BASE64')) + if ($return = $input->get('return', '', 'BASE64')) { $return = base64_decode($return); @@ -67,7 +65,7 @@ protected function populateState() * * @return object The Module object. * - * @since 11.1 + * @since 1.7.0 */ public static function getLoginModule($name = 'mod_login', $title = null) { @@ -116,7 +114,7 @@ public static function getLoginModule($name = 'mod_login', $title = null) * * @return array * - * @since 11.1 + * @since 1.7.0 */ protected static function _load($module) { diff --git a/administrator/components/com_login/views/login/tmpl/default.php b/administrator/components/com_login/views/login/tmpl/default.php index 909bc162cf18b..958bc5a01eb1c 100644 --- a/administrator/components/com_login/views/login/tmpl/default.php +++ b/administrator/components/com_login/views/login/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_login * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_login/views/login/view.html.php b/administrator/components/com_login/views/login/view.html.php index 0297dc3f4fff8..e3a8d45ab33be 100644 --- a/administrator/components/com_login/views/login/view.html.php +++ b/administrator/components/com_login/views/login/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_login * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,7 +16,7 @@ */ class LoginViewLogin extends JViewLegacy { - /** + /** * Display the view. * * @param string $tpl The name of the template file to parse. @@ -30,7 +30,7 @@ public function display($tpl = null) /** * To prevent clickjacking, only allow the login form to be used inside a frame in the same origin. * So send a X-Frame-Options HTTP Header with the SAMEORIGIN value. - * + * * @link https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet * @link https://tools.ietf.org/html/rfc7034 */ diff --git a/administrator/components/com_media/config.xml b/administrator/components/com_media/config.xml index 6ef06cfff1e74..fcbc171bf7ae5 100644 --- a/administrator/components/com_media/config.xml +++ b/administrator/components/com_media/config.xml @@ -1,6 +1,6 @@ -
    @@ -32,9 +34,11 @@ name="file_path" type="text" label="COM_MEDIA_FIELD_PATH_FILE_FOLDER_LABEL" - description="COM_MEDIA_FIELD_PATH_FILE_FOLDER_DESC" + description="COM_MEDIA_FIELD_PATH_FILE_FOLDER_DESC" size="50" default="images" + validate="filePath" + exclude="administrator|api|bin|cache|cli|components|includes|language|layouts|libraries|media|modules|plugins|templates|tmp" /> @@ -77,13 +84,14 @@ description="COM_MEDIA_FIELD_LEGAL_IMAGE_EXTENSIONS_DESC" size="50" default="bmp,gif,jpg,png" + showon="restrict_uploads:1" /> @@ -94,6 +102,7 @@ description="COM_MEDIA_FIELD_LEGAL_MIME_TYPES_DESC" size="50" default="image/jpeg,image/gif,image/png,image/bmp,application/msword,application/excel,application/pdf,application/powerpoint,text/plain,application/x-zip" + showon="restrict_uploads:1" /> + showon="restrict_uploads:1" + />
    * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_media/controllers/file.json.php b/administrator/components/com_media/controllers/file.json.php index f3dc02b1cf28b..6e5b238027236 100644 --- a/administrator/components/com_media/controllers/file.json.php +++ b/administrator/components/com_media/controllers/file.json.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -82,10 +82,10 @@ public function upload() // Transform filename to punycode $fileparts['filename'] = JStringPunycode::toPunycode($fileparts['filename']); - $tempExt = (!empty($fileparts['extension'])) ? strtolower($fileparts['extension']) : ''; + $tempExt = !empty($fileparts['extension']) ? strtolower($fileparts['extension']) : ''; - // Transform filename to punycode, then neglect otherthan non-alphanumeric characters & underscores. Also transform extension to lowercase - $safeFileName = preg_replace(array("/[\\s]/", '/[^a-zA-Z0-9_]/'), array('_', ''), $fileparts['filename']) . '.' . $tempExt; + // Transform filename to punycode, then neglect other than non-alphanumeric characters & underscores. Also transform extension to lowercase + $safeFileName = preg_replace(array("/[\\s]/", '/[^a-zA-Z0-9_\-]/'), array('_', ''), $fileparts['filename']) . '.' . $tempExt; // Create filepath with safe-filename $files['final'] = $fileparts['dirname'] . DIRECTORY_SEPARATOR . $safeFileName; @@ -93,7 +93,8 @@ public function upload() $filepath = JPath::clean($files['final']); - if (!$mediaHelper->canUpload($file, 'com_media')) + if (!$mediaHelper->canUpload($file, 'com_media') + || strpos(realpath($fileparts['dirname']), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) { try { @@ -115,12 +116,12 @@ public function upload() return; } - // Trigger the onContentBeforeSave event. - JPluginHelper::importPlugin('content'); - $dispatcher = JEventDispatcher::getInstance(); - $object_file = new JObject($file); - $object_file->filepath = $filepath; - $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.file', &$object_file, true)); + // Trigger the onContentBeforeSave event. + JPluginHelper::importPlugin('content'); + $dispatcher = JEventDispatcher::getInstance(); + $object_file = new JObject($file); + $object_file->filepath = $filepath; + $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.file', &$object_file, true)); if (in_array(false, $result, true)) { diff --git a/administrator/components/com_media/controllers/file.php b/administrator/components/com_media/controllers/file.php index 7d5ee2952afd1..ec35086d2a76c 100644 --- a/administrator/components/com_media/controllers/file.php +++ b/administrator/components/com_media/controllers/file.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -36,7 +36,8 @@ class MediaControllerFile extends JControllerLegacy public function upload() { // Check for request forgeries - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken('request'); + $params = JComponentHelper::getParams('com_media'); // Get some data from the request @@ -44,6 +45,9 @@ public function upload() $return = JFactory::getSession()->get('com_media.return_url'); $this->folder = $this->input->get('folder', '', 'path'); + // Instantiate the media helper + $mediaHelper = new JHelperMedia; + // Don't redirect to an external URL. if (!JUri::isInternal($return)) { @@ -60,47 +64,76 @@ public function upload() $this->setRedirect('index.php?option=com_media&folder=' . $this->folder); } - // Authorize the user - if (!$this->authoriseUser('create')) + // First check against unfiltered input. + if (!$this->input->files->get('Filedata', null, 'RAW')) { - return false; - } + // Total length of post back data in bytes. + $contentLength = $this->input->server->get('CONTENT_LENGTH', 0, 'INT'); - // If there are no files to upload - then bail - if (empty($files)) - { - return false; - } + // Maximum allowed size of post back data in MB. + $postMaxSize = $mediaHelper->toBytes(ini_get('post_max_size')); - // Total length of post back data in bytes. - $contentLength = (int) $_SERVER['CONTENT_LENGTH']; + // Maximum allowed size of script execution in MB. + $memoryLimit = $mediaHelper->toBytes(ini_get('memory_limit')); - // Instantiate the media helper - $mediaHelper = new JHelperMedia; + // Check for the total size of post back data. + if (($postMaxSize > 0 && $contentLength > $postMaxSize) + || ($memoryLimit != -1 && $contentLength > $memoryLimit)) + { + // Files are too large. + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNUPLOADTOOLARGE')); - // Maximum allowed size of post back data in MB. - $postMaxSize = $mediaHelper->toBytes(ini_get('post_max_size')); + return false; + } - // Maximum allowed size of script execution in MB. - $memoryLimit = $mediaHelper->toBytes(ini_get('memory_limit')); + // No files were provided. + $this->setMessage(JText::_('COM_MEDIA_ERROR_UPLOAD_INPUT'), 'warning'); - // Check for the total size of post back data. - if (($postMaxSize > 0 && $contentLength > $postMaxSize) - || ($memoryLimit != -1 && $contentLength > $memoryLimit)) + return false; + } + + if (!$files) { - JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNUPLOADTOOLARGE')); + // Files were provided but are unsafe to upload. + $this->setMessage(JText::_('COM_MEDIA_ERROR_WARNFILENOTSAFE'), 'error'); return false; } + // Authorize the user + if (!$this->authoriseUser('create')) + { + return false; + } + $uploadMaxSize = $params->get('upload_maxsize', 0) * 1024 * 1024; $uploadMaxFileSize = $mediaHelper->toBytes(ini_get('upload_max_filesize')); // Perform basic checks on file info before attempting anything foreach ($files as &$file) { - $file['name'] = JFile::makeSafe($file['name']); - $file['name'] = str_replace(' ', '-', $file['name']); + // Make the filename safe + $file['name'] = JFile::makeSafe($file['name']); + + // We need a url safe name + $fileparts = pathinfo(COM_MEDIA_BASE . '/' . $this->folder . '/' . $file['name']); + + if (strpos(realpath($fileparts['dirname']), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNINVALID_FOLDER')); + + return false; + } + + // Transform filename to punycode, check extension and transform it to lowercase + $fileparts['filename'] = JStringPunycode::toPunycode($fileparts['filename']); + $tempExt = !empty($fileparts['extension']) ? strtolower($fileparts['extension']) : ''; + + // Neglect other than non-alphanumeric characters, hyphens & underscores. + $safeFileName = preg_replace(array("/[\\s]/", '/[^a-zA-Z0-9_\-]/'), array('_', ''), $fileparts['filename']) . '.' . $tempExt; + + $file['name'] = $safeFileName; + $file['filepath'] = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $this->folder, $file['name']))); if (($file['error'] == 1) @@ -143,7 +176,6 @@ public function upload() if (!MediaHelper::canUpload($file, $err)) { // The file can't be uploaded - return false; } @@ -178,7 +210,7 @@ public function upload() /** * Check that the user is authorized to perform this action * - * @param string $action - the action to be peformed (create or delete) + * @param string $action - the action to be performed (create or delete) * * @return boolean * @@ -206,7 +238,7 @@ protected function authoriseUser($action) */ public function delete() { - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken('request'); $user = JFactory::getUser(); @@ -253,6 +285,17 @@ public function delete() $ret = true; $safePaths = array_intersect($paths, array_map(array('JFile', 'makeSafe'), $paths)); + + foreach ($safePaths as $key => $path) + { + $fullPath = implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path)); + + if (strpos(realpath($fullPath), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + unset($safePaths[$key]); + } + } + $unsafePaths = array_diff($paths, $safePaths); foreach ($unsafePaths as $path) diff --git a/administrator/components/com_media/controllers/folder.php b/administrator/components/com_media/controllers/folder.php index 6b0da855a18fb..810382511e568 100644 --- a/administrator/components/com_media/controllers/folder.php +++ b/administrator/components/com_media/controllers/folder.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -28,7 +28,7 @@ class MediaControllerFolder extends JControllerLegacy */ public function delete() { - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken('request'); $user = JFactory::getUser(); @@ -87,6 +87,14 @@ public function delete() foreach ($safePaths as $path) { $fullPath = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path))); + + if (strpos(realpath($fullPath), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNINVALID_FOLDER')); + + continue; + } + $object_file = new JObject(array('filepath' => $fullPath)); if (is_file($object_file->filepath)) @@ -155,7 +163,7 @@ public function delete() public function create() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $user = JFactory::getUser(); @@ -190,6 +198,14 @@ public function create() $path = JPath::clean(COM_MEDIA_BASE . '/' . $parent . '/' . $folder); + if (strpos(realpath(COM_MEDIA_BASE . '/' . $parent), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + $app = JFactory::getApplication(); + $app->enqueueMessage(JText::_('COM_MEDIA_ERROR_WARNINVALID_FOLDER'), 'error'); + + return false; + } + if (!is_dir($path) && !is_file($path)) { // Trigger the onContentBeforeSave event. diff --git a/administrator/components/com_media/helpers/media.php b/administrator/components/com_media/helpers/media.php index e81aff5a1ca32..483bc59c8629e 100644 --- a/administrator/components/com_media/helpers/media.php +++ b/administrator/components/com_media/helpers/media.php @@ -3,12 +3,14 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\CMS\Object\CMSObject; + /** * Media helper class. * @@ -197,4 +199,40 @@ public static function countFiles($dir) return $mediaHelper->countFiles($dir); } + + /** + * Generates the URL to the object in the action logs component + * + * @param string $contentType The content type + * @param integer $id The integer id + * @param CMSObject $mediaObject The media object being uploaded + * + * @return string The link for the action log + * + * @since 3.9.27 + */ + public static function getContentTypeLink($contentType, $id, CMSObject $mediaObject) + { + if ($contentType === 'com_media.file') + { + return ''; + } + + $link = 'index.php?option=com_media&view=media'; + $uploadedPath = substr($mediaObject->get('filepath'), strlen(COM_MEDIA_BASE) + 1); + + // Now remove the filename + $uploadedBasePath = substr_replace( + $uploadedPath, + '', + (strlen(DIRECTORY_SEPARATOR . $mediaObject->get('name')) * -1) + ); + + if (!empty($uploadedBasePath)) + { + $link = $link . '&folder=' . $uploadedBasePath; + } + + return $link; + } } diff --git a/administrator/components/com_media/layouts/toolbar/deletemedia.php b/administrator/components/com_media/layouts/toolbar/deletemedia.php index 318d85be711e6..61dd6a34959e4 100644 --- a/administrator/components/com_media/layouts/toolbar/deletemedia.php +++ b/administrator/components/com_media/layouts/toolbar/deletemedia.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_media/layouts/toolbar/newfolder.php b/administrator/components/com_media/layouts/toolbar/newfolder.php index c8b9d57fa6c3f..ef2fda9868f86 100644 --- a/administrator/components/com_media/layouts/toolbar/newfolder.php +++ b/administrator/components/com_media/layouts/toolbar/newfolder.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_media/layouts/toolbar/uploadmedia.php b/administrator/components/com_media/layouts/toolbar/uploadmedia.php index 6c4599709f630..ca8563e9f1744 100644 --- a/administrator/components/com_media/layouts/toolbar/uploadmedia.php +++ b/administrator/components/com_media/layouts/toolbar/uploadmedia.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_media/media.php b/administrator/components/com_media/media.php index 66810dfafb499..32f98c54c5533 100644 --- a/administrator/components/com_media/media.php +++ b/administrator/components/com_media/media.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -15,7 +15,7 @@ $author = $input->get('author'); // Access check. -if (!$user->authorise('core.manage', 'com_media') && (!$asset or (!$user->authorise('core.edit', $asset) +if (!$user->authorise('core.manage', 'com_media') && (!$asset || (!$user->authorise('core.edit', $asset) && !$user->authorise('core.create', $asset) && count($user->getAuthorisedCategories($asset, 'core.create')) == 0) && !($user->id == $author && $user->authorise('core.edit.own', $asset)))) @@ -38,7 +38,14 @@ $path = 'image_path'; } -define('COM_MEDIA_BASE', JPATH_ROOT . '/' . $params->get($path, 'images')); +$mediaBaseDir = JPATH_ROOT . '/' . $params->get($path, 'images'); + +if (!is_dir($mediaBaseDir)) +{ + throw new \InvalidArgumentException(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 500); +} + +define('COM_MEDIA_BASE', $mediaBaseDir); define('COM_MEDIA_BASEURL', JUri::root() . $params->get($path, 'images')); $controller = JControllerLegacy::getInstance('Media', array('base_path' => JPATH_COMPONENT_ADMINISTRATOR)); diff --git a/administrator/components/com_media/media.xml b/administrator/components/com_media/media.xml index d4e454590c9f0..5a02ffcc185cf 100644 --- a/administrator/components/com_media/media.xml +++ b/administrator/components/com_media/media.xml @@ -3,7 +3,7 @@ com_media Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_media/models/list.php b/administrator/components/com_media/models/list.php index 1d6fd526c3839..129bca4144c60 100644 --- a/administrator/components/com_media/models/list.php +++ b/administrator/components/com_media/models/list.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -113,6 +113,12 @@ public function getList() $basePath = COM_MEDIA_BASE . ((strlen($current) > 0) ? '/' . $current : ''); $mediaBase = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE . '/'); + // Reset base path + if (strpos(realpath($basePath), JPath::clean(realpath(COM_MEDIA_BASE))) !== 0) + { + $basePath = COM_MEDIA_BASE; + } + $images = array (); $folders = array (); $docs = array (); @@ -131,11 +137,13 @@ public function getList() // Iterate over the files if they exist if ($fileList !== false) { + $tmpBaseObject = new JObject; + foreach ($fileList as $file) { if (is_file($basePath . '/' . $file) && substr($file, 0, 1) != '.' && strtolower($file) !== 'index.html') { - $tmp = new JObject; + $tmp = clone $tmpBaseObject; $tmp->name = $file; $tmp->title = $file; $tmp->path = str_replace(DIRECTORY_SEPARATOR, '/', JPath::clean($basePath . '/' . $file)); @@ -209,9 +217,11 @@ public function getList() // Iterate over the folders if they exist if ($folderList !== false) { + $tmpBaseObject = new JObject; + foreach ($folderList as $folder) { - $tmp = new JObject; + $tmp = clone $tmpBaseObject; $tmp->name = basename($folder); $tmp->path = str_replace(DIRECTORY_SEPARATOR, '/', JPath::clean($basePath . '/' . $folder)); $tmp->path_relative = str_replace($mediaBase, '', $tmp->path); diff --git a/administrator/components/com_media/models/manager.php b/administrator/components/com_media/models/manager.php index a7c9c397d14ed..1a4ecd04022e5 100644 --- a/administrator/components/com_media/models/manager.php +++ b/administrator/components/com_media/models/manager.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -65,6 +65,7 @@ public function getFolderList($base = null) { $base = COM_MEDIA_BASE; } + // Corrections for windows paths $base = str_replace(DIRECTORY_SEPARATOR, '/', $base); $com_media_base_uni = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE); diff --git a/administrator/components/com_media/views/images/tmpl/default.php b/administrator/components/com_media/views/images/tmpl/default.php index 79b60094b1187..2f3cf2b739987 100644 --- a/administrator/components/com_media/views/images/tmpl/default.php +++ b/administrator/components/com_media/views/images/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,6 +16,8 @@ $onClick = ''; $fieldInput = $this->state->get('field.id'); $isMoo = $input->getInt('ismoo', 1); +$author = $input->getCmd('author'); +$asset = $input->getCmd('asset'); JHtml::_('formbehavior.chosen', 'select'); @@ -23,6 +25,7 @@ JHtml::_('bootstrap.tooltip', '.noHtmlTip', array('html' => false)); // Include jQuery +JHtml::_('behavior.core'); JHtml::_('jquery.framework'); JHtml::_('script', 'media/popup-imagemanager.min.js', array('version' => 'auto', 'relative' => true)); JHtml::_('stylesheet', 'media/popup-imagemanager.css', array('version' => 'auto', 'relative' => true)); @@ -32,10 +35,12 @@ JHtml::_('stylesheet', 'media/popup-imagemanager_rtl.css', array('version' => 'auto', 'relative' => true)); } -JFactory::getDocument()->addScriptDeclaration( - " - var image_base_path = '" . $params->get('image_path', 'images') . "/'; - " +JFactory::getDocument()->addScriptOptions( + 'mediamanager', array( + 'base' => $params->get('image_path', 'images') . '/', + 'asset' => $asset, + 'author' => $author + ) ); /** @@ -60,37 +65,39 @@ ?>
    -
    +
    -
    -
    +
    +
    - +
    folderList; ?>
    -
    - - +
    +
    + + +
    - +
    -
    +
    @@ -98,7 +105,12 @@
    - state->get('field.id')) : ?> +
    +
    + + state->get('field.id')) : ?> +
    +
    @@ -112,9 +124,7 @@
    - -
    - state->get('field.id')) : ?> +
    @@ -156,17 +166,15 @@
    - - -
    + authorise('core.create', 'com_media')) : ?> -
    +
    @@ -183,7 +191,7 @@
    - set('com_media.return_url', 'index.php?option=com_media&view=images&tmpl=component&fieldid=' . $input->getCmd('fieldid', '') . '&e_name=' . $input->getCmd('e_name') . '&asset=' . $input->getCmd('asset') . '&author=' . $input->getCmd('author')); ?> + set('com_media.return_url', 'index.php?option=com_media&view=images&tmpl=component&fieldid=' . $input->getCmd('fieldid', '') . '&e_name=' . $input->getCmd('e_name') . '&asset=' . $asset . '&author=' . $author); ?>
    diff --git a/administrator/components/com_media/views/images/view.html.php b/administrator/components/com_media/views/images/view.html.php index 43d7939e093e5..b3a242556026b 100644 --- a/administrator/components/com_media/views/images/view.html.php +++ b/administrator/components/com_media/views/images/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_media/views/imageslist/tmpl/default.php b/administrator/components/com_media/views/imageslist/tmpl/default.php index 417e19ab3eacf..8435b1d3a5f3f 100644 --- a/administrator/components/com_media/views/imageslist/tmpl/default.php +++ b/administrator/components/com_media/views/imageslist/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -27,7 +27,6 @@ @media (max-width: 767px) { li.imgOutline.thumbnail.height-80.width-80.center { float: right; - margin-right: 15px; } } ' @@ -40,7 +39,6 @@ @media (max-width: 767px) { li.imgOutline.thumbnail.height-80.width-80.center { float: left; - margin-left: 15px; } } ' diff --git a/administrator/components/com_media/views/imageslist/tmpl/default_folder.php b/administrator/components/com_media/views/imageslist/tmpl/default_folder.php index f01cf7e7dd5d9..3b1716a0d202c 100644 --- a/administrator/components/com_media/views/imageslist/tmpl/default_folder.php +++ b/administrator/components/com_media/views/imageslist/tmpl/default_folder.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -12,12 +12,12 @@ $input = JFactory::getApplication()->input; ?>
  • - +
    - _tmp_folder->name, 10, false); ?> + escape($this->_tmp_folder->name), 10, false); ?>
  • diff --git a/administrator/components/com_media/views/imageslist/tmpl/default_image.php b/administrator/components/com_media/views/imageslist/tmpl/default_image.php index 4bfffe9d6dd29..526d1b77ff39b 100644 --- a/administrator/components/com_media/views/imageslist/tmpl/default_image.php +++ b/administrator/components/com_media/views/imageslist/tmpl/default_image.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -13,18 +13,18 @@ $params = new Registry; $dispatcher = JEventDispatcher::getInstance(); -$dispatcher->trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params)); +$dispatcher->trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); ?>
  • - +
    - baseURL . '/' . $this->_tmp_img->path_relative, JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->_tmp_img->title, JHtml::_('number.bytes', $this->_tmp_img->size)), array('width' => $this->_tmp_img->width_60, 'height' => $this->_tmp_img->height_60)); ?> + baseURL . '/' . $this->escape($this->_tmp_img->path_relative), JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->escape($this->_tmp_img->title), JHtml::_('number.bytes', $this->_tmp_img->size)), array('width' => $this->_tmp_img->width_60, 'height' => $this->_tmp_img->height_60)); ?>
    - _tmp_img->name, 10, false); ?> + escape($this->_tmp_img->name), 10, false); ?>
  • trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params)); +$dispatcher->trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); diff --git a/administrator/components/com_media/views/imageslist/view.html.php b/administrator/components/com_media/views/imageslist/view.html.php index bdf82b08e8d33..5e6675157e1fb 100644 --- a/administrator/components/com_media/views/imageslist/view.html.php +++ b/administrator/components/com_media/views/imageslist/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_media/views/media/tmpl/default.php b/administrator/components/com_media/views/media/tmpl/default.php index 9f2c52160b89d..65b170559aaf6 100644 --- a/administrator/components/com_media/views/media/tmpl/default.php +++ b/administrator/components/com_media/views/media/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -77,7 +77,7 @@
    - +
    authorise('core.create', 'com_media')) : ?> @@ -94,7 +94,7 @@

    - + set('com_media.return_url', 'index.php?option=com_media'); ?> @@ -104,7 +104,7 @@
    - +
    @@ -115,7 +115,7 @@
    - +
    @@ -128,8 +128,8 @@ 'imagePreview', array( 'title' => JText::_('COM_MEDIA_PREVIEW'), - 'footer' => '', + 'footer' => '', ), '
    preview
    ' ); @@ -139,8 +139,8 @@ 'videoPreview', array( 'title' => JText::_('COM_MEDIA_PREVIEW'), - 'footer' => '', + 'footer' => '', ), '
    ' ); diff --git a/administrator/components/com_media/views/media/tmpl/default_folders.php b/administrator/components/com_media/views/media/tmpl/default_folders.php index 3930f685be7b8..3d4a61efb7391 100644 --- a/administrator/components/com_media/views/media/tmpl/default_folders.php +++ b/administrator/components/com_media/views/media/tmpl/default_folders.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -19,9 +19,9 @@ // Get a sanitised name for the target $target = str_replace('/', '-', $folder['data']->relative); ?>
  • - + - name; ?> + escape($folder['data']->name); ?> getFolderLevel($folder); ?>
  • diff --git a/administrator/components/com_media/views/media/tmpl/default_navigation.php b/administrator/components/com_media/views/media/tmpl/default_navigation.php index 3a58c552d2a09..dcf591c5a0b0e 100644 --- a/administrator/components/com_media/views/media/tmpl/default_navigation.php +++ b/administrator/components/com_media/views/media/tmpl/default_navigation.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -12,7 +12,7 @@ $style = $app->getUserStateFromRequest('media.list.layout', 'layout', 'thumbs', 'word'); ?> -
    +
    diff --git a/administrator/components/com_media/views/media/view.html.php b/administrator/components/com_media/views/media/view.html.php index 290fbb54ed877..ad7aa43b6da10 100644 --- a/administrator/components/com_media/views/media/view.html.php +++ b/administrator/components/com_media/views/media/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_media/views/medialist/tmpl/default.php b/administrator/components/com_media/views/medialist/tmpl/default.php index 3b47bf1368389..9d5d076e8a7f4 100644 --- a/administrator/components/com_media/views/medialist/tmpl/default.php +++ b/administrator/components/com_media/views/medialist/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_media/views/medialist/tmpl/details.php b/administrator/components/com_media/views/medialist/tmpl/details.php index 4040694111205..4763c0092e8dc 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details.php +++ b/administrator/components/com_media/views/medialist/tmpl/details.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -81,13 +81,13 @@ " ); ?> - +

    get($path, 'images'), - ($this->state->folder != '') ? '/' . $this->state->folder : ''; + ($this->escape($this->state->folder) != '') ? '/' . $this->escape($this->state->folder) : ''; ?>

    diff --git a/administrator/components/com_media/views/medialist/tmpl/details_doc.php b/administrator/components/com_media/views/medialist/tmpl/details_doc.php index 6744e2e2ddbc7..b42a1477c15c4 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details_doc.php +++ b/administrator/components/com_media/views/medialist/tmpl/details_doc.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -15,16 +15,16 @@ $user = JFactory::getUser(); $params = new Registry; $dispatcher = JEventDispatcher::getInstance(); -$dispatcher->trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_doc, &$params)); +$dispatcher->trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_doc, &$params, 0)); ?> -
    - _tmp_doc->icon_16, $this->_tmp_doc->title, null, true, true) ? JHtml::_('image', $this->_tmp_doc->icon_16, $this->_tmp_doc->title, array('width' => 16, 'height' => 16), true) : JHtml::_('image', 'media/con_info.png', $this->_tmp_doc->title, array('width' => 16, 'height' => 16), true);?> + + _tmp_doc->icon_16, $this->escape($this->_tmp_doc->title), null, true, true) ? JHtml::_('image', $this->_tmp_doc->icon_16, $this->_tmp_doc->title, array('width' => 16, 'height' => 16), true) : JHtml::_('image', 'media/con_info.png', $this->escape($this->_tmp_doc->title), array('width' => 16, 'height' => 16), true);?> - - _tmp_doc->title; ?> + + escape($this->_tmp_doc->title); ?>   @@ -34,9 +34,9 @@ authorise('core.delete', 'com_media')):?> - - + + -trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_doc, &$params)); +trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_doc, &$params, 0)); diff --git a/administrator/components/com_media/views/medialist/tmpl/details_docs.php b/administrator/components/com_media/views/medialist/tmpl/details_docs.php index 6fd6b83801b9c..0ce3da1fdbf36 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details_docs.php +++ b/administrator/components/com_media/views/medialist/tmpl/details_docs.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -17,22 +17,22 @@ ?> documents as $i => $doc) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$doc, &$params)); ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$doc, &$params, 0)); ?> canDelete) : ?> - name, false, 'rm', 'cb-document'); ?> + escape($doc->name), false, 'rm', 'cb-document'); ?> - - icon_16, $doc->title, null, true, true) ? JHtml::_('image', $doc->icon_16, $doc->title, array('width' => 16, 'height' => 16), true) : JHtml::_('image', 'media/con_info.png', $doc->title, array('width' => 16, 'height' => 16), true); ?> + + icon_16, $this->escape($doc->title), null, true, true) ? JHtml::_('image', $doc->icon_16, $this->escape($doc->title), array('width' => 16, 'height' => 16), true) : JHtml::_('image', 'media/con_info.png', $this->escape($doc->title), array('width' => 16, 'height' => 16), true); ?> - - title; ?> + + escape($doc->title); ?>   @@ -43,12 +43,12 @@ canDelete) : ?> - + - trigger('onContentAfterDisplay', array('com_media.file', &$doc, &$params)); ?> + trigger('onContentAfterDisplay', array('com_media.file', &$doc, &$params, 0)); ?> diff --git a/administrator/components/com_media/views/medialist/tmpl/details_folder.php b/administrator/components/com_media/views/medialist/tmpl/details_folder.php index 1dfb74c69f9bb..e07975054180a 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details_folder.php +++ b/administrator/components/com_media/views/medialist/tmpl/details_folder.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -14,11 +14,11 @@ ?> - + - _tmp_folder->name; ?> + escape($this->_tmp_folder->name); ?>   @@ -28,7 +28,7 @@ authorise('core.delete', 'com_media')):?> - + diff --git a/administrator/components/com_media/views/medialist/tmpl/details_folders.php b/administrator/components/com_media/views/medialist/tmpl/details_folders.php index b8d74b2b8bab7..3d1df77d320ae 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details_folders.php +++ b/administrator/components/com_media/views/medialist/tmpl/details_folders.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -12,11 +12,11 @@ ?> folders as $i => $folder) : ?> - path_relative; ?> + path_relative); ?> canDelete) : ?> - name, false, 'rm', 'cb-folder'); ?> + escape($folder->name), false, 'rm', 'cb-folder'); ?> @@ -24,7 +24,7 @@ - name; ?> + escape($folder->name); ?>   @@ -33,7 +33,7 @@ canDelete) : ?> - + diff --git a/administrator/components/com_media/views/medialist/tmpl/details_img.php b/administrator/components/com_media/views/medialist/tmpl/details_img.php index 542af0e6e7926..b3fd42dd20e5a 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details_img.php +++ b/administrator/components/com_media/views/medialist/tmpl/details_img.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,15 +16,15 @@ $user = JFactory::getUser(); $params = new Registry; $dispatcher = JEventDispatcher::getInstance(); -$dispatcher->trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params)); +$dispatcher->trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); ?> - _tmp_img->path_relative, JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->_tmp_img->title, JHtml::_('number.bytes', $this->_tmp_img->size)), array('width' => $this->_tmp_img->width_16, 'height' => $this->_tmp_img->height_16)); ?> + escape($this->_tmp_img->path_relative), JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->_tmp_img->title, JHtml::_('number.bytes', $this->_tmp_img->size)), array('width' => $this->_tmp_img->width_16, 'height' => $this->_tmp_img->height_16)); ?> - escape($this->_tmp_img->title); ?> + escape($this->_tmp_img->title); ?> _tmp_img->width, $this->_tmp_img->height); ?> @@ -34,9 +34,9 @@ authorise('core.delete', 'com_media')):?> - - + + -trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params)); +trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params, 0)); diff --git a/administrator/components/com_media/views/medialist/tmpl/details_imgs.php b/administrator/components/com_media/views/medialist/tmpl/details_imgs.php index 0125006e823c4..657cae7687538 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details_imgs.php +++ b/administrator/components/com_media/views/medialist/tmpl/details_imgs.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -19,22 +19,22 @@ ?> images as $i => $image) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$image, &$params)); ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$image, &$params, 0)); ?> canDelete) : ?> - name, false, 'rm', 'cb-image'); ?> + escape($image->name), false, 'rm', 'cb-image'); ?> - - path_relative, JText::sprintf('COM_MEDIA_IMAGE_TITLE', $image->title, JHtml::_('number.bytes', $image->size)), array('width' => $image->width_16, 'height' => $image->height_16)); ?> + + escape($image->path_relative), JText::sprintf('COM_MEDIA_IMAGE_TITLE', $this->escape($image->title), JHtml::_('number.bytes', $image->size)), array('width' => $image->width_16, 'height' => $image->height_16)); ?> - + escape($image->title); ?> @@ -49,11 +49,11 @@ canDelete) : ?> - + - trigger('onContentAfterDisplay', array('com_media.file', &$image, &$params)); ?> + trigger('onContentAfterDisplay', array('com_media.file', &$image, &$params, 0)); ?> diff --git a/administrator/components/com_media/views/medialist/tmpl/details_up.php b/administrator/components/com_media/views/medialist/tmpl/details_up.php index cc649e41072ff..e7ebc74f7c1a6 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details_up.php +++ b/administrator/components/com_media/views/medialist/tmpl/details_up.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -17,11 +17,11 @@   - + - .. + ..     diff --git a/administrator/components/com_media/views/medialist/tmpl/details_video.php b/administrator/components/com_media/views/medialist/tmpl/details_video.php index 2c0267228f3c3..574299ebf775d 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details_video.php +++ b/administrator/components/com_media/views/medialist/tmpl/details_video.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,7 +16,7 @@ $user = JFactory::getUser(); $params = new Registry; $dispatcher = JEventDispatcher::getInstance(); -$dispatcher->trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_video, &$params)); +$dispatcher->trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_video, &$params, 0)); JFactory::getDocument()->addScriptDeclaration(" jQuery(document).ready(function($){ @@ -29,11 +29,11 @@ - _tmp_video->icon_16, $this->_tmp_video->title, null, true); ?> + _tmp_video->icon_16, $this->escape($this->_tmp_video->title), null, true); ?> - - _tmp_video->name, 10, false); ?> + + escape($this->_tmp_video->name), 10, false); ?> @@ -44,11 +44,11 @@ authorise('core.delete', 'com_media')):?> - - + + trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_video, &$params)); +$dispatcher->trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_video, &$params, 0)); diff --git a/administrator/components/com_media/views/medialist/tmpl/details_videos.php b/administrator/components/com_media/views/medialist/tmpl/details_videos.php index 92a402647af73..7d699ca50b6bb 100644 --- a/administrator/components/com_media/views/medialist/tmpl/details_videos.php +++ b/administrator/components/com_media/views/medialist/tmpl/details_videos.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -26,23 +26,23 @@ ?> videos as $i => $video) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$video, &$params)); ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$video, &$params, 0)); ?> canDelete) : ?> - name, false, 'rm', 'cb-video'); ?> + escape($video->name), false, 'rm', 'cb-video'); ?> - - icon_16, $video->title, null, true); ?> + + icon_16, $this->escape($video->title), null, true); ?> - - name, 10, false); ?> + + escape($video->name); ?> @@ -56,12 +56,12 @@ canDelete) : ?> - + - trigger('onContentAfterDisplay', array('com_media.file', &$video, &$params)); ?> + trigger('onContentAfterDisplay', array('com_media.file', &$video, &$params, 0)); ?> diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs.php b/administrator/components/com_media/views/medialist/tmpl/thumbs.php index beed908cc2323..f1b220c2e528d 100644 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs.php +++ b/administrator/components/com_media/views/medialist/tmpl/thumbs.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -81,13 +81,13 @@ " ); ?> - + diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php b/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php index a236fb0ea65f7..5556f4297e8c3 100644 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php +++ b/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,25 +16,25 @@ ?> documents as $i => $doc) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$doc, &$params)); ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$doc, &$params, 0)); ?>
  • canDelete) : ?> - × + ×
    - name, false, 'rm', 'cb-document'); ?> + escape($doc->name), false, 'rm', 'cb-document'); ?>
    -
    - name, 10, false); ?> +
    + escape($doc->name), 10, false); ?>
  • - trigger('onContentAfterDisplay', array('com_media.file', &$doc, &$params)); ?> + trigger('onContentAfterDisplay', array('com_media.file', &$doc, &$params, 0)); ?> diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php b/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php index 7cf4d37efbc68..0e2f01338018a 100644 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php +++ b/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -13,22 +13,22 @@ folders as $i => $folder) : ?>
  • canDelete) : ?> - × + ×
    - name, false, 'rm', 'cb-folder'); ?> + escape($folder->name), false, 'rm', 'cb-folder'); ?>
  • diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs_imgs.php b/administrator/components/com_media/views/medialist/tmpl/thumbs_imgs.php index 9140ed8326495..980a0006be039 100644 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_imgs.php +++ b/administrator/components/com_media/views/medialist/tmpl/thumbs_imgs.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,29 +16,29 @@ ?> images as $i => $img) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$img, &$params)); ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$img, &$params, 0)); ?>
  • canDelete) : ?> × + href="index.php?option=com_media&task=file.delete&tmpl=index&=1&folder=state->folder); ?>&rm[]=escape($img->name); ?>" + rel="escape($img->name); ?>" title="">×
    - name, false, 'rm', 'cb-image'); ?> + escape($img->name), false, 'rm', 'cb-image'); ?>
  • - trigger('onContentAfterDisplay', array('com_media.file', &$img, &$params)); ?> + trigger('onContentAfterDisplay', array('com_media.file', &$img, &$params, 0)); ?> diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php b/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php index 862ff075b0a00..d33002dc90ea2 100644 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php +++ b/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -13,7 +13,7 @@
  • @@ -21,7 +21,7 @@  
  • - .. + ..
    diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php b/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php index b0062f4844cc5..ed0edc0a07ed5 100644 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php +++ b/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -23,25 +23,25 @@ "); ?> videos as $i => $video) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$video, &$params)); ?> + trigger('onContentBeforeDisplay', array('com_media.file', &$video, &$params, 0)); ?>
  • canDelete) : ?> - × + ×
    - name, false, 'rm', 'cb-video'); ?> + escape($video->name), false, 'rm', 'cb-video'); ?>
    - icon_32, $video->title, null, true); ?> + icon_32, $this->escape($video->title), null, true); ?>
  • - trigger('onContentAfterDisplay', array('com_media.file', &$video, &$params)); ?> + trigger('onContentAfterDisplay', array('com_media.file', &$video, &$params, 0)); ?> diff --git a/administrator/components/com_media/views/medialist/view.html.php b/administrator/components/com_media/views/medialist/view.html.php index 7a135f28df8fc..8a958207ed3dc 100644 --- a/administrator/components/com_media/views/medialist/view.html.php +++ b/administrator/components/com_media/views/medialist/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_media * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/controller.php b/administrator/components/com_menus/controller.php index 21823c69557a0..cf2cf0c3993ea 100644 --- a/administrator/components/com_menus/controller.php +++ b/administrator/components/com_menus/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -30,6 +30,48 @@ public function display($cachable = false, $urlparams = false) { JLoader::register('MenusHelper', JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php'); + // Check custom administrator menu modules + if (JModuleHelper::isAdminMultilang()) + { + $languages = JLanguageHelper::getInstalledLanguages(1, true); + $langCodes = array(); + + foreach ($languages as $language) + { + if (isset($language->metadata['nativeName'])) + { + $languageName = $language->metadata['nativeName']; + } + else + { + $languageName = $language->metadata['name']; + } + + $langCodes[$language->metadata['tag']] = $languageName; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select($db->qn('m.language')) + ->from($db->qn('#__modules', 'm')) + ->where($db->qn('m.module') . ' = ' . $db->quote('mod_menu')) + ->where($db->qn('m.published') . ' = 1') + ->where($db->qn('m.client_id') . ' = 1') + ->group($db->qn('m.language')); + + $mLanguages = $db->setQuery($query)->loadColumn(); + + // Check if we have a mod_menu module set to All languages or a mod_menu module for each admin language. + if (!in_array('*', $mLanguages) && count($langMissing = array_diff(array_keys($langCodes), $mLanguages))) + { + $app = JFactory::getApplication(); + $langMissing = array_intersect_key($langCodes, array_flip($langMissing)); + + $app->enqueueMessage(JText::sprintf('JMENU_MULTILANG_WARNING_MISSING_MODULES', implode(', ', $langMissing)), 'warning'); + } + } + return parent::display(); } } diff --git a/administrator/components/com_menus/controllers/ajax.json.php b/administrator/components/com_menus/controllers/ajax.json.php new file mode 100644 index 0000000000000..b3cac333d301a --- /dev/null +++ b/administrator/components/com_menus/controllers/ajax.json.php @@ -0,0 +1,88 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\LanguageHelper; + +/** + * The menu controller for ajax requests + * + * @since 3.9.0 + */ +class MenusControllerAjax extends JControllerLegacy +{ + /** + * Method to fetch associations of a menu item + * + * The method assumes that the following http parameters are passed in an Ajax Get request: + * token: the form token + * assocId: the id of the menu item whose associations are to be returned + * excludeLang: the association for this language is to be excluded + * + * @return null + * + * @since 3.9.0 + */ + public function fetchAssociations() + { + if (!JSession::checkToken('get')) + { + echo new JResponseJson(null, JText::_('JINVALID_TOKEN'), true); + } + else + { + $input = JFactory::getApplication()->input; + $extension = $input->get('extension'); + + $assocId = $input->getInt('assocId', 0); + + if ($assocId == 0) + { + echo new JResponseJson(null, JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'assocId'), true); + + return; + } + + $excludeLang = $input->get('excludeLang', '', 'STRING'); + + $associations = JLanguageAssociations::getAssociations('com_menus', '#__menu', 'com_menus.item', (int) $assocId, 'id', '', ''); + + unset($associations[$excludeLang]); + + // Add the title to each of the associated records + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_menus/tables'); + $menuTable = JTable::getInstance('Menu', 'JTable', array()); + + foreach ($associations as $lang => $association) + { + $menuTable->load($association->id); + $associations[$lang]->title = $menuTable->title; + } + + $countContentLanguages = count(LanguageHelper::getContentLanguages(array(0, 1))); + + if (count($associations) == 0) + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE'); + } + elseif ($countContentLanguages > count($associations) + 2) + { + $tags = implode(', ', array_keys($associations)); + $message = JText::sprintf('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME', $tags); + } + else + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL'); + } + + echo new JResponseJson($associations, $message); + } + } +} diff --git a/administrator/components/com_menus/controllers/item.php b/administrator/components/com_menus/controllers/item.php index 153582fcfd48a..a884eca5401a6 100644 --- a/administrator/components/com_menus/controllers/item.php +++ b/administrator/components/com_menus/controllers/item.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -135,7 +135,7 @@ public function add() */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $model = $this->getModel('Item', '', array()); @@ -156,7 +156,7 @@ public function batch($model = null) */ public function cancel($key = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $context = 'com_menus.edit.item'; @@ -172,7 +172,7 @@ public function cancel($key = null) $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend() - . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false + . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false ) ); } @@ -214,7 +214,7 @@ public function edit($key = null, $urlVar = null) * * @return string The arguments to append to the redirect URL. * - * @since 12.2 + * @since 3.0.1 */ protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') { @@ -251,7 +251,7 @@ protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') public function save($key = null, $urlVar = null) { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $model = $this->getModel('Item', '', array()); @@ -260,6 +260,12 @@ public function save($key = null, $urlVar = null) $task = $this->getTask(); $context = 'com_menus.edit.item'; + // Set the menutype should we need it. + if ($data['menutype'] !== '') + { + $app->input->set('menutype', $data['menutype']); + } + // Determine the name of the primary key for the data. if (empty($key)) { @@ -330,8 +336,12 @@ public function save($key = null, $urlVar = null) { $segments = explode(':', $data['link']); $protocol = strtolower($segments[0]); - $scheme = array('http', 'https', 'ftp', 'ftps', 'gopher', 'mailto', 'news', 'prospero', 'telnet', 'rlogin', 'tn3270', 'wais', 'url', - 'mid', 'cid', 'nntp', 'tel', 'urn', 'ldap', 'file', 'fax', 'modem', 'git', 'sms'); + $scheme = array( + 'http', 'https', 'ftp', 'ftps', 'gopher', 'mailto', + 'news', 'prospero', 'telnet', 'rlogin', 'tn3270', 'wais', + 'mid', 'cid', 'nntp', 'tel', 'urn', 'ldap', 'file', 'fax', + 'modem', 'git', 'sms', + ); if (!in_array($protocol, $scheme)) { @@ -347,24 +357,26 @@ public function save($key = null, $urlVar = null) $data = $model->validate($form, $data); + // Preprocess request fields to ensure that we remove not set or empty request params + $request = $form->getGroup('request', true); + // Check for the special 'request' entry. - if ($data['type'] == 'component' && isset($data['request']) && is_array($data['request']) && !empty($data['request'])) + if ($data['type'] == 'component' && !empty($request)) { $removeArgs = array(); - // Preprocess request fields to ensure that we remove not set or empty request params - $request = $form->getGroup('request'); + if (!isset($data['request']) || !is_array($data['request'])) + { + $data['request'] = array(); + } - if (!empty($request)) + foreach ($request as $field) { - foreach ($request as $field) - { - $fieldName = $field->getAttribute('name'); + $fieldName = $field->getAttribute('name'); - if (!isset($data['request'][$fieldName]) || $data['request'][$fieldName] == '') - { - $removeArgs[$fieldName] = ''; - } + if (!isset($data['request'][$fieldName]) || $data['request'][$fieldName] == '') + { + $removeArgs[$fieldName] = ''; } } @@ -478,8 +490,8 @@ public function save($key = null, $urlVar = null) // Redirect to the list screen. $this->setRedirect( JRoute::_( - 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend() - . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false + 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend() + . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false ) ); break; @@ -497,6 +509,8 @@ public function save($key = null, $urlVar = null) */ public function setType() { + $this->checkToken(); + $app = JFactory::getApplication(); // Get the posted values from the request. @@ -527,6 +541,9 @@ public function setType() { if (isset($type->request)) { + // Clean component name + $type->request->option = JFilterInput::getInstance()->clean($type->request->option, 'CMD'); + $component = JComponentHelper::getComponent($type->request->option); $data['component_id'] = $component->id; @@ -540,6 +557,7 @@ public function setType() } unset($data['request']); + $data['type'] = $title; if ($this->input->get('fieldtype') == 'type') diff --git a/administrator/components/com_menus/controllers/items.php b/administrator/components/com_menus/controllers/items.php index 120d9274d8b0c..f178777c85427 100644 --- a/administrator/components/com_menus/controllers/items.php +++ b/administrator/components/com_menus/controllers/items.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -50,13 +50,13 @@ public function getModel($name = 'Item', $prefix = 'MenusModel', $config = array /** * Rebuild the nested set tree. * - * @return bool False on failure or error, true on success. + * @return boolean False on failure or error, true on success. * * @since 1.6 */ public function rebuild() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $this->setRedirect('index.php?option=com_menus&view=items'); @@ -88,7 +88,7 @@ public function rebuild() */ public function saveorder() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); try { @@ -131,7 +131,7 @@ public function saveorder() public function setDefault() { // Check for request forgeries - JSession::checkToken('request') or die(JText::_('JINVALID_TOKEN')); + $this->checkToken('request'); $app = JFactory::getApplication(); @@ -174,11 +174,11 @@ public function setDefault() } $this->setRedirect( - JRoute::_( - 'index.php?option=' . $this->option . '&view=' . $this->view_list - . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false - ) - ); + JRoute::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false + ) + ); } /** @@ -191,7 +191,7 @@ public function setDefault() public function publish() { // Check for request forgeries - JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Get items to publish from the request. $cid = JFactory::getApplication()->input->get('cid', array(), 'array'); @@ -247,7 +247,6 @@ public function publish() } $this->setMessage(JText::plural($ntext, count($cid)), $messageType); - } catch (Exception $e) { @@ -274,12 +273,17 @@ public function publish() public function checkin() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); - $ids = JFactory::getApplication()->input->post->get('cid', array(), 'array'); + // Read the Ids from the post data + $cid = JFactory::getApplication()->input->post->get('cid', array(), 'array'); - $model = $this->getModel(); - $return = $model->checkin($ids); + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Run the model + $model = $this->getModel(); + $return = $model->checkin($cid); if ($return === false) { @@ -300,7 +304,7 @@ public function checkin() else { // Checkin succeeded. - $message = JText::plural($this->text_prefix . '_N_ITEMS_CHECKED_IN', count($ids)); + $message = JText::plural($this->text_prefix . '_N_ITEMS_CHECKED_IN', count($cid)); $this->setRedirect( JRoute::_( 'index.php?option=' . $this->option . '&view=' . $this->view_list diff --git a/administrator/components/com_menus/controllers/menu.php b/administrator/components/com_menus/controllers/menu.php index 3f4ccf1b20a1b..e255294140fde 100644 --- a/administrator/components/com_menus/controllers/menu.php +++ b/administrator/components/com_menus/controllers/menu.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -44,7 +44,7 @@ public function display($cachable = false, $urlparams = false) public function save($key = null, $urlVar = null) { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $data = $this->input->post->get('jform', array(), 'array'); @@ -59,7 +59,7 @@ public function save($key = null, $urlVar = null) JFactory::getApplication()->enqueueMessage($msg, 'error'); // Redirect back to the edit screen. - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit', false)); + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); return false; } @@ -78,10 +78,10 @@ public function save($key = null, $urlVar = null) return false; } - $data = $model->validate($form, $data); + $validData = $model->validate($form, $data); // Check for validation errors. - if ($data === false) + if ($validData === false) { // Get the validation messages. $errors = $model->getErrors(); @@ -98,29 +98,55 @@ public function save($key = null, $urlVar = null) $app->enqueueMessage($errors[$i], 'warning'); } } + // Save the data in the session. - $app->setUserState('com_menus.edit.menu.data', $data); + $app->setUserState($context . '.data', $data); // Redirect back to the edit screen. - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit', false)); + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); return false; } + if (isset($validData['preset'])) + { + $preset = trim($validData['preset']) ?: null; + + unset($validData['preset']); + } + // Attempt to save the data. - if (!$model->save($data)) + if (!$model->save($validData)) { // Save the data in the session. - $app->setUserState('com_menus.edit.menu.data', $data); + $app->setUserState($context . '.data', $validData); // Redirect back to the edit screen. $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit', false)); + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); return false; } - $this->setMessage(JText::_('COM_MENUS_MENU_SAVE_SUCCESS')); + // Import the preset selected + if (isset($preset) && $data['client_id'] == 1) + { + try + { + MenusHelper::installPreset($preset, $data['menutype']); + + $this->setMessage(JText::_('COM_MENUS_PRESET_IMPORT_SUCCESS')); + } + catch (Exception $e) + { + // Save was successful but the preset could not be loaded. Let it through with just a warning + $this->setMessage(JText::sprintf('COM_MENUS_PRESET_IMPORT_FAILED', $e->getMessage())); + } + } + else + { + $this->setMessage(JText::_('COM_MENUS_MENU_SAVE_SUCCESS')); + } // Redirect the user and adjust session state based on the chosen task. switch ($task) @@ -129,6 +155,7 @@ public function save($key = null, $urlVar = null) // Set the record data in the session. $recordId = $model->getState($this->context . '.id'); $this->holdEditId($context, $recordId); + $app->setUserState($context . '.data', null); // Redirect back to the edit screen. $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); @@ -153,4 +180,34 @@ public function save($key = null, $urlVar = null) break; } } + + /** + * Method to display a menu as preset xml. + * + * @return boolean True if successful, false otherwise. + * + * @since 3.8.0 + */ + public function exportXml() + { + // Check for request forgeries. + $this->checkToken(); + + $cid = $this->input->get('cid', array(), 'array'); + $model = $this->getModel('Menu'); + $item = $model->getItem(reset($cid)); + + if (!$item->menutype) + { + $this->setMessage(JText::_('COM_MENUS_SELECT_MENU_FIRST_EXPORT'), 'warning'); + + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menus', false)); + + return false; + } + + $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&menutype=' . $item->menutype . '&format=xml', false)); + + return true; + } } diff --git a/administrator/components/com_menus/controllers/menus.php b/administrator/components/com_menus/controllers/menus.php index e835b1b04e4d8..21437aa9bf417 100644 --- a/administrator/components/com_menus/controllers/menus.php +++ b/administrator/components/com_menus/controllers/menus.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -58,7 +58,7 @@ public function getModel($name = 'Menu', $prefix = 'MenusModel', $config = array public function delete() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $user = JFactory::getUser(); $app = JFactory::getApplication(); @@ -92,7 +92,7 @@ public function delete() // Remove the items. if (!$model->delete($cids)) { - $this->setMessage($model->getError()); + $this->setMessage($model->getError(), 'error'); } else { @@ -107,13 +107,13 @@ public function delete() /** * Rebuild the menu tree. * - * @return bool False on failure or error, true on success. + * @return boolean False on failure or error, true on success. * * @since 1.6 */ public function rebuild() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $this->setRedirect('index.php?option=com_menus&view=menus'); diff --git a/administrator/components/com_menus/helpers/associations.php b/administrator/components/com_menus/helpers/associations.php index 52a4245299e73..71bd99aa8fa47 100644 --- a/administrator/components/com_menus/helpers/associations.php +++ b/administrator/components/com_menus/helpers/associations.php @@ -3,20 +3,20 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Association\AssociationExtensionHelper; /** * Menu associations helper. * * @since 3.7.0 */ -class MenusAssociationsHelper extends JAssociationExtensionHelper +class MenusAssociationsHelper extends AssociationExtensionHelper { /** * The extension name @@ -130,7 +130,6 @@ public function getType($typeName = '') if (in_array($typeName, $this->itemTypes)) { - switch ($typeName) { case 'item': diff --git a/administrator/components/com_menus/helpers/html/menus.php b/administrator/components/com_menus/helpers/html/menus.php index 6212b2df1e95c..2bd1c4014ef94 100644 --- a/administrator/components/com_menus/helpers/html/menus.php +++ b/administrator/components/com_menus/helpers/html/menus.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -50,6 +50,7 @@ public static function association($itemid) ->from('#__menu as m') ->join('LEFT', '#__menu_types as mt ON mt.menutype=m.menutype') ->where('m.id IN (' . implode(',', array_values($associations)) . ')') + ->where('m.id != ' . $itemid) ->join('LEFT', '#__languages as l ON m.language=l.lang_code') ->select('l.image') ->select('l.title as language_title'); diff --git a/administrator/components/com_menus/helpers/menus.php b/administrator/components/com_menus/helpers/menus.php index c255900616ddb..55b525c6e0675 100644 --- a/administrator/components/com_menus/helpers/menus.php +++ b/administrator/components/com_menus/helpers/menus.php @@ -3,10 +3,14 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ +use Joomla\CMS\Menu\MenuHelper; +use Joomla\Registry\Registry; +use Joomla\Utilities\ArrayHelper; + defined('_JEXEC') or die; /** @@ -18,6 +22,8 @@ class MenusHelper { /** * Defines the valid request variables for the reverse lookup. + * + * @since 1.6 */ protected static $_filter = array('option', 'view', 'layout'); @@ -178,7 +184,8 @@ public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, a.template_style_id, a.checked_out, a.language, - a.lft') + a.lft' + ) ->from('#__menu AS a'); $query->select('e.name as componentname, e.element') @@ -321,4 +328,247 @@ public static function getAssociations($pk) return $associations; } + + /** + * Load the menu items from database for the given menutype + * + * @param string $menutype The selected menu type + * @param boolean $enabledOnly Whether to load only enabled/published menu items. + * @param int[] $exclude The menu items to exclude from the list + * + * @return array + * + * @since 3.8.0 + * + * @deprecated 4.0 This method will return a node object to iterate over in 4.0. + */ + public static function getMenuItems($menutype, $enabledOnly = false, $exclude = array()) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + // Prepare the query. + $query->select('m.*') + ->from('#__menu AS m') + ->where('m.menutype = ' . $db->q($menutype)) + ->where('m.client_id = 1') + ->where('m.id > 1'); + + if ($enabledOnly) + { + $query->where('m.published = 1'); + } + + // Filter on the enabled states. + $query->select('e.element') + ->join('LEFT', '#__extensions AS e ON m.component_id = e.extension_id') + ->where('(e.enabled = 1 OR e.enabled IS NULL)'); + + if (count($exclude)) + { + $exId = array_filter($exclude, 'is_numeric'); + $exEl = array_filter($exclude, 'is_string'); + + if ($exId) + { + $query->where('m.id NOT IN (' . implode(', ', array_map('intval', $exId)) . ')'); + $query->where('m.parent_id NOT IN (' . implode(', ', array_map('intval', $exId)) . ')'); + } + + if ($exEl) + { + $query->where('e.element NOT IN (' . implode(', ', $db->quote($exEl)) . ')'); + } + } + + // Order by lft. + $query->order('m.lft'); + + $db->setQuery($query); + + try + { + $menuItems = $db->loadObjectList(); + + foreach ($menuItems as &$menuitem) + { + $menuitem->params = new Registry($menuitem->params); + } + } + catch (RuntimeException $e) + { + $menuItems = array(); + + JFactory::getApplication()->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error'); + } + + return $menuItems; + } + + /** + * Method to install a preset menu into database and link them to the given menutype + * + * @param string $preset The preset name + * @param string $menutype The target menutype + * + * @return void + * + * @throws Exception + * + * @since 3.8.0 + */ + public static function installPreset($preset, $menutype) + { + $items = MenuHelper::loadPreset($preset, false); + + if (count($items) == 0) + { + throw new Exception(JText::_('COM_MENUS_PRESET_LOAD_FAILED')); + } + + static::installPresetItems($items, $menutype, 1); + } + + /** + * Method to install a preset menu item into database and link it to the given menutype + * + * @param stdClass[] $items The single menuitem instance with a list of its descendants + * @param string $menutype The target menutype + * @param int $parent The parent id or object + * + * @return void + * + * @throws Exception + * + * @since 3.8.0 + */ + protected static function installPresetItems(&$items, $menutype, $parent = 1) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + static $components = array(); + + if (!$components) + { + $query->select('extension_id, element')->from('#__extensions')->where('type = ' . $db->q('component')); + $components = $db->setQuery($query)->loadObjectList(); + $components = ArrayHelper::getColumn((array) $components, 'element', 'extension_id'); + } + + $dispatcher = JEventDispatcher::getInstance(); + $dispatcher->trigger('onPreprocessMenuItems', array('com_menus.administrator.import', &$items, null, true)); + + foreach ($items as &$item) + { + /** @var JTableMenu $table */ + $table = JTable::getInstance('Menu'); + + $item->alias = $menutype . '-' . $item->title; + + if ($item->type == 'separator') + { + // Do not reuse a separator + $item->title = $item->title ?: '-'; + $item->alias = microtime(true); + } + elseif ($item->type == 'heading' || $item->type == 'container') + { + // Try to match an existing record to have minimum collision for a heading + $keys = array( + 'menutype' => $menutype, + 'type' => $item->type, + 'title' => $item->title, + 'parent_id' => $parent, + 'client_id' => 1, + ); + $table->load($keys); + } + elseif ($item->type == 'url' || $item->type == 'component') + { + if (substr($item->link, 0, 8) === 'special:') + { + $special = substr($item->link, 8); + + if ($special === 'language-forum') + { + $item->link = 'index.php?option=com_admin&view=help&layout=langforum'; + } + elseif ($special === 'custom-forum') + { + $item->link = ''; + } + } + + // Try to match an existing record to have minimum collision for a link + $keys = array( + 'menutype' => $menutype, + 'type' => $item->type, + 'link' => $item->link, + 'parent_id' => $parent, + 'client_id' => 1, + ); + $table->load($keys); + } + + // Translate "hideitems" param value from "element" into "menu-item-id" + if ($item->type == 'container' && count($hideitems = (array) $item->params->get('hideitems'))) + { + foreach ($hideitems as &$hel) + { + if (!is_numeric($hel)) + { + $hel = array_search($hel, $components); + } + } + + $query->clear()->select('id')->from('#__menu')->where('component_id IN (' . implode(', ', $hideitems) . ')'); + $hideitems = $db->setQuery($query)->loadColumn(); + + $item->params->set('hideitems', $hideitems); + } + + $record = array( + 'menutype' => $menutype, + 'title' => $item->title, + 'alias' => $item->alias, + 'type' => $item->type, + 'link' => $item->link, + 'browserNav' => $item->browserNav ? 1 : 0, + 'img' => $item->class, + 'access' => $item->access, + 'component_id' => array_search($item->element, $components), + 'parent_id' => $parent, + 'client_id' => 1, + 'published' => 1, + 'language' => '*', + 'home' => 0, + 'params' => (string) $item->params, + ); + + if (!$table->bind($record)) + { + throw new Exception('Bind failed: ' . $table->getError()); + } + + $table->setLocation($parent, 'last-child'); + + if (!$table->check()) + { + throw new Exception('Check failed: ' . $table->getError()); + } + + if (!$table->store()) + { + throw new Exception('Saved failed: ' . $table->getError()); + } + + $item->id = $table->get('id'); + + if (!empty($item->submenu)) + { + static::installPresetItems($item->submenu, $menutype, $item->id); + } + } + } } diff --git a/administrator/components/com_menus/layouts/joomla/menu/edit_modules.php b/administrator/components/com_menus/layouts/joomla/menu/edit_modules.php index 7f00d6973e6f8..289bd85382d7f 100644 --- a/administrator/components/com_menus/layouts/joomla/menu/edit_modules.php +++ b/administrator/components/com_menus/layouts/joomla/menu/edit_modules.php @@ -1,13 +1,13 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; $app = JFactory::getApplication(); $form = $displayData->getForm(); diff --git a/administrator/components/com_menus/layouts/joomla/searchtools/default.php b/administrator/components/com_menus/layouts/joomla/searchtools/default.php index a290d1ca69a27..c9252da317785 100644 --- a/administrator/components/com_menus/layouts/joomla/searchtools/default.php +++ b/administrator/components/com_menus/layouts/joomla/searchtools/default.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage Layout * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; /** @var array $displayData */ $data = $displayData; diff --git a/administrator/components/com_menus/layouts/joomla/searchtools/default/bar.php b/administrator/components/com_menus/layouts/joomla/searchtools/default/bar.php index b74d8b9487fd5..559cb845d8943 100644 --- a/administrator/components/com_menus/layouts/joomla/searchtools/default/bar.php +++ b/administrator/components/com_menus/layouts/joomla/searchtools/default/bar.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage Layout * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; /** @var array $displayData */ $data = $displayData; diff --git a/administrator/components/com_menus/menus.php b/administrator/components/com_menus/menus.php index 1da4ddebce45e..fe5e8f6e10fce 100644 --- a/administrator/components/com_menus/menus.php +++ b/administrator/components/com_menus/menus.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/menus.xml b/administrator/components/com_menus/menus.xml index 285432982d620..8912118ff98aa 100644 --- a/administrator/components/com_menus/menus.xml +++ b/administrator/components/com_menus/menus.xml @@ -3,7 +3,7 @@ com_menus Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -18,6 +18,7 @@ helpers models views + presets language/en-GB.com_menus.ini diff --git a/administrator/components/com_menus/models/fields/componentscategory.php b/administrator/components/com_menus/models/fields/componentscategory.php index 792fc7b893cca..fe7e365131348 100644 --- a/administrator/components/com_menus/models/fields/componentscategory.php +++ b/administrator/components/com_menus/models/fields/componentscategory.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; use Joomla\Utilities\ArrayHelper; diff --git a/administrator/components/com_menus/models/fields/menuitembytype.php b/administrator/components/com_menus/models/fields/menuitembytype.php new file mode 100644 index 0000000000000..84fd2239a48e2 --- /dev/null +++ b/administrator/components/com_menus/models/fields/menuitembytype.php @@ -0,0 +1,278 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('JPATH_PLATFORM') or die; + +JFormHelper::loadFieldClass('groupedlist'); + +// Import the com_menus helper. +JLoader::register('MenusHelper', JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php'); + +/** + * Supports an HTML grouped select list of menu item grouped by menu + * + * @since 3.8.0 + */ +class JFormFieldMenuitemByType extends JFormFieldGroupedList +{ + /** + * The form field type. + * + * @var string + * @since 3.8.0 + */ + public $type = 'MenuItemByType'; + + /** + * The menu type. + * + * @var string + * @since 3.8.0 + */ + protected $menuType; + + /** + * The client id. + * + * @var string + * @since 3.8.0 + */ + protected $clientId; + + /** + * The language. + * + * @var array + * @since 3.8.0 + */ + protected $language; + + /** + * The published status. + * + * @var array + * @since 3.8.0 + */ + protected $published; + + /** + * The disabled status. + * + * @var array + * @since 3.8.0 + */ + protected $disable; + + /** + * Method to get certain otherwise inaccessible properties from the form field object. + * + * @param string $name The property name for which to get the value. + * + * @return mixed The property value or null. + * + * @since 3.8.0 + */ + public function __get($name) + { + switch ($name) + { + case 'menuType': + case 'clientId': + case 'language': + case 'published': + case 'disable': + return $this->$name; + } + + return parent::__get($name); + } + + /** + * Method to set certain otherwise inaccessible properties of the form field object. + * + * @param string $name The property name for which to set the value. + * @param mixed $value The value of the property. + * + * @return void + * + * @since 3.8.0 + */ + public function __set($name, $value) + { + switch ($name) + { + case 'menuType': + $this->menuType = (string) $value; + break; + + case 'clientId': + $this->clientId = (int) $value; + break; + + case 'language': + case 'published': + case 'disable': + $value = (string) $value; + $this->$name = $value ? explode(',', $value) : array(); + break; + + default: + parent::__set($name, $value); + } + } + + /** + * Method to attach a JForm object to the field. + * + * @param SimpleXMLElement $element The SimpleXMLElement object representing the `` tag for the form field object. + * @param mixed $value The form field value to validate. + * @param string $group The field name group control value. This acts as an array container for the field. + * For example if the field has name="foo" and the group value is set to "bar" then the + * full field name would end up being "bar[foo]". + * + * @return boolean True on success. + * + * @see JFormField::setup() + * @since 3.8.0 + */ + public function setup(SimpleXMLElement $element, $value, $group = null) + { + $result = parent::setup($element, $value, $group); + + if ($result == true) + { + $menuType = (string) $this->element['menu_type']; + + if (!$menuType) + { + $app = JFactory::getApplication('administrator'); + $currentMenuType = $app->getUserState('com_menus.items.menutype', ''); + $menuType = $app->input->getString('menutype', $currentMenuType); + } + + $this->menuType = $menuType; + $this->clientId = (int) $this->element['client_id']; + $this->published = $this->element['published'] ? explode(',', (string) $this->element['published']) : array(); + $this->disable = $this->element['disable'] ? explode(',', (string) $this->element['disable']) : array(); + $this->language = $this->element['language'] ? explode(',', (string) $this->element['language']) : array(); + } + + return $result; + } + + /** + * Method to get the field option groups. + * + * @return array The field option objects as a nested array in groups. + * + * @since 3.8.0 + */ + protected function getGroups() + { + $groups = array(); + + $menuType = $this->menuType; + + // Get the menu items. + $items = MenusHelper::getMenuLinks($menuType, 0, 0, $this->published, $this->language, $this->clientId); + + // Build group for a specific menu type. + if ($menuType) + { + // If the menutype is empty, group the items by menutype. + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__menu_types')) + ->where($db->quoteName('menutype') . ' = ' . $db->quote($menuType)); + $db->setQuery($query); + + try + { + $menuTitle = $db->loadResult(); + } + catch (RuntimeException $e) + { + $menuTitle = $menuType; + } + + // Initialize the group. + $groups[$menuTitle] = array(); + + // Build the options array. + foreach ($items as $key => $link) + { + // Unset if item is menu_item_root + if ($link->text === 'Menu_Item_Root') + { + unset($items[$key]); + continue; + } + + $levelPrefix = str_repeat('- ', max(0, $link->level - 1)); + + // Displays language code if not set to All + if ($link->language !== '*') + { + $lang = ' (' . $link->language . ')'; + } + else + { + $lang = ''; + } + + $groups[$menuTitle][] = JHtml::_('select.option', + $link->value, $levelPrefix . $link->text . $lang, + 'value', + 'text', + in_array($link->type, $this->disable) + ); + } + } + // Build groups for all menu types. + else + { + // Build the groups arrays. + foreach ($items as $menu) + { + // Initialize the group. + $groups[$menu->title] = array(); + + // Build the options array. + foreach ($menu->links as $link) + { + $levelPrefix = str_repeat('- ', max(0, $link->level - 1)); + + // Displays language code if not set to All + if ($link->language !== '*') + { + $lang = ' (' . $link->language . ')'; + } + else + { + $lang = ''; + } + + $groups[$menu->title][] = JHtml::_('select.option', + $link->value, + $levelPrefix . $link->text . $lang, + 'value', + 'text', + in_array($link->type, $this->disable) + ); + } + } + } + + // Merge any additional groups in the XML definition. + $groups = array_merge(parent::getGroups(), $groups); + + return $groups; + } +} diff --git a/administrator/components/com_menus/models/fields/menuordering.php b/administrator/components/com_menus/models/fields/menuordering.php index 36db588849698..4fd20c0d0e469 100644 --- a/administrator/components/com_menus/models/fields/menuordering.php +++ b/administrator/components/com_menus/models/fields/menuordering.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JFormHelper::loadFieldClass('list'); diff --git a/administrator/components/com_menus/models/fields/menuparent.php b/administrator/components/com_menus/models/fields/menuparent.php index de7dbb69b1c40..1e802436ea31b 100644 --- a/administrator/components/com_menus/models/fields/menuparent.php +++ b/administrator/components/com_menus/models/fields/menuparent.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JFormHelper::loadFieldClass('list'); @@ -96,7 +96,6 @@ protected function getOptions() { $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; } - } // Merge any additional options in the XML definition. diff --git a/administrator/components/com_menus/models/fields/menupreset.php b/administrator/components/com_menus/models/fields/menupreset.php new file mode 100644 index 0000000000000..a4e073542530c --- /dev/null +++ b/administrator/components/com_menus/models/fields/menupreset.php @@ -0,0 +1,51 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Menu\MenuHelper; + +JFormHelper::loadFieldClass('list'); + +/** + * Administrator Menu Presets list field. + * + * @since 3.8.0 + */ +class JFormFieldMenuPreset extends JFormFieldList +{ + /** + * The form field type. + * + * @var string + * + * @since 3.8.0 + */ + protected $type = 'MenuPreset'; + + /** + * Method to get the field options. + * + * @return array The field option objects. + * + * @since 3.8.0 + */ + protected function getOptions() + { + $options = array(); + $presets = MenuHelper::getPresets(); + + foreach ($presets as $preset) + { + $options[] = JHtml::_('select.option', $preset->name, JText::_($preset->title)); + } + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_menus/models/fields/menutype.php b/administrator/components/com_menus/models/fields/menutype.php index 9929607e00f05..58e25f97eb811 100644 --- a/administrator/components/com_menus/models/fields/menutype.php +++ b/administrator/components/com_menus/models/fields/menutype.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; use Joomla\Utilities\ArrayHelper; @@ -89,14 +89,15 @@ protected function getInput() function jSelectPosition_' . $this->id . '(name) { document.getElementById("' . $this->id . '").value = name; } - '); + ' + ); $link = JRoute::_('index.php?option=com_menus&view=menutypes&tmpl=component&client_id=' . $clientId . '&recordId=' . $recordId); $html[] = ''; - $html[] = '' + $html[] = ''; $html[] = JHtml::_( 'bootstrap.renderModal', 'menuTypeModal', @@ -107,8 +108,8 @@ function jSelectPosition_' . $this->id . '(name) { 'height' => '300px', 'modalWidth' => '80', 'bodyHeight' => '70', - 'footer' => '' + 'footer' => '' ) ); $html[] = 'id . "(id, title, object) { window.processModalSelect('Item', '" . $this->id . "', id, title, '', object); } - "); + " + ); + + JText::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED'); $scriptSelect[$this->id] = true; } @@ -220,14 +242,14 @@ function jSelectMenu_" . $this->id . "(id, title, object) { // Placeholder if option is present or not if (empty($title)) - { + { if ($this->element->option && (string) $this->element->option['value'] == '') { - $title_holder = JText::_($this->element->option, true); + $title_holder = JText::_($this->element->option); } else { - $title_holder = JText::_('COM_MENUS_SELECT_A_MENUITEM', true); + $title_holder = JText::_('COM_MENUS_SELECT_A_MENUITEM'); } } @@ -240,59 +262,77 @@ function jSelectMenu_" . $this->id . "(id, title, object) { // Select menu item button if ($this->allowSelect) { - $html .= '' . ' ' . JText::_('JSELECT') - . ''; + . ''; } // New menu item button if ($this->allowNew) { - $html .= '' . ' ' . JText::_('JACTION_CREATE') - . ''; + . ''; } // Edit menu item button if ($this->allowEdit) { - $html .= '' . ' ' . JText::_('JACTION_EDIT') - . ''; + . ''; } // Clear menu item button if ($this->allowClear) { - $html .= '' . '' . JText::_('JCLEAR') - . ''; + . ''; + } + + // Propagate menu item button + if ($this->allowPropagate && count($languages) > 2) + { + // Strip off language tag at the end + $tagLength = (int) strlen($this->element['language']); + $callbackFunctionStem = substr("jSelectMenu_" . $this->id, 0, -$tagLength); + + $html .= '' + . '' . JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_BUTTON') + . ''; } $html .= ''; + // Select menu item modal if ($this->allowSelect) { @@ -306,7 +346,7 @@ function jSelectMenu_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', + 'footer' => '', ) ); } @@ -327,15 +367,15 @@ function jSelectMenu_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } @@ -356,15 +396,15 @@ function jSelectMenu_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } @@ -375,11 +415,11 @@ function jSelectMenu_" . $this->id . "(id, title, object) { // Placeholder if option is present or not when clearing field if ($this->element->option && (string) $this->element->option['value'] == '') { - $title_holder = JText::_($this->element->option, true); + $title_holder = JText::_($this->element->option); } else { - $title_holder = JText::_('COM_MENUS_SELECT_A_MENUITEM', true); + $title_holder = JText::_('COM_MENUS_SELECT_A_MENUITEM'); } $html .= ' + + + diff --git a/administrator/components/com_menus/models/forms/filter_itemsadmin.xml b/administrator/components/com_menus/models/forms/filter_itemsadmin.xml index d31482bd0584e..a72f293c7ecba 100644 --- a/administrator/components/com_menus/models/forms/filter_itemsadmin.xml +++ b/administrator/components/com_menus/models/forms/filter_itemsadmin.xml @@ -28,6 +28,7 @@ diff --git a/administrator/components/com_menus/models/forms/filter_menus.xml b/administrator/components/com_menus/models/forms/filter_menus.xml index 1d5cdefd7c3fe..717cf6806e507 100644 --- a/administrator/components/com_menus/models/forms/filter_menus.xml +++ b/administrator/components/com_menus/models/forms/filter_menus.xml @@ -14,6 +14,7 @@ diff --git a/administrator/components/com_menus/models/forms/item.xml b/administrator/components/com_menus/models/forms/item.xml index 456723682a3be..fd9a057cbb143 100644 --- a/administrator/components/com_menus/models/forms/item.xml +++ b/administrator/components/com_menus/models/forms/item.xml @@ -70,7 +70,7 @@ description="COM_MENUS_ITEM_FIELD_TYPE_DESC" class="input-medium" required="true" - size="40" + size="40" /> diff --git a/administrator/components/com_menus/models/forms/item_alias.xml b/administrator/components/com_menus/models/forms/item_alias.xml index 61879dbe4c08d..72d65a362b2e7 100644 --- a/administrator/components/com_menus/models/forms/item_alias.xml +++ b/administrator/components/com_menus/models/forms/item_alias.xml @@ -5,8 +5,8 @@
    - + + + + +
    - - - - + + diff --git a/administrator/components/com_menus/models/forms/item_component.xml b/administrator/components/com_menus/models/forms/item_component.xml index 7cd48ab404560..84f1abd96ab39 100644 --- a/administrator/components/com_menus/models/forms/item_component.xml +++ b/administrator/components/com_menus/models/forms/item_component.xml @@ -4,29 +4,36 @@ >
    - - - + +
    - - - - - - - + + + + - diff --git a/administrator/components/com_menus/models/forms/item_heading.xml b/administrator/components/com_menus/models/forms/item_heading.xml index d421de20eeaea..39a36e7b843fc 100644 --- a/administrator/components/com_menus/models/forms/item_heading.xml +++ b/administrator/components/com_menus/models/forms/item_heading.xml @@ -25,6 +25,13 @@ description="COM_MENUS_ITEM_FIELD_MENU_IMAGE_DESC" /> + + + + + + + + + + + + + + + + + + + + +
    diff --git a/administrator/components/com_menus/models/forms/itemadmin_url.xml b/administrator/components/com_menus/models/forms/itemadmin_url.xml index 87b4c78285e43..29bab56210474 100644 --- a/administrator/components/com_menus/models/forms/itemadmin_url.xml +++ b/administrator/components/com_menus/models/forms/itemadmin_url.xml @@ -45,6 +45,13 @@ description="COM_MENUS_ITEM_FIELD_MENU_IMAGE_DESC" /> + + + + + * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\CMS\Factory; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; @@ -26,40 +27,40 @@ class MenusModelItem extends JModelAdmin /** * The type alias for this content type. * - * @var string - * @since 3.4 + * @var string + * @since 3.4 */ public $typeAlias = 'com_menus.item'; /** * The context used for the associations table * - * @var string - * @since 3.4.4 + * @var string + * @since 3.4.4 */ protected $associationsContext = 'com_menus.item'; /** - * @var string The prefix to use with controller messages. - * @since 1.6 + * @var string The prefix to use with controller messages. + * @since 1.6 */ protected $text_prefix = 'COM_MENUS_ITEM'; /** - * @var string The help screen key for the menu item. - * @since 1.6 + * @var string The help screen key for the menu item. + * @since 1.6 */ protected $helpKey = 'JHELP_MENUS_MENU_ITEM_MANAGER_EDIT'; /** - * @var string The help screen base URL for the menu item. - * @since 1.6 + * @var string The help screen base URL for the menu item. + * @since 1.6 */ protected $helpURL; /** - * @var boolean True to use local lookup for the help screen. - * @since 1.6 + * @var boolean True to use local lookup for the help screen. + * @since 1.6 */ protected $helpLocal = false; @@ -67,14 +68,14 @@ class MenusModelItem extends JModelAdmin * Batch copy/move command. If set to false, * the batch copy/move command is not supported * - * @var string + * @var string */ protected $batch_copymove = 'menu_id'; /** * Allowed batch commands * - * @var array + * @var array */ protected $batch_commands = array( 'assetgroup_id' => 'batchAccess', @@ -92,27 +93,19 @@ class MenusModelItem extends JModelAdmin */ protected function canDelete($record) { - $user = JFactory::getUser(); - - if (!empty($record->id)) + if (empty($record->id) || $record->published != -2) { - // Only delete trashed items - if ($record->published != -2) - { - return false; - } - - $menuTypeId = 0; + return false; + } - if (!empty($record->menutype)) - { - $menuTypeId = $this->getMenuTypeId($record->menutype); - } + $menuTypeId = 0; - return $user->authorise('core.delete', 'com_menus.menu.' . (int) $menuTypeId); + if (!empty($record->menutype)) + { + $menuTypeId = $this->getMenuTypeId($record->menutype); } - return false; + return JFactory::getUser()->authorise('core.delete', 'com_menus.menu.' . (int) $menuTypeId); } /** @@ -296,6 +289,7 @@ protected function batchCopy($value, $pks, $contexts) return false; } + // Store the row. if (!$table->store()) { @@ -592,14 +586,28 @@ public function getForm($data = array(), $loadData = true) */ protected function loadFormData() { - // Check the session for previously entered form data. - $data = array_merge((array) $this->getItem(), (array) JFactory::getApplication()->getUserState('com_menus.edit.item.data', array())); + + // Check the session for previously entered form data, providing it has an ID and it is the same. + $itemData = (array) $this->getItem(); + $sessionData = (array) JFactory::getApplication()->getUserState('com_menus.edit.item.data', array()); + + // Only merge if there is a session and itemId or itemid is null. + if (isset($sessionData['id']) && isset($itemData['id']) && $sessionData['id'] === $itemData['id'] + || is_null($itemData['id'])) + { + $data = array_merge($itemData, $sessionData); + } + else + { + $data = $itemData; + } // For a new menu item, pre-select some filters (Status, Language, Access) in edit form if those have been selected in Menu Manager if ($this->getItem()->id == 0) { // Get selected fields $filters = JFactory::getApplication()->getUserState('com_menus.items.filter'); + $data['parent_id'] = (isset($filters['parent_id']) ? $filters['parent_id'] : null); $data['published'] = (isset($filters['published']) ? $filters['published'] : null); $data['language'] = (isset($filters['language']) ? $filters['language'] : null); $data['access'] = (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access')); @@ -612,6 +620,8 @@ protected function loadFormData() $this->setState('item.menutypeid', $menuTypeId); } + $data = (object) $data; + $this->preprocessData('com_menus.item', $data); return $data; @@ -675,7 +685,7 @@ public function getItem($pk = null) if ($link = $this->getState('item.link')) { // Check if we are changing away from the actual link type. - if (MenusHelper::getLinkKey($table->link) != MenusHelper::getLinkKey($link)) + if (MenusHelper::getLinkKey($table->link) !== MenusHelper::getLinkKey($link) && (int) $table->id === (int) $this->getState('item.id')) { $table->link = $link; } @@ -849,7 +859,7 @@ public function getModules() /** * Get the list of all view levels * - * @return array|bool An array of all view levels (id, title). + * @return array|boolean An array of all view levels (id, title). * * @since 3.4 */ @@ -1135,7 +1145,7 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $formFile = $path; } } - else + elseif ($base) { // Now check for a component manifest file $path = JPath::clean($base . '/metadata.xml'); @@ -1190,8 +1200,8 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $helpURL = trim((string) $help[0]['url']); $helpLoc = trim((string) $help[0]['local']); - $this->helpKey = $helpKey ? $helpKey : $this->helpKey; - $this->helpURL = $helpURL ? $helpURL : $this->helpURL; + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; $this->helpLocal = (($helpLoc == 'true') || ($helpLoc == '1') || ($helpLoc == 'local')) ? true : false; } @@ -1225,6 +1235,7 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $field->addAttribute('new', 'true'); $field->addAttribute('edit', 'true'); $field->addAttribute('clear', 'true'); + $field->addAttribute('propagate', 'true'); $option = $field->addChild('option', 'COM_MENUS_ITEM_FIELD_ASSOCIATION_NO_VALUE'); $option->addAttribute('value', ''); } @@ -1476,7 +1487,8 @@ public function save($data) if ($associations) { $query->where('(' . $db->quoteName('id') . ' IN (' . implode(',', $associations) . ') OR ' - . $db->quoteName('key') . ' = ' . $db->quote($old_key) . ')'); + . $db->quoteName('key') . ' = ' . $db->quote($old_key) . ')' + ); } else { @@ -1542,6 +1554,11 @@ public function save($data) parent::cleanCache($option); } + if (Factory::getApplication()->input->get('task') == 'editAssociations') + { + return $this->redirectToAssociations($data); + } + return true; } @@ -1550,19 +1567,19 @@ public function save($data) * First we save the new order values in the lft values of the changed ids. * Then we invoke the table rebuild to implement the new ordering. * - * @param array $idArray Rows identifiers to be reordered - * @param array $lft_array lft values of rows to be reordered + * @param array $idArray Rows identifiers to be reordered + * @param array $lftArray lft values of rows to be reordered * - * @return boolean false on failuer or error, true otherwise. + * @return boolean false on failure or error, true otherwise. * * @since 1.6 */ - public function saveorder($idArray = null, $lft_array = null) + public function saveorder($idArray = null, $lftArray = null) { // Get an instance of the table object. $table = $this->getTable(); - if (!$table->saveorder($idArray, $lft_array)) + if (!$table->saveorder($idArray, $lftArray)) { $this->setError($table->getError()); @@ -1578,7 +1595,7 @@ public function saveorder($idArray = null, $lft_array = null) /** * Method to change the home state of one or more items. * - * @param array &$pks A list of the primary keys to change. + * @param array $pks A list of the primary keys to change. * @param integer $value The value of the home state. * * @return boolean True on success. @@ -1665,7 +1682,7 @@ public function setHome(&$pks, $value = 1) /** * Method to change the published state of one or more records. * - * @param array &$pks A list of the primary keys to change. + * @param array $pks A list of the primary keys to change. * @param integer $value The value of the published state. * * @return boolean True on success. @@ -1675,7 +1692,7 @@ public function setHome(&$pks, $value = 1) public function publish(&$pks, $value = 1) { $table = $this->getTable(); - $pks = (array) $pks; + $pks = (array) $pks; // Default menu item existence checks. if ($value != 1) @@ -1707,20 +1724,20 @@ public function publish(&$pks, $value = 1) /** * Method to change the title & alias. * - * @param integer $parent_id The id of the parent. - * @param string $alias The alias. - * @param string $title The title. + * @param integer $parentId The id of the parent. + * @param string $alias The alias. + * @param string $title The title. * * @return array Contains the modified title and alias. * * @since 1.6 */ - protected function generateNewTitle($parent_id, $alias, $title) + protected function generateNewTitle($parentId, $alias, $title) { // Alter the title & alias $table = $this->getTable(); - while ($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) + while ($table->load(array('alias' => $alias, 'parent_id' => $parentId))) { if ($title == $table->title) { @@ -1736,14 +1753,14 @@ protected function generateNewTitle($parent_id, $alias, $title) /** * Custom clean the cache * - * @param string $group Cache group name. - * @param integer $client_id Application client id. + * @param string $group Cache group name. + * @param integer $clientId Application client id. * * @return void * * @since 1.6 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { parent::cleanCache('com_menus', 0); parent::cleanCache('com_modules'); diff --git a/administrator/components/com_menus/models/items.php b/administrator/components/com_menus/models/items.php index 9febfb9e122b9..f2eb8972d826b 100644 --- a/administrator/components/com_menus/models/items.php +++ b/administrator/components/com_menus/models/items.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -44,6 +44,7 @@ public function __construct($config = array()) 'path', 'a.path', 'client_id', 'a.client_id', 'home', 'a.home', + 'parent_id', 'a.parent_id', 'a.ordering' ); @@ -90,9 +91,6 @@ protected function populateState($ordering = 'a.lft', $direction = 'asc') $this->context .= '.' . $forcedLanguage; } - $parentId = $this->getUserStateFromRequest($this->context . '.filter.parent_id', 'filter_parent_id'); - $this->setState('filter.parent_id', $parentId); - $search = $this->getUserStateFromRequest($this->context . '.search', 'filter_search'); $this->setState('filter.search', $search); @@ -112,6 +110,12 @@ protected function populateState($ordering = 'a.lft', $direction = 'asc') $currentClientId = $app->getUserState($this->context . '.client_id', 0); $clientId = $app->input->getInt('client_id', $currentClientId); + // Load mod_menu.ini file when client is administrator + if ($clientId == 1) + { + JFactory::getLanguage()->load('mod_menu', JPATH_ADMINISTRATOR, null, false, true); + } + $currentMenuType = $app->getUserState($this->context . '.menutype', ''); $menuType = $app->input->getString('menutype', $currentMenuType); @@ -156,6 +160,18 @@ protected function populateState($ordering = 'a.lft', $direction = 'asc') $this->setState('menutypetitle', $cMenu->title); $this->setState('menutypeid', $cMenu->id); } + // This menutype does not exist, leave client id unchanged but reset menutype and pagination + else + { + $menuType = ''; + + $app->input->set('limitstart', 0); + $app->input->set('menutype', $menuType); + + $app->setUserState($this->context . '.menutype', $menuType); + $this->setState('menutypetitle', ''); + $this->setState('menutypeid', ''); + } // Client id filter $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); @@ -288,10 +304,18 @@ protected function getListQuery() if ($assoc) { - $query->select('COUNT(asso2.id)>1 as association') - ->join('LEFT', '#__associations AS asso ON asso.id = a.id AND asso.context=' . $db->quote('com_menus.item')) - ->join('LEFT', '#__associations AS asso2 ON asso2.key = asso.key') - ->group('a.id, e.enabled, l.title, l.image, u.name, c.element, ag.title, e.name, mt.id, mt.title, l.sef'); + $subQuery = $db->getQuery(true) + ->select('COUNT(' . $db->quoteName('asso1.id') . ') > 1') + ->from($db->quoteName('#__associations', 'asso1')) + ->join('INNER', $db->quoteName('#__associations', 'asso2') . ' ON ' . $db->quoteName('asso1.key') . ' = ' . $db->quoteName('asso2.key')) + ->where( + array( + $db->quoteName('asso1.id') . ' = ' . $db->quoteName('a.id'), + $db->quoteName('asso1.context') . ' = ' . $db->quote('com_menus.item'), + ) + ); + + $query->select('(' . $subQuery . ') AS ' . $db->quoteName('association')); } // Join over the extensions @@ -341,7 +365,28 @@ protected function getListQuery() if (!empty($parentId)) { - $query->where('a.parent_id = ' . (int) $parentId); + $level = $this->getState('filter.level'); + + // Create a subquery for the sub-items list + $subQuery = $db->getQuery(true) + ->select('sub.id') + ->from('#__menu as sub') + ->join('INNER', '#__menu as this ON sub.lft > this.lft AND sub.rgt < this.rgt') + ->where('this.id = ' . (int) $parentId); + + if ($level) + { + $subQuery->where('sub.level <= this.level + ' . (int) ($level - 1)); + } + + // Add the subquery to the main query + $query->where('(a.parent_id = ' . (int) $parentId . ' OR a.parent_id IN (' . (string) $subQuery . '))'); + } + + // Filter on the level. + elseif ($level = $this->getState('filter.level')) + { + $query->where('a.level <= ' . (int) $level); } // Filter the items over the menu id if set. @@ -405,12 +450,6 @@ protected function getListQuery() } } - // Filter on the level. - if ($level = $this->getState('filter.level')) - { - $query->where('a.level <= ' . (int) $level); - } - // Filter on the language. if ($language = $this->getState('filter.language')) { @@ -456,10 +495,10 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') /** * Get the client id for a menu * - * @param string $menuType The menutype identifier for the menu - * @param bool $check Flag whether to perform check against ACL as well as existence + * @param string $menuType The menutype identifier for the menu + * @param boolean $check Flag whether to perform check against ACL as well as existence * - * @return int + * @return integer * * @since 3.7.0 */ @@ -478,12 +517,16 @@ protected function getMenu($menuType, $check = false) // Check if menu type exists. if (!$cMenu) { - $this->setError(JText::_('COM_MENUS_ERROR_MENUTYPE_NOT_FOUND')); + JLog::add(JText::_('COM_MENUS_ERROR_MENUTYPE_NOT_FOUND'), JLog::ERROR, 'jerror'); + + return false; } // Check if menu type is valid against ACL. elseif (!JFactory::getUser()->authorise('core.manage', 'com_menus.menu.' . $cMenu->id)) { - $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); + JLog::add(JText::_('JERROR_ALERTNOAUTHOR'), JLog::ERROR, 'jerror'); + + return false; } } @@ -495,7 +538,7 @@ protected function getMenu($menuType, $check = false) * * @return mixed An array of data items on success, false on failure. * - * @since 12.2 + * @since 3.0.1 */ public function getItems() { @@ -505,6 +548,7 @@ public function getItems() { $items = parent::getItems(); $lang = JFactory::getLanguage(); + $client = $this->state->get('filter.client_id'); if ($items) { @@ -517,7 +561,10 @@ public function getItems() } // Translate component name - $item->title = JText::_($item->title); + if ($client === 1) + { + $item->title = JText::_($item->title); + } } } diff --git a/administrator/components/com_menus/models/menu.php b/administrator/components/com_menus/models/menu.php index 4e40104c64b19..b6d8a38f52b48 100644 --- a/administrator/components/com_menus/models/menu.php +++ b/administrator/components/com_menus/models/menu.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -45,9 +45,7 @@ class MenusModelMenu extends JModelForm */ protected function canDelete($record) { - $user = JFactory::getUser(); - - return $user->authorise('core.delete', 'com_menus.menu.' . (int) $record->id); + return JFactory::getUser()->authorise('core.delete', 'com_menus.menu.' . (int) $record->id); } /** @@ -69,11 +67,11 @@ protected function canEditState($record) /** * Returns a Table object, always creating it * - * @param type $type The table type to instantiate + * @param string $type The table type to instantiate * @param string $prefix A prefix for the table class name. Optional. * @param array $config Configuration array for model. Optional. * - * @return JTable A database object + * @return JTable A database object * * @since 1.6 */ @@ -176,12 +174,42 @@ protected function loadFormData() { $data = $this->getItem(); } + else + { + unset($data['preset']); + } $this->preprocessData('com_menus.menu', $data); return $data; } + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.23 + */ + public function validate($form, $data, $group = null) + { + if (!JFactory::getUser()->authorise('core.admin', 'com_menus')) + { + if (isset($data['rules'])) + { + unset($data['rules']); + } + } + + return parent::validate($form, $data, $group); + } + /** * Method to save the form data. * @@ -341,14 +369,14 @@ public function &getModules() /** * Custom clean the cache * - * @param string $group Cache group name. - * @param integer $client_id Application client id. + * @param string $group Cache group name. + * @param integer $clientId Application client id. * * @return void * * @since 1.6 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { parent::cleanCache('com_menus', 0); parent::cleanCache('com_modules'); diff --git a/administrator/components/com_menus/models/menus.php b/administrator/components/com_menus/models/menus.php index 6c7f8e6dc566e..1e8c3c67a658b 100644 --- a/administrator/components/com_menus/models/menus.php +++ b/administrator/components/com_menus/models/menus.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -62,7 +62,7 @@ public function getItems() // Load the list items. $items = parent::getItems(); - // If emtpy or an error, just return. + // If empty or an error, just return. if (empty($items)) { return array(); diff --git a/administrator/components/com_menus/models/menutypes.php b/administrator/components/com_menus/models/menutypes.php index f4e37ebcaa703..a7c513fa928d0 100644 --- a/administrator/components/com_menus/models/menutypes.php +++ b/administrator/components/com_menus/models/menutypes.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -35,7 +35,7 @@ class MenusModelMenutypes extends JModelLegacy * @return void * * @note Calling getState in this method will result in recursion. - * @since 12.2 + * @since 3.0.1 */ protected function populateState() { @@ -175,7 +175,7 @@ protected function getTypeOptionsByComponent($component) * @param string $file File path * @param string $component Component option as in URL * - * @return array|bool + * @return array|boolean * * @since 1.6 */ @@ -262,7 +262,7 @@ protected function getTypeOptionsFromXml($file, $component) * * @param string $component Component option like in URLs * - * @return array|bool + * @return array|boolean * * @since 1.6 */ @@ -377,7 +377,7 @@ protected function getTypeOptionsFromMvc($component) * * @param string $component Component option like in URLs * - * @return array|bool + * @return array|boolean * * @since 3.7.0 */ @@ -575,7 +575,7 @@ protected function getTypeOptionsFromLayouts($component, $view) if ($layout != 'default') { // If the template is set, add in format template:layout so we save the template name - $o->request['layout'] = (isset($templateName[$file])) ? $templateName[$file] . ':' . $layout : $layout; + $o->request['layout'] = isset($templateName[$file]) ? $templateName[$file] . ':' . $layout : $layout; } // Load layout metadata if it exists. diff --git a/administrator/components/com_menus/presets/joomla.xml b/administrator/components/com_menus/presets/joomla.xml new file mode 100644 index 0000000000000..6335c1cc12b1a --- /dev/null +++ b/administrator/components/com_menus/presets/joomla.xml @@ -0,0 +1,599 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_menus/presets/menu.xsd b/administrator/components/com_menus/presets/menu.xsd new file mode 100644 index 0000000000000..01d4d07aa1785 --- /dev/null +++ b/administrator/components/com_menus/presets/menu.xsd @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_menus/presets/modern.xml b/administrator/components/com_menus/presets/modern.xml new file mode 100644 index 0000000000000..551f4e8a173c8 --- /dev/null +++ b/administrator/components/com_menus/presets/modern.xml @@ -0,0 +1,629 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_menus/tables/menu.php b/administrator/components/com_menus/tables/menu.php index 824e1c877300f..8a1156bbf0f75 100644 --- a/administrator/components/com_menus/tables/menu.php +++ b/administrator/components/com_menus/tables/menu.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/views/item/tmpl/edit.php b/administrator/components/com_menus/views/item/tmpl/edit.php index 1485d920ee41d..e76ab7fe6581f 100644 --- a/administrator/components/com_menus/views/item/tmpl/edit.php +++ b/administrator/components/com_menus/views/item/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -15,6 +15,7 @@ JHtml::_('behavior.core'); JHtml::_('behavior.tabstate'); JHtml::_('behavior.formvalidator'); +JHtml::_('formbehavior.chosen', '#jform_request_filter_tag', null, array('placeholder_text_multiple' => JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_TAGS'))); JHtml::_('formbehavior.chosen', 'select'); JHtml::_('behavior.keepalive'); @@ -46,7 +47,30 @@ $('#jform_parent_id').trigger('liszt:updated'); }); }); + + // Menu type Login Form specific + $('#item-form').on('submit', function() { + if ($('#jform_params_login_redirect_url') && $('#jform_params_logout_redirect_url')) { + // Login + if ($('#jform_params_login_redirect_url').closest('.control-group').css('display') === 'block') { + $('#jform_params_login_redirect_menuitem_id').val(''); + } + if ($('#jform_params_login_redirect_menuitem_name').closest('.control-group').css('display') === 'block') { + $('#jform_params_login_redirect_url').val(''); + + } + + // Logout + if ($('#jform_params_logout_redirect_url').closest('.control-group').css('display') === 'block') { + $('#jform_params_logout_redirect_menuitem_id').val(''); + } + if ($('#jform_params_logout_redirect_menuitem_id').closest('.control-group').css('display') === 'block') { + $('#jform_params_logout_redirect_url').val(''); + } + } + }); }); + Joomla.submitbutton = function(task, type){ if (task == 'item.setType' || task == 'item.setMenuType') { @@ -91,13 +115,33 @@ $layout = $isModal ? 'modal' : 'edit'; $tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; $clientId = $this->state->get('item.client_id', 0); +$lang = JFactory::getLanguage()->getTag(); + +// Load mod_menu.ini file when client is administrator +if ($clientId === 1) +{ + JFactory::getLanguage()->load('mod_menu', JPATH_ADMINISTRATOR, null, false, true); +} ?> -
    + + item->id != 0) : ?> +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    'details')); ?> @@ -108,7 +152,12 @@ if ($this->item->type == 'alias') { - echo $this->form->renderFieldset('aliasoptions'); + echo $this->form->renderField('aliasoptions', 'params'); + } + + if ($this->item->type == 'separator') + { + echo $this->form->renderField('text_separator', 'params'); } echo $this->form->renderFieldset('request'); @@ -116,10 +165,16 @@ if ($this->item->type == 'url') { $this->form->setFieldAttribute('link', 'readonly', 'false'); + $this->form->setFieldAttribute('link', 'required', 'true'); } echo $this->form->renderField('link'); + if ($this->item->type == 'alias') + { + echo $this->form->renderField('alias_redirect', 'params'); + } + echo $this->form->renderField('browserNav'); echo $this->form->renderField('template_style_id'); diff --git a/administrator/components/com_menus/views/item/tmpl/edit_associations.php b/administrator/components/com_menus/views/item/tmpl/edit_associations.php index ab1f92d2f332c..cb85a978d63ee 100644 --- a/administrator/components/com_menus/views/item/tmpl/edit_associations.php +++ b/administrator/components/com_menus/views/item/tmpl/edit_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/views/item/tmpl/edit_container.php b/administrator/components/com_menus/views/item/tmpl/edit_container.php index cbc3edf910ae8..5f4c4532730d4 100644 --- a/administrator/components/com_menus/views/item/tmpl/edit_container.php +++ b/administrator/components/com_menus/views/item/tmpl/edit_container.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_menus/views/item/tmpl/edit_modules.php b/administrator/components/com_menus/views/item/tmpl/edit_modules.php index 726b4b8c2ae68..32453f7c7b6b1 100644 --- a/administrator/components/com_menus/views/item/tmpl/edit_modules.php +++ b/administrator/components/com_menus/views/item/tmpl/edit_modules.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -17,29 +17,69 @@ JFactory::getDocument()->addScriptDeclaration(' var viewLevels = ' . json_encode($allLevels) . ', - menuId = parseInt(' . $this->item->id . '); + menuId = parseInt(' . (int) $this->item->id . '); - jQuery(document).ready(function() { - jQuery(document).on("click", "input:radio[id^=\'jform_toggle_modules_assigned1\']", function (event) { - jQuery(".table tr.no").hide(); - }); - jQuery(document).on("click", "input:radio[id^=\'jform_toggle_modules_assigned0\']", function (event) { - jQuery(".table tr.no").show(); - }); - jQuery(document).on("click", "input:radio[id^=\'jform_toggle_modules_published1\']", function (event) { - jQuery(".table tr.unpublished").hide(); - }); - jQuery(document).on("click", "input:radio[id^=\'jform_toggle_modules_published0\']", function (event) { - jQuery(".table tr.unpublished").show(); - }); + jQuery(function($) { + var baseLink = "index.php?option=com_modules&client_id=0&task=module.edit&tmpl=component&view=module&layout=modal&id=", + iFrameAttr = "class=\"iframe jviewport-height70\""; + + $(document) + .on("click", "input:radio[id^=\'jform_toggle_modules_assigned1\']", function (event) { + $(".table tr.no").hide(); + }) + .on("click", "input:radio[id^=\'jform_toggle_modules_assigned0\']", function (event) { + $(".table tr.no").show(); + }) + .on("click", "input:radio[id^=\'jform_toggle_modules_published1\']", function (event) { + $(".table tr.unpublished").hide(); + }) + .on("click", "input:radio[id^=\'jform_toggle_modules_published0\']", function (event) { + $(".table tr.unpublished").show(); + }) + .on("click", ".module-edit-link", function () { + var link = baseLink + $(this).data("moduleId"), + iFrame = $(""); + + $("#moduleEditModal").modal() + .find(".modal-body").empty().prepend(iFrame); + }) + .on("click", "#moduleEditModal .modal-footer .btn", function () { + var target = $(this).data("target"); + + if (target) { + $("#moduleEditModal iframe").contents().find(target).click(); + } + }); }); '); + JFactory::getDocument()->addStyleDeclaration(' ul.horizontal-buttons li { display: inline-block; padding-right: 10%; } '); + +// Set up the bootstrap modal that will be used for all module editors +echo JHtml::_( + 'bootstrap.renderModal', + 'moduleEditModal', + array( + 'title' => JText::_('COM_MENUS_EDIT_MODULE_SETTINGS'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'footer' => '' + . '' + . '', + ) +); + ?> - id . '&tmpl=component&view=module&layout=modal'; ?> - - escape($module->title); ?> + escape($module->access_title); ?> @@ -131,30 +175,6 @@ - id . 'Modal', - array( - 'title' => JText::_('COM_MENUS_EDIT_MODULE_SETTINGS'), - 'backdrop' => 'static', - 'keyboard' => false, - 'closeButton' => false, - 'url' => $link, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '' - . '' - . '', - ) - ); ?> diff --git a/administrator/components/com_menus/views/item/tmpl/edit_options.php b/administrator/components/com_menus/views/item/tmpl/edit_options.php index 993e76d264124..bd3cee4017710 100644 --- a/administrator/components/com_menus/views/item/tmpl/edit_options.php +++ b/administrator/components/com_menus/views/item/tmpl/edit_options.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/views/item/tmpl/modal.php b/administrator/components/com_menus/views/item/tmpl/modal.php index 7cca917248f71..03699f9de1ff7 100644 --- a/administrator/components/com_menus/views/item/tmpl/modal.php +++ b/administrator/components/com_menus/views/item/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/views/item/tmpl/modal_associations.php b/administrator/components/com_menus/views/item/tmpl/modal_associations.php index ab1f92d2f332c..07dd47d400025 100644 --- a/administrator/components/com_menus/views/item/tmpl/modal_associations.php +++ b/administrator/components/com_menus/views/item/tmpl/modal_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/views/item/tmpl/modal_options.php b/administrator/components/com_menus/views/item/tmpl/modal_options.php index 993e76d264124..64e9f62d7f7c0 100644 --- a/administrator/components/com_menus/views/item/tmpl/modal_options.php +++ b/administrator/components/com_menus/views/item/tmpl/modal_options.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/views/item/view.html.php b/administrator/components/com_menus/views/item/view.html.php index 019f23567ebc3..451fd2ccdc8fd 100644 --- a/administrator/components/com_menus/views/item/view.html.php +++ b/administrator/components/com_menus/views/item/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -107,6 +107,7 @@ protected function addToolbar() $isNew = ($this->item->id == 0); $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); $canDo = $this->canDo; + $clientId = $this->state->get('item.client_id', 0); JToolbarHelper::title(JText::_($isNew ? 'COM_MENUS_VIEW_NEW_ITEM_TITLE' : 'COM_MENUS_VIEW_EDIT_ITEM_TITLE'), 'list menu-add'); @@ -140,6 +141,11 @@ protected function addToolbar() JToolbarHelper::save2copy('item.save2copy'); } + if (!$isNew && JLanguageAssociations::isEnabled() && JComponentHelper::isEnabled('com_associations') && $clientId != 1) + { + JToolbarHelper::custom('item.editAssociations', 'contract', 'contract', 'JTOOLBAR_ASSOCIATIONS', false, false); + } + if ($isNew) { JToolbarHelper::cancel('item.cancel'); diff --git a/administrator/components/com_menus/views/items/tmpl/default.php b/administrator/components/com_menus/views/items/tmpl/default.php index 3deb8558aae88..b4ef2ae66ad38 100644 --- a/administrator/components/com_menus/views/items/tmpl/default.php +++ b/administrator/components/com_menus/views/items/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/views/items/tmpl/default_batch_body.php b/administrator/components/com_menus/views/items/tmpl/default_batch_body.php index 12b01e77456e8..f03fceef7c3fa 100644 --- a/administrator/components/com_menus/views/items/tmpl/default_batch_body.php +++ b/administrator/components/com_menus/views/items/tmpl/default_batch_body.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; @@ -12,9 +12,29 @@ JHtml::_('select.option', 'c', JText::_('JLIB_HTML_BATCH_COPY')), JHtml::_('select.option', 'm', JText::_('JLIB_HTML_BATCH_MOVE')) ); -$published = $this->state->get('filter.published'); -$clientId = $this->state->get('filter.client_id'); +$published = (int) $this->state->get('filter.published'); +$clientId = (int) $this->state->get('filter.client_id'); $menuType = JFactory::getApplication()->getUserState('com_menus.items.menutype'); +if ($clientId == 1) : + JFactory::getDocument()->addScriptDeclaration( + ' + jQuery(document).ready(function($){ + if ($("#batch-menu-id").length){var batchSelector = $("#batch-menu-id");} + if ($("#batch-copy-move").length) { + $("#batch-copy-move").hide(); + batchSelector.on("change", function(){ + if (batchSelector.val() != 0 || batchSelector.val() != "") { + $("#batch-copy-move").show(); + } else { + $("#batch-copy-move").hide(); + } + }); + } + }); + ' + ); +endif; + ?>
    @@ -43,7 +63,7 @@ $published, + 'published' => $this->state->get('filter.published'), 'checkacl' => (int) $this->state->get('menutypeid'), 'clientid' => (int) $clientId, ); diff --git a/administrator/components/com_menus/views/items/tmpl/default_batch_footer.php b/administrator/components/com_menus/views/items/tmpl/default_batch_footer.php index a279b3761c8e0..7441ae4237f82 100644 --- a/administrator/components/com_menus/views/items/tmpl/default_batch_footer.php +++ b/administrator/components/com_menus/views/items/tmpl/default_batch_footer.php @@ -3,18 +3,19 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; - +$published = $this->state->get('filter.published'); +$clientId = $this->state->get('filter.client_id'); $menuType = JFactory::getApplication()->getUserState('com_menus.items.menutype'); ?> - + += 0 && $clientId == 1)): ?> + diff --git a/administrator/components/com_menus/views/items/tmpl/modal.php b/administrator/components/com_menus/views/items/tmpl/modal.php index a02f1bde962cd..653b23666c7eb 100644 --- a/administrator/components/com_menus/views/items/tmpl/modal.php +++ b/administrator/components/com_menus/views/items/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -22,6 +22,7 @@ JHtml::_('behavior.polyfill', array('event'), 'lt IE 9'); JHtml::_('script', 'com_menus/admin-items-modal.min.js', array('version' => 'auto', 'relative' => true)); JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); JHtml::_('formbehavior.chosen', 'select'); // Special case for the search field tooltip. @@ -32,19 +33,21 @@ $editor = $app->input->getCmd('editor', ''); $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); +$link = 'index.php?option=com_menus&view=items&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; if (!empty($editor)) { // This view is used also in com_menus. Load the xtd script only if the editor is set! JFactory::getDocument()->addScriptOptions('xtd-menus', array('editor' => $editor)); $onclick = "jSelectMenuItem"; + $link = 'index.php?option=com_menus&view=items&layout=modal&tmpl=component&editor=' . $editor . '&' . JSession::getFormToken() . '=1'; } ?>
    - + - $this)); ?> + $this, 'options' => array('selectorFieldName' => 'menutype'))); ?> items)) : ?>
    @@ -86,82 +89,84 @@ items as $i => $item) : ?> - type != 'separator' && $item->type != 'alias' && - $item->type != 'heading' && $item->type != 'container' && $item->type != 'url') : ?> - language && JLanguageMultilang::isEnabled()) + type, array('separator', 'heading', 'alias', 'url', 'container')); ?> + language && JLanguageMultilang::isEnabled()) + { + if ($item->language !== '*') { - if ($item->language !== '*') - { - $language = $item->language; - } - else - { - $language = ''; - } + $language = $item->language; } - elseif (!JLanguageMultilang::isEnabled()) + else { $language = ''; } - ?> - - - published, $i, 0); ?> - - - $item->level)); ?> - - + } + elseif (!JLanguageMultilang::isEnabled()) + { + $language = ''; + } + ?> + + + published, $i, 0); ?> + + + $item->level)); ?> + + + escape($item->title); ?> - - note)) : ?> - escape($item->alias)); ?> - - escape($item->alias), $this->escape($item->note)); ?> - - -
    - - - escape($item->item_type); ?> -
    - - - escape($item->menutype_title); ?> - - - type == 'component') : ?> - language == '*' || $item->home == '0') : ?> - home, $i, 'items.', ($item->language != '*' || !$item->home) && 0); ?> - - language_image) : ?> - language_image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> - - language_sef; ?> - - + + escape($item->title); ?> + + + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> - - - escape($item->access_level); ?> - - - language == '') : ?> - - language == '*') : ?> - + +
    + + + escape($item->item_type); ?> +
    + + + escape($item->menutype_title); ?> + + + type == 'component') : ?> + language == '*' || $item->home == '0') : ?> + home, $i, 'items.', ($item->language != '*' || !$item->home) && 0); ?> - + language_image) : ?> + language_image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> + + language_sef; ?> + - - - - id; ?> - - - - + + + + escape($item->access_level); ?> + + + language == '') : ?> + + language == '*') : ?> + + + + + + + + id; ?> + + + diff --git a/administrator/components/com_menus/views/items/view.html.php b/administrator/components/com_menus/views/items/view.html.php index 1e880db9b0a3b..6bb249997c10f 100644 --- a/administrator/components/com_menus/views/items/view.html.php +++ b/administrator/components/com_menus/views/items/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -156,12 +156,14 @@ public function display($tpl = null) } else { + $base = $this->state->get('filter.client_id') == 0 ? JPATH_SITE : JPATH_ADMINISTRATOR; + // Get XML file from component folder for standard layouts - $file = JPATH_SITE . '/components/' . $item->componentname . '/views/' . $vars['view'] . '/tmpl/' . $vars['layout'] . '.xml'; + $file = $base . '/components/' . $item->componentname . '/views/' . $vars['view'] . '/tmpl/' . $vars['layout'] . '.xml'; if (!file_exists($file)) { - $file = JPATH_SITE . '/components/' . $item->componentname . '/view/' . $vars['view'] . '/tmpl/' . $vars['layout'] . '.xml'; + $file = $base . '/components/' . $item->componentname . '/view/' . $vars['view'] . '/tmpl/' . $vars['layout'] . '.xml'; } } @@ -189,8 +191,8 @@ public function display($tpl = null) { $titleParts[] = $vars['view']; } - } + $value = implode(' » ', $titleParts); } else @@ -237,7 +239,7 @@ public function display($tpl = null) // In menu associations modal we need to remove language filter if forcing a language. if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) { - // If the language is forced we can't allow to select the language, so transform the language selector filter into an hidden field. + // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. $languageXml = new SimpleXMLElement(''); $this->filterForm->setField($languageXml, 'filter', true); diff --git a/administrator/components/com_menus/views/menu/tmpl/edit.php b/administrator/components/com_menus/views/menu/tmpl/edit.php index 80d88e941df71..d7f80435995d1 100644 --- a/administrator/components/com_menus/views/menu/tmpl/edit.php +++ b/administrator/components/com_menus/views/menu/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -37,30 +37,17 @@ 'details')); ?> -
    -
    - form->getLabel('menutype'); ?> -
    -
    - form->getInput('menutype'); ?> -
    -
    -
    -
    - form->getLabel('description'); ?> -
    -
    - form->getInput('description'); ?> -
    -
    -
    -
    - form->getLabel('client_id'); ?> -
    -
    - form->getInput('client_id'); ?> -
    -
    + + form->renderField('menutype'); + + echo $this->form->renderField('description'); + + echo $this->form->renderField('client_id'); + + echo $this->form->renderField('preset'); + ?> + canDo->get('core.admin')) : ?> @@ -73,6 +60,5 @@ -
    diff --git a/administrator/components/com_menus/views/menu/view.html.php b/administrator/components/com_menus/views/menu/view.html.php index cba69faf0e45e..3ad3db8433072 100644 --- a/administrator/components/com_menus/views/menu/view.html.php +++ b/administrator/components/com_menus/views/menu/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_menus/views/menu/view.xml.php b/administrator/components/com_menus/views/menu/view.xml.php new file mode 100644 index 0000000000000..ec0be432276b4 --- /dev/null +++ b/administrator/components/com_menus/views/menu/view.xml.php @@ -0,0 +1,170 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ +defined('_JEXEC') or die; + +use Joomla\CMS\Menu\MenuHelper; + +/** + * The HTML Menus Menu Item View. + * + * @since 3.8.0 + */ +class MenusViewMenu extends JViewLegacy +{ + /** + * @var stdClass[] + * + * @since 3.8.0 + */ + protected $items; + + /** + * @var JObject + * + * @since 3.8.0 + */ + protected $state; + + /** + * Display the view + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return void + * + * @since 3.8.0 + */ + public function display($tpl = null) + { + $app = JFactory::getApplication(); + $menutype = $app->input->getCmd('menutype'); + + if ($menutype) + { + $items = MenusHelper::getMenuItems($menutype, true); + } + + if (empty($items)) + { + JLog::add(JText::_('COM_MENUS_SELECT_MENU_FIRST_EXPORT'), JLog::WARNING, 'jerror'); + + $app->redirect(JRoute::_('index.php?option=com_menus&view=menus', false)); + + return; + } + + $this->items = MenuHelper::createLevels($items); + + $xml = new SimpleXMLElement('' + ); + + foreach ($this->items as $item) + { + $this->addXmlChild($xml, $item); + } + + if (headers_sent($file, $line)) + { + JLog::add("Headers already sent at $file:$line.", JLog::ERROR, 'jerror'); + + return; + } + + header('content-type: application/xml'); + header('content-disposition: attachment; filename="' . $menutype . '.xml"'); + header("Cache-Control: no-cache, must-revalidate"); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header('Pragma: private'); + + $dom = new DOMDocument; + $dom->preserveWhiteSpace = true; + $dom->formatOutput = true; + $dom->loadXML($xml->asXML()); + + echo $dom->saveXML(); + + $app->close(); + } + + /** + * Add a child node to the xml + * + * @param SimpleXMLElement $xml The current XML node which would become the parent to the new node + * @param stdClass $item The menuitem object to create the child XML node from + * + * @return void + * + * @since 3.8.0 + */ + protected function addXmlChild($xml, $item) + { + $node = $xml->addChild('menuitem'); + + $node['type'] = $item->type; + + if ($item->title) + { + $node['title'] = $item->title; + } + + if ($item->link) + { + $node['link'] = $item->link; + } + + if ($item->element) + { + $node['element'] = $item->element; + } + + if ($item->class) + { + $node['class'] = $item->class; + } + + if ($item->access) + { + $node['access'] = $item->access; + } + + if ($item->browserNav) + { + $node['target'] = '_blank'; + } + + if (count($item->params)) + { + $hideitems = $item->params->get('hideitems'); + + if (count($hideitems)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select('e.element')->from('#__extensions e') + ->join('inner', '#__menu m ON m.component_id = e.extension_id') + ->where('m.id IN (' . implode(', ', $db->quote($hideitems)) . ')'); + + $hideitems = $db->setQuery($query)->loadColumn(); + + $item->params->set('hideitems', $hideitems); + } + + $node->addChild('params', (string) $item->params); + } + + foreach ($item->submenu as $sub) + { + $this->addXmlChild($node, $sub); + } + } +} diff --git a/administrator/components/com_menus/views/menus/tmpl/default.php b/administrator/components/com_menus/views/menus/tmpl/default.php index 49b8e661ba9ca..61bf23eb79e7f 100644 --- a/administrator/components/com_menus/views/menus/tmpl/default.php +++ b/administrator/components/com_menus/views/menus/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -41,6 +41,16 @@ $script[] = ' },1000);'; $script[] = ' });'; $script[] = '});'; +$script[] = ' + (function (originalFn) { + Joomla.submitform = function(task, form) { + originalFn(task, form); + if (task == "menu.exportXml") { + document.adminForm.task.value = ""; + } + }; + })(Joomla.submitform); +'; JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); ?> @@ -153,26 +163,27 @@ modules[$item->menutype])) : ?>
    - + +
    modules[$item->menutype] as &$module) : ?> - + authorise('core.edit', 'com_modules.module.' . (int) $module->id)) : ?> id . '&return=' . $return . '&tmpl=component&layout=modal'); ?> '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '' - . '', ) @@ -202,7 +213,7 @@ menutype . '&tmpl=component&layout=modal'); ?> - + '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '' - . '', ) diff --git a/administrator/components/com_menus/views/menus/view.html.php b/administrator/components/com_menus/views/menus/view.html.php index 39b74c1ab86a1..e237885253669 100644 --- a/administrator/components/com_menus/views/menus/view.html.php +++ b/administrator/components/com_menus/views/menus/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -102,6 +102,11 @@ protected function addToolbar() JToolbarHelper::custom('menus.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); + if ($canDo->get('core.admin') && $this->state->get('client_id') == 1) + { + JToolbarHelper::custom('menu.exportXml', 'download', 'download', 'COM_MENUS_MENU_EXPORT_BUTTON', true); + } + if ($canDo->get('core.admin') || $canDo->get('core.options')) { JToolbarHelper::divider(); diff --git a/administrator/components/com_menus/views/menutypes/tmpl/default.php b/administrator/components/com_menus/views/menutypes/tmpl/default.php index 781308a99736e..13494f6762d22 100644 --- a/administrator/components/com_menus/views/menutypes/tmpl/default.php +++ b/administrator/components/com_menus/views/menutypes/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_menus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -38,7 +38,7 @@
    - item->date_time); ?> + item->date_time, JText::_('DATE_FORMAT_LC2')); ?>
    diff --git a/administrator/components/com_messages/views/message/tmpl/edit.php b/administrator/components/com_messages/views/message/tmpl/edit.php index 515c57e93a22d..f2e97db10c395 100644 --- a/administrator/components/com_messages/views/message/tmpl/edit.php +++ b/administrator/components/com_messages/views/message/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_messages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_messages/views/message/view.html.php b/administrator/components/com_messages/views/message/view.html.php index 3636b50fbda61..ef7d118f30891 100644 --- a/administrator/components/com_messages/views/message/view.html.php +++ b/administrator/components/com_messages/views/message/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_messages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_messages/views/messages/tmpl/default.php b/administrator/components/com_messages/views/messages/tmpl/default.php index ac2da0441b722..3f35a0d5c281a 100644 --- a/administrator/components/com_messages/views/messages/tmpl/default.php +++ b/administrator/components/com_messages/views/messages/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_messages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_messages/views/messages/view.html.php b/administrator/components/com_messages/views/messages/view.html.php index 8adb843ccd60c..3c3077d153256 100644 --- a/administrator/components/com_messages/views/messages/view.html.php +++ b/administrator/components/com_messages/views/messages/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_messages * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -43,6 +43,7 @@ public function display($tpl = null) if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); + return false; } @@ -89,10 +90,10 @@ protected function addToolbar() 0, '', '', - '' - . '' diff --git a/administrator/components/com_modules/config.xml b/administrator/components/com_modules/config.xml index 4f7f55b2ea54f..3eb9b198ebcf4 100644 --- a/administrator/components/com_modules/config.xml +++ b/administrator/components/com_modules/config.xml @@ -17,6 +17,25 @@
    + +
    + + + + +
    +
    * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -35,7 +35,6 @@ public function display($cachable = false, $urlparams = false) // For JSON requests if ($document->getType() == 'json') { - $view = new ModulesViewModule; // Get/Create the model @@ -45,6 +44,7 @@ public function display($cachable = false, $urlparams = false) if (!$model->checkout($id)) { JFactory::getApplication()->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH'), 'error'); + return false; } @@ -76,6 +76,48 @@ public function display($cachable = false, $urlparams = false) // Load the submenu. ModulesHelper::addSubmenu($this->input->get('view', 'modules')); + // Check custom administrator menu modules + if (JModuleHelper::isAdminMultilang()) + { + $languages = JLanguageHelper::getInstalledLanguages(1, true); + $langCodes = array(); + + foreach ($languages as $language) + { + if (isset($language->metadata['nativeName'])) + { + $languageName = $language->metadata['nativeName']; + } + else + { + $languageName = $language->metadata['name']; + } + + $langCodes[$language->metadata['tag']] = $languageName; + } + + $db = JFactory::getDbo(); + $query = $db->getQuery(true); + + $query->select($db->qn('m.language')) + ->from($db->qn('#__modules', 'm')) + ->where($db->qn('m.module') . ' = ' . $db->quote('mod_menu')) + ->where($db->qn('m.published') . ' = 1') + ->where($db->qn('m.client_id') . ' = 1') + ->group($db->qn('m.language')); + + $mLanguages = $db->setQuery($query)->loadColumn(); + + // Check if we have a mod_menu module set to All languages or a mod_menu module for each admin language. + if (!in_array('*', $mLanguages) && count($langMissing = array_diff(array_keys($langCodes), $mLanguages))) + { + $app = JFactory::getApplication(); + $langMissing = array_intersect_key($langCodes, array_flip($langMissing)); + + $app->enqueueMessage(JText::sprintf('JMENU_MULTILANG_WARNING_MISSING_MODULES', implode(', ', $langMissing)), 'warning'); + } + } + return parent::display(); } } diff --git a/administrator/components/com_modules/controllers/module.php b/administrator/components/com_modules/controllers/module.php index 86da955150f16..461d0ccda0c65 100644 --- a/administrator/components/com_modules/controllers/module.php +++ b/administrator/components/com_modules/controllers/module.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -118,14 +118,19 @@ protected function allowEdit($data = array(), $key = 'id') $recordId = (int) isset($data[$key]) ? $data[$key] : 0; $user = JFactory::getUser(); - // Check general edit permission first. + // Zero record (id:0), return component edit permission by calling parent controller method + if (!$recordId) + { + return parent::allowEdit($data, $key); + } + + // Check edit on the record asset (explicit or inherited) if ($user->authorise('core.edit', 'com_modules.module.' . $recordId)) { return true; } - // Since there is no asset tracking, revert to the component permissions. - return parent::allowEdit($data, $key); + return false; } /** @@ -139,7 +144,7 @@ protected function allowEdit($data = array(), $key = 'id') */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Set the model $model = $this->getModel('Module', '', array()); @@ -191,10 +196,7 @@ protected function postSaveHook(JModelLegacy $model, $validData = array()) */ public function save($key = null, $urlVar = null) { - if (!JSession::checkToken()) - { - JFactory::getApplication()->redirect('index.php', JText::_('JINVALID_TOKEN')); - } + $this->checkToken(); if (JFactory::getDocument()->getType() == 'json') { @@ -221,7 +223,6 @@ public function save($key = null, $urlVar = null) // Add path of forms directory JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_modules/models/forms'); - } parent::save($key, $urlVar); @@ -247,7 +248,7 @@ public function orderPosition() // Check if user token is valid. if (!JSession::checkToken('get')) { - $app->enqueueMessage(JText::_('JINVALID_TOKEN'), 'error'); + $app->enqueueMessage(JText::_('JINVALID_TOKEN_NOTICE'), 'error'); echo new JResponseJson; $app->close(); } @@ -255,6 +256,17 @@ public function orderPosition() $jinput = $app->input; $clientId = $jinput->getValue('client_id'); $position = $jinput->getValue('position'); + $moduleId = $jinput->getValue('module_id'); + + // Access check. + if (!JFactory::getUser()->authorise('core.create', 'com_modules') + && !JFactory::getUser()->authorise('core.edit.state', 'com_modules') + && ($moduleId && !JFactory::getUser()->authorise('core.edit.state', 'com_modules.module.' . $moduleId))) + { + $app->enqueueMessage(\JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 'error'); + echo new JResponseJson; + $app->close(); + } $db = JFactory::getDbo(); $query = $db->getQuery(true) diff --git a/administrator/components/com_modules/controllers/modules.php b/administrator/components/com_modules/controllers/modules.php index 22a9ecb7a3ec8..1304e827c84ae 100644 --- a/administrator/components/com_modules/controllers/modules.php +++ b/administrator/components/com_modules/controllers/modules.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -28,7 +28,7 @@ class ModulesControllerModules extends JControllerAdmin public function duplicate() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $pks = $this->input->post->get('cid', array(), 'array'); $pks = ArrayHelper::toInteger($pks); diff --git a/administrator/components/com_modules/helpers/html/modules.php b/administrator/components/com_modules/helpers/html/modules.php index f7c37daaf3297..60eafc53560b5 100644 --- a/administrator/components/com_modules/helpers/html/modules.php +++ b/administrator/components/com_modules/helpers/html/modules.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/helpers/modules.php b/administrator/components/com_modules/helpers/modules.php index 48a47f1c95b93..ac6b0a1aff59f 100644 --- a/administrator/components/com_modules/helpers/modules.php +++ b/administrator/components/com_modules/helpers/modules.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/helpers/xml.php b/administrator/components/com_modules/helpers/xml.php index 2fb1093906987..1a2e0290c71ec 100644 --- a/administrator/components/com_modules/helpers/xml.php +++ b/administrator/components/com_modules/helpers/xml.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/layouts/toolbar/cancelselect.php b/administrator/components/com_modules/layouts/toolbar/cancelselect.php index 5687325d07c90..1bf6cfa3aa352 100644 --- a/administrator/components/com_modules/layouts/toolbar/cancelselect.php +++ b/administrator/components/com_modules/layouts/toolbar/cancelselect.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/layouts/toolbar/newmodule.php b/administrator/components/com_modules/layouts/toolbar/newmodule.php index 037956442341b..82c364240fb19 100644 --- a/administrator/components/com_modules/layouts/toolbar/newmodule.php +++ b/administrator/components/com_modules/layouts/toolbar/newmodule.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/models/fields/modulesmodule.php b/administrator/components/com_modules/models/fields/modulesmodule.php index 397a18f74add6..22cf9b4580148 100644 --- a/administrator/components/com_modules/models/fields/modulesmodule.php +++ b/administrator/components/com_modules/models/fields/modulesmodule.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JLoader::register('ModulesHelper', JPATH_ADMINISTRATOR . '/components/com_modules/helpers/modules.php'); @@ -37,8 +37,7 @@ class JFormFieldModulesModule extends JFormFieldList */ public function getOptions() { - $clientId = JFactory::getApplication()->input->get('client_id', 0, 'int'); - $options = ModulesHelper::getModules($clientId); + $options = ModulesHelper::getModules(JFactory::getApplication()->getUserState('com_modules.modules.client_id', 0)); return array_merge(parent::getOptions(), $options); } diff --git a/administrator/components/com_modules/models/fields/modulesposition.php b/administrator/components/com_modules/models/fields/modulesposition.php index 7577b938d4874..b6ec7dcf0ac27 100644 --- a/administrator/components/com_modules/models/fields/modulesposition.php +++ b/administrator/components/com_modules/models/fields/modulesposition.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JLoader::register('ModulesHelper', JPATH_ADMINISTRATOR . '/components/com_modules/helpers/modules.php'); @@ -37,8 +37,7 @@ class JFormFieldModulesPosition extends JFormFieldList */ public function getOptions() { - $clientId = JFactory::getApplication()->input->get('client_id', 0, 'int'); - $options = ModulesHelper::getPositions($clientId); + $options = ModulesHelper::getPositions(JFactory::getApplication()->getUserState('com_modules.modules.client_id', 0)); return array_merge(parent::getOptions(), $options); } diff --git a/administrator/components/com_modules/models/forms/advanced.xml b/administrator/components/com_modules/models/forms/advanced.xml index 3914d5657a83e..eee1a2dc29113 100644 --- a/administrator/components/com_modules/models/forms/advanced.xml +++ b/administrator/components/com_modules/models/forms/advanced.xml @@ -10,6 +10,7 @@ label="COM_MODULES_FIELD_MODULE_TAG_LABEL" description="COM_MODULES_FIELD_MODULE_TAG_DESC" default="div" + validate="options" /> - + diff --git a/administrator/components/com_modules/models/forms/filter_modulesadmin.xml b/administrator/components/com_modules/models/forms/filter_modulesadmin.xml new file mode 100644 index 0000000000000..f3b4cc6ede4f2 --- /dev/null +++ b/administrator/components/com_modules/models/forms/filter_modulesadmin.xml @@ -0,0 +1,111 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_modules/models/forms/module.xml b/administrator/components/com_modules/models/forms/module.xml index d138f0f676ad0..ea43b185fa831 100644 --- a/administrator/components/com_modules/models/forms/module.xml +++ b/administrator/components/com_modules/models/forms/module.xml @@ -3,7 +3,7 @@
    - - - - - + > - + > @@ -77,37 +89,58 @@ size="22" /> - - - - - + + + + @@ -119,7 +152,9 @@ filter="unset" /> - * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -159,6 +159,9 @@ protected function batchCopy($value, $pks, $contexts) $table->position = $position; + // Copy of the Asset ID + $oldAssetId = $table->asset_id; + // Alter the title if necessary $data = $this->generateNewTitle(0, $table->title, $table->position); $table->title = $data['0']; @@ -201,6 +204,17 @@ protected function batchCopy($value, $pks, $contexts) $db->setQuery($query); $db->execute(); } + + // Copy rules + $query->clear() + ->update($db->quoteName('#__assets', 't')) + ->join('INNER', $db->quoteName('#__assets', 's') . + ' ON ' . $db->quoteName('s.id') . ' = ' . $oldAssetId + ) + ->set($db->quoteName('t.rules') . ' = ' . $db->quoteName('s.rules')) + ->where($db->quoteName('t.id') . ' = ' . $table->asset_id); + + $db->setQuery($query)->execute(); } else { @@ -288,18 +302,14 @@ protected function batchMove($value, $pks, $contexts) */ protected function canEditState($record) { - $user = JFactory::getUser(); - // Check for existing module. if (!empty($record->id)) { - return $user->authorise('core.edit.state', 'com_modules.module.' . (int) $record->id); + return JFactory::getUser()->authorise('core.edit.state', 'com_modules.module.' . (int) $record->id); } + // Default to component settings if module not known. - else - { - return parent::canEditState('com_modules'); - } + return parent::canEditState($record); } /** @@ -469,15 +479,15 @@ public function duplicate(&$pks) /** * Method to change the title. * - * @param integer $category_id The id of the category. Not used here. - * @param string $title The title. - * @param string $position The position. + * @param integer $categoryId The id of the category. Not used here. + * @param string $title The title. + * @param string $position The position. * * @return array Contains the modified title. * * @since 2.5 */ - protected function generateNewTitle($category_id, $title, $position) + protected function generateNewTitle($categoryId, $title, $position) { // Alter the title & alias $table = $this->getTable(); @@ -530,7 +540,7 @@ public function getForm($data = array(), $loadData = true) } // Add the default fields directory - $baseFolder = ($clientId) ? JPATH_ADMINISTRATOR : JPATH_SITE; + $baseFolder = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; JForm::addFieldPath($baseFolder . '/modules' . '/' . $module . '/field'); // These variables are used to add data from the plugin XML files. @@ -541,6 +551,12 @@ public function getForm($data = array(), $loadData = true) if ($clientId == 1) { $form = $this->loadForm('com_modules.module.admin', 'moduleadmin', array('control' => 'jform', 'load_data' => $loadData), true); + + // Display language field to filter admin custom menus per language + if (!JModuleHelper::isAdminMultilang()) + { + $form->setFieldAttribute('language', 'type', 'hidden'); + } } else { @@ -611,7 +627,6 @@ protected function loadFormData() // Avoid to delete params of a second module opened in a new browser tab while new one is not saved yet. if (empty($data->params)) { - // This allows us to inject parameter settings into a new module. $params = $app->getUserState('com_modules.add.module.params'); @@ -853,8 +868,8 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $helpKey = trim((string) $help[0]['key']); $helpURL = trim((string) $help[0]['url']); - $this->helpKey = $helpKey ? $helpKey : $this->helpKey; - $this->helpURL = $helpURL ? $helpURL : $this->helpURL; + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; } } @@ -881,6 +896,14 @@ public function validate($form, $data, $group = null) { JLoader::register('ContentHelper', JPATH_ADMINISTRATOR . '/components/com_content/helpers/content.php'); + if (!JFactory::getUser()->authorise('core.admin', 'com_modules')) + { + if (isset($data['rules'])) + { + unset($data['rules']); + } + } + return parent::validate($form, $data, $group); } @@ -921,7 +944,7 @@ public function save($data) if ($data['title'] == $orig_table->title) { - $data['title'] .= ' ' . JText::_('JGLOBAL_COPY'); + $data['title'] = StringHelper::increment($data['title']); } } @@ -1051,10 +1074,14 @@ public function save($data) // Compute the extension id of this module in case the controller wants it. $query->clear() - ->select('extension_id') - ->from('#__extensions AS e') - ->join('LEFT', '#__modules AS m ON e.element = m.module') - ->where('m.id = ' . (int) $table->id); + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions', 'e')) + ->join( + 'LEFT', + $db->quoteName('#__modules', 'm') . ' ON ' . $db->quoteName('e.client_id') . ' = ' . (int) $table->client_id . + ' AND ' . $db->quoteName('e.element') . ' = ' . $db->quoteName('m.module') + ) + ->where($db->quoteName('m.id') . ' = ' . (int) $table->id); $db->setQuery($query); try @@ -1101,14 +1128,14 @@ protected function getReorderConditions($table) /** * Custom clean cache method for different clients * - * @param string $group The name of the plugin group to import (defaults to null). - * @param integer $client_id The client ID. [optional] + * @param string $group The name of the plugin group to import (defaults to null). + * @param integer $clientId The client ID. [optional] * * @return void * * @since 1.6 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { parent::cleanCache('com_modules', $this->getClient()); } diff --git a/administrator/components/com_modules/models/modules.php b/administrator/components/com_modules/models/modules.php index 10f9de6d0f3fb..05fa3465f400b 100644 --- a/administrator/components/com_modules/models/modules.php +++ b/administrator/components/com_modules/models/modules.php @@ -3,12 +3,13 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; /** @@ -103,6 +104,7 @@ protected function populateState($ordering = 'a.position', $direction = 'asc') if ($app->isClient('site') || $layout === 'modal') { $this->setState('client_id', 0); + $clientId = 0; } else { @@ -111,6 +113,12 @@ protected function populateState($ordering = 'a.position', $direction = 'asc') $this->setState('client_id', $clientId); } + // Use a different filter file when client is administrator + if ($clientId == 1) + { + $this->filterFormName = 'filter_modulesadmin'; + } + // Load the parameters. $params = JComponentHelper::getParams('com_modules'); $this->setState('params', $params); @@ -175,13 +183,14 @@ protected function _getList($query, $limitstart = 0, $limit = 0) // Process pagination. $total = count($result); $this->cache[$this->getStoreId('getTotal')] = $total; + if ($total < $limitstart) { $limitstart = 0; $this->setState('list.start', 0); } - return array_slice($result, $limitstart, $limit ? $limit : null); + return array_slice($result, $limitstart, $limit ?: null); } // If ordering by fields that doesn't need translate just order the query. @@ -296,15 +305,25 @@ protected function getListQuery() // Group (careful with PostgreSQL) $query->group( - 'a.id, a.title, a.note, a.position, a.module, a.language, a.checked_out, ' . - 'a.checked_out_time, a.published, a.access, a.ordering, l.title, l.image, uc.name, ag.title, e.name, ' . - 'l.lang_code, uc.id, ag.id, mm.moduleid, e.element, a.publish_up, a.publish_down, e.enabled' - ); + 'a.id, a.title, a.note, a.position, a.module, a.language, a.checked_out, ' + . 'a.checked_out_time, a.published, a.access, a.ordering, l.title, l.image, uc.name, ag.title, e.name, ' + . 'l.lang_code, uc.id, ag.id, mm.moduleid, e.element, a.publish_up, a.publish_down, e.enabled' + ); // Filter by client. $clientId = $this->getState('client_id'); $query->where($db->quoteName('a.client_id') . ' = ' . (int) $clientId . ' AND ' . $db->quoteName('e.client_id') . ' = ' . (int) $clientId); + // Filter by current user access level. + $user = JFactory::getUser(); + + // Get the current user for authorisation checks + if ($user->authorise('core.admin') !== true) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + // Filter by access level. if ($access = $this->getState('filter.access')) { @@ -313,6 +332,7 @@ protected function getListQuery() // Filter by published state. $state = $this->getState('filter.state'); + if (is_numeric($state)) { $query->where($db->quoteName('a.published') . ' = ' . (int) $state); @@ -342,7 +362,7 @@ protected function getListQuery() { $query->having('MIN(' . $db->quoteName('mm.menuid') . ') IS NULL'); } - // If user selected the modules assigned to some particlar page (menu item). + // If user selected the modules assigned to some particular page (menu item). else { // Modules in "All" pages. @@ -368,12 +388,14 @@ protected function getListQuery() (' . $subQuery1 . ') = 0 OR ((' . $subQuery1 . ') > 0 AND ' . $db->quoteName('a.id') . ' IN (' . $subQuery2 . ')) OR ((' . $subQuery1 . ') < 0 AND ' . $db->quoteName('a.id') . ' NOT IN (' . $subQuery3 . ')) - )'); + )' + ); } } // Filter by search in title or note or id:. $search = $this->getState('filter.search'); + if (!empty($search)) { if (stripos($search, 'id:') === 0) @@ -382,7 +404,7 @@ protected function getListQuery() } else { - $search = $db->quote('%' . strtolower($search) . '%'); + $search = $db->quote('%' . StringHelper::strtolower($search) . '%'); $query->where('(LOWER(a.title) LIKE ' . $search . ' OR LOWER(a.note) LIKE ' . $search . ')'); } } diff --git a/administrator/components/com_modules/models/positions.php b/administrator/components/com_modules/models/positions.php index 4b763e5267500..0df776db00f3c 100644 --- a/administrator/components/com_modules/models/positions.php +++ b/administrator/components/com_modules/models/positions.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -219,7 +219,7 @@ public function getItems() } } - $this->items = array_slice($positions, $limitstart, $limit ? $limit : null); + $this->items = array_slice($positions, $limitstart, $limit ?: null); } return $this->items; @@ -228,7 +228,7 @@ public function getItems() /** * Method to get the total number of items. * - * @return int The total number of items. + * @return integer The total number of items. * * @since 1.6 */ diff --git a/administrator/components/com_modules/models/select.php b/administrator/components/com_modules/models/select.php index 277f7dc32b88a..6ac733d76296d 100644 --- a/administrator/components/com_modules/models/select.php +++ b/administrator/components/com_modules/models/select.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/modules.php b/administrator/components/com_modules/modules.php index 405bd2f9adf79..5b5fd724d2726 100644 --- a/administrator/components/com_modules/modules.php +++ b/administrator/components/com_modules/modules.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/modules.xml b/administrator/components/com_modules/modules.xml index 5ee1216e9afbf..3e777e815c625 100644 --- a/administrator/components/com_modules/modules.xml +++ b/administrator/components/com_modules/modules.xml @@ -3,7 +3,7 @@ com_modules Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_modules/views/module/tmpl/edit.php b/administrator/components/com_modules/views/module/tmpl/edit.php index cb792ef98dcc2..f5dc5979707ee 100644 --- a/administrator/components/com_modules/views/module/tmpl/edit.php +++ b/administrator/components/com_modules/views/module/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -15,9 +15,13 @@ JHtml::_('behavior.combobox'); JHtml::_('behavior.keepalive'); JHtml::_('formbehavior.chosen', '#jform_position', null, array('disable_search_threshold' => 0 )); +JHtml::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_CATEGORY'))); +JHtml::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_TAG'))); +JHtml::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_AUTHOR'))); +JHtml::_('formbehavior.chosen', '.multipleAuthorAliases', null, array('placeholder_text_multiple' => JText::_('JOPTION_SELECT_AUTHOR_ALIAS'))); JHtml::_('formbehavior.chosen', 'select'); -$hasContent = empty($this->item->module) || isset($this->item->xml->customContent); +$hasContent = isset($this->item->xml->customContent); $hasContentFieldName = 'content'; // For a later improvement @@ -172,7 +176,7 @@
    item->xml) : ?> item->xml->description) : ?> -

    +

    item->xml) { @@ -183,7 +187,7 @@ echo JText::_('COM_MODULES_ERR_XML'); } ?> -

    +
    item->client_id == 0 ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); ?> @@ -195,10 +199,10 @@ $this->fieldset = 'description'; $long_description = JLayoutHelper::render('joomla.edit.fieldset', $this); if (!$long_description) { - $truncated = JHtmlString::truncate($short_description, 550, true, false); + $truncated = JHtml::_('string.truncate', $short_description, 550, true, false); if (strlen($truncated) > 500) { $long_description = $short_description; - $short_description = JHtmlString::truncate($truncated, 250); + $short_description = JHtml::_('string.truncate', $truncated, 250); if ($short_description == $long_description) { $long_description = ''; } diff --git a/administrator/components/com_modules/views/module/tmpl/edit_assignment.php b/administrator/components/com_modules/views/module/tmpl/edit_assignment.php index f6d2899f99ae4..fa93623114810 100644 --- a/administrator/components/com_modules/views/module/tmpl/edit_assignment.php +++ b/administrator/components/com_modules/views/module/tmpl/edit_assignment.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -108,7 +108,7 @@ function menuHide(val)
  • type, array('separator', 'heading', 'alias', 'url'))); + $uselessMenuItem = in_array($link->type, array('separator', 'heading', 'alias', 'url')); ?> />

    -
    -
    - + +
    +
    + +
    -
    + +
    +
    + +
    +
    +
    diff --git a/administrator/components/com_modules/views/modules/tmpl/default_batch_footer.php b/administrator/components/com_modules/views/modules/tmpl/default_batch_footer.php index 8676be8c5a1e6..5a3e117dc18e7 100644 --- a/administrator/components/com_modules/views/modules/tmpl/default_batch_footer.php +++ b/administrator/components/com_modules/views/modules/tmpl/default_batch_footer.php @@ -3,15 +3,15 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - + + \ No newline at end of file + diff --git a/administrator/components/com_modules/views/modules/tmpl/modal.php b/administrator/components/com_modules/views/modules/tmpl/modal.php index 81784671ba6b4..bd7e045918f5a 100644 --- a/administrator/components/com_modules/views/modules/tmpl/modal.php +++ b/administrator/components/com_modules/views/modules/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -17,6 +17,7 @@ // Load needed scripts JHtml::_('behavior.core'); JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); JHtml::_('formbehavior.chosen', 'select'); // Scripts for the modules xtd-button @@ -30,10 +31,16 @@ $listOrder = $this->escape($this->state->get('list.ordering')); $listDirn = $this->escape($this->state->get('list.direction')); $editor = JFactory::getApplication()->input->get('editor', '', 'cmd'); +$link = 'index.php?option=com_modules&view=modules&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; + +if (!empty($editor)) +{ + $link = 'index.php?option=com_modules&view=modules&layout=modal&tmpl=component&editor=' . $editor . '&' . JSession::getFormToken() . '=1'; +} ?>
    - + $this)); ?> total > 0) : ?> @@ -88,7 +95,7 @@ - + escape($item->title); ?> @@ -122,6 +129,7 @@ + diff --git a/administrator/components/com_modules/views/modules/view.html.php b/administrator/components/com_modules/views/modules/view.html.php index 974e320131428..e868f52e2ba38 100644 --- a/administrator/components/com_modules/views/modules/view.html.php +++ b/administrator/components/com_modules/views/modules/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -39,6 +39,7 @@ public function display($tpl = null) $this->total = $this->get('Total'); $this->filterForm = $this->get('FilterForm'); $this->activeFilters = $this->get('ActiveFilters'); + $this->clientId = $this->state->get('client_id'); // Check for errors. if (count($errors = $this->get('Errors'))) @@ -46,12 +47,9 @@ public function display($tpl = null) throw new Exception(implode("\n", $errors), 500); } - // We do not need the Page and the Language filters when filtering by administrator - if ($this->state->get('client_id') == 1) + // We do not need the Language filter when modules are not filtered + if ($this->clientId == 1 && !JModuleHelper::isAdminMultilang()) { - unset($this->activeFilters['menuitem']); - $this->filterForm->removeField('menuitem', 'filter'); - unset($this->activeFilters['language']); $this->filterForm->removeField('language', 'filter'); } @@ -176,11 +174,26 @@ protected function addToolbar() */ protected function getSortFields() { - if ($this->getLayout() == 'default') + $this->state = $this->get('State'); + + if ($this->state->get('client_id') == 0) { + if ($this->getLayout() == 'default') + { + return array( + 'ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'position' => JText::_('COM_MODULES_HEADING_POSITION'), + 'name' => JText::_('COM_MODULES_HEADING_MODULE'), + 'pages' => JText::_('COM_MODULES_HEADING_PAGES'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'language_title' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } + return array( - 'ordering' => JText::_('JGRID_HEADING_ORDERING'), - 'a.published' => JText::_('JSTATUS'), 'a.title' => JText::_('JGLOBAL_TITLE'), 'position' => JText::_('COM_MODULES_HEADING_POSITION'), 'name' => JText::_('COM_MODULES_HEADING_MODULE'), @@ -190,15 +203,30 @@ protected function getSortFields() 'a.id' => JText::_('JGRID_HEADING_ID') ); } + else + { + if ($this->getLayout() == 'default') + { + return array( + 'ordering' => JText::_('JGRID_HEADING_ORDERING'), + 'a.published' => JText::_('JSTATUS'), + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'position' => JText::_('COM_MODULES_HEADING_POSITION'), + 'name' => JText::_('COM_MODULES_HEADING_MODULE'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } - return array( - 'a.title' => JText::_('JGLOBAL_TITLE'), - 'position' => JText::_('COM_MODULES_HEADING_POSITION'), - 'name' => JText::_('COM_MODULES_HEADING_MODULE'), - 'pages' => JText::_('COM_MODULES_HEADING_PAGES'), - 'a.access' => JText::_('JGRID_HEADING_ACCESS'), - 'language_title' => JText::_('JGRID_HEADING_LANGUAGE'), - 'a.id' => JText::_('JGRID_HEADING_ID') - ); + return array( + 'a.title' => JText::_('JGLOBAL_TITLE'), + 'position' => JText::_('COM_MODULES_HEADING_POSITION'), + 'name' => JText::_('COM_MODULES_HEADING_MODULE'), + 'a.access' => JText::_('JGRID_HEADING_ACCESS'), + 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => JText::_('JGRID_HEADING_ID') + ); + } } } diff --git a/administrator/components/com_modules/views/positions/tmpl/modal.php b/administrator/components/com_modules/views/positions/tmpl/modal.php index d53c01aaaa252..73d4a911a7e1a 100644 --- a/administrator/components/com_modules/views/positions/tmpl/modal.php +++ b/administrator/components/com_modules/views/positions/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/views/positions/view.html.php b/administrator/components/com_modules/views/positions/view.html.php index e1ec5c185b1f5..c03bf5f192dd1 100644 --- a/administrator/components/com_modules/views/positions/view.html.php +++ b/administrator/components/com_modules/views/positions/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -13,7 +13,7 @@ /** * View Module positions class. - * + * * @since 1.6 */ class ModulesViewPositions extends JViewLegacy diff --git a/administrator/components/com_modules/views/preview/tmpl/default.php b/administrator/components/com_modules/views/preview/tmpl/default.php index 1033a6f25f976..f95efc5513588 100644 --- a/administrator/components/com_modules/views/preview/tmpl/default.php +++ b/administrator/components/com_modules/views/preview/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/views/preview/view.html.php b/administrator/components/com_modules/views/preview/view.html.php index 05c7387953f8f..ff4dc0589d07a 100644 --- a/administrator/components/com_modules/views/preview/view.html.php +++ b/administrator/components/com_modules/views/preview/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_modules/views/select/tmpl/default.php b/administrator/components/com_modules/views/select/tmpl/default.php index bdf61d42a5500..241d66affc36f 100644 --- a/administrator/components/com_modules/views/select/tmpl/default.php +++ b/administrator/components/com_modules/views/select/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -21,22 +21,13 @@ extension_id; ?> escape($item->name); ?> - escape(strip_tags($item->desc))), 200); ?> - escape(strip_tags($item->desc))), 90); ?> - - direction != 'rtl') : ?> + escape(strip_tags($item->desc)), 200); ?> + escape(strip_tags($item->desc)), 90); ?>
  • - -
  • - - - -
  • -
    diff --git a/administrator/components/com_modules/views/select/view.html.php b/administrator/components/com_modules/views/select/view.html.php index 93489fc147065..553eb8d55dc42 100644 --- a/administrator/components/com_modules/views/select/view.html.php +++ b/administrator/components/com_modules/views/select/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_modules * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/config.xml b/administrator/components/com_newsfeeds/config.xml index 90247d4bf6e90..9f9ec1635cf2c 100644 --- a/administrator/components/com_newsfeeds/config.xml +++ b/administrator/components/com_newsfeeds/config.xml @@ -31,7 +31,7 @@
    +
    + + + + + + + + + + + + + +
    +
    * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/controllers/ajax.json.php b/administrator/components/com_newsfeeds/controllers/ajax.json.php new file mode 100644 index 0000000000000..4fd8e2281678c --- /dev/null +++ b/administrator/components/com_newsfeeds/controllers/ajax.json.php @@ -0,0 +1,87 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\LanguageHelper; + +/** + * The newsfeed controller for ajax requests + * + * @since 3.9.0 + */ +class NewsfeedsControllerAjax extends JControllerLegacy +{ + /** + * Method to fetch associations of a newsfeed + * + * The method assumes that the following http parameters are passed in an Ajax Get request: + * token: the form token + * assocId: the id of the newsfeed whose associations are to be returned + * excludeLang: the association for this language is to be excluded + * + * @return null + * + * @since 3.9.0 + */ + public function fetchAssociations() + { + if (!JSession::checkToken('get')) + { + echo new JResponseJson(null, JText::_('JINVALID_TOKEN'), true); + } + else + { + $input = JFactory::getApplication()->input; + + $assocId = $input->getInt('assocId', 0); + + if ($assocId == 0) + { + echo new JResponseJson(null, JText::sprintf('JLIB_FORM_VALIDATE_FIELD_INVALID', 'assocId'), true); + + return; + } + + $excludeLang = $input->get('excludeLang', '', 'STRING'); + + $associations = JLanguageAssociations::getAssociations('com_newsfeeds', '#__newsfeeds', 'com_newsfeeds.item', (int) $assocId); + + unset($associations[$excludeLang]); + + // Add the title to each of the associated records + JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_newsfeeds/tables'); + $newsfeedsTable = JTable::getInstance('Newsfeed', 'NewsfeedsTable'); + + foreach ($associations as $lang => $association) + { + $newsfeedsTable->load($association->id); + $associations[$lang]->title = $newsfeedsTable->name; + } + + $countContentLanguages = count(LanguageHelper::getContentLanguages(array(0, 1))); + + if (count($associations) == 0) + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_NONE'); + } + elseif ($countContentLanguages > count($associations) + 2) + { + $tags = implode(', ', array_keys($associations)); + $message = JText::sprintf('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_SOME', $tags); + } + else + { + $message = JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_MESSAGE_ALL'); + } + + echo new JResponseJson($associations, $message); + } + } +} diff --git a/administrator/components/com_newsfeeds/controllers/newsfeed.php b/administrator/components/com_newsfeeds/controllers/newsfeed.php index d7d6b52172875..e744247fdf22b 100644 --- a/administrator/components/com_newsfeeds/controllers/newsfeed.php +++ b/administrator/components/com_newsfeeds/controllers/newsfeed.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -98,7 +98,7 @@ protected function allowEdit($data = array(), $key = 'id') */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Set the model $model = $this->getModel('Newsfeed', '', array()); diff --git a/administrator/components/com_newsfeeds/controllers/newsfeeds.php b/administrator/components/com_newsfeeds/controllers/newsfeeds.php index dd1b15dee7391..bd2e552aa1128 100644 --- a/administrator/components/com_newsfeeds/controllers/newsfeeds.php +++ b/administrator/components/com_newsfeeds/controllers/newsfeeds.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/helpers/associations.php b/administrator/components/com_newsfeeds/helpers/associations.php index db3f5bfef3ca5..36825eddcffc1 100644 --- a/administrator/components/com_newsfeeds/helpers/associations.php +++ b/administrator/components/com_newsfeeds/helpers/associations.php @@ -3,13 +3,13 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2017 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Association\AssociationExtensionHelper; JTable::addIncludePath(__DIR__ . '/../tables'); @@ -18,7 +18,7 @@ * * @since 3.7.0 */ -class NewsfeedsAssociationsHelper extends JAssociationExtensionHelper +class NewsfeedsAssociationsHelper extends AssociationExtensionHelper { /** * The extension name @@ -143,7 +143,6 @@ public function getType($typeName = '') if (in_array($typeName, $this->itemTypes)) { - switch ($typeName) { case 'newsfeed': diff --git a/administrator/components/com_newsfeeds/helpers/html/newsfeed.php b/administrator/components/com_newsfeeds/helpers/html/newsfeed.php index a5525fba1cbaa..7cdca3080cce0 100644 --- a/administrator/components/com_newsfeeds/helpers/html/newsfeed.php +++ b/administrator/components/com_newsfeeds/helpers/html/newsfeed.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -49,6 +49,7 @@ public static function association($newsfeedid) ->select('cat.title as category_title') ->join('LEFT', '#__categories as cat ON cat.id=c.catid') ->where('c.id IN (' . implode(',', array_values($associations)) . ')') + ->where('c.id != ' . $newsfeedid) ->join('LEFT', '#__languages as l ON c.language=l.lang_code') ->select('l.image') ->select('l.title as language_title'); diff --git a/administrator/components/com_newsfeeds/helpers/newsfeeds.php b/administrator/components/com_newsfeeds/helpers/newsfeeds.php index b3ed33cd18ca7..5249e494d061e 100644 --- a/administrator/components/com_newsfeeds/helpers/newsfeeds.php +++ b/administrator/components/com_newsfeeds/helpers/newsfeeds.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -43,7 +43,7 @@ public static function addSubmenu($vName) /** * Adds Count Items for Category Manager. * - * @param stdClass[] &$items The banner category objects + * @param stdClass[] &$items The category objects * * @return stdClass[] * @@ -51,53 +51,20 @@ public static function addSubmenu($vName) */ public static function countItems(&$items) { - $db = JFactory::getDbo(); - - foreach ($items as $item) - { - $item->count_trashed = 0; - $item->count_archived = 0; - $item->count_unpublished = 0; - $item->count_published = 0; - $query = $db->getQuery(true); - $query->select('published AS state, count(*) AS count') - ->from($db->qn('#__newsfeeds')) - ->where('catid = ' . (int) $item->id) - ->group('state'); - $db->setQuery($query); - $newfeeds = $db->loadObjectList(); - - foreach ($newfeeds as $newsfeed) - { - if ($newsfeed->state == 1) - { - $item->count_published = $newsfeed->count; - } - - if ($newsfeed->state == 0) - { - $item->count_unpublished = $newsfeed->count; - } - - if ($newsfeed->state == 2) - { - $item->count_archived = $newsfeed->count; - } - - if ($newsfeed->state == -2) - { - $item->count_trashed = $newsfeed->count; - } - } - } + $config = (object) array( + 'related_tbl' => 'newsfeeds', + 'state_col' => 'published', + 'group_col' => 'catid', + 'relation_type' => 'category_or_group', + ); - return $items; + return parent::countRelations($items, $config); } /** * Adds Count Items for Tag Manager. * - * @param stdClass[] &$items The newsfeed tag objects + * @param stdClass[] &$items The tag objects * @param string $extension The name of the active view. * * @return stdClass[] @@ -106,60 +73,17 @@ public static function countItems(&$items) */ public static function countTagItems(&$items, $extension) { - $db = JFactory::getDbo(); - $parts = explode('.', $extension); - $section = null; - if (count($parts) > 1) - { - $section = $parts[1]; - } - $join = $db->qn('#__newsfeeds') . ' AS c ON ct.content_item_id=c.id'; - if ($section === 'category') - { - $join = $db->qn('#__categories') . ' AS c ON ct.content_item_id=c.id'; - } - - foreach ($items as $item) - { - $item->count_trashed = 0; - $item->count_archived = 0; - $item->count_unpublished = 0; - $item->count_published = 0; - $query = $db->getQuery(true); - $query->select('published AS state, count(*) AS count') - ->from($db->qn('#__contentitem_tag_map') . 'AS ct ') - ->where('ct.tag_id = ' . (int) $item->id) - ->where('ct.type_alias =' . $db->q($extension)) - ->join('LEFT', $join) - ->group('state'); - - $db->setQuery($query); - $newsfeeds = $db->loadObjectList(); - - foreach ($newsfeeds as $newsfeed) - { - if ($newsfeed->state == 1) - { - $item->count_published = $newsfeed->count; - } - - if ($newsfeed->state == 0) - { - $item->count_unpublished = $newsfeed->count; - } - - if ($newsfeed->state == 2) - { - $item->count_archived = $newsfeed->count; - } - - if ($newsfeed->state == -2) - { - $item->count_trashed = $newsfeed->count; - } - } - } + $parts = explode('.', $extension); + $section = count($parts) > 1 ? $parts[1] : null; + + $config = (object) array( + 'related_tbl' => ($section === 'category' ? 'categories' : 'newsfeeds'), + 'state_col' => 'published', + 'group_col' => 'tag_id', + 'extension' => $extension, + 'relation_type' => 'tag_assigments', + ); - return $items; - } + return parent::countRelations($items, $config); + } } diff --git a/administrator/components/com_newsfeeds/models/fields/modal/newsfeed.php b/administrator/components/com_newsfeeds/models/fields/modal/newsfeed.php index 04b2b7aba4740..9aaf1a90ca354 100644 --- a/administrator/components/com_newsfeeds/models/fields/modal/newsfeed.php +++ b/administrator/components/com_newsfeeds/models/fields/modal/newsfeed.php @@ -3,11 +3,13 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; + +use Joomla\CMS\Language\LanguageHelper; /** * Supports a modal newsfeeds picker. @@ -33,10 +35,13 @@ class JFormFieldModal_Newsfeed extends JFormField */ protected function getInput() { - $allowNew = ((string) $this->element['new'] == 'true'); - $allowEdit = ((string) $this->element['edit'] == 'true'); - $allowClear = ((string) $this->element['clear'] != 'false'); - $allowSelect = ((string) $this->element['select'] != 'false'); + $allowNew = ((string) $this->element['new'] == 'true'); + $allowEdit = ((string) $this->element['edit'] == 'true'); + $allowClear = ((string) $this->element['clear'] != 'false'); + $allowSelect = ((string) $this->element['select'] != 'false'); + $allowPropagate = ((string) $this->element['propagate'] == 'true'); + + $languages = LanguageHelper::getContentLanguages(array(0, 1)); // Load language JFactory::getLanguage()->load('com_newsfeeds', JPATH_ADMINISTRATOR); @@ -67,7 +72,10 @@ protected function getInput() function jSelectNewsfeed_" . $this->id . "(id, title, object) { window.processModalSelect('Newsfeed', '" . $this->id . "', id, title, '', object); } - "); + " + ); + + JText::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED'); $scriptSelect[$this->id] = true; } @@ -117,55 +125,72 @@ function jSelectNewsfeed_" . $this->id . "(id, title, object) { // Select newsfeed button if ($allowSelect) { - $html .= '' . ' ' . JText::_('JSELECT') - . ''; + . ''; } // New newsfeed button if ($allowNew) { - $html .= '' . ' ' . JText::_('JACTION_CREATE') - . ''; + . ''; } // Edit newsfeed button if ($allowEdit) { - $html .= '' . ' ' . JText::_('JACTION_EDIT') - . ''; + . ''; } // Clear newsfeed button if ($allowClear) { - $html .= '' . '' . JText::_('JCLEAR') - . ''; + . ''; + } + + // Propagate newsfeed button + if ($allowPropagate && count($languages) > 2) + { + // Strip off language tag at the end + $tagLength = (int) strlen($this->element['language']); + $callbackFunctionStem = substr("jSelectNewsfeed_" . $this->id, 0, -$tagLength); + + $html .= '' + . '' . JText::_('JGLOBAL_ASSOCIATIONS_PROPAGATE_BUTTON') + . ''; } $html .= ''; @@ -183,7 +208,7 @@ function jSelectNewsfeed_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', + 'footer' => '', ) ); } @@ -204,18 +229,18 @@ function jSelectNewsfeed_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } @@ -236,18 +261,18 @@ function jSelectNewsfeed_" . $this->id . "(id, title, object) { 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', ) ); } diff --git a/administrator/components/com_newsfeeds/models/fields/newsfeeds.php b/administrator/components/com_newsfeeds/models/fields/newsfeeds.php index 3eb638fb58eb5..2624e4531b3a8 100644 --- a/administrator/components/com_newsfeeds/models/fields/newsfeeds.php +++ b/administrator/components/com_newsfeeds/models/fields/newsfeeds.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JFormHelper::loadFieldClass('list'); diff --git a/administrator/components/com_newsfeeds/models/forms/filter_newsfeeds.xml b/administrator/components/com_newsfeeds/models/forms/filter_newsfeeds.xml index 60f597b38c7cb..8e60abac2c5e8 100644 --- a/administrator/components/com_newsfeeds/models/forms/filter_newsfeeds.xml +++ b/administrator/components/com_newsfeeds/models/forms/filter_newsfeeds.xml @@ -6,6 +6,7 @@ diff --git a/administrator/components/com_newsfeeds/models/forms/newsfeed.xml b/administrator/components/com_newsfeeds/models/forms/newsfeed.xml index 93655cd20c9c0..6153e839501d1 100644 --- a/administrator/components/com_newsfeeds/models/forms/newsfeed.xml +++ b/administrator/components/com_newsfeeds/models/forms/newsfeed.xml @@ -5,7 +5,7 @@ - - - - + + + + * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -43,100 +43,6 @@ class NewsfeedsModelNewsfeed extends JModelAdmin */ protected $text_prefix = 'COM_NEWSFEEDS'; - /** - * Batch copy items to a new category or current. - * - * @param integer $value The new category. - * @param array $pks An array of row IDs. - * @param array $contexts An array of item contexts. - * - * @return mixed An array of new IDs on success, boolean false on failure. - * - * @since 11.1 - */ - protected function batchCopy($value, $pks, $contexts) - { - $categoryId = (int) $value; - - $newIds = array(); - - if (!parent::checkCategoryId($categoryId)) - { - return false; - } - - // Parent exists so we let's proceed - while (!empty($pks)) - { - // Pop the first ID off the stack - $pk = array_shift($pks); - - $this->table->reset(); - - // Check that the row actually exists - if (!$this->table->load($pk)) - { - if ($error = $this->table->getError()) - { - // Fatal error - $this->setError($error); - - return false; - } - else - { - // Not fatal error - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); - continue; - } - } - - // Alter the title & alias - $data = $this->generateNewTitle($categoryId, $this->table->alias, $this->table->name); - $this->table->name = $data['0']; - $this->table->alias = $data['1']; - - // Reset the ID because we are making a copy - $this->table->id = 0; - - // Unpublish because we are making a copy - $this->table->published = 0; - - // New category ID - $this->table->catid = $categoryId; - - // TODO: Deal with ordering? - // $this->table->ordering = 1; - - // Check the row. - if (!$this->table->check()) - { - $this->setError($this->table->getError()); - return false; - } - - parent::createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); - - // Store the row. - if (!$this->table->store()) - { - $this->setError($this->table->getError()); - return false; - } - - // Get the new item ID - $newId = $this->table->get('id'); - - // Add the new ID to the array - $newIds[$pk] = $newId; - } - - // Clean the cache - $this->cleanCache(); - - return $newIds; - } - /** * Method to test whether a record can be deleted. * @@ -148,26 +54,17 @@ protected function batchCopy($value, $pks, $contexts) */ protected function canDelete($record) { - if (!empty($record->id)) + if (empty($record->id) || $record->published != -2) { - if ($record->published != -2) - { - return false; - } - - $user = JFactory::getUser(); + return false; + } - if (!empty($record->catid)) - { - return $user->authorise('core.delete', 'com_newsfeed.category.' . (int) $record->catid); - } - else - { - return parent::canDelete($record); - } + if (!empty($record->catid)) + { + return JFactory::getUser()->authorise('core.delete', 'com_newsfeed.category.' . (int) $record->catid); } - return false; + return parent::canDelete($record); } /** @@ -181,16 +78,12 @@ protected function canDelete($record) */ protected function canEditState($record) { - $user = JFactory::getUser(); - if (!empty($record->catid)) { - return $user->authorise('core.edit.state', 'com_newsfeeds.category.' . (int) $record->catid); - } - else - { - return parent::canEditState($record); + return JFactory::getUser()->authorise('core.edit.state', 'com_newsfeeds.category.' . (int) $record->catid); } + + return parent::canEditState($record); } /** @@ -305,20 +198,22 @@ public function save($data) JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - // Cast catid to integer for comparison - $catid = (int) $data['catid']; + // Create new category, if needed. + $createCategory = true; - // Check if New Category exists - if ($catid > 0) + // If category ID is provided, check if it's valid. + if (is_numeric($data['catid']) && $data['catid']) { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_newsfeeds'); + $createCategory = !CategoriesHelper::validateCategoryId($data['catid'], 'com_newsfeeds'); } // Save New Category - if ($catid == 0 && $this->canCreateCategory()) + if ($createCategory && $this->canCreateCategory()) { $table = array(); - $table['title'] = $data['catid']; + + // Remove #new# prefix, if exists. + $table['title'] = strpos($data['catid'], '#new#') === 0 ? substr($data['catid'], 5) : $data['catid']; $table['parent_id'] = 1; $table['extension'] = 'com_newsfeeds'; $table['language'] = $data['language']; @@ -347,6 +242,7 @@ public function save($data) $data['alias'] = ''; } } + $data['published'] = 0; } @@ -486,6 +382,7 @@ protected function getReorderConditions($table) { $condition = array(); $condition[] = 'catid = ' . (int) $table->catid; + return $condition; } @@ -505,6 +402,9 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') if ($this->canCreateCategory()) { $form->setFieldAttribute('catid', 'allowAdd', 'true'); + + // Add a prefix for categories created on the fly. + $form->setFieldAttribute('catid', 'customPrefix', '#new#'); } // Association newsfeeds items @@ -532,6 +432,7 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $field->addAttribute('new', 'true'); $field->addAttribute('edit', 'true'); $field->addAttribute('clear', 'true'); + $field->addAttribute('propagate', 'true'); } $form->load($addform, false); @@ -542,41 +443,41 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') } /** - * Method to change the title & alias. - * - * @param integer $category_id The id of the parent. - * @param string $alias The alias. - * @param string $name The title. + * Is the user allowed to create an on the fly category? * - * @return array Contains the modified title and alias. + * @return boolean * - * @since 3.1 + * @since 3.6.1 */ - protected function generateNewTitle($category_id, $alias, $name) + private function canCreateCategory() { - // Alter the title & alias - $table = $this->getTable(); - while ($table->load(array('alias' => $alias, 'catid' => $category_id))) - { - if ($name == $table->name) - { - $name = StringHelper::increment($name); - } - $alias = StringHelper::increment($alias, 'dash'); - } - - return array($name, $alias); + return JFactory::getUser()->authorise('core.create', 'com_newsfeeds'); } /** - * Is the user allowed to create an on the fly category? + * Method to validate the form data. * - * @return bool + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. * - * @since 3.6.1 + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.25 */ - private function canCreateCategory() + public function validate($form, $data, $group = null) { - return JFactory::getUser()->authorise('core.create', 'com_newsfeeds'); + // Don't allow to change the users if not allowed to access com_users. + if (!JFactory::getUser()->authorise('core.manage', 'com_users')) + { + if (isset($data['created_by'])) + { + unset($data['created_by']); + } + } + + return parent::validate($form, $data, $group); } } diff --git a/administrator/components/com_newsfeeds/models/newsfeeds.php b/administrator/components/com_newsfeeds/models/newsfeeds.php index 161b87625d3d6..6f777a8b13724 100644 --- a/administrator/components/com_newsfeeds/models/newsfeeds.php +++ b/administrator/components/com_newsfeeds/models/newsfeeds.php @@ -3,12 +3,14 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\Utilities\ArrayHelper; + /** * Methods supporting a list of newsfeed records. * @@ -46,9 +48,11 @@ public function __construct($config = array()) 'numarticles', 'tag', 'level', 'c.level', + 'tag', ); $assoc = JLanguageAssociations::isEnabled(); + if ($assoc) { $config['filter_fields'][] = 'association'; @@ -130,8 +134,8 @@ protected function getStoreId($id = '') $id .= ':' . $this->getState('filter.category_id'); $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.language'); - $id .= ':' . $this->getState('filter.tag'); $id .= ':' . $this->getState('filter.level'); + $id .= ':' . serialize($this->getState('filter.tag')); return parent::getStoreId($id); } @@ -154,8 +158,8 @@ protected function getListQuery() $this->getState( 'list.select', 'a.id, a.name, a.alias, a.checked_out, a.checked_out_time, a.catid,' . - ' a.numarticles, a.cache_time, a.created_by,' . - ' a.published, a.access, a.ordering, a.language, a.publish_up, a.publish_down' + ' a.numarticles, a.cache_time, a.created_by,' . + ' a.published, a.access, a.ordering, a.language, a.publish_up, a.publish_down' ) ); $query->from($db->quoteName('#__newsfeeds', 'a')); @@ -182,10 +186,18 @@ protected function getListQuery() if ($assoc) { - $query->select('COUNT(asso2.id)>1 AS association') - ->join('LEFT', $db->quoteName('#__associations', 'asso') . ' ON asso.id = a.id AND asso.context = ' . $db->quote('com_newsfeeds.item')) - ->join('LEFT', $db->quoteName('#__associations', 'asso2') . ' ON asso2.key = asso.key') - ->group('a.id, l.title, l.image, uc.name, ag.title, c.title'); + $subQuery = $db->getQuery(true) + ->select('COUNT(' . $db->quoteName('asso1.id') . ') > 1') + ->from($db->quoteName('#__associations', 'asso1')) + ->join('INNER', $db->quoteName('#__associations', 'asso2') . ' ON ' . $db->quoteName('asso1.key') . ' = ' . $db->quoteName('asso2.key')) + ->where( + array( + $db->quoteName('asso1.id') . ' = ' . $db->quoteName('a.id'), + $db->quoteName('asso1.context') . ' = ' . $db->quote('com_newsfeeds.item'), + ) + ); + + $query->select('(' . $subQuery . ') AS ' . $db->quoteName('association')); } // Filter by access level. @@ -248,21 +260,52 @@ protected function getListQuery() $query->where($db->quoteName('a.language') . ' = ' . $db->quote($language)); } - // Filter by a single tag. - $tagId = $this->getState('filter.tag'); + // Filter by a single or group of tags. + $tag = $this->getState('filter.tag'); + + // Run simplified query when filtering by one tag. + if (\is_array($tag) && \count($tag) === 1) + { + $tag = $tag[0]; + } - if (is_numeric($tagId)) + if ($tag && \is_array($tag)) { - $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId) - ->join( - 'LEFT', $db->quoteName('#__contentitem_tag_map', 'tagmap') + $tag = ArrayHelper::toInteger($tag); + + $subQuery = $db->getQuery(true) + ->select('DISTINCT ' . $db->quoteName('content_item_id')) + ->from($db->quoteName('#__contentitem_tag_map')) + ->where( + array( + $db->quoteName('tag_id') . ' IN (' . implode(',', $tag) . ')', + $db->quoteName('type_alias') . ' = ' . $db->quote('com_newsfeeds.newsfeed'), + ) + ); + + $query->join( + 'INNER', + '(' . $subQuery . ') AS ' . $db->quoteName('tagmap') . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') - . ' AND ' . $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_newsfeeds.newsfeed') + ); + } + elseif ($tag = (int) $tag) + { + $query->join( + 'INNER', + $db->quoteName('#__contentitem_tag_map', 'tagmap') + . ' ON ' . $db->quoteName('tagmap.content_item_id') . ' = ' . $db->quoteName('a.id') + ) + ->where( + array( + $db->quoteName('tagmap.tag_id') . ' = ' . $tag, + $db->quoteName('tagmap.type_alias') . ' = ' . $db->quote('com_newsfeeds.newsfeed'), + ) ); } // Add the list ordering clause. - $orderCol = $this->state->get('list.ordering', 'a.name'); + $orderCol = $this->state->get('list.ordering', 'a.name'); $orderDirn = $this->state->get('list.direction', 'ASC'); if ($orderCol == 'a.ordering' || $orderCol == 'category_title') diff --git a/administrator/components/com_newsfeeds/newsfeeds.php b/administrator/components/com_newsfeeds/newsfeeds.php index aa0a608a1f17a..9472dd51bc732 100644 --- a/administrator/components/com_newsfeeds/newsfeeds.php +++ b/administrator/components/com_newsfeeds/newsfeeds.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/newsfeeds.xml b/administrator/components/com_newsfeeds/newsfeeds.xml index 1e2f3be470a61..535adf177e792 100644 --- a/administrator/components/com_newsfeeds/newsfeeds.xml +++ b/administrator/components/com_newsfeeds/newsfeeds.xml @@ -3,7 +3,7 @@ com_newsfeeds Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_newsfeeds/sql/install.mysql.utf8.sql b/administrator/components/com_newsfeeds/sql/install.mysql.utf8.sql index da029c00d6067..10a5dcd5fed86 100644 --- a/administrator/components/com_newsfeeds/sql/install.mysql.utf8.sql +++ b/administrator/components/com_newsfeeds/sql/install.mysql.utf8.sql @@ -3,26 +3,26 @@ -- CREATE TABLE IF NOT EXISTS `#__newsfeeds` ( - `catid` int(11) NOT NULL DEFAULT 0, - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `catid` int NOT NULL DEFAULT 0, + `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL DEFAULT '', `alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '', `link` varchar(2048) NOT NULL DEFAULT '', - `published` tinyint(1) NOT NULL DEFAULT 0, - `numarticles` int(10) unsigned NOT NULL DEFAULT 1, - `cache_time` int(10) unsigned NOT NULL DEFAULT 3600, - `checked_out` int(10) unsigned NOT NULL DEFAULT 0, + `published` tinyint NOT NULL DEFAULT 0, + `numarticles` int unsigned NOT NULL DEFAULT 1, + `cache_time` int unsigned NOT NULL DEFAULT 3600, + `checked_out` int unsigned NOT NULL DEFAULT 0, `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `ordering` int(11) NOT NULL DEFAULT 0, - `rtl` tinyint(4) NOT NULL DEFAULT 0, - `access` int(10) unsigned NOT NULL DEFAULT 0, + `ordering` int NOT NULL DEFAULT 0, + `rtl` tinyint NOT NULL DEFAULT 0, + `access` int unsigned NOT NULL DEFAULT 0, `language` char(7) NOT NULL DEFAULT '', `params` text NOT NULL, `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_by` int(10) unsigned NOT NULL DEFAULT 0, + `created_by` int unsigned NOT NULL DEFAULT 0, `created_by_alias` varchar(255) NOT NULL DEFAULT '', `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `modified_by` int(10) unsigned NOT NULL DEFAULT 0, + `modified_by` int unsigned NOT NULL DEFAULT 0, `metakey` text NOT NULL, `metadesc` text NOT NULL, `metadata` text NOT NULL, @@ -30,8 +30,8 @@ CREATE TABLE IF NOT EXISTS `#__newsfeeds` ( `publish_up` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `publish_down` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `description` text NOT NULL, - `version` int(10) unsigned NOT NULL DEFAULT 1, - `hits` int(10) unsigned NOT NULL DEFAULT 0, + `version` int unsigned NOT NULL DEFAULT 1, + `hits` int unsigned NOT NULL DEFAULT 0, `images` text NOT NULL, PRIMARY KEY (`id`), KEY `idx_access` (`access`), diff --git a/administrator/components/com_newsfeeds/tables/newsfeed.php b/administrator/components/com_newsfeeds/tables/newsfeed.php index 49188b94f4dfe..a66631d488b40 100644 --- a/administrator/components/com_newsfeeds/tables/newsfeed.php +++ b/administrator/components/com_newsfeeds/tables/newsfeed.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -35,6 +35,8 @@ public function __construct(&$db) { parent::__construct('#__newsfeeds', 'id', $db); + $this->setColumnAlias('title', 'name'); + JTableObserverTags::createObserver($this, array('typeAlias' => 'com_newsfeeds.newsfeed')); JTableObserverContenthistory::createObserver($this, array('typeAlias' => 'com_newsfeeds.newsfeed')); } @@ -50,6 +52,7 @@ public function check() if (trim($this->name) == '') { $this->setError(JText::_('COM_NEWSFEEDS_WARNING_PROVIDE_VALID_NAME')); + return false; } @@ -146,8 +149,9 @@ public function store($updateNulls = false) $this->created_by = $user->get('id'); } } + // Verify that the alias is unique - $table = JTable::getInstance('Newsfeed', 'NewsfeedsTable'); + $table = JTable::getInstance('Newsfeed', 'NewsfeedsTable', array('dbo' => $this->_db)); if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) { diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit.php index 1447ba96333c0..cbe2cab061b15 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -15,6 +15,7 @@ JHtml::_('behavior.formvalidator'); JHtml::_('behavior.keepalive'); JHtml::_('formbehavior.chosen', '#jform_catid', null, array('disable_search_threshold' => 0 )); +JHtml::_('formbehavior.chosen', '#jform_tags', null, array('placeholder_text_multiple' => JText::_('JGLOBAL_TYPE_OR_SELECT_SOME_TAGS'))); JHtml::_('formbehavior.chosen', 'select'); $app = JFactory::getApplication(); diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_associations.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_associations.php index 38de9c2f4c70d..bacf2118287cc 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_associations.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_display.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_display.php index e4a190d512cb5..f99d0569c98aa 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_display.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_display.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_metadata.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_metadata.php index 446c938e51468..fafebab13e3aa 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_metadata.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_params.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_params.php index 66665ade073a5..c269a57f96a33 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_params.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_params.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal.php index 9a5fd3ddb898a..6959376d1e5fc 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_associations.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_associations.php index 38de9c2f4c70d..bacf2118287cc 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_associations.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_associations.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_display.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_display.php index e4a190d512cb5..f99d0569c98aa 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_display.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_display.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_metadata.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_metadata.php index 446c938e51468..daf7210524640 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_metadata.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_params.php b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_params.php index 66665ade073a5..3d78dc3ac71b7 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_params.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_params.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeed/view.html.php b/administrator/components/com_newsfeeds/views/newsfeed/view.html.php index 92ef8e2ae053d..0263c55aa9887 100644 --- a/administrator/components/com_newsfeeds/views/newsfeed/view.html.php +++ b/administrator/components/com_newsfeeds/views/newsfeed/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -105,16 +105,23 @@ protected function addToolbar() JToolbarHelper::apply('newsfeed.apply'); JToolbarHelper::save('newsfeed.save'); } + if (!$checkedOut && count($user->getAuthorisedCategories('com_newsfeeds', 'core.create')) > 0) { JToolbarHelper::save2new('newsfeed.save2new'); } + // If an existing item, can save to a copy. if (!$isNew && $canDo->get('core.create')) { JToolbarHelper::save2copy('newsfeed.save2copy'); } + if (!$isNew && JLanguageAssociations::isEnabled() && JComponentHelper::isEnabled('com_associations')) + { + JToolbarHelper::custom('newsfeed.editAssociations', 'contract', 'contract', 'JTOOLBAR_ASSOCIATIONS', false, false); + } + if (empty($this->item->id)) { JToolbarHelper::cancel('newsfeed.cancel'); diff --git a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php index d71d1fbb7d3a2..cb91061e4d42f 100644 --- a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php +++ b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_body.php b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_body.php index 567b6e8698e20..c6a89e22374d7 100644 --- a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_body.php +++ b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_body.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -$published = $this->state->get('filter.published'); +$published = (int) $this->state->get('filter.published'); ?>
    diff --git a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_footer.php b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_footer.php index d0a7643556480..e4be418cdb6ad 100644 --- a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_footer.php +++ b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_footer.php @@ -3,15 +3,15 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - + + \ No newline at end of file + diff --git a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/modal.php b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/modal.php index 10ab99a55d9d7..4bd2e92baba45 100644 --- a/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/modal.php +++ b/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/modal.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -15,6 +15,7 @@ JHtml::_('behavior.core'); JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); +JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); JHtml::_('formbehavior.chosen', 'select'); // Special case for the search field tooltip. diff --git a/administrator/components/com_newsfeeds/views/newsfeeds/view.html.php b/administrator/components/com_newsfeeds/views/newsfeeds/view.html.php index 72462f8a5f78b..2022f87857602 100644 --- a/administrator/components/com_newsfeeds/views/newsfeeds/view.html.php +++ b/administrator/components/com_newsfeeds/views/newsfeeds/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_newsfeeds * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -67,6 +67,7 @@ public function display($tpl = null) if (count($errors = $this->get('Errors'))) { JError::raiseError(500, implode("\n", $errors)); + return false; } @@ -82,7 +83,7 @@ public function display($tpl = null) // We also need to change the category filter to show show categories with All or the forced language. if ($forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'CMD')) { - // If the language is forced we can't allow to select the language, so transform the language selector filter into an hidden field. + // If the language is forced we can't allow to select the language, so transform the language selector filter into a hidden field. $languageXml = new SimpleXMLElement(''); $this->filterForm->setField($languageXml, 'filter', true); diff --git a/administrator/components/com_plugins/config.xml b/administrator/components/com_plugins/config.xml index 1be01d303eb54..f95a4f66bc211 100644 --- a/administrator/components/com_plugins/config.xml +++ b/administrator/components/com_plugins/config.xml @@ -12,6 +12,7 @@ filter="rules" validate="rules" component="com_plugins" - section="component" /> + section="component" + />
    diff --git a/administrator/components/com_plugins/controller.php b/administrator/components/com_plugins/controller.php index a4199485c95d8..2bdf751510fc3 100644 --- a/administrator/components/com_plugins/controller.php +++ b/administrator/components/com_plugins/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_plugins/controllers/plugin.php b/administrator/components/com_plugins/controllers/plugin.php index 690880d1fff97..e310f11c39191 100644 --- a/administrator/components/com_plugins/controllers/plugin.php +++ b/administrator/components/com_plugins/controllers/plugin.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_plugins/controllers/plugins.php b/administrator/components/com_plugins/controllers/plugins.php index d30db20d7912f..d3ffeed0b9806 100644 --- a/administrator/components/com_plugins/controllers/plugins.php +++ b/administrator/components/com_plugins/controllers/plugins.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_plugins/helpers/plugins.php b/administrator/components/com_plugins/helpers/plugins.php index 5a9909e2440f9..9193f66c1a82a 100644 --- a/administrator/components/com_plugins/helpers/plugins.php +++ b/administrator/components/com_plugins/helpers/plugins.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -60,7 +60,7 @@ public static function getActions() /** * Returns an array of standard published state filter options. * - * @return string The HTML code for the select tag + * @return array The HTML code for the select tag */ public static function publishedOptions() { @@ -73,7 +73,7 @@ public static function publishedOptions() } /** - * Returns an array of standard published state filter options. + * Returns a list of folders filter options. * * @return string The HTML code for the select tag */ @@ -100,6 +100,34 @@ public static function folderOptions() return $options; } + /** + * Returns a list of elements filter options. + * + * @return string The HTML code for the select tag + */ + public static function elementOptions() + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT(element) AS value, element AS text') + ->from('#__extensions') + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->order('element'); + + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + return $options; + } + /** * Parse the template file. * diff --git a/administrator/components/com_plugins/models/fields/pluginelement.php b/administrator/components/com_plugins/models/fields/pluginelement.php new file mode 100644 index 0000000000000..7a2961bb011e1 --- /dev/null +++ b/administrator/components/com_plugins/models/fields/pluginelement.php @@ -0,0 +1,44 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JLoader::register('PluginsHelper', JPATH_ADMINISTRATOR . '/components/com_plugins/helpers/plugins.php'); + +JFormHelper::loadFieldClass('list'); + +/** + * Plugin Element field. + * + * @since 3.9.0 + */ +class JFormFieldPluginElement extends JFormFieldList +{ + /** + * The form field type. + * + * @var string + * @since 3.9.0 + */ + protected $type = 'PluginElement'; + + /** + * Method to get the field options. + * + * @return array The field option objects. + * + * @since 3.9.0 + */ + public function getOptions() + { + $options = PluginsHelper::elementOptions(); + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_plugins/models/fields/pluginordering.php b/administrator/components/com_plugins/models/fields/pluginordering.php index 361be0fbb8c5b..948495f0809f8 100644 --- a/administrator/components/com_plugins/models/fields/pluginordering.php +++ b/administrator/components/com_plugins/models/fields/pluginordering.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JFormHelper::loadFieldClass('ordering'); diff --git a/administrator/components/com_plugins/models/fields/plugintype.php b/administrator/components/com_plugins/models/fields/plugintype.php index c53143b726e8a..4d9d10b5cad38 100644 --- a/administrator/components/com_plugins/models/fields/plugintype.php +++ b/administrator/components/com_plugins/models/fields/plugintype.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_plugins/models/forms/filter_plugins.xml b/administrator/components/com_plugins/models/forms/filter_plugins.xml index 9c92446eb021f..170163fd59c14 100644 --- a/administrator/components/com_plugins/models/forms/filter_plugins.xml +++ b/administrator/components/com_plugins/models/forms/filter_plugins.xml @@ -6,6 +6,7 @@ COM_PLUGINS_OPTION_FOLDER + + + + diff --git a/administrator/components/com_plugins/models/forms/plugin.xml b/administrator/components/com_plugins/models/forms/plugin.xml index 41a034319eb32..271fc20e9a4c8 100644 --- a/administrator/components/com_plugins/models/forms/plugin.xml +++ b/administrator/components/com_plugins/models/forms/plugin.xml @@ -43,7 +43,7 @@ diff --git a/administrator/components/com_plugins/models/plugin.php b/administrator/components/com_plugins/models/plugin.php index 691a536afc90d..7d01afb8e1edf 100644 --- a/administrator/components/com_plugins/models/plugin.php +++ b/administrator/components/com_plugins/models/plugin.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -297,8 +297,8 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $helpKey = trim((string) $help[0]['key']); $helpURL = trim((string) $help[0]['url']); - $this->helpKey = $helpKey ? $helpKey : $this->helpKey; - $this->helpURL = $helpURL ? $helpURL : $this->helpURL; + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; } // Trigger the default form events. @@ -355,14 +355,14 @@ public function getHelp() /** * Custom clean cache method, plugins are cached in 2 places for different clients. * - * @param string $group Cache group name. - * @param integer $client_id Application client id. + * @param string $group Cache group name. + * @param integer $clientId Application client id. * * @return void * * @since 1.6 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { parent::cleanCache('com_plugins', 0); parent::cleanCache('com_plugins', 1); diff --git a/administrator/components/com_plugins/models/plugins.php b/administrator/components/com_plugins/models/plugins.php index 3e2634eadee37..704e57cd505b4 100644 --- a/administrator/components/com_plugins/models/plugins.php +++ b/administrator/components/com_plugins/models/plugins.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -75,8 +75,8 @@ protected function populateState($ordering = 'folder', $direction = 'asc') $folder = $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string'); $this->setState('filter.folder', $folder); - $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', '', 'string'); - $this->setState('filter.language', $language); + $element = $this->getUserStateFromRequest($this->context . '.filter.element', 'filter_element', '', 'string'); + $this->setState('filter.element', $element); // Load the parameters. $params = JComponentHelper::getParams('com_plugins'); @@ -104,7 +104,7 @@ protected function getStoreId($id = '') $id .= ':' . $this->getState('filter.access'); $id .= ':' . $this->getState('filter.enabled'); $id .= ':' . $this->getState('filter.folder'); - $id .= ':' . $this->getState('filter.language'); + $id .= ':' . $this->getState('filter.element'); return parent::getStoreId($id); } @@ -161,7 +161,7 @@ protected function _getList($query, $limitstart = 0, $limit = 0) $this->setState('list.start', 0); } - return array_slice($result, $limitstart, $limit ? $limit : null); + return array_slice($result, $limitstart, $limit ?: null); } else { @@ -263,6 +263,12 @@ protected function getListQuery() $query->where('a.folder = ' . $db->quote($folder)); } + // Filter by element. + if ($element = $this->getState('filter.element')) + { + $query->where('a.element = ' . $db->quote($element)); + } + // Filter by search in name or id. $search = $this->getState('filter.search'); diff --git a/administrator/components/com_plugins/plugins.php b/administrator/components/com_plugins/plugins.php index d46badb9143da..5204228c37575 100644 --- a/administrator/components/com_plugins/plugins.php +++ b/administrator/components/com_plugins/plugins.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_plugins/plugins.xml b/administrator/components/com_plugins/plugins.xml index 6ff94eda6e4e6..86aa89d1fad32 100644 --- a/administrator/components/com_plugins/plugins.xml +++ b/administrator/components/com_plugins/plugins.xml @@ -3,7 +3,7 @@ com_plugins Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_plugins/views/plugin/tmpl/edit.php b/administrator/components/com_plugins/views/plugin/tmpl/edit.php index bd1a040931a1e..e1dce3c190859 100644 --- a/administrator/components/com_plugins/views/plugin/tmpl/edit.php +++ b/administrator/components/com_plugins/views/plugin/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -17,17 +17,30 @@ JHtml::_('bootstrap.tooltip'); $this->fieldsets = $this->form->getFieldsets('params'); +$input = JFactory::getApplication()->input; + +// In case of modal +$isModal = $input->get('layout') === 'modal' ? true : false; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; + JFactory::getDocument()->addScriptDeclaration(" - Joomla.submitbutton = function(task) - { - if (task == 'plugin.cancel' || document.formvalidator.isValid(document.getElementById('style-form'))) { + Joomla.submitbutton = function(task) { + if (task === 'plugin.cancel' || document.formvalidator.isValid(document.getElementById('style-form'))) { Joomla.submitform(task, document.getElementById('style-form')); + + if (task !== 'plugin.apply') { + if (self !== top ) { + window.top.setTimeout('window.parent.location = window.top.location.href', 1000); + window.parent.jQuery('#plugin" . $this->item->extension_id . "Modal').modal('hide'); + } + } } }; "); ?> -
    +
    'general')); ?> @@ -38,7 +51,7 @@
    item->xml) : ?> item->xml->description) : ?> -

    +

    item->xml) { @@ -49,7 +62,7 @@ echo JText::_('COM_PLUGINS_XML_ERR'); } ?> -

    +
    form->getValue('folder'); ?> @@ -64,10 +77,10 @@ $this->fieldset = 'description'; $long_description = JLayoutHelper::render('joomla.edit.fieldset', $this); if (!$long_description) { - $truncated = JHtmlString::truncate($short_description, 550, true, false); + $truncated = JHtml::_('string.truncate', $short_description, 550, true, false); if (strlen($truncated) > 500) { $long_description = $short_description; - $short_description = JHtmlString::truncate($truncated, 250); + $short_description = JHtml::_('string.truncate', $truncated, 250); if ($short_description == $long_description) { $long_description = ''; } @@ -144,3 +157,4 @@ + diff --git a/administrator/components/com_plugins/views/plugin/tmpl/edit_options.php b/administrator/components/com_plugins/views/plugin/tmpl/edit_options.php index aac7c0bb73304..b91f39014c9bf 100644 --- a/administrator/components/com_plugins/views/plugin/tmpl/edit_options.php +++ b/administrator/components/com_plugins/views/plugin/tmpl/edit_options.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_plugins/views/plugin/tmpl/modal.php b/administrator/components/com_plugins/views/plugin/tmpl/modal.php new file mode 100644 index 0000000000000..36a26aa4f45a0 --- /dev/null +++ b/administrator/components/com_plugins/views/plugin/tmpl/modal.php @@ -0,0 +1,29 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +// This code is needed for proper check out in case of modal close +JFactory::getDocument()->addScriptDeclaration(' + window.parent.jQuery(".modal").on("hidden", function () { + if (typeof window.parent.jQuery("#plugin' . $this->item->extension_id . 'Modal iframe").contents().find("#closeBtn") !== "undefined") { + window.parent.jQuery("#plugin' . $this->item->extension_id . 'Modal iframe").contents().find("#closeBtn").click(); + } + }); +'); +?> + + + + +
    + setLayout('edit'); ?> + loadTemplate(); ?> +
    + diff --git a/administrator/components/com_plugins/views/plugin/view.html.php b/administrator/components/com_plugins/views/plugin/view.html.php index 0dd7a1ec8c469..d12cc6958bf97 100644 --- a/administrator/components/com_plugins/views/plugin/view.html.php +++ b/administrator/components/com_plugins/views/plugin/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_plugins/views/plugins/tmpl/default.php b/administrator/components/com_plugins/views/plugins/tmpl/default.php index 7833a007abe95..ce56a668f6ae1 100644 --- a/administrator/components/com_plugins/views/plugins/tmpl/default.php +++ b/administrator/components/com_plugins/views/plugins/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_plugins/views/plugins/view.html.php b/administrator/components/com_plugins/views/plugins/view.html.php index 37b33991946f3..ad379eb3b585c 100644 --- a/administrator/components/com_plugins/views/plugins/view.html.php +++ b/administrator/components/com_plugins/views/plugins/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_plugins * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_postinstall/controllers/message.php b/administrator/components/com_postinstall/controllers/message.php index b1b8c732ed317..4293a999b6ac7 100644 --- a/administrator/components/com_postinstall/controllers/message.php +++ b/administrator/components/com_postinstall/controllers/message.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_postinstall * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -25,6 +25,9 @@ class PostinstallControllerMessage extends FOFController */ public function reset() { + // CSRF prevention. + $this->_csrfProtection(); + /** @var PostinstallModelMessages $model */ $model = $this->getThisModel(); @@ -40,6 +43,33 @@ public function reset() $this->setRedirect('index.php?option=com_postinstall&eid=' . $eid); } + /** + * Hides all post-installation messages of the specified extension. + * + * @return void + * + * @since 3.8.7 + */ + public function hideAll() + { + // CSRF prevention. + $this->_csrfProtection(); + + /** @var PostinstallModelMessages $model */ + $model = $this->getThisModel(); + + $eid = (int) $model->getState('eid', '700', 'int'); + + if (empty($eid)) + { + $eid = 700; + } + + $model->hideMessages($eid); + + $this->setRedirect('index.php?option=com_postinstall&eid=' . $eid); + } + /** * Executes the action associated with an item. * @@ -50,10 +80,7 @@ public function reset() public function action() { // CSRF prevention. - if ($this->csrfProtection) - { - $this->_csrfProtection(); - } + $this->_csrfProtection(); $model = $this->getThisModel(); diff --git a/administrator/components/com_postinstall/models/messages.php b/administrator/components/com_postinstall/models/messages.php index 9a9667bf7f889..3691027f05aa5 100644 --- a/administrator/components/com_postinstall/models/messages.php +++ b/administrator/components/com_postinstall/models/messages.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_postinstall * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -37,7 +37,7 @@ public function buildQuery($overrideLimits = false) // Force filter only enabled messages $published = $this->getState('published', 1, 'int'); - $query->where($db->qn('enabled') . ' = ' . $db->q($published)); + $query->where($db->qn('enabled') . ' = ' . (int) $published); return $query; } @@ -59,7 +59,7 @@ public function getExtensionName($eid) $query = $db->getQuery(true) ->select(array('name', 'element', 'client_id')) ->from($db->qn('#__extensions')) - ->where($db->qn('extension_id') . ' = ' . $db->q((int) $eid)); + ->where($db->qn('extension_id') . ' = ' . (int) $eid); $db->setQuery($query, 0, 1); @@ -100,8 +100,30 @@ public function resetMessages($eid) $query = $db->getQuery(true) ->update($db->qn('#__postinstall_messages')) - ->set($db->qn('enabled') . ' = ' . $db->q(1)) - ->where($db->qn('extension_id') . ' = ' . $db->q($eid)); + ->set($db->qn('enabled') . ' = 1') + ->where($db->qn('extension_id') . ' = ' . (int) $eid); + $db->setQuery($query); + + return $db->execute(); + } + + /** + * Hides all messages for an extension + * + * @param integer $eid The extension ID whose messages we'll hide + * + * @return mixed False if we fail, a db cursor otherwise + * + * @since 3.8.7 + */ + public function hideMessages($eid) + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->update($db->qn('#__postinstall_messages')) + ->set($db->qn('enabled') . ' = 0') + ->where($db->qn('extension_id') . ' = ' . (int) $eid); $db->setQuery($query); return $db->execute(); @@ -420,7 +442,7 @@ public function addPostInstallationMessage(array $options) $query = $db->getQuery(true) ->select('*') ->from($db->qn($tableName)) - ->where($db->qn('extension_id') . ' = ' . $db->q($options['extension_id'])) + ->where($db->qn('extension_id') . ' = ' . (int) $options['extension_id']) ->where($db->qn('type') . ' = ' . $db->q($options['type'])) ->where($db->qn('title_key') . ' = ' . $db->q($options['title_key'])); @@ -449,7 +471,7 @@ public function addPostInstallationMessage(array $options) // Otherwise it's not the same row. Remove the old row before insert a new one. $query = $db->getQuery(true) ->delete($db->qn($tableName)) - ->where($db->q('extension_id') . ' = ' . $db->q($options['extension_id'])) + ->where($db->q('extension_id') . ' = ' . (int) $options['extension_id']) ->where($db->q('type') . ' = ' . $db->q($options['type'])) ->where($db->q('title_key') . ' = ' . $db->q($options['title_key'])); diff --git a/administrator/components/com_postinstall/postinstall.php b/administrator/components/com_postinstall/postinstall.php index d8fee19491017..ced667b16a502 100644 --- a/administrator/components/com_postinstall/postinstall.php +++ b/administrator/components/com_postinstall/postinstall.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_postinstall * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_postinstall/postinstall.xml b/administrator/components/com_postinstall/postinstall.xml index f91c08a96b7f6..c87f626bdae84 100644 --- a/administrator/components/com_postinstall/postinstall.xml +++ b/administrator/components/com_postinstall/postinstall.xml @@ -3,7 +3,7 @@ com_postinstall Joomla! Project September 2013 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2013 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_postinstall/toolbar.php b/administrator/components/com_postinstall/toolbar.php index 4b8753a8381ea..d710aa75f88f2 100644 --- a/administrator/components/com_postinstall/toolbar.php +++ b/administrator/components/com_postinstall/toolbar.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_postinstall * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_postinstall/views/messages/tmpl/default.php b/administrator/components/com_postinstall/views/messages/tmpl/default.php index 5a6ee4faa5c3d..dbd89b6b18b0a 100644 --- a/administrator/components/com_postinstall/views/messages/tmpl/default.php +++ b/administrator/components/com_postinstall/views/messages/tmpl/default.php @@ -3,13 +3,16 @@ * @package Joomla.Administrator * @subpackage com_postinstall * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -$renderer = JFactory::getDocument()->loadRenderer('module'); +use Joomla\CMS\Factory; + +$lang = Factory::getLanguage(); +$renderer = Factory::getDocument()->loadRenderer('module'); $options = array('style' => 'raw'); $mod = JModuleHelper::getModule('mod_feed'); $param = array( @@ -19,6 +22,8 @@ 'rssimage' => 1, 'rssitems' => 5, 'rssitemdesc' => 1, + 'rssitemdate' => 1, + 'rssrtl' => $lang->isRtl() ? 1 : 0, 'word_count' => 200, 'cache' => 0, ); @@ -27,8 +32,10 @@ JHtml::_('formbehavior.chosen', 'select'); ?> -
    + + + extension_options, 'eid', array('onchange' => 'this.form.submit()', 'class' => 'input-xlarge'), 'value', 'text', $this->eid, 'eid'); ?>
    @@ -53,14 +60,14 @@

    version_introduced); ?>

    -

    description_key); ?>

    + description_key); ?> type !== 'message') : ?> action_key); ?> - authorise('core.edit.state', 'com_postinstall')) : ?> + authorise('core.edit.state', 'com_postinstall')) : ?> @@ -71,7 +78,7 @@ eid == 700) : ?>
    -
    +
    isRtl()) : ?> style="padding-right: 20px;">

    render($mod, $params, $options); ?>
    diff --git a/administrator/components/com_postinstall/views/messages/view.html.php b/administrator/components/com_postinstall/views/messages/view.html.php index 7cfffa8c46edc..b6f9590650713 100644 --- a/administrator/components/com_postinstall/views/messages/view.html.php +++ b/administrator/components/com_postinstall/views/messages/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_postinstall * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -44,4 +44,25 @@ protected function onBrowse($tpl = null) return parent::onBrowse($tpl); } + + /** + * Executes on display of the page + * + * @param string $tpl Subtemplate to use + * + * @return boolean Return true to allow rendering of the page + * + * @since 3.8.7 + */ + protected function onDisplay($tpl = null) + { + $return = parent::onDisplay($tpl); + + if (!empty($this->items)) + { + JToolbarHelper::custom('hideAll', 'unpublish.png', 'unpublish_f2.png', 'COM_POSTINSTALL_HIDE_ALL_MESSAGES', false); + } + + return $return; + } } diff --git a/administrator/components/com_privacy/config.xml b/administrator/components/com_privacy/config.xml new file mode 100644 index 0000000000000..833d1a2834a2b --- /dev/null +++ b/administrator/components/com_privacy/config.xml @@ -0,0 +1,22 @@ + + +
    + + + +
    +
    diff --git a/administrator/components/com_privacy/controller.php b/administrator/components/com_privacy/controller.php new file mode 100644 index 0000000000000..0f3a2b219f0cf --- /dev/null +++ b/administrator/components/com_privacy/controller.php @@ -0,0 +1,140 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Response\JsonResponse; +use Joomla\CMS\Session\Session; + +/** + * Privacy Controller + * + * @since 3.9.0 + */ +class PrivacyController extends JControllerLegacy +{ + /** + * The default view. + * + * @var string + * @since 3.9.0 + */ + protected $default_view = 'dashboard'; + + /** + * Method to display a view. + * + * @param boolean $cachable If true, the view output will be cached + * @param array $urlparams An array of safe URL parameters and their variable types, for valid values see {@link JFilterInput::clean()}. + * + * @return $this + * + * @since 3.9.0 + */ + public function display($cachable = false, $urlparams = array()) + { + JLoader::register('PrivacyHelper', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/privacy.php'); + + // Get the document object. + $document = JFactory::getDocument(); + + // Set the default view name and format from the Request. + $vName = $this->input->get('view', $this->default_view); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + $model = $this->getModel($vName); + $view->setModel($model, true); + + // For the dashboard view, we need to also push the requests model into the view + if ($vName === 'dashboard') + { + $requestsModel = $this->getModel('Requests'); + + $view->setModel($requestsModel, false); + } + + if ($vName === 'request') + { + // For the default layout, we need to also push the action logs model into the view + if ($lName === 'default') + { + JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $logsModel = $this->getModel('Actionlogs', 'ActionlogsModel'); + + // Set default ordering for the context + $logsModel->setState('list.fullordering', 'a.log_date DESC'); + + // And push the model into the view + $view->setModel($logsModel, false); + } + + // For the edit layout, if mail sending is disabled then redirect back to the list view as the form is unusable in this state + if ($lName === 'edit' && !JFactory::getConfig()->get('mailonline', 1)) + { + $this->setRedirect( + JRoute::_('index.php?option=com_privacy&view=requests', false), + JText::_('COM_PRIVACY_WARNING_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED'), + 'warning' + ); + + return $this; + } + } + + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + + // Load the submenu. + PrivacyHelper::addSubmenu($this->input->get('view', $this->default_view)); + + $view->display(); + } + + return $this; + } + + /** + * Fetch and report number urgent privacy requests in JSON format, for AJAX requests + * + * @return void + * + * @since 3.9.0 + */ + public function getNumberUrgentRequests() + { + $app = Factory::getApplication(); + + // Check for a valid token. If invalid, send a 403 with the error message. + if (!Session::checkToken('get')) + { + $app->setHeader('status', 403, true); + $app->sendHeaders(); + echo new JsonResponse(new \Exception(Text::_('JINVALID_TOKEN'), 403)); + $app->close(); + } + + /** @var PrivacyModelRequests $model */ + $model = $this->getModel('requests'); + $numberUrgentRequests = $model->getNumberUrgentRequests(); + + echo new JResponseJson(array('number_urgent_requests' => $numberUrgentRequests)); + + $app->close(); + } +} diff --git a/administrator/components/com_privacy/controllers/consents.php b/administrator/components/com_privacy/controllers/consents.php new file mode 100644 index 0000000000000..43e47e4bf07f6 --- /dev/null +++ b/administrator/components/com_privacy/controllers/consents.php @@ -0,0 +1,92 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Consents management controller class. + * + * @since 3.9.0 + */ +class PrivacyControllerConsents extends JControllerForm +{ + /** + * Method to invalidate specific consents. + * + * @return boolean + * + * @since 3.9.0 + */ + public function invalidate($key = null, $urlVar = null) + { + // Check for request forgeries + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + + if (empty($ids)) + { + $this->setError(JText::_('JERROR_NO_ITEMS_SELECTED')); + } + else + { + // Get the model. + /** @var PrivacyModelConsents $model */ + $model = $this->getModel(); + + // Publish the items. + if (!$model->invalidate($ids)) + { + $this->setError($model->getError()); + } + + $message = JText::plural('COM_PRIVACY_N_CONSENTS_INVALIDATED', count($ids)); + } + + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=consents', false), $message); + } + + /** + * Method to invalidate all consents of a specific subject. + * + * @return boolean + * + * @since 3.9.0 + */ + public function invalidateAll() + { + // Check for request forgeries + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + $filters = $this->input->get('filter', array(), 'array'); + + if (isset($filters['subject']) && $filters['subject'] != '') + { + $subject = $filters['subject']; + } + else + { + $this->setError(JText::_('JERROR_NO_ITEMS_SELECTED')); + } + + // Get the model. + /** @var PrivacyModelConsents $model */ + $model = $this->getModel(); + + // Publish the items. + if (!$model->invalidateAll($subject)) + { + $this->setError($model->getError()); + } + + $message = JText::_('COM_PRIVACY_CONSENTS_INVALIDATED_ALL'); + + $this->setRedirect(JRoute::_('index.php?option=com_privacy&view=consents', false), $message); + } +} diff --git a/administrator/components/com_privacy/controllers/request.php b/administrator/components/com_privacy/controllers/request.php new file mode 100644 index 0000000000000..48727f7098ca3 --- /dev/null +++ b/administrator/components/com_privacy/controllers/request.php @@ -0,0 +1,401 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Request management controller class. + * + * @since 3.9.0 + */ +class PrivacyControllerRequest extends JControllerForm +{ + /** + * Method to complete a request. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean + * + * @since 3.9.0 + */ + public function complete($key = null, $urlVar = null) + { + // Check for request forgeries. + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + /** @var PrivacyModelRequest $model */ + $model = $this->getModel(); + + /** @var PrivacyTableRequest $table */ + $table = $model->getTable(); + + // Determine the name of the primary key for the data. + if (empty($key)) + { + $key = $table->getKeyName(); + } + + // To avoid data collisions the urlVar may be different from the primary key. + if (empty($urlVar)) + { + $urlVar = $key; + } + + $recordId = $this->input->getInt($urlVar); + + $item = $model->getItem($recordId); + + // Ensure this record can transition to the requested state + if (!$this->canTransition($item, '2')) + { + $this->setError(\JText::_('COM_PRIVACY_ERROR_COMPLETE_TRANSITION_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Build the data array for the update + $data = array( + $key => $recordId, + 'status' => '2', + ); + + // Access check. + if (!$this->allowSave($data, $key)) + { + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Log the request completed + $model->logRequestCompleted($recordId); + + $this->setMessage(\JText::_('COM_PRIVACY_REQUEST_COMPLETED')); + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Method to email the data export for a request. + * + * @return boolean + * + * @since 3.9.0 + */ + public function emailexport() + { + // Check for request forgeries. + $this->checkToken('get'); + + /** @var PrivacyModelExport $model */ + $model = $this->getModel('Export'); + + $recordId = $this->input->getUint('id'); + + if (!$model->emailDataExport($recordId)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('COM_PRIVACY_ERROR_EXPORT_EMAIL_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + } + else + { + $this->setMessage(\JText::_('COM_PRIVACY_EXPORT_EMAILED')); + } + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Method to invalidate a request. + * + * @param string $key The name of the primary key of the URL variable. + * @param string $urlVar The name of the URL variable if different from the primary key (sometimes required to avoid router collisions). + * + * @return boolean + * + * @since 3.9.0 + */ + public function invalidate($key = null, $urlVar = null) + { + // Check for request forgeries. + JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + + /** @var PrivacyModelRequest $model */ + $model = $this->getModel(); + + /** @var PrivacyTableRequest $table */ + $table = $model->getTable(); + + // Determine the name of the primary key for the data. + if (empty($key)) + { + $key = $table->getKeyName(); + } + + // To avoid data collisions the urlVar may be different from the primary key. + if (empty($urlVar)) + { + $urlVar = $key; + } + + $recordId = $this->input->getInt($urlVar); + + $item = $model->getItem($recordId); + + // Ensure this record can transition to the requested state + if (!$this->canTransition($item, '-1')) + { + $this->setError(\JText::_('COM_PRIVACY_ERROR_INVALID_TRANSITION_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Build the data array for the update + $data = array( + $key => $recordId, + 'status' => '-1', + ); + + // Access check. + if (!$this->allowSave($data, $key)) + { + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + // Log the request invalidated + $model->logRequestInvalidated($recordId); + + $this->setMessage(\JText::_('COM_PRIVACY_REQUEST_INVALIDATED')); + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Method to remove the user data for a privacy remove request. + * + * @return boolean + * + * @since 3.9.0 + */ + public function remove() + { + // Check for request forgeries. + $this->checkToken('request'); + + /** @var PrivacyModelRemove $model */ + $model = $this->getModel('Remove'); + + $recordId = $this->input->getUint('id'); + + if (!$model->removeDataForRequest($recordId)) + { + // Redirect back to the edit screen. + $this->setError(\JText::sprintf('COM_PRIVACY_ERROR_REMOVE_DATA_FAILED', $model->getError())); + $this->setMessage($this->getError(), 'error'); + + $this->setRedirect( + \JRoute::_( + 'index.php?option=com_privacy&view=request&id=' . $recordId, false + ) + ); + + return false; + } + + $this->setMessage(\JText::_('COM_PRIVACY_DATA_REMOVED')); + + $url = 'index.php?option=com_privacy&view=requests'; + + // Check if there is a return value + $return = $this->input->get('return', null, 'base64'); + + if (!is_null($return) && \JUri::isInternal(base64_decode($return))) + { + $url = base64_decode($return); + } + + // Redirect to the list screen. + $this->setRedirect(\JRoute::_($url, false)); + + return true; + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param \JModelLegacy $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 3.9.0 + */ + protected function postSaveHook(\JModelLegacy $model, $validData = array()) + { + // This hook only processes new items + if (!$model->getState($model->getName() . '.new', false)) + { + return; + } + + if (!$model->logRequestCreated($model->getState($model->getName() . '.id'))) + { + if ($error = $model->getError()) + { + JFactory::getApplication()->enqueueMessage($error, 'warning'); + } + } + + if (!$model->notifyUserAdminCreatedRequest($model->getState($model->getName() . '.id'))) + { + if ($error = $model->getError()) + { + JFactory::getApplication()->enqueueMessage($error, 'warning'); + } + } + else + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_PRIVACY_MSG_CONFIRM_EMAIL_SENT_TO_USER')); + } + } + + /** + * Method to determine if an item can transition to the specified status. + * + * @param object $item The item being updated. + * @param string $newStatus The new status of the item. + * + * @return boolean + * + * @since 3.9.0 + */ + private function canTransition($item, $newStatus) + { + switch ($item->status) + { + case '0': + // A pending item can only move to invalid through this controller due to the requirement for a user to confirm the request + return $newStatus === '-1'; + + case '1': + // A confirmed item can be marked completed or invalid + return in_array($newStatus, array('-1', '2'), true); + + // An item which is already in an invalid or complete state cannot transition, likewise if we don't know the state don't change anything + case '-1': + case '2': + default: + return false; + } + } +} diff --git a/administrator/components/com_privacy/controllers/request.xml.php b/administrator/components/com_privacy/controllers/request.xml.php new file mode 100644 index 0000000000000..aff01b72ca634 --- /dev/null +++ b/administrator/components/com_privacy/controllers/request.xml.php @@ -0,0 +1,32 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Request management controller class. + * + * @since 3.9.0 + */ +class PrivacyControllerRequest extends JControllerLegacy +{ + /** + * Method to export the data for a request. + * + * @return $this + * + * @since 3.9.0 + */ + public function export() + { + $this->input->set('view', 'export'); + + return $this->display(); + } +} diff --git a/administrator/components/com_privacy/controllers/requests.php b/administrator/components/com_privacy/controllers/requests.php new file mode 100644 index 0000000000000..11be7f1db03d3 --- /dev/null +++ b/administrator/components/com_privacy/controllers/requests.php @@ -0,0 +1,34 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Requests management controller class. + * + * @since 3.9.0 + */ +class PrivacyControllerRequests extends JControllerAdmin +{ + /** + * Method to get a model object, loading it if required. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return JModelLegacy|boolean Model object on success; otherwise false on failure. + * + * @since 3.9.0 + */ + public function getModel($name = 'Request', $prefix = 'PrivacyModel', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_privacy/helpers/export/domain.php b/administrator/components/com_privacy/helpers/export/domain.php new file mode 100644 index 0000000000000..3990755dcbffc --- /dev/null +++ b/administrator/components/com_privacy/helpers/export/domain.php @@ -0,0 +1,72 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JLoader::register('PrivacyExportItem', __DIR__ . '/item.php'); + +/** + * Data object representing all data contained in a domain. + * + * A domain is typically a single database table and the items within the domain are separate rows from the table. + * + * @since 3.9.0 + */ +class PrivacyExportDomain +{ + /** + * The name of this domain + * + * @var string + * @since 3.9.0 + */ + public $name; + + /** + * A short description of the data in this domain + * + * @var string + * @since 3.9.0 + */ + public $description; + + /** + * The items belonging to this domain + * + * @var PrivacyExportItem[] + * @since 3.9.0 + */ + protected $items = array(); + + /** + * Add an item to the domain + * + * @param PrivacyExportItem $item The item to add + * + * @return void + * + * @since 3.9.0 + */ + public function addItem(PrivacyExportItem $item) + { + $this->items[] = $item; + } + + /** + * Get the domain's items + * + * @return PrivacyExportItem[] + * + * @since 3.9.0 + */ + public function getItems() + { + return $this->items; + } +} diff --git a/administrator/components/com_privacy/helpers/export/field.php b/administrator/components/com_privacy/helpers/export/field.php new file mode 100644 index 0000000000000..9ef41610c0b9c --- /dev/null +++ b/administrator/components/com_privacy/helpers/export/field.php @@ -0,0 +1,34 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Data object representing a field within an item. + * + * @since 3.9.0 + */ +class PrivacyExportField +{ + /** + * The name of this field + * + * @var string + * @since 3.9.0 + */ + public $name; + + /** + * The field's value + * + * @var mixed + * @since 3.9.0 + */ + public $value; +} diff --git a/administrator/components/com_privacy/helpers/export/item.php b/administrator/components/com_privacy/helpers/export/item.php new file mode 100644 index 0000000000000..15aab627a9319 --- /dev/null +++ b/administrator/components/com_privacy/helpers/export/item.php @@ -0,0 +1,64 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JLoader::register('PrivacyExportField', __DIR__ . '/field.php'); + +/** + * Data object representing a single item within a domain. + * + * An item is typically a single row from a database table. + * + * @since 3.9.0 + */ +class PrivacyExportItem +{ + /** + * The primary identifier of this item, typically the primary key for a database row. + * + * @var integer + * @since 3.9.0 + */ + public $id; + + /** + * The fields belonging to this item + * + * @var PrivacyExportField[] + * @since 3.9.0 + */ + protected $fields = array(); + + /** + * Add a field to the item + * + * @param PrivacyExportField $field The field to add + * + * @return void + * + * @since 3.9.0 + */ + public function addField(PrivacyExportField $field) + { + $this->fields[] = $field; + } + + /** + * Get the item's fields + * + * @return PrivacyExportField[] + * + * @since 3.9.0 + */ + public function getFields() + { + return $this->fields; + } +} diff --git a/administrator/components/com_privacy/helpers/html/helper.php b/administrator/components/com_privacy/helpers/html/helper.php new file mode 100644 index 0000000000000..286c0a373c0d2 --- /dev/null +++ b/administrator/components/com_privacy/helpers/html/helper.php @@ -0,0 +1,46 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Privacy component HTML helper. + * + * @since 3.9.0 + */ +class PrivacyHtmlHelper +{ + /** + * Render a status label + * + * @param integer $status The item status + * + * @return string + * + * @since 3.9.0 + */ + public static function statusLabel($status) + { + switch ($status) + { + case 2: + return '' . JText::_('COM_PRIVACY_STATUS_COMPLETED') . ''; + + case 1: + return '' . JText::_('COM_PRIVACY_STATUS_CONFIRMED') . ''; + + case -1: + return '' . JText::_('COM_PRIVACY_STATUS_INVALID') . ''; + + default: + case 0: + return '' . JText::_('COM_PRIVACY_STATUS_PENDING') . ''; + } + } +} diff --git a/administrator/components/com_privacy/helpers/plugin.php b/administrator/components/com_privacy/helpers/plugin.php new file mode 100644 index 0000000000000..c2f8defded36e --- /dev/null +++ b/administrator/components/com_privacy/helpers/plugin.php @@ -0,0 +1,167 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JLoader::register('PrivacyExportDomain', __DIR__ . '/export/domain.php'); +JLoader::register('PrivacyExportField', __DIR__ . '/export/field.php'); +JLoader::register('PrivacyExportItem', __DIR__ . '/export/item.php'); +JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php'); + +/** + * Base class for privacy plugins + * + * @since 3.9.0 + */ +abstract class PrivacyPlugin extends JPlugin +{ + /** + * Database object + * + * @var JDatabaseDriver + * @since 3.9.0 + */ + protected $db; + + /** + * Affects constructor behaviour. If true, language files will be loaded automatically. + * + * @var boolean + * @since 3.9.0 + */ + protected $autoloadLanguage = true; + + /** + * Create a new domain object + * + * @param string $name The domain's name + * @param string $description The domain's description + * + * @return PrivacyExportDomain + * + * @since 3.9.0 + */ + protected function createDomain($name, $description = '') + { + $domain = new PrivacyExportDomain; + $domain->name = $name; + $domain->description = $description; + + return $domain; + } + + /** + * Create an item object for an array + * + * @param array $data The array data to convert + * @param integer|null $itemId The ID of this item + * + * @return PrivacyExportItem + * + * @since 3.9.0 + */ + protected function createItemFromArray(array $data, $itemId = null) + { + $item = new PrivacyExportItem; + $item->id = $itemId; + + foreach ($data as $key => $value) + { + if (is_object($value)) + { + $value = (array) $value; + } + + if (is_array($value)) + { + $value = print_r($value, true); + } + + $field = new PrivacyExportField; + $field->name = $key; + $field->value = $value; + + $item->addField($field); + } + + return $item; + } + + /** + * Create an item object for a JTable object + * + * @param JTable $table The JTable object to convert + * + * @return PrivacyExportItem + * + * @since 3.9.0 + */ + protected function createItemForTable($table) + { + $data = array(); + + foreach (array_keys($table->getFields()) as $fieldName) + { + $data[$fieldName] = $table->$fieldName; + } + + return $this->createItemFromArray($data, $table->{$table->getKeyName(false)}); + } + + /** + * Helper function to create the domain for the items custom fields. + * + * @param string $context The context + * @param array $items The items + * + * @return PrivacyExportDomain + * + * @since 3.9.0 + */ + protected function createCustomFieldsDomain($context, $items = array()) + { + if (!is_array($items)) + { + $items = array($items); + } + + $parts = FieldsHelper::extract($context); + + if (!$parts) + { + return array(); + } + + $type = str_replace('com_', '', $parts[0]); + + $domain = $this->createDomain($type . '_' . $parts[1] . '_custom_fields', 'joomla_' . $type . '_' . $parts[1] . '_custom_fields_data'); + + foreach ($items as $item) + { + // Get item's fields, also preparing their value property for manual display + $fields = FieldsHelper::getFields($parts[0] . '.' . $parts[1], $item); + + foreach ($fields as $field) + { + $fieldValue = is_array($field->value) ? implode(', ', $field->value) : $field->value; + + $data = array( + $type . '_id' => $item->id, + 'field_name' => $field->name, + 'field_title' => $field->title, + 'field_value' => $fieldValue, + ); + + $domain->addItem($this->createItemFromArray($data)); + } + } + + return $domain; + } +} diff --git a/administrator/components/com_privacy/helpers/privacy.php b/administrator/components/com_privacy/helpers/privacy.php new file mode 100644 index 0000000000000..f7f271dd7d61a --- /dev/null +++ b/administrator/components/com_privacy/helpers/privacy.php @@ -0,0 +1,128 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; + +/** + * Privacy component helper. + * + * @since 3.9.0 + */ +class PrivacyHelper extends JHelperContent +{ + /** + * Configure the Linkbar. + * + * @param string $vName The name of the active view. + * + * @return void + * + * @since 3.9.0 + */ + public static function addSubmenu($vName) + { + JHtmlSidebar::addEntry( + JText::_('COM_PRIVACY_SUBMENU_DASHBOARD'), + 'index.php?option=com_privacy&view=dashboard', + $vName === 'dashboard' + ); + + JHtmlSidebar::addEntry( + JText::_('COM_PRIVACY_SUBMENU_REQUESTS'), + 'index.php?option=com_privacy&view=requests', + $vName === 'requests' + ); + + JHtmlSidebar::addEntry( + JText::_('COM_PRIVACY_SUBMENU_CAPABILITIES'), + 'index.php?option=com_privacy&view=capabilities', + $vName === 'capabilities' + ); + + JHtmlSidebar::addEntry( + JText::_('COM_PRIVACY_SUBMENU_CONSENTS'), + 'index.php?option=com_privacy&view=consents', + $vName === 'consents' + ); + } + + /** + * Render the data request as a XML document. + * + * @param PrivacyExportDomain[] $exportData The data to be exported. + * + * @return string + * + * @since 3.9.0 + */ + public static function renderDataAsXml(array $exportData) + { + $export = new SimpleXMLElement(''); + + foreach ($exportData as $domain) + { + $xmlDomain = $export->addChild('domain'); + $xmlDomain->addAttribute('name', $domain->name); + $xmlDomain->addAttribute('description', $domain->description); + + foreach ($domain->getItems() as $item) + { + $xmlItem = $xmlDomain->addChild('item'); + + if ($item->id) + { + $xmlItem->addAttribute('id', $item->id); + } + + foreach ($item->getFields() as $field) + { + $xmlItem->{$field->name} = $field->value; + } + } + } + + $dom = new DOMDocument; + $dom->loadXML($export->asXML()); + $dom->formatOutput = true; + + return $dom->saveXML(); + } + + /** + * Gets the privacyconsent system plugin extension id. + * + * @return integer The privacyconsent system plugin extension id. + * + * @since 3.9.2 + */ + public static function getPrivacyConsentPluginId() + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) + ->where($db->quoteName('element') . ' = ' . $db->quote('privacyconsent')); + + $db->setQuery($query); + + try + { + $result = (int) $db->loadResult(); + } + catch (RuntimeException $e) + { + JError::raiseWarning(500, $e->getMessage()); + } + + return $result; + } +} diff --git a/administrator/components/com_privacy/helpers/removal/status.php b/administrator/components/com_privacy/helpers/removal/status.php new file mode 100644 index 0000000000000..016e0c1e4f414 --- /dev/null +++ b/administrator/components/com_privacy/helpers/removal/status.php @@ -0,0 +1,36 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Data object communicating the status of whether the data for an information request can be removed. + * + * Typically, this object will only be used to communicate data will be removed. + * + * @since 3.9.0 + */ +class PrivacyRemovalStatus +{ + /** + * Flag indicating the status reported by the plugin on whether the information can be removed + * + * @var boolean + * @since 3.9.0 + */ + public $canRemove = true; + + /** + * A status message indicating the reason data can or cannot be removed + * + * @var string + * @since 3.9.0 + */ + public $reason; +} diff --git a/administrator/components/com_privacy/models/capabilities.php b/administrator/components/com_privacy/models/capabilities.php new file mode 100644 index 0000000000000..3d6e9ed13e3d5 --- /dev/null +++ b/administrator/components/com_privacy/models/capabilities.php @@ -0,0 +1,101 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Capabilities model class. + * + * @since 3.9.0 + */ +class PrivacyModelCapabilities extends JModelLegacy +{ + /** + * Retrieve the extension capabilities. + * + * @return array + * + * @since 3.9.0 + */ + public function getCapabilities() + { + $app = JFactory::getApplication(); + + /* + * Capabilities will be collected in two parts: + * + * 1) Core capabilities - This will cover the core API, i.e. all library level classes + * 2) Extension capabilities - This will be collected by a plugin hook to select plugin groups + * + * Plugins which report capabilities should return an associative array with a single root level key which is used as the title + * for the reporting section and an array with each value being a separate capability. All capability messages should be translated + * by the extension when building the array. An example of the structure expected to be returned from plugins can be found in the + * $coreCapabilities array below. + */ + + $coreCapabilities = array( + JText::_('COM_PRIVACY_HEADING_CORE_CAPABILITIES') => array( + JText::_('COM_PRIVACY_CORE_CAPABILITY_SESSION_IP_ADDRESS_AND_COOKIE'), + JText::sprintf('COM_PRIVACY_CORE_CAPABILITY_LOGGING_IP_ADDRESS', $app->get('log_path', JPATH_ADMINISTRATOR . '/logs')), + JText::_('COM_PRIVACY_CORE_CAPABILITY_COMMUNICATION_WITH_JOOMLA_ORG'), + ) + ); + + /* + * We will search for capabilities from the following plugin groups: + * + * - Authentication: These plugins by design process user information and may have capabilities such as creating cookies + * - Captcha: These plugins may communicate information to third party systems + * - Installer: These plugins can add additional install capabilities to the Extension Manager, such as the Install from Web service + * - Privacy: These plugins are the primary integration point into this component + * - User: These plugins are intended to extend the user management system + * + * This is in addition to plugin groups which are imported before this method is triggered, generally this is the system group. + */ + + JPluginHelper::importPlugin('authentication'); + JPluginHelper::importPlugin('captcha'); + JPluginHelper::importPlugin('installer'); + JPluginHelper::importPlugin('privacy'); + JPluginHelper::importPlugin('user'); + + $pluginResults = $app->triggerEvent('onPrivacyCollectAdminCapabilities'); + + // We are going to "cheat" here and include this component's capabilities without using a plugin + $extensionCapabilities = array( + JText::_('COM_PRIVACY') => array( + JText::_('COM_PRIVACY_EXTENSION_CAPABILITY_PERSONAL_INFO'), + ) + ); + + foreach ($pluginResults as $pluginResult) + { + $extensionCapabilities += $pluginResult; + } + + // Sort the extension list alphabetically + ksort($extensionCapabilities); + + // Always prepend the core capabilities to the array + return $coreCapabilities + $extensionCapabilities; + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState() + { + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + } +} diff --git a/administrator/components/com_privacy/models/consents.php b/administrator/components/com_privacy/models/consents.php new file mode 100644 index 0000000000000..b7e0b72520a11 --- /dev/null +++ b/administrator/components/com_privacy/models/consents.php @@ -0,0 +1,226 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\Utilities\ArrayHelper; + +/** + * Consents management model class. + * + * @since 3.9.0 + */ +class PrivacyModelConsents extends JModelList +{ + /** + * Constructor. + * + * @param array $config An optional associative array of configuration settings. + * + * @since 3.9.0 + */ + public function __construct($config = array()) + { + if (empty($config['filter_fields'])) + { + $config['filter_fields'] = array( + 'id', 'a.id', + 'user_id', 'a.user_id', + 'subject', 'a.subject', + 'created', 'a.created', + 'username', 'u.username', + 'state', 'a.state' + ); + } + + parent::__construct($config); + } + + /** + * Method to get a JDatabaseQuery object for retrieving the data set from a database. + * + * @return JDatabaseQuery + * + * @since 3.9.0 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select($this->getState('list.select', 'a.*')); + $query->from($db->quoteName('#__privacy_consents', 'a')); + + // Join over the users for the username. + $query->select($db->quoteName('u.username', 'username')); + $query->join('LEFT', $db->quoteName('#__users', 'u') . ' ON u.id = a.user_id'); + + // Filter by search in email + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'uid:') === 0) + { + $query->where($db->quoteName('a.user_id') . ' = ' . (int) substr($search, 4)); + } + else + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(' . $db->quoteName('u.username') . ' LIKE ' . $search . ')'); + } + } + + $state = $this->getState('filter.state'); + + if ($state != '') + { + $query->where($db->quoteName('a.state') . ' = ' . (int) $state); + } + + // Handle the list ordering. + $ordering = $this->getState('list.ordering'); + $direction = $this->getState('list.direction'); + + if (!empty($ordering)) + { + $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); + } + + return $query; + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string + * + * @since 3.9.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState($ordering = 'a.id', $direction = 'desc') + { + // Load the filter state. + $this->setState( + 'filter.search', + $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search') + ); + + $this->setState( + 'filter.subject', + $this->getUserStateFromRequest($this->context . '.filter.subject', 'filter_subject') + ); + + $this->setState( + 'filter.state', + $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state') + ); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to invalidate specific consents. + * + * @param array $pks The ids of the consents to invalidate. + * + * @return boolean True on success. + */ + public function invalidate($pks) + { + // Sanitize the ids. + $pks = (array) $pks; + $pks = ArrayHelper::toInteger($pks); + + try + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__privacy_consents')) + ->set($db->quoteName('state') . ' = -1') + ->where($db->quoteName('id') . ' IN (' . implode(',', $pks) . ')') + ->where($db->quoteName('state') . ' = 1'); + $db->setQuery($query); + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } + + /** + * Method to invalidate a group of specific consents. + * + * @param array $subject The subject of the consents to invalidate. + * + * @return boolean True on success. + */ + public function invalidateAll($subject) + { + try + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__privacy_consents')) + ->set($db->quoteName('state') . ' = -1') + ->where($db->quoteName('subject') . ' = ' . $db->quote($subject)) + ->where($db->quoteName('state') . ' = 1'); + $db->setQuery($query); + $db->execute(); + } + catch (JDatabaseExceptionExecuting $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } +} diff --git a/administrator/components/com_privacy/models/dashboard.php b/administrator/components/com_privacy/models/dashboard.php new file mode 100644 index 0000000000000..c219692282af5 --- /dev/null +++ b/administrator/components/com_privacy/models/dashboard.php @@ -0,0 +1,158 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Router\Route; + +/** + * Dashboard model class. + * + * @since 3.9.0 + */ +class PrivacyModelDashboard extends JModelLegacy +{ + /** + * Get the information about the published privacy policy + * + * @return array Array containing a status of whether a privacy policy is set and a link to the policy document for editing + * + * @since 3.9.0 + */ + public function getPrivacyPolicyInfo() + { + $policy = array( + 'published' => false, + 'articlePublished' => false, + 'editLink' => '', + ); + + /* + * Prior to 3.9.0 it was common for a plugin such as the User - Profile plugin to define a privacy policy or + * terms of service article, therefore we will also import the user plugin group to process this event. + */ + JPluginHelper::importPlugin('privacy'); + JPluginHelper::importPlugin('user'); + + JFactory::getApplication()->triggerEvent('onPrivacyCheckPrivacyPolicyPublished', array(&$policy)); + + return $policy; + } + + /** + * Get a count of the active information requests grouped by type and status + * + * @return array Array containing site privacy requests + * + * @since 3.9.0 + */ + public function getRequestCounts() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select( + array( + 'COUNT(*) AS count', + $db->quoteName('status'), + $db->quoteName('request_type'), + ) + ) + ->from($db->quoteName('#__privacy_requests')) + ->group($db->quoteName('status')) + ->group($db->quoteName('request_type')); + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Check whether there is a menu item for the request form + * + * @return array Array containing a status of whether a menu is published for the request form and its current link + * + * @since 3.9.0 + */ + public function getRequestFormPublished() + { + $status = array( + 'exists' => false, + 'published' => false, + 'link' => '', + ); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id') . ', ' . $db->quoteName('published') . ', ' . $db->quoteName('language')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('client_id') . ' = 0') + ->where($db->quoteName('link') . ' = ' . $db->quote('index.php?option=com_privacy&view=request')); + $db->setQuery($query); + + $menuItem = $db->loadObject(); + + // Check if the menu item exists in database + if ($menuItem) + { + $status['exists'] = true; + + // Check if the menu item is published + if ($menuItem->published == 1) + { + $status['published'] = true; + } + + // Add language to the url if the site is multilingual + if (JLanguageMultilang::isEnabled() && $menuItem->language && $menuItem->language !== '*') + { + $lang = '&lang=' . $menuItem->language; + } + else + { + $lang = ''; + } + } + + $linkMode = JFactory::getApplication()->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + if (!$menuItem) + { + if (JLanguageMultilang::isEnabled()) + { + // Find the Itemid of the home menu item tagged to the site default language + $params = JComponentHelper::getParams('com_languages'); + $defaultSiteLanguage = $params->get('site'); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('client_id') . ' = 0') + ->where($db->quoteName('home') . ' = 1') + ->where($db->quoteName('language') . ' = ' . $db->quote($defaultSiteLanguage)); + $db->setQuery($query); + + $homeId = (int) $db->loadResult(); + $itemId = $homeId ? '&Itemid=' . $homeId : ''; + } + else + { + $itemId = ''; + } + + $status['link'] = JRoute::link('site', 'index.php?option=com_privacy&view=request' . $itemId, true, $linkMode); + } + else + { + $status['link'] = JRoute::link('site', 'index.php?Itemid=' . $menuItem->id . $lang, true, $linkMode); + } + + return $status; + } +} diff --git a/administrator/components/com_privacy/models/export.php b/administrator/components/com_privacy/models/export.php new file mode 100644 index 0000000000000..5c13f5b446b68 --- /dev/null +++ b/administrator/components/com_privacy/models/export.php @@ -0,0 +1,340 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JLoader::register('PrivacyHelper', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/privacy.php'); + +/** + * Export model class. + * + * @since 3.9.0 + */ +class PrivacyModelExport extends JModelLegacy +{ + /** + * Create the export document for an information request. + * + * @param integer $id The request ID to process + * + * @return PrivacyExportDomain[]|boolean A SimpleXMLElement object for a successful export or boolean false on an error + * + * @since 3.9.0 + */ + public function collectDataForExportRequest($id = null) + { + $id = !empty($id) ? $id : (int) $this->getState($this->getName() . '.request_id'); + + if (!$id) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_EXPORT')); + + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->request_type !== 'export') + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_EXPORT')); + + return false; + } + + if ($table->status != 1) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_EXPORT_UNCONFIRMED_REQUEST')); + + return false; + } + + // If there is a user account associated with the email address, load it here for use in the plugins + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($table->email) . ')'), + 0, + 1 + )->loadResult(); + + $user = $userId ? JUser::getInstance($userId) : null; + + // Log the export + $this->logExport($table); + + JPluginHelper::importPlugin('privacy'); + + $pluginResults = JFactory::getApplication()->triggerEvent('onPrivacyExportRequest', array($table, $user)); + + $domains = array(); + + foreach ($pluginResults as $pluginDomains) + { + $domains = array_merge($domains, $pluginDomains); + } + + return $domains; + } + + /** + * Email the data export to the user. + * + * @param integer $id The request ID to process + * + * @return boolean + * + * @since 3.9.0 + */ + public function emailDataExport($id = null) + { + $id = !empty($id) ? $id : (int) $this->getState($this->getName() . '.request_id'); + + if (!$id) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_EXPORT')); + + return false; + } + + $exportData = $this->collectDataForExportRequest($id); + + if ($exportData === false) + { + // Error is already set, we just need to bail + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->request_type !== 'export') + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_EXPORT')); + + return false; + } + + if ($table->status != 1) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_EXPORT_UNCONFIRMED_REQUEST')); + + return false; + } + + // Log the email + $this->logExportEmailed($table); + + /* + * If there is an associated user account, we will attempt to send this email in the user's preferred language. + * Because of this, it is expected that Language::_() is directly called and that the Text class is NOT used + * for translating all messages. + * + * Error messages will still be displayed to the administrator, so those messages should continue to use the Text class. + */ + + $lang = JFactory::getLanguage(); + + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($table->email) . ')'), + 0, + 1 + )->loadResult(); + + if ($userId) + { + $receiver = JUser::getInstance($userId); + + /* + * We don't know if the user has admin access, so we will check if they have an admin language in their parameters, + * falling back to the site language, falling back to the currently active language + */ + + $langCode = $receiver->getParam('admin_language', ''); + + if (!$langCode) + { + $langCode = $receiver->getParam('language', $lang->getTag()); + } + + $lang = JLanguage::getInstance($langCode, $lang->getDebug()); + } + + // Ensure the right language files have been loaded + $lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy', null, false, true); + + // The mailer can be set to either throw Exceptions or return boolean false, account for both + try + { + $app = JFactory::getApplication(); + + $substitutions = array( + '[SITENAME]' => $app->get('sitename'), + '[URL]' => JUri::root(), + '\\n' => "\n", + ); + + $emailSubject = $lang->_('COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_SUBJECT'); + $emailBody = $lang->_('COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_BODY'); + + foreach ($substitutions as $k => $v) + { + $emailSubject = str_replace($k, $v, $emailSubject); + $emailBody = str_replace($k, $v, $emailBody); + } + + $mailer = JFactory::getMailer(); + $mailer->setSubject($emailSubject); + $mailer->setBody($emailBody); + $mailer->addRecipient($table->email); + $mailer->addStringAttachment( + PrivacyHelper::renderDataAsXml($exportData), + 'user-data_' . JUri::getInstance()->toString(array('host')) . '.xml' + ); + + $mailResult = $mailer->Send(); + + if ($mailResult instanceof JException) + { + // JError was already called so we just need to return now + return false; + } + elseif ($mailResult === false) + { + $this->setError($mailer->ErrorInfo); + + return false; + } + + return true; + } + catch (phpmailerException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + + return true; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.9.0 + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Log the data export to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * + * @return void + * + * @since 3.9.0 + */ + public function logExport(PrivacyTableRequest $request) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'export', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_EXPORT', 'com_privacy.request', $user->id); + } + + /** + * Log the data export email to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * + * @return void + * + * @since 3.9.0 + */ + public function logExportEmailed(PrivacyTableRequest $request) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'export_emailed', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_EXPORT_EMAILED', 'com_privacy.request', $user->id); + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState() + { + // Get the pk of the record from the request. + $this->setState($this->getName() . '.request_id', JFactory::getApplication()->input->getUint('id')); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + } +} diff --git a/administrator/components/com_privacy/models/fields/requeststatus.php b/administrator/components/com_privacy/models/fields/requeststatus.php new file mode 100644 index 0000000000000..0de16b2ae70d3 --- /dev/null +++ b/administrator/components/com_privacy/models/fields/requeststatus.php @@ -0,0 +1,41 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JFormHelper::loadFieldClass('predefinedlist'); + +/** + * Form Field to load a list of request statuses + * + * @since 3.9.0 + */ +class PrivacyFormFieldRequeststatus extends JFormFieldPredefinedList +{ + /** + * The form field type. + * + * @var string + * @since 3.9.0 + */ + public $type = 'RequestStatus'; + + /** + * Available statuses + * + * @var array + * @since 3.9.0 + */ + protected $predefinedOptions = array( + '-1' => 'COM_PRIVACY_STATUS_INVALID', + '0' => 'COM_PRIVACY_STATUS_PENDING', + '1' => 'COM_PRIVACY_STATUS_CONFIRMED', + '2' => 'COM_PRIVACY_STATUS_COMPLETED', + ); +} diff --git a/administrator/components/com_privacy/models/fields/requesttype.php b/administrator/components/com_privacy/models/fields/requesttype.php new file mode 100644 index 0000000000000..b0d272fd18372 --- /dev/null +++ b/administrator/components/com_privacy/models/fields/requesttype.php @@ -0,0 +1,39 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JFormHelper::loadFieldClass('predefinedlist'); + +/** + * Form Field to load a list of request types + * + * @since 3.9.0 + */ +class PrivacyFormFieldRequesttype extends JFormFieldPredefinedList +{ + /** + * The form field type. + * + * @var string + * @since 3.9.0 + */ + public $type = 'RequestType'; + + /** + * Available types + * + * @var array + * @since 3.9.0 + */ + protected $predefinedOptions = array( + 'export' => 'COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_EXPORT', + 'remove' => 'COM_PRIVACY_HEADING_REQUEST_TYPE_TYPE_REMOVE', + ); +} diff --git a/administrator/components/com_privacy/models/forms/filter_consents.xml b/administrator/components/com_privacy/models/forms/filter_consents.xml new file mode 100644 index 0000000000000..b5adeec990905 --- /dev/null +++ b/administrator/components/com_privacy/models/forms/filter_consents.xml @@ -0,0 +1,75 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_privacy/models/forms/filter_requests.xml b/administrator/components/com_privacy/models/forms/filter_requests.xml new file mode 100644 index 0000000000000..e60aa2e8569a9 --- /dev/null +++ b/administrator/components/com_privacy/models/forms/filter_requests.xml @@ -0,0 +1,65 @@ + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_privacy/models/forms/request.xml b/administrator/components/com_privacy/models/forms/request.xml new file mode 100644 index 0000000000000..0ee1e6f9fdd01 --- /dev/null +++ b/administrator/components/com_privacy/models/forms/request.xml @@ -0,0 +1,54 @@ + +
    +
    + + + + + + + + + + + + + + + + +
    +
    diff --git a/administrator/components/com_privacy/models/remove.php b/administrator/components/com_privacy/models/remove.php new file mode 100644 index 0000000000000..c95694534f6ed --- /dev/null +++ b/administrator/components/com_privacy/models/remove.php @@ -0,0 +1,204 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JLoader::register('PrivacyHelper', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/privacy.php'); +JLoader::register('PrivacyRemovalStatus', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/removal/status.php'); + +/** + * Remove model class. + * + * @since 3.9.0 + */ +class PrivacyModelRemove extends JModelLegacy +{ + /** + * Remove the user data. + * + * @param integer $id The request ID to process + * + * @return boolean + * + * @since 3.9.0 + */ + public function removeDataForRequest($id = null) + { + $id = !empty($id) ? $id : (int) $this->getState($this->getName() . '.request_id'); + + if (!$id) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_ID_REQUIRED_FOR_REMOVE')); + + return false; + } + + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + if ($table->request_type !== 'remove') + { + $this->setError(JText::_('COM_PRIVACY_ERROR_REQUEST_TYPE_NOT_REMOVE')); + + return false; + } + + if ($table->status != 1) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_REMOVE_UNCONFIRMED_REQUEST')); + + return false; + } + + // If there is a user account associated with the email address, load it here for use in the plugins + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($table->email) . ')'), + 0, + 1 + )->loadResult(); + + $user = $userId ? JUser::getInstance($userId) : null; + + $canRemove = true; + + JPluginHelper::importPlugin('privacy'); + + /** @var PrivacyRemovalStatus[] $pluginResults */ + $pluginResults = JFactory::getApplication()->triggerEvent('onPrivacyCanRemoveData', array($table, $user)); + + foreach ($pluginResults as $status) + { + if (!$status->canRemove) + { + $this->setError($status->reason ?: JText::_('COM_PRIVACY_ERROR_CANNOT_REMOVE_DATA')); + + $canRemove = false; + } + } + + if (!$canRemove) + { + $this->logRemoveBlocked($table, $this->getErrors()); + + return false; + } + + // Log the removal + $this->logRemove($table); + + JFactory::getApplication()->triggerEvent('onPrivacyRemoveData', array($table, $user)); + + return true; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.9.0 + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Log the data removal to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * + * @return void + * + * @since 3.9.0 + */ + public function logRemove(PrivacyTableRequest $request) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'remove', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_REMOVE', 'com_privacy.request', $user->id); + } + + /** + * Log the data removal being blocked to the action log system. + * + * @param PrivacyTableRequest $request The request record being processed + * @param string[] $reasons The reasons given why the record could not be removed. + * + * @return void + * + * @since 3.9.0 + */ + public function logRemoveBlocked(PrivacyTableRequest $request, array $reasons) + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'remove-blocked', + 'id' => $request->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $request->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + 'reasons' => implode('; ', $reasons), + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_REMOVE_BLOCKED', 'com_privacy.request', $user->id); + } + + /** + * Method to auto-populate the model state. + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState() + { + // Get the pk of the record from the request. + $this->setState($this->getName() . '.request_id', JFactory::getApplication()->input->getUint('id')); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + } +} diff --git a/administrator/components/com_privacy/models/request.php b/administrator/components/com_privacy/models/request.php new file mode 100644 index 0000000000000..6641542100d27 --- /dev/null +++ b/administrator/components/com_privacy/models/request.php @@ -0,0 +1,462 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Router\Route; + +/** + * Request item model class. + * + * @since 3.9.0 + */ +class PrivacyModelRequest extends JModelAdmin +{ + /** + * Clean the cache + * + * @param string $group The cache group + * @param integer $clientId The ID of the client + * + * @return void + * + * @since 3.9.0 + */ + protected function cleanCache($group = 'com_privacy', $clientId = 1) + { + parent::cleanCache('com_privacy', 1); + } + + /** + * Method for getting the form from the model. + * + * @param array $data Data for the form. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return JForm|boolean A JForm object on success, false on failure + * + * @since 3.9.0 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_privacy.request', 'request', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $name The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $options Configuration array for model. Optional. + * + * @return JTable A JTable object + * + * @since 3.9.0 + * @throws \Exception + */ + public function getTable($name = 'Request', $prefix = 'PrivacyTable', $options = array()) + { + return parent::getTable($name, $prefix, $options); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return array The default data is an empty array. + * + * @since 3.9.0 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = JFactory::getApplication()->getUserState('com_privacy.edit.request.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + return $data; + } + + /** + * Log the completion of a request to the action log system. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since 3.9.0 + */ + public function logRequestCompleted($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'request-completed', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_ADMIN_COMPLETED_REQUEST', 'com_privacy.request', $user->id); + + return true; + } + + /** + * Log the creation of a request to the action log system. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since 3.9.0 + */ + public function logRequestCreated($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'request-created', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_ADMIN_CREATED_REQUEST', 'com_privacy.request', $user->id); + + return true; + } + + /** + * Log the invalidation of a request to the action log system. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since 3.9.0 + */ + public function logRequestInvalidated($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_actionlogs/models', 'ActionlogsModel'); + + $user = JFactory::getUser(); + + $message = array( + 'action' => 'request-invalidated', + 'requesttype' => $table->request_type, + 'subjectemail' => $table->email, + 'id' => $table->id, + 'itemlink' => 'index.php?option=com_privacy&view=request&id=' . $table->id, + 'userid' => $user->id, + 'username' => $user->username, + 'accountlink' => 'index.php?option=com_users&task=user.edit&id=' . $user->id, + ); + + /** @var ActionlogsModelActionlog $model */ + $model = JModelLegacy::getInstance('Actionlog', 'ActionlogsModel'); + $model->addLog(array($message), 'COM_PRIVACY_ACTION_LOG_ADMIN_INVALIDATED_REQUEST', 'com_privacy.request', $user->id); + + return true; + } + + /** + * Notifies the user that an information request has been created by a site administrator. + * + * Because confirmation tokens are stored in the database as a hashed value, this method will generate a new confirmation token + * for the request. + * + * @param integer $id The ID of the request to process. + * + * @return boolean + * + * @since 3.9.0 + */ + public function notifyUserAdminCreatedRequest($id) + { + /** @var PrivacyTableRequest $table */ + $table = $this->getTable(); + + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + /* + * If there is an associated user account, we will attempt to send this email in the user's preferred language. + * Because of this, it is expected that Language::_() is directly called and that the Text class is NOT used + * for translating all messages. + * + * Error messages will still be displayed to the administrator, so those messages should continue to use the Text class. + */ + + $lang = JFactory::getLanguage(); + + $db = $this->getDbo(); + + $userId = (int) $db->setQuery( + $db->getQuery(true) + ->select('id') + ->from($db->quoteName('#__users')) + ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(' . $db->quote($table->email) . ')'), + 0, + 1 + )->loadResult(); + + if ($userId) + { + $receiver = JUser::getInstance($userId); + + /* + * We don't know if the user has admin access, so we will check if they have an admin language in their parameters, + * falling back to the site language, falling back to the currently active language + */ + + $langCode = $receiver->getParam('admin_language', ''); + + if (!$langCode) + { + $langCode = $receiver->getParam('language', $lang->getTag()); + } + + $lang = JLanguage::getInstance($langCode, $lang->getDebug()); + } + + // Ensure the right language files have been loaded + $lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy', null, false, true); + + // Regenerate the confirmation token + $token = JApplicationHelper::getHash(JUserHelper::genRandomPassword()); + $hashedToken = JUserHelper::hashPassword($token); + + $table->confirm_token = $hashedToken; + $table->confirm_token_created_at = JFactory::getDate()->toSql(); + + try + { + $table->store(); + } + catch (JDatabaseException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + + // The mailer can be set to either throw Exceptions or return boolean false, account for both + try + { + $app = JFactory::getApplication(); + + $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; + + $substitutions = array( + '[SITENAME]' => $app->get('sitename'), + '[URL]' => JUri::root(), + '[TOKENURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm&confirm_token=' . $token, false, $linkMode, true), + '[FORMURL]' => JRoute::link('site', 'index.php?option=com_privacy&view=confirm', false, $linkMode, true), + '[TOKEN]' => $token, + '\\n' => "\n", + ); + + switch ($table->request_type) + { + case 'export': + $emailSubject = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_EXPORT_REQUEST'); + $emailBody = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_EXPORT_REQUEST'); + + break; + + case 'remove': + $emailSubject = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_SUBJECT_REMOVE_REQUEST'); + $emailBody = $lang->_('COM_PRIVACY_EMAIL_ADMIN_REQUEST_BODY_REMOVE_REQUEST'); + + break; + + default: + $this->setError(JText::_('COM_PRIVACY_ERROR_UNKNOWN_REQUEST_TYPE')); + + return false; + } + + foreach ($substitutions as $k => $v) + { + $emailSubject = str_replace($k, $v, $emailSubject); + $emailBody = str_replace($k, $v, $emailBody); + } + + $mailer = JFactory::getMailer(); + $mailer->setSubject($emailSubject); + $mailer->setBody($emailBody); + $mailer->addRecipient($table->email); + + $mailResult = $mailer->Send(); + + if ($mailResult instanceof JException) + { + // JError was already called so we just need to return now + return false; + } + elseif ($mailResult === false) + { + $this->setError($mailer->ErrorInfo); + + return false; + } + + return true; + } + catch (phpmailerException $exception) + { + $this->setError($exception->getMessage()); + + return false; + } + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success, False on error. + * + * @since 3.9.0 + */ + public function save($data) + { + $table = $this->getTable(); + $key = $table->getKeyName(); + $pk = !empty($data[$key]) ? $data[$key] : (int) $this->getState($this->getName() . '.id'); + + if (!$pk && !JFactory::getConfig()->get('mailonline', 1)) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_WHEN_SENDMAIL_DISABLED')); + + return false; + } + + return parent::save($data); + } + + /** + * Method to validate the form data. + * + * @param JForm $form The form to validate against. + * @param array $data The data to validate. + * @param string $group The name of the field group to validate. + * + * @return array|boolean Array of filtered data if valid, false otherwise. + * + * @see JFormRule + * @see JFilterInput + * @since 3.9.0 + */ + public function validate($form, $data, $group = null) + { + $validatedData = parent::validate($form, $data, $group); + + // If parent validation failed there's no point in doing our extended validation + if ($validatedData === false) + { + return false; + } + + // Make sure the status is always 0 + $validatedData['status'] = 0; + + // The user cannot create a request for their own account + if (strtolower(JFactory::getUser()->email) === strtolower($validatedData['email'])) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_CANNOT_CREATE_REQUEST_FOR_SELF')); + + return false; + } + + // Check for an active request for this email address + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->select('COUNT(id)') + ->from('#__privacy_requests') + ->where('email = ' . $db->quote($validatedData['email'])) + ->where('request_type = ' . $db->quote($validatedData['request_type'])) + ->where('status IN (0, 1)'); + + $activeRequestCount = (int) $db->setQuery($query)->loadResult(); + + if ($activeRequestCount > 0) + { + $this->setError(JText::_('COM_PRIVACY_ERROR_ACTIVE_REQUEST_FOR_EMAIL')); + + return false; + } + + return $validatedData; + } +} diff --git a/administrator/components/com_privacy/models/requests.php b/administrator/components/com_privacy/models/requests.php new file mode 100644 index 0000000000000..fdfe9e0ab3930 --- /dev/null +++ b/administrator/components/com_privacy/models/requests.php @@ -0,0 +1,190 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Component\ComponentHelper; + +/** + * Requests management model class. + * + * @since 3.9.0 + */ +class PrivacyModelRequests extends JModelList +{ + /** + * Constructor. + * + * @param array $config An optional associative array of configuration settings. + * + * @since 3.9.0 + */ + public function __construct($config = array()) + { + if (empty($config['filter_fields'])) + { + $config['filter_fields'] = array( + 'id', 'a.id', + 'email', 'a.email', + 'requested_at', 'a.requested_at', + 'request_type', 'a.request_type', + 'status', 'a.status', + ); + } + + parent::__construct($config); + } + + /** + * Method to get a JDatabaseQuery object for retrieving the data set from a database. + * + * @return JDatabaseQuery + * + * @since 3.9.0 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select($this->getState('list.select', 'a.*')); + $query->from($db->quoteName('#__privacy_requests', 'a')); + + // Filter by status + $status = $this->getState('filter.status'); + + if (is_numeric($status)) + { + $query->where('a.status = ' . (int) $status); + } + + // Filter by request type + $requestType = $this->getState('filter.request_type', ''); + + if ($requestType) + { + $query->where('a.request_type = ' . $db->quote($db->escape($requestType, true))); + } + + // Filter by search in email + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . $db->escape($search, true) . '%'); + $query->where('(' . $db->quoteName('a.email') . ' LIKE ' . $search . ')'); + } + } + + // Handle the list ordering. + $ordering = $this->getState('list.ordering'); + $direction = $this->getState('list.direction'); + + if (!empty($ordering)) + { + $query->order($db->escape($ordering) . ' ' . $db->escape($direction)); + } + + return $query; + } + + /** + * Method to get a store id based on model configuration state. + * + * This is necessary because the model is used by the component and + * different modules that might need different sets of data or different + * ordering requirements. + * + * @param string $id A prefix for the store id. + * + * @return string + * + * @since 3.9.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.status'); + $id .= ':' . $this->getState('filter.request_type'); + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. + * @param string $direction An optional direction (asc|desc). + * + * @return void + * + * @since 3.9.0 + */ + protected function populateState($ordering = 'a.id', $direction = 'desc') + { + // Load the filter state. + $this->setState( + 'filter.search', + $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search') + ); + + $this->setState( + 'filter.status', + $this->getUserStateFromRequest($this->context . '.filter.status', 'filter_status', '', 'int') + ); + + $this->setState( + 'filter.request_type', + $this->getUserStateFromRequest($this->context . '.filter.request_type', 'filter_request_type', '', 'string') + ); + + // Load the parameters. + $this->setState('params', JComponentHelper::getParams('com_privacy')); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to return number privacy requests older than X days. + * + * @return integer + * + * @since 3.9.0 + */ + public function getNumberUrgentRequests() + { + // Load the parameters. + $params = ComponentHelper::getComponent('com_privacy')->getParams(); + $notify = (int) $params->get('notify', 14); + $now = JFactory::getDate()->toSql(); + $period = '-' . $notify; + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)'); + $query->from($db->quoteName('#__privacy_requests')); + $query->where($db->quoteName('status') . ' = 1 '); + $query->where($query->dateAdd($db->quote($now), $period, 'DAY') . ' > ' . $db->quoteName('requested_at')); + $db->setQuery($query); + + return (int) $db->loadResult(); + } +} diff --git a/administrator/components/com_privacy/privacy.php b/administrator/components/com_privacy/privacy.php new file mode 100644 index 0000000000000..303a4c35d5117 --- /dev/null +++ b/administrator/components/com_privacy/privacy.php @@ -0,0 +1,20 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +// Only super user can access here +if (!JFactory::getUser()->authorise('core.admin')) +{ + throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); +} + +$controller = JControllerLegacy::getInstance('Privacy'); +$controller->execute(JFactory::getApplication()->input->get('task')); +$controller->redirect(); diff --git a/administrator/components/com_privacy/privacy.xml b/administrator/components/com_privacy/privacy.xml new file mode 100644 index 0000000000000..6b6a8ba9c5f7f --- /dev/null +++ b/administrator/components/com_privacy/privacy.xml @@ -0,0 +1,40 @@ + + + com_privacy + Joomla! Project + May 2018 + (C) 2018 Open Source Matters, Inc. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + COM_PRIVACY_XML_DESCRIPTION + + controller.php + privacy.php + router.php + controllers + models + views + + + language/en-GB.com_privacy.ini + + + + config.xml + controller.php + privacy.php + controllers + helpers + models + tables + views + + + language/en-GB.com_privacy.ini + language/en-GB.com_privacy.sys.ini + + + + diff --git a/administrator/components/com_privacy/tables/consent.php b/administrator/components/com_privacy/tables/consent.php new file mode 100644 index 0000000000000..3ef204b8d1d9c --- /dev/null +++ b/administrator/components/com_privacy/tables/consent.php @@ -0,0 +1,65 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Table interface class for the #__privacy_consents table + * + * @property integer $id Item ID (primary key) + * @property integer $remind The status of the reminder request + * @property string $token Hashed token for the reminder request + * @property integer $user_id User ID (pseudo foreign key to the #__users table) if the request is associated to a user account + * + * @since 3.9.0 + */ +class PrivacyTableConsent extends JTable +{ + /** + * The class constructor. + * + * @param JDatabaseDriver $db JDatabaseDriver connector object. + * + * @since 3.9.0 + */ + public function __construct(JDatabaseDriver $db) + { + parent::__construct('#__privacy_consents', 'id', $db); + } + + /** + * Method to store a row in the database from the Table instance properties. + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return boolean True on success. + * + * @since 3.9.0 + */ + public function store($updateNulls = false) + { + $date = JFactory::getDate(); + + // Set default values for new records + if (!$this->id) + { + if (!$this->remind) + { + $this->remind = '0'; + } + + if (!$this->created) + { + $this->created = $date->toSql(); + } + } + + return parent::store($updateNulls); + } +} diff --git a/administrator/components/com_privacy/tables/request.php b/administrator/components/com_privacy/tables/request.php new file mode 100644 index 0000000000000..5e6804f579376 --- /dev/null +++ b/administrator/components/com_privacy/tables/request.php @@ -0,0 +1,68 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Table interface class for the #__privacy_requests table + * + * @property integer $id Item ID (primary key) + * @property string $email The email address of the individual requesting the data + * @property string $requested_at The time the request was created at + * @property integer $status The status of the information request + * @property string $request_type The type of information request + * @property string $confirm_token Hashed token for confirming the information request + * @property string $confirm_token_created_at The time the confirmation token was generated + * + * @since 3.9.0 + */ +class PrivacyTableRequest extends JTable +{ + /** + * The class constructor. + * + * @param JDatabaseDriver $db JDatabaseDriver connector object. + * + * @since 3.9.0 + */ + public function __construct(JDatabaseDriver $db) + { + parent::__construct('#__privacy_requests', 'id', $db); + } + + /** + * Method to store a row in the database from the Table instance properties. + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return boolean True on success. + * + * @since 3.9.0 + */ + public function store($updateNulls = false) + { + $date = JFactory::getDate(); + + // Set default values for new records + if (!$this->id) + { + if (!$this->status) + { + $this->status = '0'; + } + + if (!$this->requested_at) + { + $this->requested_at = $date->toSql(); + } + } + + return parent::store($updateNulls); + } +} diff --git a/administrator/components/com_privacy/views/capabilities/tmpl/default.php b/administrator/components/com_privacy/views/capabilities/tmpl/default.php new file mode 100644 index 0000000000000..110f372f2c95f --- /dev/null +++ b/administrator/components/com_privacy/views/capabilities/tmpl/default.php @@ -0,0 +1,54 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** @var PrivacyViewCapabilities $this */ + +?> +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + +
    +

    + +
    + capabilities)) : ?> +
    + +
    + + + 'slide-0')); ?> + + capabilities as $extension => $capabilities) : ?> + + +
    + +
    + +
      + +
    • + +
    + + + + + + + +
    diff --git a/administrator/components/com_privacy/views/capabilities/view.html.php b/administrator/components/com_privacy/views/capabilities/view.html.php new file mode 100644 index 0000000000000..ba275110981b0 --- /dev/null +++ b/administrator/components/com_privacy/views/capabilities/view.html.php @@ -0,0 +1,88 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Capabilities view class + * + * @since 3.9.0 + */ +class PrivacyViewCapabilities extends JViewLegacy +{ + /** + * The reported extension capabilities + * + * @var array + * @since 3.9.0 + */ + protected $capabilities; + + /** + * The HTML markup for the sidebar + * + * @var string + * @since 3.9.0 + */ + protected $sidebar; + + /** + * The state information + * + * @var JObject + * @since 3.9.0 + */ + protected $state; + + /** + * Execute and display a template script. + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return mixed A string if successful, otherwise an Error object. + * + * @see JViewLegacy::loadTemplate() + * @since 3.9.0 + * @throws Exception + */ + public function display($tpl = null) + { + // Initialise variables + $this->capabilities = $this->get('Capabilities'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_CAPABILITIES'), 'lock'); + + JToolbarHelper::preferences('com_privacy'); + + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_CAPABILITIES'); + } +} diff --git a/administrator/components/com_privacy/views/consents/tmpl/default.php b/administrator/components/com_privacy/views/consents/tmpl/default.php new file mode 100644 index 0000000000000..afcfd3d605e84 --- /dev/null +++ b/administrator/components/com_privacy/views/consents/tmpl/default.php @@ -0,0 +1,118 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** @var PrivacyViewConsent $this */ + +// Load the tooltip behavior. +JHtml::_('bootstrap.tooltip'); +JHtml::_('behavior.multiselect'); +JHtml::_('formbehavior.chosen', 'select'); + +$user = JFactory::getUser(); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$now = JFactory::getDate(); +$stateIcons = array(-1 => 'trash', 0 => 'archive', 1 => 'publish'); +$stateMsgs = array(-1 => JText::_('COM_PRIVACY_CONSENTS_STATE_INVALIDATED'), 0 => JText::_('COM_PRIVACY_CONSENTS_STATE_OBSOLETE'), 1 => JText::_('COM_PRIVACY_CONSENTS_STATE_VALID')); + +?> +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    + id); ?> + + + + username; ?> + + user_id; ?> + + subject); ?> + + body; ?> + + + created), null, $now); ?> + + + id; ?> +
    + + + + + +
    + diff --git a/administrator/components/com_privacy/views/consents/tmpl/default.xml b/administrator/components/com_privacy/views/consents/tmpl/default.xml new file mode 100644 index 0000000000000..b36c1cde72aea --- /dev/null +++ b/administrator/components/com_privacy/views/consents/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/administrator/components/com_privacy/views/consents/view.html.php b/administrator/components/com_privacy/views/consents/view.html.php new file mode 100644 index 0000000000000..18d60ce7e3e71 --- /dev/null +++ b/administrator/components/com_privacy/views/consents/view.html.php @@ -0,0 +1,142 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Consents view class + * + * @since 3.9.0 + */ +class PrivacyViewConsents extends JViewLegacy +{ + /** + * The active search tools filters + * + * @var array + * @since 3.9.0 + * @note Must be public to be accessed from the search tools layout + */ + public $activeFilters; + + /** + * Form instance containing the search tools filter form + * + * @var JForm + * @since 3.9.0 + * @note Must be public to be accessed from the search tools layout + */ + public $filterForm; + + /** + * The items to display + * + * @var array + * @since 3.9.0 + */ + protected $items; + + /** + * The pagination object + * + * @var JPagination + * @since 3.9.0 + */ + protected $pagination; + + /** + * The HTML markup for the sidebar + * + * @var string + * @since 3.9.0 + */ + protected $sidebar; + + /** + * The state information + * + * @var JObject + * @since 3.9.0 + */ + protected $state; + + /** + * Execute and display a template script. + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return mixed A string if successful, otherwise an Error object. + * + * @see JViewLegacy::loadTemplate() + * @since 3.9.0 + * @throws Exception + */ + public function display($tpl = null) + { + // Initialise variables + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_CONSENTS'), 'lock'); + + $bar = JToolbar::getInstance('toolbar'); + + // Add a button to invalidate a consent + $bar->appendButton( + 'Confirm', + 'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_CONFIRM_MSG', + 'trash', + 'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE', + 'consents.invalidate', + true + ); + + // If the filter is restricted to a specific subject, show the "Invalidate all" button + if ($this->state->get('filter.subject') != '') + { + $bar->appendButton( + 'Confirm', + 'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_ALL_CONFIRM_MSG', + 'cancel', + 'COM_PRIVACY_CONSENTS_TOOLBAR_INVALIDATE_ALL', + 'consents.invalidateAll', + false + ); + } + + JToolbarHelper::preferences('com_privacy'); + + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_CONSENTS'); + } +} diff --git a/administrator/components/com_privacy/views/dashboard/tmpl/default.php b/administrator/components/com_privacy/views/dashboard/tmpl/default.php new file mode 100644 index 0000000000000..8374566cea4e3 --- /dev/null +++ b/administrator/components/com_privacy/views/dashboard/tmpl/default.php @@ -0,0 +1,186 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; + +/** @var PrivacyViewDashboard $this */ + +// Include the component HTML helpers. +JHtml::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/html'); + +JHtml::_('bootstrap.tooltip'); + +$totalRequests = 0; +$activeRequests = 0; + +?> +sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + +
    +
    +
    + +
    + requestCounts)) : ?> +
    +
    +
    +
    +
    + requestCounts as $row) : ?> +
    + +
    status); ?>
    +
    count; ?>
    +
    + status, array(0, 1))) : ?> + count; ?> + + count; ?> + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + privacyPolicyInfo['published'] && $this->privacyPolicyInfo['articlePublished']) : ?> + + + + + privacyPolicyInfo['published'] && !$this->privacyPolicyInfo['articlePublished']) : ?> + + + + + + + + + + +
    +
    +
    + privacyPolicyInfo['editLink'] !== '') : ?> + + + privacyConsentPluginId); ?> + + +
    +
    +
    +
    + requestFormPublished['published'] && $this->requestFormPublished['exists']) : ?> + + + + + requestFormPublished['published'] && $this->requestFormPublished['exists']) : ?> + + + + + + + + + + +
    +
    +
    + requestFormPublished['link'] !== '') : ?> + requestFormPublished['link']; ?> + +
    +
    +
    +
    + numberOfUrgentRequests === 0) : ?> + + + + + + + + + + +
    +
    +
    + urgentRequestDays); ?> + numberOfUrgentRequests > 0) : ?> + + +
    +
    +
    +
    + sendMailEnabled) : ?> + + + + + + + + + + +
    +
    + sendMailEnabled) : ?> +
    + + +
    + +
    +
    +
    +
    +
    +
    +
    diff --git a/administrator/components/com_privacy/views/dashboard/tmpl/default.xml b/administrator/components/com_privacy/views/dashboard/tmpl/default.xml new file mode 100644 index 0000000000000..f9a24bf36cad4 --- /dev/null +++ b/administrator/components/com_privacy/views/dashboard/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/administrator/components/com_privacy/views/dashboard/view.html.php b/administrator/components/com_privacy/views/dashboard/view.html.php new file mode 100644 index 0000000000000..4562de63060c0 --- /dev/null +++ b/administrator/components/com_privacy/views/dashboard/view.html.php @@ -0,0 +1,134 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; + +/** + * Dashboard view class + * + * @since 3.9.0 + */ +class PrivacyViewDashboard extends JViewLegacy +{ + /** + * Number of urgent requests based on the component configuration + * + * @var integer + * @since 3.9.0 + */ + protected $numberOfUrgentRequests; + + /** + * Information about whether a privacy policy is published + * + * @var array + * @since 3.9.0 + */ + protected $privacyPolicyInfo; + + /** + * The request counts + * + * @var array + * @since 3.9.0 + */ + protected $requestCounts; + + /** + * Information about whether a menu item for the request form is published + * + * @var array + * @since 3.9.0 + */ + protected $requestFormPublished; + + /** + * Flag indicating the site supports sending email + * + * @var boolean + * @since 3.9.0 + */ + protected $sendMailEnabled; + + /** + * The HTML markup for the sidebar + * + * @var string + * @since 3.9.0 + */ + protected $sidebar; + + /** + * Id of the system privacy consent plugin + * + * @var integer + * @since 3.9.2 + */ + protected $privacyConsentPluginId; + + /** + * Execute and display a template script. + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return mixed A string if successful, otherwise an Error object. + * + * @see JViewLegacy::loadTemplate() + * @since 3.9.0 + * @throws Exception + */ + public function display($tpl = null) + { + // Initialise variables + $this->privacyConsentPluginId = PrivacyHelper::getPrivacyConsentPluginId(); + $this->privacyPolicyInfo = $this->get('PrivacyPolicyInfo'); + $this->requestCounts = $this->get('RequestCounts'); + $this->requestFormPublished = $this->get('RequestFormPublished'); + $this->sendMailEnabled = (bool) Factory::getConfig()->get('mailonline', 1); + + /** @var PrivacyModelRequests $requestsModel */ + $requestsModel = $this->getModel('requests'); + + $this->numberOfUrgentRequests = $requestsModel->getNumberUrgentRequests(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->urgentRequestDays = (int) ComponentHelper::getParams('com_privacy')->get('notify', 14); + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JToolbarHelper::title(Text::_('COM_PRIVACY_VIEW_DASHBOARD'), 'lock'); + + JToolbarHelper::preferences('com_privacy'); + + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_DASHBOARD'); + } +} diff --git a/administrator/components/com_privacy/views/export/view.xml.php b/administrator/components/com_privacy/views/export/view.xml.php new file mode 100644 index 0000000000000..9add4208dff25 --- /dev/null +++ b/administrator/components/com_privacy/views/export/view.xml.php @@ -0,0 +1,55 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JLoader::register('PrivacyHelper', JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/privacy.php'); + +/** + * Export view class + * + * @since 3.9.0 + * + * @property-read \Joomla\CMS\Document\XmlDocument $document + */ +class PrivacyViewExport extends JViewLegacy +{ + /** + * Execute and display a template script. + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return mixed A string if successful, otherwise an Error object. + * + * @see JViewLegacy::loadTemplate() + * @since 3.9.0 + * @throws Exception + */ + public function display($tpl = null) + { + /** @var PrivacyModelExport $model */ + $model = $this->getModel(); + + $exportData = $model->collectDataForExportRequest(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $requestId = $model->getState($model->getName() . '.request_id'); + + // This document should always be downloaded + $this->document->setDownload(true); + $this->document->setName('export-request-' . $requestId); + + echo PrivacyHelper::renderDataAsXml($exportData); + } +} diff --git a/administrator/components/com_privacy/views/request/tmpl/default.php b/administrator/components/com_privacy/views/request/tmpl/default.php new file mode 100644 index 0000000000000..4466b37f5d4e7 --- /dev/null +++ b/administrator/components/com_privacy/views/request/tmpl/default.php @@ -0,0 +1,90 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** @var PrivacyViewRequest $this */ + +// Include the component HTML helpers. +JHtml::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/html'); + +JHtml::_('behavior.formvalidator'); +JHtml::_('behavior.keepalive'); + +$js = <<< JS +Joomla.submitbutton = function(task) { + if (task === 'request.cancel' || document.formvalidator.isValid(document.getElementById('item-form'))) { + Joomla.submitform(task, document.getElementById('item-form')); + } +}; +JS; + +JFactory::getDocument()->addScriptDeclaration($js); +?> + +
    +
    +
    +

    +
    +
    :
    +
    item->email; ?>
    + +
    :
    +
    item->status); ?>
    + +
    :
    +
    item->request_type); ?>
    + +
    :
    +
    item->requested_at, JText::_('DATE_FORMAT_LC6')); ?>
    +
    +
    +
    +

    + actionlogs)) : ?> +
    + +
    + + + + + + + + + actionlogs as $i => $item) : ?> + + + + + + + +
    + + + + + +
    + + + log_date, JText::_('DATE_FORMAT_LC6')); ?> + + name; ?> +
    + +
    +
    + + + +
    diff --git a/administrator/components/com_privacy/views/request/tmpl/edit.php b/administrator/components/com_privacy/views/request/tmpl/edit.php new file mode 100644 index 0000000000000..64e0da012681a --- /dev/null +++ b/administrator/components/com_privacy/views/request/tmpl/edit.php @@ -0,0 +1,44 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** @var PrivacyViewRequest $this */ + +JHtml::_('behavior.formvalidator'); +JHtml::_('behavior.keepalive'); +JHtml::_('formbehavior.chosen', 'select'); + +$js = <<< JS +Joomla.submitbutton = function(task) { + if (task === 'request.cancel' || document.formvalidator.isValid(document.getElementById('item-form'))) { + Joomla.submitform(task, document.getElementById('item-form')); + } +}; +JS; + +JFactory::getDocument()->addScriptDeclaration($js); +?> + +
    +
    +
    +
    +
    + form->renderField('email'); ?> + form->renderField('status'); ?> + form->renderField('request_type'); ?> +
    +
    +
    + + + +
    +
    diff --git a/administrator/components/com_privacy/views/request/view.html.php b/administrator/components/com_privacy/views/request/view.html.php new file mode 100644 index 0000000000000..7605cb40723cf --- /dev/null +++ b/administrator/components/com_privacy/views/request/view.html.php @@ -0,0 +1,176 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Request view class + * + * @since 3.9.0 + */ +class PrivacyViewRequest extends JViewLegacy +{ + /** + * The action logs for the item + * + * @var array + * @since 3.9.0 + */ + protected $actionlogs; + + /** + * The form object + * + * @var JForm + * @since 3.9.0 + */ + protected $form; + + /** + * The item record + * + * @var JObject + * @since 3.9.0 + */ + protected $item; + + /** + * The state information + * + * @var JObject + * @since 3.9.0 + */ + protected $state; + + /** + * Execute and display a template script. + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return mixed A string if successful, otherwise an Error object. + * + * @see JViewLegacy::loadTemplate() + * @since 3.9.0 + * @throws Exception + */ + public function display($tpl = null) + { + // Initialise variables. + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Variables only required for the default layout + if ($this->getLayout() === 'default') + { + /** @var ActionlogsModelActionlogs $logsModel */ + $logsModel = $this->getModel('actionlogs'); + + $this->actionlogs = $logsModel->getLogsForItem('com_privacy.request', $this->item->id); + + // Load the com_actionlogs language strings for use in the layout + $lang = JFactory::getLanguage(); + $lang->load('com_actionlogs', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_actionlogs', JPATH_ADMINISTRATOR . '/components/com_actionlogs', null, false, true); + } + + // Variables only required for the edit layout + if ($this->getLayout() === 'edit') + { + $this->form = $this->get('Form'); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JFactory::getApplication('administrator')->set('hidemainmenu', true); + + // Set the title and toolbar based on the layout + if ($this->getLayout() === 'edit') + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_REQUEST_ADD_REQUEST'), 'lock'); + + JToolbarHelper::apply('request.save'); + JToolbarHelper::cancel('request.cancel'); + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_REQUEST_EDIT'); + } + else + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_REQUEST_SHOW_REQUEST'), 'lock'); + + $bar = JToolbar::getInstance('toolbar'); + + // Add transition and action buttons based on item status + switch ($this->item->status) + { + case '0': + $bar->appendButton('Standard', 'cancel-circle', 'COM_PRIVACY_TOOLBAR_INVALIDATE', 'request.invalidate', false); + + break; + + case '1': + $return = '&return=' . base64_encode('index.php?option=com_privacy&view=request&id=' . (int) $this->item->id); + + $bar->appendButton('Standard', 'apply', 'COM_PRIVACY_TOOLBAR_COMPLETE', 'request.complete', false); + $bar->appendButton('Standard', 'cancel-circle', 'COM_PRIVACY_TOOLBAR_INVALIDATE', 'request.invalidate', false); + + if ($this->item->request_type === 'export') + { + JToolbarHelper::link( + JRoute::_('index.php?option=com_privacy&task=request.export&format=xml&id=' . (int) $this->item->id . $return), + 'COM_PRIVACY_ACTION_EXPORT_DATA', + 'download' + ); + + if (JFactory::getConfig()->get('mailonline', 1)) + { + JToolbarHelper::link( + JRoute::_( + 'index.php?option=com_privacy&task=request.emailexport&id=' . (int) $this->item->id . $return + . '&' . JSession::getFormToken() . '=1' + ), + 'COM_PRIVACY_ACTION_EMAIL_EXPORT_DATA', + 'mail' + ); + } + } + + if ($this->item->request_type === 'remove') + { + $bar->appendButton('Standard', 'delete', 'COM_PRIVACY_ACTION_DELETE_DATA', 'request.remove', false); + } + + break; + + // Item is in a "locked" state and cannot transition + default: + break; + } + + JToolbarHelper::cancel('request.cancel', 'JTOOLBAR_CLOSE'); + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_REQUEST'); + } + } +} diff --git a/administrator/components/com_privacy/views/requests/tmpl/default.php b/administrator/components/com_privacy/views/requests/tmpl/default.php new file mode 100644 index 0000000000000..2a62aa4ac05d6 --- /dev/null +++ b/administrator/components/com_privacy/views/requests/tmpl/default.php @@ -0,0 +1,127 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** @var PrivacyViewRequests $this */ + +// Include the component HTML helpers. +JHtml::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/html'); + +// Load the tooltip behavior. +JHtml::_('bootstrap.tooltip'); +JHtml::_('behavior.multiselect'); +JHtml::_('formbehavior.chosen', 'select'); + +$user = JFactory::getUser(); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$now = JFactory::getDate(); + +$urgentRequestDate= clone $now; +$urgentRequestDate->sub(new DateInterval('P' . $this->urgentRequestAge . 'D')); +?> +
    + sidebar)) : ?> +
    + sidebar; ?> +
    +
    + +
    + + $this)); ?> +
    + items)) : ?> +
    + +
    + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + requested_at); + ?> + + + + + + + + + + +
    + + + + + + + + + + + +
    + pagination->getListFooter(); ?> +
    +
    + status == 1 && $item->request_type === 'export') : ?> + + sendMailEnabled) : ?> + + + + status == 1 && $item->request_type === 'remove') : ?> + + +
    +
    + status); ?> + + status == 1 && $urgentRequestDate >= $itemRequestedAt) : ?> + + + + escape($item->email)); ?> + + + request_type); ?> + + + + + + id; ?> +
    + + + + + +
    + diff --git a/administrator/components/com_privacy/views/requests/tmpl/default.xml b/administrator/components/com_privacy/views/requests/tmpl/default.xml new file mode 100644 index 0000000000000..4c624d279a747 --- /dev/null +++ b/administrator/components/com_privacy/views/requests/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/administrator/components/com_privacy/views/requests/view.html.php b/administrator/components/com_privacy/views/requests/view.html.php new file mode 100644 index 0000000000000..dcb3924b05382 --- /dev/null +++ b/administrator/components/com_privacy/views/requests/view.html.php @@ -0,0 +1,141 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Requests view class + * + * @since 3.9.0 + */ +class PrivacyViewRequests extends JViewLegacy +{ + /** + * The active search tools filters + * + * @var array + * @since 3.9.0 + * @note Must be public to be accessed from the search tools layout + */ + public $activeFilters; + + /** + * Form instance containing the search tools filter form + * + * @var JForm + * @since 3.9.0 + * @note Must be public to be accessed from the search tools layout + */ + public $filterForm; + + /** + * The items to display + * + * @var array + * @since 3.9.0 + */ + protected $items; + + /** + * The pagination object + * + * @var JPagination + * @since 3.9.0 + */ + protected $pagination; + + /** + * Flag indicating the site supports sending email + * + * @var boolean + * @since 3.9.0 + */ + protected $sendMailEnabled; + + /** + * The HTML markup for the sidebar + * + * @var string + * @since 3.9.0 + */ + protected $sidebar; + + /** + * The state information + * + * @var JObject + * @since 3.9.0 + */ + protected $state; + + /** + * The age of urgent requests + * + * @var integer + * @since 3.9.0 + */ + protected $urgentRequestAge; + + /** + * Execute and display a template script. + * + * @param string $tpl The name of the template file to parse; automatically searches through the template paths. + * + * @return mixed A string if successful, otherwise an Error object. + * + * @see JViewLegacy::loadTemplate() + * @since 3.9.0 + * @throws Exception + */ + public function display($tpl = null) + { + // Initialise variables + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->urgentRequestAge = (int) JComponentHelper::getParams('com_privacy')->get('notify', 14); + $this->sendMailEnabled = (bool) JFactory::getConfig()->get('mailonline', 1); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + $this->sidebar = JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.9.0 + */ + protected function addToolbar() + { + JToolbarHelper::title(JText::_('COM_PRIVACY_VIEW_REQUESTS'), 'lock'); + + // Requests can only be created if mail sending is enabled + if (JFactory::getConfig()->get('mailonline', 1)) + { + JToolbarHelper::addNew('request.add'); + } + + JToolbarHelper::preferences('com_privacy'); + JToolbarHelper::help('JHELP_COMPONENTS_PRIVACY_REQUESTS'); + + } +} diff --git a/administrator/components/com_redirect/config.xml b/administrator/components/com_redirect/config.xml index c2a41bd41e17b..9c87ece04da68 100644 --- a/administrator/components/com_redirect/config.xml +++ b/administrator/components/com_redirect/config.xml @@ -3,7 +3,7 @@
    + > JYES + + + + +
    + > * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_redirect/controllers/link.php b/administrator/components/com_redirect/controllers/link.php index 491e5d0dfd2ed..7c4f1b55ce153 100644 --- a/administrator/components/com_redirect/controllers/link.php +++ b/administrator/components/com_redirect/controllers/link.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_redirect/controllers/links.php b/administrator/components/com_redirect/controllers/links.php index 9994730988b0f..82dfb9ce97516 100644 --- a/administrator/components/com_redirect/controllers/links.php +++ b/administrator/components/com_redirect/controllers/links.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -28,7 +28,7 @@ class RedirectControllerLinks extends JControllerAdmin public function activate() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $ids = $this->input->get('cid', array(), 'array'); $newUrl = $this->input->getString('new_url'); @@ -69,7 +69,7 @@ public function activate() public function duplicateUrls() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $ids = $this->input->get('cid', array(), 'array'); $newUrl = $this->input->getString('new_url'); @@ -123,6 +123,9 @@ public function getModel($name = 'Link', $prefix = 'RedirectModel', $config = ar */ public function batch() { + // Check for request forgeries. + $this->checkToken(); + $batch_urls_request = $this->input->post->get('batch_urls', array(), 'array'); $batch_urls_lines = array_map('trim', explode("\n", $batch_urls_request[0])); @@ -132,7 +135,19 @@ public function batch() { if (!empty($batch_urls_line)) { - $batch_urls[] = array_map('trim', explode('|', $batch_urls_line)); + $params = JComponentHelper::getParams('com_redirect'); + $separator = $params->get('separator', '|'); + + // Basic check to make sure the correct separator is being used + if (!\Joomla\String\StringHelper::strpos($batch_urls_line, $separator)) + { + $this->setMessage(JText::sprintf('COM_REDIRECT_NO_SEPARATOR_FOUND', $separator), 'error'); + $this->setRedirect('index.php?option=com_redirect&view=links'); + + return false; + } + + $batch_urls[] = array_map('trim', explode($separator, $batch_urls_line)); } } @@ -162,6 +177,9 @@ public function batch() */ public function purge() { + // Check for request forgeries. + $this->checkToken(); + $model = $this->getModel('Links'); if ($model->purge()) diff --git a/administrator/components/com_redirect/helpers/html/redirect.php b/administrator/components/com_redirect/helpers/html/redirect.php index 4eaf07184b1b7..6e7d89ba15f46 100644 --- a/administrator/components/com_redirect/helpers/html/redirect.php +++ b/administrator/components/com_redirect/helpers/html/redirect.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_redirect/helpers/redirect.php b/administrator/components/com_redirect/helpers/redirect.php index 93779082edeb6..5679b5bcb3366 100644 --- a/administrator/components/com_redirect/helpers/redirect.php +++ b/administrator/components/com_redirect/helpers/redirect.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -81,39 +81,10 @@ public static function publishedOptions() return $options; } - /** - * Determines if the plugin for Redirect to work is enabled. - * - * @return boolean - * - * @since 1.6 - */ - public static function isEnabled() - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('enabled')) - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) - ->where($db->quoteName('element') . ' = ' . $db->quote('redirect')); - $db->setQuery($query); - - try - { - $result = (boolean) $db->loadResult(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - return $result; - } - /** * Gets the redirect system plugin extension id. * - * @return int The redirect system plugin extension id. + * @return integer The redirect system plugin extension id. * * @since 3.6.0 */ diff --git a/administrator/components/com_redirect/layouts/toolbar/batch.php b/administrator/components/com_redirect/layouts/toolbar/batch.php index 01029f20c9776..8c8766c124683 100644 --- a/administrator/components/com_redirect/layouts/toolbar/batch.php +++ b/administrator/components/com_redirect/layouts/toolbar/batch.php @@ -3,18 +3,18 @@ * @package Joomla.Administrator * @subpackage Layout * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2016 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JHtml::_('behavior.core'); $title = $displayData['title']; ?> - diff --git a/administrator/components/com_redirect/models/fields/redirect.php b/administrator/components/com_redirect/models/fields/redirect.php index 2daf53e9ef786..7bd83413d6a5b 100644 --- a/administrator/components/com_redirect/models/fields/redirect.php +++ b/administrator/components/com_redirect/models/fields/redirect.php @@ -3,11 +3,11 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2014 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -defined('JPATH_BASE') or die; +defined('_JEXEC') or die; JFormHelper::loadFieldClass('list'); diff --git a/administrator/components/com_redirect/models/forms/filter_links.xml b/administrator/components/com_redirect/models/forms/filter_links.xml index a54890a890bb1..4d1bd3dfc51a6 100644 --- a/administrator/components/com_redirect/models/forms/filter_links.xml +++ b/administrator/components/com_redirect/models/forms/filter_links.xml @@ -4,13 +4,14 @@ diff --git a/administrator/components/com_redirect/models/forms/link.xml b/administrator/components/com_redirect/models/forms/link.xml index c7fd6b46a5585..981b0bfd1b14f 100644 --- a/administrator/components/com_redirect/models/forms/link.xml +++ b/administrator/components/com_redirect/models/forms/link.xml @@ -3,7 +3,7 @@
    @@ -62,7 +61,7 @@ label="COM_REDIRECT_FIELD_REFERRER_LABEL" id="referer" size="50" - readonly="true" + readonly="true" />
    @@ -103,6 +102,7 @@ label="COM_REDIRECT_FIELD_REDIRECT_STATUS_CODE_LABEL" description="COM_REDIRECT_FIELD_REDIRECT_STATUS_CODE_DESC" default="301" + validate="options" class="input-xlarge" />
    diff --git a/administrator/components/com_redirect/models/link.php b/administrator/components/com_redirect/models/link.php index fed0ea96e7050..870e28a5a7fcd 100644 --- a/administrator/components/com_redirect/models/link.php +++ b/administrator/components/com_redirect/models/link.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -40,26 +40,7 @@ protected function canDelete($record) return false; } - $user = JFactory::getUser(); - - return $user->authorise('core.delete', 'com_redirect'); - } - - /** - * Method to test whether a record can have its state edited. - * - * @param object $record A record object. - * - * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. - * - * @since 1.6 - */ - protected function canEditState($record) - { - $user = JFactory::getUser(); - - // Check the component since there are no categories or other assets. - return $user->authorise('core.edit.state', 'com_redirect'); + return parent::canDelete($record); } /** @@ -245,6 +226,7 @@ public function duplicateUrls(&$pks, $url, $comment = null) { $query->set($db->quoteName('comment') . ' = ' . $db->quote($comment)); } + $db->setQuery($query); try diff --git a/administrator/components/com_redirect/models/links.php b/administrator/components/com_redirect/models/links.php index 69cd7126852b0..0fd562aec57fd 100644 --- a/administrator/components/com_redirect/models/links.php +++ b/administrator/components/com_redirect/models/links.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -191,15 +191,18 @@ protected function getListQuery() /** * Add the entered URLs into the database * - * @param array $batch_urls Array of URLs to enter into the database + * @param array $batchUrls Array of URLs to enter into the database * - * @return bool + * @return boolean */ - public function batchProcess($batch_urls) + public function batchProcess($batchUrls) { $db = JFactory::getDbo(); $query = $db->getQuery(true); + $params = JComponentHelper::getParams('com_redirect'); + $state = (int) $params->get('defaultImportState', 0); + $columns = array( $db->quoteName('old_url'), $db->quoteName('new_url'), @@ -212,17 +215,9 @@ public function batchProcess($batch_urls) $query->columns($columns); - foreach ($batch_urls as $batch_url) + foreach ($batchUrls as $batch_url) { - // Source URLs need to have the correct URL format to work properly - if (strpos($batch_url[0], JUri::root()) === false) - { - $old_url = JUri::root() . $batch_url[0]; - } - else - { - $old_url = $batch_url[0]; - } + $old_url = $batch_url[0]; // Destination URL can also be an external URL if (!empty($batch_url[1])) @@ -236,7 +231,7 @@ public function batchProcess($batch_urls) $query->insert($db->quoteName('#__redirect_links'), false) ->values( - $db->quote($old_url) . ', ' . $db->quote($new_url) . ' ,' . $db->quote('') . ', ' . $db->quote('') . ', 0, 0, ' . + $db->quote($old_url) . ', ' . $db->quote($new_url) . ' ,' . $db->quote('') . ', ' . $db->quote('') . ', 0, ' . $state . ', ' . $db->quote(JFactory::getDate()->toSql()) ); } diff --git a/administrator/components/com_redirect/redirect.php b/administrator/components/com_redirect/redirect.php index da376b562f0d2..2e128364f140f 100644 --- a/administrator/components/com_redirect/redirect.php +++ b/administrator/components/com_redirect/redirect.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_redirect/redirect.xml b/administrator/components/com_redirect/redirect.xml index b2ebc17f771d2..e8e7b81e9472c 100644 --- a/administrator/components/com_redirect/redirect.xml +++ b/administrator/components/com_redirect/redirect.xml @@ -3,7 +3,7 @@ com_redirect Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_redirect/tables/link.php b/administrator/components/com_redirect/tables/link.php index 0f684de30b852..8030e62321312 100644 --- a/administrator/components/com_redirect/tables/link.php +++ b/administrator/components/com_redirect/tables/link.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -47,6 +47,7 @@ public function check() return false; } + // Check for NOT NULL. if (empty($this->referer)) { @@ -84,17 +85,20 @@ public function check() // Check for existing name $query = $db->getQuery(true) ->select($db->quoteName('id')) + ->select($db->quoteName('old_url')) ->from('#__redirect_links') ->where($db->quoteName('old_url') . ' = ' . $db->quote($this->old_url)); $db->setQuery($query); + $urls = $db->loadAssocList(); - $xid = (int) $db->loadResult(); - - if ($xid && $xid != (int) $this->id) + foreach ($urls as $url) { - $this->setError(JText::_('COM_REDIRECT_ERROR_DUPLICATE_OLD_URL')); + if ($url['old_url'] === $this->old_url && (int) $url['id'] != (int) $this->id) + { + $this->setError(JText::_('COM_REDIRECT_ERROR_DUPLICATE_OLD_URL')); - return false; + return false; + } } return true; diff --git a/administrator/components/com_redirect/views/link/tmpl/edit.php b/administrator/components/com_redirect/views/link/tmpl/edit.php index 45cbb3e4520ef..7922472598057 100644 --- a/administrator/components/com_redirect/views/link/tmpl/edit.php +++ b/administrator/components/com_redirect/views/link/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_redirect/views/link/view.html.php b/administrator/components/com_redirect/views/link/view.html.php index 4795ea95bcb15..15915631a8f61 100644 --- a/administrator/components/com_redirect/views/link/view.html.php +++ b/administrator/components/com_redirect/views/link/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_redirect/views/links/tmpl/default.php b/administrator/components/com_redirect/views/links/tmpl/default.php index 9e05ec4a69c21..12ee2f99e4d0d 100644 --- a/administrator/components/com_redirect/views/links/tmpl/default.php +++ b/administrator/components/com_redirect/views/links/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -23,6 +23,32 @@
    $this)); ?> + redirectPluginId) : ?> + redirectPluginId . '&tmpl=component&layout=modal'); ?> + redirectPluginId . 'Modal', + array( + 'url' => $link, + 'title' => JText::_('COM_REDIRECT_EDIT_PLUGIN_SETTINGS'), + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'closeButton' => false, + 'backdrop' => 'static', + 'keyboard' => false, + 'footer' => '' + . '' + . '' + ) + ); ?> + + items)) : ?>
    diff --git a/administrator/components/com_redirect/views/links/tmpl/default.xml b/administrator/components/com_redirect/views/links/tmpl/default.xml new file mode 100644 index 0000000000000..2158f363299cc --- /dev/null +++ b/administrator/components/com_redirect/views/links/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/administrator/components/com_redirect/views/links/tmpl/default_addform.php b/administrator/components/com_redirect/views/links/tmpl/default_addform.php index ca88ff47562d3..98e6e03368fdc 100644 --- a/administrator/components/com_redirect/views/links/tmpl/default_addform.php +++ b/administrator/components/com_redirect/views/links/tmpl/default_addform.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_redirect/views/links/tmpl/default_batch_body.php b/administrator/components/com_redirect/views/links/tmpl/default_batch_body.php index 6c7c5c71fae1a..cab816dc6bd60 100644 --- a/administrator/components/com_redirect/views/links/tmpl/default_batch_body.php +++ b/administrator/components/com_redirect/views/links/tmpl/default_batch_body.php @@ -3,17 +3,19 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; $published = $this->state->get('filter.published'); +$params = $this->params; +$separator = $params->get('separator', '|'); ?>
    -

    +

    diff --git a/administrator/components/com_redirect/views/links/tmpl/default_batch_footer.php b/administrator/components/com_redirect/views/links/tmpl/default_batch_footer.php index 430158e097cd5..312c34cda4cc5 100644 --- a/administrator/components/com_redirect/views/links/tmpl/default_batch_footer.php +++ b/administrator/components/com_redirect/views/links/tmpl/default_batch_footer.php @@ -3,15 +3,15 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - + + diff --git a/administrator/components/com_redirect/views/links/view.html.php b/administrator/components/com_redirect/views/links/view.html.php index c2c7683f99e85..242bb51d77dc4 100644 --- a/administrator/components/com_redirect/views/links/view.html.php +++ b/administrator/components/com_redirect/views/links/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_redirect * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -20,12 +20,18 @@ class RedirectViewLinks extends JViewLegacy protected $collect_urls_enabled; + protected $redirectPluginId = 0; + protected $items; protected $pagination; protected $state; + public $filterForm; + + public $activeFilters; + /** * Display the view. * @@ -34,18 +40,21 @@ class RedirectViewLinks extends JViewLegacy * @return mixed False if unsuccessful, otherwise void. * * @since 1.6 + * + * @throws Exception */ public function display($tpl = null) { // Set variables $app = JFactory::getApplication(); - $this->enabled = RedirectHelper::isEnabled(); + $this->enabled = JPluginHelper::isEnabled('system', 'redirect'); $this->collect_urls_enabled = RedirectHelper::collectUrlsEnabled(); $this->items = $this->get('Items'); $this->pagination = $this->get('Pagination'); $this->state = $this->get('State'); $this->filterForm = $this->get('FilterForm'); $this->activeFilters = $this->get('ActiveFilters'); + $this->params = JComponentHelper::getParams('com_redirect'); // Check for errors. if (count($errors = $this->get('Errors'))) @@ -56,22 +65,42 @@ public function display($tpl = null) // Show messages about the enabled plugin and if the plugin should collect URLs if ($this->enabled && $this->collect_urls_enabled) { - $app->enqueueMessage(JText::_('COM_REDIRECT_PLUGIN_ENABLED') . ' ' . JText::_('COM_REDIRECT_COLLECT_URLS_ENABLED'), 'notice'); - } - elseif ($this->enabled && !$this->collect_urls_enabled) - { - $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . RedirectHelper::getRedirectPluginId()); - $app->enqueueMessage(JText::_('COM_REDIRECT_PLUGIN_ENABLED') . JText::sprintf('COM_REDIRECT_COLLECT_URLS_DISABLED', $link), 'notice'); + $app->enqueueMessage(JText::sprintf('COM_REDIRECT_COLLECT_URLS_ENABLED', JText::_('COM_REDIRECT_PLUGIN_ENABLED')), 'notice'); } else { - $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . RedirectHelper::getRedirectPluginId()); - $app->enqueueMessage(JText::sprintf('COM_REDIRECT_PLUGIN_DISABLED', $link), 'error'); + $this->redirectPluginId = RedirectHelper::getRedirectPluginId(); + + $link = JHtml::_( + 'link', + '#plugin' . $this->redirectPluginId . 'Modal', + JText::_('COM_REDIRECT_SYSTEM_PLUGIN'), + 'class="alert-link" data-toggle="modal" id="title-' . $this->redirectPluginId . '"' + ); + + // To be removed in Joomla 4 + if (JFactory::getApplication()->getTemplate() === 'hathor') + { + $link = JHtml::_( + 'link', + JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . RedirectHelper::getRedirectPluginId()), + JText::_('COM_REDIRECT_SYSTEM_PLUGIN') + ); + } + + if ($this->enabled && !$this->collect_urls_enabled) + { + $app->enqueueMessage(JText::sprintf('COM_REDIRECT_COLLECT_MODAL_URLS_DISABLED', JText::_('COM_REDIRECT_PLUGIN_ENABLED'), $link), 'notice'); + } + else + { + $app->enqueueMessage(JText::sprintf('COM_REDIRECT_PLUGIN_MODAL_DISABLED', $link), 'error'); + } } $this->addToolbar(); - parent::display($tpl); + return parent::display($tpl); } /** @@ -107,7 +136,7 @@ protected function addToolbar() JToolbarHelper::unpublish('links.unpublish', 'JTOOLBAR_DISABLE', true); } - if ($state->get('filter.state') != -1 ) + if ($state->get('filter.state') != -1) { JToolbarHelper::divider(); @@ -129,6 +158,8 @@ protected function addToolbar() $title = JText::_('JTOOLBAR_BULK_IMPORT'); + JHtml::_('bootstrap.modal', 'collapseModal'); + // Instantiate a new JLayoutFile instance and render the batch button $layout = new JLayoutFile('toolbar.batch'); @@ -155,6 +186,5 @@ protected function addToolbar() } JToolbarHelper::help('JHELP_COMPONENTS_REDIRECT_MANAGER'); - } } diff --git a/administrator/components/com_search/controller.php b/administrator/components/com_search/controller.php index 66e567bf20662..fea58b6543715 100644 --- a/administrator/components/com_search/controller.php +++ b/administrator/components/com_search/controller.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_search * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_search/controllers/searches.php b/administrator/components/com_search/controllers/searches.php index bd590dfb3ada7..4e6e093e6b3d7 100644 --- a/administrator/components/com_search/controllers/searches.php +++ b/administrator/components/com_search/controllers/searches.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_search * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -24,7 +24,7 @@ class SearchControllerSearches extends JControllerLegacy public function reset() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $model = $this->getModel('Searches'); @@ -44,7 +44,7 @@ public function reset() public function toggleResults() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); if ($this->getModel('Searches')->getState('show_results', 1, 'int') === 0) { diff --git a/administrator/components/com_search/helpers/search.php b/administrator/components/com_search/helpers/search.php index 46359aeb6b401..0014f0b37613e 100644 --- a/administrator/components/com_search/helpers/search.php +++ b/administrator/components/com_search/helpers/search.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_search * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -150,19 +150,19 @@ public static function limitSearchWord(&$searchword) /** * Logs a search term. * - * @param string $search_term The term being searched. + * @param string $searchTerm The term being searched. * * @return void * * @since 1.5 - * @deprecated 4.0 Use JSearchHelper::logSearch() instead. + * @deprecated 4.0 Use \Joomla\CMS\Helper\SearchHelper::logSearch() instead. */ - public static function logSearch($search_term) + public static function logSearch($searchTerm) { try { JLog::add( - sprintf('%s() is deprecated. Use JSearchHelper::logSearch() instead.', __METHOD__), + sprintf('%s() is deprecated. Use \Joomla\CMS\Helper\SearchHelper::logSearch() instead.', __METHOD__), JLog::WARNING, 'deprecated' ); @@ -172,7 +172,7 @@ public static function logSearch($search_term) // Informational log only } - JSearchHelper::logSearch($search_term, 'com_search'); + \Joomla\CMS\Helper\SearchHelper::logSearch($searchTerm, 'com_search'); } /** @@ -287,8 +287,9 @@ public static function _smartSubstr($text, $searchword) $lsearchword = StringHelper::strtolower(self::remove_accents($searchword)); $wordfound = false; $pos = 0; + $length = $length > $textlen ? $textlen : $length; - while ($wordfound === false && $pos < $textlen) + while ($wordfound === false && $pos + $length < $textlen) { if (($wordpos = @StringHelper::strpos($ltext, ' ', $pos + $length)) !== false) { @@ -310,11 +311,48 @@ public static function _smartSubstr($text, $searchword) if ($wordfound !== false) { - return (($pos > 0) ? '... ' : '') . StringHelper::substr($text, $pos, $chunk_size) . ' ...'; + // Check if original text is different length than searched text (changed by function self::remove_accents) + // Displayed text only, adjust $chunk_size + if ($pos === 0) + { + $iOriLen = StringHelper::strlen(StringHelper::substr($text, 0, $pos + $chunk_size)); + $iModLen = StringHelper::strlen(self::remove_accents(StringHelper::substr($text, 0, $pos + $chunk_size))); + + $chunk_size += $iOriLen - $iModLen; + } + else + { + $iOriSkippedLen = StringHelper::strlen(StringHelper::substr($text, 0, $pos)); + $iModSkippedLen = StringHelper::strlen(self::remove_accents(StringHelper::substr($text, 0, $pos))); + + // Adjust starting position $pos + if ($iOriSkippedLen !== $iModSkippedLen) + { + $pos += $iOriSkippedLen - $iModSkippedLen; + } + + $iOriReturnLen = StringHelper::strlen(StringHelper::substr($text, $pos, $chunk_size)); + $iModReturnLen = StringHelper::strlen(self::remove_accents(StringHelper::substr($text, $pos, $chunk_size))); + + if ($iOriReturnLen !== $iModReturnLen) + { + $chunk_size += $iOriReturnLen - $iModReturnLen; + } + } + + $sPre = $pos > 0 ? '... ' : ''; + $sPost = ($pos + $chunk_size) >= StringHelper::strlen($text) ? '' : ' ...'; + + return $sPre . StringHelper::substr($text, $pos, $chunk_size) . $sPost; } else { - if (($wordpos = @StringHelper::strpos($text, ' ', $length)) !== false) + if (($mbtextlen = StringHelper::strlen($text)) < $length) + { + $length = $mbtextlen; + } + + if (($wordpos = StringHelper::strpos($text, ' ', $length)) !== false) { return StringHelper::substr($text, 0, $wordpos) . ' ...'; } diff --git a/administrator/components/com_search/helpers/site.php b/administrator/components/com_search/helpers/site.php index ee651450edf6e..344996f9c88fb 100644 --- a/administrator/components/com_search/helpers/site.php +++ b/administrator/components/com_search/helpers/site.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_search * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_search/models/forms/filter_searches.xml b/administrator/components/com_search/models/forms/filter_searches.xml index c22da9f46fab1..a43dc7f4aec2f 100644 --- a/administrator/components/com_search/models/forms/filter_searches.xml +++ b/administrator/components/com_search/models/forms/filter_searches.xml @@ -4,6 +4,7 @@ diff --git a/administrator/components/com_search/models/searches.php b/administrator/components/com_search/models/searches.php index 1ed48ec25f3ae..6af0ee1ed7a68 100644 --- a/administrator/components/com_search/models/searches.php +++ b/administrator/components/com_search/models/searches.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_search * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -162,7 +162,7 @@ public function getItems() } /** - * Method to reset the seach log table. + * Method to reset the search log table. * * @return boolean * diff --git a/administrator/components/com_search/search.php b/administrator/components/com_search/search.php index 9bdbd0c930af5..5b3147566ef92 100644 --- a/administrator/components/com_search/search.php +++ b/administrator/components/com_search/search.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_search * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_search/search.xml b/administrator/components/com_search/search.xml index 1dc7a24799a71..a2918cf0e5e7b 100644 --- a/administrator/components/com_search/search.xml +++ b/administrator/components/com_search/search.xml @@ -3,7 +3,7 @@ com_search Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_search/views/searches/tmpl/default.php b/administrator/components/com_search/views/searches/tmpl/default.php index bf267d93be3ec..6e2891691688f 100644 --- a/administrator/components/com_search/views/searches/tmpl/default.php +++ b/administrator/components/com_search/views/searches/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_search * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_search/views/searches/tmpl/default.xml b/administrator/components/com_search/views/searches/tmpl/default.xml new file mode 100644 index 0000000000000..ff4f089e29582 --- /dev/null +++ b/administrator/components/com_search/views/searches/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/administrator/components/com_search/views/searches/view.html.php b/administrator/components/com_search/views/searches/view.html.php index ac5d5157f51dc..4a549c3f0f5af 100644 --- a/administrator/components/com_search/views/searches/view.html.php +++ b/administrator/components/com_search/views/searches/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_search * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_tags/config.xml b/administrator/components/com_tags/config.xml index 3c846ae774c6e..30623cfa75aa3 100644 --- a/administrator/components/com_tags/config.xml +++ b/administrator/components/com_tags/config.xml @@ -29,7 +29,7 @@ - JHIDE - JHIDE - JHIDE - - - @@ -94,9 +95,9 @@ - JGLOBAL_ORDER_DESCENDING - - @@ -131,9 +133,9 @@ - JSHOW - - JSHOW - +
    - +
    - COM_TAGS_ANY - - COM_TAGS_INCLUDE - + - - JALL - -
    + +
    - @@ -256,8 +259,8 @@ - JGLOBAL_ORDER_DESCENDING - JHIDE - JSHOW - + - - - + JHIDE - JSHOW - - JSHOW - +
    - +
    - -
    - -
    + * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_tags/controllers/tag.php b/administrator/components/com_tags/controllers/tag.php index 1f1d0818ed4b6..922fcd8c9a263 100644 --- a/administrator/components/com_tags/controllers/tag.php +++ b/administrator/components/com_tags/controllers/tag.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -29,7 +29,7 @@ protected function allowAdd($data = array()) { $user = JFactory::getUser(); - return ($user->authorise('core.create', 'com_tags')); + return $user->authorise('core.create', 'com_tags'); } /** @@ -59,7 +59,7 @@ protected function allowEdit($data = array(), $key = 'id') */ public function batch($model = null) { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); // Set the model $model = $this->getModel('Tag'); diff --git a/administrator/components/com_tags/controllers/tags.php b/administrator/components/com_tags/controllers/tags.php index cd8bff2848096..5c77f498e2bd0 100644 --- a/administrator/components/com_tags/controllers/tags.php +++ b/administrator/components/com_tags/controllers/tags.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -41,7 +41,7 @@ public function getModel($name = 'Tag', $prefix = 'TagsModel', $config = array(' */ public function rebuild() { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $this->setRedirect(JRoute::_('index.php?option=com_tags&view=tags', false)); diff --git a/administrator/components/com_tags/helpers/tags.php b/administrator/components/com_tags/helpers/tags.php index 8e1b0902a41dd..da50e3de8bfcb 100644 --- a/administrator/components/com_tags/helpers/tags.php +++ b/administrator/components/com_tags/helpers/tags.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_tags/models/forms/filter_tags.xml b/administrator/components/com_tags/models/forms/filter_tags.xml index 63d08d839488a..58641d6aff8f1 100644 --- a/administrator/components/com_tags/models/forms/filter_tags.xml +++ b/administrator/components/com_tags/models/forms/filter_tags.xml @@ -4,6 +4,7 @@ diff --git a/administrator/components/com_tags/models/forms/tag.xml b/administrator/components/com_tags/models/forms/tag.xml index da0baab5703ab..028e184f591dd 100644 --- a/administrator/components/com_tags/models/forms/tag.xml +++ b/administrator/components/com_tags/models/forms/tag.xml @@ -2,7 +2,7 @@ JALL - - - - - + + + +
    diff --git a/administrator/components/com_tags/models/tag.php b/administrator/components/com_tags/models/tag.php index 85e653e8aa8d3..d9cb423cd5ff0 100644 --- a/administrator/components/com_tags/models/tag.php +++ b/administrator/components/com_tags/models/tag.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -53,29 +53,12 @@ class TagsModelTag extends JModelAdmin */ protected function canDelete($record) { - if (!empty($record->id)) + if (empty($record->id) || $record->published != -2) { - if ($record->published != -2) - { - return false; - } - - return parent::canDelete($record); + return false; } - } - /** - * Method to test whether a record can have its state changed. - * - * @param object $record A record object. - * - * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. - * - * @since 3.1 - */ - protected function canEditState($record) - { - return parent::canEditState($record); + return parent::canDelete($record); } /** @@ -150,20 +133,9 @@ public function getItem($pk = null) $registry = new Registry($result->urls); $result->urls = $registry->toArray(); - // Convert the created and modified dates to local user time for display in the form. + // Convert the modified date to local user time for display in the form. $tz = new DateTimeZone(JFactory::getApplication()->get('offset')); - if ((int) $result->created_time) - { - $date = new JDate($result->created_time); - $date->setTimezone($tz); - $result->created_time = $date->toSql(true); - } - else - { - $result->created_time = null; - } - if ((int) $result->modified_time) { $date = new JDate($result->modified_time); @@ -289,9 +261,21 @@ public function save($data) // Alter the title for save as copy if ($input->get('task') == 'save2copy') { - list($title, $alias) = $this->generateNewTitle($data['parent_id'], $data['alias'], $data['title']); - $data['title'] = $title; - $data['alias'] = $alias; + $origTable = $this->getTable(); + $origTable->load($input->getInt('id')); + + if ($data['title'] == $origTable->title) + { + list($title, $alias) = $this->generateNewTitle($data['parent_id'], $data['alias'], $data['title']); + $data['title'] = $title; + $data['alias'] = $alias; + } + elseif ($data['alias'] == $origTable->alias) + { + $data['alias'] = ''; + } + + $data['published'] = 0; } // Bind the data. @@ -392,19 +376,19 @@ public function rebuild() * First we save the new order values in the lft values of the changed ids. * Then we invoke the table rebuild to implement the new ordering. * - * @param array $idArray An array of primary key ids. - * @param integer $lft_array The lft value + * @param array $idArray An array of primary key ids. + * @param integer $lftArray The lft value * * @return boolean False on failure or error, True otherwise * * @since 3.1 */ - public function saveorder($idArray = null, $lft_array = null) + public function saveorder($idArray = null, $lftArray = null) { // Get an instance of the table object. $table = $this->getTable(); - if (!$table->saveorder($idArray, $lft_array)) + if (!$table->saveorder($idArray, $lftArray)) { $this->setError($table->getError()); @@ -420,20 +404,20 @@ public function saveorder($idArray = null, $lft_array = null) /** * Method to change the title & alias. * - * @param integer $parent_id The id of the parent. - * @param string $alias The alias. - * @param string $title The title. + * @param integer $parentId The id of the parent. + * @param string $alias The alias. + * @param string $title The title. * * @return array Contains the modified title and alias. * * @since 3.1 */ - protected function generateNewTitle($parent_id, $alias, $title) + protected function generateNewTitle($parentId, $alias, $title) { // Alter the title & alias $table = $this->getTable(); - while ($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) + while ($table->load(array('alias' => $alias, 'parent_id' => $parentId))) { $title = ($table->title != $title) ? $title : StringHelper::increment($title); $alias = StringHelper::increment($alias, 'dash'); diff --git a/administrator/components/com_tags/models/tags.php b/administrator/components/com_tags/models/tags.php index 3cea0fba897bc..c621eae28d40a 100644 --- a/administrator/components/com_tags/models/tags.php +++ b/administrator/components/com_tags/models/tags.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -141,7 +141,7 @@ protected function getListQuery() $query->select( $this->getState( 'list.select', - 'a.id, a.title, a.alias, a.note, a.published, a.access' . + 'a.id, a.title, a.alias, a.note, a.published, a.access, a.description' . ', a.checked_out, a.checked_out_time, a.created_user_id' . ', a.path, a.parent_id, a.level, a.lft, a.rgt' . ', a.language' @@ -241,7 +241,7 @@ protected function getListQuery() * * @return mixed Boolean false if there is an error, otherwise the count of records checked in. * - * @since 12.2 + * @since 3.0.1 */ public function checkin($pks = array()) { @@ -328,7 +328,7 @@ public function getTable($type = 'Tag', $prefix = 'TagsTable', $config = array() * * @return mixed An array of data items on success, false on failure. * - * @since 12.2 + * @since 3.0.1 */ public function getItems() { diff --git a/administrator/components/com_tags/tables/tag.php b/administrator/components/com_tags/tables/tag.php index d0ca966d2bd08..6cb05235a0690 100644 --- a/administrator/components/com_tags/tables/tag.php +++ b/administrator/components/com_tags/tables/tag.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -141,6 +141,7 @@ public function check() $bad_characters = array("\"", '<', '>'); $this->metadesc = StringHelper::str_ireplace($bad_characters, '', $this->metadesc); } + // Not Null sanity check $date = JFactory::getDate(); diff --git a/administrator/components/com_tags/tags.php b/administrator/components/com_tags/tags.php index 56823e1d6a4c6..75d97abdcd6a5 100644 --- a/administrator/components/com_tags/tags.php +++ b/administrator/components/com_tags/tags.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_tags/tags.xml b/administrator/components/com_tags/tags.xml index 07b2c92243335..c16ae6d99e51e 100644 --- a/administrator/components/com_tags/tags.xml +++ b/administrator/components/com_tags/tags.xml @@ -3,7 +3,7 @@ com_tags Joomla! Project December 2013 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2013 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_tags/views/tag/tmpl/edit.php b/administrator/components/com_tags/views/tag/tmpl/edit.php index 1aa5087eaec80..da3f7eb241fa9 100644 --- a/administrator/components/com_tags/views/tag/tmpl/edit.php +++ b/administrator/components/com_tags/views/tag/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_tags/views/tag/tmpl/edit_metadata.php b/administrator/components/com_tags/views/tag/tmpl/edit_metadata.php index 42f305b88ee48..f38c619f06ba3 100644 --- a/administrator/components/com_tags/views/tag/tmpl/edit_metadata.php +++ b/administrator/components/com_tags/views/tag/tmpl/edit_metadata.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_tags/views/tag/tmpl/edit_options.php b/administrator/components/com_tags/views/tag/tmpl/edit_options.php index 85b595a38e411..904cc6c2330f9 100644 --- a/administrator/components/com_tags/views/tag/tmpl/edit_options.php +++ b/administrator/components/com_tags/views/tag/tmpl/edit_options.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_tags/views/tag/view.html.php b/administrator/components/com_tags/views/tag/view.html.php index d0a13d63b430d..cea53b4e3b853 100644 --- a/administrator/components/com_tags/views/tag/view.html.php +++ b/administrator/components/com_tags/views/tag/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -102,7 +102,7 @@ protected function addToolbar() { JToolbarHelper::apply('tag.apply'); JToolbarHelper::save('tag.save'); - + if ($canDo->get('core.create')) { JToolbarHelper::save2new('tag.save2new'); diff --git a/administrator/components/com_tags/views/tags/tmpl/default.php b/administrator/components/com_tags/views/tags/tmpl/default.php index 723b3e679c584..1ade08a25cc05 100644 --- a/administrator/components/com_tags/views/tags/tmpl/default.php +++ b/administrator/components/com_tags/views/tags/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_tags/views/tags/tmpl/default.xml b/administrator/components/com_tags/views/tags/tmpl/default.xml new file mode 100644 index 0000000000000..7cbc9e3693fb9 --- /dev/null +++ b/administrator/components/com_tags/views/tags/tmpl/default.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/administrator/components/com_tags/views/tags/tmpl/default_batch_body.php b/administrator/components/com_tags/views/tags/tmpl/default_batch_body.php index 6da4127511ee5..532afb2e564f9 100644 --- a/administrator/components/com_tags/views/tags/tmpl/default_batch_body.php +++ b/administrator/components/com_tags/views/tags/tmpl/default_batch_body.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; diff --git a/administrator/components/com_tags/views/tags/tmpl/default_batch_footer.php b/administrator/components/com_tags/views/tags/tmpl/default_batch_footer.php index fe6ad8be32017..89e84d8726b72 100644 --- a/administrator/components/com_tags/views/tags/tmpl/default_batch_footer.php +++ b/administrator/components/com_tags/views/tags/tmpl/default_batch_footer.php @@ -3,15 +3,15 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; ?> - + + \ No newline at end of file + diff --git a/administrator/components/com_tags/views/tags/view.html.php b/administrator/components/com_tags/views/tags/view.html.php index 14d98fdd1852f..7c32a579a368d 100644 --- a/administrator/components/com_tags/views/tags/view.html.php +++ b/administrator/components/com_tags/views/tags/view.html.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_tags * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2013 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -69,6 +69,7 @@ public function display($tpl = null) { $this->addToolbar(); } + parent::display($tpl); } diff --git a/administrator/components/com_templates/config.xml b/administrator/components/com_templates/config.xml index 3b7c468b0830f..9309e86e5d373 100644 --- a/administrator/components/com_templates/config.xml +++ b/administrator/components/com_templates/config.xml @@ -19,7 +19,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_templates/controllers/style.php b/administrator/components/com_templates/controllers/style.php index 155b89fcd06df..b92b1073f67c2 100644 --- a/administrator/components/com_templates/controllers/style.php +++ b/administrator/components/com_templates/controllers/style.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -36,16 +36,12 @@ class TemplatesControllerStyle extends JControllerForm */ public function save($key = null, $urlVar = null) { - if (!JSession::checkToken()) - { - JFactory::getApplication()->redirect('index.php', JText::_('JINVALID_TOKEN')); - } + $this->checkToken(); $document = JFactory::getDocument(); - if ($document->getType() == 'json') + if ($document->getType() === 'json') { - $app = JFactory::getApplication(); $lang = JFactory::getLanguage(); $model = $this->getModel(); @@ -55,7 +51,7 @@ public function save($key = null, $urlVar = null) $context = $this->option . '.edit.' . $this->context; $task = $this->getTask(); - $item = $model->getItem($app->getTemplate('template')->id); + $item = $model->getItem($app->getTemplate(true)->id); // Setting received params $item->set('params', $data); @@ -68,7 +64,6 @@ public function save($key = null, $urlVar = null) // Access check. if (!$this->allowSave($data, $key)) { - $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); return false; @@ -153,7 +148,6 @@ public function save($key = null, $urlVar = null) $this->postSaveHook($model, $validData); return true; - } else { diff --git a/administrator/components/com_templates/controllers/styles.php b/administrator/components/com_templates/controllers/styles.php index 93e3c9ca57319..6889e24640a39 100644 --- a/administrator/components/com_templates/controllers/styles.php +++ b/administrator/components/com_templates/controllers/styles.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -26,7 +26,7 @@ class TemplatesControllerStyles extends JControllerAdmin public function duplicate() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $pks = $this->input->post->get('cid', array(), 'array'); @@ -77,7 +77,7 @@ public function getModel($name = 'Style', $prefix = 'TemplatesModel', $config = public function setDefault() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $pks = $this->input->post->get('cid', array(), 'array'); @@ -114,7 +114,7 @@ public function setDefault() public function unsetDefault() { // Check for request forgeries - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken('request'); $pks = $this->input->get->get('cid', array(), 'array'); $pks = ArrayHelper::toInteger($pks); diff --git a/administrator/components/com_templates/controllers/template.php b/administrator/components/com_templates/controllers/template.php index 6f707a34c816f..1672a0e046dd8 100644 --- a/administrator/components/com_templates/controllers/template.php +++ b/administrator/components/com_templates/controllers/template.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -11,6 +11,8 @@ JLoader::register('InstallerModelInstall', JPATH_ADMINISTRATOR . '/components/com_installer/models/install.php'); +use Joomla\CMS\Filter\InputFilter; + /** * Template style controller class. * @@ -57,7 +59,7 @@ public function close() { $app = JFactory::getApplication(); $file = base64_encode('home'); - $id = $app->input->get('id'); + $id = (int) $app->input->get('id', 0, 'int'); $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; $this->setRedirect(JRoute::_($url, false)); } @@ -72,14 +74,22 @@ public function close() public function copy() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $this->input->set('installtype', 'folder'); - $newName = $this->input->get('new_name'); - $newNameRaw = $this->input->get('new_name', null, 'string'); - $templateID = $this->input->getInt('id', 0); - $file = $this->input->get('file'); + $newName = (string) $this->input->get('new_name', null, 'cmd'); + $newNameRaw = (string) $this->input->get('new_name', null, 'string'); + $templateID = (int) $this->input->get('id', 0, 'int'); + $file = (string) $this->input->get('file', '', 'cmd'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } $this->setRedirect('index.php?option=com_templates&view=template&id=' . $templateID . '&file=' . $file); $model = $this->getModel('Template', 'TemplatesModel'); @@ -171,7 +181,7 @@ public function getModel($name = 'Template', $prefix = 'TemplatesModel', $config } /** - * Method to check if you can add a new record. + * Method to check if the user can modify template files * * @return boolean * @@ -179,19 +189,7 @@ public function getModel($name = 'Template', $prefix = 'TemplatesModel', $config */ protected function allowEdit() { - return JFactory::getUser()->authorise('core.edit', 'com_templates'); - } - - /** - * Method to check if you can save a new or existing record. - * - * @return boolean - * - * @since 3.2 - */ - protected function allowSave() - { - return $this->allowEdit(); + return JFactory::getUser()->authorise('core.admin'); } /** @@ -204,17 +202,17 @@ protected function allowSave() public function save() { // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $data = $this->input->post->get('jform', array(), 'array'); $task = $this->getTask(); $model = $this->getModel(); - $fileName = $app->input->get('file'); + $fileName = (string) $app->input->get('file', '', 'cmd'); $explodeArray = explode(':', base64_decode($fileName)); // Access check. - if (!$this->allowSave()) + if (!$this->allowEdit()) { $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); @@ -295,21 +293,19 @@ public function save() // Redirect the user based on the chosen task. switch ($task) { - case 'apply': - - // Redirect back to the edit screen. - $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName; - $this->setRedirect(JRoute::_($url, false)); - break; + case 'apply': + // Redirect back to the edit screen. + $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName; + $this->setRedirect(JRoute::_($url, false)); + break; - default: - - // Redirect to the list screen. - $file = base64_encode('home'); - $id = $app->input->get('id'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - break; + default: + // Redirect to the list screen. + $file = base64_encode('home'); + $id = (int) $app->input->get('id', 0, 'int'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(JRoute::_($url, false)); + break; } } @@ -322,11 +318,23 @@ public function save() */ public function overrides() { + // Check for request forgeries. + $this->checkToken('get'); + $app = JFactory::getApplication(); $model = $this->getModel(); - $file = $app->input->get('file'); - $override = base64_decode($app->input->get('folder')); - $id = $app->input->get('id'); + $file = (string) $app->input->get('file', '', 'cmd'); + $override = (string) InputFilter::getInstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('folder', '', 'base64')), 'path'); + $id = (int) $app->input->get('id', 0, 'int'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + if ($model->createOverride($override)) { @@ -347,10 +355,21 @@ public function overrides() */ public function less() { + // Check for request forgeries + $this->checkToken(); + $app = JFactory::getApplication(); $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } if ($model->compileLess($file)) { @@ -375,14 +394,22 @@ public function less() public function delete() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } - if (base64_decode(urldecode($file)) == 'index.php') + if (base64_decode(urldecode($file)) == '/index.php') { $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_INDEX_DELETE'), 'warning'); $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; @@ -414,15 +441,23 @@ public function delete() public function createFile() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - $name = $app->input->get('name'); - $location = base64_decode($app->input->get('address')); - $type = $app->input->get('type'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $name = (string) $app->input->get('name', '', 'cmd'); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); + $type = (string) $app->input->get('type', '', 'cmd'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } if ($type == 'null') { @@ -461,14 +496,22 @@ public function createFile() public function uploadFile() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); $upload = $app->input->files->get('files'); - $location = base64_decode($app->input->get('address')); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } if ($return = $model->uploadFile($upload, $location)) { @@ -495,14 +538,22 @@ public function uploadFile() public function createFolder() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); $name = $app->input->get('name'); - $location = base64_decode($app->input->get('address')); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $name)) { @@ -534,13 +585,21 @@ public function createFolder() public function deleteFolder() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - $location = base64_decode($app->input->get('address')); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } if (empty($location)) { @@ -578,15 +637,23 @@ public function deleteFolder() public function renameFile() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); $newName = $app->input->get('new_name'); - if (base64_decode(urldecode($file)) == 'index.php') + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + if (base64_decode(urldecode($file)) == '/index.php') { $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_RENAME_INDEX'), 'warning'); $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; @@ -621,15 +688,26 @@ public function renameFile() */ public function cropImage() { + // Check for request forgeries + $this->checkToken(); + $app = JFactory::getApplication(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); $x = $app->input->get('x'); $y = $app->input->get('y'); $w = $app->input->get('w'); $h = $app->input->get('h'); $model = $this->getModel(); + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + if (empty($w) && empty($h) && empty($x) && empty($y)) { $app->enqueueMessage(JText::_('COM_TEMPLATES_CROP_AREA_ERROR'), 'error'); @@ -659,13 +737,24 @@ public function cropImage() */ public function resizeImage() { + // Check for request forgeries + $this->checkToken(); + $app = JFactory::getApplication(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); $width = $app->input->get('width'); $height = $app->input->get('height'); $model = $this->getModel(); + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + if ($model->resizeImage($file, $width, $height)) { $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_RESIZE_SUCCESS')); @@ -690,15 +779,23 @@ public function resizeImage() public function copyFile() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); $newName = $app->input->get('new_name'); - $location = base64_decode($app->input->get('address')); + $location = (string) InputFilter::getinstance(array(), array(), 1, 1)->clean(base64_decode($app->input->get('address', '', 'base64')), 'path'); $model = $this->getModel(); + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + if (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) { $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); @@ -728,13 +825,21 @@ public function copyFile() public function extractArchive() { // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); + $this->checkToken(); $app = JFactory::getApplication(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); + $id = (int) $app->input->get('id', 0, 'int'); + $file = (string) $app->input->get('file', '', 'cmd'); $model = $this->getModel(); + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + if ($model->extractArchive($file)) { $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_SUCCESS')); diff --git a/administrator/components/com_templates/helpers/html/templates.php b/administrator/components/com_templates/helpers/html/templates.php index 4387fa1d7e62e..a10b803fd4eaa 100644 --- a/administrator/components/com_templates/helpers/html/templates.php +++ b/administrator/components/com_templates/helpers/html/templates.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -44,8 +44,8 @@ public static function thumb($template, $clientId = 0) if (file_exists($preview)) { - $html = '' . $html . ''; + $html = ''; } } @@ -76,7 +76,7 @@ public static function thumbModal($template, $clientId = 0) if (file_exists($preview)) { $preview = $baseUrl . '/templates/' . $template . '/template_preview.png'; - $footer = ''; $html .= JHtml::_( diff --git a/administrator/components/com_templates/helpers/template.php b/administrator/components/com_templates/helpers/template.php index c24d832be1a0c..d8174736a9a04 100644 --- a/administrator/components/com_templates/helpers/template.php +++ b/administrator/components/com_templates/helpers/template.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_templates/helpers/templates.php b/administrator/components/com_templates/helpers/templates.php index 2b3b5dc70d851..562bfddefbe48 100644 --- a/administrator/components/com_templates/helpers/templates.php +++ b/administrator/components/com_templates/helpers/templates.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_templates/models/fields/templatelocation.php b/administrator/components/com_templates/models/fields/templatelocation.php index 8e9777bc02c25..a339901b59ccf 100644 --- a/administrator/components/com_templates/models/fields/templatelocation.php +++ b/administrator/components/com_templates/models/fields/templatelocation.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -14,7 +14,7 @@ JFormHelper::loadFieldClass('list'); /** - * Template Location field. + * Template Location field. * * @since 3.5 */ diff --git a/administrator/components/com_templates/models/fields/templatename.php b/administrator/components/com_templates/models/fields/templatename.php index 3b640995b7079..c845062fe2f2d 100644 --- a/administrator/components/com_templates/models/fields/templatename.php +++ b/administrator/components/com_templates/models/fields/templatename.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2015 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_templates/models/forms/filter_styles.xml b/administrator/components/com_templates/models/forms/filter_styles.xml index fd4636873c500..c8d87294de493 100644 --- a/administrator/components/com_templates/models/forms/filter_styles.xml +++ b/administrator/components/com_templates/models/forms/filter_styles.xml @@ -14,6 +14,7 @@ - + diff --git a/administrator/components/com_templates/models/forms/filter_templates.xml b/administrator/components/com_templates/models/forms/filter_templates.xml index 7a4c190b0afac..239f4e8a2ce1d 100644 --- a/administrator/components/com_templates/models/forms/filter_templates.xml +++ b/administrator/components/com_templates/models/forms/filter_templates.xml @@ -14,6 +14,7 @@ diff --git a/administrator/components/com_templates/models/forms/style.xml b/administrator/components/com_templates/models/forms/style.xml index 90ed931d373f9..897efc18dcd74 100644 --- a/administrator/components/com_templates/models/forms/style.xml +++ b/administrator/components/com_templates/models/forms/style.xml @@ -3,7 +3,7 @@
    * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -120,7 +120,7 @@ public function delete(&$pks) // You should not delete a default style if ($table->home != '0') { - JError::raiseWarning(SOME_ERROR_NUMBER, JText::_('COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE')); + JError::raiseWarning(500, JText::_('COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE')); return false; } @@ -224,15 +224,15 @@ public function duplicate(&$pks) /** * Method to change the title. * - * @param integer $category_id The id of the category. - * @param string $alias The alias. - * @param string $title The title. + * @param integer $categoryId The id of the category. + * @param string $alias The alias. + * @param string $title The title. * * @return string New title. * * @since 1.7.1 */ - protected function generateNewTitle($category_id, $alias, $title) + protected function generateNewTitle($categoryId, $alias, $title) { // Alter the title $table = $this->getTable(); @@ -248,7 +248,7 @@ protected function generateNewTitle($category_id, $alias, $title) /** * Method to get the record form. * - * @param array $data An optional array of data for the form to interogate. + * @param array $data An optional array of data for the form to interrogate. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return JForm A JForm object on success, false on failure @@ -271,7 +271,7 @@ public function getForm($data = array(), $loadData = true) } // Add the default fields directory - $baseFolder = ($clientId) ? JPATH_ADMINISTRATOR : JPATH_SITE; + $baseFolder = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; JForm::addFieldPath($baseFolder . '/templates/' . $template . '/field'); // These variables are used to add data from the plugin XML files. @@ -382,7 +382,7 @@ public function getItem($pk = null) * @param array $config Configuration array for model. Optional. * * @return JTable A database object - */ + */ public function getTable($type = 'Style', $prefix = 'TemplatesTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); @@ -432,7 +432,7 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') // Disable home field if it is default style if ((is_array($data) && array_key_exists('home', $data) && $data['home'] == '1') - || ((is_object($data) && isset($data->home) && $data->home == '1'))) + || (is_object($data) && isset($data->home) && $data->home == '1')) { $form->setFieldAttribute('home', 'readonly', 'true'); } @@ -451,8 +451,8 @@ protected function preprocessForm(JForm $form, $data, $group = 'content') $helpKey = trim((string) $help[0]['key']); $helpURL = trim((string) $help[0]['url']); - $this->helpKey = $helpKey ? $helpKey : $this->helpKey; - $this->helpURL = $helpURL ? $helpURL : $this->helpURL; + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; } // Trigger the default form events. @@ -626,20 +626,20 @@ public function setHome($id = 0) } // Reset the home fields for the client_id. - $db->setQuery( - 'UPDATE #__template_styles' . - ' SET home = \'0\'' . - ' WHERE client_id = ' . (int) $style->client_id . - ' AND home = \'1\'' - ); + $query = $db->getQuery(true) + ->update('#__template_styles') + ->set('home = ' . $db->q('0')) + ->where('client_id = ' . (int) $style->client_id) + ->where('home = ' . $db->q('1')); + $db->setQuery($query); $db->execute(); // Set the new home style. - $db->setQuery( - 'UPDATE #__template_styles' . - ' SET home = \'1\'' . - ' WHERE id = ' . (int) $id - ); + $query = $db->getQuery(true) + ->update('#__template_styles') + ->set('home = ' . $db->q('1')) + ->where('id = ' . (int) $id); + $db->setQuery($query); $db->execute(); // Clean the cache. @@ -669,11 +669,11 @@ public function unsetHome($id = 0) } // Lookup the client_id. - $db->setQuery( - 'SELECT client_id, home' . - ' FROM #__template_styles' . - ' WHERE id = ' . (int) $id - ); + $query = $db->getQuery(true) + ->select('client_id, home') + ->from('#__template_styles') + ->where('id = ' . (int) $id); + $db->setQuery($query); $style = $db->loadObject(); if (!is_numeric($style->client_id)) @@ -686,11 +686,11 @@ public function unsetHome($id = 0) } // Set the new home style. - $db->setQuery( - 'UPDATE #__template_styles' . - ' SET home = \'0\'' . - ' WHERE id = ' . (int) $id - ); + $query = $db->getQuery(true) + ->update('#__template_styles') + ->set('home = ' . $db->q('0')) + ->where('id = ' . (int) $id); + $db->setQuery($query); $db->execute(); // Clean the cache. @@ -714,14 +714,14 @@ public function getHelp() /** * Custom clean cache method * - * @param string $group The cache group - * @param integer $client_id The ID of the client + * @param string $group The cache group + * @param integer $clientId The ID of the client * * @return void * * @since 1.6 */ - protected function cleanCache($group = null, $client_id = 0) + protected function cleanCache($group = null, $clientId = 0) { parent::cleanCache('com_templates'); parent::cleanCache('_system'); diff --git a/administrator/components/com_templates/models/styles.php b/administrator/components/com_templates/models/styles.php index c0451f579429b..5644d5575aeea 100644 --- a/administrator/components/com_templates/models/styles.php +++ b/administrator/components/com_templates/models/styles.php @@ -3,12 +3,14 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\String\StringHelper; + /** * Methods supporting a list of template style records. * @@ -172,7 +174,8 @@ protected function getListQuery() $db->quoteName('a.home') . ' IN (' . $menuItemLanguageSubQuery . ') OR ' . // Custom template styles override (only if assigned to the selected menu item). '(' . $db->quoteName('a.home') . ' = ' . $db->quote(0) . ' AND ' . $menuItemId . ' IN (' . $templateStylesMenuItemsSubQuery . '))' . - ')'); + ')' + ); } } @@ -185,7 +188,7 @@ protected function getListQuery() } else { - $search = $db->quote('%' . strtolower($search) . '%'); + $search = $db->quote('%' . StringHelper::strtolower($search) . '%'); $query->where('(' . ' LOWER(a.template) LIKE ' . $search . ' OR LOWER(a.title) LIKE ' . $search . ')'); } } diff --git a/administrator/components/com_templates/models/template.php b/administrator/components/com_templates/models/template.php index d66789aa1d4e1..5b2adf8d4e97b 100644 --- a/administrator/components/com_templates/models/template.php +++ b/administrator/components/com_templates/models/template.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -330,8 +330,8 @@ protected function fixTemplateName() foreach ($files as $file) { - $newFile = str_replace($oldName, $newName, $file); - $result = JFile::move($file, $newFile) && $result; + $newFile = '/' . str_replace($oldName, $newName, basename($file)); + $result = JFile::move($file, dirname($file) . $newFile) && $result; } // Edit XML file @@ -441,6 +441,7 @@ public function &getSource() catch (Exception $e) { $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_FOUND'), 'error'); + return; } @@ -563,6 +564,7 @@ public function getOverridesList() $client = JApplicationHelper::getClientInfo($template->client_id); $componentPath = JPath::clean($client->path . '/components/'); $modulePath = JPath::clean($client->path . '/modules/'); + $pluginPath = JPath::clean(JPATH_ROOT . '/plugins/'); $layoutPath = JPath::clean(JPATH_ROOT . '/layouts/'); $components = JFolder::folders($componentPath); @@ -596,6 +598,18 @@ public function getOverridesList() } } + foreach (JFolder::folders($pluginPath) as $pluginGroup) + { + foreach (JFolder::folders($pluginPath . '/' . $pluginGroup) as $plugin) + { + if (file_exists($pluginPath . '/' . $pluginGroup . '/' . $plugin . '/tmpl/')) + { + $pluginLayoutPath = JPath::clean($pluginPath . '/' . $pluginGroup . '/'); + $result['plugins'][$pluginGroup][] = $this->getOverridesFolder($plugin, $pluginLayoutPath); + } + } + } + $modules = JFolder::folders($modulePath); foreach ($modules as $module) @@ -681,6 +695,12 @@ public function createOverride($override) $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/' . $url); } } + elseif (stripos($override, JPath::clean(JPATH_ROOT . '/plugins/')) === 0) + { + $size = count($explodeArray); + $layoutPath = JPath::clean('plg_' . $explodeArray[$size - 2] . '_' . $explodeArray[$size - 1]); + $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/' . $layoutPath); + } else { $layoutPath = implode('/', array_slice($explodeArray, -2)); @@ -706,6 +726,10 @@ public function createOverride($override) { $return = $this->createTemplateOverride(JPath::clean($override . '/tmpl'), $htmlPath); } + elseif (stripos($override, JPath::clean(JPATH_ROOT . '/plugins/')) === 0) + { + $return = $this->createTemplateOverride(JPath::clean($override . '/tmpl'), $htmlPath); + } else { $return = $this->createTemplateOverride($override, $htmlPath); @@ -804,7 +828,7 @@ public function compileLess($input) $inFile = urldecode(base64_decode($input)); $explodeArray = explode('/', $inFile); $fileName = end($explodeArray); - $outFile = reset(explode('.', $fileName)); + $outFile = current(explode('.', $fileName)); $less = new JLess; $less->setFormatter(new JLessFormatterJoomla); @@ -885,6 +909,7 @@ public function createFile($name, $type, $location) return false; } + // Check if the format is allowed and will be showed in the backend $check = $this->checkFormat($type); @@ -1134,12 +1159,26 @@ public function cropImage($file, $w, $h, $x, $y) $client = JApplicationHelper::getClientInfo($template->client_id); $relPath = base64_decode($file); $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $relPath); - $JImage = new JImage($path); try { - $image = $JImage->crop($w, $h, $x, $y, true); - $image->toFile($path); + $image = new \JImage($path); + $properties = $image->getImageFileProperties($path); + + switch ($properties->mime) + { + case 'image/png': + $imageType = \IMAGETYPE_PNG; + break; + case 'image/gif': + $imageType = \IMAGETYPE_GIF; + break; + default: + $imageType = \IMAGETYPE_JPEG; + } + + $image->crop($w, $h, $x, $y, false); + $image->toFile($path, $imageType); return true; } @@ -1170,12 +1209,25 @@ public function resizeImage($file, $width, $height) $relPath = base64_decode($file); $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $relPath); - $JImage = new JImage($path); - try { - $image = $JImage->resize($width, $height, true, 1); - $image->toFile($path); + $image = new \JImage($path); + $properties = $image->getImageFileProperties($path); + + switch ($properties->mime) + { + case 'image/png': + $imageType = \IMAGETYPE_PNG; + break; + case 'image/gif': + $imageType = \IMAGETYPE_GIF; + break; + default: + $imageType = \IMAGETYPE_JPEG; + } + + $image->resize($width, $height, false, \JImage::SCALE_FILL); + $image->toFile($path, $imageType); return true; } @@ -1423,14 +1475,14 @@ public function extractArchive($file) } /** - * Check if the extension is allowed and will be shown in the template manager - * - * @param string $ext The extension to check if it is allowed - * - * @return boolean true if the extension is allowed false otherwise - * - * @since 3.6.0 - */ + * Check if the extension is allowed and will be shown in the template manager + * + * @param string $ext The extension to check if it is allowed + * + * @return boolean true if the extension is allowed false otherwise + * + * @since 3.6.0 + */ protected function checkFormat($ext) { if (!isset($this->allowedFormats)) diff --git a/administrator/components/com_templates/models/templates.php b/administrator/components/com_templates/models/templates.php index e145fc15f364c..9ca818132f01e 100644 --- a/administrator/components/com_templates/models/templates.php +++ b/administrator/components/com_templates/models/templates.php @@ -3,12 +3,14 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\String\StringHelper; + /** * Methods supporting a list of template extension records. * @@ -98,7 +100,7 @@ protected function getListQuery() } else { - $search = $db->quote('%' . strtolower($search) . '%'); + $search = $db->quote('%' . StringHelper::strtolower($search) . '%'); $query->where('(' . ' LOWER(a.element) LIKE ' . $search . ' OR LOWER(a.name) LIKE ' . $search . ')'); } } diff --git a/administrator/components/com_templates/tables/style.php b/administrator/components/com_templates/tables/style.php index a065b1d975a52..c85c8d4c76b62 100644 --- a/administrator/components/com_templates/tables/style.php +++ b/administrator/components/com_templates/tables/style.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -115,7 +115,7 @@ public function store($updateNulls = false) public function delete($pk = null) { $k = $this->_tbl_key; - $pk = (is_null($pk)) ? $this->$k : $pk; + $pk = is_null($pk) ? $this->$k : $pk; if (!is_null($pk)) { diff --git a/administrator/components/com_templates/templates.php b/administrator/components/com_templates/templates.php index 51f9d1becdb44..67ed489de70a8 100644 --- a/administrator/components/com_templates/templates.php +++ b/administrator/components/com_templates/templates.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2008 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/components/com_templates/templates.xml b/administrator/components/com_templates/templates.xml index 6b98efe365c69..69ae36fb5b0cd 100644 --- a/administrator/components/com_templates/templates.xml +++ b/administrator/components/com_templates/templates.xml @@ -3,7 +3,7 @@ com_templates Joomla! Project April 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org diff --git a/administrator/components/com_templates/views/style/tmpl/edit.php b/administrator/components/com_templates/views/style/tmpl/edit.php index f9daadf4b80f4..48266ef614dea 100644 --- a/administrator/components/com_templates/views/style/tmpl/edit.php +++ b/administrator/components/com_templates/views/style/tmpl/edit.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -37,9 +37,9 @@
    -

    +

    item->template); ?> -

    +
    item->client_id == 0 ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); ?> diff --git a/administrator/components/com_templates/views/style/tmpl/edit_assignment.php b/administrator/components/com_templates/views/style/tmpl/edit_assignment.php index a3175d793142f..0cc017bd5e516 100644 --- a/administrator/components/com_templates/views/style/tmpl/edit_assignment.php +++ b/administrator/components/com_templates/views/style/tmpl/edit_assignment.php @@ -3,13 +3,13 @@ * @package Joomla.Administrator * @subpackage com_templates * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -// Initiasile related data. +// Initialise related data. JLoader::register('MenusHelper', JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php'); $menuTypes = MenusHelper::getMenuLinks(); $user = JFactory::getUser(); @@ -26,14 +26,14 @@
  • diff --git a/administrator/modules/mod_custom/tmpl/default.php b/administrator/modules/mod_custom/tmpl/default.php index 3a114d3e96e9d..c4ce101d06ae1 100644 --- a/administrator/modules/mod_custom/tmpl/default.php +++ b/administrator/modules/mod_custom/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_custom * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_feed/helper.php b/administrator/modules/mod_feed/helper.php index 06beb58b3a03a..6fd4c1127ea87 100644 --- a/administrator/modules/mod_feed/helper.php +++ b/administrator/modules/mod_feed/helper.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_feed * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_feed/mod_feed.php b/administrator/modules/mod_feed/mod_feed.php index 61268f0d444c0..7d2de12328a28 100644 --- a/administrator/modules/mod_feed/mod_feed.php +++ b/administrator/modules/mod_feed/mod_feed.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_feed * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -26,6 +26,6 @@ } $feed = ModFeedHelper::getFeed($params); -$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8'); +$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8'); require JModuleHelper::getLayoutPath('mod_feed', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_feed/mod_feed.xml b/administrator/modules/mod_feed/mod_feed.xml index 1981a0361f50a..fd51e85a28a85 100644 --- a/administrator/modules/mod_feed/mod_feed.xml +++ b/administrator/modules/mod_feed/mod_feed.xml @@ -3,7 +3,7 @@ mod_feed Joomla! Project July 2005 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -40,6 +40,7 @@ description="MOD_FEED_FIELD_RTL_DESC" class="btn-group btn-group-yesno" default="0" + filter="integer" > @@ -52,6 +53,19 @@ description="MOD_FEED_FIELD_RSSTITLE_DESC" class="btn-group btn-group-yesno" default="1" + filter="integer" + > + + +
    + + @@ -64,6 +78,7 @@ description="MOD_FEED_FIELD_DESCRIPTION_DESC" class="btn-group btn-group-yesno" default="1" + filter="integer" > @@ -76,6 +91,7 @@ description="MOD_FEED_FIELD_IMAGE_DESC" class="btn-group btn-group-yesno" default="1" + filter="integer" > @@ -83,10 +99,11 @@ + + + + + @@ -103,11 +134,12 @@
    @@ -115,7 +147,7 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" /> @@ -139,10 +172,11 @@
    diff --git a/administrator/modules/mod_feed/tmpl/default.php b/administrator/modules/mod_feed/tmpl/default.php index 3f13b3c7d78f7..1abc9d7ab4c57 100644 --- a/administrator/modules/mod_feed/tmpl/default.php +++ b/administrator/modules/mod_feed/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_feed * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -16,7 +16,7 @@ else { $lang = JFactory::getLanguage(); - $myrtl = $params->get('rssrtl'); + $myrtl = $params->get('rssrtl', 0); $direction = ' '; if ($lang->isRtl() && $myrtl == 0) @@ -49,19 +49,22 @@ } if ($feed != false) : - // Image handling - $iUrl = isset($feed->image) ? $feed->image : null; - $iTitle = isset($feed->imagetitle) ? $feed->imagetitle : null; ?> -
    +
    title) && $params->get('rsstitle', 1)) : ?>

    title; ?>

    + get('rssdate', 1)) : ?> +

    + publishedDate, JText::_('DATE_FORMAT_LC3')); ?> +

    @@ -70,38 +73,48 @@ - get('rssimage', 1) && $iUrl) : ?> - <?php echo @$iTitle; ?> + get('rssimage', 1) && $feed->image) : ?> + <?php echo $feed->image->title; ?> -
      - get('rssitems', 5); $i++) : + + + +
        > + +
          + + get('rssitems', 3); $i++) : if (!$feed->offsetExists($i)) : break; endif; - $uri = (!empty($feed[$i]->uri) || !is_null($feed[$i]->uri)) ? $feed[$i]->uri : $feed[$i]->guid; - $uri = substr($uri, 0, 4) != 'http' ? $params->get('rsslink') : $uri; - $text = !empty($feed[$i]->content) || !is_null($feed[$i]->content) ? $feed[$i]->content : $feed[$i]->description; + $uri = $feed[$i]->uri || !$feed[$i]->isPermaLink ? trim($feed[$i]->uri) : trim($feed[$i]->guid); + $uri = !$uri || stripos($uri, 'http') !== 0 ? $rssurl : $uri; + $text = $feed[$i]->content !== '' ? trim($feed[$i]->content) : ''; ?>
        • + title); ?> - - get('rssitemdesc') && !empty($text)) : ?> + get('rssitemdate', 0)) : ?> +
          + publishedDate, JText::_('DATE_FORMAT_LC3')); ?> +
          + + get('rssitemdesc', 1) && $text !== '') : ?>
          get('word_count'), true, false); + $text = JHtml::_('string.truncate', $text, $params->get('word_count', 0), true, false); echo str_replace(''', "'", $text); ?>
          diff --git a/administrator/modules/mod_latest/helper.php b/administrator/modules/mod_latest/helper.php index 82083d85a279d..859a05174dacd 100644 --- a/administrator/modules/mod_latest/helper.php +++ b/administrator/modules/mod_latest/helper.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_latest * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -37,7 +37,7 @@ public static function getList(&$params) ' a.access, a.created, a.created_by, a.created_by_alias, a.featured, a.state, a.publish_up, a.publish_down'); // Set Ordering filter - switch ($params->get('ordering')) + switch ($params->get('ordering', 'c_dsc')) { case 'm_dsc': $model->setState('list.ordering', 'modified DESC, created'); @@ -52,7 +52,7 @@ public static function getList(&$params) } // Set Category Filter - $categoryId = $params->get('catid'); + $categoryId = $params->get('catid', null); if (is_numeric($categoryId)) { @@ -62,7 +62,7 @@ public static function getList(&$params) // Set User Filter. $userId = $user->get('id'); - switch ($params->get('user_id')) + switch ($params->get('user_id', '0')) { case 'by_me': $model->setState('filter.author_id', $userId); @@ -112,9 +112,9 @@ public static function getList(&$params) */ public static function getTitle($params) { - $who = $params->get('user_id'); - $catid = (int) $params->get('catid'); - $type = $params->get('ordering') == 'c_dsc' ? '_CREATED' : '_MODIFIED'; + $who = $params->get('user_id', '0'); + $catid = (int) $params->get('catid', null); + $type = $params->get('ordering', 'c_dsc') == 'c_dsc' ? '_CREATED' : '_MODIFIED'; if ($catid) { @@ -134,6 +134,10 @@ public static function getTitle($params) $title = ''; } - return JText::plural('MOD_LATEST_TITLE' . $type . ($catid ? '_CATEGORY' : '') . ($who != '0' ? "_$who" : ''), (int) $params->get('count'), $title); + return JText::plural( + 'MOD_LATEST_TITLE' . $type . ($catid ? '_CATEGORY' : '') . ($who != '0' ? "_$who" : ''), + (int) $params->get('count', 5), + $title + ); } } diff --git a/administrator/modules/mod_latest/mod_latest.php b/administrator/modules/mod_latest/mod_latest.php index 7bb17edfb6ebb..59e8688fa71bd 100644 --- a/administrator/modules/mod_latest/mod_latest.php +++ b/administrator/modules/mod_latest/mod_latest.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_latest * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_latest/mod_latest.xml b/administrator/modules/mod_latest/mod_latest.xml index 1479df47899b2..9c39b861e4408 100644 --- a/administrator/modules/mod_latest/mod_latest.xml +++ b/administrator/modules/mod_latest/mod_latest.xml @@ -3,7 +3,7 @@ mod_latest Joomla! Project July 2004 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -24,10 +24,11 @@
          @@ -70,12 +72,13 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" /> diff --git a/administrator/modules/mod_latest/tmpl/default.php b/administrator/modules/mod_latest/tmpl/default.php index dd2dc96b7143b..84b7a1b0b871c 100644 --- a/administrator/modules/mod_latest/tmpl/default.php +++ b/administrator/modules/mod_latest/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_latest * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_latestactions/helper.php b/administrator/modules/mod_latestactions/helper.php new file mode 100644 index 0000000000000..cb88094bcf7e8 --- /dev/null +++ b/administrator/modules/mod_latestactions/helper.php @@ -0,0 +1,69 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text; +use Joomla\CMS\MVC\Model\BaseDatabaseModel; + +/** + * Helper for mod_latestactions + * + * @since 3.9.0 + */ +abstract class ModLatestActionsHelper +{ + /** + * Get a list of articles. + * + * @param \Joomla\Registry\Registry &$params The module parameters. + * + * @return mixed An array of action logs, or false on error. + */ + public static function getList(&$params) + { + JLoader::register('ActionlogsModelActionlogs', JPATH_ADMINISTRATOR . '/components/com_actionlogs/models/actionlogs.php'); + JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php'); + + /* @var ActionlogsModelActionlogs $model */ + $model = BaseDatabaseModel::getInstance('Actionlogs', 'ActionlogsModel', array('ignore_request' => true)); + + // Set the Start and Limit + $model->setState('list.start', 0); + $model->setState('list.limit', $params->get('count', 5)); + $model->setState('list.ordering', 'a.id'); + $model->setState('list.direction', 'DESC'); + + $rows = $model->getItems(); + + // Load all actionlog plugins language files + ActionlogsHelper::loadActionLogPluginsLanguage(); + + foreach ($rows as $row) + { + $row->message = ActionlogsHelper::getHumanReadableLogMessage($row); + } + + return $rows; + } + + /** + * Get the alternate title for the module + * + * @param \Joomla\Registry\Registry $params The module parameters. + * + * @return string The alternate title for the module. + * + * @since 3.9.1 + */ + public static function getTitle($params) + { + return Text::plural('MOD_LATESTACTIONS_TITLE', $params->get('count', 5)); + } +} diff --git a/administrator/modules/mod_latestactions/mod_latestactions.php b/administrator/modules/mod_latestactions/mod_latestactions.php new file mode 100644 index 0000000000000..cd1f560d54fc0 --- /dev/null +++ b/administrator/modules/mod_latestactions/mod_latestactions.php @@ -0,0 +1,31 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\Helper\ModuleHelper; + +// Only super user can view this data +if (!Factory::getUser()->authorise('core.admin')) +{ + return; +} + +// Include dependencies. +JLoader::register('ModLatestActionsHelper', __DIR__ . '/helper.php'); + +$list = ModLatestActionsHelper::getList($params); + +if ($params->get('automatic_title', 0)) +{ + $module->title = ModLatestActionsHelper::getTitle($params); +} + +require ModuleHelper::getLayoutPath('mod_latestactions', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_latestactions/mod_latestactions.xml b/administrator/modules/mod_latestactions/mod_latestactions.xml new file mode 100644 index 0000000000000..62e9da5ed41a8 --- /dev/null +++ b/administrator/modules/mod_latestactions/mod_latestactions.xml @@ -0,0 +1,95 @@ + + + mod_latestactions + Joomla! Project + May 2018 + (C) 2018 Open Source Matters, Inc. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + MOD_LATESTACTIONS_XML_DESCRIPTION + + mod_latestactions.php + helper.php + tmpl + + + en-GB.mod_latestactions.ini + en-GB.mod_latestactions.sys.ini + + + + +
          + +
          +
          + + + + + + + + + + + + + + + + + + + +
          +
          +
          +
          diff --git a/administrator/modules/mod_latestactions/tmpl/default.php b/administrator/modules/mod_latestactions/tmpl/default.php new file mode 100644 index 0000000000000..4c0b2c90243d4 --- /dev/null +++ b/administrator/modules/mod_latestactions/tmpl/default.php @@ -0,0 +1,38 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; + +HTMLHelper::_('bootstrap.tooltip'); +?> +
          + + $item) : ?> +
          +
          + message; ?> +
          +
          +
          + log_date, JText::_('DATE_FORMAT_LC5')); ?> +
          +
          +
          + + +
          +
          +
          +
          +
          + +
          diff --git a/administrator/modules/mod_logged/helper.php b/administrator/modules/mod_logged/helper.php index 80a4fb1714b30..bfbb9aaef8bfb 100644 --- a/administrator/modules/mod_logged/helper.php +++ b/administrator/modules/mod_logged/helper.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_logged * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -73,6 +73,6 @@ public static function getList(&$params) */ public static function getTitle($params) { - return JText::plural('MOD_LOGGED_TITLE', $params->get('count')); + return JText::plural('MOD_LOGGED_TITLE', $params->get('count', 5)); } } diff --git a/administrator/modules/mod_logged/mod_logged.php b/administrator/modules/mod_logged/mod_logged.php index 691f804140a64..e599a6610c6bd 100644 --- a/administrator/modules/mod_logged/mod_logged.php +++ b/administrator/modules/mod_logged/mod_logged.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_logged * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_logged/mod_logged.xml b/administrator/modules/mod_logged/mod_logged.xml index 748a251609687..8d364ab730639 100644 --- a/administrator/modules/mod_logged/mod_logged.xml +++ b/administrator/modules/mod_logged/mod_logged.xml @@ -3,7 +3,7 @@ mod_logged Joomla! Project January 2005 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -23,10 +23,11 @@
          @@ -45,7 +47,8 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" /> diff --git a/administrator/modules/mod_logged/tmpl/default.php b/administrator/modules/mod_logged/tmpl/default.php index b4d2b1eba1af7..283b0aac6ca18 100644 --- a/administrator/modules/mod_logged/tmpl/default.php +++ b/administrator/modules/mod_logged/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_logged * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -17,7 +17,7 @@
          client_id == 0) : ?> - + diff --git a/administrator/modules/mod_login/helper.php b/administrator/modules/mod_login/helper.php index 758ce671901e0..0753a6c72c0f8 100644 --- a/administrator/modules/mod_login/helper.php +++ b/administrator/modules/mod_login/helper.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_login * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -49,7 +49,7 @@ function ($a, $b) array_unshift($languages, JHtml::_('select.option', '', JText::_('JDEFAULTLANGUAGE'))); - return JHtml::_('select.genericlist', $languages, 'lang', ' class="advancedSelect"', 'value', 'text', null); + return JHtml::_('select.genericlist', $languages, 'lang', 'class="advancedSelect" tabindex="4"', 'value', 'text', null); } /** diff --git a/administrator/modules/mod_login/mod_login.php b/administrator/modules/mod_login/mod_login.php index c48860246b61c..0e15703d41564 100644 --- a/administrator/modules/mod_login/mod_login.php +++ b/administrator/modules/mod_login/mod_login.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_login * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_login/mod_login.xml b/administrator/modules/mod_login/mod_login.xml index 102535cc5fd00..636760a94aec8 100644 --- a/administrator/modules/mod_login/mod_login.xml +++ b/administrator/modules/mod_login/mod_login.xml @@ -3,7 +3,7 @@ mod_login Joomla! Project March 2005 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -29,6 +29,7 @@ description="MOD_LOGIN_FIELD_USESECURE_DESC" class="btn-group btn-group-yesno" default="0" + filter="integer" > @@ -39,7 +40,8 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" /> * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -18,7 +18,7 @@ JHtml::_('formbehavior.chosen', '.advancedSelect'); } ?> -
          +
          @@ -62,7 +62,7 @@ - + @@ -88,7 +88,7 @@
          -
          diff --git a/administrator/modules/mod_menu/helper.php b/administrator/modules/mod_menu/helper.php index dfb295d984835..583c4f43e0e63 100644 --- a/administrator/modules/mod_menu/helper.php +++ b/administrator/modules/mod_menu/helper.php @@ -3,15 +3,12 @@ * @package Joomla.Administrator * @subpackage mod_menu * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2007 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -use Joomla\Registry\Registry; -use Joomla\Utilities\ArrayHelper; - /** * Helper for mod_menu * @@ -25,23 +22,28 @@ abstract class ModMenuHelper * @return array An array of the available menus (from the menu types table). * * @since 1.6 + * + * @deprecated 4.0 */ public static function getMenus() { $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('a.*, SUM(b.home) AS home') - ->from('#__menu_types AS a') - ->join('LEFT', '#__menu AS b ON b.menutype = a.menutype AND b.home != 0') - ->select('b.language') - ->join('LEFT', '#__languages AS l ON l.lang_code = language') - ->select('l.image') - ->select('l.sef') - ->select('l.title_native') + + // Search for home menu and language if exists + $subQuery = $db->getQuery(true) + ->select('b.menutype, b.home, b.language, l.image, l.sef, l.title_native') + ->from('#__menu AS b') + ->leftJoin('#__languages AS l ON l.lang_code = b.language') + ->where('b.home != 0') ->where('(b.client_id = 0 OR b.client_id IS NULL)'); - // Sqlsrv change - $query->group('a.id, a.menutype, a.description, a.title, b.menutype,b.language,l.image,l.sef,l.title_native'); + // Get all menu types with optional home menu and language + $query = $db->getQuery(true) + ->select('a.id, a.asset_id, a.menutype, a.title, a.description, a.client_id') + ->select('c.home, c.language, c.image, c.sef, c.title_native') + ->from('#__menu_types AS a') + ->leftJoin('(' . (string) $subQuery . ') c ON c.menutype = a.menutype') + ->order('a.id'); $db->setQuery($query); @@ -52,323 +54,9 @@ public static function getMenus() catch (RuntimeException $e) { $result = array(); - JFactory::getApplication()->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error'); + JFactory::getApplication()->enqueueMessage(JText::sprintf('JERROR_LOADING_MENUS', $e->getMessage()), 'error'); } return $result; } - - /** - * Get a list of the authorised, non-special components to display in the components menu. - * - * @param boolean $authCheck An optional switch to turn off the auth check (to support custom layouts 'grey out' behaviour). - * @param boolean $enabledOnly Whether to load only enabled/published menu items. - * @param int[] $exclude The menu items to exclude from the list - * - * @return array A nest array of component objects and submenus - * - * @since 1.6 - */ - public static function getComponents($authCheck = true, $enabledOnly = false, $exclude = array()) - { - $lang = JFactory::getLanguage(); - $user = JFactory::getUser(); - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - $result = array(); - - // Prepare the query. - $query->select('m.id, m.title, m.alias, m.link, m.parent_id, m.img, e.element, m.menutype') - ->from('#__menu AS m') - ->where('m.menutype = ' . $db->q('main')) - ->where('m.client_id = 1') - ->where('m.id > 1'); - - if ($enabledOnly) - { - $query->where('m.published = 1'); - } - - if (count($exclude)) - { - $query->where('m.id NOT IN (' . implode(', ', array_map('intval', $exclude)) . ')'); - $query->where('m.parent_id NOT IN (' . implode(', ', array_map('intval', $exclude)) . ')'); - } - - // Filter on the enabled states. - $query->join('INNER', '#__extensions AS e ON m.component_id = e.extension_id') - ->where('e.enabled = 1'); - - // Order by lft. - $query->order('m.lft'); - - $db->setQuery($query); - - // Component list - try - { - $components = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - $components = array(); - JFactory::getApplication()->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error'); - } - - // Parse the list of extensions. - foreach ($components as &$component) - { - // Trim the menu link. - $component->link = trim($component->link); - - if ($component->parent_id == 1) - { - // Only add this top level if it is authorised and enabled. - if ($authCheck == false || ($authCheck && $user->authorise('core.manage', $component->element))) - { - // Root level. - $result[$component->id] = $component; - - if (!isset($result[$component->id]->submenu)) - { - $result[$component->id]->submenu = array(); - } - - // If the root menu link is empty, add it in. - if (empty($component->link)) - { - $component->link = 'index.php?option=' . $component->element; - } - - if (!empty($component->element)) - { - // Load the core file then - // Load extension-local file. - $lang->load($component->element . '.sys', JPATH_BASE, null, false, true) - || $lang->load($component->element . '.sys', JPATH_ADMINISTRATOR . '/components/' . $component->element, null, false, true); - } - - $component->text = JText::_(strtoupper($component->title)); - } - } - // Sub-menu level. - // Add the submenu link if it is defined. - elseif (isset($result[$component->parent_id]) && isset($result[$component->parent_id]->submenu) && !empty($component->link)) - { - $component->text = JText::_(strtoupper($component->title)); - - $result[$component->parent_id]->submenu[] = &$component; - } - } - - return ArrayHelper::sortObjects($result, 'text', 1, false, true); - } - - /** - * Load the menu items from database for the given menutype - * - * @param string $menutype The selected menu type - * - * @return array - * - * @since 3.7.0 - */ - public static function getMenuItems($menutype) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - // Prepare the query. - $query->select('m.*') - ->from('#__menu AS m') - ->where('m.menutype = ' . $db->q($menutype)) - ->where('m.client_id = 1') - ->where('m.published = 1') - ->where('m.id > 1'); - - // Filter on the enabled states. - $query->select('e.element') - ->join('LEFT', '#__extensions AS e ON m.component_id = e.extension_id') - ->where('(e.enabled = 1 OR e.enabled IS NULL)'); - - // Order by lft. - $query->order('m.lft'); - - $db->setQuery($query); - - // Component list - try - { - $menuItems = $db->loadObjectList(); - - foreach ($menuItems as &$menuitem) - { - $menuitem->params = new Registry($menuitem->params); - } - } - catch (RuntimeException $e) - { - $menuItems = array(); - JFactory::getApplication()->enqueueMessage(JText::_('JERROR_AN_ERROR_HAS_OCCURRED'), 'error'); - } - - return $menuItems; - } - - /** - * Parse the list of extensions. - * - * @param array $menuItems List of loaded components - * @param bool $authCheck An optional switch to turn off the auth check (to support custom layouts 'grey out' behaviour). - * - * @return array - * - * @since 3.7.0 - */ - public static function parseItems($menuItems, $authCheck = true) - { - $result = array(); - $user = JFactory::getUser(); - $lang = JFactory::getLanguage(); - $levels = $user->getAuthorisedViewLevels(); - - // Process each item - foreach ($menuItems as $i => &$menuitem) - { - /* - * Exclude item with menu item option set to exclude from menu modules - * Exclude item if the component is not authorised - * Exclude item if menu item set access level is not met - */ - if (($menuitem->params->get('menu_show', 1) == 0) - || ($menuitem->element && $authCheck && !$user->authorise('core.manage', $menuitem->element)) - || ($menuitem->access && !in_array($menuitem->access, $levels))) - { - continue; - } - - // Evaluate link url - switch ($menuitem->type) - { - case 'url': - case 'component': - $menuitem->link = trim($menuitem->link); - break; - case 'separator': - case 'heading': - case 'container': - $menuitem->link = '#'; - break; - case 'alias': - $aliasTo = $menuitem->params->get('aliasoptions'); - $menuitem->link = static::getLink($aliasTo); - break; - default: - } - - if ($menuitem->link == '') - { - continue; - } - - // Translate Menu item label, if needed - if (!empty($menuitem->element)) - { - $lang->load($menuitem->element . '.sys', JPATH_BASE, null, false, true) - || $lang->load($menuitem->element . '.sys', JPATH_ADMINISTRATOR . '/components/' . $menuitem->element, null, false, true); - } - - $menuitem->text = $lang->hasKey($menuitem->title) ? JText::_($menuitem->title) : $menuitem->title; - $menuitem->submenu = array(); - - $result[$menuitem->parent_id][$menuitem->id] = $menuitem; - } - - // Do an early exit if there are no top level menu items. - if (!isset($result[1])) - { - return array(); - } - - // Put the items under respective parent menu items. - foreach ($result as $parentId => &$mItems) - { - foreach ($mItems as &$mItem) - { - if (isset($result[$mItem->id])) - { - static::cleanup($result[$mItem->id]); - - $mItem->submenu = &$result[$mItem->id]; - } - } - } - - // Return only top level items - return $result[1]; - } - - /** - * Method to get a link to the aliased menu item - * - * @param int $menuId The record id of the referencing menu item - * - * @return string - * - * @since 3.7.0 - */ - protected static function getLink($menuId) - { - $table = JTable::getInstance('Menu'); - $table->load($menuId); - - // Look for an alias-to-alias - if ($table->type == 'alias') - { - $params = new Registry($table->params); - $aliasTo = $params->get('aliasoptions'); - - return static::getLink($aliasTo); - } - - return $table->link; - } - - /** - * Method to cleanup the menu items for repeated, leading or trailing separators in a given menu level - * - * @param array &$items The list of menu items in the selected level - * - * @return void - * - * @since 3.7.0 - */ - protected static function cleanup(&$items) - { - $b = true; - - foreach ($items as $k => &$item) - { - if ($item->type == 'separator') - { - if ($b) - { - $item = false; - } - - $b = true; - } - else - { - $b = false; - } - } - - if ($b) - { - $item = false; - } - - $items = array_filter($items); - } } diff --git a/administrator/modules/mod_menu/menu.php b/administrator/modules/mod_menu/menu.php index ca2095d9a1dc3..e73ae817b5314 100644 --- a/administrator/modules/mod_menu/menu.php +++ b/administrator/modules/mod_menu/menu.php @@ -3,12 +3,18 @@ * @package Joomla.Administrator * @subpackage mod_menu * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; +use Joomla\CMS\Factory; +use Joomla\CMS\Log\Log; +use Joomla\CMS\Menu\Node; +use Joomla\CMS\Menu\Tree; +use Joomla\CMS\Menu\MenuHelper; +use Joomla\CMS\User\User; use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; @@ -20,679 +26,500 @@ class JAdminCssMenu { /** - * CSS string to add to document head + * The Menu tree object * - * @var string + * @var Tree + * @since 3.8.0 + * @deprecated 4.0 */ - protected $_css = null; + protected $tree; /** - * Root node + * The module options * - * @var object + * @var Registry + * @since 3.8.0 */ - protected $_root = null; + protected $params; /** - * Current working node + * The menu bar state * - * @var object + * @var bool + * @since 3.8.0 */ - protected $_current = null; + protected $enabled; /** - * Constructor + * The current user + * + * @var User + * @since 3.9.1 */ - public function __construct() - { - $this->_root = new JMenuNode('ROOT'); - $this->_current = &$this->_root; - } + protected $user; /** - * Method to add a child + * JAdminCssMenu constructor. * - * @param JMenuNode $node The node to process - * @param boolean $setCurrent True to set as current working node + * @param User|null $user The current user * - * @return void + * @since 3.9.1 */ - public function addChild(JMenuNode $node, $setCurrent = false) + public function __construct(User $user = null) { - $this->_current->addChild($node); - - if ($setCurrent) + if ($user === null) { - $this->_current = &$node; + Log::add( + sprintf( + 'Not passing a %s instance into the %s constructor is deprecated. As of 4.0, it will be required.', + 'Joomla\CMS\User\User', + __CLASS__ + ), + Log::WARNING, + 'deprecated' + ); + + $user = Factory::getUser(); } - } - /** - * Method to get the parent - * - * @return void - */ - public function getParent() - { - $this->_current = &$this->_current->getParent(); + $this->user = $user; } /** - * Method to get the parent + * Get the current menu tree * - * @param bool $clear Whether to clear the existing menu items or just reset the pointer to root element + * @return Tree * - * @return void + * @since 3.8.0 + * + * @deprecated 4.0 */ - public function reset($clear = false) + public function getTree() { - if ($clear) + if (!$this->tree) { - $this->_root = new JMenuNode('ROOT'); + $this->tree = new Tree; } - $this->_current = &$this->_root; + return $this->tree; } /** - * Method to add a separator node + * Populate the menu items in the menu tree object * - * @param string $title The separator label text. A dash "-" can be used to use a horizontal bar instead of text label. + * @param Registry $params Menu configuration parameters + * @param bool $enabled Whether the menu should be enabled or disabled * * @return void + * + * @since 3.7.0 */ - public function addSeparator($title = null) + public function load($params, $enabled) { - if ($title == '-' || $title == '') + $this->tree = $this->getTree(); + $this->params = $params; + $this->enabled = $enabled; + $menutype = $this->params->get('menutype', '*'); + + if ($menutype === '*') { - $title = null; + $name = $this->params->get('preset', 'joomla'); + $levels = MenuHelper::loadPreset($name); } + else + { + $items = MenusHelper::getMenuItems($menutype, true); - $this->addChild(new JMenuNode($title, null, 'separator', false)); - } + if ($this->enabled && $this->params->get('check', 1)) + { + if ($this->check($items, $this->params)) + { + $this->params->set('recovery', true); - /** - * Method to render the menu - * - * @param string $id The id of the menu to be rendered - * @param string $class The class of the menu to be rendered - * - * @return void - */ - public function renderMenu($id = 'menu', $class = '') - { - $depth = 1; + // In recovery mode, load the preset inside a special root node. + $this->tree->addChild(new Node\Heading('MOD_MENU_RECOVERY_MENU_ROOT'), true); - if (!empty($id)) - { - $id = 'id="' . $id . '"'; - } + $levels = MenuHelper::loadPreset('joomla'); + $levels = $this->preprocess($levels); - if (!empty($class)) - { - $class = 'class="' . $class . '"'; - } + $this->populateTree($levels); - // Recurse through children if they exist - while ($this->_current->hasChildren()) - { - echo '
            \n"; + $this->tree->addChild(new Node\Separator); - foreach ($this->_current->getChildren() as $child) - { - $this->_current = & $child; - $this->renderLevel($depth++); - } + // Add link to exit recovery mode + $uri = clone JUri::getInstance(); + $uri->setVar('recover_menu', 0); - echo "
          \n"; + $this->tree->addChild(new Node\Url('MOD_MENU_RECOVERY_EXIT', $uri->toString())); - echo ''; - } + $this->tree->getParent(); + } + } - if ($this->_css) - { - // Add style to document head - JFactory::getDocument()->addStyleDeclaration($this->_css); + $levels = MenuHelper::createLevels($items); } + + $levels = $this->preprocess($levels); + + $this->populateTree($levels); } /** - * Method to render a given level of a menu + * Method to render a given level of a menu using provided layout file * - * @param integer $depth The level of the menu to be rendered + * @param string $layoutFile The layout file to be used to render * * @return void + * + * @since 3.8.0 */ - public function renderLevel($depth) + public function renderSubmenu($layoutFile) { - // Build the CSS class suffix - $class = ''; - - if ($this->_current->hasChildren()) + if (is_file($layoutFile)) { - $class = ' class="dropdown"'; - } + $children = $this->tree->getCurrent()->getChildren(); - if ($this->_current->class == 'separator') - { - $class = $this->_current->title ? ' class="menuitem-group"' : ' class="divider"'; - } - - if ($this->_current->hasChildren() && $this->_current->class) - { - $class = ' class="dropdown-submenu"'; - - if ($this->_current->class == 'scrollable-menu') + foreach ($children as $child) { - $class = ' class="dropdown scrollable-menu"'; + $this->tree->setCurrent($child); + + // This sets the scope to this object for the layout file and also isolates other `include`s + require $layoutFile; } } + } - if ($this->_current->class == 'disabled') + /** + * Check the flat list of menu items for important links + * + * @param array $items The menu items array + * @param Registry $params Module options + * + * @return boolean Whether to show recovery menu + * + * @since 3.8.0 + */ + protected function check($items, Registry $params) + { + $authMenus = $this->user->authorise('core.manage', 'com_menus'); + $authModules = $this->user->authorise('core.manage', 'com_modules'); + + if (!$authMenus && !$authModules) { - $class = ' class="disabled"'; + return false; } - // Print the item - echo ''; - - // Print a link if it exists - $linkClass = array(); - $dataToggle = ''; - $dropdownCaret = ''; + $app = JFactory::getApplication(); + $types = ArrayHelper::getColumn($items, 'type'); + $elements = ArrayHelper::getColumn($items, 'element'); + $rMenu = $authMenus && !in_array('com_menus', $elements); + $rModule = $authModules && !in_array('com_modules', $elements); + $rContainer = !in_array('container', $types); - if ($this->_current->hasChildren()) + if ($rMenu || $rModule || $rContainer) { - $linkClass[] = 'dropdown-toggle'; - $dataToggle = ' data-toggle="dropdown"'; + $recovery = $app->getUserStateFromRequest('mod_menu.recovery', 'recover_menu', 0, 'int'); - if (!$this->_current->getParent()->hasParent()) + if ($recovery) { - $dropdownCaret = ' '; + return true; } - } - else - { - $linkClass[] = 'no-dropdown'; - } - if ($this->_current->link != null && $this->_current->getParent()->title != 'ROOT') - { - $iconClass = $this->getIconClass($this->_current->class); + $missing = array(); - if (!empty($iconClass)) + if ($rMenu) { - $linkClass[] = $iconClass; + $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_MENU_MANAGER'); } - } - - // Implode out $linkClass for rendering - $linkClass = ' class="' . implode(' ', $linkClass) . '"'; - - if ($this->_current->link != null && $this->_current->target != null) - { - echo '' - . $this->_current->title . $dropdownCaret . ''; - } - elseif ($this->_current->link != null && $this->_current->target == null) - { - echo '' . $this->_current->title . $dropdownCaret . ''; - } - elseif ($this->_current->title != null && $this->_current->class != 'separator') - { - echo '' . $this->_current->title . $dropdownCaret . ''; - } - else - { - echo '' . $this->_current->title . ''; - } - - // Recurse through children if they exist - while ($this->_current->hasChildren()) - { - if ($this->_current->class) - { - $id = ''; - if (!empty($this->_current->id)) - { - $id = ' id="menu-' . strtolower($this->_current->id) . '"'; - } - - echo '' . "\n"; - } - else + if ($rModule) { - echo '\n"; - } - - echo "
        • \n"; - } - - /** - * Method to get the CSS class name for an icon identifier or create one if - * a custom image path is passed as the identifier - * - * @param string $identifier Icon identification string - * - * @return string CSS class name - * - * @since 1.5 - */ - public function getIconClass($identifier) - { - static $classes; - - // Initialise the known classes array if it does not exist - if (!is_array($classes)) - { - $classes = array(); - } + $uri = clone JUri::getInstance(); + $uri->setVar('recover_menu', 1); - /* - * If we don't already know about the class... build it and mark it - * known so we don't have to build it again - */ - if (!isset($classes[$identifier])) - { - if (substr($identifier, 0, 6) == 'class:') - { - // We were passed a class name - $class = substr($identifier, 6); - $classes[$identifier] = "menu-$class"; - } - else - { - if ($identifier == null) - { - return null; - } + $table = JTable::getInstance('MenuType'); + $menutype = $params->get('menutype'); - // Build the CSS class for the icon - $class = preg_replace('#\.[^.]*$#', '', basename($identifier)); - $class = preg_replace('#\.\.[^A-Za-z0-9\.\_\- ]#', '', $class); + $table->load(array('menutype' => $menutype)); - $this->_css .= "\n.menu-$class {\n" . - " background: url($identifier) no-repeat;\n" . - "}\n"; + $menutype = $table->get('title', $menutype); + $message = JText::sprintf('MOD_MENU_IMPORTANT_ITEMS_INACCESSIBLE_LIST_WARNING', $menutype, implode(', ', $missing), $uri); - $classes[$identifier] = "menu-$class"; - } + $app->enqueueMessage($message, 'warning'); } - return $classes[$identifier]; + return false; } /** - * Populate the menu items in the menu object for disabled state + * Filter and perform other preparatory tasks for loaded menu items based on access rights and module configurations for display * - * @param Registry $params Menu configuration parameters - * @param bool $enabled Whether the menu should be enabled or disabled + * @param \stdClass[] $items The levelled array of menu item objects * - * @return void + * @return array * - * @since 3.7.0 + * @since 3.8.0 */ - public function load($params, $enabled) + protected function preprocess($items) { - $menutype = $params->get('menutype', '*'); + $result = array(); + $language = JFactory::getLanguage(); - $this->reset(true); + $noSeparator = true; - if ($menutype == '*') - { - require __DIR__ . '/preset/' . ($enabled ? 'enabled.php' : 'disabled.php'); - } - else + // Call preprocess for the menu items on plugins. + // Plugins should normally process the current level only unless their logic needs deep levels too. + $dispatcher = JEventDispatcher::getInstance(); + $dispatcher->trigger('onPreprocessMenuItems', array('com_menus.administrator.module', &$items, $this->params, $this->enabled)); + + foreach ($items as $i => &$item) { - $items = ModMenuHelper::getMenuItems($menutype); - $types = ArrayHelper::getColumn($items, 'type'); - $app = JFactory::getApplication(); - $me = JFactory::getUser(); + // Exclude item with menu item option set to exclude from menu modules + if ($item->params->get('menu_show', 1) == 0) + { + continue; + } - $authMenus = $me->authorise('core.manage', 'com_menus'); - $authModules = $me->authorise('core.manage', 'com_modules'); + $item->scope = isset($item->scope) ? $item->scope : 'default'; + $item->icon = isset($item->icon) ? $item->icon : ''; - if ($enabled && $params->get('check') && ($authMenus || $authModules)) + // Whether this scope can be displayed. Applies only to preset items. Db driven items should use un/published state. + if (($item->scope === 'help' && !$this->params->get('showhelp', 1)) || ($item->scope === 'edit' && !$this->params->get('shownew', 1))) { - $elements = ArrayHelper::getColumn($items, 'element'); + continue; + } - $rMenu = $authMenus && !in_array('com_menus', $elements); - $rModule = $authModules && !in_array('com_modules', $elements); - $rContainer = !in_array('container', $types); + if (substr($item->link, 0, 8) === 'special:') + { + $special = substr($item->link, 8); - if ($rMenu || $rModule || $rContainer) + if ($special === 'language-forum') { - $recovery = $app->getUserStateFromRequest('mod_menu.recovery', 'recover_menu', 0, 'int'); - - if ($recovery) - { - $params->set('recovery', true); - - // In recovery mode, load the preset inside a special root node. - $this->addChild(new JMenuNode(JText::_('MOD_MENU_RECOVERY_MENU_ROOT'), '#'), true); - - require __DIR__ . '/preset/enabled.php'; - - $this->addSeparator(); - - $uri = clone JUri::getInstance(); - $uri->setVar('recover_menu', 0); - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_RECOVERY_EXIT'), $uri->toString())); - - $this->getParent(); - } - else - { - $missing = array(); - - if ($rMenu) - { - $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_MENU_MANAGER'); - } + $item->link = 'index.php?option=com_admin&view=help&layout=langforum'; + } + elseif ($special === 'custom-forum') + { + $item->link = $this->params->get('forum_url'); + } + } - if ($rModule) - { - $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_MODULE_MANAGER'); - } + // Exclude item if is not enabled + if ($item->element && !JComponentHelper::isEnabled($item->element)) + { + continue; + } - if ($rContainer) - { - $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_COMPONENTS_CONTAINER'); - } + // Exclude Mass Mail if disabled in global configuration + if ($item->scope === 'massmail' && (JFactory::getApplication()->get('massmailoff', 0) == 1)) + { + continue; + } - $uri = clone JUri::getInstance(); - $uri->setVar('recover_menu', 1); + // Exclude item if the component is not authorised + $assetName = $item->element; - $table = JTable::getInstance('MenuType'); - $table->load(array('menutype' => $menutype)); - $mType = $table->get('title', $menutype); + if ($item->element === 'com_categories') + { + parse_str($item->link, $query); + $assetName = isset($query['extension']) ? $query['extension'] : 'com_content'; + } + elseif ($item->element === 'com_fields') + { + parse_str($item->link, $query); - $msg = JText::sprintf('MOD_MENU_IMPORTANT_ITEMS_INACCESSIBLE_LIST_WARNING', $mType, implode(', ', $missing), $uri); + // Only display Fields menus when enabled in the component + $createFields = null; - $app->enqueueMessage($msg, 'warning'); - } + if (isset($query['context'])) + { + $createFields = JComponentHelper::getParams(strstr($query['context'], '.', true))->get('custom_fields_enable', 1); } - } - // Create levels - $items = ModMenuHelper::parseItems($items); - - // Menu items for dynamic db driven setup to load here - $this->loadItems($items, $enabled); - } - } + if (!$createFields) + { + continue; + } - /** - * Load the menu items from an array - * - * @param array $items Menu items loaded from database - * @param bool $enabled Whether the menu should be enabled or disabled - * - * @return void - * - * @since 3.7.0 - */ - protected function loadItems($items, $enabled = true) - { - foreach ($items as $item) - { - if ($item->type == 'separator') + list($assetName) = isset($query['context']) ? explode('.', $query['context'], 2) : array('com_fields'); + } + // Special case for components which only allow super user access + elseif (in_array($item->element, array('com_config', 'com_privacy', 'com_actionlogs'), true) && !$this->user->authorise('core.admin')) { - $this->addSeparator($item->text); + continue; } - elseif ($item->type == 'heading' && !count($item->submenu)) + elseif ($item->element === 'com_joomlaupdate' && !$this->user->authorise('core.admin')) { - // Exclude if it is a heading type menu item, and has no children. + continue; } - elseif ($item->type == 'container') + elseif (($item->link === 'index.php?option=com_installer&view=install' || $item->link === 'index.php?option=com_installer&view=languages') + && !$this->user->authorise('core.admin')) { - $exclude = (array) $item->params->get('hideitems') ?: array(); - $components = ModMenuHelper::getComponents(true, false, $exclude); + continue; + } + elseif ($item->element === 'com_admin') + { + parse_str($item->link, $query); - // Exclude if it is a container type menu item, and has no children. - if (count($item->submenu) || count($components)) + if (isset($query['view']) && $query['view'] === 'sysinfo' && !$this->user->authorise('core.admin')) { - $this->addChild(new JMenuNode($item->text, $item->link, $item->parent_id == 1 ? null : 'class:'), true); - - if ($enabled) - { - // Load explicitly assigned child items first. - $this->loadItems($item->submenu); - - // Add a separator between dynamic menu items and components menu items - if (count($item->submenu) && count($components)) - { - $this->addSeparator($item->text); - } - - // Adding component submenu the old way, this assumes 2-level menu only - foreach ($components as $component) - { - if (empty($component->submenu)) - { - $this->addChild(new JMenuNode($component->text, $component->link, $component->img)); - } - else - { - $this->addChild(new JMenuNode($component->text, $component->link, $component->img), true); - - foreach ($component->submenu as $sub) - { - $this->addChild(new JMenuNode($sub->text, $sub->link, $sub->img)); - } - - $this->getParent(); - } - } - } - - $this->getParent(); + continue; } } - elseif (!$enabled) + + if ($assetName && !$this->user->authorise(($item->scope === 'edit') ? 'core.create' : 'core.manage', $assetName)) { - $this->addChild(new JMenuNode($item->text, $item->link, 'disabled')); + continue; } - else - { - $target = $item->browserNav ? '_blank' : null; - $this->addChild(new JMenuNode($item->text, $item->link, $item->parent_id == 1 ? null : 'class:', false, $target), true); - $this->loadItems($item->submenu); - $this->getParent(); + // Exclude if link is invalid + if (is_null($item->link) || (!in_array($item->type, array('separator', 'heading', 'container')) && trim($item->link) === '')) + { + continue; } - } - } -} -/** - * A Node for JAdminCssMenu - * - * @see JAdminCssMenu - * @since 1.5 - */ -class JMenuNode -{ - /** - * Node Title - * - * @var string - */ - public $title = null; + // Process any children if exists + $item->submenu = $this->preprocess($item->submenu); - /** - * Node Id - * - * @var string - */ - public $id = null; + // Populate automatic children for container items + if ($item->type === 'container') + { + $exclude = (array) $item->params->get('hideitems') ?: array(); + $components = MenusHelper::getMenuItems('main', false, $exclude); - /** - * Node Link - * - * @var string - */ - public $link = null; + $item->components = MenuHelper::createLevels($components); + $item->components = $this->preprocess($item->components); + $item->components = ArrayHelper::sortObjects($item->components, 'text', 1, false, true); + } - /** - * Link Target - * - * @var string - */ - public $target = null; + // Exclude if there are no child items under heading or container + if (in_array($item->type, array('heading', 'container')) && empty($item->submenu) && empty($item->components)) + { + continue; + } - /** - * CSS Class for node - * - * @var string - */ - public $class = null; + // Remove repeated and edge positioned separators, It is important to put this check at the end of any logical filtering. + if ($item->type === 'separator') + { + if ($noSeparator) + { + continue; + } - /** - * Active Node? - * - * @var boolean - */ - public $active = false; + $noSeparator = true; + } + else + { + $noSeparator = false; + } - /** - * Parent node - * - * @var JMenuNode - */ - protected $_parent = null; + // Ok we passed everything, load language at last only + if ($item->element) + { + $language->load($item->element . '.sys', JPATH_ADMINISTRATOR, null, false, true) || + $language->load($item->element . '.sys', JPATH_ADMINISTRATOR . '/components/' . $item->element, null, false, true); + } - /** - * Array of Children - * - * @var array - */ - protected $_children = array(); + if ($item->type === 'separator' && $item->params->get('text_separator') == 0) + { + $item->title = ''; + } - /** - * Constructor for the class. - * - * @param string $title The title of the node - * @param string $link The node link - * @param string $class The CSS class for the node - * @param boolean $active True if node is active, false otherwise - * @param string $target The link target - * @param string $titleicon The title icon for the node - */ - public function __construct($title, $link = null, $class = null, $active = false, $target = null, $titleicon = null) - { - $this->title = $titleicon ? $title . $titleicon : $title; - $this->link = JFilterOutput::ampReplace($link); - $this->class = $class; - $this->active = $active; + $item->text = JText::_($item->title); - $this->id = null; + $result[$i] = $item; + } - if (!empty($link) && $link !== '#') + // If last one was a separator remove it too. + if ($noSeparator && isset($i)) { - $uri = new JUri($link); - $params = $uri->getQuery(true); - $parts = array(); - - foreach ($params as $value) - { - $parts[] = str_replace(array('.', '_'), '-', $value); - } - - $this->id = implode('-', $parts); + unset($result[$i]); } - $this->target = $target; + return $result; } /** - * Add child to this node - * - * If the child already has a parent, the link is unset + * Load the menu items from a hierarchical list of items into the menu tree * - * @param JMenuNode &$child The child to be added + * @param stdClass[] $levels Menu items as a hierarchical list format * * @return void - */ - public function addChild(JMenuNode &$child) - { - $child->setParent($this); - } - - /** - * Set the parent of a this node * - * If the node already has a parent, the link is unset + * @since 3.8.0 * - * @param JMenuNode &$parent The JMenuNode for parent to be set or null - * - * @return void + * @deprecated 4.0 */ - public function setParent(JMenuNode &$parent = null) + protected function populateTree($levels) { - $hash = spl_object_hash($this); - - if (!is_null($this->_parent)) + foreach ($levels as $item) { - unset($this->_parent->_children[$hash]); - } + $class = $this->enabled ? $item->class : 'disabled'; - if (!is_null($parent)) - { - $parent->_children[$hash] = &$this; - } + if ($item->type === 'separator') + { + $this->tree->addChild(new Node\Separator($item->title)); + } + elseif ($item->type === 'heading') + { + // We already excluded heading type menu item with no children. + $this->tree->addChild(new Node\Heading($item->title, $class, null, $item->icon), $this->enabled); - $this->_parent = &$parent; - } + if ($this->enabled) + { + $this->populateTree($item->submenu); + $this->tree->getParent(); + } + } + elseif ($item->type === 'url') + { + $cNode = new Node\Url($item->title, $item->link, $item->browserNav, $class, null, $item->icon); + $this->tree->addChild($cNode, $this->enabled); - /** - * Get the children of this node - * - * @return array The children - */ - public function &getChildren() - { - return $this->_children; - } + if ($this->enabled) + { + $this->populateTree($item->submenu); + $this->tree->getParent(); + } + } + elseif ($item->type === 'component') + { + $cNode = new Node\Component($item->title, $item->element, $item->link, $item->browserNav, $class, null, $item->icon); + $this->tree->addChild($cNode, $this->enabled); - /** - * Get the parent of this node - * - * @return mixed JMenuNode object with the parent or null for no parent - */ - public function &getParent() - { - return $this->_parent; - } + if ($this->enabled) + { + $this->populateTree($item->submenu); + $this->tree->getParent(); + } + } + elseif ($item->type === 'container') + { + // We already excluded container type menu item with no children. + $this->tree->addChild(new Node\Container($item->title, $item->class, null, $item->icon), $this->enabled); - /** - * Test if this node has children - * - * @return boolean True if there are children - */ - public function hasChildren() - { - return (bool) count($this->_children); - } + if ($this->enabled) + { + $this->populateTree($item->submenu); - /** - * Test if this node has a parent - * - * @return boolean True if there is a parent - */ - public function hasParent() - { - return $this->getParent() != null; + // Add a separator between dynamic menu items and components menu items + if (count($item->submenu) && count($item->components)) + { + $this->tree->addChild(new Node\Separator); + } + + $this->populateTree($item->components); + + $this->tree->getParent(); + } + } + } } } diff --git a/administrator/modules/mod_menu/mod_menu.php b/administrator/modules/mod_menu/mod_menu.php index a625f99b0b11e..14eb444f7935c 100644 --- a/administrator/modules/mod_menu/mod_menu.php +++ b/administrator/modules/mod_menu/mod_menu.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_menu * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -12,6 +12,7 @@ use Joomla\Registry\Registry; // Include the module helper classes. +JLoader::register('MenusHelper', JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php'); JLoader::register('ModMenuHelper', __DIR__ . '/helper.php'); JLoader::register('JAdminCssMenu', __DIR__ . '/menu.php'); @@ -21,7 +22,7 @@ $input = JFactory::getApplication()->input; $enabled = !$input->getBool('hidemainmenu'); -$menu = new JAdminCssMenu; +$menu = new JAdminCssMenu($user); $menu->load($params, $enabled); // Render the module layout diff --git a/administrator/modules/mod_menu/mod_menu.xml b/administrator/modules/mod_menu/mod_menu.xml index 3721d11415ba6..8273ecc750e5b 100644 --- a/administrator/modules/mod_menu/mod_menu.xml +++ b/administrator/modules/mod_menu/mod_menu.xml @@ -3,7 +3,7 @@ mod_menu Joomla! Project March 2006 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -23,7 +23,7 @@ -
          +
          - + + + - - - - @@ -80,6 +78,8 @@ description="MOD_MENU_FIELD_SHOWHELP_DESC" class="btn-group btn-group-yesno" default="1" + filter="integer" + showon="menutype:*" > @@ -93,6 +93,26 @@ filter="url" size="30" default="" + showon="menutype:*" + validate="url" + /> +
          + +
          + + +
          diff --git a/administrator/modules/mod_menu/preset/disabled.php b/administrator/modules/mod_menu/preset/disabled.php deleted file mode 100644 index 91ac2b32ed174..0000000000000 --- a/administrator/modules/mod_menu/preset/disabled.php +++ /dev/null @@ -1,78 +0,0 @@ -addChild(new JMenuNode(JText::_('MOD_MENU_SYSTEM'), null, 'disabled')); - -/** - * Users Submenu - */ -if ($user->authorise('core.manage', 'com_users')) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS'), null, 'disabled')); -} - -/** - * Menus Submenu - */ -if ($user->authorise('core.manage', 'com_menus')) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_MENUS'), null, 'disabled')); -} - -/** - * Content Submenu - */ -if ($user->authorise('core.manage', 'com_content')) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_CONTENT'), null, 'disabled')); -} - -/** - * Components Submenu - */ - -// Get the authorised components and sub-menus. -$components = ModMenuHelper::getComponents(true); - -// Check if there are any components, otherwise, don't display the components menu item -if ($components) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COMPONENTS'), null, 'disabled')); -} - -/** - * Extensions Submenu - */ -$im = $user->authorise('core.manage', 'com_installer'); -$mm = $user->authorise('core.manage', 'com_modules'); -$pm = $user->authorise('core.manage', 'com_plugins'); -$tm = $user->authorise('core.manage', 'com_templates'); -$lm = $user->authorise('core.manage', 'com_languages'); - -if ($im || $mm || $pm || $tm || $lm) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_EXTENSIONS_EXTENSIONS'), null, 'disabled')); -} - -/** - * Help Submenu - */ -if ($params->get('showhelp', 1)) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP'), null, 'disabled')); -} diff --git a/administrator/modules/mod_menu/preset/enabled.php b/administrator/modules/mod_menu/preset/enabled.php deleted file mode 100644 index 610c4e1a50805..0000000000000 --- a/administrator/modules/mod_menu/preset/enabled.php +++ /dev/null @@ -1,450 +0,0 @@ -get('recovery', 0); -$shownew = (boolean) $params->get('shownew', 1); -$showhelp = (boolean) $params->get('showhelp', 1); -$user = JFactory::getUser(); -$lang = JFactory::getLanguage(); -$rootClass = $recovery ? 'class:' : null; - -// Is com_fields installed and enabled? -$comFieldsEnabled = JComponentHelper::isInstalled('com_fields') && JComponentHelper::isEnabled('com_fields'); - -/** - * Site Submenu - */ -$this->addChild(new JMenuNode(JText::_('MOD_MENU_SYSTEM'), '#', $rootClass), true); -$this->addChild(new JMenuNode(JText::_('MOD_MENU_CONTROL_PANEL'), 'index.php', 'class:cpanel')); - -if ($user->authorise('core.admin')) -{ - $this->addSeparator(); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_CONFIGURATION'), 'index.php?option=com_config', 'class:config')); -} - -if ($user->authorise('core.manage', 'com_checkin')) -{ - $this->addSeparator(); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_GLOBAL_CHECKIN'), 'index.php?option=com_checkin', 'class:checkin')); -} - -if ($user->authorise('core.manage', 'com_cache')) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_CLEAR_CACHE'), 'index.php?option=com_cache', 'class:clear')); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_PURGE_EXPIRED_CACHE'), 'index.php?option=com_cache&view=purge', 'class:purge')); -} - -if ($user->authorise('core.admin')) -{ - $this->addSeparator(); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_SYSTEM_INFORMATION'), 'index.php?option=com_admin&view=sysinfo', 'class:info')); -} - -$this->getParent(); - -/** - * Users Submenu - */ -if ($user->authorise('core.manage', 'com_users')) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS_USERS'), '#', $rootClass), true); - $createUser = $shownew && $user->authorise('core.create', 'com_users'); - $createGrp = $user->authorise('core.admin', 'com_users'); - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS_USER_MANAGER'), 'index.php?option=com_users&view=users', 'class:user'), $createUser); - - if ($createUser) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS_ADD_USER'), 'index.php?option=com_users&task=user.add', 'class:newarticle')); - $this->getParent(); - } - - if ($createGrp) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS_GROUPS'), 'index.php?option=com_users&view=groups', 'class:groups'), $createUser); - - if ($createUser) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS_ADD_GROUP'), 'index.php?option=com_users&task=group.add', 'class:newarticle')); - $this->getParent(); - } - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS_LEVELS'), 'index.php?option=com_users&view=levels', 'class:levels'), $createUser); - - if ($createUser) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS_ADD_LEVEL'), 'index.php?option=com_users&task=level.add', 'class:newarticle')); - $this->getParent(); - } - } - - if ($comFieldsEnabled && JComponentHelper::getParams('com_users')->get('custom_fields_enable', '1')) - { - $this->addSeparator(); - $this->addChild( - new JMenuNode( - JText::_('MOD_MENU_FIELDS'), 'index.php?option=com_fields&context=com_users.user', 'class:fields') - ); - - $this->addChild( - new JMenuNode( - JText::_('MOD_MENU_FIELDS_GROUP'), 'index.php?option=com_fields&view=groups&context=com_users.user', 'class:category') - ); - } - - $this->addSeparator(); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS_NOTES'), 'index.php?option=com_users&view=notes', 'class:user-note'), $createUser); - - if ($createUser) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_USERS_ADD_NOTE'), 'index.php?option=com_users&task=note.add', 'class:newarticle')); - $this->getParent(); - } - - $this->addChild( - new JMenuNode( - JText::_('MOD_MENU_COM_USERS_NOTE_CATEGORIES'), 'index.php?option=com_categories&view=categories&extension=com_users', 'class:category'), - $createUser - ); - - if ($createUser) - { - $this->addChild( - new JMenuNode( - JText::_('MOD_MENU_COM_CONTENT_NEW_CATEGORY'), 'index.php?option=com_categories&task=category.add&extension=com_users', - 'class:newarticle' - ) - ); - - $this->getParent(); - } - - if (JFactory::getApplication()->get('massmailoff') != 1) - { - $this->addSeparator(); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_MASS_MAIL_USERS'), 'index.php?option=com_users&view=mail', 'class:massmail')); - } - - $this->getParent(); -} - -/** - * Menus Submenu - */ -if ($user->authorise('core.manage', 'com_menus')) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_MENUS'), '#', $rootClass), true); - $createMenu = $shownew && $user->authorise('core.create', 'com_menus'); - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_MENU_MANAGER'), 'index.php?option=com_menus&view=menus', 'class:menumgr'), $createMenu); - - if ($createMenu) - { - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_MENU_MANAGER_NEW_MENU'), 'index.php?option=com_menus&view=menu&layout=edit', 'class:newarticle') - ); - $this->getParent(); - } - - $this->addSeparator(); - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_MENUS_ALL_ITEMS'), 'index.php?option=com_menus&view=items&menutype=', 'class:allmenu')); - $this->addSeparator(JText::_('JSITE')); - - // Menu Types - $menuTypes = ModMenuHelper::getMenus(); - $menuTypes = ArrayHelper::sortObjects($menuTypes, isset($menuTypes[0]->client_id) ? array('client_id', 'title') : 'title', 1, false); - - foreach ($menuTypes as $mti => $menuType) - { - if (!$user->authorise('core.manage', 'com_menus.menu.' . (int) $menuType->id)) - { - continue; - } - - $alt = '*' . $menuType->sef . '*'; - - if ($menuType->home == 0) - { - $titleicon = ''; - } - elseif ($menuType->home == 1 && $menuType->language == '*') - { - $titleicon = ' '; - } - elseif ($menuType->home > 1) - { - $titleicon = ' ' - . JHtml::_('image', 'mod_languages/icon-16-language.png', $menuType->home, array('title' => JText::_('MOD_MENU_HOME_MULTIPLE')), true) - . ''; - } - elseif ($menuType->image && JHtml::_('image', 'mod_languages/' . $menuType->image . '.gif', null, null, true, true)) - { - $titleicon = ' ' . - JHtml::_('image', 'mod_languages/' . $menuType->image . '.gif', $alt, array('title' => $menuType->title_native), true) . ''; - } - else - { - $titleicon = ' ' . $menuType->sef . ''; - } - - if (isset($menuTypes[$mti - 1], $menuType->client_id) && $menuTypes[$mti - 1]->client_id != $menuType->client_id) - { - $this->addSeparator(JText::_('JADMINISTRATOR')); - } - - $this->addChild( - new JMenuNode( - $menuType->title, 'index.php?option=com_menus&view=items&menutype=' . $menuType->menutype, 'class:menu', null, null, $titleicon - ), - $user->authorise('core.create', 'com_menus.menu.' . (int) $menuType->id) - ); - - if ($user->authorise('core.create', 'com_menus.menu.' . (int) $menuType->id)) - { - $this->addChild( - new JMenuNode( - JText::_('MOD_MENU_MENU_MANAGER_NEW_MENU_ITEM'), - 'index.php?option=com_menus&view=item&layout=edit&menutype=' . $menuType->menutype, 'class:newarticle' - ) - ); - - $this->getParent(); - } - } - - $this->getParent(); -} - -/** - * Content Submenu - */ -if ($user->authorise('core.manage', 'com_content')) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_CONTENT'), '#', $rootClass), true); - $createContent = $shownew && $user->authorise('core.create', 'com_content'); - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_CONTENT_ARTICLE_MANAGER'), 'index.php?option=com_content', 'class:article'), $createContent); - - if ($createContent) - { - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_COM_CONTENT_NEW_ARTICLE'), 'index.php?option=com_content&task=article.add', 'class:newarticle') - ); - $this->getParent(); - } - - $this->addChild( - new JMenuNode( - JText::_('MOD_MENU_COM_CONTENT_CATEGORY_MANAGER'), 'index.php?option=com_categories&extension=com_content', 'class:category' - ), - $createContent - ); - - if ($createContent) - { - $this->addChild( - new JMenuNode( - JText::_('MOD_MENU_COM_CONTENT_NEW_CATEGORY'), - 'index.php?option=com_categories&task=category.add&extension=com_content', 'class:newarticle' - ) - ); - $this->getParent(); - } - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COM_CONTENT_FEATURED'), 'index.php?option=com_content&view=featured', 'class:featured')); - - if ($comFieldsEnabled && JComponentHelper::getParams('com_content')->get('custom_fields_enable', '1')) - { - $this->addSeparator(); - $this->addChild( - new JMenuNode( - JText::_('MOD_MENU_FIELDS'), 'index.php?option=com_fields&context=com_content.article', 'class:fields') - ); - - $this->addChild( - new JMenuNode( - JText::_('MOD_MENU_FIELDS_GROUP'), 'index.php?option=com_fields&view=groups&context=com_content.article', 'class:category') - ); - } - - if ($user->authorise('core.manage', 'com_media')) - { - $this->addSeparator(); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_MEDIA_MANAGER'), 'index.php?option=com_media', 'class:media')); - } - - $this->getParent(); -} - -/** - * Components Submenu - */ - -// Get the authorised components and sub-menus. -$components = ModMenuHelper::getComponents(true); - -// Check if there are any components, otherwise, don't render the menu -if ($components) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_COMPONENTS'), '#', $rootClass), true); - - foreach ($components as &$component) - { - if (!empty($component->submenu)) - { - // This component has a db driven submenu. - $this->addChild(new JMenuNode($component->text, $component->link, $component->img), true); - - foreach ($component->submenu as $sub) - { - $this->addChild(new JMenuNode($sub->text, $sub->link, $sub->img)); - } - - $this->getParent(); - } - else - { - $this->addChild(new JMenuNode($component->text, $component->link, $component->img)); - } - } - - $this->getParent(); -} - -/** - * Extensions Submenu - */ -$im = $user->authorise('core.manage', 'com_installer'); -$mm = $user->authorise('core.manage', 'com_modules'); -$pm = $user->authorise('core.manage', 'com_plugins'); -$tm = $user->authorise('core.manage', 'com_templates'); -$lm = $user->authorise('core.manage', 'com_languages'); - -if ($im || $mm || $pm || $tm || $lm) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_EXTENSIONS_EXTENSIONS'), '#', $rootClass), true); - - if ($im) - { - $cls = 'class:install'; - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_EXTENSIONS_EXTENSION_MANAGER'), 'index.php?option=com_installer', $cls), $im); - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_INSTALLER_SUBMENU_INSTALL'), 'index.php?option=com_installer', $cls)); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_INSTALLER_SUBMENU_UPDATE'), 'index.php?option=com_installer&view=update', $cls)); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_INSTALLER_SUBMENU_MANAGE'), 'index.php?option=com_installer&view=manage', $cls)); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_INSTALLER_SUBMENU_DISCOVER'), 'index.php?option=com_installer&view=discover', $cls)); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_INSTALLER_SUBMENU_DATABASE'), 'index.php?option=com_installer&view=database', $cls)); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_INSTALLER_SUBMENU_WARNINGS'), 'index.php?option=com_installer&view=warnings', $cls)); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_INSTALLER_SUBMENU_LANGUAGES'), 'index.php?option=com_installer&view=languages', $cls)); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_INSTALLER_SUBMENU_UPDATESITES'), 'index.php?option=com_installer&view=updatesites', $cls)); - $this->getParent(); - } - - if ($im && ($mm || $pm || $tm || $lm)) - { - $this->addSeparator(); - } - - if ($mm) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_EXTENSIONS_MODULE_MANAGER'), 'index.php?option=com_modules', 'class:module')); - } - - if ($pm) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_EXTENSIONS_PLUGIN_MANAGER'), 'index.php?option=com_plugins', 'class:plugin')); - } - - if ($tm) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_EXTENSIONS_TEMPLATE_MANAGER'), 'index.php?option=com_templates', 'class:themes'), $tm); - - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_COM_TEMPLATES_SUBMENU_STYLES'), 'index.php?option=com_templates&view=styles', 'class:themes') - ); - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_COM_TEMPLATES_SUBMENU_TEMPLATES'), 'index.php?option=com_templates&view=templates', 'class:themes') - ); - $this->getParent(); - } - - if ($lm) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_EXTENSIONS_LANGUAGE_MANAGER'), 'index.php?option=com_languages', 'class:language'), $lm); - - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_COM_LANGUAGES_SUBMENU_INSTALLED'), 'index.php?option=com_languages&view=installed', 'class:language') - ); - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_COM_LANGUAGES_SUBMENU_CONTENT'), 'index.php?option=com_languages&view=languages', 'class:language') - ); - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_COM_LANGUAGES_SUBMENU_OVERRIDES'), 'index.php?option=com_languages&view=overrides', 'class:language') - ); - $this->getParent(); - } - - $this->getParent(); -} - -/** - * Help Submenu - */ -if ($showhelp == 1) -{ - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP'), '#', $rootClass), true); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_JOOMLA'), 'index.php?option=com_admin&view=help', 'class:help')); - $this->addSeparator(); - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_SUPPORT_OFFICIAL_FORUM'), 'https://forum.joomla.org', 'class:help-forum', false, '_blank')); - - if ($forum_url = $params->get('forum_url')) - { - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_SUPPORT_CUSTOM_FORUM'), $forum_url, 'class:help-forum', false, '_blank')); - } - - $debug = $lang->setDebug(false); - - if ($lang->hasKey('MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM_VALUE') && JText::_('MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM_VALUE') != '') - { - $forum_url = 'https://forum.joomla.org/viewforum.php?f=' . (int) JText::_('MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM_VALUE'); - $lang->setDebug($debug); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM'), $forum_url, 'class:help-forum', false, '_blank')); - } - - $lang->setDebug($debug); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_DOCUMENTATION'), 'https://docs.joomla.org', 'class:help-docs', false, '_blank')); - $this->addSeparator(); - - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_EXTENSIONS'), 'https://extensions.joomla.org', 'class:help-jed', false, '_blank')); - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_HELP_TRANSLATIONS'), 'https://community.joomla.org/translations.html', 'class:help-trans', false, '_blank') - ); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_RESOURCES'), 'https://resources.joomla.org', 'class:help-jrd', false, '_blank')); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_COMMUNITY'), 'https://community.joomla.org', 'class:help-community', false, '_blank')); - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_HELP_SECURITY'), 'https://developer.joomla.org/security-centre.html', 'class:help-security', false, '_blank') - ); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_DEVELOPER'), 'https://developer.joomla.org', 'class:help-dev', false, '_blank')); - $this->addChild(new JMenuNode(JText::_('MOD_MENU_HELP_XCHANGE'), 'https://joomla.stackexchange.com', 'class:help-dev', false, '_blank')); - $this->addChild( - new JMenuNode(JText::_('MOD_MENU_HELP_SHOP'), 'https://community.joomla.org/the-joomla-shop.html', 'class:help-shop', false, '_blank') - ); - $this->getParent(); -} diff --git a/administrator/modules/mod_menu/tmpl/default.php b/administrator/modules/mod_menu/tmpl/default.php index ff9edb4c9e2ef..74d11536f49e0 100644 --- a/administrator/modules/mod_menu/tmpl/default.php +++ b/administrator/modules/mod_menu/tmpl/default.php @@ -3,12 +3,33 @@ * @package Joomla.Administrator * @subpackage mod_menu * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -$direction = JFactory::getDocument()->direction == 'rtl' ? 'pull-right' : ''; +$doc = JFactory::getDocument(); +$direction = $doc->direction == 'rtl' ? 'pull-right' : ''; +$class = $enabled ? 'nav ' . $direction : 'nav disabled ' . $direction; -$menu->renderMenu('menu', $enabled ? 'nav ' . $direction : 'nav disabled ' . $direction); +// Recurse through children of root node if they exist +$menuTree = $menu->getTree(); +$root = $menuTree->reset(); + +if ($root->hasChildren()) +{ + echo '\n"; + + echo ''; + + if ($css = $menuTree->getCss()) + { + $doc->addStyleDeclaration(implode("\n", $css)); + } +} diff --git a/administrator/modules/mod_menu/tmpl/default_submenu.php b/administrator/modules/mod_menu/tmpl/default_submenu.php new file mode 100644 index 0000000000000..25b4a660fe61a --- /dev/null +++ b/administrator/modules/mod_menu/tmpl/default_submenu.php @@ -0,0 +1,138 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ +use Joomla\CMS\Menu\Node\Separator; + +defined('_JEXEC') or die; + +/** + * ========================================================================================================= + * IMPORTANT: The scope of this layout file is the `JAdminCssMenu` object and NOT the module context. + * ========================================================================================================= + */ +/** @var JAdminCssMenu $this */ +$current = $this->tree->getCurrent(); + +// Build the CSS class suffix +if (!$this->enabled) +{ + $class = ' class="disabled"'; +} +elseif ($current instanceOf Separator) +{ + $class = $current->get('title') ? ' class="menuitem-group"' : ' class="divider"'; +} +elseif ($current->hasChildren()) +{ + if ($current->getLevel() == 1) + { + $class = ' class="dropdown"'; + } + elseif ($current->get('class') == 'scrollable-menu') + { + $class = ' class="dropdown scrollable-menu"'; + } + else + { + $class = ' class="dropdown-submenu"'; + } +} +else +{ + $class = ''; +} + +// Print the item +echo ''; + +// Print a link if it exists +$linkClass = array(); +$dataToggle = ''; +$dropdownCaret = ''; + +if ($current->hasChildren()) +{ + $linkClass[] = 'dropdown-toggle'; + $dataToggle = ' data-toggle="dropdown"'; + + if ($current->getLevel() == 1) + { + $dropdownCaret = ' '; + } +} +else +{ + $linkClass[] = 'no-dropdown'; +} + +if (!($current instanceof Separator) && ($current->getLevel() > 1)) +{ + $iconClass = $this->tree->getIconClass(); + + if (trim($iconClass)) + { + $linkClass[] = $iconClass; + } +} + +// Implode out $linkClass for rendering +$linkClass = ' class="' . implode(' ', $linkClass) . '" '; + +// Links: component/url/heading/container +if ($link = $current->get('link')) +{ + $icon = $current->get('icon'); + + if ($icon) + { + if (substr($icon, 0, 6) == 'class:') + { + $icon = ''; + } + elseif (substr($icon, 0, 6) == 'image:') + { + $icon = JHtml::_('image', substr($icon, 6), null, null, true); + } + else + { + $icon = JHtml::_('image', $icon, null); + } + } + + $target = $current->get('target') ? 'target="' . $current->get('target') . '"' : ''; + + echo '' . + JText::_($current->get('title')) . $icon . $dropdownCaret . ''; +} +// Separator +else +{ + echo '' . JText::_($current->get('title')) . ''; +} + +// Recurse through children if they exist +if ($this->enabled && $current->hasChildren()) +{ + if ($current->getLevel() > 1) + { + $id = $current->get('id') ? ' id="menu-' . strtolower($current->get('id')) . '"' : ''; + + echo '' . "\n"; + } + else + { + echo '\n"; +} + +echo "\n"; diff --git a/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.ini b/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.ini index e3d994d75f03f..81b81e203963a 100644 --- a/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.ini +++ b/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.ini @@ -1,6 +1,6 @@ ; Joomla! Project -; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; (C) 2011 Open Source Matters, Inc. +; License GNU General Public License version 2 or later; see LICENSE.txt ; Note : All ini files need to be saved as UTF-8 MOD_MULTILANGSTATUS="Multilanguage Status" diff --git a/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.sys.ini b/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.sys.ini index e3d994d75f03f..81b81e203963a 100644 --- a/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.sys.ini +++ b/administrator/modules/mod_multilangstatus/language/en-GB/en-GB.mod_multilangstatus.sys.ini @@ -1,6 +1,6 @@ ; Joomla! Project -; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; (C) 2011 Open Source Matters, Inc. +; License GNU General Public License version 2 or later; see LICENSE.txt ; Note : All ini files need to be saved as UTF-8 MOD_MULTILANGSTATUS="Multilanguage Status" diff --git a/administrator/modules/mod_multilangstatus/mod_multilangstatus.php b/administrator/modules/mod_multilangstatus/mod_multilangstatus.php index 4a1eb242e2d19..0ad05fcd2d039 100644 --- a/administrator/modules/mod_multilangstatus/mod_multilangstatus.php +++ b/administrator/modules/mod_multilangstatus/mod_multilangstatus.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_multilangstatus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_multilangstatus/mod_multilangstatus.xml b/administrator/modules/mod_multilangstatus/mod_multilangstatus.xml index 20942743c3df8..727357da2ea43 100644 --- a/administrator/modules/mod_multilangstatus/mod_multilangstatus.xml +++ b/administrator/modules/mod_multilangstatus/mod_multilangstatus.xml @@ -3,7 +3,7 @@ mod_multilangstatus Joomla! Project September 2011 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2011 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -34,13 +34,15 @@ type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" />
          diff --git a/administrator/modules/mod_multilangstatus/tmpl/default.php b/administrator/modules/mod_multilangstatus/tmpl/default.php index df18d6900f94e..5fb7072e2039d 100644 --- a/administrator/modules/mod_multilangstatus/tmpl/default.php +++ b/administrator/modules/mod_multilangstatus/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_multilangstatus * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2011 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -42,7 +42,7 @@ 'width' => '800px', 'bodyHeight' => '70', 'modalWidth' => '80', - 'footer' => '', + 'footer' => '', ) ); diff --git a/administrator/modules/mod_popular/helper.php b/administrator/modules/mod_popular/helper.php index 2e07afcc38355..5ec6c978c8ea1 100644 --- a/administrator/modules/mod_popular/helper.php +++ b/administrator/modules/mod_popular/helper.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_popular * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -41,7 +41,7 @@ public static function getList(&$params) $model->setState('list.direction', 'DESC'); // Set Category Filter - $categoryId = $params->get('catid'); + $categoryId = $params->get('catid', null); if (is_numeric($categoryId)) { @@ -51,7 +51,7 @@ public static function getList(&$params) // Set User Filter. $userId = $user->get('id'); - switch ($params->get('user_id')) + switch ($params->get('user_id', '0')) { case 'by_me': $model->setState('filter.author_id', $userId); @@ -101,8 +101,8 @@ public static function getList(&$params) */ public static function getTitle($params) { - $who = $params->get('user_id'); - $catid = (int) $params->get('catid'); + $who = $params->get('user_id', '0'); + $catid = (int) $params->get('catid', null); if ($catid) { @@ -122,6 +122,10 @@ public static function getTitle($params) $title = ''; } - return JText::plural('MOD_POPULAR_TITLE' . ($catid ? '_CATEGORY' : '') . ($who != '0' ? "_$who" : ''), (int) $params->get('count'), $title); + return JText::plural( + 'MOD_POPULAR_TITLE' . ($catid ? '_CATEGORY' : '') . ($who != '0' ? "_$who" : ''), + (int) $params->get('count', 5), + $title + ); } } diff --git a/administrator/modules/mod_popular/mod_popular.php b/administrator/modules/mod_popular/mod_popular.php index 51a6f78751cc2..b8cba577585d4 100644 --- a/administrator/modules/mod_popular/mod_popular.php +++ b/administrator/modules/mod_popular/mod_popular.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_popular * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_popular/mod_popular.xml b/administrator/modules/mod_popular/mod_popular.xml index 0f8ac06db087a..c26a5999f2d67 100644 --- a/administrator/modules/mod_popular/mod_popular.xml +++ b/administrator/modules/mod_popular/mod_popular.xml @@ -3,7 +3,7 @@ mod_popular Joomla! Project July 2004 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -24,10 +24,11 @@
          @@ -60,7 +62,8 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" /> diff --git a/administrator/modules/mod_popular/tmpl/default.php b/administrator/modules/mod_popular/tmpl/default.php index e54f9b48a0e48..4803efdda287a 100644 --- a/administrator/modules/mod_popular/tmpl/default.php +++ b/administrator/modules/mod_popular/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_popular * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_privacy_dashboard/helper.php b/administrator/modules/mod_privacy_dashboard/helper.php new file mode 100644 index 0000000000000..45892d0076316 --- /dev/null +++ b/administrator/modules/mod_privacy_dashboard/helper.php @@ -0,0 +1,42 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Helper class for admin privacy dashboard module + * + * @since 3.9.0 + */ +class ModPrivacyDashboardHelper +{ + /** + * Method to retrieve information about the site privacy requests + * + * @return array Array containing site privacy requests + * + * @since 3.9.0 + */ + public static function getData() + { + JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_privacy/models', 'PrivacyModel'); + + /** @var PrivacyModelDashboard $model */ + $model = JModelLegacy::getInstance('Dashboard', 'PrivacyModel'); + + try + { + return $model->getRequestCounts(); + } + catch (JDatabaseException $e) + { + return array(); + } + } +} diff --git a/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.php b/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.php new file mode 100644 index 0000000000000..282480ef5b6d6 --- /dev/null +++ b/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.php @@ -0,0 +1,30 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +// Only super user can view this data +if (!JFactory::getUser()->authorise('core.admin')) +{ + return; +} + +// Load the privacy component language file. +$lang = JFactory::getLanguage(); +$lang->load('com_privacy', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('com_privacy', JPATH_ADMINISTRATOR . '/components/com_privacy', null, false, true); + +JHtml::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_privacy/helpers/html'); + +JLoader::register('ModPrivacyDashboardHelper', __DIR__ . '/helper.php'); + +$list = ModPrivacyDashboardHelper::getData(); +$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8'); + +require JModuleHelper::getLayoutPath('mod_privacy_dashboard', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.xml b/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.xml new file mode 100644 index 0000000000000..c3694c4ae833c --- /dev/null +++ b/administrator/modules/mod_privacy_dashboard/mod_privacy_dashboard.xml @@ -0,0 +1,74 @@ + + + mod_privacy_dashboard + Joomla! Project + June 2018 + (C) 2018 Open Source Matters, Inc. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.9.0 + MOD_PRIVACY_DASHBOARD_XML_DESCRIPTION + + mod_privacy_dashboard.php + tmpl + helper.php + + + en-GB.mod_privacy_dashboard.ini + en-GB.mod_privacy_dashboard.sys.ini + + + + +
          +
          +
          + + + + + + + + + + + + + + +
          +
          +
          +
          diff --git a/administrator/modules/mod_privacy_dashboard/tmpl/default.php b/administrator/modules/mod_privacy_dashboard/tmpl/default.php new file mode 100644 index 0000000000000..2441672651194 --- /dev/null +++ b/administrator/modules/mod_privacy_dashboard/tmpl/default.php @@ -0,0 +1,51 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +JHtml::_('bootstrap.tooltip'); + +$totalRequests = 0; +$activeRequests = 0; + +?> +
          + +
          +
          +
          +
          +
          + +
          + +
          status); ?>
          +
          count; ?>
          +
          + status, array(0, 1))) : ?> + count; ?> + + count; ?> + +
          +
          +
          +
          + +
          +
          +
          +
          +
          + +
          diff --git a/administrator/modules/mod_quickicon/helper.php b/administrator/modules/mod_quickicon/helper.php index 72fbf3f930251..371ff40b723a3 100644 --- a/administrator/modules/mod_quickicon/helper.php +++ b/administrator/modules/mod_quickicon/helper.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_quickicon * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_quickicon/mod_quickicon.php b/administrator/modules/mod_quickicon/mod_quickicon.php index 49b04a99f4b85..74094f169a0f3 100644 --- a/administrator/modules/mod_quickicon/mod_quickicon.php +++ b/administrator/modules/mod_quickicon/mod_quickicon.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_quickicon * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_quickicon/mod_quickicon.xml b/administrator/modules/mod_quickicon/mod_quickicon.xml index 096ac7ccbe0e2..84eaa0b9a8200 100644 --- a/administrator/modules/mod_quickicon/mod_quickicon.xml +++ b/administrator/modules/mod_quickicon/mod_quickicon.xml @@ -2,8 +2,8 @@ mod_quickicon Joomla! Project - Nov 2005 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + November 2005 + (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -22,12 +22,12 @@
          -
          @@ -36,6 +36,7 @@ type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" /> @@ -59,10 +61,11 @@
          diff --git a/administrator/modules/mod_quickicon/tmpl/default.php b/administrator/modules/mod_quickicon/tmpl/default.php index c4455aa0cc982..35ccd9e15abee 100644 --- a/administrator/modules/mod_quickicon/tmpl/default.php +++ b/administrator/modules/mod_quickicon/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_quickicon * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_sampledata/helper.php b/administrator/modules/mod_sampledata/helper.php new file mode 100644 index 0000000000000..7b2162faff51a --- /dev/null +++ b/administrator/modules/mod_sampledata/helper.php @@ -0,0 +1,34 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +/** + * Helper for mod_sampledata + * + * @since 3.8.0 + */ +abstract class ModSampledataHelper +{ + /** + * Get a list of sampledata. + * + * @return mixed An array of sampledata, or false on error. + * + * @since 3.8.0 + */ + public static function getList() + { + JPluginHelper::importPlugin('sampledata'); + $dispatcher = JEventDispatcher::getInstance(); + $data = $dispatcher->trigger('onSampledataGetOverview', array('test', 'foo')); + + return $data; + } +} diff --git a/administrator/modules/mod_sampledata/mod_sampledata.php b/administrator/modules/mod_sampledata/mod_sampledata.php new file mode 100644 index 0000000000000..4950e78bde522 --- /dev/null +++ b/administrator/modules/mod_sampledata/mod_sampledata.php @@ -0,0 +1,20 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +// Include dependencies. +JLoader::register('ModSampledataHelper', __DIR__ . '/helper.php'); + +$items = ModSampledataHelper::getList(); + +// Filter out empty entries +$items = array_filter($items); + +require JModuleHelper::getLayoutPath('mod_sampledata', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_sampledata/mod_sampledata.xml b/administrator/modules/mod_sampledata/mod_sampledata.xml new file mode 100644 index 0000000000000..f892667a504be --- /dev/null +++ b/administrator/modules/mod_sampledata/mod_sampledata.xml @@ -0,0 +1,38 @@ + + + mod_sampledata + Joomla! Project + July 2017 + (C) 2017 Open Source Matters, Inc. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 3.8.0 + MOD_SAMPLEDATA_XML_DESCRIPTION + + mod_sampledata.php + helper.php + tmpl + + + js + + + en-GB.mod_sampledata.ini + en-GB.mod_sampledata.sys.ini + + + + +
          + +
          +
          +
          +
          diff --git a/administrator/modules/mod_sampledata/tmpl/default.php b/administrator/modules/mod_sampledata/tmpl/default.php new file mode 100644 index 0000000000000..ab0db3c67da7a --- /dev/null +++ b/administrator/modules/mod_sampledata/tmpl/default.php @@ -0,0 +1,59 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Session\Session; + +JHtml::_('jquery.framework'); +JHtml::_('bootstrap.tooltip'); +JHtml::_('script', 'mod_sampledata/sampledata-process.js', false, true); + +JText::script('MOD_SAMPLEDATA_CONFIRM_START'); +JText::script('MOD_SAMPLEDATA_ITEM_ALREADY_PROCESSED'); +JText::script('MOD_SAMPLEDATA_INVALID_RESPONSE'); + +JFactory::getDocument()->addScriptDeclaration(' + var modSampledataUrl = "index.php?option=com_ajax&format=json&group=sampledata&' . Session::getFormToken() . '=1", + modSampledataIconProgress = "' . JUri::root(true) . '/media/jui/images/ajax-loader.gif"; +'); +?> +
          + +
          + $item) : ?> +
          + +
          + + description; ?> + +
          +
          + +
          + +
          + +
          +
            +
            + +
            + +
            + +
            diff --git a/administrator/modules/mod_stats_admin/helper.php b/administrator/modules/mod_stats_admin/helper.php index 37b310bf96dc7..549755d5b5684 100644 --- a/administrator/modules/mod_stats_admin/helper.php +++ b/administrator/modules/mod_stats_admin/helper.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_stats_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -32,10 +32,10 @@ public static function getStats(&$params) $rows = array(); $query = $db->getQuery(true); - $serverinfo = $params->get('serverinfo'); - $siteinfo = $params->get('siteinfo'); - $counter = $params->get('counter'); - $increase = $params->get('increase'); + $serverinfo = $params->get('serverinfo', 0); + $siteinfo = $params->get('siteinfo', 0); + $counter = $params->get('counter', 0); + $increase = $params->get('increase', 0); $i = 0; @@ -83,6 +83,7 @@ public static function getStats(&$params) $query->select('COUNT(id) AS count_users') ->from('#__users'); $db->setQuery($query); + try { $users = $db->loadResult(); @@ -97,6 +98,7 @@ public static function getStats(&$params) ->from('#__content') ->where('state = 1'); $db->setQuery($query); + try { $items = $db->loadResult(); @@ -112,6 +114,7 @@ public static function getStats(&$params) $rows[$i]->title = JText::_('MOD_STATS_USERS'); $rows[$i]->icon = 'users'; $rows[$i]->data = $users; + $rows[$i]->link = JRoute::_('index.php?option=com_users'); $i++; } @@ -121,6 +124,7 @@ public static function getStats(&$params) $rows[$i]->title = JText::_('MOD_STATS_ARTICLES'); $rows[$i]->icon = 'file'; $rows[$i]->data = $items; + $rows[$i]->link = JRoute::_('index.php?option=com_content&view=articles&filter[published]=1'); $i++; } } @@ -169,6 +173,7 @@ public static function getStats(&$params) $rows[$i]->title = $row['title']; $rows[$i]->icon = isset($row['icon']) ? $row['icon'] : 'info'; $rows[$i]->data = $row['data']; + $rows[$i]->link = isset($row['link']) ? $row['link'] : null; $i++; } } diff --git a/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.ini b/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.ini index 8fd1335559328..e089cfd1c25fb 100644 --- a/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.ini +++ b/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.ini @@ -1,6 +1,6 @@ ; Joomla! Project -; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; (C) 2012 Open Source Matters, Inc. +; License GNU General Public License version 2 or later; see LICENSE.txt ; Note : All ini files need to be saved as UTF-8 MOD_STATS_ADMIN="Statistics" @@ -21,4 +21,4 @@ MOD_STATS_PHP="PHP" MOD_STATS_TIME="Time" MOD_STATS_USERS="Users" MOD_STATS_WEBLINKS="Web Links" -MOD_STATS_XML_DESCRIPTION="The Statistics Module shows information about your server installation together with statistics on the website users, number of Articles in your database and the number of Web links you provide." +MOD_STATS_XML_DESCRIPTION="The Statistics Module shows information about your server installation together with statistics on the website users and the number of Articles in your database." diff --git a/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.sys.ini b/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.sys.ini index 1d1bf87cfb7ff..90a9decaaceba 100644 --- a/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.sys.ini +++ b/administrator/modules/mod_stats_admin/language/en-GB.mod_stats_admin.sys.ini @@ -1,9 +1,9 @@ ; Joomla! Project -; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; (C) 2012 Open Source Matters, Inc. +; License GNU General Public License version 2 or later; see LICENSE.txt ; Note : All ini files need to be saved as UTF-8 MOD_STATS_ADMIN="Statistics" -MOD_STATS_XML_DESCRIPTION="The Statistics Module shows information about your server installation together with statistics on the website users, number of Articles in your database and the number of Web links you provide." +MOD_STATS_XML_DESCRIPTION="The Statistics Module shows information about your server installation together with statistics on the website users and the number of Articles in your database." MOD_STATS_LAYOUT_DEFAULT="Default" diff --git a/administrator/modules/mod_stats_admin/mod_stats_admin.php b/administrator/modules/mod_stats_admin/mod_stats_admin.php index a3949b3eb85d6..e47c4527f7804 100644 --- a/administrator/modules/mod_stats_admin/mod_stats_admin.php +++ b/administrator/modules/mod_stats_admin/mod_stats_admin.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_stats_admin * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -15,6 +15,6 @@ $serverinfo = $params->get('serverinfo'); $siteinfo = $params->get('siteinfo'); $list = ModStatsHelper::getStats($params); -$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8'); +$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8'); require JModuleHelper::getLayoutPath('mod_stats_admin', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_stats_admin/mod_stats_admin.xml b/administrator/modules/mod_stats_admin/mod_stats_admin.xml index c3e941965702f..02465fcb4ab53 100644 --- a/administrator/modules/mod_stats_admin/mod_stats_admin.xml +++ b/administrator/modules/mod_stats_admin/mod_stats_admin.xml @@ -3,7 +3,7 @@ mod_stats_admin Joomla! Project July 2004 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -30,6 +30,7 @@ description="MOD_STATS_FIELD_SERVERINFO_DESC" class="btn-group btn-group-yesno" default="0" + filter="integer" > @@ -42,6 +43,7 @@ description="MOD_STATS_FIELD_SITEINFO_DESC" class="btn-group btn-group-yesno" default="0" + filter="integer" > @@ -54,6 +56,7 @@ description="MOD_STATS_FIELD_COUNTER_DESC" class="btn-group btn-group-yesno" default="0" + filter="integer" > @@ -61,10 +64,11 @@
            @@ -72,7 +76,8 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" /> @@ -96,10 +102,11 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; + +JHtml::_('jquery.framework'); +JFactory::getDocument()->addScriptDeclaration(' + jQuery(document).ready(function($) { + $("a.js-revert").on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + + var activeTab = []; + activeTab.push("#" + e.target.href.split("#")[1]); + var path = window.location.pathname; + localStorage.removeItem(e.target.href.replace(/&return=[a-zA-Z0-9%]+/, "").replace(/&[a-zA-Z-_]+=[0-9]+/, "")); + localStorage.setItem(path + e.target.href.split("index.php")[1].split("#")[0], JSON.stringify(activeTab)); + return window.location.href = e.target.href.split("#")[0]; + }); + }); +'); ?> -
              +
              -
            • title; ?> data; ?>
            • +
              +
              + title; ?> +
              +
              + link)) : ?> + data; ?> + + data; ?> + +
              +
              -
            +
      diff --git a/administrator/modules/mod_status/mod_status.php b/administrator/modules/mod_status/mod_status.php index 302d1bee4e471..edc93fdfa3920 100644 --- a/administrator/modules/mod_status/mod_status.php +++ b/administrator/modules/mod_status/mod_status.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_status * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_status/mod_status.xml b/administrator/modules/mod_status/mod_status.xml index b6667fc555a6b..286b894a75f53 100644 --- a/administrator/modules/mod_status/mod_status.xml +++ b/administrator/modules/mod_status/mod_status.xml @@ -2,8 +2,8 @@ mod_status Joomla! Project - Feb 2006 - (C) 2005 - 2017 Open Source Matters. All rights reserved. + February 2006 + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -28,6 +28,7 @@ description="MOD_STATUS_FIELD_SHOW_VIEWSITE_DESC" class="btn-group btn-group-yesno" default="1" + filter="integer" > @@ -40,6 +41,7 @@ description="MOD_STATUS_FIELD_SHOW_VIEWADMIN_DESC" class="btn-group btn-group-yesno" default="0" + filter="integer" > @@ -52,6 +54,7 @@ description="MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_DESC" class="btn-group btn-group-yesno" default="1" + filter="integer" > @@ -64,6 +67,7 @@ description="MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_ADMIN_DESC" class="btn-group btn-group-yesno" default="1" + filter="integer" > @@ -76,6 +80,7 @@ description="MOD_STATUS_FIELD_SHOW_MESSAGES_DESC" class="btn-group btn-group-yesno" default="1" + filter="integer" > @@ -87,14 +92,16 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" />
      diff --git a/administrator/modules/mod_status/tmpl/default.php b/administrator/modules/mod_status/tmpl/default.php index 2ff61fa5f2b0b..db9145292fe1e 100644 --- a/administrator/modules/mod_status/tmpl/default.php +++ b/administrator/modules/mod_status/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_status * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2009 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_submenu/mod_submenu.php b/administrator/modules/mod_submenu/mod_submenu.php index 85b09a0cab9fd..7d8c1664d93f9 100644 --- a/administrator/modules/mod_submenu/mod_submenu.php +++ b/administrator/modules/mod_submenu/mod_submenu.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_submenu * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_submenu/mod_submenu.xml b/administrator/modules/mod_submenu/mod_submenu.xml index 218f38a45ccad..485bf07c9c17f 100644 --- a/administrator/modules/mod_submenu/mod_submenu.xml +++ b/administrator/modules/mod_submenu/mod_submenu.xml @@ -2,8 +2,8 @@ mod_submenu Joomla! Project - Feb 2006 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + February 2006 + (C) 2006 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -25,14 +25,15 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" />
      diff --git a/administrator/modules/mod_submenu/tmpl/default.php b/administrator/modules/mod_submenu/tmpl/default.php index b095a2a323efb..a3afe15305f33 100644 --- a/administrator/modules/mod_submenu/tmpl/default.php +++ b/administrator/modules/mod_submenu/tmpl/default.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_submenu * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_title/mod_title.php b/administrator/modules/mod_title/mod_title.php index a0e5f6fd1b8a8..31023e5af1898 100644 --- a/administrator/modules/mod_title/mod_title.php +++ b/administrator/modules/mod_title/mod_title.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_title * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2006 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_title/mod_title.xml b/administrator/modules/mod_title/mod_title.xml index 8254b45e2a82d..4ad929955ea33 100644 --- a/administrator/modules/mod_title/mod_title.xml +++ b/administrator/modules/mod_title/mod_title.xml @@ -2,8 +2,8 @@ mod_title Joomla! Project - Nov 2005 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + November 2005 + (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -25,7 +25,8 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" /> * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_toolbar/mod_toolbar.php b/administrator/modules/mod_toolbar/mod_toolbar.php index 7b733895f57ad..437a8e37e1c71 100644 --- a/administrator/modules/mod_toolbar/mod_toolbar.php +++ b/administrator/modules/mod_toolbar/mod_toolbar.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_toolbar * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2005 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_toolbar/mod_toolbar.xml b/administrator/modules/mod_toolbar/mod_toolbar.xml index d2709aaab466b..187c38512c2de 100644 --- a/administrator/modules/mod_toolbar/mod_toolbar.xml +++ b/administrator/modules/mod_toolbar/mod_toolbar.xml @@ -2,8 +2,8 @@ mod_toolbar Joomla! Project - Nov 2005 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + November 2005 + (C) 2005 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -26,6 +26,7 @@ type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" /> * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_version/helper.php b/administrator/modules/mod_version/helper.php index 9f673c7430379..39eafe7f3da01 100644 --- a/administrator/modules/mod_version/helper.php +++ b/administrator/modules/mod_version/helper.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_version * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -27,7 +27,7 @@ public static function getVersion(&$params) { $version = new JVersion; $versionText = $version->getShortVersion(); - $product = $params->get('product', 0); + $product = $params->get('product', 1); if ($params->get('format', 'short') === 'long') { diff --git a/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.ini b/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.ini index 51c512093986e..ae9e535f0140e 100644 --- a/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.ini +++ b/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.ini @@ -1,6 +1,6 @@ ; Joomla! Project -; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; (C) 2012 Open Source Matters, Inc. +; License GNU General Public License version 2 or later; see LICENSE.txt ; Note : All ini files need to be saved as UTF-8 MOD_VERSION="Joomla! Version Information" diff --git a/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.sys.ini b/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.sys.ini index 6906ac2884ceb..43507fc71fbe9 100644 --- a/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.sys.ini +++ b/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.sys.ini @@ -1,6 +1,6 @@ ; Joomla! Project -; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; (C) 2012 Open Source Matters, Inc. +; License GNU General Public License version 2 or later; see LICENSE.txt ; Note : All ini files need to be saved as UTF-8 MOD_VERSION="Joomla! Version Information" diff --git a/administrator/modules/mod_version/mod_version.php b/administrator/modules/mod_version/mod_version.php index d19366754c51a..67a8b83d161e3 100644 --- a/administrator/modules/mod_version/mod_version.php +++ b/administrator/modules/mod_version/mod_version.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage mod_version * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2012 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/modules/mod_version/mod_version.xml b/administrator/modules/mod_version/mod_version.xml index 0fbf06689e61a..9c17b79909993 100644 --- a/administrator/modules/mod_version/mod_version.xml +++ b/administrator/modules/mod_version/mod_version.xml @@ -3,7 +3,7 @@ mod_version Joomla! Project January 2012 - Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. + (C) 2012 Open Source Matters, Inc. GNU General Public License version 2 or later; see LICENSE.txt admin@joomla.org www.joomla.org @@ -41,6 +41,7 @@ description="MOD_VERSION_PRODUCT_DESC" class="btn-group btn-group-yesno" default="1" + filter="integer" > @@ -51,7 +52,8 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + description="JFIELD_ALT_MODULE_LAYOUT_DESC" + validate="moduleLayout" /> * @license GNU General Public License version 2 or later; see LICENSE.txt */ diff --git a/administrator/templates/hathor/component.php b/administrator/templates/hathor/component.php index c7ae7bf34d448..431dbc4734730 100644 --- a/administrator/templates/hathor/component.php +++ b/administrator/templates/hathor/component.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage Template.hathor * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -12,7 +12,7 @@ /** @var JDocumentHtml $this */ // Get additional language strings prefixed with TPL_HATHOR -// @todo: Do we realy need this? +// @todo: Do we really need this? $lang = JFactory::getLanguage(); $lang->load('tpl_hathor', JPATH_ADMINISTRATOR) || $lang->load('tpl_hathor', JPATH_ADMINISTRATOR . '/templates/hathor/language'); diff --git a/administrator/templates/hathor/cpanel.php b/administrator/templates/hathor/cpanel.php index 33b8b35a87619..37aa967f9f4cb 100644 --- a/administrator/templates/hathor/cpanel.php +++ b/administrator/templates/hathor/cpanel.php @@ -3,7 +3,7 @@ * @package Joomla.Administrator * @subpackage Template.hathor * - * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved. + * @copyright (C) 2010 Open Source Matters, Inc. * @license GNU General Public License version 2 or later; see LICENSE.txt */ @@ -91,7 +91,7 @@

      params->get('showSiteName') ? $app->get('sitename') . ' ' . JText::_('JADMINISTRATION') : JText::_('JADMINISTRATION'); ?>

      -
      +