diff --git a/.appveyor.yml b/.appveyor.yml index 60cee9472f7bf..681dfa94698e4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -5,9 +5,9 @@ clone_folder: C:\projects\joomla-cms ## Build matrix for lowest and highest possible targets environment: matrix: - - php_ver_target: 5.6 - php_ver_target: 7.0 - php_ver_target: 7.1 + - php_ver_target: 7.2 init: - SET PATH=C:\Program Files\OpenSSL;C:\tools\php;%PATH% @@ -24,11 +24,7 @@ services: install: - IF EXIST C:\tools\php (SET PHP=0) - 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" - } Else { + If ($env:PHP -eq "1") { appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php_ver_target | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') $VC = "vc14" $PHPBuild = "x64" @@ -38,16 +34,6 @@ install: # Get the MSSQL DLL's - ps: >- If ($env:PHP -eq "1") { - If ($env:php_ver_target -eq "5.6") { - $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.3.0" cd c:\tools\php\ext $source = "http://windows.php.net/downloads/pecl/releases/sqlsrv/$($DLLVersion)/php_sqlsrv-$($DLLVersion)-$($env:php_ver_target)-nts-vc14-x64.zip" @@ -61,7 +47,7 @@ install: #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 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 @@ -69,16 +55,13 @@ install: - IF %PHP%==1 echo extension=php_mbstring.dll >> php.ini - IF %PHP%==1 echo extension=php_fileinfo.dll >> php.ini - IF %PHP%==1 echo extension=php_gd2.dll >> php.ini + - ps: >- - If ($env:php_ver_target -eq "5.6") { - Add-Content php.ini "`nextension=php_sqlsrv_nts.dll" - Add-Content php.ini "`nextension=php_pdo_sqlsrv_nts.dll" - Add-Content php.ini "`n" - } Else { + If ($env:PHP -eq "1") { Add-Content php.ini "`nextension=php_sqlsrv.dll" Add-Content php.ini "`nextension=php_pdo_sqlsrv.dll" - Add-Content php.ini "`n" - } + Add-Content php.ini "`n"} + - IF %PHP%==1 echo extension=php_pgsql.dll >> php.ini - IF %PHP%==1 echo extension=php_pdo_pgsql.dll >> php.ini - IF %PHP%==1 echo extension=php_pdo_sqlite.dll >> php.ini @@ -90,7 +73,7 @@ install: # 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"} + $wincache = "2.0.0.8" cd c:\tools\php\ext $source = "http://windows.php.net/downloads/pecl/releases/wincache/$($wincache)/php_wincache-$($wincache)-$($env:php_ver_target)-nts-$($VC)-$($PHPBuild).zip" $destination = "c:\tools\php\ext\php_wincache-$($wincache)-$($env:php_ver_target)-nts-$($VC)-$($PHPBuild).zip" @@ -108,26 +91,21 @@ install: - appveyor-retry appveyor DownloadFile https://getcomposer.org/composer.phar - cd C:\projects\joomla-cms - appveyor-retry composer install --no-progress --profile - + - appveyor-retry composer update joomla/test-unit --no-progress --profile before_test: # Database setup for MySQL via PowerShell tools - > "C:\Program Files\MySQL\MySQL Server 5.7\bin\mysql" -u root -p"Password12!" -e "CREATE DATABASE IF NOT EXISTS joomla_ut;" - - > - "C:\Program Files\MySQL\MySQL Server 5.7\bin\mysql" -u root -p"Password12!" joomla_ut < tests\unit\schema\mysql.sql - # Database setup for PostgreSQL - SET PGUSER=postgres - SET PGPASSWORD=Password12! - PATH=C:\Program Files\PostgreSQL\9.4\bin\;%PATH% - createdb joomla_ut - - psql -d joomla_ut -a -f tests\unit\schema\postgresql.sql # Database setup for SQL Server - ps: $sqlInstance = "(local)\SQL2014" - ps: sqlcmd -b -E -S "$sqlInstance" -Q "CREATE DATABASE joomla_ut" - - ps: sqlcmd -S "$sqlInstance" -U "sa" -P "Password12!" -i $env:APPVEYOR_BUILD_FOLDER\tests\unit\schema\sqlsrv.sql test_script: - cd C:\projects\joomla-cms - - libraries/vendor/bin/phpunit -c appveyor-phpunit.xml + - libraries/vendor/bin/phpunit --configuration ./libraries/vendor/joomla/test-unit/phpunit.xml.dist diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000000000..afb89fa94bf60 --- /dev/null +++ b/.babelrc @@ -0,0 +1,15 @@ +{ + "presets": [ + [ + "env", + { + "modules": false, + "targets": { + "browsers": [ + "last 1 version" + ] + } + } + ] + ] +} diff --git a/.drone.yml b/.drone.yml index 85f368db19b48..894a40a62ba9f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -7,22 +7,84 @@ pipeline: image: joomlaprojects/docker-phpcs commands: - echo $(date) - - /root/.composer/vendor/bin/phpcs --report=full --extensions=php -p --standard=build/phpcs/Joomla . + - /root/.composer/vendor/bin/phpcs --report=full --extensions=php -p --encoding=utf-8 --standard=build/phpcs/Joomla . - echo $(date) + restore-cache: + image: drillster/drone-volume-cache + restore: true + mount: + - ./node_modules + - ./libraries/vendor + volumes: + - /tmp/cache:/cache + + prepare: + image: joomlaprojects/docker-tools:develop + commands: + - composer install --no-progress --no-suggest + # needed for unit testing + - composer update joomla/test-unit --no-progress --no-suggest + # needed for system testing + - composer update joomla/test-system --no-progress --no-suggest + - composer update joomla-projects/selenium-server-standalone --no-progress --no-suggest + - npm install --unsafe-perm + + rebuild-cache: + image: drillster/drone-volume-cache + rebuild: true + mount: + - ./node_modules + - ./libraries/vendor + volumes: + - /tmp/cache:/cache + + php70-unit: + group: unit + image: joomlaprojects/docker-php70:develop + commands: + - ./libraries/vendor/bin/phpunit --configuration ./libraries/vendor/joomla/test-unit/phpunit.xml.dist + + php71-unit: + group: unit + image: joomlaprojects/docker-php71:develop + commands: + - ./libraries/vendor/bin/phpunit --configuration ./libraries/vendor/joomla/test-unit/phpunit.xml.dist + + php72-unit: + group: unit + image: joomlaprojects/docker-php72:develop + commands: + - ./libraries/vendor/bin/phpunit --configuration ./libraries/vendor/joomla/test-unit/phpunit.xml.dist + javascript: - image: joomlaprojects/docker-systemtests:latest + image: joomlaprojects/docker-systemtests:develop 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) + - node_modules/karma/bin/karma start node_modules/joomla-javascript-tests/src/karma.conf.js --single-run + + system-tests: + image: joomlaprojects/docker-systemtests:develop + commands: + - bash libraries/vendor/joomla/test-system/src/drone-run.sh "$(pwd)" + +services: + mysql: + image: mysql:5.7 + environment: + MYSQL_USER: joomla_ut + MYSQL_PASSWORD: joomla_ut + MYSQL_ROOT_PASSWORD: joomla_ut + MYSQL_DATABASE: test_joomla + + memcached: + image: memcached:alpine + + redis: + image: redis:alpine + postgres: + image: postgres diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000000..912f193b079f3 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +# A list of files to ignore from linting +# TODO: Fix the webcomponents codestyle then also allow linting on them +*.js +!*.es6.js +*.vue diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000000..be8ee9e6d98c3 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,27 @@ +{ + // Extend the airbnb eslint config + "extends": "airbnb-base", + // ESLint will not look in parent folders for eslint configs + "root": true, + // An environment defines global variables that are predefined. + "env": { + "browser": true, + "es6": true, + "node": true + }, + // Additional global variables your script accesses during execution + "globals": { + "Joomla": true + }, + // Rule overrides + "rules": { + // Disable no-params-reassign for properties + "no-param-reassign": ["error", { "props": false }], + // Allow usage of dev-dependencies in js files in build directory + "import/no-extraneous-dependencies": ["error", {"devDependencies": ["build/**/*.js"]}], + // Allow strict mode (we are not dealing with modules) + "strict": [0], + // Disable alert rule till we have a CE in place + "no-alert": 0 + } +} diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000000..2ee7ddb5a203b --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,65 @@ +# 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/* @mbabker +components/com_finder/* @mbabker +modules/mod_finder/* @mbabker +plugins/content/finder/* @mbabker +plugins/finder/* @mbabker + +# Language strings +administrator/language/en-GB/* @brianteeman +installation/language/en-GB/* @brianteeman +language/en-GB/* @brianteeman +README.md @brianteeman +README.txt @brianteeman + +# CodeMirror +media/editors/codemirror/* @okonomiyaki3000 +plugins/editors/codemirror/* @okonomiyaki3000 + +# Statistics Server +plugins/system/stats/* @mbabker @wilsonge + +# Release Tools +build.xml @mbabker +build/build.php @mbabker @rdeutz @wilsonge +build/bump.php @mbabker @rdeutz @wilsonge +build/deleted_file_check.php @mbabker @rdeutz @wilsonge + +# Core/Extension Install/Update Tools +administrator/components/com_joomlaupdate/* @mbabker @rdeutz @wilsonge @zero-24 +libraries/src/Installer/* @mbabker @rdeutz @wilsonge @zero-24 +libraries/src/Updater/* @mbabker @rdeutz @wilsonge @zero-24 + +# Automated Testing +build/jenkins/* @mbabker @rdeutz +build/travis/* @mbabker @rdeutz +tests/codeception/* @rdeutz +tests/javascript/* @dgt41 @rdeutz +tests/unit/* @mbabker @rdeutz +.appveyor.yml @mbabker @rdeutz +.drone.yml @rdeutz +.hound.yml @mbabker +.travis.yml @mbabker @rdeutz +appveyor-phpunit.xml @mbabker @rdeutz +codeception.yml @rdeutz +karma.conf.js @dgt41 @rdeutz +phpunit.xml.dist @mbabker @rdeutz +RoboFile.dist.ini @rdeutz +RoboFile.php @rdeutz +travis-phpunit.xml @mbabker @rdeutz + +# Core JS +media/*/js/* @dgt41 + +# CSP Tooling +plugins/system/httpheaders/* @zero-24 +administrator/components/com_csp/* @zero-24 +components/com_csp/* @zero-24 diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index f716bd5f7e8e5..1f4c40264b859 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -1,8 +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://resources.joomla.org) (JRD). +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). diff --git a/.gitignore b/.gitignore index 90be3a9720be0..875e93f47524e 100644 --- a/.gitignore +++ b/.gitignore @@ -18,29 +18,59 @@ /configuration.php /.htaccess /web.config +/.php_cs /.php_cs.cache +/media + +# Template CSS files generated by NPM. +/administrator/templates/atum/css +/installation/template/css/template-rtl.min.css +/installation/template/css/template-rtl.css +/installation/template/css/template.min.css +/installation/template/css/template.css +/templates/cassiopeia/css # Test Related Files # /phpunit.xml +selenium.log +composer.phar +/test-install + + +# Vendor directory handeling +/libraries/vendor +!libraries/vendor/.gitkeep + +/media/vendor +!media/vendor/.gitkeep # Stubs file holding mapped classes /stubs.php -# Node modules # +# JS/CSS Build # node_modules/ +/build/assets_tmp +/scss-lint-report.xml + +# Removed in Joomla 4 # +administrator/templates/isis +administrator/templates/hathor +templates/beez3 +build/generatecss.php +media/jui/less + +# CSS map files # +.map # phpDocumentor Logs # phpdoc-* # Patch Tester # /administrator/components/com_patchtester -/administrator/templates/hathor/html/com_patchtester +/administrator/templates/atum/html/com_patchtester /components/com_patchtester /media/com_patchtester -# Install from Web plugin # -/plugins/installer/webinstaller - # Languages # administrator/language/* !administrator/language/en-GB @@ -64,124 +94,11 @@ Desktop.ini # Only apply this rule to the main repository's gitignore files !/.gitignore !/build/.gitignore -!/tests/unit/suites/libraries/joomla/archive/.gitignore -!/tests/unit/tmp/.gitignore - -# 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/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/*/docs -/libraries/vendor/joomla/*/Tests -/libraries/vendor/joomla/*/vendor -/libraries/vendor/joomla/*/.scrutinizer.yml -/libraries/vendor/joomla/*/.travis.yml -/libraries/vendor/joomla/*/CONTRIBUTING.md -/libraries/vendor/joomla/*/composer.json -/libraries/vendor/joomla/*/phpunit.xml.dist -/libraries/vendor/joomla/*/README.md -/libraries/vendor/joomla/session/Joomla/Session/.github -/libraries/vendor/joomla/session/Joomla/Session/_Tests -/libraries/vendor/joomla/session/Joomla/Session/build -/libraries/vendor/joomla/session/Joomla/Session/Tests -/libraries/vendor/joomla/session/Joomla/Session/CONTRIBUTING.md -/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/leafo/lessphp/docs -/libraries/vendor/leafo/lessphp/tests -/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/README.md -/libraries/vendor/paragonie/random_compat/.gitignore -/libraries/vendor/paragonie/random_compat/.scrutinizer.yml -/libraries/vendor/paragonie/random_compat/.travis.yml -/libraries/vendor/paragonie/random_compat/dist -/libraries/vendor/paragonie/random_compat/other -/libraries/vendor/paragonie/random_compat/CHANGELOG.md -/libraries/vendor/paragonie/random_compat/ERRATA.md -/libraries/vendor/paragonie/random_compat/RATIONALE.md -/libraries/vendor/paragonie/random_compat/README.md -/libraries/vendor/paragonie/random_compat/SECURITY.md -/libraries/vendor/paragonie/random_compat/build-phar.sh -/libraries/vendor/paragonie/random_compat/composer.json -/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/composer.json -/libraries/vendor/paragonie/sodium_compat/composer.lock -/libraries/vendor/paragonie/sodium_compat/phpunit.xml.dist -/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/.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/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/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-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-util/composer.json -/libraries/vendor/symfony/polyfill-util/README.md -/libraries/vendor/symfony/polyfill-util/TestListener.php -/libraries/vendor/symfony/yaml/Tests -/libraries/vendor/symfony/yaml/.gitignore -/libraries/vendor/symfony/yaml/CHANGELOG.md -/libraries/vendor/symfony/yaml/composer.json -/libraries/vendor/symfony/yaml/phpunit.xml.dist -/libraries/vendor/symfony/yaml/README.md -/libraries/vendor/simplepie/simplepie/demo -/libraries/vendor/simplepie/simplepie/tests -/libraries/vendor/simplepie/simplepie/README.markdown -/libraries/vendor/simplepie/simplepie/phpunit.xml.dist -/libraries/vendor/simplepie/simplepie/.gitignore -/libraries/vendor/simplepie/simplepie/.travis.yml -/libraries/vendor/simplepie/simplepie/compatibility_test -/libraries/vendor/simplepie/simplepie/build -/libraries/vendor/simplepie/simplepie/idn/ReadMe.txt -/libraries/vendor/simplepie/simplepie/composer.json - -# 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 +# Media Manager +/media/com_media/js/mediamanager.min.js.map +/media/com_media/css/mediamanager.min.css.map diff --git a/.hound.yml b/.hound.yml index 87a3326e2f952..40dd05d8358a3 100644 --- a/.hound.yml +++ b/.hound.yml @@ -1,12 +1,15 @@ -fail_on_violations: false +fail_on_violations: true scss: - enabled: false + config_file: scss-lint.yml -jshint: - enabled: false - eslint: + enabled: true + config_file: .eslintrc + ignore_file: .eslintignore + +# Disable hound default linters +jshint: enabled: false ruby: diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 597141e11be68..0000000000000 --- a/.php_cs +++ /dev/null @@ -1,65 +0,0 @@ -in(array(__DIR__ . '/libraries')) - ->files() - ->depth(0); - -$mainFinder = Symfony\CS\Finder\DefaultFinder::create() - ->in( - array( - __DIR__ . '/libraries/cms', - __DIR__ . '/libraries/joomla', - __DIR__ . '/libraries/legacy', - ) - ) - ->append($topFilesFinder); - -return Symfony\CS\Config\Config::create() - ->setUsingLinter(false) - ->setUsingCache(true) - ->level(Symfony\CS\FixerInterface::NONE_LEVEL) - ->fixers( - array( - // psr-1 - 'encoding', - // psr-2 - 'elseif', - 'eof_ending', - 'function_call_space', - 'line_after_namespace', - 'linefeed', - 'lowercase_constants', - 'lowercase_keywords', - 'method_argument_space', - 'multiple_use', - 'parenthesis', - 'single_line_after_imports', - 'trailing_spaces', - 'visibility', - // symfony - 'array_element_no_space_before_comma', - 'array_element_white_space_after_comma', - 'duplicate_semicolon', - 'empty_return', - 'extra_empty_lines', - 'function_typehint_space', - 'include', - 'join_function', - 'list_commas', - 'multiline_array_trailing_comma', - 'no_blank_lines_after_class_opening', - 'phpdoc_trim', - 'return', - 'single_array_no_trailing_comma', - 'single_blank_line_before_namespace', - 'spaces_cast', - 'unneeded_control_parentheses', - 'unused_use', - 'whitespacy_lines', - // contrib - 'concat_with_spaces', - 'long_array_syntax', - ) - ) - ->finder($mainFinder); diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 0000000000000..a3a9a4d8c828a --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,62 @@ +in(array(__DIR__ . '/libraries')) + ->files() + ->depth(0); + +$mainFinder = PhpCsFixer\Finder::create() + ->in( + array( + __DIR__ . '/libraries/cms', + __DIR__ . '/libraries/joomla', + ) + ) + ->append($topFilesFinder); + +return PhpCsFixer\Config::create() + ->setRiskyAllowed(true) + ->setIndent("\t") + ->setRules( + array( + // psr-1 + 'encoding' => true, + // psr-2 + 'elseif' => true, + 'single_blank_line_at_eof' => true, + 'no_spaces_after_function_name' => true, + 'blank_line_after_namespace' => true, + 'line_ending' => true, + 'lowercase_constants' => true, + 'lowercase_keywords' => true, + 'method_argument_space' => true, + 'single_import_per_statement' => true, + 'no_spaces_inside_parenthesis' => true, + 'single_line_after_imports' => true, + 'no_trailing_whitespace' => true, + 'visibility_required' => true, + // symfony + 'no_whitespace_before_comma_in_array' => true, + 'whitespace_after_comma_in_array' => true, + 'no_empty_statement' => true, + 'simplified_null_return' => true, + 'no_extra_consecutive_blank_lines' => true, + 'function_typehint_space' => true, + 'include' => true, + 'no_alias_functions' => true, + 'no_trailing_comma_in_list_call' => true, + 'trailing_comma_in_multiline_array' => true, + 'no_blank_lines_after_class_opening' => true, + 'phpdoc_trim' => true, + 'blank_line_before_return' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'single_blank_line_before_namespace' => true, + 'cast_spaces' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unused_imports' => true, + 'no_whitespace_in_blank_line' => true, + // contrib + 'concat_space' => ['spacing' => 'one'], + ) + ) + ->setFinder($mainFinder); diff --git a/.travis.yml b/.travis.yml index 070893c5e55d0..1f4feb5c9a4d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,51 +3,23 @@ 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_MEMCACHE="no" - - php: 7.1 - env: INSTALL_APCU="yes" INSTALL_MEMCACHE="no" - # Requires older Precise image - - php: 5.3 - env: INSTALL_APC="yes" - sudo: true - dist: precise - # The new Trusty image has issues with running APC, do not enable it here - - php: 5.4 - env: INSTALL_APC="no" - - php: 5.5 - env: INSTALL_APCU="yes" - - php: 5.6 - env: INSTALL_APCU="yes" - - php: 7.2 - env: INSTALL_APCU="yes" INSTALL_MEMCACHE="no" - php: nightly - env: INSTALL_APCU="yes" INSTALL_MEMCACHE="no" allow_failures: - - php: 7.2 - php: nightly -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 + # Abort travis execution if setup fails + - set -e + # Disable xdebug. + - phpenv config-rm xdebug.ini || echo "xdebug not available" + # Make sure all dev dependencies are installed, ignore platform requirements because Travis is missing the LDAP tooling on all new images + - composer install --ignore-platform-reqs script: - - if [[ $RUN_UNIT_TESTS == "yes" ]]; then libraries/vendor/bin/phpunit --configuration travisci-phpunit.xml; fi + - libraries/vendor/bin/phpunit --configuration ./libraries/vendor/joomla/test-unit/phpunit.xml.dist branches: except: diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000000000..77e149faa53a7 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'scss_lint', '~> 0.56.0' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000000000..3edd8cb391c48 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,25 @@ +GEM + remote: https://rubygems.org/ + specs: + ffi (1.9.25) + rake (12.3.1) + rb-fsevent (0.10.3) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + sass (3.5.7) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + scss_lint (0.56.0) + rake (>= 0.9, < 13) + sass (~> 3.5.3) + +PLATFORMS + ruby + +DEPENDENCIES + scss_lint (~> 0.56.0) + +BUNDLED WITH + 1.16.2 diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 5b7fd8f3ce9e2..0000000000000 --- a/Jenkinsfile +++ /dev/null @@ -1,75 +0,0 @@ -#!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 b0af7b464221d..962f48dc23a14 100644 --- a/README.md +++ b/README.md @@ -3,78 +3,56 @@ Joomla! CMS™ [![Analytics](https://ga-beacon.appspot.com/UA-544070-3/joomla-cm Build Status --------------------- -| Travis-CI | Drone-CI | AppVeyor | Jenkins | -| ------------- | ------------- | ------------- | ------------- | -| [![Build Status](https://travis-ci.org/joomla/joomla-cms.svg?branch=staging)](https://travis-ci.org/joomla/joomla-cms) | [![Build Status](http://213.160.72.75/api/badges/joomla/joomla-cms/status.svg)](http://213.160.72.75/joomla/joomla-cms) | [![Build status](https://ci.appveyor.com/api/projects/status/bpcxulw6nnxlv8kb/branch/staging?svg=true)](https://ci.appveyor.com/project/joomla/joomla-cms) | [![Build Status](http://build.joomla.org/job/cms/badge/icon)](http://build.joomla.org/job/cms/) | +| Travis-CI | Drone-CI | AppVeyor | +| ------------- | ------------- | ------------- | +| [![Build Status](https://travis-ci.org/joomla/joomla-cms.svg?branch=staging)](https://travis-ci.org/joomla/joomla-cms) | [![Build Status](http://213.160.72.75/api/badges/joomla/joomla-cms/status.svg)](http://213.160.72.75/joomla/joomla-cms) | [![Build status](https://ci.appveyor.com/api/projects/status/bpcxulw6nnxlv8kb/branch/staging?svg=true)](https://ci.appveyor.com/project/joomla/joomla-cms) | What is this? --------------------- -* This is a Joomla! 3.x installation/upgrade package. +* This is the source of Joomla! 4.x. * Joomla's [Official website](https://www.joomla.org). -* Joomla! 3.8 [version history](https://docs.joomla.org/Special:MyLanguage/Joomla_3.8_version_history). -* Detailed changes are in the [changelog](https://github.com/joomla/joomla-cms/commits/staging). +* Joomla! 4.0 [version history](https://docs.joomla.org/Special:MyLanguage/Joomla_4.0_version_history). +* Detailed changes are in the [changelog](https://github.com/joomla/joomla-cms/commits/4.0-dev). What is Joomla? --------------------- * [Joomla!](https://www.joomla.org/about-joomla.html) is a **Content Management System** (CMS) which enables you to build websites and powerful online applications. -* It is a simple and powerful web server application which requires a server with PHP and either MySQL, PostgreSQL or SQL Server to run. You can find [full technical requirements here](https://downloads.joomla.org/technical-requirements). +* It is a simple and powerful web server application which requires a server with PHP and either MySQL or PostgreSQL to run. You can find [full technical requirements here](https://downloads.joomla.org/technical-requirements). * Joomla! is **free and Open Source software** distributed under the GNU General Public License version 2 or later. -Is Joomla! for you? +Looking for an installable package? --------------------- -* 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). +Joomla is not installable out of the box from this repository, please use: +- For the latest stable package: https://downloads.joomla.org +- For a nightly package: https://developer.joomla.org/nightly-builds.html -How to find a Joomla! translation? +How to get a working installation from the source --------------------- -* Repository of [accredited language packs](https://community.joomla.org/translations.html). -* You can also [add languages](https://docs.joomla.org/Special:MyLanguage/J3.x:Setup_a_Multilingual_Site/Installing_New_Language) directly to your website via your Joomla! administration panel. -* Learn how to [setup a Multilingual Joomla! Site](https://docs.joomla.org/Special:MyLanguage/J3.x:Setup_a_Multilingual_Site) +For detailed instructions please visit https://docs.joomla.org/J4.x:Setting_Up_Your_Local_Environment -Learn Joomla! ---------------------- -* Read ['Getting Started with Joomla!'](https://docs.joomla.org/Special:MyLanguage/J3.x:Getting_Started_with_Joomla!) to learn the basics. -* Before installing, read the ['Beginners' Guide'](https://docs.joomla.org/Special:MyLanguage/Portal:Beginners). - -What are the benefits of Joomla? ---------------------- -* The functionality of a Joomla! website can be extended by installing extensions that you can create (or download) to suit your needs. -* There are many ready-made extensions that you can download and install. -* Check out the [Joomla! Extensions Directory (JED)](https://extensions.joomla.org). - -Is it easy to change the layout display? ---------------------- -* The layout is controlled by templates that you can edit. -* There are a lot of ready-made professional templates that you can download. -* Template management information is [available here](https://docs.joomla.org/Special:MyLanguage/Portal:Template_Management). - -Ready to install Joomla? ---------------------- -* 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. - -Updates are free! ---------------------- -* Always use the [latest version](https://downloads.joomla.org/latest). +You will need: +- PHP - basically the same as you need for running a Joomla Site, but you need the cli (command line interface) Version (see https://docs.joomla.org/Configuring_a_LAMPP_server_for_PHP_development) +- Composer - for managing Joomla's PHP Dependencies. For help installing composer please read the documentation at https://getcomposer.org/doc/00-intro.md +- Node.js - for compiling Joomla's Javascript and SASS files. For help installing Node.js please follow the instructions available on https://nodejs.org/en/ +- Git - for version management. Download from here https://git-scm.com/downloads (MacOS users can also use Brew and Linux users can use the built-in package manager, eg apt, yum, etc). -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). - -Do you already have a Joomla! site that isn't built with Joomla! 3.x? ---------------------- -* What's [new in Joomla! 3.x](https://www.joomla.org/3)? -* What are the [main differences between 2.5 and 3.x](https://docs.joomla.org/Special:MyLanguage/What_are_the_major_differences_between_Joomla!_2.5_and_3.x%3F)? -* How to [migrate from 2.5.x to 3.x](https://docs.joomla.org/Special:MyLanguage/Joomla_2.5_to_3.x_Step_by_Step_Migration). -* How to [migrate from 1.5.x to 3.x](https://docs.joomla.org/Special:MyLanguage/Joomla_1.5_to_3.x_Step_by_Step_Migration). +**Steps to setup the local environment:** +- Clone the repository: +```bash +git clone git@github.com:joomla/joomla-cms.git +``` +- Go to the joomla-cms folder: +```bash +cd joomla-cms +``` +- Install all the needed composer packages: +```bash +composer install +``` +- Install all the needed npm packages: +```bash +npm install +``` Do you want to improve Joomla? -------------------- diff --git a/README.txt b/README.txt index 6d93aedcc1e61..006fedcd41833 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 + * This is a Joomla! 4.x installation/upgrade package. * Joomla! Official site: https://www.joomla.org - * Joomla! 3.8 version history - https://docs.joomla.org/Special:MyLanguage/Joomla_3.8_version_history - * Detailed changes in the Changelog: https://github.com/joomla/joomla-cms/commits/staging + * Joomla! 4.0 version history - https://docs.joomla.org/Special:MyLanguage/Joomla_4.0_version_history + * Detailed changes in the Changelog: https://github.com/joomla/joomla-cms/commits/4.0-dev 2- What is Joomla? * Joomla! is a Content Management System (CMS) which enables you to build Web sites and powerful online applications. @@ -17,11 +17,11 @@ 4- How to find a Joomla! translation? * Repository of accredited language packs: https://community.joomla.org/translations.html - * You can also add languages directly to your website via your Joomla! administration panel: https://docs.joomla.org/Special:MyLanguage/J3.x:Setup_a_Multilingual_Site/Installing_New_Language - * Learn how to setup a Multilingual Joomla! Site: https://docs.joomla.org/Special:MyLanguage/J3.x:Setup_a_Multilingual_Site + * You can also add languages directly to your website via your Joomla! administration panel: https://docs.joomla.org/Special:MyLanguage/J4.x:Setup_a_Multilingual_Site/Installing_New_Language + * Learn how to setup a Multilingual Joomla! Site: https://docs.joomla.org/Special:MyLanguage/J4.x:Setup_a_Multilingual_Site 5- Learn Joomla! - * Read Getting Started with Joomla to find out the basics: https://docs.joomla.org/Special:MyLanguage/J3.x:Getting_Started_with_Joomla! + * Read Getting Started with Joomla to find out the basics: https://docs.joomla.org/Special:MyLanguage/J4.x:Getting_Started_with_Joomla! * Before installing, read the beginners guide: https://docs.joomla.org/Special:MyLanguage/Portal:Beginners 6- What are the benefits of Joomla? @@ -36,7 +36,7 @@ 8- Ready to install Joomla? * Check the minimum requirements here: https://downloads.joomla.org/technical-requirements - * How do you install Joomla - https://docs.joomla.org/Special:MyLanguage/J3.x:Installing_Joomla + * How do you install Joomla - https://docs.joomla.org/Special:MyLanguage/J4.x:Installing_Joomla * You could start your Joomla! experience building your site on a local test server. When ready it can be moved to an online hosting account of your choice. See the tutorial: https://docs.joomla.org/Special:MyLanguage/Installing_Joomla_locally @@ -52,9 +52,10 @@ * Post questions at our forums: https://forum.joomla.org * Joomla! Resources Directory (JRD): https://resources.joomla.org/ -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 - * What are the main differences from 2.5 to 3? https://docs.joomla.org/Special:MyLanguage/What_are_the_major_differences_between_Joomla!_2.5_and_3.x%3F +11- Do you already have a Joomla! site that's not built with Joomla! 4.x ? + * What's new in Joomla! 4.x: https://www.joomla.org/4 + * What are the main differences between 3.x and 4.x? https://docs.joomla.org/Special:MyLanguage/What_are_the_major_differences_between_Joomla!_3.x_and_4.x + * How to migrate from 3.x to 4.x? Tutorial: https://docs.joomla.org/Special:MyLanguage/Joomla_3.x_to_4.x_Step_by_Step_Migration * How to migrate from 2.5.x to 3.x? Tutorial: https://docs.joomla.org/Special:MyLanguage/Joomla_2.5_to_3.x_Step_by_Step_Migration * 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 diff --git a/RoboFile.dist.ini b/RoboFile.dist.ini deleted file mode 100644 index ea5cafda52596..0000000000000 --- a/RoboFile.dist.ini +++ /dev/null @@ -1,6 +0,0 @@ -; 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 index e271464e187ec..9f20da0847b70 100644 --- a/RoboFile.php +++ b/RoboFile.php @@ -10,12 +10,12 @@ /** * 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 + * Do a `$ composer install` afterwards you will be able to execute robo like + * `$ ./libraries/vendor/bin/robo` to see a list of commands * * @see http://robo.li/ */ -require_once __DIR__ . '/tests/codeception/vendor/autoload.php'; +require_once __DIR__ . '/libraries/vendor/autoload.php'; if (!defined('JPATH_BASE')) { @@ -31,38 +31,37 @@ */ class RoboFile extends \Robo\Tasks { - // Load tasks from composer, see composer.json - use \Joomla\Jorobo\Tasks\loadTasks; + use JoomlaRobo\Tasks; /** - * Path to the codeception tests folder + * Path to the Selenium folder# * * @var string * @since 3.7.3 */ - private $testsPath = 'tests/codeception/'; + const SELENIUM_FOLDER = __DIR__ . '/libraries/vendor/joomla-projects/selenium-server-standalone'; /** - * Local configuration parameters + * Path to the vendor folder * - * @var array + * @var string * @since 3.7.3 */ - private $configuration = array(); + private $vendorPath = 'libraries/vendor/'; /** - * @var array | null - * @since 3.7.3 + * Path to the tests + * + * @var string + * @since 4.0.0 */ - private $suiteConfig; + private $testsPath = 'libraries/vendor/joomla/test-system/src/'; /** - * Path to the local CMS test folder - * - * @var string + * @var array | null * @since 3.7.3 */ - protected $cmsPath = null; + private $suiteConfig; /** * RoboFile constructor. @@ -71,67 +70,11 @@ class RoboFile extends \Robo\Tasks */ 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) * @@ -143,38 +86,81 @@ private function getTestingPath() */ public function createTestingSite($useHtaccess = false) { + $cmsPath = $this->getSuiteConfig()['modules']['config']['Helper\\Acceptance']['cmsPath']; + $localUser = $this->getSuiteConfig()['modules']['config']['Helper\\Acceptance']['localUser']; + // Clean old testing site - if (is_dir($this->cmsPath)) + if (is_dir($cmsPath)) { try { - $this->taskDeleteDir($this->cmsPath)->run(); + $this->taskDeleteDir($cmsPath)->run(); } catch (Exception $e) { // Sorry, we tried :( - $this->say('Sorry, you will have to delete ' . $this->cmsPath . ' manually.'); + $this->say('Sorry, you will have to delete ' . $cmsPath . ' manually.'); exit(1); } } - $exclude = ['tests', 'tests-phpunit', '.run', '.github', '.git']; - - $this->copyJoomla($this->cmsPath, $exclude); + $exclude = [ + '.drone', + '.github', + '.git', + '.run', + '.idea', + 'build', + 'dev', + 'node_modules', + 'tests', + 'test-install', + '.appveyor.yml', + '.babelrc', + '.drone.yml', + '.eslintignore', + '.eslintrc', + '.gitignore', + '.hound.yml', + '.php_cs', + '.travis.yml', + 'appveyor-phpunit.xml', + 'build.js', + 'build.xml', + 'codeception.yml', + 'composer.json', + 'composer.lock', + 'configuration.php', + 'drone-package.json', + 'Gemfile', + 'htaccess.txt', + 'karma.conf.js', + 'package.json', + 'package-lock.json', + 'phpunit.xml.dist', + 'RoboFile.dist.ini', + 'RoboFile.php', + 'robots.txt.dist', + 'scss-lint.yml', + 'selenium.log', + 'travisci-phpunit.xml', + ]; + + $this->copyJoomla($cmsPath, $exclude); // Optionally change owner to fix permissions issues - if (!empty($this->configuration->localUser)) + if (!empty($localUser)) { - $this->_exec('chown -R ' . $this->configuration->localUser . ' ' . $this->cmsPath); + $this->_exec('chown -R ' . $localUser . ' ' . $cmsPath); } // Optionally uses Joomla default htaccess file. Used by TravisCI if ($useHtaccess == true) { $this->say('Renaming htaccess.txt to .htaccess'); - $this->_copy('./htaccess.txt', $this->cmsPath . '/.htaccess'); - $this->_exec('sed -e "s,# RewriteBase /,RewriteBase /tests/codeception/joomla-cms,g" -in-place tests/codeception/joomla-cms/.htaccess'); + $this->_copy('./htaccess.txt', $cmsPath . '/.htaccess'); + $this->_exec('sed -e "s,# RewriteBase /,RewriteBase /test-install/joomla-cms,g" -in-place test-install/joomla-cms/.htaccess'); } } @@ -231,94 +217,99 @@ protected function copyJoomla($dst, $exclude = array()) } /** - * Downloads Composer + * 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 void + * @return mixed */ - private function getComposer() + public function runTests($opts = ['use-htaccess' => false, 'env' => 'desktop']) { - // 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'); + $this->say("Running tests"); + + $pathToCodeception = $this->prepareRun($opts); + + $suites = [ + 'acceptance/install/', + 'acceptance/administrator/components/com_content', + 'acceptance/administrator/components/com_media', + 'acceptance/administrator/components/com_menu', + 'acceptance/administrator/components/com_users', + ]; + + foreach ($suites as $suite) { + $this->taskCodecept($pathToCodeception) + ->arg('--fail-fast') + ->arg('--steps') + ->arg('--debug') + ->env($opts['env']) + ->arg($this->testsPath . $suite) + ->run() + ->stopOnFail(); } } /** - * Runs Selenium Standalone Server. + * Install only Joomla * - * @since 3.7.3 + * @param array $opts Additional options + * + * @since 4.0.0 * * @return void */ - public function runSelenium() + public function runInstall($opts = ['use-htaccess' => false, 'env' => 'desktop']) { - 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 '); - } + $this->say("Running Installation"); - sleep(3); + $pathToCodeception = $this->prepareRun($opts); + + $this->taskCodecept($pathToCodeception) + ->arg('--fail-fast') + ->arg('--steps') + ->arg('--debug') + ->env($opts['env']) + ->arg($this->testsPath . 'acceptance/install/') + ->run() + ->stopOnFail(); } /** - * Executes all the Selenium System Tests in a suite on your machine + * Prepare the installation * - * @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 + * @param array $opts Optional Options * - * @since 3.7.3 + * @return string Path to codeception * - * @return mixed + * @since 4.0.0 */ - public function runTests($opts = ['use-htaccess' => false, 'env' => 'desktop']) + protected function prepareRun($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->taskRunSelenium(self::SELENIUM_FOLDER, $this->getWebdriver())->run(); - $this->runSelenium(); + // Wait until the server started + sleep(3); // Make sure to run the build command to generate AcceptanceTester if ($this->isWindows()) { - $this->_exec('php ' . $this->getWindowsPath($this->testsPath . 'vendor/bin/codecept') . ' build'); - $pathToCodeception = $this->getWindowsPath($this->testsPath . 'vendor/bin/codecept'); + $this->_exec('php ' . $this->getWindowsPath($this->vendorPath . 'bin/codecept') . ' build'); + $pathToCodeception = $this->getWindowsPath($this->vendorPath . 'bin/codecept'); } else { - $this->_exec('php ' . $this->testsPath . 'vendor/bin/codecept build'); + $this->_exec('php ' . $this->vendorPath . 'bin/codecept build'); - $pathToCodeception = $this->testsPath . 'vendor/bin/codecept'; + $pathToCodeception = $this->vendorPath . '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(); + return $pathToCodeception; } /** @@ -329,14 +320,16 @@ public function runTests($opts = ['use-htaccess' => false, 'env' => 'desktop']) * * @since 3.7.3 * + * @throws Exception if test not found + * * @return void */ public function runTest($pathToTestFile = null, $suite = 'acceptance') { - $this->runSelenium(); + $this->taskRunSelenium(self::SELENIUM_FOLDER, $this->getWebdriver()); // Make sure to run the build command to generate AcceptanceTester - $path = 'tests/codeception/vendor/bin/codecept'; + $path = $this->vendorPath . 'bin/codecept'; $this->_exec('php ' . $this->isWindows() ? $this->getWindowsPath($path) : $path . ' build'); if (!$pathToTestFile) @@ -345,7 +338,7 @@ public function runTest($pathToTestFile = null, $suite = 'acceptance') $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( - $this->testsPath . $suite, + $this->testsPath . '/' . $suite, RecursiveDirectoryIterator::SKIP_DOTS ), RecursiveIteratorIterator::SELF_FIRST @@ -377,7 +370,7 @@ public function runTest($pathToTestFile = null, $suite = 'acceptance') $test = $tests[$testNumber]; } - $pathToTestFile = $this->testsPath . $suite . '/' . $test; + $pathToTestFile = $this->testsPath . '/' . $suite . '/' . $test; // Loading the class to display the methods in the class @@ -389,7 +382,7 @@ public function runTest($pathToTestFile = null, $suite = 'acceptance') if (isset($fileName[1]) && strripos($fileName[1], 'cest')) { - require $this->testsPath . $suite . '/' . $test; + require $this->testsPath . '/' . $suite . '/' . $test; $className = explode(".", $fileName[1]); $class_methods = get_class_methods($className[0]); @@ -423,7 +416,7 @@ public function runTest($pathToTestFile = null, $suite = 'acceptance') $pathToTestFile = $pathToTestFile . ':' . $method; } - $testPathCodecept = $this->testsPath . 'vendor/bin/codecept'; + $testPathCodecept = $this->vendorPath . 'bin/codecept'; $this->taskCodecept($this->isWindows() ? $this->getWindowsPath($testPathCodecept) : $testPathCodecept) ->test($pathToTestFile) @@ -468,73 +461,10 @@ private function getWindowsPath($path) */ 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'; - } + $suiteConfig = $this->getSuiteConfig(); + $driver = $suiteConfig['modules']['config']['JoomlaBrowser']['browser']; - return 'linux'; + return $driver; } /** @@ -550,7 +480,7 @@ private function getSuiteConfig($suite = 'acceptance') { if (!$this->suiteConfig) { - $this->suiteConfig = Symfony\Component\Yaml\Yaml::parse(file_get_contents("tests/codeception/{$suite}.suite.yml")); + $this->suiteConfig = Symfony\Component\Yaml\Yaml::parse(file_get_contents(__DIR__ . '/libraries/vendor/joomla/test-system/src/' . $suite . '.suite.yml')); } return $this->suiteConfig; diff --git a/administrator/components/com_admin/Controller/DisplayController.php b/administrator/components/com_admin/Controller/DisplayController.php new file mode 100644 index 0000000000000..29166badb2589 --- /dev/null +++ b/administrator/components/com_admin/Controller/DisplayController.php @@ -0,0 +1,24 @@ +app->getIdentity()->id; + } + + /** + * Overrides parent save method to check the submitted passwords match. + * + * @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.2 + */ + public function save($key = null, $urlVar = null) + { + $this->setRedirect(Route::_('index.php?option=com_admin&view=profile&layout=edit&id=' . $this->app->getIdentity()->id, false)); + + $return = parent::save(); + + if ($this->getTask() != 'apply') + { + // Redirect to the main page. + $this->setRedirect(Route::_('index.php', false)); + } + + return $return; + } + + /** + * Method to cancel an edit. + * + * @param string $key The name of the primary key of the URL variable. + * + * @return boolean True if access level checks pass, false otherwise. + * + * @since 1.6 + */ + public function cancel($key = null) + { + $return = parent::cancel($key); + + // Redirect to the main page. + $this->setRedirect(Route::_('index.php', false)); + + return $return; + } +} diff --git a/administrator/components/com_admin/Dispatcher/Dispatcher.php b/administrator/components/com_admin/Dispatcher/Dispatcher.php new file mode 100644 index 0000000000000..59670da27b3cc --- /dev/null +++ b/administrator/components/com_admin/Dispatcher/Dispatcher.php @@ -0,0 +1,31 @@ +getRegistry()->register('system', new System); + $this->getRegistry()->register('phpsetting', new PhpSetting); + $this->getRegistry()->register('directory', new Directory); + } +} diff --git a/administrator/components/com_admin/Model/HelpModel.php b/administrator/components/com_admin/Model/HelpModel.php new file mode 100644 index 0000000000000..097713c3d061c --- /dev/null +++ b/administrator/components/com_admin/Model/HelpModel.php @@ -0,0 +1,215 @@ +help_search)) + { + $this->help_search = Factory::getApplication()->input->getString('helpsearch'); + } + + return $this->help_search; + } + + /** + * Method to get the page + * + * @return string The page + * + * @since 1.6 + */ + public function &getPage() + { + if (is_null($this->page)) + { + $this->page = Help::createUrl(Factory::getApplication()->input->get('page', 'JHELP_START_HERE')); + } + + return $this->page; + } + + /** + * Method to get the lang tag + * + * @return string lang iso tag + * + * @since 1.6 + */ + public function getLangTag() + { + if (is_null($this->lang_tag)) + { + $this->lang_tag = Factory::getLanguage()->getTag(); + + if (!is_dir(JPATH_BASE . '/help/' . $this->lang_tag)) + { + // Use English as fallback + $this->lang_tag = 'en-GB'; + } + } + + return $this->lang_tag; + } + + /** + * Method to get the table of contents + * + * @return array Table of contents + */ + public function &getToc() + { + if (!is_null($this->toc)) + { + return $this->toc; + } + + // Get vars + $lang_tag = $this->getLangTag(); + $help_search = $this->getHelpSearch(); + + // New style - Check for a TOC \JSON file + if (file_exists(JPATH_BASE . '/help/' . $lang_tag . '/toc.json')) + { + $data = json_decode(file_get_contents(JPATH_BASE . '/help/' . $lang_tag . '/toc.json')); + + // Loop through the data array + foreach ($data as $key => $value) + { + $this->toc[$key] = Text::_('COM_ADMIN_HELP_' . $value); + } + + // Sort the Table of Contents + asort($this->toc); + + return $this->toc; + } + + // Get Help files + $files = Folder::files(JPATH_BASE . '/help/' . $lang_tag, '\.xml$|\.html$'); + $this->toc = array(); + + foreach ($files as $file) + { + $buffer = file_get_contents(JPATH_BASE . '/help/' . $lang_tag . '/' . $file); + + if (!preg_match('#(.*?)#', $buffer, $m)) + { + continue; + } + + $title = trim($m[1]); + + if (!$title) + { + continue; + } + + // Translate the page title + $title = Text::_($title); + + // Strip the extension + $file = preg_replace('#\.xml$|\.html$#', '', $file); + + if ($help_search && StringHelper::strpos(StringHelper::strtolower(strip_tags($buffer)), StringHelper::strtolower($help_search)) === false) + { + continue; + } + + // Add an item in the Table of Contents + $this->toc[$file] = $title; + } + + // Sort the Table of Contents + asort($this->toc); + + return $this->toc; + } + + /** + * Method to get the latest version check + * + * @return string Latest Version Check URL + */ + public function &getLatestVersionCheck() + { + if (!$this->latest_version_check) + { + $override = 'https://help.joomla.org/proxy/index.php?keyref=Help{major}{minor}:' + . 'Joomla_Version_{major}_{minor}_{maintenance}/{langcode}&lang={langcode}'; + $this->latest_version_check = Help::createUrl('JVERSION', false, $override); + } + + return $this->latest_version_check; + } +} diff --git a/administrator/components/com_admin/Model/ProfileModel.php b/administrator/components/com_admin/Model/ProfileModel.php new file mode 100644 index 0000000000000..db13165865dce --- /dev/null +++ b/administrator/components/com_admin/Model/ProfileModel.php @@ -0,0 +1,168 @@ +loadForm('com_admin.profile', 'profile', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Check for username compliance and parameter set + $isUsernameCompliant = true; + + if ($this->loadFormData()->username) + { + $username = $this->loadFormData()->username; + $isUsernameCompliant = !(preg_match('#[<>"\'%;()&\\\\]|\\.\\./#', $username) || strlen(utf8_decode($username)) < 2 + || trim($username) != $username); + } + + $this->setState('user.username.compliant', $isUsernameCompliant); + + if (!ComponentHelper::getParams('com_users')->get('change_login_name') && $isUsernameCompliant) + { + $form->setFieldAttribute('username', 'required', 'false'); + $form->setFieldAttribute('username', 'readonly', 'true'); + $form->setFieldAttribute('username', 'description', 'COM_ADMIN_USER_FIELD_NOCHANGE_USERNAME_DESC'); + } + + // When multilanguage is set, a user's default site language should also be a Content Language + if (Multilanguage::isEnabled()) + { + $form->setFieldAttribute('language', 'type', 'frontend_language', 'params'); + } + + // If the user needs to change their password, mark the password fields as required + if (Factory::getUser()->requireReset) + { + $form->setFieldAttribute('password', 'required', 'true'); + $form->setFieldAttribute('password2', 'required', 'true'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_users.edit.user.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + // Load the users plugins. + PluginHelper::importPlugin('user'); + + $this->preprocessData('com_admin.profile', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + return parent::getItem(Factory::getUser()->id); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $user = Factory::getUser(); + + unset($data['id']); + unset($data['groups']); + unset($data['sendEmail']); + unset($data['block']); + + $isUsernameCompliant = $this->getState('user.username.compliant'); + + if (!ComponentHelper::getParams('com_users')->get('change_login_name') && $isUsernameCompliant) + { + unset($data['username']); + } + + // Bind the data. + if (!$user->bind($data)) + { + $this->setError($user->getError()); + + return false; + } + + $user->groups = null; + + // Store the data. + if (!$user->save()) + { + $this->setError($user->getError()); + + return false; + } + + $this->setState('user.id', $user->id); + + return true; + } +} diff --git a/administrator/components/com_admin/Model/SysinfoModel.php b/administrator/components/com_admin/Model/SysinfoModel.php new file mode 100644 index 0000000000000..8ba3bb9a34c2c --- /dev/null +++ b/administrator/components/com_admin/Model/SysinfoModel.php @@ -0,0 +1,745 @@ + array( + 'CONTEXT_DOCUMENT_ROOT', + 'Cookie', + 'DOCUMENT_ROOT', + 'extension_dir', + 'error_log', + 'Host', + 'HTTP_COOKIE', + 'HTTP_HOST', + 'HTTP_ORIGIN', + 'HTTP_REFERER', + 'HTTP Request', + 'include_path', + 'mysql.default_socket', + 'MYSQL_SOCKET', + 'MYSQL_INCLUDE', + 'MYSQL_LIBS', + 'mysqli.default_socket', + 'MYSQLI_SOCKET', + 'PATH', + 'Path to sendmail', + 'pdo_mysql.default_socket', + 'Referer', + 'REMOTE_ADDR', + 'SCRIPT_FILENAME', + 'sendmail_path', + 'SERVER_ADDR', + 'SERVER_ADMIN', + 'Server Administrator', + 'SERVER_NAME', + 'Server Root', + 'session.name', + 'session.save_path', + 'upload_tmp_dir', + 'User/Group', + 'open_basedir', + ), + 'other' => array( + 'db', + 'dbprefix', + 'fromname', + 'live_site', + 'log_path', + 'mailfrom', + 'memcached_server_host', + 'open_basedir', + 'Origin', + 'proxy_host', + 'proxy_user', + 'proxy_pass', + 'redis_server_host', + 'redis_server_auth', + 'secret', + 'sendmail', + 'session.save_path', + 'session_memcached_server_host', + 'session_redis_server_host', + 'session_redis_server_auth', + 'sitename', + 'smtphost', + 'tmp_path', + 'open_basedir', + ) + ); + + /** + * System values that can be "safely" shared + * + * @var array + * + * @since 3.5 + */ + protected $safeData; + + /** + * Information about writable state of directories + * + * @var array + * @since 1.6 + */ + protected $directories = array(); + + /** + * The current editor. + * + * @var string + * @since 1.6 + */ + protected $editor = null; + + /** + * 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 a specific section in the privateSettings array + * + * @return array + * + * @since 3.5 + */ + protected function cleanPrivateData($dataArray, $dataType = 'other') + { + $dataType = isset($this->privateSettings[$dataType]) ? $dataType : 'other'; + + $privateSettings = $this->privateSettings[$dataType]; + + if (!$privateSettings) + { + return $dataArray; + } + + foreach ($dataArray as $section => $values) + { + if (is_array($values)) + { + $dataArray[$section] = $this->cleanPrivateData($values, $dataType); + } + + if (in_array($section, $privateSettings, true)) + { + $dataArray[$section] = $this->cleanSectionPrivateData($values); + } + } + + return $dataArray; + } + + /** + * Obfuscate section values + * + * @param mixed $sectionValues Section data + * + * @return mixed + * + * @since 3.5 + */ + protected function cleanSectionPrivateData($sectionValues) + { + if (!is_array($sectionValues)) + { + if (strstr($sectionValues, JPATH_ROOT)) + { + $sectionValues = 'xxxxxx'; + } + + return strlen($sectionValues) ? 'xxxxxx' : ''; + } + + foreach ($sectionValues as $setting => $value) + { + $sectionValues[$setting] = strlen($value) ? 'xxxxxx' : ''; + } + + return $sectionValues; + } + + /** + * Method to get the PHP settings + * + * @return array Some PHP settings + * + * @since 1.6 + */ + public function &getPhpSettings() + { + if (!empty($this->php_settings)) + { + return $this->php_settings; + } + + $this->php_settings = array( + 'display_errors' => ini_get('display_errors') == '1', + 'short_open_tag' => ini_get('short_open_tag') == '1', + 'file_uploads' => ini_get('file_uploads') == '1', + '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'), + 'disable_functions' => ini_get('disable_functions'), + 'xml' => extension_loaded('xml'), + 'zlib' => extension_loaded('zlib'), + 'zip' => function_exists('zip_open') && function_exists('zip_read'), + 'mbstring' => extension_loaded('mbstring'), + 'iconv' => function_exists('iconv'), + 'max_input_vars' => ini_get('max_input_vars'), + ); + + return $this->php_settings; + } + + /** + * Method to get the config + * + * @return array config values + * + * @since 1.6 + */ + public function &getConfig() + { + if (!empty($this->config)) + { + return $this->config; + } + + $registry = new Registry(new \JConfig); + $this->config = $registry->toArray(); + $hidden = array('host', 'user', 'password', 'ftp_user', 'ftp_pass', 'smtpuser', 'smtppass',); + + foreach ($hidden as $key) + { + $this->config[$key] = 'xxxxxx'; + } + + return $this->config; + } + + /** + * Method to get the system information + * + * @return array System information values + * + * @since 1.6 + */ + public function &getInfo() + { + if (!empty($this->info)) + { + return $this->info; + } + + $db = $this->getDbo(); + + $this->info = array( + 'php' => php_uname(), + 'dbserver' => $db->getServerType(), + 'dbversion' => $db->getVersion(), + 'dbcollation' => $db->getCollation(), + 'dbconnectioncollation' => $db->getConnectionCollation(), + 'phpversion' => PHP_VERSION, + 'server' => $_SERVER['SERVER_SOFTWARE'] ?? getenv('SERVER_SOFTWARE'), + 'sapi_name' => PHP_SAPI, + 'version' => (new Version)->getLongVersion(), + 'useragent' => $_SERVER['HTTP_USER_AGENT'] ?? '', + ); + + return $this->info; + } + + /** + * Check if the phpinfo function is enabled + * + * @return boolean True if enabled + * + * @since 3.4.1 + */ + public function phpinfoEnabled() + { + return !in_array('phpinfo', explode(',', ini_get('disable_functions'))); + } + + /** + * Method to get filter data from the model + * + * @param string $dataType Type of data to get safely + * @param bool $public If true no sensitive information will be removed + * + * @return array + * + * @since 3.5 + */ + public function getSafeData($dataType, $public = true) + { + if (isset($this->safeData[$dataType])) + { + return $this->safeData[$dataType]; + } + + $methodName = 'get' . ucfirst($dataType); + + if (!method_exists($this, $methodName)) + { + return array(); + } + + $data = $this->$methodName($public); + + $this->safeData[$dataType] = $this->cleanPrivateData($data, $dataType); + + return $this->safeData[$dataType]; + } + + /** + * Method to get the PHP info + * + * @return string PHP info + * + * @since 1.6 + */ + public function &getPHPInfo() + { + if (!$this->phpinfoEnabled()) + { + $this->php_info = Text::_('COM_ADMIN_PHPINFO_DISABLED'); + + return $this->php_info; + } + + if (!is_null($this->php_info)) + { + return $this->php_info; + } + + ob_start(); + date_default_timezone_set('UTC'); + phpinfo(INFO_GENERAL | INFO_CONFIGURATION | INFO_MODULES); + $phpInfo = ob_get_contents(); + ob_end_clean(); + preg_match_all('#]*>(.*)#siU', $phpInfo, $output); + $output = preg_replace('#]*>#', '', $output[1][0]); + $output = preg_replace('#(\w),(\w)#', '\1, \2', $output); + $output = preg_replace('#
#', '', $output); + $output = str_replace('
', '', $output); + $output = preg_replace('#
(.*)<\/tr>#', '$1', $output); + $output = str_replace('
', '', $output); + $output = str_replace('', '', $output); + $this->php_info = $output; + + return $this->php_info; + } + + /** + * Get phpinfo() output as array + * + * @return array + * + * @since 3.5 + */ + public function getPhpInfoArray() + { + // Already cached + if (null !== $this->phpInfoArray) + { + return $this->phpInfoArray; + } + + $phpInfo = $this->getPhpInfo(); + + $this->phpInfoArray = $this->parsePhpInfo($phpInfo); + + return $this->phpInfoArray; + } + + /** + * Method to get a list of installed extensions + * + * @return array installed extensions + * + * @since 3.5 + */ + public function getExtensions() + { + $installed = array(); + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__extensions')); + $db->setQuery($query); + + try + { + $extensions = $db->loadObjectList(); + } + catch (\Exception $e) + { + try + { + Log::add(Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()), Log::WARNING, 'jerror'); + } + catch (\RuntimeException $exception) + { + Factory::getApplication()->enqueueMessage( + Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()), + 'warning' + ); + } + + return $installed; + } + + if (empty($extensions)) + { + return $installed; + } + + foreach ($extensions as $extension) + { + if (strlen($extension->name) == 0) + { + continue; + } + + $installed[$extension->name] = array( + 'name' => $extension->name, + 'type' => $extension->type, + 'state' => $extension->enabled ? Text::_('JENABLED') : Text::_('JDISABLED'), + 'author' => 'unknown', + 'version' => 'unknown', + 'creationDate' => 'unknown', + 'authorUrl' => 'unknown', + ); + + $manifest = new Registry($extension->manifest_cache); + + $extraData = array( + 'author' => $manifest->get('author', ''), + 'version' => $manifest->get('version', ''), + 'creationDate' => $manifest->get('creationDate', ''), + 'authorUrl' => $manifest->get('authorUrl', '') + ); + + $installed[$extension->name] = array_merge($installed[$extension->name], $extraData); + } + + return $installed; + } + + /** + * Method to get the directory states + * + * @param bool $public If true no information is going to be removed + * + * @return array States of directories + * + * @since 1.6 + */ + public function getDirectory($public = false) + { + if (!empty($this->directories)) + { + return $this->directories; + } + + $this->directories = array(); + + $registry = Factory::getApplication()->getConfig(); + $cparams = ComponentHelper::getParams('com_media'); + + $this->addDirectory('administrator/components', JPATH_ADMINISTRATOR . '/components'); + $this->addDirectory('administrator/language', JPATH_ADMINISTRATOR . '/language'); + + // List all admin languages + $admin_langs = new \DirectoryIterator(JPATH_ADMINISTRATOR . '/language'); + + foreach ($admin_langs as $folder) + { + if (!$folder->isDir() || $folder->isDot()) + { + continue; + } + + $this->addDirectory( + 'administrator/language/' . $folder->getFilename(), + JPATH_ADMINISTRATOR . '/language/' . $folder->getFilename() + ); + } + + // List all manifests folders + $manifests = new \DirectoryIterator(JPATH_ADMINISTRATOR . '/manifests'); + + foreach ($manifests as $folder) + { + if (!$folder->isDir() || $folder->isDot()) + { + continue; + } + + $this->addDirectory( + 'administrator/manifests/' . $folder->getFilename(), + JPATH_ADMINISTRATOR . '/manifests/' . $folder->getFilename() + ); + } + + $this->addDirectory('administrator/modules', JPATH_ADMINISTRATOR . '/modules'); + $this->addDirectory('administrator/templates', JPATH_THEMES); + + $this->addDirectory('components', JPATH_SITE . '/components'); + + $this->addDirectory($cparams->get('image_path'), JPATH_SITE . '/' . $cparams->get('image_path')); + + // List all images folders + $image_folders = new \DirectoryIterator(JPATH_SITE . '/' . $cparams->get('image_path')); + + foreach ($image_folders as $folder) + { + if (!$folder->isDir() || $folder->isDot()) + { + continue; + } + + $this->addDirectory( + 'images/' . $folder->getFilename(), + JPATH_SITE . '/' . $cparams->get('image_path') . '/' . $folder->getFilename() + ); + } + + $this->addDirectory('language', JPATH_SITE . '/language'); + + // List all site languages + $site_langs = new \DirectoryIterator(JPATH_SITE . '/language'); + + foreach ($site_langs as $folder) + { + if (!$folder->isDir() || $folder->isDot()) + { + continue; + } + + $this->addDirectory('language/' . $folder->getFilename(), JPATH_SITE . '/language/' . $folder->getFilename()); + } + + $this->addDirectory('libraries', JPATH_LIBRARIES); + + $this->addDirectory('media', JPATH_SITE . '/media'); + $this->addDirectory('modules', JPATH_SITE . '/modules'); + $this->addDirectory('plugins', JPATH_PLUGINS); + + $plugin_groups = new \DirectoryIterator(JPATH_SITE . '/plugins'); + + foreach ($plugin_groups as $folder) + { + if (!$folder->isDir() || $folder->isDot()) + { + continue; + } + + $this->addDirectory('plugins/' . $folder->getFilename(), JPATH_PLUGINS . '/' . $folder->getFilename()); + } + + $this->addDirectory('templates', JPATH_SITE . '/templates'); + $this->addDirectory('configuration.php', JPATH_CONFIGURATION . '/configuration.php'); + + // Is there a cache path in configuration.php? + if ($cache_path = trim($registry->get('cache_path', ''))) + { + // Frontend and backend use same directory for caching. + $this->addDirectory($cache_path, $cache_path, 'COM_ADMIN_CACHE_DIRECTORY'); + } + else + { + $this->addDirectory('administrator/cache', JPATH_CACHE, 'COM_ADMIN_CACHE_DIRECTORY'); + } + + $this->addDirectory('media/cache', JPATH_ROOT . '/media/cache', 'COM_ADMIN_MEDIA_CACHE_DIRECTORY'); + + if ($public) + { + $this->addDirectory( + 'log', + $registry->get('log_path', JPATH_ADMINISTRATOR . '/logs'), + 'COM_ADMIN_LOG_DIRECTORY' + ); + $this->addDirectory( + 'tmp', + $registry->get('tmp_path', JPATH_ROOT . '/tmp'), + 'COM_ADMIN_TEMP_DIRECTORY' + ); + } + else + { + $this->addDirectory( + $registry->get('log_path', JPATH_ADMINISTRATOR . '/logs'), + $registry->get('log_path', JPATH_ADMINISTRATOR . '/logs'), + 'COM_ADMIN_LOG_DIRECTORY' + ); + $this->addDirectory( + $registry->get('tmp_path', JPATH_ROOT . '/tmp'), + $registry->get('tmp_path', JPATH_ROOT . '/tmp'), + 'COM_ADMIN_TEMP_DIRECTORY' + ); + } + + return $this->directories; + } + + /** + * Method to add a directory + * + * @param string $name Directory Name + * @param string $path Directory path + * @param string $message Message + * + * @return void + * + * @since 1.6 + */ + private function addDirectory($name, $path, $message = '') + { + $this->directories[$name] = array('writable' => is_writable($path), 'message' => $message,); + } + + /** + * Method to get the editor + * + * @return string The default editor + * + * @note Has to be removed (it is present in the config...) + * @since 1.6 + */ + public function &getEditor() + { + if (!is_null($this->editor)) + { + return $this->editor; + } + + $this->editor = Factory::getApplication()->get('editor'); + + return $this->editor; + } + + /** + * Parse phpinfo output into an array + * Source https://gist.github.com/sbmzhcn/6255314 + * + * @param string $html Output of phpinfo() + * + * @return array + * + * @since 3.5 + */ + protected function parsePhpInfo($html) + { + $html = strip_tags($html, '

'); + $html = preg_replace('/]*>([^<]+)<\/th>/', '\1', $html); + $html = preg_replace('/]*>([^<]+)<\/td>/', '\1', $html); + $t = preg_split('/(]*>[^<]+<\/h2>)/', $html, -1, PREG_SPLIT_DELIM_CAPTURE); + $r = array(); + $count = count($t); + $p1 = '([^<]+)<\/info>'; + $p2 = '/' . $p1 . '\s*' . $p1 . '\s*' . $p1 . '/'; + $p3 = '/' . $p1 . '\s*' . $p1 . '/'; + + for ($i = 1; $i < $count; $i++) + { + if (preg_match('/]*>([^<]+)<\/h2>/', $t[$i], $matchs)) + { + $name = trim($matchs[1]); + $vals = explode("\n", $t[$i + 1]); + + foreach ($vals AS $val) + { + // 3cols + if (preg_match($p2, $val, $matchs)) + { + $r[$name][trim($matchs[1])] = array(trim($matchs[2]), trim($matchs[3]),); + } + // 2cols + elseif (preg_match($p3, $val, $matchs)) + { + $r[$name][trim($matchs[1])] = trim($matchs[2]); + } + } + } + } + + return $r; + } +} diff --git a/administrator/components/com_admin/Service/HTML/Directory.php b/administrator/components/com_admin/Service/HTML/Directory.php new file mode 100644 index 0000000000000..78f05e8877968 --- /dev/null +++ b/administrator/components/com_admin/Service/HTML/Directory.php @@ -0,0 +1,60 @@ +' . Text::_('COM_ADMIN_WRITABLE') . ''; + } + + return '' . Text::_('COM_ADMIN_UNWRITABLE') . ''; + } + + /** + * Method to generate a message for a directory + * + * @param string $dir the directory + * @param boolean $message the message + * @param boolean $visible is the $dir visible? + * + * @return string html code + */ + public function message($dir, $message, $visible = true) + { + $output = $visible ? $dir : ''; + + if (empty($message)) + { + return $output; + } + + return $output . ' ' . Text::_($message) . ''; + } +} diff --git a/administrator/components/com_admin/Service/HTML/PhpSetting.php b/administrator/components/com_admin/Service/HTML/PhpSetting.php new file mode 100644 index 0000000000000..8dea08936b974 --- /dev/null +++ b/administrator/components/com_admin/Service/HTML/PhpSetting.php @@ -0,0 +1,82 @@ +help_search = $this->get('HelpSearch'); + $this->page = $this->get('Page'); + $this->toc = $this->get('Toc'); + $this->lang_tag = $this->get('LangTag'); + $this->latest_version_check = $this->get('LatestVersionCheck'); + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Setup the Toolbar + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + ToolbarHelper::title(Text::_('COM_ADMIN_HELP'), 'support help_header'); + } +} diff --git a/administrator/components/com_admin/View/Profile/HtmlView.php b/administrator/components/com_admin/View/Profile/HtmlView.php new file mode 100644 index 0000000000000..e416b0f6bf22d --- /dev/null +++ b/administrator/components/com_admin/View/Profile/HtmlView.php @@ -0,0 +1,104 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->form->setValue('password', null); + $this->form->setValue('password2', null); + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', 1); + + ToolbarHelper::title(Text::_('COM_ADMIN_VIEW_PROFILE_TITLE'), 'user user-profile'); + + ToolbarHelper::saveGroup( + [ + ['apply', 'profile.apply'], + ['save', 'profile.save'] + ], + 'btn-success' + ); + + ToolbarHelper::cancel('profile.cancel', 'JTOOLBAR_CLOSE'); + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_ADMIN_USER_PROFILE_EDIT'); + } +} diff --git a/administrator/components/com_admin/View/Sysinfo/HtmlView.php b/administrator/components/com_admin/View/Sysinfo/HtmlView.php new file mode 100644 index 0000000000000..a3aab923f4994 --- /dev/null +++ b/administrator/components/com_admin/View/Sysinfo/HtmlView.php @@ -0,0 +1,110 @@ +authorise('core.admin')) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + $this->php_settings = $this->get('PhpSettings'); + $this->config = $this->get('config'); + $this->info = $this->get('info'); + $this->php_info = $this->get('PhpInfo'); + $this->directory = $this->get('directory'); + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Setup the Toolbar + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + ToolbarHelper::title(Text::_('COM_ADMIN_SYSTEM_INFORMATION'), 'info-2 systeminfo'); + ToolbarHelper::link(Route::_('index.php?option=com_admin&view=sysinfo&format=text'), 'COM_ADMIN_DOWNLOAD_SYSTEM_INFORMATION_TEXT', 'download'); + ToolbarHelper::link(Route::_('index.php?option=com_admin&view=sysinfo&format=json'), 'COM_ADMIN_DOWNLOAD_SYSTEM_INFORMATION_JSON', 'download'); + ToolbarHelper::help('JHELP_SITE_SYSTEM_INFORMATION'); + } +} diff --git a/administrator/components/com_admin/View/Sysinfo/JsonView.php b/administrator/components/com_admin/View/Sysinfo/JsonView.php new file mode 100644 index 0000000000000..f8ea936672b42 --- /dev/null +++ b/administrator/components/com_admin/View/Sysinfo/JsonView.php @@ -0,0 +1,75 @@ +authorise('core.admin')) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + header('MIME-Version: 1.0'); + header('Content-Disposition: attachment; filename="systeminfo-' . date('c') . '.json"'); + header('Content-Transfer-Encoding: binary'); + + $data = $this->getLayoutData(); + + echo json_encode($data); + + Factory::getApplication()->close(); + } + + /** + * Get the data for the view + * + * @return array + * + * @since 3.5 + */ + protected function getLayoutData() + { + /* @var \Joomla\Component\Admin\Administrator\Model\SysInfoModel $model */ + $model = $this->getModel(); + + return array( + 'info' => $model->getSafeData('info'), + 'phpSettings' => $model->getSafeData('phpSettings'), + 'config' => $model->getSafeData('config'), + 'directories' => $model->getSafeData('directory', true), + 'phpInfo' => $model->getSafeData('phpInfoArray'), + 'extensions' => $model->getSafeData('extensions') + ); + } +} diff --git a/administrator/components/com_admin/View/Sysinfo/TextView.php b/administrator/components/com_admin/View/Sysinfo/TextView.php new file mode 100644 index 0000000000000..224ca666498fa --- /dev/null +++ b/administrator/components/com_admin/View/Sysinfo/TextView.php @@ -0,0 +1,184 @@ +authorise('core.admin')) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + header('Content-Type: text/plain; charset=utf-8'); + header('Content-Description: File Transfer'); + header('Content-Disposition: attachment; filename="systeminfo-' . date('c') . '.txt"'); + header('Cache-Control: must-revalidate'); + + $data = $this->getLayoutData(); + + $lines = array(); + + foreach ($data as $sectionName => $section) + { + $customRenderingMethod = 'render' . ucfirst($sectionName); + + if (method_exists($this, $customRenderingMethod)) + { + $lines[] = $this->$customRenderingMethod($section['title'], $section['data']); + } + else + { + $lines[] = $this->renderSection($section['title'], $section['data']); + } + } + + echo str_replace(JPATH_ROOT, 'xxxxxx', implode("\n\n", $lines)); + + Factory::getApplication()->close(); + } + + /** + * Get the data for the view + * + * @return array + * + * @since 3.5 + */ + protected function getLayoutData() + { + /* @var \Joomla\Component\Admin\Administrator\Model\SysInfoModel $model */ + $model = $this->getModel(); + + return array( + 'info' => array( + 'title' => Text::_('COM_ADMIN_SYSTEM_INFORMATION', true), + 'data' => $model->getSafeData('info') + ), + 'phpSettings' => array( + 'title' => Text::_('COM_ADMIN_PHP_SETTINGS', true), + 'data' => $model->getSafeData('phpSettings') + ), + 'config' => array( + 'title' => Text::_('COM_ADMIN_CONFIGURATION_FILE', true), + 'data' => $model->getSafeData('config') + ), + 'directories' => array( + 'title' => Text::_('COM_ADMIN_DIRECTORY_PERMISSIONS', true), + 'data' => $model->getSafeData('directory', true) + ), + 'phpInfo' => array( + 'title' => Text::_('COM_ADMIN_PHP_INFORMATION', true), + 'data' => $model->getSafeData('phpInfoArray') + ), + 'extensions' => array( + 'title' => Text::_('COM_ADMIN_EXTENSIONS', true), + 'data' => $model->getSafeData('extensions') + ) + ); + } + + /** + * Render a section + * + * @param string $sectionName Name of the section to render + * @param array $sectionData Data of the section to render + * @param integer $level Depth level for indentation + * + * @return string + * + * @since 3.5 + */ + protected function renderSection($sectionName, $sectionData, $level = 0) + { + $lines = array(); + + $margin = ($level > 0) ? str_repeat("\t", $level) : null; + + $lines[] = $margin . '============='; + $lines[] = $margin . $sectionName; + $lines[] = $margin . '============='; + $level++; + + foreach ($sectionData as $name => $value) + { + if (is_array($value)) + { + if ($name == 'Directive') + { + continue; + } + + $lines[] = ''; + $lines[] = $this->renderSection($name, $value, $level); + } + else + { + if (is_bool($value)) + { + $value = $value ? 'true' : 'false'; + } + + if (is_int($name) && ($name == 0 || $name == 1)) + { + $name = ($name == 0 ? 'Local Value' : 'Master Value'); + } + + $lines[] = $margin . $name . ': ' . $value; + } + } + + return implode("\n", $lines); + } + + /** + * Specific rendering for directories + * + * @param string $sectionName Name of the section + * @param array $sectionData Directories information + * @param integer $level Starting level + * + * @return string + * + * @since 3.5 + */ + protected function renderDirectories($sectionName, $sectionData, $level = -1) + { + foreach ($sectionData as $directory => $data) + { + $sectionData[$directory] = $data['writable'] ? ' writable' : ' NOT writable'; + } + + return $this->renderSection($sectionName, $sectionData, $level); + } +} diff --git a/administrator/components/com_admin/admin.php b/administrator/components/com_admin/admin.php deleted file mode 100644 index 3e0986cdaeed3..0000000000000 --- a/administrator/components/com_admin/admin.php +++ /dev/null @@ -1,17 +0,0 @@ -execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_admin/admin.xml b/administrator/components/com_admin/admin.xml index aeeaea2513515..c964ee62448fa 100644 --- a/administrator/components/com_admin/admin.xml +++ b/administrator/components/com_admin/admin.xml @@ -10,6 +10,7 @@ 3.0.0 COM_ADMIN_XML_DESCRIPTION + Joomla\Component\Admin admin.php diff --git a/administrator/components/com_admin/controller.php b/administrator/components/com_admin/controller.php deleted file mode 100644 index 305dbc4fe703a..0000000000000 --- a/administrator/components/com_admin/controller.php +++ /dev/null @@ -1,19 +0,0 @@ -id; - } - - /** - * Overrides parent save method to check the submitted passwords match. - * - * @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.2 - */ - public function save($key = null, $urlVar = null) - { - $this->setRedirect(JRoute::_('index.php?option=com_admin&view=profile&layout=edit&id=' . JFactory::getUser()->id, false)); - - $return = parent::save(); - - if ($this->getTask() != 'apply') - { - // Redirect to the main page. - $this->setRedirect(JRoute::_('index.php', false)); - } - - return $return; - } - - /** - * Method to cancel an edit. - * - * @param string $key The name of the primary key of the URL variable. - * - * @return boolean True if access level checks pass, false otherwise. - * - * @since 1.6 - */ - public function cancel($key = null) - { - $return = parent::cancel($key); - - // Redirect to the main page. - $this->setRedirect(JRoute::_('index.php', false)); - - return $return; - } -} diff --git a/administrator/components/com_admin/forms/profile.xml b/administrator/components/com_admin/forms/profile.xml new file mode 100644 index 0000000000000..77fb1bdce1082 --- /dev/null +++ b/administrator/components/com_admin/forms/profile.xml @@ -0,0 +1,149 @@ + +
+
+ + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
diff --git a/administrator/components/com_admin/helpers/html/directory.php b/administrator/components/com_admin/helpers/html/directory.php deleted file mode 100644 index 17a977367489c..0000000000000 --- a/administrator/components/com_admin/helpers/html/directory.php +++ /dev/null @@ -1,56 +0,0 @@ -' . JText::_('COM_ADMIN_WRITABLE') . ''; - } - - return '' . JText::_('COM_ADMIN_UNWRITABLE') . ''; - } - - /** - * Method to generate a message for a directory - * - * @param string $dir the directory - * @param boolean $message the message - * @param boolean $visible is the $dir visible? - * - * @return string html code - */ - public static function message($dir, $message, $visible = true) - { - $output = $visible ? $dir : ''; - - if (empty($message)) - { - return $output; - } - - return $output . ' ' . JText::_($message) . ''; - } -} diff --git a/administrator/components/com_admin/helpers/html/phpsetting.php b/administrator/components/com_admin/helpers/html/phpsetting.php deleted file mode 100644 index d84f3cb93ee7e..0000000000000 --- a/administrator/components/com_admin/helpers/html/phpsetting.php +++ /dev/null @@ -1,77 +0,0 @@ - -
-
- - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
-
-
diff --git a/administrator/components/com_admin/models/help.php b/administrator/components/com_admin/models/help.php deleted file mode 100644 index ed29c3ab6a1d3..0000000000000 --- a/administrator/components/com_admin/models/help.php +++ /dev/null @@ -1,209 +0,0 @@ -help_search)) - { - $this->help_search = JFactory::getApplication()->input->getString('helpsearch'); - } - - return $this->help_search; - } - - /** - * Method to get the page - * - * @return string The page - * - * @since 1.6 - */ - public function &getPage() - { - if (is_null($this->page)) - { - $this->page = JHelp::createUrl(JFactory::getApplication()->input->get('page', 'JHELP_START_HERE')); - } - - return $this->page; - } - - /** - * Method to get the lang tag - * - * @return string lang iso tag - * - * @since 1.6 - */ - public function getLangTag() - { - if (is_null($this->lang_tag)) - { - $this->lang_tag = JFactory::getLanguage()->getTag(); - - if (!is_dir(JPATH_BASE . '/help/' . $this->lang_tag)) - { - // Use English as fallback - $this->lang_tag = 'en-GB'; - } - } - - return $this->lang_tag; - } - - /** - * Method to get the table of contents - * - * @return array Table of contents - */ - public function &getToc() - { - if (!is_null($this->toc)) - { - return $this->toc; - } - - // Get vars - $lang_tag = $this->getLangTag(); - $help_search = $this->getHelpSearch(); - - // New style - Check for a TOC JSON file - if (file_exists(JPATH_BASE . '/help/' . $lang_tag . '/toc.json')) - { - $data = json_decode(file_get_contents(JPATH_BASE . '/help/' . $lang_tag . '/toc.json')); - - // Loop through the data array - foreach ($data as $key => $value) - { - $this->toc[$key] = JText::_('COM_ADMIN_HELP_' . $value); - } - - // Sort the Table of Contents - asort($this->toc); - - return $this->toc; - } - - // Get Help files - jimport('joomla.filesystem.folder'); - $files = JFolder::files(JPATH_BASE . '/help/' . $lang_tag, '\.xml$|\.html$'); - $this->toc = array(); - - foreach ($files as $file) - { - $buffer = file_get_contents(JPATH_BASE . '/help/' . $lang_tag . '/' . $file); - - if (!preg_match('#(.*?)#', $buffer, $m)) - { - continue; - } - - $title = trim($m[1]); - - if (!$title) - { - continue; - } - - // Translate the page title - $title = JText::_($title); - - // Strip the extension - $file = preg_replace('#\.xml$|\.html$#', '', $file); - - if ($help_search && StringHelper::strpos(StringHelper::strtolower(strip_tags($buffer)), StringHelper::strtolower($help_search)) === false) - { - continue; - } - - // Add an item in the Table of Contents - $this->toc[$file] = $title; - } - - // Sort the Table of Contents - asort($this->toc); - - return $this->toc; - } - - /** - * Method to get the latest version check - * - * @return string Latest Version Check URL - */ - public function &getLatestVersionCheck() - { - if (!$this->latest_version_check) - { - $override = 'https://help.joomla.org/proxy/index.php?keyref=Help{major}{minor}:' - . 'Joomla_Version_{major}_{minor}_{maintenance}/{langcode}&lang={langcode}'; - $this->latest_version_check = JHelp::createUrl('JVERSION', false, $override); - } - - return $this->latest_version_check; - } -} diff --git a/administrator/components/com_admin/models/profile.php b/administrator/components/com_admin/models/profile.php deleted file mode 100644 index 79f84acb803e6..0000000000000 --- a/administrator/components/com_admin/models/profile.php +++ /dev/null @@ -1,162 +0,0 @@ -loadForm('com_admin.profile', 'profile', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - // Check for username compliance and parameter set - $isUsernameCompliant = true; - - if ($this->loadFormData()->username) - { - $username = $this->loadFormData()->username; - $isUsernameCompliant = !(preg_match('#[<>"\'%;()&\\\\]|\\.\\./#', $username) || strlen(utf8_decode($username)) < 2 - || trim($username) != $username); - } - - $this->setState('user.username.compliant', $isUsernameCompliant); - - if (!JComponentHelper::getParams('com_users')->get('change_login_name') && $isUsernameCompliant) - { - $form->setFieldAttribute('username', 'required', 'false'); - $form->setFieldAttribute('username', 'readonly', 'true'); - $form->setFieldAttribute('username', 'description', 'COM_ADMIN_USER_FIELD_NOCHANGE_USERNAME_DESC'); - } - - // When multilanguage is set, a user's default site language should also be a Content Language - if (JLanguageMultilang::isEnabled()) - { - $form->setFieldAttribute('language', 'type', 'frontend_language', 'params'); - } - - // If the user needs to change their password, mark the password fields as required - if (JFactory::getUser()->requireReset) - { - $form->setFieldAttribute('password', 'required', 'true'); - $form->setFieldAttribute('password2', 'required', 'true'); - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_users.edit.user.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - // Load the users plugins. - JPluginHelper::importPlugin('user'); - - $this->preprocessData('com_admin.profile', $data); - - return $data; - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - * - * @since 1.6 - */ - public function getItem($pk = null) - { - return parent::getItem(JFactory::getUser()->id); - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function save($data) - { - $user = JFactory::getUser(); - - unset($data['id']); - unset($data['groups']); - unset($data['sendEmail']); - unset($data['block']); - - $isUsernameCompliant = $this->getState('user.username.compliant'); - - if (!JComponentHelper::getParams('com_users')->get('change_login_name') && $isUsernameCompliant) - { - unset($data['username']); - } - - // Bind the data. - if (!$user->bind($data)) - { - $this->setError($user->getError()); - - return false; - } - - $user->groups = null; - - // Store the data. - if (!$user->save()) - { - $this->setError($user->getError()); - - return false; - } - - $this->setState('user.id', $user->id); - - return true; - } -} diff --git a/administrator/components/com_admin/models/sysinfo.php b/administrator/components/com_admin/models/sysinfo.php deleted file mode 100644 index b08decc9be32a..0000000000000 --- a/administrator/components/com_admin/models/sysinfo.php +++ /dev/null @@ -1,744 +0,0 @@ - array( - 'CONTEXT_DOCUMENT_ROOT', - 'Cookie', - 'DOCUMENT_ROOT', - 'extension_dir', - 'error_log', - 'Host', - 'HTTP_COOKIE', - 'HTTP_HOST', - 'HTTP_ORIGIN', - 'HTTP_REFERER', - 'HTTP Request', - 'include_path', - 'mysql.default_socket', - 'MYSQL_SOCKET', - 'MYSQL_INCLUDE', - 'MYSQL_LIBS', - 'mysqli.default_socket', - 'MYSQLI_SOCKET', - 'PATH', - 'Path to sendmail', - 'pdo_mysql.default_socket', - 'Referer', - 'REMOTE_ADDR', - 'SCRIPT_FILENAME', - 'sendmail_path', - 'SERVER_ADDR', - 'SERVER_ADMIN', - 'Server Administrator', - 'SERVER_NAME', - 'Server Root', - 'session.name', - 'session.save_path', - 'upload_tmp_dir', - 'User/Group', - 'open_basedir', - ), - 'other' => array( - 'db', - 'dbprefix', - 'fromname', - 'live_site', - 'log_path', - 'mailfrom', - 'memcache_server_host', - 'memcached_server_host', - 'open_basedir', - 'Origin', - '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', - 'open_basedir', - ) - ); - - /** - * System values that can be "safely" shared - * - * @var array - * - * @since 3.5 - */ - protected $safeData; - - /** - * Information about writable state of directories - * - * @var array - * @since 1.6 - */ - protected $directories = array(); - - /** - * The current editor. - * - * @var string - * @since 1.6 - */ - protected $editor = null; - - /** - * 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 a specific section in the privateSettings array - * - * @return array - * - * @since 3.5 - */ - protected function cleanPrivateData($dataArray, $dataType = 'other') - { - $dataType = isset($this->privateSettings[$dataType]) ? $dataType : 'other'; - - $privateSettings = $this->privateSettings[$dataType]; - - if (!$privateSettings) - { - return $dataArray; - } - - foreach ($dataArray as $section => $values) - { - if (is_array($values)) - { - $dataArray[$section] = $this->cleanPrivateData($values, $dataType); - } - - if (in_array($section, $privateSettings, true)) - { - $dataArray[$section] = $this->cleanSectionPrivateData($values); - } - } - - return $dataArray; - } - - /** - * Obfuscate section values - * - * @param mixed $sectionValues Section data - * - * @return mixed - * - * @since 3.5 - */ - protected function cleanSectionPrivateData($sectionValues) - { - if (!is_array($sectionValues)) - { - if (strstr($sectionValues, JPATH_ROOT)) - { - $sectionValues = 'xxxxxx'; - } - - return strlen($sectionValues) ? 'xxxxxx' : ''; - } - - foreach ($sectionValues as $setting => $value) - { - $sectionValues[$setting] = strlen($value) ? 'xxxxxx' : ''; - } - - return $sectionValues; - } - - /** - * Method to get the PHP settings - * - * @return array Some PHP settings - * - * @since 1.6 - */ - public function &getPhpSettings() - { - if (!empty($this->php_settings)) - { - return $this->php_settings; - } - - $this->php_settings = array( - 'safe_mode' => ini_get('safe_mode') == '1', - 'display_errors' => ini_get('display_errors') == '1', - 'short_open_tag' => ini_get('short_open_tag') == '1', - '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' => (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'), - 'disable_functions' => ini_get('disable_functions'), - 'xml' => extension_loaded('xml'), - 'zlib' => extension_loaded('zlib'), - 'zip' => function_exists('zip_open') && function_exists('zip_read'), - 'mbstring' => extension_loaded('mbstring'), - 'iconv' => function_exists('iconv'), - 'max_input_vars' => ini_get('max_input_vars'), - ); - - return $this->php_settings; - } - - /** - * Method to get the config - * - * @return array config values - * - * @since 1.6 - */ - public function &getConfig() - { - if (!empty($this->config)) - { - return $this->config; - } - - $registry = new Registry(new JConfig); - $this->config = $registry->toArray(); - $hidden = array('host', 'user', 'password', 'ftp_user', 'ftp_pass', 'smtpuser', 'smtppass',); - - foreach ($hidden as $key) - { - $this->config[$key] = 'xxxxxx'; - } - - return $this->config; - } - - /** - * Method to get the system information - * - * @return array System information values - * - * @since 1.6 - */ - public function &getInfo() - { - if (!empty($this->info)) - { - return $this->info; - } - - $version = new JVersion; - $platform = new JPlatform; - $db = $this->getDbo(); - - $this->info = array( - 'php' => php_uname(), - 'dbserver' => $db->getServerType(), - 'dbversion' => $db->getVersion(), - 'dbcollation' => $db->getCollation(), - 'dbconnectioncollation' => $db->getConnectionCollation(), - 'phpversion' => phpversion(), - 'server' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : getenv('SERVER_SOFTWARE'), - 'sapi_name' => php_sapi_name(), - 'version' => $version->getLongVersion(), - 'platform' => $platform->getLongVersion(), - 'useragent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '', - ); - - return $this->info; - } - - /** - * Check if the phpinfo function is enabled - * - * @return boolean True if enabled - * - * @since 3.4.1 - */ - public function phpinfoEnabled() - { - return !in_array('phpinfo', explode(',', ini_get('disable_functions'))); - } - - /** - * Method to get filter data from the model - * - * @param string $dataType Type of data to get safely - * @param bool $public If true no sensitive information will be removed - * - * @return array - * - * @since 3.5 - */ - public function getSafeData($dataType, $public = true) - { - if (isset($this->safeData[$dataType])) - { - return $this->safeData[$dataType]; - } - - $methodName = 'get' . ucfirst($dataType); - - if (!method_exists($this, $methodName)) - { - return array(); - } - - $data = $this->$methodName($public); - - $this->safeData[$dataType] = $this->cleanPrivateData($data, $dataType); - - return $this->safeData[$dataType]; - } - - /** - * Method to get the PHP info - * - * @return string PHP info - * - * @since 1.6 - */ - public function &getPHPInfo() - { - if (!$this->phpinfoEnabled()) - { - $this->php_info = JText::_('COM_ADMIN_PHPINFO_DISABLED'); - - return $this->php_info; - } - - if (!is_null($this->php_info)) - { - return $this->php_info; - } - - ob_start(); - date_default_timezone_set('UTC'); - phpinfo(INFO_GENERAL | INFO_CONFIGURATION | INFO_MODULES); - $phpInfo = ob_get_contents(); - ob_end_clean(); - preg_match_all('#]*>(.*)#siU', $phpInfo, $output); - $output = preg_replace('#]*>#', '', $output[1][0]); - $output = preg_replace('#(\w),(\w)#', '\1, \2', $output); - $output = preg_replace('#
#', '', $output); - $output = str_replace('
', '', $output); - $output = preg_replace('#
(.*)<\/tr>#', '$1', $output); - $output = str_replace('
', '', $output); - $output = str_replace('', '', $output); - $this->php_info = $output; - - return $this->php_info; - } - - /** - * Get phpinfo() output as array - * - * @return array - * - * @since 3.5 - */ - public function getPhpInfoArray() - { - // Already cached - if (null !== $this->phpInfoArray) - { - return $this->phpInfoArray; - } - - $phpInfo = $this->getPhpInfo(); - - $this->phpInfoArray = $this->parsePhpInfo($phpInfo); - - return $this->phpInfoArray; - } - - /** - * Method to get a list of installed extensions - * - * @return array installed extensions - * - * @since 3.5 - */ - public function getExtensions() - { - $installed = array(); - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('*') - ->from($db->qn('#__extensions')); - $db->setQuery($query); - - try - { - $extensions = $db->loadObjectList(); - } - catch (Exception $e) - { - try - { - JLog::add(JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()), JLog::WARNING, 'jerror'); - } - catch (RuntimeException $exception) - { - JFactory::getApplication()->enqueueMessage( - JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()), - 'warning' - ); - } - - return $installed; - } - - if (empty($extensions)) - { - return $installed; - } - - foreach ($extensions as $extension) - { - if (strlen($extension->name) == 0) - { - continue; - } - - $installed[$extension->name] = array( - 'name' => $extension->name, - 'type' => $extension->type, - 'state' => $extension->enabled ? JText::_('JENABLED') : JText::_('JDISABLED'), - 'author' => 'unknown', - 'version' => 'unknown', - 'creationDate' => 'unknown', - 'authorUrl' => 'unknown', - ); - - $manifest = new Registry($extension->manifest_cache); - - $extraData = array( - 'author' => $manifest->get('author', ''), - 'version' => $manifest->get('version', ''), - 'creationDate' => $manifest->get('creationDate', ''), - 'authorUrl' => $manifest->get('authorUrl', '') - ); - - $installed[$extension->name] = array_merge($installed[$extension->name], $extraData); - } - - return $installed; - } - - /** - * Method to get the directory states - * - * @param bool $public If true no information is going to be removed - * - * @return array States of directories - * - * @since 1.6 - */ - public function getDirectory($public = false) - { - if (!empty($this->directories)) - { - return $this->directories; - } - - $this->directories = array(); - - $registry = JFactory::getConfig(); - $cparams = JComponentHelper::getParams('com_media'); - - $this->addDirectory('administrator/components', JPATH_ADMINISTRATOR . '/components'); - $this->addDirectory('administrator/language', JPATH_ADMINISTRATOR . '/language'); - - // List all admin languages - $admin_langs = new DirectoryIterator(JPATH_ADMINISTRATOR . '/language'); - - foreach ($admin_langs as $folder) - { - if (!$folder->isDir() || $folder->isDot()) - { - continue; - } - - $this->addDirectory( - 'administrator/language/' . $folder->getFilename(), - JPATH_ADMINISTRATOR . '/language/' . $folder->getFilename() - ); - } - - // List all manifests folders - $manifests = new DirectoryIterator(JPATH_ADMINISTRATOR . '/manifests'); - - foreach ($manifests as $folder) - { - if (!$folder->isDir() || $folder->isDot()) - { - continue; - } - - $this->addDirectory( - 'administrator/manifests/' . $folder->getFilename(), - JPATH_ADMINISTRATOR . '/manifests/' . $folder->getFilename() - ); - } - - $this->addDirectory('administrator/modules', JPATH_ADMINISTRATOR . '/modules'); - $this->addDirectory('administrator/templates', JPATH_THEMES); - - $this->addDirectory('components', JPATH_SITE . '/components'); - - $this->addDirectory($cparams->get('image_path'), JPATH_SITE . '/' . $cparams->get('image_path')); - - // List all images folders - $image_folders = new DirectoryIterator(JPATH_SITE . '/' . $cparams->get('image_path')); - - foreach ($image_folders as $folder) - { - if (!$folder->isDir() || $folder->isDot()) - { - continue; - } - - $this->addDirectory( - 'images/' . $folder->getFilename(), - JPATH_SITE . '/' . $cparams->get('image_path') . '/' . $folder->getFilename() - ); - } - - $this->addDirectory('language', JPATH_SITE . '/language'); - - // List all site languages - $site_langs = new DirectoryIterator(JPATH_SITE . '/language'); - - foreach ($site_langs as $folder) - { - if (!$folder->isDir() || $folder->isDot()) - { - continue; - } - - $this->addDirectory('language/' . $folder->getFilename(), JPATH_SITE . '/language/' . $folder->getFilename()); - } - - $this->addDirectory('libraries', JPATH_LIBRARIES); - - $this->addDirectory('media', JPATH_SITE . '/media'); - $this->addDirectory('modules', JPATH_SITE . '/modules'); - $this->addDirectory('plugins', JPATH_PLUGINS); - - $plugin_groups = new DirectoryIterator(JPATH_SITE . '/plugins'); - - foreach ($plugin_groups as $folder) - { - if (!$folder->isDir() || $folder->isDot()) - { - continue; - } - - $this->addDirectory('plugins/' . $folder->getFilename(), JPATH_PLUGINS . '/' . $folder->getFilename()); - } - - $this->addDirectory('templates', JPATH_SITE . '/templates'); - $this->addDirectory('configuration.php', JPATH_CONFIGURATION . '/configuration.php'); - - // Is there a cache path in configuration.php? - if ($cache_path = trim($registry->get('cache_path', ''))) - { - // Frontend and backend use same directory for caching. - $this->addDirectory($cache_path, $cache_path, 'COM_ADMIN_CACHE_DIRECTORY'); - } - else - { - $this->addDirectory('cache', JPATH_SITE . '/cache', 'COM_ADMIN_CACHE_DIRECTORY'); - $this->addDirectory('administrator/cache', JPATH_CACHE, 'COM_ADMIN_CACHE_DIRECTORY'); - } - - if ($public) - { - $this->addDirectory( - 'log', - $registry->get('log_path', JPATH_ADMINISTRATOR . '/logs'), - 'COM_ADMIN_LOG_DIRECTORY' - ); - $this->addDirectory( - 'tmp', - $registry->get('tmp_path', JPATH_ROOT . '/tmp'), - 'COM_ADMIN_TEMP_DIRECTORY' - ); - } - else - { - $this->addDirectory( - $registry->get('log_path', JPATH_ADMINISTRATOR . '/logs'), - $registry->get('log_path', JPATH_ADMINISTRATOR . '/logs'), - 'COM_ADMIN_LOG_DIRECTORY' - ); - $this->addDirectory( - $registry->get('tmp_path', JPATH_ROOT . '/tmp'), - $registry->get('tmp_path', JPATH_ROOT . '/tmp'), - 'COM_ADMIN_TEMP_DIRECTORY' - ); - } - - return $this->directories; - } - - /** - * Method to add a directory - * - * @param string $name Directory Name - * @param string $path Directory path - * @param string $message Message - * - * @return void - * - * @since 1.6 - */ - private function addDirectory($name, $path, $message = '') - { - $this->directories[$name] = array('writable' => is_writable($path), 'message' => $message,); - } - - /** - * Method to get the editor - * - * @return string The default editor - * - * @note Has to be removed (it is present in the config...) - * @since 1.6 - */ - public function &getEditor() - { - if (!is_null($this->editor)) - { - return $this->editor; - } - - $this->editor = JFactory::getConfig()->get('editor'); - - return $this->editor; - } - - /** - * Parse phpinfo output into an array - * Source https://gist.github.com/sbmzhcn/6255314 - * - * @param string $html Output of phpinfo() - * - * @return array - * - * @since 3.5 - */ - protected function parsePhpInfo($html) - { - $html = strip_tags($html, '

'); - $html = preg_replace('/]*>([^<]+)<\/th>/', '\1', $html); - $html = preg_replace('/]*>([^<]+)<\/td>/', '\1', $html); - $t = preg_split('/(]*>[^<]+<\/h2>)/', $html, -1, PREG_SPLIT_DELIM_CAPTURE); - $r = array(); - $count = count($t); - $p1 = '([^<]+)<\/info>'; - $p2 = '/' . $p1 . '\s*' . $p1 . '\s*' . $p1 . '/'; - $p3 = '/' . $p1 . '\s*' . $p1 . '/'; - - for ($i = 1; $i < $count; $i++) - { - if (preg_match('/]*>([^<]+)<\/h2>/', $t[$i], $matchs)) - { - $name = trim($matchs[1]); - $vals = explode("\n", $t[$i + 1]); - - foreach ($vals AS $val) - { - // 3cols - if (preg_match($p2, $val, $matchs)) - { - $r[$name][trim($matchs[1])] = array(trim($matchs[2]), trim($matchs[3]),); - } - // 2cols - elseif (preg_match($p3, $val, $matchs)) - { - $r[$name][trim($matchs[1])] = trim($matchs[2]); - } - } - } - } - - return $r; - } -} diff --git a/administrator/components/com_admin/postinstall/eaccelerator.php b/administrator/components/com_admin/postinstall/eaccelerator.php index 50cc782c5962a..2ce85a26240a1 100644 --- a/administrator/components/com_admin/postinstall/eaccelerator.php +++ b/administrator/components/com_admin/postinstall/eaccelerator.php @@ -13,6 +13,11 @@ use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Client\ClientHelper; +use Joomla\CMS\Filesystem\File; +use Joomla\CMS\Filesystem\Path; +use Joomla\CMS\Factory; /** * Checks if the eAccelerator caching method is enabled. @@ -28,7 +33,7 @@ */ function admin_postinstall_eaccelerator_condition() { - $app = JFactory::getApplication(); + $app = Factory::getApplication(); $cacheHandler = $app->get('cacheHandler', ''); return (ucfirst($cacheHandler) == 'Eaccelerator'); @@ -48,34 +53,31 @@ function admin_postinstall_eaccelerator_action() $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); + $ftp = ClientHelper::getCredentials('ftp', true); // Attempt to make the file writeable if using FTP. - if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0644')) + if (!$ftp['enabled'] && Path::isOwner($file) && !Path::setPermissions($file, '0644')) { - JError::raiseNotice(500, JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE')); + Factory::getApplication()->enqueueMessage(Text::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE'), 'notice'); } // Attempt to write the configuration file as a PHP class named JConfig. $configuration = $config->toString('PHP', array('class' => 'JConfig', 'closingtag' => false)); - if (!JFile::write($file, $configuration)) + if (!File::write($file, $configuration)) { - JFactory::getApplication()->enqueueMessage(JText::_('COM_CONFIG_ERROR_WRITE_FAILED'), 'error'); + Factory::getApplication()->enqueueMessage(Text::_('COM_CONFIG_ERROR_WRITE_FAILED'), 'error'); return; } // Attempt to make the file unwriteable if using FTP. - if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0444')) + if (!$ftp['enabled'] && Path::isOwner($file) && !Path::setPermissions($file, '0444')) { - JError::raiseNotice(500, JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE')); + Factory::getApplication()->enqueueMessage(Text::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'), 'notice'); } } diff --git a/administrator/components/com_admin/postinstall/joomla40checks.php b/administrator/components/com_admin/postinstall/joomla40checks.php deleted file mode 100644 index df26ad6235327..0000000000000 --- a/administrator/components/com_admin/postinstall/joomla40checks.php +++ /dev/null @@ -1,56 +0,0 @@ -getServerType(); - $serverVersion = $db->getVersion(); - - if ($serverType == 'mssql') - { - // MS SQL support will be dropped - return true; - } - - if ($serverType == 'postgresql' && version_compare($serverVersion, '9.2', 'lt')) - { - // PostgreSQL minimum version is 9.2 - return true; - } - - if ($serverType == 'mysql' && version_compare($serverVersion, '5.5.3', 'lt')) - { - // MySQL minimum version is 5.5.3 - return true; - } - - if ($db->name === 'mysql') - { - // Using deprecated MySQL driver - return true; - } - - // PHP minimum version is 7.0 - return version_compare(PHP_VERSION, '7.0', 'lt'); -} diff --git a/administrator/components/com_admin/postinstall/languageaccess340.php b/administrator/components/com_admin/postinstall/languageaccess340.php index 915379dfd9fad..b9fab5252bbf8 100644 --- a/administrator/components/com_admin/postinstall/languageaccess340.php +++ b/administrator/components/com_admin/postinstall/languageaccess340.php @@ -12,6 +12,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\Factory; + /** * Checks if the installation is affected by the issue with content languages access in 3.4.0 * @@ -24,7 +26,7 @@ */ function admin_postinstall_languageaccess340_condition() { - $db = JFactory::getDbo(); + $db = Factory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('access')) ->from($db->quoteName('#__languages')) diff --git a/administrator/components/com_admin/script.php b/administrator/components/com_admin/script.php index 4b2b2739f6fc1..c2f893debecbc 100644 --- a/administrator/components/com_admin/script.php +++ b/administrator/components/com_admin/script.php @@ -9,6 +9,15 @@ defined('_JEXEC') or die; +use Joomla\Database\UTF8MB4SupportInterface; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Extension\ExtensionHelper; +use Joomla\CMS\Filesystem\File; +use Joomla\CMS\Log\Log; +use Joomla\CMS\Filesystem\Folder; +use Joomla\CMS\Factory; +use Joomla\CMS\Installer\Installer; + /** * Script file of Joomla CMS * @@ -27,8 +36,8 @@ class JoomlaInstallerScript /** * Function to act prior to installation process begins * - * @param string $action Which action is happening (install|uninstall|discover_install|update) - * @param JInstaller $installer The class calling this method + * @param string $action Which action is happening (install|uninstall|discover_install|update) + * @param Installer $installer The class calling this method * * @return boolean True on success * @@ -60,7 +69,7 @@ public function preflight($action, $installer) /** * Method to update Joomla! * - * @param JInstaller $installer The class calling this method + * @param Installer $installer The class calling this method * * @return void */ @@ -69,11 +78,11 @@ public function update($installer) $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; $options['text_file'] = 'joomla_update.php'; - JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); + Log::addLogger($options, Log::INFO, array('Update', 'databasequery', 'jerror')); try { - JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_DELETE_FILES'), JLog::INFO, 'Update'); + Log::add(Text::_('COM_JOOMLAUPDATE_UPDATE_LOG_DELETE_FILES'), Log::INFO, 'Update'); } catch (RuntimeException $exception) { @@ -84,7 +93,6 @@ public function update($installer) $this->deleteUnexistingFiles(); $this->updateManifestCaches(); $this->updateDatabase(); - $this->clearRadCache(); $this->updateAssets($installer); $this->clearStatsCache(); $this->convertTablesToUtf8mb4(true); @@ -95,79 +103,6 @@ public function update($installer) $this->flushSessions(); } - /** - * Called after any type of action - * - * @param string $action Which action is happening (install|uninstall|discover_install|update) - * @param JInstaller $installer The class calling this method - * - * @return boolean True on success - * - * @since 3.7.0 - */ - public function postflight($action, $installer) - { - if ($action === 'update') - { - if (!empty($this->fromVersion) && version_compare($this->fromVersion, '3.7.0', 'lt')) - { - /* - * Do a check if the menu item exists, skip if it does. Only needed when we are in pre stable state. - */ - $db = JFactory::getDbo(); - - $query = $db->getQuery(true) - ->select('id') - ->from($db->quoteName('#__menu')) - ->where($db->quoteName('menutype') . ' = ' . $db->quote('main')) - ->where($db->quoteName('title') . ' = ' . $db->quote('com_associations')) - ->where($db->quoteName('client_id') . ' = 1') - ->where($db->quoteName('component_id') . ' = 34'); - - $result = $db->setQuery($query)->loadResult(); - - if (!empty($result)) - { - return true; - } - - /* - * Add a menu item for com_associations, we need to do that here because with a plain sql statement we - * damage the nested set structure for the menu table - */ - $newMenuItem = JTable::getInstance('Menu'); - - $data = array(); - $data['menutype'] = 'main'; - $data['title'] = 'com_associations'; - $data['alias'] = 'Multilingual Associations'; - $data['path'] = 'Multilingual Associations'; - $data['link'] = 'index.php?option=com_associations'; - $data['type'] = 'component'; - $data['published'] = 1; - $data['parent_id'] = 1; - - // We have used a SQL Statement to add the extension so using 34 is safe (fingers crossed) - $data['component_id'] = 34; - $data['img'] = 'class:associations'; - $data['language'] = '*'; - $data['client_id'] = 1; - - $newMenuItem->setLocation($data['parent_id'], 'last-child'); - - if (!$newMenuItem->save($data)) - { - // Install failed, roll back changes - $installer->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK', $newMenuItem->getError())); - - return false; - } - } - } - - return true; - } - /** * Method to clear our stats plugin cache to ensure we get fresh data on Joomla Update * @@ -177,7 +112,7 @@ public function postflight($action, $installer) */ protected function clearStatsCache() { - $db = JFactory::getDbo(); + $db = Factory::getDbo(); try { @@ -193,7 +128,7 @@ protected function clearStatsCache() } catch (Exception $e) { - echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; + echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; return; } @@ -221,7 +156,7 @@ protected function clearStatsCache() } catch (Exception $e) { - echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; + echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; return; } @@ -234,13 +169,10 @@ protected function clearStatsCache() */ protected function updateDatabase() { - if (JFactory::getDbo()->getServerType() === 'mysql') + if (Factory::getDbo()->getServerType() === 'mysql') { $this->updateDatabaseMysql(); } - - $this->uninstallEosPlugin(); - $this->removeJedUpdateserver(); } /** @@ -250,7 +182,7 @@ protected function updateDatabase() */ protected function updateDatabaseMysql() { - $db = JFactory::getDbo(); + $db = Factory::getDbo(); $db->setQuery('SHOW ENGINES'); @@ -260,7 +192,7 @@ protected function updateDatabaseMysql() } catch (Exception $e) { - echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; + echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; return; } @@ -280,7 +212,7 @@ protected function updateDatabaseMysql() } catch (Exception $e) { - echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; + echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; return; } @@ -289,90 +221,6 @@ protected function updateDatabaseMysql() } } - /** - * Uninstall the 2.5 EOS plugin - * - * @return void - */ - protected function uninstallEosPlugin() - { - $db = JFactory::getDbo(); - - // Check if the 2.5 EOS plugin is present and uninstall it if so - $id = $db->setQuery( - $db->getQuery(true) - ->select('extension_id') - ->from('#__extensions') - ->where('name = ' . $db->quote('PLG_EOSNOTIFY')) - )->loadResult(); - - // Skip update when id doesn’t exists - if (!$id) - { - return; - } - - // We need to unprotect the plugin so we can uninstall it - $db->setQuery( - $db->getQuery(true) - ->update('#__extensions') - ->set('protected = 0') - ->where($db->quoteName('extension_id') . ' = ' . $id) - )->execute(); - - $installer = new JInstaller; - $installer->uninstall('plugin', $id); - } - - /** - * Remove the never used JED Updateserver - * - * @return void - * - * @since 3.7.0 - */ - protected function removeJedUpdateserver() - { - $db = JFactory::getDbo(); - - try - { - // Get the update site ID of the JED Update server - $id = $db->setQuery( - $db->getQuery(true) - ->select('update_site_id') - ->from($db->quoteName('#__update_sites')) - ->where($db->quoteName('location') . ' = ' . $db->quote('https://update.joomla.org/jed/list.xml')) - )->loadResult(); - - // Skip delete when id doesn’t exists - if (!$id) - { - return; - } - - // Delete from update sites - $db->setQuery( - $db->getQuery(true) - ->delete($db->quoteName('#__update_sites')) - ->where($db->quoteName('update_site_id') . ' = ' . $id) - )->execute(); - - // Delete from update sites extensions - $db->setQuery( - $db->getQuery(true) - ->delete($db->quoteName('#__update_sites_extensions')) - ->where($db->quoteName('update_site_id') . ' = ' . $id) - )->execute(); - } - catch (Exception $e) - { - echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; - - return; - } - } - /** * Update the manifest caches * @@ -380,10 +228,10 @@ protected function removeJedUpdateserver() */ protected function updateManifestCaches() { - $extensions = JExtensionHelper::getCoreExtensions(); + $extensions = ExtensionHelper::getCoreExtensions(); // Attempt to refresh manifest caches - $db = JFactory::getDbo(); + $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('*') ->from('#__extensions'); @@ -406,18 +254,18 @@ protected function updateManifestCaches() } catch (Exception $e) { - echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; + echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; return; } - $installer = new JInstaller; + $installer = new Installer; foreach ($extensions as $extension) { if (!$installer->refreshManifestCache($extension->extension_id)) { - echo JText::sprintf('FILES_JOOMLA_ERROR_MANIFEST', $extension->type, $extension->element, $extension->name, $extension->client_id) . '
'; + echo Text::sprintf('FILES_JOOMLA_ERROR_MANIFEST', $extension->type, $extension->element, $extension->name, $extension->client_id) . '
'; } } } @@ -430,1813 +278,3696 @@ protected function updateManifestCaches() public function deleteUnexistingFiles() { $files = array( - /* - * 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 - '/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', - '/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', - '/components/com_fields/controllers/field.php', - // Joomla 3.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', - '/administrator/components/com_admin/sql/updates/mysql/1.7.1-2011-09-15-2.sql', - '/administrator/components/com_admin/sql/updates/mysql/1.7.1-2011-09-15-3.sql', - '/administrator/components/com_admin/sql/updates/mysql/1.7.1-2011-09-15-4.sql', - '/administrator/components/com_admin/sql/updates/mysql/1.7.1-2011-09-15.sql', - '/administrator/components/com_admin/sql/updates/mysql/1.7.1-2011-09-17.sql', - '/administrator/components/com_admin/sql/updates/mysql/1.7.1-2011-09-20.sql', - '/administrator/components/com_admin/sql/updates/mysql/1.7.3-2011-10-15.sql', - '/administrator/components/com_admin/sql/updates/mysql/1.7.3-2011-10-19.sql', - '/administrator/components/com_admin/sql/updates/mysql/1.7.3-2011-11-10.sql', - '/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/views/sysinfo/tmpl/default_navigation.php', - '/administrator/components/com_categories/config.xml', - '/administrator/components/com_categories/helpers/categoriesadministrator.php', - '/administrator/components/com_contact/elements/contact.php', - '/administrator/components/com_contact/elements/index.html', - '/administrator/components/com_content/elements/article.php', - '/administrator/components/com_content/elements/author.php', - '/administrator/components/com_content/elements/index.html', - '/administrator/components/com_installer/models/fields/client.php', - '/administrator/components/com_installer/models/fields/group.php', - '/administrator/components/com_installer/models/fields/index.html', - '/administrator/components/com_installer/models/fields/search.php', - '/administrator/components/com_installer/models/forms/index.html', - '/administrator/components/com_installer/models/forms/manage.xml', - '/administrator/components/com_installer/views/install/tmpl/default_form.php', - '/administrator/components/com_installer/views/manage/tmpl/default_filter.php', - '/administrator/components/com_languages/views/installed/tmpl/default_ftp.php', - '/administrator/components/com_languages/views/installed/tmpl/default_navigation.php', - '/administrator/components/com_modules/models/fields/index.html', - '/administrator/components/com_modules/models/fields/moduleorder.php', - '/administrator/components/com_modules/models/fields/moduleposition.php', - '/administrator/components/com_newsfeeds/elements/index.html', - '/administrator/components/com_newsfeeds/elements/newsfeed.php', - '/administrator/components/com_templates/views/prevuuw/index.html', - '/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/includes/menu.php', - '/administrator/includes/router.php', - '/administrator/manifests/packages/pkg_joomla.xml', - '/administrator/modules/mod_submenu/helper.php', - '/administrator/templates/hathor/css/ie6.css', - '/administrator/templates/hathor/html/mod_submenu/index.html', - '/administrator/templates/hathor/html/mod_submenu/default.php', - '/components/com_media/controller.php', - '/components/com_media/helpers/index.html', - '/components/com_media/helpers/media.php', - '/includes/menu.php', - '/includes/pathway.php', - '/includes/router.php', - '/language/en-GB/en-GB.pkg_joomla.sys.ini', - '/libraries/cms/controller/index.html', - '/libraries/cms/controller/legacy.php', - '/libraries/cms/model/index.html', - '/libraries/cms/model/legacy.php', - '/libraries/cms/schema/changeitemmysql.php', - '/libraries/cms/schema/changeitemsqlazure.php', - '/libraries/cms/schema/changeitemsqlsrv.php', - '/libraries/cms/view/index.html', - '/libraries/cms/view/legacy.php', - '/libraries/joomla/application/application.php', - '/libraries/joomla/application/categories.php', - '/libraries/joomla/application/cli/daemon.php', - '/libraries/joomla/application/cli/index.html', - '/libraries/joomla/application/component/controller.php', - '/libraries/joomla/application/component/controlleradmin.php', - '/libraries/joomla/application/component/controllerform.php', - '/libraries/joomla/application/component/helper.php', - '/libraries/joomla/application/component/index.html', - '/libraries/joomla/application/component/model.php', - '/libraries/joomla/application/component/modeladmin.php', - '/libraries/joomla/application/component/modelform.php', - '/libraries/joomla/application/component/modelitem.php', - '/libraries/joomla/application/component/modellist.php', - '/libraries/joomla/application/component/view.php', - '/libraries/joomla/application/helper.php', - '/libraries/joomla/application/input.php', - '/libraries/joomla/application/input/cli.php', - '/libraries/joomla/application/input/cookie.php', - '/libraries/joomla/application/input/files.php', - '/libraries/joomla/application/input/index.html', - '/libraries/joomla/application/menu.php', - '/libraries/joomla/application/module/helper.php', - '/libraries/joomla/application/module/index.html', - '/libraries/joomla/application/pathway.php', - '/libraries/joomla/application/web/webclient.php', - '/libraries/joomla/base/node.php', - '/libraries/joomla/base/object.php', - '/libraries/joomla/base/observable.php', - '/libraries/joomla/base/observer.php', - '/libraries/joomla/base/tree.php', - '/libraries/joomla/cache/storage/eaccelerator.php', - '/libraries/joomla/cache/storage/helpers/helper.php', - '/libraries/joomla/cache/storage/helpers/index.html', - '/libraries/joomla/database/database/index.html', - '/libraries/joomla/database/database/mysql.php', - '/libraries/joomla/database/database/mysqlexporter.php', - '/libraries/joomla/database/database/mysqli.php', - '/libraries/joomla/database/database/mysqliexporter.php', - '/libraries/joomla/database/database/mysqliimporter.php', - '/libraries/joomla/database/database/mysqlimporter.php', - '/libraries/joomla/database/database/mysqliquery.php', - '/libraries/joomla/database/database/mysqlquery.php', - '/libraries/joomla/database/database/sqlazure.php', - '/libraries/joomla/database/database/sqlazurequery.php', - '/libraries/joomla/database/database/sqlsrv.php', - '/libraries/joomla/database/database/sqlsrvquery.php', - '/libraries/joomla/database/exception.php', - '/libraries/joomla/database/table.php', - '/libraries/joomla/database/table/asset.php', - '/libraries/joomla/database/table/category.php', - '/libraries/joomla/database/table/content.php', - '/libraries/joomla/database/table/extension.php', - '/libraries/joomla/database/table/index.html', - '/libraries/joomla/database/table/language.php', - '/libraries/joomla/database/table/menu.php', - '/libraries/joomla/database/table/menutype.php', - '/libraries/joomla/database/table/module.php', - '/libraries/joomla/database/table/session.php', - '/libraries/joomla/database/table/update.php', - '/libraries/joomla/database/table/user.php', - '/libraries/joomla/database/table/usergroup.php', - '/libraries/joomla/database/table/viewlevel.php', - '/libraries/joomla/database/tablenested.php', - '/libraries/joomla/environment/request.php', - '/libraries/joomla/environment/uri.php', - '/libraries/joomla/error/error.php', - '/libraries/joomla/error/exception.php', - '/libraries/joomla/error/index.html', - '/libraries/joomla/error/log.php', - '/libraries/joomla/error/profiler.php', - '/libraries/joomla/filesystem/archive.php', - '/libraries/joomla/filesystem/archive/bzip2.php', - '/libraries/joomla/filesystem/archive/gzip.php', - '/libraries/joomla/filesystem/archive/index.html', - '/libraries/joomla/filesystem/archive/tar.php', - '/libraries/joomla/filesystem/archive/zip.php', - '/libraries/joomla/form/fields/category.php', - '/libraries/joomla/form/fields/componentlayout.php', - '/libraries/joomla/form/fields/contentlanguage.php', - '/libraries/joomla/form/fields/editor.php', - '/libraries/joomla/form/fields/editors.php', - '/libraries/joomla/form/fields/media.php', - '/libraries/joomla/form/fields/menuitem.php', - '/libraries/joomla/form/fields/modulelayout.php', - '/libraries/joomla/html/editor.php', - '/libraries/joomla/html/html/access.php', - '/libraries/joomla/html/html/batch.php', - '/libraries/joomla/html/html/behavior.php', - '/libraries/joomla/html/html/category.php', - '/libraries/joomla/html/html/content.php', - '/libraries/joomla/html/html/contentlanguage.php', - '/libraries/joomla/html/html/date.php', - '/libraries/joomla/html/html/email.php', - '/libraries/joomla/html/html/form.php', - '/libraries/joomla/html/html/grid.php', - '/libraries/joomla/html/html/image.php', - '/libraries/joomla/html/html/index.html', - '/libraries/joomla/html/html/jgrid.php', - '/libraries/joomla/html/html/list.php', - '/libraries/joomla/html/html/menu.php', - '/libraries/joomla/html/html/number.php', - '/libraries/joomla/html/html/rules.php', - '/libraries/joomla/html/html/select.php', - '/libraries/joomla/html/html/sliders.php', - '/libraries/joomla/html/html/string.php', - '/libraries/joomla/html/html/tabs.php', - '/libraries/joomla/html/html/tel.php', - '/libraries/joomla/html/html/user.php', - '/libraries/joomla/html/pagination.php', - '/libraries/joomla/html/pane.php', - '/libraries/joomla/html/parameter.php', - '/libraries/joomla/html/parameter/element.php', - '/libraries/joomla/html/parameter/element/calendar.php', - '/libraries/joomla/html/parameter/element/category.php', - '/libraries/joomla/html/parameter/element/componentlayouts.php', - '/libraries/joomla/html/parameter/element/contentlanguages.php', - '/libraries/joomla/html/parameter/element/editors.php', - '/libraries/joomla/html/parameter/element/filelist.php', - '/libraries/joomla/html/parameter/element/folderlist.php', - '/libraries/joomla/html/parameter/element/helpsites.php', - '/libraries/joomla/html/parameter/element/hidden.php', - '/libraries/joomla/html/parameter/element/imagelist.php', - '/libraries/joomla/html/parameter/element/index.html', - '/libraries/joomla/html/parameter/element/languages.php', - '/libraries/joomla/html/parameter/element/list.php', - '/libraries/joomla/html/parameter/element/menu.php', - '/libraries/joomla/html/parameter/element/menuitem.php', - '/libraries/joomla/html/parameter/element/modulelayouts.php', - '/libraries/joomla/html/parameter/element/password.php', - '/libraries/joomla/html/parameter/element/radio.php', - '/libraries/joomla/html/parameter/element/spacer.php', - '/libraries/joomla/html/parameter/element/sql.php', - '/libraries/joomla/html/parameter/element/templatestyle.php', - '/libraries/joomla/html/parameter/element/text.php', - '/libraries/joomla/html/parameter/element/textarea.php', - '/libraries/joomla/html/parameter/element/timezones.php', - '/libraries/joomla/html/parameter/element/usergroup.php', - '/libraries/joomla/html/parameter/index.html', - '/libraries/joomla/html/toolbar.php', - '/libraries/joomla/html/toolbar/button.php', - '/libraries/joomla/html/toolbar/button/confirm.php', - '/libraries/joomla/html/toolbar/button/custom.php', - '/libraries/joomla/html/toolbar/button/help.php', - '/libraries/joomla/html/toolbar/button/index.html', - '/libraries/joomla/html/toolbar/button/link.php', - '/libraries/joomla/html/toolbar/button/popup.php', - '/libraries/joomla/html/toolbar/button/separator.php', - '/libraries/joomla/html/toolbar/button/standard.php', - '/libraries/joomla/html/toolbar/index.html', - '/libraries/joomla/image/filters/brightness.php', - '/libraries/joomla/image/filters/contrast.php', - '/libraries/joomla/image/filters/edgedetect.php', - '/libraries/joomla/image/filters/emboss.php', - '/libraries/joomla/image/filters/grayscale.php', - '/libraries/joomla/image/filters/index.html', - '/libraries/joomla/image/filters/negate.php', - '/libraries/joomla/image/filters/sketchy.php', - '/libraries/joomla/image/filters/smooth.php', - '/libraries/joomla/language/help.php', - '/libraries/joomla/language/latin_transliterate.php', - '/libraries/joomla/log/logexception.php', - '/libraries/joomla/log/loggers/database.php', - '/libraries/joomla/log/loggers/echo.php', - '/libraries/joomla/log/loggers/formattedtext.php', - '/libraries/joomla/log/loggers/index.html', - '/libraries/joomla/log/loggers/messagequeue.php', - '/libraries/joomla/log/loggers/syslog.php', - '/libraries/joomla/log/loggers/w3c.php', - '/libraries/joomla/methods.php', - '/libraries/joomla/session/storage/eaccelerator.php', - '/libraries/joomla/string/stringnormalize.php', - '/libraries/joomla/utilities/date.php', - '/libraries/joomla/utilities/simplecrypt.php', - '/libraries/joomla/utilities/simplexml.php', - '/libraries/joomla/utilities/string.php', - '/libraries/joomla/utilities/xmlelement.php', - '/media/plg_quickicon_extensionupdate/extensionupdatecheck.js', - '/media/plg_quickicon_joomlaupdate/jupdatecheck.js', - // Joomla! 3.1 - '/libraries/joomla/application/router.php', - '/libraries/joomla/form/rules/boolean.php', - '/libraries/joomla/form/rules/color.php', - '/libraries/joomla/form/rules/email.php', - '/libraries/joomla/form/rules/equals.php', - '/libraries/joomla/form/rules/index.html', - '/libraries/joomla/form/rules/options.php', - '/libraries/joomla/form/rules/rules.php', - '/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', - '/libraries/joomla/installer/adapters/language.php', - '/libraries/joomla/installer/adapters/library.php', - '/libraries/joomla/installer/adapters/module.php', - '/libraries/joomla/installer/adapters/package.php', - '/libraries/joomla/installer/adapters/plugin.php', - '/libraries/joomla/installer/adapters/template.php', - '/libraries/joomla/installer/extension.php', - '/libraries/joomla/installer/helper.php', - '/libraries/joomla/installer/index.html', - '/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', - '/media/system/js/swf-uncompressed.js', - '/media/system/js/swf.js', - '/media/system/js/uploader-uncompressed.js', - '/media/system/js/uploader.js', - '/media/system/swf/index.html', - '/media/system/swf/uploader.swf', - // Joomla! 3.2 - '/administrator/components/com_contact/models/fields/modal/contacts.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', - '/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', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-sealed.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-smile.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-surprised.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/img/smiley-tongue-out.gif', - '/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/js/emotions.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/emotions/langs/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/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/js/fullpage.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/fullpage/langs/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/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/iespell/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/inlinepopups/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/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/vertical.gif', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/insertdatetime/index.html', - '/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/layer/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/lists/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/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/js/embed.js', - '/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/nonbreaking/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/noneditable/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/pagebreak/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/paste/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/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/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/jscripts/embed.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/print/index.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/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/searchreplace/css/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/searchreplace/css/searchreplace.css', - '/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/spellchecker/css/content.css', - '/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/style/css/index.html', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/style/css/props.css', - '/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/tabfocus/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/table/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/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/js/cell.js', - '/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/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/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/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/visualchars/editor_plugin.js', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/wordcount/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/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/del.htm', - '/media/editors/tinymce/jscripts/tiny_mce/plugins/xhtmlxtras/editor_plugin.js', - '/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/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/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/pagebreak.gif', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/quicktime.gif', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/realmedia.gif', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/img/shockwave.gif', - '/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/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/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/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/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/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/ui.css', - '/media/editors/tinymce/jscripts/tiny_mce/themes/advanced/skins/o2k7/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/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/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/skins/default/content.css', - '/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/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/utils/editable_selects.js', - '/media/editors/tinymce/jscripts/tiny_mce/utils/form_utils.js', - '/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', - '/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 - '/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', - '/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/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/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/ServiceProviderInterface.php', - '/libraries/framework/Joomla/Registry/Format/index.html', - '/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/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', - '/libraries/framework/Symfony/Component/Yaml/Unescaper.php', - '/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/phpmailer.php', - '/libraries/phpmailer/pop.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', - '/media/editors/codemirror/js/closetag.js', - '/media/editors/codemirror/js/codemirror.js', - '/media/editors/codemirror/js/css.js', - '/media/editors/codemirror/js/foldcode.js', - '/media/editors/codemirror/js/foldgutter.js', - '/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', - '/administrator/templates/hathor/html/com_categories/categories/default_batch.php', - '/administrator/templates/hathor/html/com_tags/tags/default_batch.php', - '/media/editors/codemirror/mode/clike/scala.html', - '/media/editors/codemirror/mode/css/less.html', - '/media/editors/codemirror/mode/css/less_test.js', - '/media/editors/codemirror/mode/css/scss.html', - '/media/editors/codemirror/mode/css/scss_test.js', - '/media/editors/codemirror/mode/css/test.js', - '/media/editors/codemirror/mode/gfm/test.js', - '/media/editors/codemirror/mode/haml/test.js', - '/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/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/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', - '/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', - '/libraries/simplepie/LICENSE.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', - '/media/system/js/permissions.min.js', - '/libraries/platform.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', - '/administrator/components/com_banners/views/banners/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_menus/views/items/tmpl/default_batch.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_users/views/users/tmpl/default_batch.php', - '/components/com_contact/metadata.xml', - '/components/com_contact/views/category/metadata.xml', - '/components/com_contact/views/contact/metadata.xml', - '/components/com_contact/views/featured/metadata.xml', - '/components/com_content/metadata.xml', - '/components/com_content/views/archive/metadata.xml', - '/components/com_content/views/article/metadata.xml', - '/components/com_content/views/categories/metadata.xml', - '/components/com_content/views/category/metadata.xml', - '/components/com_content/views/featured/metadata.xml', - '/components/com_content/views/form/metadata.xml', - '/components/com_finder/views/search/metadata.xml', - '/components/com_mailto/views/mailto/metadata.xml', - '/components/com_mailto/views/sent/metadata.xml', - '/components/com_newsfeeds/metadata.xml', - '/components/com_newsfeeds/views/category/metadata.xml', - '/components/com_newsfeeds/views/newsfeed/metadata.xml', - '/components/com_search/views/search/metadata.xml', - '/components/com_tags/metadata.xml', - '/components/com_tags/views/tag/metadata.xml', - '/components/com_users/metadata.xml', - '/components/com_users/views/login/metadata.xml', - '/components/com_users/views/profile/metadata.xml', - '/components/com_users/views/registration/metadata.xml', - '/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_content/models/fields/votelist.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', - '/media/editors/none/none.js', - '/media/editors/none/none.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 - '/administrator/components/com_admin/postinstall/phpversion.php', - '/components/com_content/layouts/field/prepare/modal_article.php', - // Joomla 3.8.0 - '/administrator/components/com_content/models/fields/votelist.php', - '/administrator/modules/mod_menu/preset/disabled.php', - '/administrator/modules/mod_menu/preset/enabled.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/extension/helper.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', - // Joomla 3.8.4 - '/libraries/src/Mail/language/phpmailer.lang-joomla.php', + // Joomla 4.0 + '/administrator/components/com_admin/admin.php', + '/administrator/components/com_admin/controller.php', + '/administrator/components/com_admin/controllers/profile.php', + '/administrator/components/com_admin/models/forms/profile.xml', + '/administrator/components/com_admin/models/help.php', + '/administrator/components/com_admin/models/profile.php', + '/administrator/components/com_admin/models/sysinfo.php', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-06.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-16.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-19.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-20.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-1.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-2.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-22.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-23.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-24.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2012-01-10.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.0-2012-01-14.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.1-2012-01-26.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.2-2012-03-05.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.3-2012-03-13.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.4-2012-03-18.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.4-2012-03-19.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.5.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.6.sql', + '/administrator/components/com_admin/sql/updates/mysql/2.5.7.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.0.0.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.0.1.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.0.2.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.0.3.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.1.0.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.1.1.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.1.2.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.1.3.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.1.4.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.1.5.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.2.0.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.2.1.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.2.2-2013-12-22.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.2.2-2013-12-28.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-08.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-15.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-18.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-23.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.2.3-2014-02-20.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.3.0-2014-02-16.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.3.0-2014-04-02.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.3.4-2014-08-03.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.3.6-2014-09-30.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-08-24.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-01.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-16.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-10-20.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-12-03.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.4.0-2015-01-21.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.4.0-2015-02-26.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-07-01.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-13.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-26.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-30.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-11-04.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-11-05.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.0-2016-02-26.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.0-2016-03-01.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.1-2016-03-25.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.5.1-2016-03-29.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-01.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-06.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-08.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-09.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-05-06.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-01.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-05.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.6.3-2016-08-15.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.6.3-2016-08-16.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-06.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-22.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-29.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-09-29.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-01.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-02.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-04.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-19.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-21.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-24.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-27.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-08.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-09.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-15.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-17.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-31.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-02.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-15.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-17.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-03.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-09.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-19.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-04-10.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-04-19.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.3-2017-06-03.sql', + '/administrator/components/com_admin/sql/updates/mysql/3.7.4-2017-07-05.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.0.0.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.0.1.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.0.2.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.0.3.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.1.0.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.1.1.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.1.2.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.1.3.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.1.4.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.1.5.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.2.0.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.2.1.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2013-12-22.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2013-12-28.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-08.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-15.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-18.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-23.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.2.3-2014-02-20.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2013-12-21.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2014-02-16.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2014-04-02.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.3.4-2014-08-03.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.3.6-2014-09-30.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-08-24.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-09-01.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-09-16.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-10-20.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-12-03.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2015-01-21.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2015-02-26.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.4.4-2015-07-11.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-13.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-26.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-30.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-11-04.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-11-05.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2016-03-01.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-01.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-08.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-09.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-05-06.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-06-01.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-06-05.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-08-15.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-08-16.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-10-04.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-06.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-22.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-29.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-09-29.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-10-01.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-10-02.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-04.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-19.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-21.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-24.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-08.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-09.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-15.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-17.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-31.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-02.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-15.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-17.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-03-03.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-03-09.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-10.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-19.sql', + '/administrator/components/com_admin/sql/updates/postgresql/3.7.4-2017-07-05.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/2.5.2-2012-03-05.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/2.5.3-2012-03-13.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-18.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-19.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/2.5.5.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/2.5.6.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/2.5.7.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.0.0.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.0.1.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.0.2.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.0.3.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.1.0.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.1.1.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.1.2.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.1.3.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.1.4.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.1.5.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.2.0.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.2.1.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2013-12-22.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2013-12-28.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-08.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-15.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-18.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-23.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.2.3-2014-02-20.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.3.0-2014-02-16.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.3.0-2014-04-02.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.3.4-2014-08-03.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.3.6-2014-09-30.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-08-24.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-09-01.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-09-16.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-10-20.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-12-03.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2015-01-21.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2015-02-26.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.4.4-2015-07-11.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-13.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-26.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-30.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-11-04.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-11-05.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2016-03-01.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-01.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-06.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-08.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-09.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-05-06.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-06-01.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-06-05.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.6.3-2016-08-15.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.6.3-2016-08-16.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-06.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-22.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-29.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-09-29.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-10-01.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-10-02.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-04.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-19.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-24.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-08.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-09.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-15.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-17.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-31.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-02.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-15.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-16.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-17.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-03-03.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-03-09.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-04-10.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-04-19.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.7.4-2017-07-05.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-28.sql', + '/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-31.sql', + '/administrator/components/com_admin/views/help/tmpl/default.php', + '/administrator/components/com_admin/views/help/tmpl/default.xml', + '/administrator/components/com_admin/views/help/view.html.php', + '/administrator/components/com_admin/views/profile/tmpl/edit.php', + '/administrator/components/com_admin/views/profile/view.html.php', + '/administrator/components/com_admin/views/sysinfo/tmpl/default.php', + '/administrator/components/com_admin/views/sysinfo/tmpl/default.xml', + '/administrator/components/com_admin/views/sysinfo/tmpl/default_config.php', + '/administrator/components/com_admin/views/sysinfo/tmpl/default_directory.php', + '/administrator/components/com_admin/views/sysinfo/tmpl/default_phpinfo.php', + '/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php', + '/administrator/components/com_admin/views/sysinfo/tmpl/default_system.php', + '/administrator/components/com_admin/views/sysinfo/view.html.php', + '/administrator/components/com_admin/views/sysinfo/view.json.php', + '/administrator/components/com_admin/views/sysinfo/view.text.php', + '/administrator/components/com_associations/associations.php', + '/administrator/components/com_associations/controller.php', + '/administrator/components/com_associations/controllers/association.php', + '/administrator/components/com_associations/controllers/associations.php', + '/administrator/components/com_associations/helpers/associations.php', + '/administrator/components/com_associations/models/association.php', + '/administrator/components/com_associations/models/associations.php', + '/administrator/components/com_associations/models/fields/itemlanguage.php', + '/administrator/components/com_associations/models/fields/itemtype.php', + '/administrator/components/com_associations/models/fields/modalassociation.php', + '/administrator/components/com_associations/models/forms/association.xml', + '/administrator/components/com_associations/models/forms/filter_associations.xml', + '/administrator/components/com_associations/views/association/tmpl/edit.php', + '/administrator/components/com_associations/views/association/view.html.php', + '/administrator/components/com_associations/views/associations/tmpl/default.php', + '/administrator/components/com_associations/views/associations/tmpl/default.xml', + '/administrator/components/com_associations/views/associations/tmpl/modal.php', + '/administrator/components/com_associations/views/associations/view.html.php', + '/administrator/components/com_banners/banners.php', + '/administrator/components/com_banners/controller.php', + '/administrator/components/com_banners/controllers/banner.php', + '/administrator/components/com_banners/controllers/banners.php', + '/administrator/components/com_banners/controllers/client.php', + '/administrator/components/com_banners/controllers/clients.php', + '/administrator/components/com_banners/controllers/tracks.php', + '/administrator/components/com_banners/controllers/tracks.raw.php', + '/administrator/components/com_banners/models/banner.php', + '/administrator/components/com_banners/models/banners.php', + '/administrator/components/com_banners/models/client.php', + '/administrator/components/com_banners/models/clients.php', + '/administrator/components/com_banners/models/download.php', + '/administrator/components/com_banners/models/fields/bannerclient.php', + '/administrator/components/com_banners/models/fields/clicks.php', + '/administrator/components/com_banners/models/fields/impmade.php', + '/administrator/components/com_banners/models/fields/imptotal.php', + '/administrator/components/com_banners/models/forms/banner.xml', + '/administrator/components/com_banners/models/forms/client.xml', + '/administrator/components/com_banners/models/forms/download.xml', + '/administrator/components/com_banners/models/forms/filter_banners.xml', + '/administrator/components/com_banners/models/forms/filter_clients.xml', + '/administrator/components/com_banners/models/forms/filter_tracks.xml', + '/administrator/components/com_banners/models/tracks.php', + '/administrator/components/com_banners/tables/banner.php', + '/administrator/components/com_banners/tables/client.php', + '/administrator/components/com_banners/views/banner/tmpl/edit.php', + '/administrator/components/com_banners/views/banner/view.html.php', + '/administrator/components/com_banners/views/banners/tmpl/default.php', + '/administrator/components/com_banners/views/banners/tmpl/default_batch_body.php', + '/administrator/components/com_banners/views/banners/tmpl/default_batch_footer.php', + '/administrator/components/com_banners/views/banners/view.html.php', + '/administrator/components/com_banners/views/client/tmpl/edit.php', + '/administrator/components/com_banners/views/client/view.html.php', + '/administrator/components/com_banners/views/clients/tmpl/default.php', + '/administrator/components/com_banners/views/clients/view.html.php', + '/administrator/components/com_banners/views/download/tmpl/default.php', + '/administrator/components/com_banners/views/download/view.html.php', + '/administrator/components/com_banners/views/tracks/tmpl/default.php', + '/administrator/components/com_banners/views/tracks/view.html.php', + '/administrator/components/com_banners/views/tracks/view.raw.php', + '/administrator/components/com_cache/cache.php', + '/administrator/components/com_cache/controller.php', + '/administrator/components/com_cache/helpers/cache.php', + '/administrator/components/com_cache/models/cache.php', + '/administrator/components/com_cache/models/forms/filter_cache.xml', + '/administrator/components/com_cache/views/cache/tmpl/default.php', + '/administrator/components/com_cache/views/cache/tmpl/default.xml', + '/administrator/components/com_cache/views/cache/view.html.php', + '/administrator/components/com_cache/views/purge/tmpl/default.php', + '/administrator/components/com_cache/views/purge/tmpl/default.xml', + '/administrator/components/com_cache/views/purge/view.html.php', + '/administrator/components/com_categories/categories.php', + '/administrator/components/com_categories/controller.php', + '/administrator/components/com_categories/controllers/categories.php', + '/administrator/components/com_categories/controllers/category.php', + '/administrator/components/com_categories/models/categories.php', + '/administrator/components/com_categories/models/category.php', + '/administrator/components/com_categories/models/fields/categoryedit.php', + '/administrator/components/com_categories/models/fields/categoryparent.php', + '/administrator/components/com_categories/models/fields/modal/category.php', + '/administrator/components/com_categories/models/forms/category.xml', + '/administrator/components/com_categories/models/forms/filter_categories.xml', + '/administrator/components/com_categories/tables/category.php', + '/administrator/components/com_categories/views/categories/tmpl/default.php', + '/administrator/components/com_categories/views/categories/tmpl/default.xml', + '/administrator/components/com_categories/views/categories/tmpl/default_batch_body.php', + '/administrator/components/com_categories/views/categories/tmpl/default_batch_footer.php', + '/administrator/components/com_categories/views/categories/tmpl/modal.php', + '/administrator/components/com_categories/views/categories/view.html.php', + '/administrator/components/com_categories/views/category/tmpl/edit.php', + '/administrator/components/com_categories/views/category/tmpl/edit.xml', + '/administrator/components/com_categories/views/category/tmpl/edit_associations.php', + '/administrator/components/com_categories/views/category/tmpl/edit_metadata.php', + '/administrator/components/com_categories/views/category/tmpl/modal.php', + '/administrator/components/com_categories/views/category/tmpl/modal_associations.php', + '/administrator/components/com_categories/views/category/tmpl/modal_extrafields.php', + '/administrator/components/com_categories/views/category/tmpl/modal_metadata.php', + '/administrator/components/com_categories/views/category/tmpl/modal_options.php', + '/administrator/components/com_categories/views/category/view.html.php', + '/administrator/components/com_checkin/checkin.php', + '/administrator/components/com_checkin/controller.php', + '/administrator/components/com_checkin/models/checkin.php', + '/administrator/components/com_checkin/models/forms/filter_checkin.xml', + '/administrator/components/com_checkin/views/checkin/tmpl/default.php', + '/administrator/components/com_checkin/views/checkin/tmpl/default.xml', + '/administrator/components/com_checkin/views/checkin/view.html.php', + '/administrator/components/com_config/config.php', + '/administrator/components/com_config/controller.php', + '/administrator/components/com_config/controller/application/cancel.php', + '/administrator/components/com_config/controller/application/display.php', + '/administrator/components/com_config/controller/application/removeroot.php', + '/administrator/components/com_config/controller/application/save.php', + '/administrator/components/com_config/controller/application/sendtestmail.php', + '/administrator/components/com_config/controller/application/store.php', + '/administrator/components/com_config/controller/component/cancel.php', + '/administrator/components/com_config/controller/component/display.php', + '/administrator/components/com_config/controller/component/save.php', + '/administrator/components/com_config/controllers/application.php', + '/administrator/components/com_config/controllers/component.php', + '/administrator/components/com_config/helper/config.php', + '/administrator/components/com_config/model/application.php', + '/administrator/components/com_config/model/component.php', + '/administrator/components/com_config/model/field/configcomponents.php', + '/administrator/components/com_config/model/field/filters.php', + '/administrator/components/com_config/model/form/application.xml', + '/administrator/components/com_config/models/application.php', + '/administrator/components/com_config/models/component.php', + '/administrator/components/com_config/view/application/html.php', + '/administrator/components/com_config/view/application/json.php', + '/administrator/components/com_config/view/application/tmpl/default.php', + '/administrator/components/com_config/view/application/tmpl/default.xml', + '/administrator/components/com_config/view/application/tmpl/default_cache.php', + '/administrator/components/com_config/view/application/tmpl/default_cookie.php', + '/administrator/components/com_config/view/application/tmpl/default_database.php', + '/administrator/components/com_config/view/application/tmpl/default_debug.php', + '/administrator/components/com_config/view/application/tmpl/default_filters.php', + '/administrator/components/com_config/view/application/tmpl/default_ftp.php', + '/administrator/components/com_config/view/application/tmpl/default_ftplogin.php', + '/administrator/components/com_config/view/application/tmpl/default_locale.php', + '/administrator/components/com_config/view/application/tmpl/default_mail.php', + '/administrator/components/com_config/view/application/tmpl/default_metadata.php', + '/administrator/components/com_config/view/application/tmpl/default_navigation.php', + '/administrator/components/com_config/view/application/tmpl/default_permissions.php', + '/administrator/components/com_config/view/application/tmpl/default_proxy.php', + '/administrator/components/com_config/view/application/tmpl/default_seo.php', + '/administrator/components/com_config/view/application/tmpl/default_server.php', + '/administrator/components/com_config/view/application/tmpl/default_session.php', + '/administrator/components/com_config/view/application/tmpl/default_site.php', + '/administrator/components/com_config/view/application/tmpl/default_system.php', + '/administrator/components/com_config/view/component/html.php', + '/administrator/components/com_config/view/component/tmpl/default.php', + '/administrator/components/com_config/view/component/tmpl/default.xml', + '/administrator/components/com_config/view/component/tmpl/default_navigation.php', + '/administrator/components/com_contact/contact.php', + '/administrator/components/com_contact/controller.php', + '/administrator/components/com_contact/controllers/contact.php', + '/administrator/components/com_contact/controllers/contacts.php', + '/administrator/components/com_contact/models/contact.php', + '/administrator/components/com_contact/models/contacts.php', + '/administrator/components/com_contact/models/fields/modal/contact.php', + '/administrator/components/com_contact/models/forms/contact.xml', + '/administrator/components/com_contact/models/forms/fields/mail.xml', + '/administrator/components/com_contact/models/forms/filter_contacts.xml', + '/administrator/components/com_contact/tables/contact.php', + '/administrator/components/com_contact/views/contact/tmpl/edit.php', + '/administrator/components/com_contact/views/contact/tmpl/edit_associations.php', + '/administrator/components/com_contact/views/contact/tmpl/edit_metadata.php', + '/administrator/components/com_contact/views/contact/tmpl/edit_params.php', + '/administrator/components/com_contact/views/contact/tmpl/modal.php', + '/administrator/components/com_contact/views/contact/tmpl/modal_associations.php', + '/administrator/components/com_contact/views/contact/tmpl/modal_metadata.php', + '/administrator/components/com_contact/views/contact/tmpl/modal_params.php', + '/administrator/components/com_contact/views/contact/view.html.php', + '/administrator/components/com_contact/views/contacts/tmpl/default.php', + '/administrator/components/com_contact/views/contacts/tmpl/default_batch.php', + '/administrator/components/com_contact/views/contacts/tmpl/default_batch_body.php', + '/administrator/components/com_contact/views/contacts/tmpl/default_batch_footer.php', + '/administrator/components/com_contact/views/contacts/tmpl/modal.php', + '/administrator/components/com_contact/views/contacts/view.html.php', + '/administrator/components/com_content/content.php', + '/administrator/components/com_content/controller.php', + '/administrator/components/com_content/controllers/article.php', + '/administrator/components/com_content/controllers/articles.php', + '/administrator/components/com_content/controllers/featured.php', + '/administrator/components/com_content/models/article.php', + '/administrator/components/com_content/models/articles.php', + '/administrator/components/com_content/models/feature.php', + '/administrator/components/com_content/models/featured.php', + '/administrator/components/com_content/models/fields/modal/article.php', + '/administrator/components/com_content/models/fields/voteradio.php', + '/administrator/components/com_content/models/forms/article.xml', + '/administrator/components/com_content/models/forms/filter_articles.xml', + '/administrator/components/com_content/models/forms/filter_featured.xml', + '/administrator/components/com_content/tables/featured.php', + '/administrator/components/com_content/views/article/tmpl/edit.php', + '/administrator/components/com_content/views/article/tmpl/edit.xml', + '/administrator/components/com_content/views/article/tmpl/edit_associations.php', + '/administrator/components/com_content/views/article/tmpl/edit_metadata.php', + '/administrator/components/com_content/views/article/tmpl/modal.php', + '/administrator/components/com_content/views/article/tmpl/modal_associations.php', + '/administrator/components/com_content/views/article/tmpl/modal_metadata.php', + '/administrator/components/com_content/views/article/tmpl/pagebreak.php', + '/administrator/components/com_content/views/article/view.html.php', + '/administrator/components/com_content/views/articles/tmpl/default.php', + '/administrator/components/com_content/views/articles/tmpl/default.xml', + '/administrator/components/com_content/views/articles/tmpl/default_batch_body.php', + '/administrator/components/com_content/views/articles/tmpl/default_batch_footer.php', + '/administrator/components/com_content/views/articles/tmpl/modal.php', + '/administrator/components/com_content/views/articles/view.html.php', + '/administrator/components/com_content/views/featured/tmpl/default.php', + '/administrator/components/com_content/views/featured/tmpl/default.xml', + '/administrator/components/com_content/views/featured/view.html.php', + '/administrator/components/com_contenthistory/contenthistory.php', + '/administrator/components/com_contenthistory/controller.php', + '/administrator/components/com_contenthistory/controllers/history.php', + '/administrator/components/com_contenthistory/controllers/preview.php', + '/administrator/components/com_contenthistory/helpers/html/textdiff.php', + '/administrator/components/com_contenthistory/models/compare.php', + '/administrator/components/com_contenthistory/models/history.php', + '/administrator/components/com_contenthistory/models/preview.php', + '/administrator/components/com_contenthistory/views/compare/tmpl/compare.php', + '/administrator/components/com_contenthistory/views/compare/view.html.php', + '/administrator/components/com_contenthistory/views/history/tmpl/modal.php', + '/administrator/components/com_contenthistory/views/history/view.html.php', + '/administrator/components/com_contenthistory/views/preview/tmpl/preview.php', + '/administrator/components/com_contenthistory/views/preview/view.html.php', + '/administrator/components/com_cpanel/controller.php', + '/administrator/components/com_cpanel/cpanel.php', + '/administrator/components/com_cpanel/views/cpanel/tmpl/default.php', + '/administrator/components/com_cpanel/views/cpanel/tmpl/default.xml', + '/administrator/components/com_cpanel/views/cpanel/view.html.php', + '/administrator/components/com_fields/controller.php', + '/administrator/components/com_fields/controllers/field.php', + '/administrator/components/com_fields/controllers/fields.php', + '/administrator/components/com_fields/controllers/group.php', + '/administrator/components/com_fields/controllers/groups.php', + '/administrator/components/com_fields/fields.php', + '/administrator/components/com_fields/libraries/fieldslistplugin.php', + '/administrator/components/com_fields/libraries/fieldsplugin.php', + '/administrator/components/com_fields/models/field.php', + '/administrator/components/com_fields/models/fields.php', + '/administrator/components/com_fields/models/fields/fieldcontexts.php', + '/administrator/components/com_fields/models/fields/fieldgroups.php', + '/administrator/components/com_fields/models/fields/section.php', + '/administrator/components/com_fields/models/fields/type.php', + '/administrator/components/com_fields/models/forms/field.xml', + '/administrator/components/com_fields/models/forms/filter_fields.xml', + '/administrator/components/com_fields/models/forms/filter_groups.xml', + '/administrator/components/com_fields/models/forms/group.xml', + '/administrator/components/com_fields/models/group.php', + '/administrator/components/com_fields/models/groups.php', + '/administrator/components/com_fields/tables/field.php', + '/administrator/components/com_fields/tables/group.php', + '/administrator/components/com_fields/views/field/tmpl/edit.php', + '/administrator/components/com_fields/views/field/view.html.php', + '/administrator/components/com_fields/views/fields/tmpl/default.php', + '/administrator/components/com_fields/views/fields/tmpl/default_batch_body.php', + '/administrator/components/com_fields/views/fields/tmpl/default_batch_footer.php', + '/administrator/components/com_fields/views/fields/tmpl/modal.php', + '/administrator/components/com_fields/views/fields/view.html.php', + '/administrator/components/com_fields/views/group/tmpl/edit.php', + '/administrator/components/com_fields/views/group/view.html.php', + '/administrator/components/com_fields/views/groups/tmpl/default.php', + '/administrator/components/com_fields/views/groups/tmpl/default_batch_body.php', + '/administrator/components/com_fields/views/groups/tmpl/default_batch_footer.php', + '/administrator/components/com_fields/views/groups/view.html.php', + '/administrator/components/com_finder/controller.php', + '/administrator/components/com_finder/controllers/filter.php', + '/administrator/components/com_finder/controllers/filters.php', + '/administrator/components/com_finder/controllers/index.php', + '/administrator/components/com_finder/controllers/indexer.json.php', + '/administrator/components/com_finder/controllers/maps.php', + '/administrator/components/com_finder/helpers/finder.php', + '/administrator/components/com_finder/helpers/indexer/driver/sqlsrv.php', + '/administrator/components/com_finder/models/fields/branches.php', + '/administrator/components/com_finder/models/fields/contentmap.php', + '/administrator/components/com_finder/models/fields/contenttypes.php', + '/administrator/components/com_finder/models/fields/directories.php', + '/administrator/components/com_finder/models/fields/searchfilter.php', + '/administrator/components/com_finder/models/filter.php', + '/administrator/components/com_finder/models/filters.php', + '/administrator/components/com_finder/models/forms/filter.xml', + '/administrator/components/com_finder/models/forms/filter_filters.xml', + '/administrator/components/com_finder/models/forms/filter_index.xml', + '/administrator/components/com_finder/models/forms/filter_maps.xml', + '/administrator/components/com_finder/models/index.php', + '/administrator/components/com_finder/models/indexer.php', + '/administrator/components/com_finder/models/maps.php', + '/administrator/components/com_finder/models/statistics.php', + '/administrator/components/com_finder/tables/filter.php', + '/administrator/components/com_finder/tables/link.php', + '/administrator/components/com_finder/tables/map.php', + '/administrator/components/com_finder/views/filter/tmpl/edit.php', + '/administrator/components/com_finder/views/filter/view.html.php', + '/administrator/components/com_finder/views/filters/tmpl/default.php', + '/administrator/components/com_finder/views/filters/view.html.php', + '/administrator/components/com_finder/views/index/tmpl/default.php', + '/administrator/components/com_finder/views/index/view.html.php', + '/administrator/components/com_finder/views/indexer/tmpl/default.php', + '/administrator/components/com_finder/views/indexer/view.html.php', + '/administrator/components/com_finder/views/maps/tmpl/default.php', + '/administrator/components/com_finder/views/maps/view.html.php', + '/administrator/components/com_finder/views/statistics/tmpl/default.php', + '/administrator/components/com_finder/views/statistics/view.html.php', + '/administrator/components/com_installer/controller.php', + '/administrator/components/com_installer/controllers/database.php', + '/administrator/components/com_installer/controllers/discover.php', + '/administrator/components/com_installer/controllers/install.php', + '/administrator/components/com_installer/controllers/manage.php', + '/administrator/components/com_installer/controllers/update.php', + '/administrator/components/com_installer/controllers/updatesites.php', + '/administrator/components/com_installer/installer.php', + '/administrator/components/com_installer/models/database.php', + '/administrator/components/com_installer/models/discover.php', + '/administrator/components/com_installer/models/extension.php', + '/administrator/components/com_installer/models/fields/extensionstatus.php', + '/administrator/components/com_installer/models/fields/folder.php', + '/administrator/components/com_installer/models/fields/location.php', + '/administrator/components/com_installer/models/fields/type.php', + '/administrator/components/com_installer/models/forms/filter_discover.xml', + '/administrator/components/com_installer/models/forms/filter_languages.xml', + '/administrator/components/com_installer/models/forms/filter_manage.xml', + '/administrator/components/com_installer/models/forms/filter_update.xml', + '/administrator/components/com_installer/models/forms/filter_updatesites.xml', + '/administrator/components/com_installer/models/install.php', + '/administrator/components/com_installer/models/languages.php', + '/administrator/components/com_installer/models/manage.php', + '/administrator/components/com_installer/models/update.php', + '/administrator/components/com_installer/models/updatesites.php', + '/administrator/components/com_installer/models/warnings.php', + '/administrator/components/com_installer/views/database/tmpl/default.php', + '/administrator/components/com_installer/views/database/tmpl/default.xml', + '/administrator/components/com_installer/views/database/view.html.php', + '/administrator/components/com_installer/views/default/tmpl/default_ftp.php', + '/administrator/components/com_installer/views/default/tmpl/default_message.php', + '/administrator/components/com_installer/views/default/view.php', + '/administrator/components/com_installer/views/discover/tmpl/default.php', + '/administrator/components/com_installer/views/discover/tmpl/default.xml', + '/administrator/components/com_installer/views/discover/tmpl/default_item.php', + '/administrator/components/com_installer/views/discover/view.html.php', + '/administrator/components/com_installer/views/install/tmpl/default.php', + '/administrator/components/com_installer/views/install/tmpl/default.xml', + '/administrator/components/com_installer/views/install/view.html.php', + '/administrator/components/com_installer/views/languages/tmpl/default.php', + '/administrator/components/com_installer/views/languages/tmpl/default.xml', + '/administrator/components/com_installer/views/languages/view.html.php', + '/administrator/components/com_installer/views/manage/tmpl/default.php', + '/administrator/components/com_installer/views/manage/tmpl/default.xml', + '/administrator/components/com_installer/views/manage/view.html.php', + '/administrator/components/com_installer/views/update/tmpl/default.php', + '/administrator/components/com_installer/views/update/tmpl/default.xml', + '/administrator/components/com_installer/views/update/view.html.php', + '/administrator/components/com_installer/views/updatesites/tmpl/default.php', + '/administrator/components/com_installer/views/updatesites/tmpl/default.xml', + '/administrator/components/com_installer/views/updatesites/view.html.php', + '/administrator/components/com_installer/views/warnings/tmpl/default.php', + '/administrator/components/com_installer/views/warnings/tmpl/default.xml', + '/administrator/components/com_installer/views/warnings/view.html.php', + '/administrator/components/com_joomlaupdate/controller.php', + '/administrator/components/com_joomlaupdate/controllers/update.php', + '/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php', + '/administrator/components/com_joomlaupdate/helpers/select.php', + '/administrator/components/com_joomlaupdate/joomlaupdate.php', + '/administrator/components/com_joomlaupdate/models/default.php', + '/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php', + '/administrator/components/com_joomlaupdate/views/default/tmpl/default.php', + '/administrator/components/com_joomlaupdate/views/default/tmpl/default.xml', + '/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php', + '/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php', + '/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php', + '/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php', + '/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php', + '/administrator/components/com_joomlaupdate/views/default/view.html.php', + '/administrator/components/com_joomlaupdate/views/update/tmpl/default.php', + '/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php', + '/administrator/components/com_joomlaupdate/views/update/view.html.php', + '/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php', + '/administrator/components/com_joomlaupdate/views/upload/view.html.php', + '/administrator/components/com_languages/controller.php', + '/administrator/components/com_languages/controllers/installed.php', + '/administrator/components/com_languages/controllers/language.php', + '/administrator/components/com_languages/controllers/languages.php', + '/administrator/components/com_languages/controllers/override.php', + '/administrator/components/com_languages/controllers/overrides.php', + '/administrator/components/com_languages/controllers/strings.json.php', + '/administrator/components/com_languages/helpers/jsonresponse.php', + '/administrator/components/com_languages/helpers/languages.php', + '/administrator/components/com_languages/helpers/multilangstatus.php', + '/administrator/components/com_languages/languages.php', + '/administrator/components/com_languages/models/forms/filter_installed.xml', + '/administrator/components/com_languages/models/forms/filter_languages.xml', + '/administrator/components/com_languages/models/forms/language.xml', + '/administrator/components/com_languages/models/forms/override.xml', + '/administrator/components/com_languages/models/installed.php', + '/administrator/components/com_languages/models/language.php', + '/administrator/components/com_languages/models/languages.php', + '/administrator/components/com_languages/models/override.php', + '/administrator/components/com_languages/models/overrides.php', + '/administrator/components/com_languages/models/strings.php', + '/administrator/components/com_languages/views/installed/tmpl/default.php', + '/administrator/components/com_languages/views/installed/tmpl/default.xml', + '/administrator/components/com_languages/views/installed/view.html.php', + '/administrator/components/com_languages/views/language/tmpl/edit.php', + '/administrator/components/com_languages/views/language/view.html.php', + '/administrator/components/com_languages/views/languages/tmpl/default.php', + '/administrator/components/com_languages/views/languages/tmpl/default.xml', + '/administrator/components/com_languages/views/languages/view.html.php', + '/administrator/components/com_languages/views/multilangstatus/tmpl/default.php', + '/administrator/components/com_languages/views/multilangstatus/view.html.php', + '/administrator/components/com_languages/views/override/tmpl/edit.php', + '/administrator/components/com_languages/views/override/view.html.php', + '/administrator/components/com_languages/views/overrides/tmpl/default.php', + '/administrator/components/com_languages/views/overrides/tmpl/default.xml', + '/administrator/components/com_languages/views/overrides/view.html.php', + '/administrator/components/com_login/controller.php', + '/administrator/components/com_login/login.php', + '/administrator/components/com_login/models/login.php', + '/administrator/components/com_login/views/login/tmpl/default.php', + '/administrator/components/com_login/views/login/view.html.php', + '/administrator/components/com_media/controller.php', + '/administrator/components/com_media/controllers/file.json.php', + '/administrator/components/com_media/controllers/file.php', + '/administrator/components/com_media/controllers/folder.php', + '/administrator/components/com_media/helpers/media.php', + '/administrator/components/com_media/layouts/toolbar/deletemedia.php', + '/administrator/components/com_media/layouts/toolbar/newfolder.php', + '/administrator/components/com_media/layouts/toolbar/uploadmedia.php', + '/administrator/components/com_media/media.php', + '/administrator/components/com_media/models/list.php', + '/administrator/components/com_media/models/manager.php', + '/administrator/components/com_media/views/images/tmpl/default.php', + '/administrator/components/com_media/views/images/view.html.php', + '/administrator/components/com_media/views/imageslist/tmpl/default.php', + '/administrator/components/com_media/views/imageslist/tmpl/default_folder.php', + '/administrator/components/com_media/views/imageslist/tmpl/default_image.php', + '/administrator/components/com_media/views/imageslist/view.html.php', + '/administrator/components/com_media/views/media/tmpl/default.php', + '/administrator/components/com_media/views/media/tmpl/default.xml', + '/administrator/components/com_media/views/media/tmpl/default_folders.php', + '/administrator/components/com_media/views/media/tmpl/default_navigation.php', + '/administrator/components/com_media/views/media/view.html.php', + '/administrator/components/com_media/views/medialist/tmpl/default.php', + '/administrator/components/com_media/views/medialist/tmpl/details.php', + '/administrator/components/com_media/views/medialist/tmpl/details_doc.php', + '/administrator/components/com_media/views/medialist/tmpl/details_docs.php', + '/administrator/components/com_media/views/medialist/tmpl/details_folder.php', + '/administrator/components/com_media/views/medialist/tmpl/details_folders.php', + '/administrator/components/com_media/views/medialist/tmpl/details_img.php', + '/administrator/components/com_media/views/medialist/tmpl/details_imgs.php', + '/administrator/components/com_media/views/medialist/tmpl/details_up.php', + '/administrator/components/com_media/views/medialist/tmpl/details_video.php', + '/administrator/components/com_media/views/medialist/tmpl/details_videos.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs_imgs.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php', + '/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php', + '/administrator/components/com_media/views/medialist/view.html.php', + '/administrator/components/com_menus/controller.php', + '/administrator/components/com_menus/controllers/item.php', + '/administrator/components/com_menus/controllers/items.php', + '/administrator/components/com_menus/controllers/menu.php', + '/administrator/components/com_menus/controllers/menus.php', + '/administrator/components/com_menus/layouts/joomla/searchtools/default/bar.php', + '/administrator/components/com_menus/menus.php', + '/administrator/components/com_menus/models/fields/componentscategory.php', + '/administrator/components/com_menus/models/fields/menuordering.php', + '/administrator/components/com_menus/models/fields/menuparent.php', + '/administrator/components/com_menus/models/fields/menutype.php', + '/administrator/components/com_menus/models/fields/modal/menu.php', + '/administrator/components/com_menus/models/forms/filter_items.xml', + '/administrator/components/com_menus/models/forms/filter_itemsadmin.xml', + '/administrator/components/com_menus/models/forms/filter_menus.xml', + '/administrator/components/com_menus/models/forms/item.xml', + '/administrator/components/com_menus/models/forms/item_alias.xml', + '/administrator/components/com_menus/models/forms/item_component.xml', + '/administrator/components/com_menus/models/forms/item_heading.xml', + '/administrator/components/com_menus/models/forms/item_separator.xml', + '/administrator/components/com_menus/models/forms/item_url.xml', + '/administrator/components/com_menus/models/forms/itemadmin.xml', + '/administrator/components/com_menus/models/forms/itemadmin_alias.xml', + '/administrator/components/com_menus/models/forms/itemadmin_component.xml', + '/administrator/components/com_menus/models/forms/itemadmin_container.xml', + '/administrator/components/com_menus/models/forms/itemadmin_heading.xml', + '/administrator/components/com_menus/models/forms/itemadmin_separator.xml', + '/administrator/components/com_menus/models/forms/itemadmin_url.xml', + '/administrator/components/com_menus/models/forms/menu.xml', + '/administrator/components/com_menus/models/item.php', + '/administrator/components/com_menus/models/items.php', + '/administrator/components/com_menus/models/menu.php', + '/administrator/components/com_menus/models/menus.php', + '/administrator/components/com_menus/models/menutypes.php', + '/administrator/components/com_menus/tables/menu.php', + '/administrator/components/com_menus/views/item/tmpl/edit.php', + '/administrator/components/com_menus/views/item/tmpl/edit.xml', + '/administrator/components/com_menus/views/item/tmpl/edit_associations.php', + '/administrator/components/com_menus/views/item/tmpl/edit_container.php', + '/administrator/components/com_menus/views/item/tmpl/edit_modules.php', + '/administrator/components/com_menus/views/item/tmpl/edit_options.php', + '/administrator/components/com_menus/views/item/tmpl/modal.php', + '/administrator/components/com_menus/views/item/tmpl/modal_associations.php', + '/administrator/components/com_menus/views/item/tmpl/modal_options.php', + '/administrator/components/com_menus/views/item/view.html.php', + '/administrator/components/com_menus/views/items/tmpl/default.php', + '/administrator/components/com_menus/views/items/tmpl/default.xml', + '/administrator/components/com_menus/views/items/tmpl/default_batch_body.php', + '/administrator/components/com_menus/views/items/tmpl/default_batch_footer.php', + '/administrator/components/com_menus/views/items/tmpl/modal.php', + '/administrator/components/com_menus/views/items/view.html.php', + '/administrator/components/com_menus/views/menu/tmpl/edit.php', + '/administrator/components/com_menus/views/menu/tmpl/edit.xml', + '/administrator/components/com_menus/views/menu/view.html.php', + '/administrator/components/com_menus/views/menu/view.xml.php', + '/administrator/components/com_menus/views/menus/tmpl/default.php', + '/administrator/components/com_menus/views/menus/tmpl/default.xml', + '/administrator/components/com_menus/views/menus/view.html.php', + '/administrator/components/com_menus/views/menutypes/tmpl/default.php', + '/administrator/components/com_menus/views/menutypes/view.html.php', + '/administrator/components/com_messages/controller.php', + '/administrator/components/com_messages/controllers/config.php', + '/administrator/components/com_messages/controllers/message.php', + '/administrator/components/com_messages/controllers/messages.php', + '/administrator/components/com_messages/helpers/messages.php', + '/administrator/components/com_messages/messages.php', + '/administrator/components/com_messages/models/config.php', + '/administrator/components/com_messages/models/fields/messagestates.php', + '/administrator/components/com_messages/models/fields/usermessages.php', + '/administrator/components/com_messages/models/forms/config.xml', + '/administrator/components/com_messages/models/forms/filter_messages.xml', + '/administrator/components/com_messages/models/forms/message.xml', + '/administrator/components/com_messages/models/message.php', + '/administrator/components/com_messages/models/messages.php', + '/administrator/components/com_messages/tables/message.php', + '/administrator/components/com_messages/views/config/tmpl/default.php', + '/administrator/components/com_messages/views/config/view.html.php', + '/administrator/components/com_messages/views/message/tmpl/default.php', + '/administrator/components/com_messages/views/message/tmpl/edit.php', + '/administrator/components/com_messages/views/message/view.html.php', + '/administrator/components/com_messages/views/messages/tmpl/default.php', + '/administrator/components/com_messages/views/messages/view.html.php', + '/administrator/components/com_modules/controller.php', + '/administrator/components/com_modules/controllers/module.php', + '/administrator/components/com_modules/controllers/modules.php', + '/administrator/components/com_modules/helpers/xml.php', + '/administrator/components/com_modules/models/fields/modulesmodule.php', + '/administrator/components/com_modules/models/fields/modulesposition.php', + '/administrator/components/com_modules/models/forms/advanced.xml', + '/administrator/components/com_modules/models/forms/filter_modules.xml', + '/administrator/components/com_modules/models/forms/filter_modulesadmin.xml', + '/administrator/components/com_modules/models/forms/module.xml', + '/administrator/components/com_modules/models/forms/moduleadmin.xml', + '/administrator/components/com_modules/models/module.php', + '/administrator/components/com_modules/models/modules.php', + '/administrator/components/com_modules/models/positions.php', + '/administrator/components/com_modules/models/select.php', + '/administrator/components/com_modules/modules.php', + '/administrator/components/com_modules/views/module/tmpl/edit.php', + '/administrator/components/com_modules/views/module/tmpl/edit_assignment.php', + '/administrator/components/com_modules/views/module/tmpl/edit_options.php', + '/administrator/components/com_modules/views/module/tmpl/edit_positions.php', + '/administrator/components/com_modules/views/module/tmpl/modal.php', + '/administrator/components/com_modules/views/module/view.html.php', + '/administrator/components/com_modules/views/module/view.json.php', + '/administrator/components/com_modules/views/modules/tmpl/default.php', + '/administrator/components/com_modules/views/modules/tmpl/default.xml', + '/administrator/components/com_modules/views/modules/tmpl/default_batch_body.php', + '/administrator/components/com_modules/views/modules/tmpl/default_batch_footer.php', + '/administrator/components/com_modules/views/modules/tmpl/modal.php', + '/administrator/components/com_modules/views/modules/view.html.php', + '/administrator/components/com_modules/views/positions/tmpl/modal.php', + '/administrator/components/com_modules/views/positions/view.html.php', + '/administrator/components/com_modules/views/preview/tmpl/default.php', + '/administrator/components/com_modules/views/preview/view.html.php', + '/administrator/components/com_modules/views/select/tmpl/default.php', + '/administrator/components/com_modules/views/select/view.html.php', + '/administrator/components/com_newsfeeds/controller.php', + '/administrator/components/com_newsfeeds/controllers/newsfeed.php', + '/administrator/components/com_newsfeeds/controllers/newsfeeds.php', + '/administrator/components/com_newsfeeds/models/fields/modal/newsfeed.php', + '/administrator/components/com_newsfeeds/models/fields/newsfeeds.php', + '/administrator/components/com_newsfeeds/models/forms/filter_newsfeeds.xml', + '/administrator/components/com_newsfeeds/models/forms/newsfeed.xml', + '/administrator/components/com_newsfeeds/models/newsfeed.php', + '/administrator/components/com_newsfeeds/models/newsfeeds.php', + '/administrator/components/com_newsfeeds/newsfeeds.php', + '/administrator/components/com_newsfeeds/tables/newsfeed.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_associations.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_display.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_metadata.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/edit_params.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_associations.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_display.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_metadata.php', + '/administrator/components/com_newsfeeds/views/newsfeed/tmpl/modal_params.php', + '/administrator/components/com_newsfeeds/views/newsfeed/view.html.php', + '/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default.php', + '/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_body.php', + '/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/default_batch_footer.php', + '/administrator/components/com_newsfeeds/views/newsfeeds/tmpl/modal.php', + '/administrator/components/com_newsfeeds/views/newsfeeds/view.html.php', + '/administrator/components/com_plugins/controller.php', + '/administrator/components/com_plugins/controllers/plugin.php', + '/administrator/components/com_plugins/controllers/plugins.php', + '/administrator/components/com_plugins/models/fields/pluginordering.php', + '/administrator/components/com_plugins/models/fields/plugintype.php', + '/administrator/components/com_plugins/models/forms/filter_plugins.xml', + '/administrator/components/com_plugins/models/forms/plugin.xml', + '/administrator/components/com_plugins/models/plugin.php', + '/administrator/components/com_plugins/models/plugins.php', + '/administrator/components/com_plugins/plugins.php', + '/administrator/components/com_plugins/views/plugin/tmpl/edit.php', + '/administrator/components/com_plugins/views/plugin/tmpl/edit_options.php', + '/administrator/components/com_plugins/views/plugin/tmpl/modal.php', + '/administrator/components/com_plugins/views/plugin/view.html.php', + '/administrator/components/com_plugins/views/plugins/tmpl/default.php', + '/administrator/components/com_plugins/views/plugins/tmpl/default.xml', + '/administrator/components/com_plugins/views/plugins/view.html.php', + '/administrator/components/com_postinstall/controllers/message.php', + '/administrator/components/com_postinstall/fof.xml', + '/administrator/components/com_postinstall/models/messages.php', + '/administrator/components/com_postinstall/postinstall.php', + '/administrator/components/com_postinstall/toolbar.php', + '/administrator/components/com_postinstall/views/messages/tmpl/default.php', + '/administrator/components/com_postinstall/views/messages/tmpl/default.xml', + '/administrator/components/com_postinstall/views/messages/view.html.php', + '/administrator/components/com_redirect/controller.php', + '/administrator/components/com_redirect/controllers/link.php', + '/administrator/components/com_redirect/controllers/links.php', + '/administrator/components/com_redirect/models/fields/redirect.php', + '/administrator/components/com_redirect/models/forms/filter_links.xml', + '/administrator/components/com_redirect/models/forms/link.xml', + '/administrator/components/com_redirect/models/link.php', + '/administrator/components/com_redirect/models/links.php', + '/administrator/components/com_redirect/redirect.php', + '/administrator/components/com_redirect/tables/link.php', + '/administrator/components/com_redirect/views/link/tmpl/edit.php', + '/administrator/components/com_redirect/views/link/view.html.php', + '/administrator/components/com_redirect/views/links/tmpl/default.php', + '/administrator/components/com_redirect/views/links/tmpl/default.xml', + '/administrator/components/com_redirect/views/links/tmpl/default_addform.php', + '/administrator/components/com_redirect/views/links/tmpl/default_batch_body.php', + '/administrator/components/com_redirect/views/links/tmpl/default_batch_footer.php', + '/administrator/components/com_redirect/views/links/view.html.php', + '/administrator/components/com_search/controller.php', + '/administrator/components/com_search/controllers/searches.php', + '/administrator/components/com_search/models/forms/filter_searches.xml', + '/administrator/components/com_search/models/searches.php', + '/administrator/components/com_search/search.php', + '/administrator/components/com_search/views/searches/tmpl/default.php', + '/administrator/components/com_search/views/searches/view.html.php', + '/administrator/components/com_tags/controller.php', + '/administrator/components/com_tags/controllers/tag.php', + '/administrator/components/com_tags/controllers/tags.php', + '/administrator/components/com_tags/helpers/tags.php', + '/administrator/components/com_tags/models/forms/filter_tags.xml', + '/administrator/components/com_tags/models/forms/tag.xml', + '/administrator/components/com_tags/models/tag.php', + '/administrator/components/com_tags/models/tags.php', + '/administrator/components/com_tags/tables/tag.php', + '/administrator/components/com_tags/tags.php', + '/administrator/components/com_tags/views/tag/tmpl/edit.php', + '/administrator/components/com_tags/views/tag/tmpl/edit_metadata.php', + '/administrator/components/com_tags/views/tag/tmpl/edit_options.php', + '/administrator/components/com_tags/views/tag/view.html.php', + '/administrator/components/com_tags/views/tags/tmpl/default.php', + '/administrator/components/com_tags/views/tags/tmpl/default_batch_body.php', + '/administrator/components/com_tags/views/tags/tmpl/default_batch_footer.php', + '/administrator/components/com_tags/views/tags/view.html.php', + '/administrator/components/com_templates/controller.php', + '/administrator/components/com_templates/controllers/style.php', + '/administrator/components/com_templates/controllers/styles.php', + '/administrator/components/com_templates/controllers/template.php', + '/administrator/components/com_templates/models/fields/templatelocation.php', + '/administrator/components/com_templates/models/fields/templatename.php', + '/administrator/components/com_templates/models/forms/filter_styles.xml', + '/administrator/components/com_templates/models/forms/filter_templates.xml', + '/administrator/components/com_templates/models/forms/source.xml', + '/administrator/components/com_templates/models/forms/style.xml', + '/administrator/components/com_templates/models/forms/style_administrator.xml', + '/administrator/components/com_templates/models/forms/style_site.xml', + '/administrator/components/com_templates/models/style.php', + '/administrator/components/com_templates/models/styles.php', + '/administrator/components/com_templates/models/template.php', + '/administrator/components/com_templates/models/templates.php', + '/administrator/components/com_templates/tables/style.php', + '/administrator/components/com_templates/templates.php', + '/administrator/components/com_templates/views/style/tmpl/edit.php', + '/administrator/components/com_templates/views/style/tmpl/edit_assignment.php', + '/administrator/components/com_templates/views/style/tmpl/edit_options.php', + '/administrator/components/com_templates/views/style/view.html.php', + '/administrator/components/com_templates/views/style/view.json.php', + '/administrator/components/com_templates/views/styles/tmpl/default.php', + '/administrator/components/com_templates/views/styles/tmpl/default.xml', + '/administrator/components/com_templates/views/styles/view.html.php', + '/administrator/components/com_templates/views/template/tmpl/default.php', + '/administrator/components/com_templates/views/template/tmpl/default_description.php', + '/administrator/components/com_templates/views/template/tmpl/default_folders.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_copy_body.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_copy_footer.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_delete_body.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_delete_footer.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_file_body.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_file_footer.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_folder_body.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_folder_footer.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_rename_body.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_rename_footer.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_resize_body.php', + '/administrator/components/com_templates/views/template/tmpl/default_modal_resize_footer.php', + '/administrator/components/com_templates/views/template/tmpl/default_tree.php', + '/administrator/components/com_templates/views/template/tmpl/readonly.php', + '/administrator/components/com_templates/views/template/view.html.php', + '/administrator/components/com_templates/views/templates/tmpl/default.php', + '/administrator/components/com_templates/views/templates/tmpl/default.xml', + '/administrator/components/com_templates/views/templates/view.html.php', + '/administrator/components/com_users/controller.php', + '/administrator/components/com_users/controllers/group.php', + '/administrator/components/com_users/controllers/groups.php', + '/administrator/components/com_users/controllers/level.php', + '/administrator/components/com_users/controllers/levels.php', + '/administrator/components/com_users/controllers/mail.php', + '/administrator/components/com_users/controllers/note.php', + '/administrator/components/com_users/controllers/notes.php', + '/administrator/components/com_users/controllers/profile.json.php', + '/administrator/components/com_users/controllers/user.php', + '/administrator/components/com_users/controllers/users.php', + '/administrator/components/com_users/models/debuggroup.php', + '/administrator/components/com_users/models/debuguser.php', + '/administrator/components/com_users/models/fields/groupparent.php', + '/administrator/components/com_users/models/fields/levels.php', + '/administrator/components/com_users/models/forms/fields/user.xml', + '/administrator/components/com_users/models/forms/filter_debuggroup.xml', + '/administrator/components/com_users/models/forms/filter_debuguser.xml', + '/administrator/components/com_users/models/forms/filter_groups.xml', + '/administrator/components/com_users/models/forms/filter_levels.xml', + '/administrator/components/com_users/models/forms/filter_notes.xml', + '/administrator/components/com_users/models/forms/filter_users.xml', + '/administrator/components/com_users/models/forms/group.xml', + '/administrator/components/com_users/models/forms/level.xml', + '/administrator/components/com_users/models/forms/mail.xml', + '/administrator/components/com_users/models/forms/note.xml', + '/administrator/components/com_users/models/forms/user.xml', + '/administrator/components/com_users/models/group.php', + '/administrator/components/com_users/models/groups.php', + '/administrator/components/com_users/models/level.php', + '/administrator/components/com_users/models/levels.php', + '/administrator/components/com_users/models/mail.php', + '/administrator/components/com_users/models/note.php', + '/administrator/components/com_users/models/notes.php', + '/administrator/components/com_users/models/user.php', + '/administrator/components/com_users/models/users.php', + '/administrator/components/com_users/tables/note.php', + '/administrator/components/com_users/users.php', + '/administrator/components/com_users/views/debuggroup/tmpl/default.php', + '/administrator/components/com_users/views/debuggroup/view.html.php', + '/administrator/components/com_users/views/debuguser/tmpl/default.php', + '/administrator/components/com_users/views/debuguser/view.html.php', + '/administrator/components/com_users/views/group/tmpl/edit.php', + '/administrator/components/com_users/views/group/tmpl/edit.xml', + '/administrator/components/com_users/views/group/view.html.php', + '/administrator/components/com_users/views/groups/tmpl/default.php', + '/administrator/components/com_users/views/groups/tmpl/default.xml', + '/administrator/components/com_users/views/groups/view.html.php', + '/administrator/components/com_users/views/level/tmpl/edit.php', + '/administrator/components/com_users/views/level/tmpl/edit.xml', + '/administrator/components/com_users/views/level/view.html.php', + '/administrator/components/com_users/views/levels/tmpl/default.php', + '/administrator/components/com_users/views/levels/tmpl/default.xml', + '/administrator/components/com_users/views/levels/view.html.php', + '/administrator/components/com_users/views/mail/tmpl/default.php', + '/administrator/components/com_users/views/mail/tmpl/default.xml', + '/administrator/components/com_users/views/mail/view.html.php', + '/administrator/components/com_users/views/note/tmpl/edit.php', + '/administrator/components/com_users/views/note/tmpl/edit.xml', + '/administrator/components/com_users/views/note/view.html.php', + '/administrator/components/com_users/views/notes/tmpl/default.php', + '/administrator/components/com_users/views/notes/tmpl/default.xml', + '/administrator/components/com_users/views/notes/tmpl/modal.php', + '/administrator/components/com_users/views/notes/view.html.php', + '/administrator/components/com_users/views/user/tmpl/edit.php', + '/administrator/components/com_users/views/user/tmpl/edit.xml', + '/administrator/components/com_users/views/user/tmpl/edit_groups.php', + '/administrator/components/com_users/views/user/view.html.php', + '/administrator/components/com_users/views/users/tmpl/default.php', + '/administrator/components/com_users/views/users/tmpl/default.xml', + '/administrator/components/com_users/views/users/tmpl/default_batch_body.php', + '/administrator/components/com_users/views/users/tmpl/default_batch_footer.php', + '/administrator/components/com_users/views/users/tmpl/modal.php', + '/administrator/components/com_users/views/users/view.html.php', + '/administrator/includes/helper.php', + '/administrator/includes/subtoolbar.php', + '/administrator/includes/toolbar.php', + '/administrator/language/en-GB/en-GB.mod_submenu.ini', + '/administrator/language/en-GB/en-GB.mod_submenu.sys.ini', + '/administrator/language/en-GB/en-GB.plg_system_p3p.ini', + '/administrator/language/en-GB/en-GB.plg_system_p3p.sys.ini', + '/administrator/language/en-GB/en-GB.tpl_hathor.ini', + '/administrator/language/en-GB/en-GB.tpl_hathor.sys.ini', + '/administrator/language/en-GB/en-GB.tpl_isis.ini', + '/administrator/language/en-GB/en-GB.tpl_isis.sys.ini', + '/administrator/manifests/libraries/fof.xml', + '/administrator/manifests/libraries/phputf8.xml', + '/administrator/manifests/packages/pkg_weblinks.xml', + '/administrator/modules/mod_feed/helper.php', + '/administrator/modules/mod_latest/helper.php', + '/administrator/modules/mod_logged/helper.php', + '/administrator/modules/mod_login/helper.php', + '/administrator/modules/mod_menu/helper.php', + '/administrator/modules/mod_menu/menu.php', + '/administrator/modules/mod_popular/helper.php', + '/administrator/modules/mod_quickicon/helper.php', + '/administrator/modules/mod_sampledata/helper.php', + '/administrator/modules/mod_stats_admin/helper.php', + '/administrator/modules/mod_submenu/mod_submenu.php', + '/administrator/modules/mod_submenu/mod_submenu.xml', + '/administrator/modules/mod_submenu/tmpl/default.php', + '/administrator/modules/mod_version/helper.php', + '/administrator/modules/mod_version/language/en-GB/en-GB.mod_version.sys.ini', + '/administrator/templates/hathor/LICENSE.txt', + '/administrator/templates/hathor/component.php', + '/administrator/templates/hathor/cpanel.php', + '/administrator/templates/hathor/css/boldtext.css', + '/administrator/templates/hathor/css/colour_blue.css', + '/administrator/templates/hathor/css/colour_blue_rtl.css', + '/administrator/templates/hathor/css/colour_brown.css', + '/administrator/templates/hathor/css/colour_brown_rtl.css', + '/administrator/templates/hathor/css/colour_highcontrast.css', + '/administrator/templates/hathor/css/colour_highcontrast_rtl.css', + '/administrator/templates/hathor/css/colour_standard.css', + '/administrator/templates/hathor/css/colour_standard_rtl.css', + '/administrator/templates/hathor/css/error.css', + '/administrator/templates/hathor/css/ie7.css', + '/administrator/templates/hathor/css/ie8.css', + '/administrator/templates/hathor/css/template.css', + '/administrator/templates/hathor/css/template_rtl.css', + '/administrator/templates/hathor/css/theme.css', + '/administrator/templates/hathor/error.php', + '/administrator/templates/hathor/favicon.ico', + '/administrator/templates/hathor/html/com_admin/help/default.php', + '/administrator/templates/hathor/html/com_admin/profile/edit.php', + '/administrator/templates/hathor/html/com_admin/sysinfo/default.php', + '/administrator/templates/hathor/html/com_admin/sysinfo/default_config.php', + '/administrator/templates/hathor/html/com_admin/sysinfo/default_directory.php', + '/administrator/templates/hathor/html/com_admin/sysinfo/default_navigation.php', + '/administrator/templates/hathor/html/com_admin/sysinfo/default_phpsettings.php', + '/administrator/templates/hathor/html/com_admin/sysinfo/default_system.php', + '/administrator/templates/hathor/html/com_associations/associations/default.php', + '/administrator/templates/hathor/html/com_banners/banner/edit.php', + '/administrator/templates/hathor/html/com_banners/banners/default.php', + '/administrator/templates/hathor/html/com_banners/client/edit.php', + '/administrator/templates/hathor/html/com_banners/clients/default.php', + '/administrator/templates/hathor/html/com_banners/download/default.php', + '/administrator/templates/hathor/html/com_banners/tracks/default.php', + '/administrator/templates/hathor/html/com_cache/cache/default.php', + '/administrator/templates/hathor/html/com_cache/purge/default.php', + '/administrator/templates/hathor/html/com_categories/categories/default.php', + '/administrator/templates/hathor/html/com_categories/category/edit.php', + '/administrator/templates/hathor/html/com_categories/category/edit_options.php', + '/administrator/templates/hathor/html/com_checkin/checkin/default.php', + '/administrator/templates/hathor/html/com_config/application/default.php', + '/administrator/templates/hathor/html/com_config/application/default_cache.php', + '/administrator/templates/hathor/html/com_config/application/default_cookie.php', + '/administrator/templates/hathor/html/com_config/application/default_database.php', + '/administrator/templates/hathor/html/com_config/application/default_debug.php', + '/administrator/templates/hathor/html/com_config/application/default_filters.php', + '/administrator/templates/hathor/html/com_config/application/default_ftp.php', + '/administrator/templates/hathor/html/com_config/application/default_ftplogin.php', + '/administrator/templates/hathor/html/com_config/application/default_locale.php', + '/administrator/templates/hathor/html/com_config/application/default_mail.php', + '/administrator/templates/hathor/html/com_config/application/default_metadata.php', + '/administrator/templates/hathor/html/com_config/application/default_navigation.php', + '/administrator/templates/hathor/html/com_config/application/default_permissions.php', + '/administrator/templates/hathor/html/com_config/application/default_seo.php', + '/administrator/templates/hathor/html/com_config/application/default_server.php', + '/administrator/templates/hathor/html/com_config/application/default_session.php', + '/administrator/templates/hathor/html/com_config/application/default_site.php', + '/administrator/templates/hathor/html/com_config/application/default_system.php', + '/administrator/templates/hathor/html/com_config/component/default.php', + '/administrator/templates/hathor/html/com_contact/contact/edit.php', + '/administrator/templates/hathor/html/com_contact/contact/edit_params.php', + '/administrator/templates/hathor/html/com_contact/contacts/default.php', + '/administrator/templates/hathor/html/com_contact/contacts/modal.php', + '/administrator/templates/hathor/html/com_content/article/edit.php', + '/administrator/templates/hathor/html/com_content/articles/default.php', + '/administrator/templates/hathor/html/com_content/articles/modal.php', + '/administrator/templates/hathor/html/com_content/featured/default.php', + '/administrator/templates/hathor/html/com_contenthistory/history/modal.php', + '/administrator/templates/hathor/html/com_cpanel/cpanel/default.php', + '/administrator/templates/hathor/html/com_fields/field/edit.php', + '/administrator/templates/hathor/html/com_fields/fields/default.php', + '/administrator/templates/hathor/html/com_fields/group/edit.php', + '/administrator/templates/hathor/html/com_fields/groups/default.php', + '/administrator/templates/hathor/html/com_finder/filters/default.php', + '/administrator/templates/hathor/html/com_finder/index/default.php', + '/administrator/templates/hathor/html/com_finder/maps/default.php', + '/administrator/templates/hathor/html/com_installer/database/default.php', + '/administrator/templates/hathor/html/com_installer/default/default_ftp.php', + '/administrator/templates/hathor/html/com_installer/discover/default.php', + '/administrator/templates/hathor/html/com_installer/install/default.php', + '/administrator/templates/hathor/html/com_installer/install/default_form.php', + '/administrator/templates/hathor/html/com_installer/languages/default.php', + '/administrator/templates/hathor/html/com_installer/languages/default_filter.php', + '/administrator/templates/hathor/html/com_installer/manage/default.php', + '/administrator/templates/hathor/html/com_installer/manage/default_filter.php', + '/administrator/templates/hathor/html/com_installer/update/default.php', + '/administrator/templates/hathor/html/com_installer/warnings/default.php', + '/administrator/templates/hathor/html/com_joomlaupdate/default/default.php', + '/administrator/templates/hathor/html/com_languages/installed/default.php', + '/administrator/templates/hathor/html/com_languages/installed/default_ftp.php', + '/administrator/templates/hathor/html/com_languages/languages/default.php', + '/administrator/templates/hathor/html/com_languages/overrides/default.php', + '/administrator/templates/hathor/html/com_menus/item/edit.php', + '/administrator/templates/hathor/html/com_menus/item/edit_options.php', + '/administrator/templates/hathor/html/com_menus/items/default.php', + '/administrator/templates/hathor/html/com_menus/menu/edit.php', + '/administrator/templates/hathor/html/com_menus/menus/default.php', + '/administrator/templates/hathor/html/com_menus/menutypes/default.php', + '/administrator/templates/hathor/html/com_messages/message/edit.php', + '/administrator/templates/hathor/html/com_messages/messages/default.php', + '/administrator/templates/hathor/html/com_modules/module/edit.php', + '/administrator/templates/hathor/html/com_modules/module/edit_assignment.php', + '/administrator/templates/hathor/html/com_modules/module/edit_options.php', + '/administrator/templates/hathor/html/com_modules/modules/default.php', + '/administrator/templates/hathor/html/com_modules/positions/modal.php', + '/administrator/templates/hathor/html/com_newsfeeds/newsfeed/edit.php', + '/administrator/templates/hathor/html/com_newsfeeds/newsfeed/edit_params.php', + '/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/default.php', + '/administrator/templates/hathor/html/com_newsfeeds/newsfeeds/modal.php', + '/administrator/templates/hathor/html/com_plugins/plugin/edit.php', + '/administrator/templates/hathor/html/com_plugins/plugin/edit_options.php', + '/administrator/templates/hathor/html/com_plugins/plugins/default.php', + '/administrator/templates/hathor/html/com_postinstall/messages/default.php', + '/administrator/templates/hathor/html/com_redirect/links/default.php', + '/administrator/templates/hathor/html/com_search/searches/default.php', + '/administrator/templates/hathor/html/com_tags/tag/edit.php', + '/administrator/templates/hathor/html/com_tags/tag/edit_metadata.php', + '/administrator/templates/hathor/html/com_tags/tag/edit_options.php', + '/administrator/templates/hathor/html/com_tags/tags/default.php', + '/administrator/templates/hathor/html/com_templates/style/edit.php', + '/administrator/templates/hathor/html/com_templates/style/edit_assignment.php', + '/administrator/templates/hathor/html/com_templates/style/edit_options.php', + '/administrator/templates/hathor/html/com_templates/styles/default.php', + '/administrator/templates/hathor/html/com_templates/template/default.php', + '/administrator/templates/hathor/html/com_templates/template/default_description.php', + '/administrator/templates/hathor/html/com_templates/template/default_folders.php', + '/administrator/templates/hathor/html/com_templates/template/default_tree.php', + '/administrator/templates/hathor/html/com_templates/templates/default.php', + '/administrator/templates/hathor/html/com_users/debuggroup/default.php', + '/administrator/templates/hathor/html/com_users/debuguser/default.php', + '/administrator/templates/hathor/html/com_users/groups/default.php', + '/administrator/templates/hathor/html/com_users/levels/default.php', + '/administrator/templates/hathor/html/com_users/note/edit.php', + '/administrator/templates/hathor/html/com_users/notes/default.php', + '/administrator/templates/hathor/html/com_users/user/edit.php', + '/administrator/templates/hathor/html/com_users/users/default.php', + '/administrator/templates/hathor/html/com_users/users/modal.php', + '/administrator/templates/hathor/html/com_weblinks/weblink/edit.php', + '/administrator/templates/hathor/html/com_weblinks/weblink/edit_params.php', + '/administrator/templates/hathor/html/com_weblinks/weblinks/default.php', + '/administrator/templates/hathor/html/layouts/com_media/toolbar/deletemedia.php', + '/administrator/templates/hathor/html/layouts/com_media/toolbar/newfolder.php', + '/administrator/templates/hathor/html/layouts/com_media/toolbar/uploadmedia.php', + '/administrator/templates/hathor/html/layouts/com_messages/toolbar/mysettings.php', + '/administrator/templates/hathor/html/layouts/com_modules/toolbar/cancelselect.php', + '/administrator/templates/hathor/html/layouts/com_modules/toolbar/newmodule.php', + '/administrator/templates/hathor/html/layouts/joomla/edit/details.php', + '/administrator/templates/hathor/html/layouts/joomla/edit/fieldset.php', + '/administrator/templates/hathor/html/layouts/joomla/edit/global.php', + '/administrator/templates/hathor/html/layouts/joomla/edit/metadata.php', + '/administrator/templates/hathor/html/layouts/joomla/edit/params.php', + '/administrator/templates/hathor/html/layouts/joomla/quickicons/icon.php', + '/administrator/templates/hathor/html/layouts/joomla/sidebars/submenu.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/base.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/batch.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/confirm.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/containerclose.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/containeropen.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/help.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/iconclass.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/link.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/modal.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/popup.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/separator.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/slider.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/standard.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/title.php', + '/administrator/templates/hathor/html/layouts/joomla/toolbar/versions.php', + '/administrator/templates/hathor/html/layouts/plugins/user/profile/fields/dob.php', + '/administrator/templates/hathor/html/mod_login/default.php', + '/administrator/templates/hathor/html/mod_quickicon/default.php', + '/administrator/templates/hathor/html/modules.php', + '/administrator/templates/hathor/html/pagination.php', + '/administrator/templates/hathor/images/admin/blank.png', + '/administrator/templates/hathor/images/admin/checked_out.png', + '/administrator/templates/hathor/images/admin/collapseall.png', + '/administrator/templates/hathor/images/admin/disabled.png', + '/administrator/templates/hathor/images/admin/downarrow-1.png', + '/administrator/templates/hathor/images/admin/downarrow.png', + '/administrator/templates/hathor/images/admin/downarrow0.png', + '/administrator/templates/hathor/images/admin/expandall.png', + '/administrator/templates/hathor/images/admin/featured.png', + '/administrator/templates/hathor/images/admin/filesave.png', + '/administrator/templates/hathor/images/admin/filter_16.png', + '/administrator/templates/hathor/images/admin/icon-16-allow.png', + '/administrator/templates/hathor/images/admin/icon-16-allowinactive.png', + '/administrator/templates/hathor/images/admin/icon-16-deny.png', + '/administrator/templates/hathor/images/admin/icon-16-denyinactive.png', + '/administrator/templates/hathor/images/admin/icon-16-links.png', + '/administrator/templates/hathor/images/admin/icon-16-notice-note.png', + '/administrator/templates/hathor/images/admin/icon-16-protected.png', + '/administrator/templates/hathor/images/admin/menu_divider.png', + '/administrator/templates/hathor/images/admin/note_add_16.png', + '/administrator/templates/hathor/images/admin/publish_g.png', + '/administrator/templates/hathor/images/admin/publish_r.png', + '/administrator/templates/hathor/images/admin/publish_x.png', + '/administrator/templates/hathor/images/admin/publish_y.png', + '/administrator/templates/hathor/images/admin/sort_asc.png', + '/administrator/templates/hathor/images/admin/sort_desc.png', + '/administrator/templates/hathor/images/admin/tick.png', + '/administrator/templates/hathor/images/admin/trash.png', + '/administrator/templates/hathor/images/admin/uparrow-1.png', + '/administrator/templates/hathor/images/admin/uparrow.png', + '/administrator/templates/hathor/images/admin/uparrow0.png', + '/administrator/templates/hathor/images/arrow.png', + '/administrator/templates/hathor/images/bg-menu.gif', + '/administrator/templates/hathor/images/calendar.png', + '/administrator/templates/hathor/images/header/icon-48-alert.png', + '/administrator/templates/hathor/images/header/icon-48-apply.png', + '/administrator/templates/hathor/images/header/icon-48-archive.png', + '/administrator/templates/hathor/images/header/icon-48-article-add.png', + '/administrator/templates/hathor/images/header/icon-48-article-edit.png', + '/administrator/templates/hathor/images/header/icon-48-article.png', + '/administrator/templates/hathor/images/header/icon-48-assoc.png', + '/administrator/templates/hathor/images/header/icon-48-banner-categories.png', + '/administrator/templates/hathor/images/header/icon-48-banner-client.png', + '/administrator/templates/hathor/images/header/icon-48-banner-tracks.png', + '/administrator/templates/hathor/images/header/icon-48-banner.png', + '/administrator/templates/hathor/images/header/icon-48-calendar.png', + '/administrator/templates/hathor/images/header/icon-48-category-add.png', + '/administrator/templates/hathor/images/header/icon-48-category.png', + '/administrator/templates/hathor/images/header/icon-48-checkin.png', + '/administrator/templates/hathor/images/header/icon-48-clear.png', + '/administrator/templates/hathor/images/header/icon-48-component.png', + '/administrator/templates/hathor/images/header/icon-48-config.png', + '/administrator/templates/hathor/images/header/icon-48-contacts-categories.png', + '/administrator/templates/hathor/images/header/icon-48-contacts.png', + '/administrator/templates/hathor/images/header/icon-48-content.png', + '/administrator/templates/hathor/images/header/icon-48-cpanel.png', + '/administrator/templates/hathor/images/header/icon-48-default.png', + '/administrator/templates/hathor/images/header/icon-48-deny.png', + '/administrator/templates/hathor/images/header/icon-48-download.png', + '/administrator/templates/hathor/images/header/icon-48-edit.png', + '/administrator/templates/hathor/images/header/icon-48-extension.png', + '/administrator/templates/hathor/images/header/icon-48-featured.png', + '/administrator/templates/hathor/images/header/icon-48-frontpage.png', + '/administrator/templates/hathor/images/header/icon-48-generic.png', + '/administrator/templates/hathor/images/header/icon-48-groups-add.png', + '/administrator/templates/hathor/images/header/icon-48-groups.png', + '/administrator/templates/hathor/images/header/icon-48-help-forum.png', + '/administrator/templates/hathor/images/header/icon-48-help-this.png', + '/administrator/templates/hathor/images/header/icon-48-help_header.png', + '/administrator/templates/hathor/images/header/icon-48-inbox.png', + '/administrator/templates/hathor/images/header/icon-48-info.png', + '/administrator/templates/hathor/images/header/icon-48-install.png', + '/administrator/templates/hathor/images/header/icon-48-jupdate-updatefound.png', + '/administrator/templates/hathor/images/header/icon-48-jupdate-uptodate.png', + '/administrator/templates/hathor/images/header/icon-48-language.png', + '/administrator/templates/hathor/images/header/icon-48-levels-add.png', + '/administrator/templates/hathor/images/header/icon-48-levels.png', + '/administrator/templates/hathor/images/header/icon-48-links-cat.png', + '/administrator/templates/hathor/images/header/icon-48-links.png', + '/administrator/templates/hathor/images/header/icon-48-massmail.png', + '/administrator/templates/hathor/images/header/icon-48-media.png', + '/administrator/templates/hathor/images/header/icon-48-menu-add.png', + '/administrator/templates/hathor/images/header/icon-48-menu.png', + '/administrator/templates/hathor/images/header/icon-48-menumgr.png', + '/administrator/templates/hathor/images/header/icon-48-module.png', + '/administrator/templates/hathor/images/header/icon-48-move.png', + '/administrator/templates/hathor/images/header/icon-48-new-privatemessage.png', + '/administrator/templates/hathor/images/header/icon-48-newcategory.png', + '/administrator/templates/hathor/images/header/icon-48-newsfeeds-cat.png', + '/administrator/templates/hathor/images/header/icon-48-newsfeeds.png', + '/administrator/templates/hathor/images/header/icon-48-notice.png', + '/administrator/templates/hathor/images/header/icon-48-plugin.png', + '/administrator/templates/hathor/images/header/icon-48-preview.png', + '/administrator/templates/hathor/images/header/icon-48-print.png', + '/administrator/templates/hathor/images/header/icon-48-purge.png', + '/administrator/templates/hathor/images/header/icon-48-puzzle.png', + '/administrator/templates/hathor/images/header/icon-48-read-privatemessage.png', + '/administrator/templates/hathor/images/header/icon-48-readmess.png', + '/administrator/templates/hathor/images/header/icon-48-redirect.png', + '/administrator/templates/hathor/images/header/icon-48-revert.png', + '/administrator/templates/hathor/images/header/icon-48-search.png', + '/administrator/templates/hathor/images/header/icon-48-section.png', + '/administrator/templates/hathor/images/header/icon-48-send.png', + '/administrator/templates/hathor/images/header/icon-48-static.png', + '/administrator/templates/hathor/images/header/icon-48-stats.png', + '/administrator/templates/hathor/images/header/icon-48-tags.png', + '/administrator/templates/hathor/images/header/icon-48-themes.png', + '/administrator/templates/hathor/images/header/icon-48-trash.png', + '/administrator/templates/hathor/images/header/icon-48-unarchive.png', + '/administrator/templates/hathor/images/header/icon-48-upload.png', + '/administrator/templates/hathor/images/header/icon-48-user-add.png', + '/administrator/templates/hathor/images/header/icon-48-user-edit.png', + '/administrator/templates/hathor/images/header/icon-48-user-profile.png', + '/administrator/templates/hathor/images/header/icon-48-user.png', + '/administrator/templates/hathor/images/header/icon-48-writemess.png', + '/administrator/templates/hathor/images/header/icon-messaging.png', + '/administrator/templates/hathor/images/j_arrow.png', + '/administrator/templates/hathor/images/j_arrow_down.png', + '/administrator/templates/hathor/images/j_arrow_left.png', + '/administrator/templates/hathor/images/j_arrow_right.png', + '/administrator/templates/hathor/images/j_login_lock.png', + '/administrator/templates/hathor/images/j_logo.png', + '/administrator/templates/hathor/images/logo.png', + '/administrator/templates/hathor/images/menu/icon-16-alert.png', + '/administrator/templates/hathor/images/menu/icon-16-apply.png', + '/administrator/templates/hathor/images/menu/icon-16-archive.png', + '/administrator/templates/hathor/images/menu/icon-16-article.png', + '/administrator/templates/hathor/images/menu/icon-16-assoc.png', + '/administrator/templates/hathor/images/menu/icon-16-back-user.png', + '/administrator/templates/hathor/images/menu/icon-16-banner-categories.png', + '/administrator/templates/hathor/images/menu/icon-16-banner-client.png', + '/administrator/templates/hathor/images/menu/icon-16-banner-tracks.png', + '/administrator/templates/hathor/images/menu/icon-16-banner.png', + '/administrator/templates/hathor/images/menu/icon-16-calendar.png', + '/administrator/templates/hathor/images/menu/icon-16-category.png', + '/administrator/templates/hathor/images/menu/icon-16-checkin.png', + '/administrator/templates/hathor/images/menu/icon-16-clear.png', + '/administrator/templates/hathor/images/menu/icon-16-component.png', + '/administrator/templates/hathor/images/menu/icon-16-config.png', + '/administrator/templates/hathor/images/menu/icon-16-contacts-categories.png', + '/administrator/templates/hathor/images/menu/icon-16-contacts.png', + '/administrator/templates/hathor/images/menu/icon-16-content.png', + '/administrator/templates/hathor/images/menu/icon-16-cpanel.png', + '/administrator/templates/hathor/images/menu/icon-16-default.png', + '/administrator/templates/hathor/images/menu/icon-16-delete.png', + '/administrator/templates/hathor/images/menu/icon-16-deny.png', + '/administrator/templates/hathor/images/menu/icon-16-download.png', + '/administrator/templates/hathor/images/menu/icon-16-edit.png', + '/administrator/templates/hathor/images/menu/icon-16-featured.png', + '/administrator/templates/hathor/images/menu/icon-16-frontpage.png', + '/administrator/templates/hathor/images/menu/icon-16-generic.png', + '/administrator/templates/hathor/images/menu/icon-16-groups.png', + '/administrator/templates/hathor/images/menu/icon-16-help-community.png', + '/administrator/templates/hathor/images/menu/icon-16-help-dev.png', + '/administrator/templates/hathor/images/menu/icon-16-help-docs.png', + '/administrator/templates/hathor/images/menu/icon-16-help-forum.png', + '/administrator/templates/hathor/images/menu/icon-16-help-jed.png', + '/administrator/templates/hathor/images/menu/icon-16-help-jrd.png', + '/administrator/templates/hathor/images/menu/icon-16-help-security.png', + '/administrator/templates/hathor/images/menu/icon-16-help-shop.png', + '/administrator/templates/hathor/images/menu/icon-16-help-this.png', + '/administrator/templates/hathor/images/menu/icon-16-help-trans.png', + '/administrator/templates/hathor/images/menu/icon-16-help.png', + '/administrator/templates/hathor/images/menu/icon-16-inbox.png', + '/administrator/templates/hathor/images/menu/icon-16-info.png', + '/administrator/templates/hathor/images/menu/icon-16-install.png', + '/administrator/templates/hathor/images/menu/icon-16-language.png', + '/administrator/templates/hathor/images/menu/icon-16-levels.png', + '/administrator/templates/hathor/images/menu/icon-16-links-cat.png', + '/administrator/templates/hathor/images/menu/icon-16-links.png', + '/administrator/templates/hathor/images/menu/icon-16-logout.png', + '/administrator/templates/hathor/images/menu/icon-16-maintenance.png', + '/administrator/templates/hathor/images/menu/icon-16-massmail.png', + '/administrator/templates/hathor/images/menu/icon-16-media.png', + '/administrator/templates/hathor/images/menu/icon-16-menu.png', + '/administrator/templates/hathor/images/menu/icon-16-menumgr.png', + '/administrator/templates/hathor/images/menu/icon-16-messages.png', + '/administrator/templates/hathor/images/menu/icon-16-messaging.png', + '/administrator/templates/hathor/images/menu/icon-16-module.png', + '/administrator/templates/hathor/images/menu/icon-16-move.png', + '/administrator/templates/hathor/images/menu/icon-16-new-privatemessage.png', + '/administrator/templates/hathor/images/menu/icon-16-new.png', + '/administrator/templates/hathor/images/menu/icon-16-newarticle.png', + '/administrator/templates/hathor/images/menu/icon-16-newcategory.png', + '/administrator/templates/hathor/images/menu/icon-16-newgroup.png', + '/administrator/templates/hathor/images/menu/icon-16-newlevel.png', + '/administrator/templates/hathor/images/menu/icon-16-newsfeeds-cat.png', + '/administrator/templates/hathor/images/menu/icon-16-newsfeeds.png', + '/administrator/templates/hathor/images/menu/icon-16-newuser.png', + '/administrator/templates/hathor/images/menu/icon-16-nopreview.png', + '/administrator/templates/hathor/images/menu/icon-16-notdefault.png', + '/administrator/templates/hathor/images/menu/icon-16-notice.png', + '/administrator/templates/hathor/images/menu/icon-16-plugin.png', + '/administrator/templates/hathor/images/menu/icon-16-preview.png', + '/administrator/templates/hathor/images/menu/icon-16-print.png', + '/administrator/templates/hathor/images/menu/icon-16-purge.png', + '/administrator/templates/hathor/images/menu/icon-16-puzzle.png', + '/administrator/templates/hathor/images/menu/icon-16-read-privatemessage.png', + '/administrator/templates/hathor/images/menu/icon-16-readmess.png', + '/administrator/templates/hathor/images/menu/icon-16-redirect.png', + '/administrator/templates/hathor/images/menu/icon-16-revert.png', + '/administrator/templates/hathor/images/menu/icon-16-search.png', + '/administrator/templates/hathor/images/menu/icon-16-send.png', + '/administrator/templates/hathor/images/menu/icon-16-stats.png', + '/administrator/templates/hathor/images/menu/icon-16-tags.png', + '/administrator/templates/hathor/images/menu/icon-16-themes.png', + '/administrator/templates/hathor/images/menu/icon-16-trash.png', + '/administrator/templates/hathor/images/menu/icon-16-unarticle.png', + '/administrator/templates/hathor/images/menu/icon-16-upload.png', + '/administrator/templates/hathor/images/menu/icon-16-user-dd.png', + '/administrator/templates/hathor/images/menu/icon-16-user-note.png', + '/administrator/templates/hathor/images/menu/icon-16-user.png', + '/administrator/templates/hathor/images/menu/icon-16-viewsite.png', + '/administrator/templates/hathor/images/menu/icon-16-writemess.png', + '/administrator/templates/hathor/images/mini_icon.png', + '/administrator/templates/hathor/images/notice-alert.png', + '/administrator/templates/hathor/images/notice-info.png', + '/administrator/templates/hathor/images/notice-note.png', + '/administrator/templates/hathor/images/required.png', + '/administrator/templates/hathor/images/selector-arrow-hc.png', + '/administrator/templates/hathor/images/selector-arrow-rtl.png', + '/administrator/templates/hathor/images/selector-arrow-std.png', + '/administrator/templates/hathor/images/selector-arrow.png', + '/administrator/templates/hathor/images/system/calendar.png', + '/administrator/templates/hathor/images/system/selector-arrow.png', + '/administrator/templates/hathor/images/toolbar/icon-32-adduser.png', + '/administrator/templates/hathor/images/toolbar/icon-32-alert.png', + '/administrator/templates/hathor/images/toolbar/icon-32-apply.png', + '/administrator/templates/hathor/images/toolbar/icon-32-archive.png', + '/administrator/templates/hathor/images/toolbar/icon-32-article-add.png', + '/administrator/templates/hathor/images/toolbar/icon-32-article.png', + '/administrator/templates/hathor/images/toolbar/icon-32-back.png', + '/administrator/templates/hathor/images/toolbar/icon-32-banner-categories.png', + '/administrator/templates/hathor/images/toolbar/icon-32-banner-client.png', + '/administrator/templates/hathor/images/toolbar/icon-32-banner-tracks.png', + '/administrator/templates/hathor/images/toolbar/icon-32-banner.png', + '/administrator/templates/hathor/images/toolbar/icon-32-batch.png', + '/administrator/templates/hathor/images/toolbar/icon-32-calendar.png', + '/administrator/templates/hathor/images/toolbar/icon-32-cancel.png', + '/administrator/templates/hathor/images/toolbar/icon-32-checkin.png', + '/administrator/templates/hathor/images/toolbar/icon-32-cog.png', + '/administrator/templates/hathor/images/toolbar/icon-32-component.png', + '/administrator/templates/hathor/images/toolbar/icon-32-config.png', + '/administrator/templates/hathor/images/toolbar/icon-32-contacts-categories.png', + '/administrator/templates/hathor/images/toolbar/icon-32-contacts.png', + '/administrator/templates/hathor/images/toolbar/icon-32-copy.png', + '/administrator/templates/hathor/images/toolbar/icon-32-css.png', + '/administrator/templates/hathor/images/toolbar/icon-32-default.png', + '/administrator/templates/hathor/images/toolbar/icon-32-delete-style.png', + '/administrator/templates/hathor/images/toolbar/icon-32-delete.png', + '/administrator/templates/hathor/images/toolbar/icon-32-deny.png', + '/administrator/templates/hathor/images/toolbar/icon-32-download.png', + '/administrator/templates/hathor/images/toolbar/icon-32-edit.png', + '/administrator/templates/hathor/images/toolbar/icon-32-error.png', + '/administrator/templates/hathor/images/toolbar/icon-32-export.png', + '/administrator/templates/hathor/images/toolbar/icon-32-extension.png', + '/administrator/templates/hathor/images/toolbar/icon-32-featured.png', + '/administrator/templates/hathor/images/toolbar/icon-32-forward.png', + '/administrator/templates/hathor/images/toolbar/icon-32-help.png', + '/administrator/templates/hathor/images/toolbar/icon-32-html.png', + '/administrator/templates/hathor/images/toolbar/icon-32-inbox.png', + '/administrator/templates/hathor/images/toolbar/icon-32-info.png', + '/administrator/templates/hathor/images/toolbar/icon-32-links.png', + '/administrator/templates/hathor/images/toolbar/icon-32-lock.png', + '/administrator/templates/hathor/images/toolbar/icon-32-menu.png', + '/administrator/templates/hathor/images/toolbar/icon-32-messaging.png', + '/administrator/templates/hathor/images/toolbar/icon-32-messanging.png', + '/administrator/templates/hathor/images/toolbar/icon-32-module.png', + '/administrator/templates/hathor/images/toolbar/icon-32-move.png', + '/administrator/templates/hathor/images/toolbar/icon-32-new-privatemessage.png', + '/administrator/templates/hathor/images/toolbar/icon-32-new-style.png', + '/administrator/templates/hathor/images/toolbar/icon-32-new.png', + '/administrator/templates/hathor/images/toolbar/icon-32-notice.png', + '/administrator/templates/hathor/images/toolbar/icon-32-preview.png', + '/administrator/templates/hathor/images/toolbar/icon-32-print.png', + '/administrator/templates/hathor/images/toolbar/icon-32-publish.png', + '/administrator/templates/hathor/images/toolbar/icon-32-purge.png', + '/administrator/templates/hathor/images/toolbar/icon-32-read-privatemessage.png', + '/administrator/templates/hathor/images/toolbar/icon-32-refresh.png', + '/administrator/templates/hathor/images/toolbar/icon-32-remove.png', + '/administrator/templates/hathor/images/toolbar/icon-32-revert.png', + '/administrator/templates/hathor/images/toolbar/icon-32-save-copy.png', + '/administrator/templates/hathor/images/toolbar/icon-32-save-new.png', + '/administrator/templates/hathor/images/toolbar/icon-32-save.png', + '/administrator/templates/hathor/images/toolbar/icon-32-search.png', + '/administrator/templates/hathor/images/toolbar/icon-32-send.png', + '/administrator/templates/hathor/images/toolbar/icon-32-stats.png', + '/administrator/templates/hathor/images/toolbar/icon-32-trash.png', + '/administrator/templates/hathor/images/toolbar/icon-32-unarchive.png', + '/administrator/templates/hathor/images/toolbar/icon-32-unblock.png', + '/administrator/templates/hathor/images/toolbar/icon-32-unpublish.png', + '/administrator/templates/hathor/images/toolbar/icon-32-upload.png', + '/administrator/templates/hathor/images/toolbar/icon-32-user-add.png', + '/administrator/templates/hathor/images/toolbar/icon-32-xml.png', + '/administrator/templates/hathor/index.php', + '/administrator/templates/hathor/js/template.js', + '/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.ini', + '/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.sys.ini', + '/administrator/templates/hathor/less/buttons.less', + '/administrator/templates/hathor/less/colour_baseline.less', + '/administrator/templates/hathor/less/colour_blue.less', + '/administrator/templates/hathor/less/colour_brown.less', + '/administrator/templates/hathor/less/colour_standard.less', + '/administrator/templates/hathor/less/forms.less', + '/administrator/templates/hathor/less/hathor_variables.less', + '/administrator/templates/hathor/less/icomoon.less', + '/administrator/templates/hathor/less/modals.less', + '/administrator/templates/hathor/less/template.less', + '/administrator/templates/hathor/less/variables.less', + '/administrator/templates/hathor/login.php', + '/administrator/templates/hathor/postinstall/hathormessage.php', + '/administrator/templates/hathor/templateDetails.xml', + '/administrator/templates/hathor/template_preview.png', + '/administrator/templates/hathor/template_thumbnail.png', + '/administrator/templates/isis/component.php', + '/administrator/templates/isis/cpanel.php', + '/administrator/templates/isis/css/template-rtl.css', + '/administrator/templates/isis/css/template.css', + '/administrator/templates/isis/error.php', + '/administrator/templates/isis/favicon.ico', + '/administrator/templates/isis/html/com_media/imageslist/default_folder.php', + '/administrator/templates/isis/html/com_media/imageslist/default_image.php', + '/administrator/templates/isis/html/com_media/medialist/thumbs_folders.php', + '/administrator/templates/isis/html/com_media/medialist/thumbs_imgs.php', + '/administrator/templates/isis/html/editor_content.css', + '/administrator/templates/isis/html/layouts/joomla/form/field/media.php', + '/administrator/templates/isis/html/layouts/joomla/form/field/user.php', + '/administrator/templates/isis/html/layouts/joomla/pagination/link.php', + '/administrator/templates/isis/html/layouts/joomla/pagination/links.php', + '/administrator/templates/isis/html/layouts/joomla/system/message.php', + '/administrator/templates/isis/html/layouts/joomla/toolbar/versions.php', + '/administrator/templates/isis/html/mod_version/default.php', + '/administrator/templates/isis/html/modules.php', + '/administrator/templates/isis/html/pagination.php', + '/administrator/templates/isis/images/admin/blank.png', + '/administrator/templates/isis/images/admin/checked_out.png', + '/administrator/templates/isis/images/admin/collapseall.png', + '/administrator/templates/isis/images/admin/disabled.png', + '/administrator/templates/isis/images/admin/downarrow-1.png', + '/administrator/templates/isis/images/admin/downarrow.png', + '/administrator/templates/isis/images/admin/downarrow0.png', + '/administrator/templates/isis/images/admin/expandall.png', + '/administrator/templates/isis/images/admin/featured.png', + '/administrator/templates/isis/images/admin/filesave.png', + '/administrator/templates/isis/images/admin/filter_16.png', + '/administrator/templates/isis/images/admin/icon-16-add.png', + '/administrator/templates/isis/images/admin/icon-16-allow.png', + '/administrator/templates/isis/images/admin/icon-16-allowinactive.png', + '/administrator/templates/isis/images/admin/icon-16-deny.png', + '/administrator/templates/isis/images/admin/icon-16-denyinactive.png', + '/administrator/templates/isis/images/admin/icon-16-links.png', + '/administrator/templates/isis/images/admin/icon-16-notice-note.png', + '/administrator/templates/isis/images/admin/icon-16-protected.png', + '/administrator/templates/isis/images/admin/menu_divider.png', + '/administrator/templates/isis/images/admin/note_add_16.png', + '/administrator/templates/isis/images/admin/publish_g.png', + '/administrator/templates/isis/images/admin/publish_r.png', + '/administrator/templates/isis/images/admin/publish_x.png', + '/administrator/templates/isis/images/admin/publish_y.png', + '/administrator/templates/isis/images/admin/sort_asc.png', + '/administrator/templates/isis/images/admin/sort_desc.png', + '/administrator/templates/isis/images/admin/tick.png', + '/administrator/templates/isis/images/admin/trash.png', + '/administrator/templates/isis/images/admin/uparrow-1.png', + '/administrator/templates/isis/images/admin/uparrow.png', + '/administrator/templates/isis/images/admin/uparrow0.png', + '/administrator/templates/isis/images/emailButton.png', + '/administrator/templates/isis/images/joomla.png', + '/administrator/templates/isis/images/login-joomla-inverse.png', + '/administrator/templates/isis/images/login-joomla.png', + '/administrator/templates/isis/images/logo-inverse.png', + '/administrator/templates/isis/images/logo.png', + '/administrator/templates/isis/images/pdf_button.png', + '/administrator/templates/isis/images/printButton.png', + '/administrator/templates/isis/images/system/sort_asc.png', + '/administrator/templates/isis/images/system/sort_desc.png', + '/administrator/templates/isis/img/glyphicons-halflings-white.png', + '/administrator/templates/isis/img/glyphicons-halflings.png', + '/administrator/templates/isis/index.php', + '/administrator/templates/isis/js/application.js', + '/administrator/templates/isis/js/classes.js', + '/administrator/templates/isis/js/template.js', + '/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.ini', + '/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.sys.ini', + '/administrator/templates/isis/less/blocks/_chzn-override.less', + '/administrator/templates/isis/less/blocks/_custom.less', + '/administrator/templates/isis/less/blocks/_editors.less', + '/administrator/templates/isis/less/blocks/_forms.less', + '/administrator/templates/isis/less/blocks/_global.less', + '/administrator/templates/isis/less/blocks/_header.less', + '/administrator/templates/isis/less/blocks/_login.less', + '/administrator/templates/isis/less/blocks/_media.less', + '/administrator/templates/isis/less/blocks/_modals.less', + '/administrator/templates/isis/less/blocks/_navbar.less', + '/administrator/templates/isis/less/blocks/_quickicons.less', + '/administrator/templates/isis/less/blocks/_sidebar.less', + '/administrator/templates/isis/less/blocks/_status.less', + '/administrator/templates/isis/less/blocks/_tables.less', + '/administrator/templates/isis/less/blocks/_toolbar.less', + '/administrator/templates/isis/less/blocks/_treeselect.less', + '/administrator/templates/isis/less/blocks/_utility-classes.less', + '/administrator/templates/isis/less/bootstrap/button-groups.less', + '/administrator/templates/isis/less/bootstrap/buttons.less', + '/administrator/templates/isis/less/bootstrap/mixins.less', + '/administrator/templates/isis/less/bootstrap/responsive-1200px-min.less', + '/administrator/templates/isis/less/bootstrap/responsive-768px-979px.less', + '/administrator/templates/isis/less/bootstrap/wells.less', + '/administrator/templates/isis/less/icomoon.less', + '/administrator/templates/isis/less/pages/_com_cpanel.less', + '/administrator/templates/isis/less/pages/_com_postinstall.less', + '/administrator/templates/isis/less/pages/_com_templates.less', + '/administrator/templates/isis/less/template-rtl.less', + '/administrator/templates/isis/less/template.less', + '/administrator/templates/isis/less/variables.less', + '/administrator/templates/isis/login.php', + '/administrator/templates/isis/templateDetails.xml', + '/administrator/templates/isis/template_preview.png', + '/administrator/templates/isis/template_thumbnail.png', + '/bin/index.html', + '/bin/keychain.php', + '/components/com_banners/banners.php', + '/components/com_banners/controller.php', + '/components/com_banners/helpers/banner.php', + '/components/com_banners/models/banner.php', + '/components/com_banners/models/banners.php', + '/components/com_config/config.php', + '/components/com_config/controller/cancel.php', + '/components/com_config/controller/canceladmin.php', + '/components/com_config/controller/cmsbase.php', + '/components/com_config/controller/config/display.php', + '/components/com_config/controller/config/save.php', + '/components/com_config/controller/display.php', + '/components/com_config/controller/helper.php', + '/components/com_config/controller/modules/cancel.php', + '/components/com_config/controller/modules/display.php', + '/components/com_config/controller/modules/save.php', + '/components/com_config/controller/templates/display.php', + '/components/com_config/controller/templates/save.php', + '/components/com_config/model/cms.php', + '/components/com_config/model/config.php', + '/components/com_config/model/form.php', + '/components/com_config/model/form/config.xml', + '/components/com_config/model/form/modules.xml', + '/components/com_config/model/form/modules_advanced.xml', + '/components/com_config/model/form/templates.xml', + '/components/com_config/model/modules.php', + '/components/com_config/model/templates.php', + '/components/com_config/view/cms/html.php', + '/components/com_config/view/cms/json.php', + '/components/com_config/view/config/html.php', + '/components/com_config/view/config/tmpl/default.php', + '/components/com_config/view/config/tmpl/default.xml', + '/components/com_config/view/config/tmpl/default_metadata.php', + '/components/com_config/view/config/tmpl/default_seo.php', + '/components/com_config/view/config/tmpl/default_site.php', + '/components/com_config/view/modules/html.php', + '/components/com_config/view/modules/tmpl/default.php', + '/components/com_config/view/modules/tmpl/default_options.php', + '/components/com_config/view/modules/tmpl/default_positions.php', + '/components/com_config/view/templates/html.php', + '/components/com_config/view/templates/tmpl/default.php', + '/components/com_config/view/templates/tmpl/default.xml', + '/components/com_config/view/templates/tmpl/default_options.php', + '/components/com_contact/contact.php', + '/components/com_contact/controller.php', + '/components/com_contact/controllers/contact.php', + '/components/com_contact/helpers/legacyrouter.php', + '/components/com_contact/models/categories.php', + '/components/com_contact/models/category.php', + '/components/com_contact/models/contact.php', + '/components/com_contact/models/featured.php', + '/components/com_contact/models/forms/contact.xml', + '/components/com_contact/models/forms/filter_contacts.xml', + '/components/com_contact/models/forms/form.xml', + '/components/com_contact/models/rules/contactemail.php', + '/components/com_contact/models/rules/contactemailmessage.php', + '/components/com_contact/models/rules/contactemailsubject.php', + '/components/com_contact/views/categories/tmpl/default.php', + '/components/com_contact/views/categories/tmpl/default.xml', + '/components/com_contact/views/categories/tmpl/default_items.php', + '/components/com_contact/views/categories/view.html.php', + '/components/com_contact/views/category/tmpl/default.php', + '/components/com_contact/views/category/tmpl/default.xml', + '/components/com_contact/views/category/tmpl/default_children.php', + '/components/com_contact/views/category/tmpl/default_items.php', + '/components/com_contact/views/category/view.feed.php', + '/components/com_contact/views/category/view.html.php', + '/components/com_contact/views/contact/tmpl/default.php', + '/components/com_contact/views/contact/tmpl/default.xml', + '/components/com_contact/views/contact/tmpl/default_address.php', + '/components/com_contact/views/contact/tmpl/default_articles.php', + '/components/com_contact/views/contact/tmpl/default_form.php', + '/components/com_contact/views/contact/tmpl/default_links.php', + '/components/com_contact/views/contact/tmpl/default_profile.php', + '/components/com_contact/views/contact/tmpl/default_user_custom_fields.php', + '/components/com_contact/views/contact/view.html.php', + '/components/com_contact/views/contact/view.vcf.php', + '/components/com_contact/views/featured/tmpl/default.php', + '/components/com_contact/views/featured/tmpl/default.xml', + '/components/com_contact/views/featured/tmpl/default_items.php', + '/components/com_contact/views/featured/view.html.php', + '/components/com_content/content.php', + '/components/com_content/controller.php', + '/components/com_content/controllers/article.php', + '/components/com_content/helpers/legacyrouter.php', + '/components/com_content/models/archive.php', + '/components/com_content/models/article.php', + '/components/com_content/models/articles.php', + '/components/com_content/models/categories.php', + '/components/com_content/models/category.php', + '/components/com_content/models/featured.php', + '/components/com_content/models/form.php', + '/components/com_content/models/forms/article.xml', + '/components/com_content/models/forms/filter_articles.xml', + '/components/com_content/views/archive/tmpl/default.php', + '/components/com_content/views/archive/tmpl/default.xml', + '/components/com_content/views/archive/tmpl/default_items.php', + '/components/com_content/views/archive/view.html.php', + '/components/com_content/views/article/tmpl/default.php', + '/components/com_content/views/article/tmpl/default.xml', + '/components/com_content/views/article/tmpl/default_links.php', + '/components/com_content/views/article/view.html.php', + '/components/com_content/views/categories/tmpl/default.php', + '/components/com_content/views/categories/tmpl/default.xml', + '/components/com_content/views/categories/tmpl/default_items.php', + '/components/com_content/views/categories/view.html.php', + '/components/com_content/views/category/tmpl/blog.php', + '/components/com_content/views/category/tmpl/blog.xml', + '/components/com_content/views/category/tmpl/blog_children.php', + '/components/com_content/views/category/tmpl/blog_item.php', + '/components/com_content/views/category/tmpl/blog_links.php', + '/components/com_content/views/category/tmpl/default.php', + '/components/com_content/views/category/tmpl/default.xml', + '/components/com_content/views/category/tmpl/default_articles.php', + '/components/com_content/views/category/tmpl/default_children.php', + '/components/com_content/views/category/view.feed.php', + '/components/com_content/views/category/view.html.php', + '/components/com_content/views/featured/tmpl/default.php', + '/components/com_content/views/featured/tmpl/default.xml', + '/components/com_content/views/featured/tmpl/default_item.php', + '/components/com_content/views/featured/tmpl/default_links.php', + '/components/com_content/views/featured/view.feed.php', + '/components/com_content/views/featured/view.html.php', + '/components/com_content/views/form/tmpl/edit.php', + '/components/com_content/views/form/tmpl/edit.xml', + '/components/com_content/views/form/view.html.php', + '/components/com_contenthistory/contenthistory.php', + '/components/com_fields/controller.php', + '/components/com_fields/models/forms/filter_fields.xml', + '/components/com_finder/controller.php', + '/components/com_finder/controllers/suggestions.json.php', + '/components/com_finder/finder.php', + '/components/com_finder/models/search.php', + '/components/com_finder/models/suggestions.php', + '/components/com_finder/views/search/tmpl/default.php', + '/components/com_finder/views/search/tmpl/default.xml', + '/components/com_finder/views/search/tmpl/default_form.php', + '/components/com_finder/views/search/tmpl/default_result.php', + '/components/com_finder/views/search/tmpl/default_results.php', + '/components/com_finder/views/search/view.feed.php', + '/components/com_finder/views/search/view.html.php', + '/components/com_finder/views/search/view.opensearch.php', + '/components/com_mailto/controller.php', + '/components/com_mailto/mailto.php', + '/components/com_mailto/views/mailto/tmpl/default.php', + '/components/com_mailto/views/mailto/view.html.php', + '/components/com_mailto/views/sent/tmpl/default.php', + '/components/com_mailto/views/sent/view.html.php', + '/components/com_media/media.php', + '/components/com_menus/models/forms/filter_items.xml', + '/components/com_modules/controller.php', + '/components/com_modules/models/forms/filter_modules.xml', + '/components/com_modules/modules.php', + '/components/com_newsfeeds/controller.php', + '/components/com_newsfeeds/helpers/legacyrouter.php', + '/components/com_newsfeeds/models/categories.php', + '/components/com_newsfeeds/models/category.php', + '/components/com_newsfeeds/models/newsfeed.php', + '/components/com_newsfeeds/newsfeeds.php', + '/components/com_newsfeeds/views/categories/tmpl/default.php', + '/components/com_newsfeeds/views/categories/tmpl/default.xml', + '/components/com_newsfeeds/views/categories/tmpl/default_items.php', + '/components/com_newsfeeds/views/categories/view.html.php', + '/components/com_newsfeeds/views/category/tmpl/default.php', + '/components/com_newsfeeds/views/category/tmpl/default.xml', + '/components/com_newsfeeds/views/category/tmpl/default_children.php', + '/components/com_newsfeeds/views/category/tmpl/default_items.php', + '/components/com_newsfeeds/views/category/view.html.php', + '/components/com_newsfeeds/views/newsfeed/tmpl/default.php', + '/components/com_newsfeeds/views/newsfeed/tmpl/default.xml', + '/components/com_newsfeeds/views/newsfeed/view.html.php', + '/components/com_search/controller.php', + '/components/com_search/models/search.php', + '/components/com_search/search.php', + '/components/com_search/views/search/tmpl/default.php', + '/components/com_search/views/search/tmpl/default.xml', + '/components/com_search/views/search/tmpl/default_error.php', + '/components/com_search/views/search/tmpl/default_form.php', + '/components/com_search/views/search/tmpl/default_results.php', + '/components/com_search/views/search/view.html.php', + '/components/com_search/views/search/view.opensearch.php', + '/components/com_tags/controller.php', + '/components/com_tags/controllers/tags.php', + '/components/com_tags/models/tag.php', + '/components/com_tags/models/tags.php', + '/components/com_tags/tags.php', + '/components/com_tags/views/tag/tmpl/default.php', + '/components/com_tags/views/tag/tmpl/default.xml', + '/components/com_tags/views/tag/tmpl/default_items.php', + '/components/com_tags/views/tag/tmpl/list.php', + '/components/com_tags/views/tag/tmpl/list.xml', + '/components/com_tags/views/tag/tmpl/list_items.php', + '/components/com_tags/views/tag/view.feed.php', + '/components/com_tags/views/tag/view.html.php', + '/components/com_tags/views/tags/tmpl/default.php', + '/components/com_tags/views/tags/tmpl/default.xml', + '/components/com_tags/views/tags/tmpl/default_items.php', + '/components/com_tags/views/tags/view.feed.php', + '/components/com_tags/views/tags/view.html.php', + '/components/com_users/controller.php', + '/components/com_users/controllers/profile.json.php', + '/components/com_users/controllers/profile.php', + '/components/com_users/controllers/profile_base_json.php', + '/components/com_users/controllers/registration.php', + '/components/com_users/controllers/remind.php', + '/components/com_users/controllers/reset.php', + '/components/com_users/controllers/user.php', + '/components/com_users/helpers/legacyrouter.php', + '/components/com_users/models/forms/frontend.xml', + '/components/com_users/models/forms/frontend_admin.xml', + '/components/com_users/models/forms/login.xml', + '/components/com_users/models/forms/profile.xml', + '/components/com_users/models/forms/registration.xml', + '/components/com_users/models/forms/remind.xml', + '/components/com_users/models/forms/reset_complete.xml', + '/components/com_users/models/forms/reset_confirm.xml', + '/components/com_users/models/forms/reset_request.xml', + '/components/com_users/models/forms/sitelang.xml', + '/components/com_users/models/login.php', + '/components/com_users/models/profile.php', + '/components/com_users/models/registration.php', + '/components/com_users/models/remind.php', + '/components/com_users/models/reset.php', + '/components/com_users/models/rules/loginuniquefield.php', + '/components/com_users/models/rules/logoutuniquefield.php', + '/components/com_users/users.php', + '/components/com_users/views/login/tmpl/default.php', + '/components/com_users/views/login/tmpl/default.xml', + '/components/com_users/views/login/tmpl/default_login.php', + '/components/com_users/views/login/tmpl/default_logout.php', + '/components/com_users/views/login/tmpl/logout.xml', + '/components/com_users/views/login/view.html.php', + '/components/com_users/views/profile/tmpl/default.php', + '/components/com_users/views/profile/tmpl/default.xml', + '/components/com_users/views/profile/tmpl/default_core.php', + '/components/com_users/views/profile/tmpl/default_custom.php', + '/components/com_users/views/profile/tmpl/default_params.php', + '/components/com_users/views/profile/tmpl/edit.php', + '/components/com_users/views/profile/tmpl/edit.xml', + '/components/com_users/views/profile/view.html.php', + '/components/com_users/views/registration/tmpl/complete.php', + '/components/com_users/views/registration/tmpl/default.php', + '/components/com_users/views/registration/tmpl/default.xml', + '/components/com_users/views/registration/view.html.php', + '/components/com_users/views/remind/tmpl/default.php', + '/components/com_users/views/remind/tmpl/default.xml', + '/components/com_users/views/remind/view.html.php', + '/components/com_users/views/reset/tmpl/complete.php', + '/components/com_users/views/reset/tmpl/confirm.php', + '/components/com_users/views/reset/tmpl/default.php', + '/components/com_users/views/reset/tmpl/default.xml', + '/components/com_users/views/reset/view.html.php', + '/components/com_wrapper/controller.php', + '/components/com_wrapper/views/wrapper/tmpl/default.php', + '/components/com_wrapper/views/wrapper/tmpl/default.xml', + '/components/com_wrapper/views/wrapper/view.html.php', + '/components/com_wrapper/wrapper.php', + '/language/en-GB/en-GB.lib_fof.ini', + '/language/en-GB/en-GB.lib_fof.sys.ini', + '/language/en-GB/en-GB.lib_phputf8.sys.ini', + '/language/en-GB/en-GB.tpl_beez3.ini', + '/language/en-GB/en-GB.tpl_beez3.sys.ini', + '/language/en-GB/en-GB.tpl_protostar.ini', + '/language/en-GB/en-GB.tpl_protostar.sys.ini', + '/layouts/joomla/edit/details.php', + '/layouts/joomla/html/formbehavior/ajaxchosen.php', + '/layouts/joomla/html/formbehavior/chosen.php', + '/layouts/joomla/html/sortablelist.php', + '/layouts/joomla/html/tag.php', + '/layouts/joomla/sidebars/toggle.php', + '/layouts/libraries/cms/html/bootstrap/addtabscript.php', + '/layouts/libraries/cms/html/bootstrap/starttabsetscript.php', + '/libraries/cms/html/rules.php', + '/libraries/cms/html/sliders.php', + '/libraries/cms/html/tabs.php', + '/libraries/cms/less/formatter/joomla.php', + '/libraries/cms/less/less.php', + '/libraries/fof/LICENSE.txt', + '/libraries/fof/autoloader/component.php', + '/libraries/fof/autoloader/fof.php', + '/libraries/fof/config/domain/dispatcher.php', + '/libraries/fof/config/domain/interface.php', + '/libraries/fof/config/domain/tables.php', + '/libraries/fof/config/domain/views.php', + '/libraries/fof/config/provider.php', + '/libraries/fof/controller/controller.php', + '/libraries/fof/database/database.php', + '/libraries/fof/database/driver.php', + '/libraries/fof/database/driver/joomla.php', + '/libraries/fof/database/driver/mysql.php', + '/libraries/fof/database/driver/mysqli.php', + '/libraries/fof/database/driver/oracle.php', + '/libraries/fof/database/driver/pdo.php', + '/libraries/fof/database/driver/pdomysql.php', + '/libraries/fof/database/driver/postgresql.php', + '/libraries/fof/database/driver/sqlazure.php', + '/libraries/fof/database/driver/sqlite.php', + '/libraries/fof/database/driver/sqlsrv.php', + '/libraries/fof/database/factory.php', + '/libraries/fof/database/installer.php', + '/libraries/fof/database/interface.php', + '/libraries/fof/database/iterator.php', + '/libraries/fof/database/iterator/azure.php', + '/libraries/fof/database/iterator/mysql.php', + '/libraries/fof/database/iterator/mysqli.php', + '/libraries/fof/database/iterator/oracle.php', + '/libraries/fof/database/iterator/pdo.php', + '/libraries/fof/database/iterator/pdomysql.php', + '/libraries/fof/database/iterator/postgresql.php', + '/libraries/fof/database/iterator/sqlite.php', + '/libraries/fof/database/iterator/sqlsrv.php', + '/libraries/fof/database/query.php', + '/libraries/fof/database/query/element.php', + '/libraries/fof/database/query/limitable.php', + '/libraries/fof/database/query/mysql.php', + '/libraries/fof/database/query/mysqli.php', + '/libraries/fof/database/query/oracle.php', + '/libraries/fof/database/query/pdo.php', + '/libraries/fof/database/query/pdomysql.php', + '/libraries/fof/database/query/postgresql.php', + '/libraries/fof/database/query/preparable.php', + '/libraries/fof/database/query/sqlazure.php', + '/libraries/fof/database/query/sqlite.php', + '/libraries/fof/database/query/sqlsrv.php', + '/libraries/fof/dispatcher/dispatcher.php', + '/libraries/fof/download/adapter/abstract.php', + '/libraries/fof/download/adapter/cacert.pem', + '/libraries/fof/download/adapter/curl.php', + '/libraries/fof/download/adapter/fopen.php', + '/libraries/fof/download/download.php', + '/libraries/fof/download/interface.php', + '/libraries/fof/encrypt/aes.php', + '/libraries/fof/encrypt/aes/abstract.php', + '/libraries/fof/encrypt/aes/interface.php', + '/libraries/fof/encrypt/aes/mcrypt.php', + '/libraries/fof/encrypt/aes/openssl.php', + '/libraries/fof/encrypt/base32.php', + '/libraries/fof/encrypt/randval.php', + '/libraries/fof/encrypt/randvalinterface.php', + '/libraries/fof/encrypt/totp.php', + '/libraries/fof/form/field.php', + '/libraries/fof/form/field/accesslevel.php', + '/libraries/fof/form/field/actions.php', + '/libraries/fof/form/field/button.php', + '/libraries/fof/form/field/cachehandler.php', + '/libraries/fof/form/field/calendar.php', + '/libraries/fof/form/field/captcha.php', + '/libraries/fof/form/field/checkbox.php', + '/libraries/fof/form/field/checkboxes.php', + '/libraries/fof/form/field/components.php', + '/libraries/fof/form/field/editor.php', + '/libraries/fof/form/field/email.php', + '/libraries/fof/form/field/groupedbutton.php', + '/libraries/fof/form/field/groupedlist.php', + '/libraries/fof/form/field/hidden.php', + '/libraries/fof/form/field/image.php', + '/libraries/fof/form/field/imagelist.php', + '/libraries/fof/form/field/integer.php', + '/libraries/fof/form/field/language.php', + '/libraries/fof/form/field/list.php', + '/libraries/fof/form/field/media.php', + '/libraries/fof/form/field/model.php', + '/libraries/fof/form/field/ordering.php', + '/libraries/fof/form/field/password.php', + '/libraries/fof/form/field/plugins.php', + '/libraries/fof/form/field/published.php', + '/libraries/fof/form/field/radio.php', + '/libraries/fof/form/field/relation.php', + '/libraries/fof/form/field/rules.php', + '/libraries/fof/form/field/selectrow.php', + '/libraries/fof/form/field/sessionhandler.php', + '/libraries/fof/form/field/spacer.php', + '/libraries/fof/form/field/sql.php', + '/libraries/fof/form/field/tag.php', + '/libraries/fof/form/field/tel.php', + '/libraries/fof/form/field/text.php', + '/libraries/fof/form/field/textarea.php', + '/libraries/fof/form/field/timezone.php', + '/libraries/fof/form/field/title.php', + '/libraries/fof/form/field/url.php', + '/libraries/fof/form/field/user.php', + '/libraries/fof/form/field/usergroup.php', + '/libraries/fof/form/form.php', + '/libraries/fof/form/header.php', + '/libraries/fof/form/header/accesslevel.php', + '/libraries/fof/form/header/field.php', + '/libraries/fof/form/header/fielddate.php', + '/libraries/fof/form/header/fieldfilterable.php', + '/libraries/fof/form/header/fieldsearchable.php', + '/libraries/fof/form/header/fieldselectable.php', + '/libraries/fof/form/header/fieldsql.php', + '/libraries/fof/form/header/filterdate.php', + '/libraries/fof/form/header/filterfilterable.php', + '/libraries/fof/form/header/filtersearchable.php', + '/libraries/fof/form/header/filterselectable.php', + '/libraries/fof/form/header/filtersql.php', + '/libraries/fof/form/header/language.php', + '/libraries/fof/form/header/model.php', + '/libraries/fof/form/header/ordering.php', + '/libraries/fof/form/header/published.php', + '/libraries/fof/form/header/rowselect.php', + '/libraries/fof/form/helper.php', + '/libraries/fof/hal/document.php', + '/libraries/fof/hal/link.php', + '/libraries/fof/hal/links.php', + '/libraries/fof/hal/render/interface.php', + '/libraries/fof/hal/render/json.php', + '/libraries/fof/include.php', + '/libraries/fof/inflector/inflector.php', + '/libraries/fof/input/input.php', + '/libraries/fof/input/jinput/cli.php', + '/libraries/fof/input/jinput/cookie.php', + '/libraries/fof/input/jinput/files.php', + '/libraries/fof/input/jinput/input.php', + '/libraries/fof/input/jinput/json.php', + '/libraries/fof/integration/joomla/filesystem/filesystem.php', + '/libraries/fof/integration/joomla/platform.php', + '/libraries/fof/layout/file.php', + '/libraries/fof/layout/helper.php', + '/libraries/fof/less/formatter/classic.php', + '/libraries/fof/less/formatter/compressed.php', + '/libraries/fof/less/formatter/joomla.php', + '/libraries/fof/less/formatter/lessjs.php', + '/libraries/fof/less/less.php', + '/libraries/fof/less/parser/parser.php', + '/libraries/fof/model/behavior.php', + '/libraries/fof/model/behavior/access.php', + '/libraries/fof/model/behavior/emptynonzero.php', + '/libraries/fof/model/behavior/enabled.php', + '/libraries/fof/model/behavior/filters.php', + '/libraries/fof/model/behavior/language.php', + '/libraries/fof/model/behavior/private.php', + '/libraries/fof/model/dispatcher/behavior.php', + '/libraries/fof/model/field.php', + '/libraries/fof/model/field/boolean.php', + '/libraries/fof/model/field/date.php', + '/libraries/fof/model/field/number.php', + '/libraries/fof/model/field/text.php', + '/libraries/fof/model/model.php', + '/libraries/fof/platform/filesystem/filesystem.php', + '/libraries/fof/platform/filesystem/interface.php', + '/libraries/fof/platform/interface.php', + '/libraries/fof/platform/platform.php', + '/libraries/fof/query/abstract.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/behavior.php', + '/libraries/fof/table/behavior/assets.php', + '/libraries/fof/table/behavior/contenthistory.php', + '/libraries/fof/table/behavior/tags.php', + '/libraries/fof/table/dispatcher/behavior.php', + '/libraries/fof/table/nested.php', + '/libraries/fof/table/relations.php', + '/libraries/fof/table/table.php', + '/libraries/fof/template/utils.php', + '/libraries/fof/toolbar/toolbar.php', + '/libraries/fof/utils/array/array.php', + '/libraries/fof/utils/cache/cleaner.php', + '/libraries/fof/utils/config/helper.php', + '/libraries/fof/utils/filescheck/filescheck.php', + '/libraries/fof/utils/ini/parser.php', + '/libraries/fof/utils/installscript/installscript.php', + '/libraries/fof/utils/ip/ip.php', + '/libraries/fof/utils/object/object.php', + '/libraries/fof/utils/observable/dispatcher.php', + '/libraries/fof/utils/observable/event.php', + '/libraries/fof/utils/phpfunc/phpfunc.php', + '/libraries/fof/utils/timer/timer.php', + '/libraries/fof/utils/update/collection.php', + '/libraries/fof/utils/update/extension.php', + '/libraries/fof/utils/update/joomla.php', + '/libraries/fof/utils/update/update.php', + '/libraries/fof/version.txt', + '/libraries/fof/view/csv.php', + '/libraries/fof/view/form.php', + '/libraries/fof/view/html.php', + '/libraries/fof/view/json.php', + '/libraries/fof/view/raw.php', + '/libraries/fof/view/view.php', + '/libraries/joomla/application/web/router.php', + '/libraries/joomla/application/web/router/base.php', + '/libraries/joomla/application/web/router/rest.php', + '/libraries/joomla/archive/archive.php', + '/libraries/joomla/archive/bzip2.php', + '/libraries/joomla/archive/extractable.php', + '/libraries/joomla/archive/gzip.php', + '/libraries/joomla/archive/tar.php', + '/libraries/joomla/archive/wrapper/archive.php', + '/libraries/joomla/archive/zip.php', + '/libraries/joomla/database/database.php', + '/libraries/joomla/database/driver.php', + '/libraries/joomla/database/driver/mysql.php', + '/libraries/joomla/database/driver/mysqli.php', + '/libraries/joomla/database/driver/oracle.php', + '/libraries/joomla/database/driver/pdo.php', + '/libraries/joomla/database/driver/pdomysql.php', + '/libraries/joomla/database/driver/postgresql.php', + '/libraries/joomla/database/driver/sqlazure.php', + '/libraries/joomla/database/driver/sqlite.php', + '/libraries/joomla/database/driver/sqlsrv.php', + '/libraries/joomla/database/exception/connecting.php', + '/libraries/joomla/database/exception/executing.php', + '/libraries/joomla/database/exception/unsupported.php', + '/libraries/joomla/database/exporter.php', + '/libraries/joomla/database/exporter/mysql.php', + '/libraries/joomla/database/exporter/mysqli.php', + '/libraries/joomla/database/exporter/pdomysql.php', + '/libraries/joomla/database/exporter/postgresql.php', + '/libraries/joomla/database/factory.php', + '/libraries/joomla/database/importer.php', + '/libraries/joomla/database/importer/mysql.php', + '/libraries/joomla/database/importer/mysqli.php', + '/libraries/joomla/database/importer/pdomysql.php', + '/libraries/joomla/database/importer/postgresql.php', + '/libraries/joomla/database/interface.php', + '/libraries/joomla/database/iterator.php', + '/libraries/joomla/database/iterator/mysql.php', + '/libraries/joomla/database/iterator/mysqli.php', + '/libraries/joomla/database/iterator/oracle.php', + '/libraries/joomla/database/iterator/pdo.php', + '/libraries/joomla/database/iterator/pdomysql.php', + '/libraries/joomla/database/iterator/postgresql.php', + '/libraries/joomla/database/iterator/sqlazure.php', + '/libraries/joomla/database/iterator/sqlite.php', + '/libraries/joomla/database/iterator/sqlsrv.php', + '/libraries/joomla/database/query.php', + '/libraries/joomla/database/query/element.php', + '/libraries/joomla/database/query/limitable.php', + '/libraries/joomla/database/query/mysql.php', + '/libraries/joomla/database/query/mysqli.php', + '/libraries/joomla/database/query/oracle.php', + '/libraries/joomla/database/query/pdo.php', + '/libraries/joomla/database/query/pdomysql.php', + '/libraries/joomla/database/query/postgresql.php', + '/libraries/joomla/database/query/preparable.php', + '/libraries/joomla/database/query/sqlazure.php', + '/libraries/joomla/database/query/sqlite.php', + '/libraries/joomla/database/query/sqlsrv.php', + '/libraries/joomla/event/dispatcher.php', + '/libraries/joomla/event/event.php', + '/libraries/joomla/facebook/album.php', + '/libraries/joomla/facebook/checkin.php', + '/libraries/joomla/facebook/comment.php', + '/libraries/joomla/facebook/event.php', + '/libraries/joomla/facebook/facebook.php', + '/libraries/joomla/facebook/group.php', + '/libraries/joomla/facebook/link.php', + '/libraries/joomla/facebook/note.php', + '/libraries/joomla/facebook/oauth.php', + '/libraries/joomla/facebook/object.php', + '/libraries/joomla/facebook/photo.php', + '/libraries/joomla/facebook/post.php', + '/libraries/joomla/facebook/status.php', + '/libraries/joomla/facebook/user.php', + '/libraries/joomla/facebook/video.php', + '/libraries/joomla/form/fields/accesslevel.php', + '/libraries/joomla/form/fields/aliastag.php', + '/libraries/joomla/form/fields/cachehandler.php', + '/libraries/joomla/form/fields/calendar.php', + '/libraries/joomla/form/fields/checkbox.php', + '/libraries/joomla/form/fields/checkboxes.php', + '/libraries/joomla/form/fields/color.php', + '/libraries/joomla/form/fields/combo.php', + '/libraries/joomla/form/fields/components.php', + '/libraries/joomla/form/fields/databaseconnection.php', + '/libraries/joomla/form/fields/email.php', + '/libraries/joomla/form/fields/file.php', + '/libraries/joomla/form/fields/filelist.php', + '/libraries/joomla/form/fields/folderlist.php', + '/libraries/joomla/form/fields/groupedlist.php', + '/libraries/joomla/form/fields/hidden.php', + '/libraries/joomla/form/fields/imagelist.php', + '/libraries/joomla/form/fields/integer.php', + '/libraries/joomla/form/fields/language.php', + '/libraries/joomla/form/fields/list.php', + '/libraries/joomla/form/fields/meter.php', + '/libraries/joomla/form/fields/note.php', + '/libraries/joomla/form/fields/number.php', + '/libraries/joomla/form/fields/password.php', + '/libraries/joomla/form/fields/plugins.php', + '/libraries/joomla/form/fields/predefinedlist.php', + '/libraries/joomla/form/fields/radio.php', + '/libraries/joomla/form/fields/range.php', + '/libraries/joomla/form/fields/repeatable.php', + '/libraries/joomla/form/fields/rules.php', + '/libraries/joomla/form/fields/sessionhandler.php', + '/libraries/joomla/form/fields/spacer.php', + '/libraries/joomla/form/fields/sql.php', + '/libraries/joomla/form/fields/subform.php', + '/libraries/joomla/form/fields/tel.php', + '/libraries/joomla/form/fields/text.php', + '/libraries/joomla/form/fields/textarea.php', + '/libraries/joomla/form/fields/timezone.php', + '/libraries/joomla/form/fields/url.php', + '/libraries/joomla/form/fields/usergroup.php', + '/libraries/joomla/github/account.php', + '/libraries/joomla/github/commits.php', + '/libraries/joomla/github/forks.php', + '/libraries/joomla/github/github.php', + '/libraries/joomla/github/hooks.php', + '/libraries/joomla/github/http.php', + '/libraries/joomla/github/meta.php', + '/libraries/joomla/github/milestones.php', + '/libraries/joomla/github/object.php', + '/libraries/joomla/github/package.php', + '/libraries/joomla/github/package/activity.php', + '/libraries/joomla/github/package/activity/events.php', + '/libraries/joomla/github/package/activity/notifications.php', + '/libraries/joomla/github/package/activity/starring.php', + '/libraries/joomla/github/package/activity/watching.php', + '/libraries/joomla/github/package/authorization.php', + '/libraries/joomla/github/package/data.php', + '/libraries/joomla/github/package/data/blobs.php', + '/libraries/joomla/github/package/data/commits.php', + '/libraries/joomla/github/package/data/refs.php', + '/libraries/joomla/github/package/data/tags.php', + '/libraries/joomla/github/package/data/trees.php', + '/libraries/joomla/github/package/gists.php', + '/libraries/joomla/github/package/gists/comments.php', + '/libraries/joomla/github/package/gitignore.php', + '/libraries/joomla/github/package/issues.php', + '/libraries/joomla/github/package/issues/assignees.php', + '/libraries/joomla/github/package/issues/comments.php', + '/libraries/joomla/github/package/issues/events.php', + '/libraries/joomla/github/package/issues/labels.php', + '/libraries/joomla/github/package/issues/milestones.php', + '/libraries/joomla/github/package/markdown.php', + '/libraries/joomla/github/package/orgs.php', + '/libraries/joomla/github/package/orgs/members.php', + '/libraries/joomla/github/package/orgs/teams.php', + '/libraries/joomla/github/package/pulls.php', + '/libraries/joomla/github/package/pulls/comments.php', + '/libraries/joomla/github/package/repositories.php', + '/libraries/joomla/github/package/repositories/collaborators.php', + '/libraries/joomla/github/package/repositories/comments.php', + '/libraries/joomla/github/package/repositories/commits.php', + '/libraries/joomla/github/package/repositories/contents.php', + '/libraries/joomla/github/package/repositories/downloads.php', + '/libraries/joomla/github/package/repositories/forks.php', + '/libraries/joomla/github/package/repositories/hooks.php', + '/libraries/joomla/github/package/repositories/keys.php', + '/libraries/joomla/github/package/repositories/merging.php', + '/libraries/joomla/github/package/repositories/statistics.php', + '/libraries/joomla/github/package/repositories/statuses.php', + '/libraries/joomla/github/package/search.php', + '/libraries/joomla/github/package/users.php', + '/libraries/joomla/github/package/users/emails.php', + '/libraries/joomla/github/package/users/followers.php', + '/libraries/joomla/github/package/users/keys.php', + '/libraries/joomla/github/refs.php', + '/libraries/joomla/github/statuses.php', + '/libraries/joomla/google/auth.php', + '/libraries/joomla/google/auth/oauth2.php', + '/libraries/joomla/google/data.php', + '/libraries/joomla/google/data/adsense.php', + '/libraries/joomla/google/data/calendar.php', + '/libraries/joomla/google/data/picasa.php', + '/libraries/joomla/google/data/picasa/album.php', + '/libraries/joomla/google/data/picasa/photo.php', + '/libraries/joomla/google/data/plus.php', + '/libraries/joomla/google/data/plus/activities.php', + '/libraries/joomla/google/data/plus/comments.php', + '/libraries/joomla/google/data/plus/people.php', + '/libraries/joomla/google/embed.php', + '/libraries/joomla/google/embed/analytics.php', + '/libraries/joomla/google/embed/maps.php', + '/libraries/joomla/google/google.php', + '/libraries/joomla/grid/grid.php', + '/libraries/joomla/keychain/keychain.php', + '/libraries/joomla/linkedin/communications.php', + '/libraries/joomla/linkedin/companies.php', + '/libraries/joomla/linkedin/groups.php', + '/libraries/joomla/linkedin/jobs.php', + '/libraries/joomla/linkedin/linkedin.php', + '/libraries/joomla/linkedin/oauth.php', + '/libraries/joomla/linkedin/object.php', + '/libraries/joomla/linkedin/people.php', + '/libraries/joomla/linkedin/stream.php', + '/libraries/joomla/mediawiki/categories.php', + '/libraries/joomla/mediawiki/http.php', + '/libraries/joomla/mediawiki/images.php', + '/libraries/joomla/mediawiki/links.php', + '/libraries/joomla/mediawiki/mediawiki.php', + '/libraries/joomla/mediawiki/object.php', + '/libraries/joomla/mediawiki/pages.php', + '/libraries/joomla/mediawiki/search.php', + '/libraries/joomla/mediawiki/sites.php', + '/libraries/joomla/mediawiki/users.php', + '/libraries/joomla/oauth1/client.php', + '/libraries/joomla/oauth2/client.php', + '/libraries/joomla/observable/interface.php', + '/libraries/joomla/observer/interface.php', + '/libraries/joomla/observer/mapper.php', + '/libraries/joomla/observer/updater.php', + '/libraries/joomla/observer/updater/interface.php', + '/libraries/joomla/observer/wrapper/mapper.php', + '/libraries/joomla/openstreetmap/changesets.php', + '/libraries/joomla/openstreetmap/elements.php', + '/libraries/joomla/openstreetmap/gps.php', + '/libraries/joomla/openstreetmap/info.php', + '/libraries/joomla/openstreetmap/oauth.php', + '/libraries/joomla/openstreetmap/object.php', + '/libraries/joomla/openstreetmap/openstreetmap.php', + '/libraries/joomla/openstreetmap/user.php', + '/libraries/joomla/platform.php', + '/libraries/joomla/route/wrapper/route.php', + '/libraries/joomla/session/handler/interface.php', + '/libraries/joomla/session/handler/joomla.php', + '/libraries/joomla/session/handler/native.php', + '/libraries/joomla/session/storage.php', + '/libraries/joomla/session/storage/apc.php', + '/libraries/joomla/session/storage/database.php', + '/libraries/joomla/session/storage/memcache.php', + '/libraries/joomla/session/storage/memcached.php', + '/libraries/joomla/session/storage/none.php', + '/libraries/joomla/session/storage/redis.php', + '/libraries/joomla/session/storage/wincache.php', + '/libraries/joomla/session/storage/xcache.php', + '/libraries/joomla/string/string.php', + '/libraries/joomla/string/wrapper/normalise.php', + '/libraries/joomla/string/wrapper/punycode.php', + '/libraries/joomla/twitter/block.php', + '/libraries/joomla/twitter/directmessages.php', + '/libraries/joomla/twitter/favorites.php', + '/libraries/joomla/twitter/friends.php', + '/libraries/joomla/twitter/help.php', + '/libraries/joomla/twitter/lists.php', + '/libraries/joomla/twitter/oauth.php', + '/libraries/joomla/twitter/object.php', + '/libraries/joomla/twitter/places.php', + '/libraries/joomla/twitter/profile.php', + '/libraries/joomla/twitter/search.php', + '/libraries/joomla/twitter/statuses.php', + '/libraries/joomla/twitter/trends.php', + '/libraries/joomla/twitter/twitter.php', + '/libraries/joomla/twitter/users.php', + '/libraries/joomla/utilities/arrayhelper.php', + '/libraries/legacy/application/application.php', + '/libraries/legacy/base/node.php', + '/libraries/legacy/base/observable.php', + '/libraries/legacy/base/observer.php', + '/libraries/legacy/base/tree.php', + '/libraries/legacy/database/exception.php', + '/libraries/legacy/database/mysql.php', + '/libraries/legacy/database/mysqli.php', + '/libraries/legacy/database/sqlazure.php', + '/libraries/legacy/database/sqlsrv.php', + '/libraries/legacy/dispatcher/dispatcher.php', + '/libraries/legacy/form/field/category.php', + '/libraries/legacy/form/field/componentlayout.php', + '/libraries/legacy/form/field/modulelayout.php', + '/libraries/legacy/log/logexception.php', + '/libraries/legacy/request/request.php', + '/libraries/legacy/response/response.php', + '/libraries/legacy/simplecrypt/simplecrypt.php', + '/libraries/legacy/simplepie/factory.php', + '/libraries/legacy/table/session.php', + '/libraries/legacy/utilities/xmlelement.php', + '/libraries/phputf8/LICENSE', + '/libraries/phputf8/README', + '/libraries/phputf8/mbstring/core.php', + '/libraries/phputf8/native/core.php', + '/libraries/phputf8/ord.php', + '/libraries/phputf8/str_ireplace.php', + '/libraries/phputf8/str_pad.php', + '/libraries/phputf8/str_split.php', + '/libraries/phputf8/strcasecmp.php', + '/libraries/phputf8/strcspn.php', + '/libraries/phputf8/stristr.php', + '/libraries/phputf8/strrev.php', + '/libraries/phputf8/strspn.php', + '/libraries/phputf8/substr_replace.php', + '/libraries/phputf8/trim.php', + '/libraries/phputf8/ucfirst.php', + '/libraries/phputf8/ucwords.php', + '/libraries/phputf8/utf8.php', + '/libraries/phputf8/utils/ascii.php', + '/libraries/phputf8/utils/bad.php', + '/libraries/phputf8/utils/patterns.php', + '/libraries/phputf8/utils/position.php', + '/libraries/phputf8/utils/specials.php', + '/libraries/phputf8/utils/unicode.php', + '/libraries/phputf8/utils/validation.php', + '/libraries/src/Access/Wrapper/Access.php', + '/libraries/src/Cache/Storage/CacheliteStorage.php', + '/libraries/src/Crypt/Cipher/BlowfishCipher.php', + '/libraries/src/Crypt/Cipher/McryptCipher.php', + '/libraries/src/Crypt/Cipher/Rijndael256Cipher.php', + '/libraries/src/Crypt/Cipher/SimpleCipher.php', + '/libraries/src/Crypt/Cipher/TripleDesCipher.php', + '/libraries/src/Crypt/CipherInterface.php', + '/libraries/src/Crypt/CryptPassword.php', + '/libraries/src/Crypt/Key.php', + '/libraries/src/Crypt/Password/SimpleCryptPassword.php', + '/libraries/src/Crypt/README.md', + '/libraries/src/Http/Wrapper/FactoryWrapper.php', + '/libraries/src/Mail/MailWrapper.php', + '/libraries/src/Table/Observer/AbstractObserver.php', + '/libraries/src/Table/Observer/ContentHistory.php', + '/libraries/src/Table/Observer/Tags.php', + '/libraries/vendor/joomla/application/src/AbstractDaemonApplication.php', + '/libraries/vendor/joomla/application/src/Cli/ColorProcessor.php', + '/libraries/vendor/joomla/registry/src/AbstractRegistryFormat.php', + '/libraries/vendor/joomla/session/Joomla/Session/LICENSE', + '/libraries/vendor/joomla/session/Joomla/Session/Session.php', + '/libraries/vendor/joomla/session/Joomla/Session/Storage.php', + '/libraries/vendor/joomla/session/Joomla/Session/Storage/Apc.php', + '/libraries/vendor/joomla/session/Joomla/Session/Storage/Database.php', + '/libraries/vendor/joomla/session/Joomla/Session/Storage/Memcache.php', + '/libraries/vendor/joomla/session/Joomla/Session/Storage/Memcached.php', + '/libraries/vendor/joomla/session/Joomla/Session/Storage/None.php', + '/libraries/vendor/joomla/session/Joomla/Session/Storage/Wincache.php', + '/libraries/vendor/joomla/session/Joomla/Session/Storage/Xcache.php', + '/libraries/vendor/joomla/string/src/String.php', + '/libraries/vendor/leafo/lessphp/LICENSE', + '/libraries/vendor/leafo/lessphp/lessc.inc.php', + '/libraries/vendor/leafo/lessphp/lessify', + '/libraries/vendor/leafo/lessphp/lessify.inc.php', + '/libraries/vendor/leafo/lessphp/plessc', + '/libraries/vendor/paragonie/random_compat/lib/random_bytes_openssl.php', + '/libraries/vendor/phpmailer/phpmailer/PHPMailerAutoload.php', + '/libraries/vendor/phpmailer/phpmailer/class.phpmailer.php', + '/libraries/vendor/phpmailer/phpmailer/class.phpmaileroauth.php', + '/libraries/vendor/phpmailer/phpmailer/class.phpmaileroauthgoogle.php', + '/libraries/vendor/phpmailer/phpmailer/class.pop3.php', + '/libraries/vendor/phpmailer/phpmailer/class.smtp.php', + '/libraries/vendor/phpmailer/phpmailer/composer.lock', + '/libraries/vendor/phpmailer/phpmailer/extras/EasyPeasyICS.php', + '/libraries/vendor/phpmailer/phpmailer/extras/htmlfilter.php', + '/libraries/vendor/phpmailer/phpmailer/extras/ntlm_sasl_client.php', + '/libraries/vendor/simplepie/simplepie/LICENSE.txt', + '/libraries/vendor/simplepie/simplepie/autoloader.php', + '/libraries/vendor/simplepie/simplepie/db.sql', + '/libraries/vendor/simplepie/simplepie/idn/LICENCE', + '/libraries/vendor/simplepie/simplepie/idn/idna_convert.class.php', + '/libraries/vendor/simplepie/simplepie/idn/npdata.ser', + '/libraries/vendor/simplepie/simplepie/library/SimplePie.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Author.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Cache.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Cache/Base.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Cache/DB.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Cache/File.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcache.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Cache/MySQL.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Caption.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Category.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Content/Type/Sniffer.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Copyright.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Core.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Credit.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Decode/HTML/Entities.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Enclosure.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Exception.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/File.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/HTTP/Parser.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/IRI.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Item.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Locator.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Misc.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Net/IPv6.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Parse/Date.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Parser.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Rating.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Registry.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Restriction.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Sanitize.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/Source.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/XML/Declaration/Parser.php', + '/libraries/vendor/simplepie/simplepie/library/SimplePie/gzdecode.php', + '/libraries/vendor/symfony/polyfill-php55/LICENSE', + '/libraries/vendor/symfony/polyfill-php55/Php55.php', + '/libraries/vendor/symfony/polyfill-php55/Php55ArrayColumn.php', + '/libraries/vendor/symfony/polyfill-php55/bootstrap.php', + '/media/cms/css/debug.css', + '/media/com_associations/js/sidebyside-uncompressed.js', + '/media/com_contenthistory/css/jquery.pretty-text-diff.css', + '/media/com_contenthistory/js/diff_match_patch.js', + '/media/com_contenthistory/js/jquery.pretty-text-diff.js', + '/media/com_contenthistory/js/jquery.pretty-text-diff.min.js', + '/media/com_finder/js/autocompleter.js', + '/media/editors/codemirror/LICENSE', + '/media/editors/codemirror/addon/comment/comment.js', + '/media/editors/codemirror/addon/comment/comment.min.js', + '/media/editors/codemirror/addon/comment/continuecomment.js', + '/media/editors/codemirror/addon/comment/continuecomment.min.js', + '/media/editors/codemirror/addon/dialog/dialog.css', + '/media/editors/codemirror/addon/dialog/dialog.js', + '/media/editors/codemirror/addon/dialog/dialog.min.css', + '/media/editors/codemirror/addon/dialog/dialog.min.js', + '/media/editors/codemirror/addon/display/autorefresh.js', + '/media/editors/codemirror/addon/display/autorefresh.min.js', + '/media/editors/codemirror/addon/display/fullscreen.css', + '/media/editors/codemirror/addon/display/fullscreen.js', + '/media/editors/codemirror/addon/display/fullscreen.min.css', + '/media/editors/codemirror/addon/display/fullscreen.min.js', + '/media/editors/codemirror/addon/display/panel.js', + '/media/editors/codemirror/addon/display/panel.min.js', + '/media/editors/codemirror/addon/display/placeholder.js', + '/media/editors/codemirror/addon/display/placeholder.min.js', + '/media/editors/codemirror/addon/display/rulers.js', + '/media/editors/codemirror/addon/display/rulers.min.js', + '/media/editors/codemirror/addon/edit/closebrackets.js', + '/media/editors/codemirror/addon/edit/closebrackets.min.js', + '/media/editors/codemirror/addon/edit/closetag.js', + '/media/editors/codemirror/addon/edit/closetag.min.js', + '/media/editors/codemirror/addon/edit/continuelist.js', + '/media/editors/codemirror/addon/edit/continuelist.min.js', + '/media/editors/codemirror/addon/edit/matchbrackets.js', + '/media/editors/codemirror/addon/edit/matchbrackets.min.js', + '/media/editors/codemirror/addon/edit/matchtags.js', + '/media/editors/codemirror/addon/edit/matchtags.min.js', + '/media/editors/codemirror/addon/edit/trailingspace.js', + '/media/editors/codemirror/addon/edit/trailingspace.min.js', + '/media/editors/codemirror/addon/fold/brace-fold.js', + '/media/editors/codemirror/addon/fold/brace-fold.min.js', + '/media/editors/codemirror/addon/fold/comment-fold.js', + '/media/editors/codemirror/addon/fold/comment-fold.min.js', + '/media/editors/codemirror/addon/fold/foldcode.js', + '/media/editors/codemirror/addon/fold/foldcode.min.js', + '/media/editors/codemirror/addon/fold/foldgutter.css', + '/media/editors/codemirror/addon/fold/foldgutter.js', + '/media/editors/codemirror/addon/fold/foldgutter.min.css', + '/media/editors/codemirror/addon/fold/foldgutter.min.js', + '/media/editors/codemirror/addon/fold/indent-fold.js', + '/media/editors/codemirror/addon/fold/indent-fold.min.js', + '/media/editors/codemirror/addon/fold/markdown-fold.js', + '/media/editors/codemirror/addon/fold/markdown-fold.min.js', + '/media/editors/codemirror/addon/fold/xml-fold.js', + '/media/editors/codemirror/addon/fold/xml-fold.min.js', + '/media/editors/codemirror/addon/hint/anyword-hint.js', + '/media/editors/codemirror/addon/hint/anyword-hint.min.js', + '/media/editors/codemirror/addon/hint/css-hint.js', + '/media/editors/codemirror/addon/hint/css-hint.min.js', + '/media/editors/codemirror/addon/hint/html-hint.js', + '/media/editors/codemirror/addon/hint/html-hint.min.js', + '/media/editors/codemirror/addon/hint/javascript-hint.js', + '/media/editors/codemirror/addon/hint/javascript-hint.min.js', + '/media/editors/codemirror/addon/hint/show-hint.css', + '/media/editors/codemirror/addon/hint/show-hint.js', + '/media/editors/codemirror/addon/hint/show-hint.min.css', + '/media/editors/codemirror/addon/hint/show-hint.min.js', + '/media/editors/codemirror/addon/hint/sql-hint.js', + '/media/editors/codemirror/addon/hint/sql-hint.min.js', + '/media/editors/codemirror/addon/hint/xml-hint.js', + '/media/editors/codemirror/addon/hint/xml-hint.min.js', + '/media/editors/codemirror/addon/lint/coffeescript-lint.js', + '/media/editors/codemirror/addon/lint/coffeescript-lint.min.js', + '/media/editors/codemirror/addon/lint/css-lint.js', + '/media/editors/codemirror/addon/lint/css-lint.min.js', + '/media/editors/codemirror/addon/lint/html-lint.js', + '/media/editors/codemirror/addon/lint/html-lint.min.js', + '/media/editors/codemirror/addon/lint/javascript-lint.js', + '/media/editors/codemirror/addon/lint/javascript-lint.min.js', + '/media/editors/codemirror/addon/lint/json-lint.js', + '/media/editors/codemirror/addon/lint/json-lint.min.js', + '/media/editors/codemirror/addon/lint/lint.css', + '/media/editors/codemirror/addon/lint/lint.js', + '/media/editors/codemirror/addon/lint/lint.min.css', + '/media/editors/codemirror/addon/lint/lint.min.js', + '/media/editors/codemirror/addon/lint/yaml-lint.js', + '/media/editors/codemirror/addon/lint/yaml-lint.min.js', + '/media/editors/codemirror/addon/merge/merge.css', + '/media/editors/codemirror/addon/merge/merge.js', + '/media/editors/codemirror/addon/merge/merge.min.css', + '/media/editors/codemirror/addon/merge/merge.min.js', + '/media/editors/codemirror/addon/mode/loadmode.js', + '/media/editors/codemirror/addon/mode/loadmode.min.js', + '/media/editors/codemirror/addon/mode/multiplex.js', + '/media/editors/codemirror/addon/mode/multiplex.min.js', + '/media/editors/codemirror/addon/mode/multiplex_test.js', + '/media/editors/codemirror/addon/mode/multiplex_test.min.js', + '/media/editors/codemirror/addon/mode/overlay.js', + '/media/editors/codemirror/addon/mode/overlay.min.js', + '/media/editors/codemirror/addon/mode/simple.js', + '/media/editors/codemirror/addon/mode/simple.min.js', + '/media/editors/codemirror/addon/runmode/colorize.js', + '/media/editors/codemirror/addon/runmode/colorize.min.js', + '/media/editors/codemirror/addon/runmode/runmode-standalone.js', + '/media/editors/codemirror/addon/runmode/runmode-standalone.min.js', + '/media/editors/codemirror/addon/runmode/runmode.js', + '/media/editors/codemirror/addon/runmode/runmode.min.js', + '/media/editors/codemirror/addon/runmode/runmode.node.js', + '/media/editors/codemirror/addon/scroll/annotatescrollbar.js', + '/media/editors/codemirror/addon/scroll/annotatescrollbar.min.js', + '/media/editors/codemirror/addon/scroll/scrollpastend.js', + '/media/editors/codemirror/addon/scroll/scrollpastend.min.js', + '/media/editors/codemirror/addon/scroll/simplescrollbars.css', + '/media/editors/codemirror/addon/scroll/simplescrollbars.js', + '/media/editors/codemirror/addon/scroll/simplescrollbars.min.css', + '/media/editors/codemirror/addon/scroll/simplescrollbars.min.js', + '/media/editors/codemirror/addon/search/jump-to-line.js', + '/media/editors/codemirror/addon/search/jump-to-line.min.js', + '/media/editors/codemirror/addon/search/match-highlighter.js', + '/media/editors/codemirror/addon/search/match-highlighter.min.js', + '/media/editors/codemirror/addon/search/matchesonscrollbar.css', + '/media/editors/codemirror/addon/search/matchesonscrollbar.js', + '/media/editors/codemirror/addon/search/matchesonscrollbar.min.css', + '/media/editors/codemirror/addon/search/matchesonscrollbar.min.js', + '/media/editors/codemirror/addon/search/search.js', + '/media/editors/codemirror/addon/search/search.min.js', + '/media/editors/codemirror/addon/search/searchcursor.js', + '/media/editors/codemirror/addon/search/searchcursor.min.js', + '/media/editors/codemirror/addon/selection/active-line.js', + '/media/editors/codemirror/addon/selection/active-line.min.js', + '/media/editors/codemirror/addon/selection/mark-selection.js', + '/media/editors/codemirror/addon/selection/mark-selection.min.js', + '/media/editors/codemirror/addon/selection/selection-pointer.js', + '/media/editors/codemirror/addon/selection/selection-pointer.min.js', + '/media/editors/codemirror/addon/tern/tern.css', + '/media/editors/codemirror/addon/tern/tern.js', + '/media/editors/codemirror/addon/tern/tern.min.css', + '/media/editors/codemirror/addon/tern/tern.min.js', + '/media/editors/codemirror/addon/tern/worker.js', + '/media/editors/codemirror/addon/tern/worker.min.js', + '/media/editors/codemirror/addon/wrap/hardwrap.js', + '/media/editors/codemirror/addon/wrap/hardwrap.min.js', + '/media/editors/codemirror/keymap/emacs.js', + '/media/editors/codemirror/keymap/emacs.min.js', + '/media/editors/codemirror/keymap/sublime.js', + '/media/editors/codemirror/keymap/sublime.min.js', + '/media/editors/codemirror/keymap/vim.js', + '/media/editors/codemirror/keymap/vim.min.js', + '/media/editors/codemirror/lib/addons.css', + '/media/editors/codemirror/lib/addons.js', + '/media/editors/codemirror/lib/addons.min.css', + '/media/editors/codemirror/lib/addons.min.js', + '/media/editors/codemirror/lib/codemirror.css', + '/media/editors/codemirror/lib/codemirror.js', + '/media/editors/codemirror/lib/codemirror.min.css', + '/media/editors/codemirror/lib/codemirror.min.js', + '/media/editors/codemirror/mode/apl/apl.js', + '/media/editors/codemirror/mode/apl/apl.min.js', + '/media/editors/codemirror/mode/asciiarmor/asciiarmor.js', + '/media/editors/codemirror/mode/asciiarmor/asciiarmor.min.js', + '/media/editors/codemirror/mode/asn.1/asn.1.js', + '/media/editors/codemirror/mode/asn.1/asn.min.js', + '/media/editors/codemirror/mode/asterisk/asterisk.js', + '/media/editors/codemirror/mode/asterisk/asterisk.min.js', + '/media/editors/codemirror/mode/brainfuck/brainfuck.js', + '/media/editors/codemirror/mode/brainfuck/brainfuck.min.js', + '/media/editors/codemirror/mode/clike/clike.js', + '/media/editors/codemirror/mode/clike/clike.min.js', + '/media/editors/codemirror/mode/clojure/clojure.js', + '/media/editors/codemirror/mode/clojure/clojure.min.js', + '/media/editors/codemirror/mode/cmake/cmake.js', + '/media/editors/codemirror/mode/cmake/cmake.min.js', + '/media/editors/codemirror/mode/cobol/cobol.js', + '/media/editors/codemirror/mode/cobol/cobol.min.js', + '/media/editors/codemirror/mode/coffeescript/coffeescript.js', + '/media/editors/codemirror/mode/coffeescript/coffeescript.min.js', + '/media/editors/codemirror/mode/commonlisp/commonlisp.js', + '/media/editors/codemirror/mode/commonlisp/commonlisp.min.js', + '/media/editors/codemirror/mode/crystal/crystal.js', + '/media/editors/codemirror/mode/crystal/crystal.min.js', + '/media/editors/codemirror/mode/css/css.js', + '/media/editors/codemirror/mode/css/css.min.js', + '/media/editors/codemirror/mode/cypher/cypher.js', + '/media/editors/codemirror/mode/cypher/cypher.min.js', + '/media/editors/codemirror/mode/d/d.js', + '/media/editors/codemirror/mode/d/d.min.js', + '/media/editors/codemirror/mode/dart/dart.js', + '/media/editors/codemirror/mode/dart/dart.min.js', + '/media/editors/codemirror/mode/diff/diff.js', + '/media/editors/codemirror/mode/diff/diff.min.js', + '/media/editors/codemirror/mode/django/django.js', + '/media/editors/codemirror/mode/django/django.min.js', + '/media/editors/codemirror/mode/dockerfile/dockerfile.js', + '/media/editors/codemirror/mode/dockerfile/dockerfile.min.js', + '/media/editors/codemirror/mode/dtd/dtd.js', + '/media/editors/codemirror/mode/dtd/dtd.min.js', + '/media/editors/codemirror/mode/dylan/dylan.js', + '/media/editors/codemirror/mode/dylan/dylan.min.js', + '/media/editors/codemirror/mode/ebnf/ebnf.js', + '/media/editors/codemirror/mode/ebnf/ebnf.min.js', + '/media/editors/codemirror/mode/ecl/ecl.js', + '/media/editors/codemirror/mode/ecl/ecl.min.js', + '/media/editors/codemirror/mode/eiffel/eiffel.js', + '/media/editors/codemirror/mode/eiffel/eiffel.min.js', + '/media/editors/codemirror/mode/elm/elm.js', + '/media/editors/codemirror/mode/elm/elm.min.js', + '/media/editors/codemirror/mode/erlang/erlang.js', + '/media/editors/codemirror/mode/erlang/erlang.min.js', + '/media/editors/codemirror/mode/factor/factor.js', + '/media/editors/codemirror/mode/factor/factor.min.js', + '/media/editors/codemirror/mode/fcl/fcl.js', + '/media/editors/codemirror/mode/fcl/fcl.min.js', + '/media/editors/codemirror/mode/forth/forth.js', + '/media/editors/codemirror/mode/forth/forth.min.js', + '/media/editors/codemirror/mode/fortran/fortran.js', + '/media/editors/codemirror/mode/fortran/fortran.min.js', + '/media/editors/codemirror/mode/gas/gas.js', + '/media/editors/codemirror/mode/gas/gas.min.js', + '/media/editors/codemirror/mode/gfm/gfm.js', + '/media/editors/codemirror/mode/gfm/gfm.min.js', + '/media/editors/codemirror/mode/gherkin/gherkin.js', + '/media/editors/codemirror/mode/gherkin/gherkin.min.js', + '/media/editors/codemirror/mode/go/go.js', + '/media/editors/codemirror/mode/go/go.min.js', + '/media/editors/codemirror/mode/groovy/groovy.js', + '/media/editors/codemirror/mode/groovy/groovy.min.js', + '/media/editors/codemirror/mode/haml/haml.js', + '/media/editors/codemirror/mode/haml/haml.min.js', + '/media/editors/codemirror/mode/handlebars/handlebars.js', + '/media/editors/codemirror/mode/handlebars/handlebars.min.js', + '/media/editors/codemirror/mode/haskell-literate/haskell-literate.js', + '/media/editors/codemirror/mode/haskell-literate/haskell-literate.min.js', + '/media/editors/codemirror/mode/haskell/haskell.js', + '/media/editors/codemirror/mode/haskell/haskell.min.js', + '/media/editors/codemirror/mode/haxe/haxe.js', + '/media/editors/codemirror/mode/haxe/haxe.min.js', + '/media/editors/codemirror/mode/htmlembedded/htmlembedded.js', + '/media/editors/codemirror/mode/htmlembedded/htmlembedded.min.js', + '/media/editors/codemirror/mode/htmlmixed/htmlmixed.js', + '/media/editors/codemirror/mode/htmlmixed/htmlmixed.min.js', + '/media/editors/codemirror/mode/http/http.js', + '/media/editors/codemirror/mode/http/http.min.js', + '/media/editors/codemirror/mode/idl/idl.js', + '/media/editors/codemirror/mode/idl/idl.min.js', + '/media/editors/codemirror/mode/javascript/javascript.js', + '/media/editors/codemirror/mode/javascript/javascript.min.js', + '/media/editors/codemirror/mode/jinja2/jinja2.js', + '/media/editors/codemirror/mode/jinja2/jinja2.min.js', + '/media/editors/codemirror/mode/jsx/jsx.js', + '/media/editors/codemirror/mode/jsx/jsx.min.js', + '/media/editors/codemirror/mode/julia/julia.js', + '/media/editors/codemirror/mode/julia/julia.min.js', + '/media/editors/codemirror/mode/livescript/livescript.js', + '/media/editors/codemirror/mode/livescript/livescript.min.js', + '/media/editors/codemirror/mode/lua/lua.js', + '/media/editors/codemirror/mode/lua/lua.min.js', + '/media/editors/codemirror/mode/markdown/markdown.js', + '/media/editors/codemirror/mode/markdown/markdown.min.js', + '/media/editors/codemirror/mode/mathematica/mathematica.js', + '/media/editors/codemirror/mode/mathematica/mathematica.min.js', + '/media/editors/codemirror/mode/mbox/mbox.js', + '/media/editors/codemirror/mode/mbox/mbox.min.js', + '/media/editors/codemirror/mode/meta.js', + '/media/editors/codemirror/mode/meta.min.js', + '/media/editors/codemirror/mode/mirc/mirc.js', + '/media/editors/codemirror/mode/mirc/mirc.min.js', + '/media/editors/codemirror/mode/mllike/mllike.js', + '/media/editors/codemirror/mode/mllike/mllike.min.js', + '/media/editors/codemirror/mode/modelica/modelica.js', + '/media/editors/codemirror/mode/modelica/modelica.min.js', + '/media/editors/codemirror/mode/mscgen/mscgen.js', + '/media/editors/codemirror/mode/mscgen/mscgen.min.js', + '/media/editors/codemirror/mode/mumps/mumps.js', + '/media/editors/codemirror/mode/mumps/mumps.min.js', + '/media/editors/codemirror/mode/nginx/nginx.js', + '/media/editors/codemirror/mode/nginx/nginx.min.js', + '/media/editors/codemirror/mode/nsis/nsis.js', + '/media/editors/codemirror/mode/nsis/nsis.min.js', + '/media/editors/codemirror/mode/ntriples/ntriples.js', + '/media/editors/codemirror/mode/ntriples/ntriples.min.js', + '/media/editors/codemirror/mode/octave/octave.js', + '/media/editors/codemirror/mode/octave/octave.min.js', + '/media/editors/codemirror/mode/oz/oz.js', + '/media/editors/codemirror/mode/oz/oz.min.js', + '/media/editors/codemirror/mode/pascal/pascal.js', + '/media/editors/codemirror/mode/pascal/pascal.min.js', + '/media/editors/codemirror/mode/pegjs/pegjs.js', + '/media/editors/codemirror/mode/pegjs/pegjs.min.js', + '/media/editors/codemirror/mode/perl/perl.js', + '/media/editors/codemirror/mode/perl/perl.min.js', + '/media/editors/codemirror/mode/php/php.js', + '/media/editors/codemirror/mode/php/php.min.js', + '/media/editors/codemirror/mode/pig/pig.js', + '/media/editors/codemirror/mode/pig/pig.min.js', + '/media/editors/codemirror/mode/powershell/powershell.js', + '/media/editors/codemirror/mode/powershell/powershell.min.js', + '/media/editors/codemirror/mode/properties/properties.js', + '/media/editors/codemirror/mode/properties/properties.min.js', + '/media/editors/codemirror/mode/protobuf/protobuf.js', + '/media/editors/codemirror/mode/protobuf/protobuf.min.js', + '/media/editors/codemirror/mode/pug/pug.js', + '/media/editors/codemirror/mode/pug/pug.min.js', + '/media/editors/codemirror/mode/puppet/puppet.js', + '/media/editors/codemirror/mode/puppet/puppet.min.js', + '/media/editors/codemirror/mode/python/python.js', + '/media/editors/codemirror/mode/python/python.min.js', + '/media/editors/codemirror/mode/q/q.js', + '/media/editors/codemirror/mode/q/q.min.js', + '/media/editors/codemirror/mode/r/r.js', + '/media/editors/codemirror/mode/r/r.min.js', + '/media/editors/codemirror/mode/rpm/changes/index.html', + '/media/editors/codemirror/mode/rpm/rpm.js', + '/media/editors/codemirror/mode/rpm/rpm.min.js', + '/media/editors/codemirror/mode/rst/rst.js', + '/media/editors/codemirror/mode/rst/rst.min.js', + '/media/editors/codemirror/mode/ruby/ruby.js', + '/media/editors/codemirror/mode/ruby/ruby.min.js', + '/media/editors/codemirror/mode/rust/rust.js', + '/media/editors/codemirror/mode/rust/rust.min.js', + '/media/editors/codemirror/mode/sas/sas.js', + '/media/editors/codemirror/mode/sas/sas.min.js', + '/media/editors/codemirror/mode/sass/sass.js', + '/media/editors/codemirror/mode/sass/sass.min.js', + '/media/editors/codemirror/mode/scheme/scheme.js', + '/media/editors/codemirror/mode/scheme/scheme.min.js', + '/media/editors/codemirror/mode/shell/shell.js', + '/media/editors/codemirror/mode/shell/shell.min.js', + '/media/editors/codemirror/mode/sieve/sieve.js', + '/media/editors/codemirror/mode/sieve/sieve.min.js', + '/media/editors/codemirror/mode/slim/slim.js', + '/media/editors/codemirror/mode/slim/slim.min.js', + '/media/editors/codemirror/mode/smalltalk/smalltalk.js', + '/media/editors/codemirror/mode/smalltalk/smalltalk.min.js', + '/media/editors/codemirror/mode/smarty/smarty.js', + '/media/editors/codemirror/mode/smarty/smarty.min.js', + '/media/editors/codemirror/mode/solr/solr.js', + '/media/editors/codemirror/mode/solr/solr.min.js', + '/media/editors/codemirror/mode/soy/soy.js', + '/media/editors/codemirror/mode/soy/soy.min.js', + '/media/editors/codemirror/mode/sparql/sparql.js', + '/media/editors/codemirror/mode/sparql/sparql.min.js', + '/media/editors/codemirror/mode/spreadsheet/spreadsheet.js', + '/media/editors/codemirror/mode/spreadsheet/spreadsheet.min.js', + '/media/editors/codemirror/mode/sql/sql.js', + '/media/editors/codemirror/mode/sql/sql.min.js', + '/media/editors/codemirror/mode/stex/stex.js', + '/media/editors/codemirror/mode/stex/stex.min.js', + '/media/editors/codemirror/mode/stylus/stylus.js', + '/media/editors/codemirror/mode/stylus/stylus.min.js', + '/media/editors/codemirror/mode/swift/swift.js', + '/media/editors/codemirror/mode/swift/swift.min.js', + '/media/editors/codemirror/mode/tcl/tcl.js', + '/media/editors/codemirror/mode/tcl/tcl.min.js', + '/media/editors/codemirror/mode/textile/textile.js', + '/media/editors/codemirror/mode/textile/textile.min.js', + '/media/editors/codemirror/mode/tiddlywiki/tiddlywiki.css', + '/media/editors/codemirror/mode/tiddlywiki/tiddlywiki.js', + '/media/editors/codemirror/mode/tiddlywiki/tiddlywiki.min.css', + '/media/editors/codemirror/mode/tiddlywiki/tiddlywiki.min.js', + '/media/editors/codemirror/mode/tiki/tiki.css', + '/media/editors/codemirror/mode/tiki/tiki.js', + '/media/editors/codemirror/mode/tiki/tiki.min.css', + '/media/editors/codemirror/mode/tiki/tiki.min.js', + '/media/editors/codemirror/mode/toml/toml.js', + '/media/editors/codemirror/mode/toml/toml.min.js', + '/media/editors/codemirror/mode/tornado/tornado.js', + '/media/editors/codemirror/mode/tornado/tornado.min.js', + '/media/editors/codemirror/mode/troff/troff.js', + '/media/editors/codemirror/mode/troff/troff.min.js', + '/media/editors/codemirror/mode/ttcn-cfg/ttcn-cfg.js', + '/media/editors/codemirror/mode/ttcn-cfg/ttcn-cfg.min.js', + '/media/editors/codemirror/mode/ttcn/ttcn.js', + '/media/editors/codemirror/mode/ttcn/ttcn.min.js', + '/media/editors/codemirror/mode/turtle/turtle.js', + '/media/editors/codemirror/mode/turtle/turtle.min.js', + '/media/editors/codemirror/mode/twig/twig.js', + '/media/editors/codemirror/mode/twig/twig.min.js', + '/media/editors/codemirror/mode/vb/vb.js', + '/media/editors/codemirror/mode/vb/vb.min.js', + '/media/editors/codemirror/mode/vbscript/vbscript.js', + '/media/editors/codemirror/mode/vbscript/vbscript.min.js', + '/media/editors/codemirror/mode/velocity/velocity.js', + '/media/editors/codemirror/mode/velocity/velocity.min.js', + '/media/editors/codemirror/mode/verilog/verilog.js', + '/media/editors/codemirror/mode/verilog/verilog.min.js', + '/media/editors/codemirror/mode/vhdl/vhdl.js', + '/media/editors/codemirror/mode/vhdl/vhdl.min.js', + '/media/editors/codemirror/mode/vue/vue.js', + '/media/editors/codemirror/mode/vue/vue.min.js', + '/media/editors/codemirror/mode/webidl/webidl.js', + '/media/editors/codemirror/mode/webidl/webidl.min.js', + '/media/editors/codemirror/mode/xml/xml.js', + '/media/editors/codemirror/mode/xml/xml.min.js', + '/media/editors/codemirror/mode/xquery/xquery.js', + '/media/editors/codemirror/mode/xquery/xquery.min.js', + '/media/editors/codemirror/mode/yacas/yacas.js', + '/media/editors/codemirror/mode/yacas/yacas.min.js', + '/media/editors/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js', + '/media/editors/codemirror/mode/yaml-frontmatter/yaml-frontmatter.min.js', + '/media/editors/codemirror/mode/yaml/yaml.js', + '/media/editors/codemirror/mode/yaml/yaml.min.js', + '/media/editors/codemirror/mode/z80/z80.js', + '/media/editors/codemirror/mode/z80/z80.min.js', + '/media/editors/codemirror/theme/3024-day.css', + '/media/editors/codemirror/theme/3024-night.css', + '/media/editors/codemirror/theme/abcdef.css', + '/media/editors/codemirror/theme/ambiance-mobile.css', + '/media/editors/codemirror/theme/ambiance.css', + '/media/editors/codemirror/theme/base16-dark.css', + '/media/editors/codemirror/theme/base16-light.css', + '/media/editors/codemirror/theme/bespin.css', + '/media/editors/codemirror/theme/blackboard.css', + '/media/editors/codemirror/theme/cobalt.css', + '/media/editors/codemirror/theme/colorforth.css', + '/media/editors/codemirror/theme/dracula.css', + '/media/editors/codemirror/theme/duotone-dark.css', + '/media/editors/codemirror/theme/duotone-light.css', + '/media/editors/codemirror/theme/eclipse.css', + '/media/editors/codemirror/theme/elegant.css', + '/media/editors/codemirror/theme/erlang-dark.css', + '/media/editors/codemirror/theme/hopscotch.css', + '/media/editors/codemirror/theme/icecoder.css', + '/media/editors/codemirror/theme/isotope.css', + '/media/editors/codemirror/theme/lesser-dark.css', + '/media/editors/codemirror/theme/liquibyte.css', + '/media/editors/codemirror/theme/material.css', + '/media/editors/codemirror/theme/mbo.css', + '/media/editors/codemirror/theme/mdn-like.css', + '/media/editors/codemirror/theme/midnight.css', + '/media/editors/codemirror/theme/monokai.css', + '/media/editors/codemirror/theme/neat.css', + '/media/editors/codemirror/theme/neo.css', + '/media/editors/codemirror/theme/night.css', + '/media/editors/codemirror/theme/panda-syntax.css', + '/media/editors/codemirror/theme/paraiso-dark.css', + '/media/editors/codemirror/theme/paraiso-light.css', + '/media/editors/codemirror/theme/pastel-on-dark.css', + '/media/editors/codemirror/theme/railscasts.css', + '/media/editors/codemirror/theme/rubyblue.css', + '/media/editors/codemirror/theme/seti.css', + '/media/editors/codemirror/theme/solarized.css', + '/media/editors/codemirror/theme/the-matrix.css', + '/media/editors/codemirror/theme/tomorrow-night-bright.css', + '/media/editors/codemirror/theme/tomorrow-night-eighties.css', + '/media/editors/codemirror/theme/ttcn.css', + '/media/editors/codemirror/theme/twilight.css', + '/media/editors/codemirror/theme/vibrant-ink.css', + '/media/editors/codemirror/theme/xq-dark.css', + '/media/editors/codemirror/theme/xq-light.css', + '/media/editors/codemirror/theme/yeti.css', + '/media/editors/codemirror/theme/zenburn.css', + '/media/editors/none/js/none.js', + '/media/editors/none/js/none.min.js', + '/media/editors/tinymce/changelog.txt', + '/media/editors/tinymce/langs/af.js', + '/media/editors/tinymce/langs/ar.js', + '/media/editors/tinymce/langs/be.js', + '/media/editors/tinymce/langs/bg.js', + '/media/editors/tinymce/langs/bs.js', + '/media/editors/tinymce/langs/ca.js', + '/media/editors/tinymce/langs/cs.js', + '/media/editors/tinymce/langs/cy.js', + '/media/editors/tinymce/langs/da.js', + '/media/editors/tinymce/langs/de.js', + '/media/editors/tinymce/langs/el.js', + '/media/editors/tinymce/langs/es.js', + '/media/editors/tinymce/langs/et.js', + '/media/editors/tinymce/langs/eu.js', + '/media/editors/tinymce/langs/fa.js', + '/media/editors/tinymce/langs/fi.js', + '/media/editors/tinymce/langs/fo.js', + '/media/editors/tinymce/langs/fr.js', + '/media/editors/tinymce/langs/ga.js', + '/media/editors/tinymce/langs/gl.js', + '/media/editors/tinymce/langs/he.js', + '/media/editors/tinymce/langs/hr.js', + '/media/editors/tinymce/langs/hu.js', + '/media/editors/tinymce/langs/id.js', + '/media/editors/tinymce/langs/it.js', + '/media/editors/tinymce/langs/ja.js', + '/media/editors/tinymce/langs/ka.js', + '/media/editors/tinymce/langs/km.js', + '/media/editors/tinymce/langs/ko.js', + '/media/editors/tinymce/langs/lb.js', + '/media/editors/tinymce/langs/lt.js', + '/media/editors/tinymce/langs/lv.js', + '/media/editors/tinymce/langs/mk.js', + '/media/editors/tinymce/langs/ms.js', + '/media/editors/tinymce/langs/nb.js', + '/media/editors/tinymce/langs/nl.js', + '/media/editors/tinymce/langs/pl.js', + '/media/editors/tinymce/langs/pt-BR.js', + '/media/editors/tinymce/langs/pt-PT.js', + '/media/editors/tinymce/langs/readme.md', + '/media/editors/tinymce/langs/ro.js', + '/media/editors/tinymce/langs/ru.js', + '/media/editors/tinymce/langs/si-LK.js', + '/media/editors/tinymce/langs/sk.js', + '/media/editors/tinymce/langs/sl.js', + '/media/editors/tinymce/langs/sr.js', + '/media/editors/tinymce/langs/sv.js', + '/media/editors/tinymce/langs/sw.js', + '/media/editors/tinymce/langs/sy.js', + '/media/editors/tinymce/langs/ta.js', + '/media/editors/tinymce/langs/th.js', + '/media/editors/tinymce/langs/tr.js', + '/media/editors/tinymce/langs/ug.js', + '/media/editors/tinymce/langs/uk.js', + '/media/editors/tinymce/langs/vi.js', + '/media/editors/tinymce/langs/zh-CN.js', + '/media/editors/tinymce/langs/zh-TW.js', + '/media/editors/tinymce/license.txt', + '/media/editors/tinymce/plugins/advlist/plugin.min.js', + '/media/editors/tinymce/plugins/anchor/plugin.min.js', + '/media/editors/tinymce/plugins/autolink/plugin.min.js', + '/media/editors/tinymce/plugins/autoresize/plugin.min.js', + '/media/editors/tinymce/plugins/autosave/plugin.min.js', + '/media/editors/tinymce/plugins/bbcode/plugin.min.js', + '/media/editors/tinymce/plugins/charmap/plugin.min.js', + '/media/editors/tinymce/plugins/code/plugin.min.js', + '/media/editors/tinymce/plugins/codesample/css/prism.css', + '/media/editors/tinymce/plugins/codesample/plugin.min.js', + '/media/editors/tinymce/plugins/colorpicker/plugin.min.js', + '/media/editors/tinymce/plugins/contextmenu/plugin.min.js', + '/media/editors/tinymce/plugins/directionality/plugin.min.js', + '/media/editors/tinymce/plugins/emoticons/img/smiley-cool.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-cry.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-embarassed.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-frown.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-innocent.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-kiss.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-laughing.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-money-mouth.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-sealed.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-smile.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-surprised.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-tongue-out.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-undecided.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-wink.gif', + '/media/editors/tinymce/plugins/emoticons/img/smiley-yell.gif', + '/media/editors/tinymce/plugins/emoticons/plugin.min.js', + '/media/editors/tinymce/plugins/example/dialog.html', + '/media/editors/tinymce/plugins/example/plugin.min.js', + '/media/editors/tinymce/plugins/example_dependency/plugin.min.js', + '/media/editors/tinymce/plugins/fullpage/plugin.min.js', + '/media/editors/tinymce/plugins/fullscreen/plugin.min.js', + '/media/editors/tinymce/plugins/hr/plugin.min.js', + '/media/editors/tinymce/plugins/image/plugin.min.js', + '/media/editors/tinymce/plugins/imagetools/plugin.min.js', + '/media/editors/tinymce/plugins/importcss/plugin.min.js', + '/media/editors/tinymce/plugins/insertdatetime/plugin.min.js', + '/media/editors/tinymce/plugins/layer/plugin.min.js', + '/media/editors/tinymce/plugins/legacyoutput/plugin.min.js', + '/media/editors/tinymce/plugins/link/plugin.min.js', + '/media/editors/tinymce/plugins/lists/plugin.min.js', + '/media/editors/tinymce/plugins/media/plugin.min.js', + '/media/editors/tinymce/plugins/nonbreaking/plugin.min.js', + '/media/editors/tinymce/plugins/noneditable/plugin.min.js', + '/media/editors/tinymce/plugins/pagebreak/plugin.min.js', + '/media/editors/tinymce/plugins/paste/plugin.min.js', + '/media/editors/tinymce/plugins/preview/plugin.min.js', + '/media/editors/tinymce/plugins/print/plugin.min.js', + '/media/editors/tinymce/plugins/save/plugin.min.js', + '/media/editors/tinymce/plugins/searchreplace/plugin.min.js', + '/media/editors/tinymce/plugins/spellchecker/plugin.min.js', + '/media/editors/tinymce/plugins/tabfocus/plugin.min.js', + '/media/editors/tinymce/plugins/table/plugin.min.js', + '/media/editors/tinymce/plugins/template/plugin.min.js', + '/media/editors/tinymce/plugins/textcolor/plugin.min.js', + '/media/editors/tinymce/plugins/textpattern/plugin.min.js', + '/media/editors/tinymce/plugins/toc/plugin.min.js', + '/media/editors/tinymce/plugins/visualblocks/css/visualblocks.css', + '/media/editors/tinymce/plugins/visualblocks/plugin.min.js', + '/media/editors/tinymce/plugins/visualchars/plugin.min.js', + '/media/editors/tinymce/plugins/wordcount/plugin.min.js', + '/media/editors/tinymce/skins/lightgray/content.inline.min.css', + '/media/editors/tinymce/skins/lightgray/content.min.css', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce-small.eot', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce-small.svg', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce-small.ttf', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce-small.woff', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce.eot', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce.svg', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce.ttf', + '/media/editors/tinymce/skins/lightgray/fonts/tinymce.woff', + '/media/editors/tinymce/skins/lightgray/img/anchor.gif', + '/media/editors/tinymce/skins/lightgray/img/loader.gif', + '/media/editors/tinymce/skins/lightgray/img/object.gif', + '/media/editors/tinymce/skins/lightgray/img/trans.gif', + '/media/editors/tinymce/skins/lightgray/skin.ie7.min.css', + '/media/editors/tinymce/skins/lightgray/skin.min.css', + '/media/editors/tinymce/templates/layout1.html', + '/media/editors/tinymce/templates/snippet1.html', + '/media/editors/tinymce/themes/modern/theme.min.js', + '/media/editors/tinymce/tinymce.min.js', + '/media/jui/css/bootstrap-extended.css', + '/media/jui/css/bootstrap-responsive.css', + '/media/jui/css/bootstrap-responsive.min.css', + '/media/jui/css/bootstrap-rtl.css', + '/media/jui/css/bootstrap-tooltip-extended.css', + '/media/jui/css/bootstrap.css', + '/media/jui/css/bootstrap.min.css', + '/media/jui/css/chosen-sprite.png', + '/media/jui/css/chosen-sprite@2x.png', + '/media/jui/css/chosen.css', + '/media/jui/css/icomoon.css', + '/media/jui/css/jquery.minicolors.css', + '/media/jui/css/jquery.searchtools.css', + '/media/jui/css/jquery.simplecolors.css', + '/media/jui/css/sortablelist.css', + '/media/jui/fonts/IcoMoon.dev.commented.svg', + '/media/jui/fonts/IcoMoon.dev.svg', + '/media/jui/fonts/IcoMoon.eot', + '/media/jui/fonts/IcoMoon.svg', + '/media/jui/fonts/IcoMoon.ttf', + '/media/jui/fonts/IcoMoon.woff', + '/media/jui/fonts/icomoon-license.txt', + '/media/jui/images/ajax-loader.gif', + '/media/jui/img/ajax-loader.gif', + '/media/jui/img/alpha.png', + '/media/jui/img/bg-overlay.png', + '/media/jui/img/glyphicons-halflings-white.png', + '/media/jui/img/glyphicons-halflings.png', + '/media/jui/img/hue.png', + '/media/jui/img/joomla.png', + '/media/jui/img/jquery.minicolors.png', + '/media/jui/img/saturation.png', + '/media/jui/js/ajax-chosen.js', + '/media/jui/js/ajax-chosen.min.js', + '/media/jui/js/bootstrap-tooltip-extended.js', + '/media/jui/js/bootstrap-tooltip-extended.min.js', + '/media/jui/js/bootstrap.js', + '/media/jui/js/bootstrap.min.js', + '/media/jui/js/chosen.jquery.js', + '/media/jui/js/chosen.jquery.min.js', + '/media/jui/js/cms-uncompressed.js', + '/media/jui/js/cms.js', + '/media/jui/js/fielduser.js', + '/media/jui/js/fielduser.min.js', + '/media/jui/js/html5-uncompressed.js', + '/media/jui/js/html5.js', + '/media/jui/js/icomoon-lte-ie7.js', + '/media/jui/js/jquery-migrate.js', + '/media/jui/js/jquery-migrate.min.js', + '/media/jui/js/jquery-noconflict.js', + '/media/jui/js/jquery.autocomplete.js', + '/media/jui/js/jquery.autocomplete.min.js', + '/media/jui/js/jquery.js', + '/media/jui/js/jquery.min.js', + '/media/jui/js/jquery.minicolors.js', + '/media/jui/js/jquery.minicolors.min.js', + '/media/jui/js/jquery.searchtools.js', + '/media/jui/js/jquery.searchtools.min.js', + '/media/jui/js/jquery.simplecolors.js', + '/media/jui/js/jquery.simplecolors.min.js', + '/media/jui/js/jquery.ui.core.js', + '/media/jui/js/jquery.ui.core.min.js', + '/media/jui/js/jquery.ui.sortable.js', + '/media/jui/js/jquery.ui.sortable.min.js', + '/media/jui/js/sortablelist.js', + '/media/jui/js/treeselectmenu.jquery.js', + '/media/jui/js/treeselectmenu.jquery.min.js', + '/media/jui/less/accordion.less', + '/media/jui/less/alerts.less', + '/media/jui/less/bootstrap-extended.less', + '/media/jui/less/bootstrap-rtl.less', + '/media/jui/less/bootstrap.less', + '/media/jui/less/breadcrumbs.less', + '/media/jui/less/button-groups.less', + '/media/jui/less/buttons.less', + '/media/jui/less/carousel.less', + '/media/jui/less/close.less', + '/media/jui/less/code.less', + '/media/jui/less/component-animations.less', + '/media/jui/less/dropdowns.less', + '/media/jui/less/forms.less', + '/media/jui/less/grid.less', + '/media/jui/less/hero-unit.less', + '/media/jui/less/icomoon.less', + '/media/jui/less/labels-badges.less', + '/media/jui/less/layouts.less', + '/media/jui/less/media.less', + '/media/jui/less/mixins.less', + '/media/jui/less/modals.joomla.less', + '/media/jui/less/modals.less', + '/media/jui/less/navbar.less', + '/media/jui/less/navs.less', + '/media/jui/less/pager.less', + '/media/jui/less/pagination.less', + '/media/jui/less/popovers.less', + '/media/jui/less/progress-bars.less', + '/media/jui/less/reset.less', + '/media/jui/less/responsive-1200px-min.less', + '/media/jui/less/responsive-767px-max.joomla.less', + '/media/jui/less/responsive-767px-max.less', + '/media/jui/less/responsive-768px-979px.less', + '/media/jui/less/responsive-navbar.less', + '/media/jui/less/responsive-utilities.less', + '/media/jui/less/responsive.less', + '/media/jui/less/scaffolding.less', + '/media/jui/less/sprites.less', + '/media/jui/less/tables.less', + '/media/jui/less/thumbnails.less', + '/media/jui/less/tooltip.less', + '/media/jui/less/type.less', + '/media/jui/less/utilities.less', + '/media/jui/less/variables.less', + '/media/jui/less/wells.less', + '/media/media/css/background.png', + '/media/media/css/bigplay.fw.png', + '/media/media/css/bigplay.png', + '/media/media/css/bigplay.svg', + '/media/media/css/controls-ted.png', + '/media/media/css/controls-wmp-bg.png', + '/media/media/css/controls-wmp.png', + '/media/media/css/controls.fw.png', + '/media/media/css/controls.png', + '/media/media/css/controls.svg', + '/media/media/css/jumpforward.png', + '/media/media/css/loading.gif', + '/media/media/css/mediaelementplayer.css', + '/media/media/css/mediaelementplayer.min.css', + '/media/media/css/medialist-details.css', + '/media/media/css/medialist-details_rtl.css', + '/media/media/css/medialist-thumbs.css', + '/media/media/css/medialist-thumbs_rtl.css', + '/media/media/css/mediamanager.css', + '/media/media/css/mediamanager_rtl.css', + '/media/media/css/mejs-skins.css', + '/media/media/css/popup-imagelist.css', + '/media/media/css/popup-imagelist_rtl.css', + '/media/media/css/popup-imagemanager.css', + '/media/media/css/popup-imagemanager_rtl.css', + '/media/media/css/skipback.png', + '/media/media/images/bar.gif', + '/media/media/images/con_info.png', + '/media/media/images/delete.png', + '/media/media/images/dots.gif', + '/media/media/images/failed.png', + '/media/media/images/folder.gif', + '/media/media/images/folder.png', + '/media/media/images/folder_sm.png', + '/media/media/images/folderup_16.png', + '/media/media/images/folderup_32.png', + '/media/media/images/mime-icon-16/avi.png', + '/media/media/images/mime-icon-16/doc.png', + '/media/media/images/mime-icon-16/mov.png', + '/media/media/images/mime-icon-16/mp3.png', + '/media/media/images/mime-icon-16/mp4.png', + '/media/media/images/mime-icon-16/odc.png', + '/media/media/images/mime-icon-16/odd.png', + '/media/media/images/mime-icon-16/odt.png', + '/media/media/images/mime-icon-16/ogg.png', + '/media/media/images/mime-icon-16/pdf.png', + '/media/media/images/mime-icon-16/ppt.png', + '/media/media/images/mime-icon-16/rar.png', + '/media/media/images/mime-icon-16/rtf.png', + '/media/media/images/mime-icon-16/svg.png', + '/media/media/images/mime-icon-16/sxd.png', + '/media/media/images/mime-icon-16/tar.png', + '/media/media/images/mime-icon-16/tgz.png', + '/media/media/images/mime-icon-16/wma.png', + '/media/media/images/mime-icon-16/wmv.png', + '/media/media/images/mime-icon-16/xls.png', + '/media/media/images/mime-icon-16/zip.png', + '/media/media/images/mime-icon-32/avi.png', + '/media/media/images/mime-icon-32/doc.png', + '/media/media/images/mime-icon-32/mov.png', + '/media/media/images/mime-icon-32/mp3.png', + '/media/media/images/mime-icon-32/mp4.png', + '/media/media/images/mime-icon-32/odc.png', + '/media/media/images/mime-icon-32/odd.png', + '/media/media/images/mime-icon-32/odt.png', + '/media/media/images/mime-icon-32/ogg.png', + '/media/media/images/mime-icon-32/pdf.png', + '/media/media/images/mime-icon-32/ppt.png', + '/media/media/images/mime-icon-32/rar.png', + '/media/media/images/mime-icon-32/rtf.png', + '/media/media/images/mime-icon-32/svg.png', + '/media/media/images/mime-icon-32/sxd.png', + '/media/media/images/mime-icon-32/tar.png', + '/media/media/images/mime-icon-32/tgz.png', + '/media/media/images/mime-icon-32/wma.png', + '/media/media/images/mime-icon-32/wmv.png', + '/media/media/images/mime-icon-32/xls.png', + '/media/media/images/mime-icon-32/zip.png', + '/media/media/images/progress.gif', + '/media/media/images/remove.png', + '/media/media/images/success.png', + '/media/media/images/upload.png', + '/media/media/images/uploading.png', + '/media/media/js/flashmediaelement-cdn.swf', + '/media/media/js/flashmediaelement.swf', + '/media/media/js/mediaelement-and-player.js', + '/media/media/js/mediaelement-and-player.min.js', + '/media/media/js/mediafield-mootools.js', + '/media/media/js/mediafield-mootools.min.js', + '/media/media/js/mediafield.js', + '/media/media/js/mediafield.min.js', + '/media/media/js/mediamanager.js', + '/media/media/js/mediamanager.min.js', + '/media/media/js/popup-imagemanager.js', + '/media/media/js/popup-imagemanager.min.js', + '/media/media/js/silverlightmediaelement.xap', + '/media/overrider/css/overrider.css', + '/media/overrider/js/overrider.js', + '/media/overrider/js/overrider.min.js', + '/media/system/css/jquery.Jcrop.min.css', + '/media/system/css/modal.css', + '/media/system/images/modal/bg_e.png', + '/media/system/images/modal/bg_n.png', + '/media/system/images/modal/bg_ne.png', + '/media/system/images/modal/bg_nw.png', + '/media/system/images/modal/bg_s.png', + '/media/system/images/modal/bg_se.png', + '/media/system/images/modal/bg_sw.png', + '/media/system/images/modal/bg_w.png', + '/media/system/images/modal/closebox.png', + '/media/system/images/modal/spinner.gif', + '/media/system/js/associations-edit-uncompressed.js', + '/media/system/js/associations-edit.js', + '/media/system/js/associations-edit.min.js', + '/media/system/js/calendar-setup-uncompressed.js', + '/media/system/js/calendar-setup.js', + '/media/system/js/calendar-uncompressed.js', + '/media/system/js/calendar.js', + '/media/system/js/caption-uncompressed.js', + '/media/system/js/caption.js', + '/media/system/js/color-field-adv-init.js', + '/media/system/js/color-field-adv-init.min.js', + '/media/system/js/color-field-init.js', + '/media/system/js/color-field-init.min.js', + '/media/system/js/combobox-uncompressed.js', + '/media/system/js/combobox.js', + '/media/system/js/core-uncompressed.js', + '/media/system/js/frontediting-uncompressed.js', + '/media/system/js/highlighter-uncompressed.js', + '/media/system/js/html5fallback-uncompressed.js', + '/media/system/js/html5fallback.js', + '/media/system/js/jquery.Jcrop.js', + '/media/system/js/jquery.Jcrop.min.js', + '/media/system/js/keepalive-uncompressed.js', + '/media/system/js/modal-fields-uncompressed.js', + '/media/system/js/modal-fields.js', + '/media/system/js/modal-uncompressed.js', + '/media/system/js/modal.js', + '/media/system/js/moduleorder.js', + '/media/system/js/mootools-core-uncompressed.js', + '/media/system/js/mootools-core.js', + '/media/system/js/mootools-more-uncompressed.js', + '/media/system/js/mootools-more.js', + '/media/system/js/mootree-uncompressed.js', + '/media/system/js/mootree.js', + '/media/system/js/multiselect-uncompressed.js', + '/media/system/js/passwordstrength.js', + '/media/system/js/permissions-uncompressed.js', + '/media/system/js/permissions.js', + '/media/system/js/polyfill.classlist-uncompressed.js', + '/media/system/js/polyfill.classlist.js', + '/media/system/js/polyfill.event-uncompressed.js', + '/media/system/js/polyfill.event.js', + '/media/system/js/polyfill.filter-uncompressed.js', + '/media/system/js/polyfill.filter.js', + '/media/system/js/polyfill.map-uncompressed.js', + '/media/system/js/polyfill.map.js', + '/media/system/js/polyfill.xpath-uncompressed.js', + '/media/system/js/polyfill.xpath.js', + '/media/system/js/progressbar-uncompressed.js', + '/media/system/js/progressbar.js', + '/media/system/js/punycode-uncompressed.js', + '/media/system/js/punycode.js', + '/media/system/js/repeatable-uncompressed.js', + '/media/system/js/repeatable.js', + '/media/system/js/sendtestmail-uncompressed.js', + '/media/system/js/sendtestmail.js', + '/media/system/js/subform-repeatable-uncompressed.js', + '/media/system/js/subform-repeatable.js', + '/media/system/js/switcher-uncompressed.js', + '/media/system/js/switcher.js', + '/media/system/js/tabs-state-uncompressed.js', + '/media/system/js/tabs.js', + '/media/system/js/validate-uncompressed.js', + '/media/system/js/validate.js', + '/modules/mod_articles_archive/helper.php', + '/modules/mod_articles_categories/helper.php', + '/modules/mod_articles_category/helper.php', + '/modules/mod_articles_latest/helper.php', + '/modules/mod_articles_news/helper.php', + '/modules/mod_articles_popular/helper.php', + '/modules/mod_banners/helper.php', + '/modules/mod_breadcrumbs/helper.php', + '/modules/mod_feed/helper.php', + '/modules/mod_finder/helper.php', + '/modules/mod_languages/helper.php', + '/modules/mod_login/helper.php', + '/modules/mod_menu/helper.php', + '/modules/mod_random_image/helper.php', + '/modules/mod_related_items/helper.php', + '/modules/mod_search/helper.php', + '/modules/mod_stats/helper.php', + '/modules/mod_syndicate/helper.php', + '/modules/mod_tags_popular/helper.php', + '/modules/mod_tags_similar/helper.php', + '/modules/mod_users_latest/helper.php', + '/modules/mod_whosonline/helper.php', + '/modules/mod_wrapper/helper.php', + '/plugins/captcha/recaptcha/recaptchalib.php', + '/plugins/system/p3p/p3p.php', + '/plugins/system/p3p/p3p.xml', + '/templates/beez3/component.php', + '/templates/beez3/css/general.css', + '/templates/beez3/css/ie7only.css', + '/templates/beez3/css/ieonly.css', + '/templates/beez3/css/layout.css', + '/templates/beez3/css/nature.css', + '/templates/beez3/css/nature_rtl.css', + '/templates/beez3/css/personal.css', + '/templates/beez3/css/personal_rtl.css', + '/templates/beez3/css/position.css', + '/templates/beez3/css/print.css', + '/templates/beez3/css/red.css', + '/templates/beez3/css/template.css', + '/templates/beez3/css/template_rtl.css', + '/templates/beez3/css/turq.css', + '/templates/beez3/css/turq.less', + '/templates/beez3/error.php', + '/templates/beez3/favicon.ico', + '/templates/beez3/html/com_contact/categories/default.php', + '/templates/beez3/html/com_contact/categories/default_items.php', + '/templates/beez3/html/com_contact/category/default.php', + '/templates/beez3/html/com_contact/category/default_children.php', + '/templates/beez3/html/com_contact/category/default_items.php', + '/templates/beez3/html/com_contact/contact/default.php', + '/templates/beez3/html/com_contact/contact/default_address.php', + '/templates/beez3/html/com_contact/contact/default_articles.php', + '/templates/beez3/html/com_contact/contact/default_form.php', + '/templates/beez3/html/com_contact/contact/default_links.php', + '/templates/beez3/html/com_contact/contact/default_profile.php', + '/templates/beez3/html/com_contact/contact/default_user_custom_fields.php', + '/templates/beez3/html/com_contact/contact/encyclopedia.php', + '/templates/beez3/html/com_content/archive/default.php', + '/templates/beez3/html/com_content/archive/default_items.php', + '/templates/beez3/html/com_content/article/default.php', + '/templates/beez3/html/com_content/article/default_links.php', + '/templates/beez3/html/com_content/categories/default.php', + '/templates/beez3/html/com_content/categories/default_items.php', + '/templates/beez3/html/com_content/category/blog.php', + '/templates/beez3/html/com_content/category/blog_children.php', + '/templates/beez3/html/com_content/category/blog_item.php', + '/templates/beez3/html/com_content/category/blog_links.php', + '/templates/beez3/html/com_content/category/default.php', + '/templates/beez3/html/com_content/category/default_articles.php', + '/templates/beez3/html/com_content/category/default_children.php', + '/templates/beez3/html/com_content/featured/default.php', + '/templates/beez3/html/com_content/featured/default_item.php', + '/templates/beez3/html/com_content/featured/default_links.php', + '/templates/beez3/html/com_content/form/edit.php', + '/templates/beez3/html/com_newsfeeds/categories/default.php', + '/templates/beez3/html/com_newsfeeds/categories/default_items.php', + '/templates/beez3/html/com_newsfeeds/category/default.php', + '/templates/beez3/html/com_newsfeeds/category/default_children.php', + '/templates/beez3/html/com_newsfeeds/category/default_items.php', + '/templates/beez3/html/com_weblinks/categories/default.php', + '/templates/beez3/html/com_weblinks/categories/default_items.php', + '/templates/beez3/html/com_weblinks/category/default.php', + '/templates/beez3/html/com_weblinks/category/default_children.php', + '/templates/beez3/html/com_weblinks/category/default_items.php', + '/templates/beez3/html/com_weblinks/form/edit.php', + '/templates/beez3/html/layouts/joomla/system/message.php', + '/templates/beez3/html/mod_breadcrumbs/default.php', + '/templates/beez3/html/mod_languages/default.php', + '/templates/beez3/html/mod_login/default.php', + '/templates/beez3/html/mod_login/default_logout.php', + '/templates/beez3/html/modules.php', + '/templates/beez3/images/all_bg.gif', + '/templates/beez3/images/arrow.png', + '/templates/beez3/images/arrow2_grey.png', + '/templates/beez3/images/arrow_white_grey.png', + '/templates/beez3/images/blog_more.gif', + '/templates/beez3/images/blog_more_hover.gif', + '/templates/beez3/images/close.png', + '/templates/beez3/images/content_bg.gif', + '/templates/beez3/images/footer_bg.gif', + '/templates/beez3/images/footer_bg.png', + '/templates/beez3/images/header-bg.gif', + '/templates/beez3/images/minus.png', + '/templates/beez3/images/nature/arrow1.gif', + '/templates/beez3/images/nature/arrow1_rtl.gif', + '/templates/beez3/images/nature/arrow2.gif', + '/templates/beez3/images/nature/arrow2_grey.png', + '/templates/beez3/images/nature/arrow2_rtl.gif', + '/templates/beez3/images/nature/arrow_nav.gif', + '/templates/beez3/images/nature/arrow_small.png', + '/templates/beez3/images/nature/arrow_small_rtl.png', + '/templates/beez3/images/nature/blog_more.gif', + '/templates/beez3/images/nature/box.png', + '/templates/beez3/images/nature/box1.png', + '/templates/beez3/images/nature/grey_bg.png', + '/templates/beez3/images/nature/headingback.png', + '/templates/beez3/images/nature/karo.gif', + '/templates/beez3/images/nature/level4.png', + '/templates/beez3/images/nature/nav_level1_a.gif', + '/templates/beez3/images/nature/nav_level_1.gif', + '/templates/beez3/images/nature/pfeil.gif', + '/templates/beez3/images/nature/readmore_arrow.png', + '/templates/beez3/images/nature/searchbutton.png', + '/templates/beez3/images/nature/tabs.gif', + '/templates/beez3/images/nav_level_1.gif', + '/templates/beez3/images/news.gif', + '/templates/beez3/images/personal/arrow2_grey.jpg', + '/templates/beez3/images/personal/arrow2_grey.png', + '/templates/beez3/images/personal/bg2.png', + '/templates/beez3/images/personal/button.png', + '/templates/beez3/images/personal/dot.png', + '/templates/beez3/images/personal/ecke.gif', + '/templates/beez3/images/personal/footer.jpg', + '/templates/beez3/images/personal/grey_bg.png', + '/templates/beez3/images/personal/navi_active.png', + '/templates/beez3/images/personal/personal2.png', + '/templates/beez3/images/personal/readmore_arrow.png', + '/templates/beez3/images/personal/readmore_arrow_hover.png', + '/templates/beez3/images/personal/tabs_back.png', + '/templates/beez3/images/plus.png', + '/templates/beez3/images/req.png', + '/templates/beez3/images/slider_minus.png', + '/templates/beez3/images/slider_minus_rtl.png', + '/templates/beez3/images/slider_plus.png', + '/templates/beez3/images/slider_plus_rtl.png', + '/templates/beez3/images/system/arrow.png', + '/templates/beez3/images/system/arrow_rtl.png', + '/templates/beez3/images/system/calendar.png', + '/templates/beez3/images/system/j_button2_blank.png', + '/templates/beez3/images/system/j_button2_image.png', + '/templates/beez3/images/system/j_button2_left.png', + '/templates/beez3/images/system/j_button2_pagebreak.png', + '/templates/beez3/images/system/j_button2_readmore.png', + '/templates/beez3/images/system/notice-alert.png', + '/templates/beez3/images/system/notice-alert_rtl.png', + '/templates/beez3/images/system/notice-info.png', + '/templates/beez3/images/system/notice-info_rtl.png', + '/templates/beez3/images/system/notice-note.png', + '/templates/beez3/images/system/notice-note_rtl.png', + '/templates/beez3/images/system/selector-arrow.png', + '/templates/beez3/images/table_footer.gif', + '/templates/beez3/images/trans.gif', + '/templates/beez3/index.php', + '/templates/beez3/javascript/hide.js', + '/templates/beez3/javascript/md_stylechanger.js', + '/templates/beez3/javascript/respond.js', + '/templates/beez3/javascript/respond.src.js', + '/templates/beez3/javascript/template.js', + '/templates/beez3/jsstrings.php', + '/templates/beez3/language/en-GB/en-GB.tpl_beez3.ini', + '/templates/beez3/language/en-GB/en-GB.tpl_beez3.sys.ini', + '/templates/beez3/templateDetails.xml', + '/templates/beez3/template_preview.png', + '/templates/beez3/template_thumbnail.png', + '/templates/protostar/component.php', + '/templates/protostar/css/offline.css', + '/templates/protostar/css/template.css', + '/templates/protostar/error.php', + '/templates/protostar/favicon.ico', + '/templates/protostar/html/com_media/imageslist/default_folder.php', + '/templates/protostar/html/com_media/imageslist/default_image.php', + '/templates/protostar/html/layouts/joomla/form/field/contenthistory.php', + '/templates/protostar/html/layouts/joomla/form/field/media.php', + '/templates/protostar/html/layouts/joomla/form/field/user.php', + '/templates/protostar/html/layouts/joomla/system/message.php', + '/templates/protostar/html/modules.php', + '/templates/protostar/html/pagination.php', + '/templates/protostar/images/logo.png', + '/templates/protostar/images/system/rating_star.png', + '/templates/protostar/images/system/rating_star_blank.png', + '/templates/protostar/images/system/sort_asc.png', + '/templates/protostar/images/system/sort_desc.png', + '/templates/protostar/img/glyphicons-halflings-white.png', + '/templates/protostar/img/glyphicons-halflings.png', + '/templates/protostar/index.php', + '/templates/protostar/js/application.js', + '/templates/protostar/js/classes.js', + '/templates/protostar/js/template.js', + '/templates/protostar/language/en-GB/en-GB.tpl_protostar.ini', + '/templates/protostar/language/en-GB/en-GB.tpl_protostar.sys.ini', + '/templates/protostar/less/icomoon.less', + '/templates/protostar/less/template.less', + '/templates/protostar/less/template_rtl.less', + '/templates/protostar/less/variables.less', + '/templates/protostar/offline.php', + '/templates/protostar/templateDetails.xml', + '/templates/protostar/template_preview.png', + '/templates/protostar/template_thumbnail.png', + '/templates/system/css/system.css', + '/templates/system/css/toolbar.css', + '/templates/system/images/calendar.png', + '/templates/system/images/j_button2_blank.png', + '/templates/system/images/j_button2_image.png', + '/templates/system/images/j_button2_left.png', + '/templates/system/images/j_button2_pagebreak.png', + '/templates/system/images/j_button2_readmore.png', + '/templates/system/images/j_button2_right.png', + '/templates/system/images/selector-arrow.png', ); // TODO There is an issue while deleting folders using the ftp mode $folders = array( - '/administrator/components/com_admin/sql/updates/sqlsrv', - '/media/com_finder/images/mime', - '/media/com_finder/images', - '/components/com_media/helpers', - // Joomla 3.0 - '/administrator/components/com_contact/elements', - '/administrator/components/com_content/elements', - '/administrator/components/com_newsfeeds/elements', - '/administrator/components/com_templates/views/prevuuw/tmpl', - '/administrator/components/com_templates/views/prevuuw', - '/libraries/cms/controller', - '/libraries/cms/model', - '/libraries/cms/view', - '/libraries/joomla/application/cli', - '/libraries/joomla/application/component', - '/libraries/joomla/application/input', - '/libraries/joomla/application/module', - '/libraries/joomla/cache/storage/helpers', - '/libraries/joomla/database/table', - '/libraries/joomla/database/database', - '/libraries/joomla/error', - '/libraries/joomla/filesystem/archive', - '/libraries/joomla/html/html', - '/libraries/joomla/html/toolbar', - '/libraries/joomla/html/toolbar/button', - '/libraries/joomla/html/parameter', - '/libraries/joomla/html/parameter/element', - '/libraries/joomla/image/filters', - '/libraries/joomla/log/loggers', - // Joomla! 3.1 - '/libraries/joomla/form/rules', - '/libraries/joomla/html/language/en-GB', - '/libraries/joomla/html/language', - '/libraries/joomla/html', - '/libraries/joomla/installer/adapters', - '/libraries/joomla/installer', - '/libraries/joomla/pagination', - '/libraries/legacy/html', - '/libraries/legacy/menu', - '/libraries/legacy/pathway', - '/media/system/swf/', - '/media/editors/tinymce/jscripts', - // Joomla! 3.2 - '/libraries/joomla/plugin', - '/libraries/legacy/component', - '/libraries/legacy/module', - '/administrator/components/com_weblinks/models/fields', - '/plugins/user/joomla/postinstall', - '/libraries/joomla/registry/format', - '/libraries/joomla/registry', - // Joomla! 3.3 - '/plugins/user/profile/fields', - '/media/editors/tinymce/plugins/compat3x', - // Joomla! 3.4 - '/administrator/components/com_tags/helpers/html', - '/administrator/components/com_tags/models/fields', - '/administrator/templates/hathor/html/com_finder/filter', - '/administrator/templates/hathor/html/com_finder/statistics', - '/libraries/compat/password/lib', - '/libraries/compat/password', - '/libraries/compat', - '/libraries/framework/Joomla/Application/Cli/Output/Processor', - '/libraries/framework/Joomla/Application/Cli/Output', - '/libraries/framework/Joomla/Application/Cli', - '/libraries/framework/Joomla/Application', - '/libraries/framework/Joomla/DI/Exception', - '/libraries/framework/Joomla/DI', - '/libraries/framework/Joomla/Registry/Format', - '/libraries/framework/Joomla/Registry', - '/libraries/framework/Joomla', - '/libraries/framework/Symfony/Component/Yaml/Exception', - '/libraries/framework/Symfony/Component/Yaml', - '/libraries/framework', - '/libraries/phpmailer/language', - '/libraries/phpmailer', - '/media/editors/codemirror/css', - '/media/editors/codemirror/js', - '/media/com_banners', - // Joomla! 3.4.1 - '/administrator/components/com_config/views', - '/administrator/components/com_config/models/fields', - '/administrator/components/com_config/models/forms', - // Joomla! 3.4.2 - '/media/editors/codemirror/mode/smartymixed', - // Joomla! 3.5 - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml/Exception', - '/libraries/vendor/symfony/yaml/Symfony/Component/Yaml', - '/libraries/vendor/symfony/yaml/Symfony/Component', - '/libraries/vendor/symfony/yaml/Symfony', - '/libraries/joomla/document/error', - '/libraries/joomla/document/image', - '/libraries/joomla/document/json', - '/libraries/joomla/document/opensearch', - '/libraries/joomla/document/raw', - '/libraries/joomla/document/xml', - '/administrator/components/com_media/models/forms', - '/media/editors/codemirror/mode/kotlin', - '/media/editors/tinymce/plugins/compat3x', - '/plugins/editors/tinymce/fields', - '/plugins/user/profile/fields', - // Joomla 3.6 - '/libraries/simplepie/idn', - '/libraries/simplepie', - // Joomla! 3.6.3 - '/media/editors/codemirror/mode/jade', - // Joomla! 3.7.0 - '/libraries/joomla/data', - '/administrator/components/com_cache/layouts/joomla/searchtools/default', - '/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', - '/administrator/components/com_templates/layouts/joomla/searchtools/default', - '/administrator/components/com_templates/layouts/joomla/searchtools', - '/administrator/components/com_templates/layouts/joomla', - '/administrator/components/com_templates/layouts', - '/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! 4.0 + '/templates/beez3', + '/administrator/templates/isis', + '/administrator/templates/hathor', + '/media/jui/less', ); - jimport('joomla.filesystem.file'); - foreach ($files as $file) { - if (JFile::exists(JPATH_ROOT . $file) && !JFile::delete(JPATH_ROOT . $file)) + if (File::exists(JPATH_ROOT . $file) && !File::delete(JPATH_ROOT . $file)) { - echo JText::sprintf('FILES_JOOMLA_ERROR_FILE_FOLDER', $file) . '
'; + echo Text::sprintf('FILES_JOOMLA_ERROR_FILE_FOLDER', $file) . '
'; } } - jimport('joomla.filesystem.folder'); - foreach ($folders as $folder) { - if (JFolder::exists(JPATH_ROOT . $folder) && !JFolder::delete(JPATH_ROOT . $folder)) + if (Folder::exists(JPATH_ROOT . $folder) && !Folder::delete(JPATH_ROOT . $folder)) { - echo JText::sprintf('FILES_JOOMLA_ERROR_FILE_FOLDER', $folder) . '
'; + echo Text::sprintf('FILES_JOOMLA_ERROR_FILE_FOLDER', $folder) . '
'; } } - - /* - * Needed for updates post-3.4 - * If com_weblinks doesn't exist then assume we can delete the weblinks package manifest (included in the update packages) - */ - if (!JFile::exists(JPATH_ROOT . '/administrator/components/com_weblinks/weblinks.php') - && JFile::exists(JPATH_ROOT . '/administrator/manifests/packages/pkg_weblinks.xml')) - { - JFile::delete(JPATH_ROOT . '/administrator/manifests/packages/pkg_weblinks.xml'); - } - } - - /** - * Clears the RAD layer's table cache. - * - * The cache vastly improves performance but needs to be cleared every time you update the database schema. - * - * @return void - * - * @since 3.2 - */ - protected function clearRadCache() - { - jimport('joomla.filesystem.file'); - - if (JFile::exists(JPATH_ROOT . '/cache/fof/cache.php')) - { - JFile::delete(JPATH_ROOT . '/cache/fof/cache.php'); - } } /** * Method to create assets for newly installed components * - * @param JInstaller $installer The class calling this method + * @param Installer $installer The class calling this method * * @return boolean * @@ -2244,16 +3975,9 @@ protected function clearRadCache() */ public function updateAssets($installer) { - // List all components added since 1.6 + // List all components added since 4.0 $newComponents = array( - 'com_finder', - 'com_joomlaupdate', - 'com_tags', - 'com_contenthistory', - 'com_ajax', - 'com_postinstall', - 'com_fields', - 'com_associations', + 'com_csp', ); foreach ($newComponents as $component) @@ -2275,7 +3999,7 @@ public function updateAssets($installer) if (!$asset->store()) { // Install failed, roll back changes - $installer->abort(JText::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK', $asset->stderr(true))); + $installer->abort(Text::sprintf('JLIB_INSTALLER_ABORT_COMP_INSTALL_ROLLBACK', $asset->getError(true))); return false; } @@ -2297,7 +4021,7 @@ public function flushSessions() * The session may have not been started yet (e.g. CLI-based Joomla! update scripts). Let's make sure we do * have a valid session. */ - $session = JFactory::getSession(); + $session = Factory::getSession(); /** * Restarting the Session require a new login for the current user so lets check if we have an active session @@ -2315,7 +4039,7 @@ public function flushSessions() return true; } - $db = JFactory::getDbo(); + $db = Factory::getDbo(); try { @@ -2329,14 +4053,14 @@ public function flushSessions() // Non-MySQL databases, use a simple DELETE FROM query default: $query = $db->getQuery(true) - ->delete($db->qn('#__session')); + ->delete($db->quoteName('#__session')); $db->setQuery($query)->execute(); break; } } catch (Exception $e) { - echo JText::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; + echo Text::sprintf('JLIB_DATABASE_ERROR_FUNCTION_FAILED', $e->getCode(), $e->getMessage()) . '
'; return false; } @@ -2355,12 +4079,9 @@ public function flushSessions() */ public function convertTablesToUtf8mb4($doDbFixMsg = false) { - $db = JFactory::getDbo(); - - // This is only required for MySQL databases - $serverType = $db->getServerType(); + $db = Factory::getDbo(); - if ($serverType != 'mysql') + if (!($db instanceof UTF8MB4SupportInterface)) { return; } @@ -2387,12 +4108,12 @@ public function convertTablesToUtf8mb4($doDbFixMsg = false) catch (Exception $e) { // Render the error message from the Exception object - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); if ($doDbFixMsg) { // Show an error message telling to check database problems - JFactory::getApplication()->enqueueMessage(JText::_('JLIB_DATABASE_ERROR_DATABASE_UPGRADE_FAILED'), 'error'); + Factory::getApplication()->enqueueMessage(Text::_('JLIB_DATABASE_ERROR_DATABASE_UPGRADE_FAILED'), 'error'); } return; @@ -2449,7 +4170,7 @@ public function convertTablesToUtf8mb4($doDbFixMsg = false) $converted = 0; // Still render the error message from the Exception object - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); } } } @@ -2458,7 +4179,7 @@ public function convertTablesToUtf8mb4($doDbFixMsg = false) if ($doDbFixMsg && $converted == 0) { // Show an error message telling to check database problems - JFactory::getApplication()->enqueueMessage(JText::_('JLIB_DATABASE_ERROR_DATABASE_UPGRADE_FAILED'), 'error'); + Factory::getApplication()->enqueueMessage(Text::_('JLIB_DATABASE_ERROR_DATABASE_UPGRADE_FAILED'), 'error'); } // Set flag in database if the update is done. @@ -2475,8 +4196,7 @@ public function convertTablesToUtf8mb4($doDbFixMsg = false) */ private function cleanJoomlaCache() { - JModelLegacy::addIncludePath(JPATH_ROOT . '/administrator/components/com_cache/models'); - $model = JModelLegacy::getInstance('cache', 'CacheModel'); + $model = new \Joomla\Component\Cache\Administrator\Model\CacheModel; // Clean frontend cache $model->clean(); diff --git a/administrator/components/com_admin/services/provider.php b/administrator/components/com_admin/services/provider.php new file mode 100644 index 0000000000000..e0ce521d93765 --- /dev/null +++ b/administrator/components/com_admin/services/provider.php @@ -0,0 +1,56 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Admin')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Admin')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new AdminComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + $component->setRegistry($container->get(Registry::class)); + + return $component; + } + ); + } +}; 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 deleted file mode 100644 index f0998e83a2273..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-06.sql +++ /dev/null @@ -1,9 +0,0 @@ -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 -(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`; - -REPLACE INTO `#__update_sites` VALUES -(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 deleted file mode 100644 index 77ed80d3fc383..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-16.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE IF NOT EXISTS `#__overrider` ( - `id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'Primary Key', - `constant` varchar(255) NOT NULL, - `string` text NOT NULL, - `file` varchar(255) NOT NULL, - PRIMARY KEY (`id`) -) DEFAULT CHARSET=utf8; \ No newline at end of file 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 deleted file mode 100644 index 94e9c9ae44543..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-19.sql +++ /dev/null @@ -1,20 +0,0 @@ -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', - `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', - `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `created_user_id` int(10) 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_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', - `publish_down` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', - PRIMARY KEY (`id`), - KEY `idx_user_id` (`user_id`), - KEY `idx_category_id` (`catid`) -) DEFAULT CHARSET=utf8; diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-20.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-20.sql deleted file mode 100644 index 1de207eec8396..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-20.sql +++ /dev/null @@ -1,7 +0,0 @@ -SELECT @old_params:= CONCAT(SUBSTRING_INDEX(SUBSTRING(params, LOCATE('"filters":', params)), '}}', 1), '}}') as filters -FROM `#__extensions` -WHERE name="com_content"; - -UPDATE `#__extensions` -SET params=CONCAT('{',SUBSTRING(params, 2, CHAR_LENGTH(params)-2),IF(params='','',','),@old_params,'}') -WHERE name="com_config"; \ No newline at end of file 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 deleted file mode 100644 index 1529436042092..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-1.sql +++ /dev/null @@ -1,11 +0,0 @@ -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 -(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 - 2018 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), -(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), -(445, 'plg_finder_newsfeeds', 'plugin', 'newsfeeds', 'finder', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 4, 0), -(446, 'plg_finder_weblinks', 'plugin', 'weblinks', 'finder', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 5, 0), -(223, 'mod_finder', 'module', 'mod_finder', '', 0, 1, 0, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 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 deleted file mode 100644 index dd1a0d44f16c3..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-21-2.sql +++ /dev/null @@ -1,244 +0,0 @@ -CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) 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, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) 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, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) 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, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms4` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms5` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms6` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms7` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms8` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms9` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsa` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsb` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsc` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsd` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_termse` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsf` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_taxonomy` ( - `id` int(10) unsigned NOT NULL auto_increment, - `parent_id` int(10) 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', - PRIMARY KEY (`id`), - KEY `parent_id` (`parent_id`), - KEY `state` (`state`), - KEY `ordering` (`ordering`), - KEY `access` (`access`), - KEY `idx_parent_published` (`parent_id`,`state`,`access`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_taxonomy_map` ( - `link_id` int(10) unsigned NOT NULL, - `node_id` int(10) unsigned NOT NULL, - PRIMARY KEY (`link_id`,`node_id`), - KEY `link_id` (`link_id`), - KEY `node_id` (`node_id`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_terms` ( - `term_id` int(10) 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', - `weight` float unsigned NOT NULL default '0', - `soundex` varchar(75) NOT NULL, - `links` int(10) NOT NULL default '0', - PRIMARY KEY (`term_id`), - UNIQUE KEY `idx_term` (`term`), - KEY `idx_term_phrase` (`term`,`phrase`), - KEY `idx_stem_phrase` (`stem`,`phrase`), - KEY `idx_soundex_phrase` (`soundex`,`phrase`) -) DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_terms_common` ( - `term` varchar(75) NOT NULL, - `language` varchar(3) NOT NULL, - KEY `idx_word_lang` (`term`,`language`), - KEY `idx_lang` (`language`) -) DEFAULT CHARSET=utf8; - - -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', - `weight` float unsigned NOT NULL default '1', - `context` tinyint(1) 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, - `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', - `term_weight` float unsigned NOT NULL, - `context` tinyint(1) unsigned NOT NULL default '2', - `context_weight` float unsigned NOT NULL, - `total_weight` float unsigned NOT NULL, - KEY `token` (`term`), - KEY `keyword_id` (`term_id`) -) ENGINE=MEMORY DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__finder_types` ( - `id` int(10) unsigned NOT NULL auto_increment, - `title` varchar(100) NOT NULL, - `mime` varchar(100) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `title` (`title`) -) DEFAULT CHARSET=utf8; - - diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-22.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-22.sql deleted file mode 100644 index 2f0ffd56cd6f1..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-22.sql +++ /dev/null @@ -1,123 +0,0 @@ -REPLACE INTO `#__finder_taxonomy` (`id`, `parent_id`, `title`, `state`, `access`, `ordering`) VALUES -(1, 0, 'ROOT', 0, 0, 0); - -REPLACE INTO `#__finder_terms_common` (`term`, `language`) VALUES -('a', 'en'), -('about', 'en'), -('after', 'en'), -('ago', 'en'), -('all', 'en'), -('am', 'en'), -('an', 'en'), -('and', 'en'), -('ani', 'en'), -('any', 'en'), -('are', 'en'), -('aren''t', 'en'), -('as', 'en'), -('at', 'en'), -('be', 'en'), -('but', 'en'), -('by', 'en'), -('for', 'en'), -('from', 'en'), -('get', 'en'), -('go', 'en'), -('how', 'en'), -('if', 'en'), -('in', 'en'), -('into', 'en'), -('is', 'en'), -('isn''t', 'en'), -('it', 'en'), -('its', 'en'), -('me', 'en'), -('more', 'en'), -('most', 'en'), -('must', 'en'), -('my', 'en'), -('new', 'en'), -('no', 'en'), -('none', 'en'), -('not', 'en'), -('noth', 'en'), -('nothing', 'en'), -('of', 'en'), -('off', 'en'), -('often', 'en'), -('old', 'en'), -('on', 'en'), -('onc', 'en'), -('once', 'en'), -('onli', 'en'), -('only', 'en'), -('or', 'en'), -('other', 'en'), -('our', 'en'), -('ours', 'en'), -('out', 'en'), -('over', 'en'), -('page', 'en'), -('she', 'en'), -('should', 'en'), -('small', 'en'), -('so', 'en'), -('some', 'en'), -('than', 'en'), -('thank', 'en'), -('that', 'en'), -('the', 'en'), -('their', 'en'), -('theirs', 'en'), -('them', 'en'), -('then', 'en'), -('there', 'en'), -('these', 'en'), -('they', 'en'), -('this', 'en'), -('those', 'en'), -('thus', 'en'), -('time', 'en'), -('times', 'en'), -('to', 'en'), -('too', 'en'), -('true', 'en'), -('under', 'en'), -('until', 'en'), -('up', 'en'), -('upon', 'en'), -('use', 'en'), -('user', 'en'), -('users', 'en'), -('veri', 'en'), -('version', 'en'), -('very', 'en'), -('via', 'en'), -('want', 'en'), -('was', 'en'), -('way', 'en'), -('were', 'en'), -('what', 'en'), -('when', 'en'), -('where', 'en'), -('whi', 'en'), -('which', 'en'), -('who', 'en'), -('whom', 'en'), -('whose', 'en'), -('why', 'en'), -('wide', 'en'), -('will', 'en'), -('with', 'en'), -('within', 'en'), -('without', 'en'), -('would', 'en'), -('yes', 'en'), -('yet', 'en'), -('you', 'en'), -('your', 'en'), -('yours', 'en'); - - -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_finder', 'Smart Search', '', 'Smart Search', 'index.php?option=com_finder', 'component', 0, 1, 1, 27, 0, 0, '0000-00-00 00:00:00', 0, 0, 'class:finder', 0, '', 41, 42, 0, '*', 1); 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 deleted file mode 100644 index 5dae6e534ee56..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-23.sql +++ /dev/null @@ -1,47 +0,0 @@ -CREATE TABLE IF NOT EXISTS `#__finder_filters` ( - `filter_id` int(10) unsigned NOT NULL auto_increment, - `title` varchar(255) NOT NULL, - `alias` varchar(255) NOT NULL, - `state` tinyint(1) NOT NULL default '1', - `created` datetime NOT NULL default '0000-00-00 00:00:00', - `created_by` int(10) 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', - `checked_out_time` datetime NOT NULL default '0000-00-00 00:00:00', - `map_count` int(10) 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, - `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', - `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', - `start_date` datetime NOT NULL default '0000-00-00 00:00:00', - `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, - `object` mediumblob NOT NULL, - PRIMARY KEY (`link_id`), - KEY `idx_type` (`type_id`), - KEY `idx_title` (`title`), - KEY `idx_md5` (`md5sum`), - KEY `idx_url` (`url`(75)), - KEY `idx_published_list` (`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`list_price`), - KEY `idx_published_sale` (`published`,`state`,`access`,`publish_start_date`,`publish_end_date`,`sale_price`) -) DEFAULT CHARSET=utf8; - diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-24.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-24.sql deleted file mode 100644 index bbaaff3f6193c..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2011-12-24.sql +++ /dev/null @@ -1,8 +0,0 @@ -ALTER TABLE `#__menu` DROP INDEX `idx_client_id_parent_id_alias`; - --- --- The following statment had to be modified for utf8mb4 in Joomla! 3.5.1, changing --- `alias` to `alias`(100) --- - -ALTER TABLE `#__menu` ADD UNIQUE `idx_client_id_parent_id_alias_language` ( `client_id` , `parent_id` , `alias`(100) , `language` ); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2012-01-10.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2012-01-10.sql deleted file mode 100644 index c91221452a724..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2012-01-10.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `#__updates` ADD COLUMN `infourl` text NOT NULL AFTER `detailsurl`; diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2012-01-14.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.0-2012-01-14.sql deleted file mode 100644 index 4817357cd0e3a..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.0-2012-01-14.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `#__languages` CHANGE `sitename` `sitename` VARCHAR( 1024 ) NOT NULL DEFAULT ''; - 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 deleted file mode 100644 index c6fb1d0b8cc5d..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.1-2012-01-26.sql +++ /dev/null @@ -1,8 +0,0 @@ -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 - 2018 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); - -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 diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.2-2012-03-05.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.2-2012-03-05.sql deleted file mode 100644 index 1c06a396e19e2..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.2-2012-03-05.sql +++ /dev/null @@ -1 +0,0 @@ -# Dummy SQL file to set schema version \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.3-2012-03-13.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.3-2012-03-13.sql deleted file mode 100644 index 1c06a396e19e2..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.3-2012-03-13.sql +++ /dev/null @@ -1 +0,0 @@ -# Dummy SQL file to set schema version \ No newline at end of file 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 deleted file mode 100644 index d24ec9d278f17..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.4-2012-03-18.sql +++ /dev/null @@ -1,5 +0,0 @@ -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 - 2018 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); - -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.4-2012-03-19.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.4-2012-03-19.sql deleted file mode 100644 index 1f43a493b7030..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.4-2012-03-19.sql +++ /dev/null @@ -1,7 +0,0 @@ -ALTER TABLE `#__languages` ADD COLUMN `access` integer unsigned NOT NULL default 0 AFTER `published`; - -ALTER TABLE `#__languages` ADD INDEX `idx_access` (`access`); - -UPDATE `#__categories` SET `extension` = 'com_users.notes' WHERE `extension` = 'com_users'; - -UPDATE `#__extensions` SET `enabled` = '1' WHERE `protected` = '1' AND `type` <> 'plugin'; 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 deleted file mode 100644 index c73b70888bb22..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.5.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE `#__redirect_links` ADD COLUMN `hits` INT(10) 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 diff --git a/administrator/components/com_admin/sql/updates/mysql/2.5.6.sql b/administrator/components/com_admin/sql/updates/mysql/2.5.6.sql deleted file mode 100644 index ff1afae20a6df..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.6.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 2.5.6 \ 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 deleted file mode 100644 index edb2486371704..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/2.5.7.sql +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 7043e21224775..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.0.0.sql +++ /dev/null @@ -1,147 +0,0 @@ -ALTER TABLE `#__users` DROP INDEX `usertype`; -ALTER TABLE `#__session` DROP INDEX `whosonline`; - -DROP TABLE IF EXISTS `#__update_categories`; - -ALTER TABLE `#__contact_details` DROP `imagepos`; -ALTER TABLE `#__content` DROP COLUMN `title_alias`; -ALTER TABLE `#__content` DROP COLUMN `sectionid`; -ALTER TABLE `#__content` DROP COLUMN `mask`; -ALTER TABLE `#__content` DROP COLUMN `parentid`; -ALTER TABLE `#__newsfeeds` DROP COLUMN `filename`; -ALTER TABLE `#__menu` DROP COLUMN `ordering`; -ALTER TABLE `#__session` DROP COLUMN `usertype`; -ALTER TABLE `#__users` DROP COLUMN `usertype`; -ALTER TABLE `#__updates` DROP COLUMN `categoryid`; - -UPDATE `#__extensions` SET protected = 0 WHERE -`name` = 'com_search' OR -`name` = 'mod_articles_archive' OR -`name` = 'mod_articles_latest' OR -`name` = 'mod_banners' OR -`name` = 'mod_feed' OR -`name` = 'mod_footer' OR -`name` = 'mod_users_latest' OR -`name` = 'mod_articles_category' OR -`name` = 'mod_articles_categories' OR -`name` = 'plg_content_pagebreak' OR -`name` = 'plg_content_pagenavigation' OR -`name` = 'plg_content_vote' OR -`name` = 'plg_editors_tinymce' OR -`name` = 'plg_system_p3p' OR -`name` = 'plg_user_contactcreator' OR -`name` = 'plg_user_profile'; - -DELETE FROM `#__extensions` WHERE `extension_id` = 800; - -ALTER TABLE `#__assets` ENGINE=InnoDB; -ALTER TABLE `#__associations` ENGINE=InnoDB; -ALTER TABLE `#__banners` ENGINE=InnoDB; -ALTER TABLE `#__banner_clients` ENGINE=InnoDB; -ALTER TABLE `#__banner_tracks` ENGINE=InnoDB; -ALTER TABLE `#__categories` ENGINE=InnoDB; -ALTER TABLE `#__contact_details` ENGINE=InnoDB; -ALTER TABLE `#__content` ENGINE=InnoDB; -ALTER TABLE `#__content_frontpage` ENGINE=InnoDB; -ALTER TABLE `#__content_rating` ENGINE=InnoDB; -ALTER TABLE `#__core_log_searches` ENGINE=InnoDB; -ALTER TABLE `#__extensions` ENGINE=InnoDB; -ALTER TABLE `#__finder_filters` ENGINE=InnoDB; -ALTER TABLE `#__finder_links` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms0` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms1` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms2` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms3` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms4` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms5` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms6` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms7` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms8` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_terms9` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_termsa` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_termsb` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_termsc` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_termsd` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_termse` ENGINE=InnoDB; -ALTER TABLE `#__finder_links_termsf` ENGINE=InnoDB; -ALTER TABLE `#__finder_taxonomy` ENGINE=InnoDB; -ALTER TABLE `#__finder_taxonomy_map` ENGINE=InnoDB; -ALTER TABLE `#__finder_terms` ENGINE=InnoDB; -ALTER TABLE `#__finder_terms_common` ENGINE=InnoDB; -ALTER TABLE `#__finder_types` ENGINE=InnoDB; -ALTER TABLE `#__languages` ENGINE=InnoDB; -ALTER TABLE `#__menu` ENGINE=InnoDB; -ALTER TABLE `#__menu_types` ENGINE=InnoDB; -ALTER TABLE `#__messages` ENGINE=InnoDB; -ALTER TABLE `#__messages_cfg` ENGINE=InnoDB; -ALTER TABLE `#__modules` ENGINE=InnoDB; -ALTER TABLE `#__modules_menu` ENGINE=InnoDB; -ALTER TABLE `#__newsfeeds` ENGINE=InnoDB; -ALTER TABLE `#__overrider` ENGINE=InnoDB; -ALTER TABLE `#__redirect_links` ENGINE=InnoDB; -ALTER TABLE `#__schemas` ENGINE=InnoDB; -ALTER TABLE `#__session` ENGINE=InnoDB; -ALTER TABLE `#__template_styles` ENGINE=InnoDB; -ALTER TABLE `#__updates` ENGINE=InnoDB; -ALTER TABLE `#__update_sites` ENGINE=InnoDB; -ALTER TABLE `#__update_sites_extensions` ENGINE=InnoDB; -ALTER TABLE `#__users` ENGINE=InnoDB; -ALTER TABLE `#__usergroups` ENGINE=InnoDB; -ALTER TABLE `#__user_notes` ENGINE=InnoDB; -ALTER TABLE `#__user_profiles` ENGINE=InnoDB; -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 `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 `#__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'; -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' ); - -ALTER TABLE `#__finder_terms` ADD COLUMN `language` char(3) NOT NULL DEFAULT ''; -ALTER TABLE `#__finder_tokens` ADD COLUMN `language` char(3) NOT NULL DEFAULT ''; -ALTER TABLE `#__finder_tokens_aggregate` ADD COLUMN `language` char(3) NOT NULL DEFAULT ''; - -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 - 2018 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 - 2018 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 - 2018 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); - -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"}'), - ('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"}'); - -UPDATE `#__template_styles` -SET home = (CASE WHEN (SELECT count FROM (SELECT count(`id`) AS count - FROM `#__template_styles` - WHERE home = '1' - AND client_id = 1) as c) = 0 - THEN '1' - ELSE '0' - END) -WHERE template = 'isis' -AND home != '1'; - -UPDATE `#__template_styles` -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 - 2018 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); - -UPDATE `#__update_sites` -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.1.sql b/administrator/components/com_admin/sql/updates/mysql/3.0.1.sql deleted file mode 100644 index c9f8fdaa6ed4b..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.0.1.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.0.1 \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.0.2.sql b/administrator/components/com_admin/sql/updates/mysql/3.0.2.sql deleted file mode 100644 index df708fc2fcea7..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.0.2.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.0.2 \ No newline at end of file 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 deleted file mode 100644 index 23fcc72c144df..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.0.3.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `#__associations` CHANGE `id` `id` INT(11) 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 deleted file mode 100644 index b07d05c28ccbb..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.1.0.sql +++ /dev/null @@ -1,165 +0,0 @@ --- --- Table structure for table `#__content_types` --- - -CREATE TABLE IF NOT EXISTS `#__content_types` ( - `type_id` int(10) 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 '', - `rules` text NOT NULL, - `field_mappings` text NOT NULL, - `router` varchar(255) NOT NULL DEFAULT '', - PRIMARY KEY (`type_id`), - KEY `idx_alias` (`type_alias`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=10000; - --- --- Dumping data for table `#__content_types` --- - -INSERT INTO `#__content_types` (`type_id`, `type_title`, `type_alias`, `table`, `rules`, `field_mappings`,`router`) VALUES -(1, 'Article', 'com_content.article', '{"special":{"dbtable":"#__content","key":"id","type":"Content","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"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"}], "special": [{"fulltext":"fulltext"}]}','ContentHelperRoute::getArticleRoute'), -(2, 'Contact', 'com_contact.contact', '{"special":{"dbtable":"#__contact_details","key":"id","type":"Contact","prefix":"ContactTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"address", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"image", "core_urls":"webpage", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}], "special": [{"con_position":"con_position","suburb":"suburb","state":"state","country":"country","postcode":"postcode","telephone":"telephone","fax":"fax","misc":"misc","email_to":"email_to","default_con":"default_con","user_id":"user_id","mobile":"mobile","sortname1":"sortname1","sortname2":"sortname2","sortname3":"sortname3"}]}','ContactHelperRoute::getContactRoute'), -(3, 'Newsfeed', 'com_newsfeeds.newsfeed', '{"special":{"dbtable":"#__newsfeeds","key":"id","type":"Newsfeed","prefix":"NewsfeedsTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"description", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"link", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}], "special": [{"numarticles":"numarticles","cache_time":"cache_time","rtl":"rtl"}]}','NewsfeedsHelperRoute::getNewsfeedRoute'), -(4, 'User', 'com_users.user', '{"special":{"dbtable":"#__users","key":"id","type":"User","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"name","core_state":"null","core_alias":"username","core_created_time":"registerdate","core_modified_time":"lastvisitDate","core_body":"null", "core_hits":"null","core_publish_up":"null","core_publish_down":"null","access":"null", "core_params":"params", "core_featured":"null", "core_metadata":"null", "core_language":"null", "core_images":"null", "core_urls":"null", "core_version":"null", "core_ordering":"null", "core_metakey":"null", "core_metadesc":"null", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}], "special": [{}]}','UsersHelperRoute::getUserRoute'), -(5, 'Article Category', 'com_content.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}]}','ContentHelperRoute::getCategoryRoute'), -(6, 'Contact Category', 'com_contact.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}]}','ContactHelperRoute::getCategoryRoute'), -(7, 'Newsfeeds Category', 'com_newsfeeds.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}]}','NewsfeedsHelperRoute::getCategoryRoute'), -(8, 'Tag', 'com_tags.tag', '{"special":{"dbtable":"#__tags","key":"tag_id","type":"Tag","prefix":"TagsTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"urls", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path"}]}','TagsHelperRoute::getTagRoute'); - -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', - `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', - 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`), - KEY `idx_tag` (`tag_id`), - KEY `idx_type` (`type_id`), - KEY `idx_core_content_id` (`core_content_id`) -) 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', - `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', - `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `access` int(10) 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_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_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', - `language` char(7) NOT NULL, - `version` int(10) 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`), - KEY `tag_idx` (`published`,`access`), - KEY `idx_access` (`access`), - KEY `idx_checkout` (`checked_out`), - KEY `idx_path` (`path`), - KEY `idx_left_right` (`lft`,`rgt`), - KEY `idx_alias` (`alias`), - KEY `idx_language` (`language`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- --- Dumping data for table `#__tags` --- - -INSERT INTO `#__tags` (`id`, `parent_id`, `lft`, `rgt`, `level`, `path`, `title`, `alias`, `note`, `description`, `published`, `checked_out`, `checked_out_time`, `access`, `params`, `metadesc`, `metakey`, `metadata`, `created_user_id`, `created_time`,`created_by_alias`, `modified_user_id`, `modified_time`, `images`, `urls`, `hits`, `language`, `version`) -VALUES (1, 0, 0, 1, 0, '', 'ROOT', 'root', '', '', 1, 0, '0000-00-00 00:00:00', 1, '{}', '', '', '', '', '2011-01-01 00:00:01','', 0, '0000-00-00 00:00:00', '', '', 0, '*', 1); - --- --- Table structure for table `#__ucm_base` --- - -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, - PRIMARY KEY (`ucm_id`), - KEY `idx_ucm_item_id` (`ucm_item_id`), - KEY `idx_ucm_type_id` (`ucm_type_id`), - KEY `idx_ucm_language_id` (`ucm_language_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -CREATE TABLE IF NOT EXISTS `#__ucm_content` ( - `core_content_id` int(10) 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_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_params` text NOT NULL, - `core_featured` tinyint(4) 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_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_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_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_metakey` text NOT NULL, - `core_metadesc` text NOT NULL, - `core_catid` int(10) 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, - PRIMARY KEY (`core_content_id`), - KEY `tag_idx` (`core_state`,`core_access`), - KEY `idx_access` (`core_access`), - KEY `idx_alias` (`core_alias`), - KEY `idx_language` (`core_language`), - KEY `idx_title` (`core_title`), - KEY `idx_modified_time` (`core_modified_time`), - KEY `idx_created_time` (`core_created_time`), - KEY `idx_content_type` (`core_type_alias`), - KEY `idx_core_modified_user_id` (`core_modified_user_id`), - KEY `idx_core_checked_out_user_id` (`core_checked_out_user_id`), - KEY `idx_core_created_user_id` (`core_created_user_id`), - KEY `idx_core_type_id` (`core_type_id`) - ) 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 - 2018 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 - 2018 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 - 2018 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 - 2018 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); - -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.1.1.sql b/administrator/components/com_admin/sql/updates/mysql/3.1.1.sql deleted file mode 100644 index df442faa0ef8d..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.1.1.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.1.1 \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.1.2.sql b/administrator/components/com_admin/sql/updates/mysql/3.1.2.sql deleted file mode 100644 index 40079fd6e1d07..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.1.2.sql +++ /dev/null @@ -1,16 +0,0 @@ -UPDATE `#__content_types` SET `table` = '{"special":{"dbtable":"#__content","key":"id","type":"Content","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE `type_title` = 'Article'; -UPDATE `#__content_types` SET `table` = '{"special":{"dbtable":"#__contact_details","key":"id","type":"Contact","prefix":"ContactTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE `type_title` = 'Contact'; -UPDATE `#__content_types` SET `table` = '{"special":{"dbtable":"#__newsfeeds","key":"id","type":"Newsfeed","prefix":"NewsfeedsTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE `type_title` = 'Newsfeed'; -UPDATE `#__content_types` SET `table` = '{"special":{"dbtable":"#__users","key":"id","type":"User","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE `type_title` = 'User'; -UPDATE `#__content_types` SET `table` = '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE `type_title` = 'Article Category'; -UPDATE `#__content_types` SET `table` = '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE `type_title` = 'Contact Category'; -UPDATE `#__content_types` SET `table` = '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE `type_title` = 'Newsfeeds Category'; -UPDATE `#__content_types` SET `table` = '{"special":{"dbtable":"#__tags","key":"tag_id","type":"Tag","prefix":"TagsTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE `type_title` = 'Tag'; -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"}, "special": {"fulltext":"fulltext"}}' WHERE `type_title` = 'Article'; -UPDATE `#__content_types` SET `field_mappings` = '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"address", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"image", "core_urls":"webpage", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}, "special": {"con_position":"con_position","suburb":"suburb","state":"state","country":"country","postcode":"postcode","telephone":"telephone","fax":"fax","misc":"misc","email_to":"email_to","default_con":"default_con","user_id":"user_id","mobile":"mobile","sortname1":"sortname1","sortname2":"sortname2","sortname3":"sortname3"}}' WHERE `type_title` = 'Contact'; -UPDATE `#__content_types` SET `field_mappings` = '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"description", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"link", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}, "special": {"numarticles":"numarticles","cache_time":"cache_time","rtl":"rtl"}}' WHERE `type_title` = 'Newsfeed'; -UPDATE `#__content_types` SET `field_mappings` = '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"null","core_alias":"username","core_created_time":"registerdate","core_modified_time":"lastvisitDate","core_body":"null", "core_hits":"null","core_publish_up":"null","core_publish_down":"null","access":"null", "core_params":"params", "core_featured":"null", "core_metadata":"null", "core_language":"null", "core_images":"null", "core_urls":"null", "core_version":"null", "core_ordering":"null", "core_metakey":"null", "core_metadesc":"null", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}, "special": {}}' WHERE `type_title` = 'User'; -UPDATE `#__content_types` SET `field_mappings` = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}' WHERE `type_title` = 'Article Category'; -UPDATE `#__content_types` SET `field_mappings` = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}' WHERE `type_title` = 'Contact Category'; -UPDATE `#__content_types` SET `field_mappings` = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}' WHERE `type_title` = 'Newsfeeds Category'; -UPDATE `#__content_types` SET `field_mappings` = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"urls", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path"}}' WHERE `type_title` = 'Tag'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.1.3.sql b/administrator/components/com_admin/sql/updates/mysql/3.1.3.sql deleted file mode 100644 index ebc1102eb1eeb..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.1.3.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.1.3 diff --git a/administrator/components/com_admin/sql/updates/mysql/3.1.4.sql b/administrator/components/com_admin/sql/updates/mysql/3.1.4.sql deleted file mode 100644 index e4bba830403e3..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.1.4.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(104, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.1.5.sql b/administrator/components/com_admin/sql/updates/mysql/3.1.5.sql deleted file mode 100644 index 2c9caba74fc12..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.1.5.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.1.5 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 deleted file mode 100644 index 591393406a7b3..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.0.sql +++ /dev/null @@ -1,93 +0,0 @@ -/* Core 3.2 schema updates */ - -ALTER TABLE `#__content_types` ADD COLUMN `content_history_options` VARCHAR(5120) NOT NULL COMMENT 'JSON string for com_contenthistory options'; - -UPDATE `#__content_types` SET `content_history_options` = '{"formFile":"administrator\\/components\\/com_content\\/models\\/forms\\/article.xml", "hideFields":["asset_id","checked_out","checked_out_time","version"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "hits"],"convertToInt":["publish_up", "publish_down", "featured", "ordering"],"displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"} ]}' WHERE `type_alias` = 'com_content.article'; -UPDATE `#__content_types` SET `content_history_options` = '{"formFile":"administrator\\/components\\/com_contact\\/models\\/forms\\/contact.xml","hideFields":["default_con","checked_out","checked_out_time","version","xreference"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "hits"],"convertToInt":["publish_up", "publish_down", "featured", "ordering"], "displayLookup":[ {"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"} ] }' WHERE `type_alias` = 'com_contact.contact'; -UPDATE `#__content_types` SET `content_history_options` = '{"formFile":"administrator\\/components\\/com_categories\\/models\\/forms\\/category.xml", "hideFields":["asset_id","checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"],"convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"parent_id","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}]}' WHERE `type_alias` IN ('com_content.category', 'com_contact.category', 'com_newsfeeds.category'); -UPDATE `#__content_types` SET `content_history_options` = '{"formFile":"administrator\\/components\\/com_newsfeeds\\/models\\/forms\\/newsfeed.xml","hideFields":["asset_id","checked_out","checked_out_time","version"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "hits"],"convertToInt":["publish_up", "publish_down", "featured", "ordering"],"displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}' WHERE `type_alias` = 'com_newsfeeds.newsfeed'; -UPDATE `#__content_types` SET `content_history_options` = '{"formFile":"administrator\\/components\\/com_tags\\/models\\/forms\\/tag.xml", "hideFields":["checked_out","checked_out_time","version", "lft", "rgt", "level", "path", "urls", "publish_up", "publish_down"],"ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"],"convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"}, {"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}' WHERE `type_alias` = 'com_tags.tag'; - -INSERT INTO `#__content_types` (`type_title`, `type_alias`, `table`, `rules`, `field_mappings`, `router`, `content_history_options`) VALUES -('Banner', 'com_banners.banner', '{"special":{"dbtable":"#__banners","key":"id","type":"Banner","prefix":"BannersTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"description", "core_hits":"null","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"link", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"null", "asset_id":"null"}, "special":{"imptotal":"imptotal", "impmade":"impmade", "clicks":"clicks", "clickurl":"clickurl", "custombannercode":"custombannercode", "cid":"cid", "purchase_type":"purchase_type", "track_impressions":"track_impressions", "track_clicks":"track_clicks"}}', '', '{"formFile":"administrator\\/components\\/com_banners\\/models\\/forms\\/banner.xml", "hideFields":["checked_out","checked_out_time","version", "reset"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "imptotal", "impmade", "reset"], "convertToInt":["publish_up", "publish_down", "ordering"], "displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}, {"sourceColumn":"cid","targetTable":"#__banner_clients","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}'), -('Banners Category', 'com_banners.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}', '', '{"formFile":"administrator\\/components\\/com_categories\\/models\\/forms\\/category.xml", "hideFields":["asset_id","checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"], "convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"parent_id","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}]}'), -('Banner Client', 'com_banners.client', '{"special":{"dbtable":"#__banner_clients","key":"id","type":"Client","prefix":"BannersTable"}}', '', '', '', '{"formFile":"administrator\\/components\\/com_banners\\/models\\/forms\\/client.xml", "hideFields":["checked_out","checked_out_time"], "ignoreChanges":["checked_out", "checked_out_time"], "convertToInt":[], "displayLookup":[]}'), -('User Notes', 'com_users.note', '{"special":{"dbtable":"#__user_notes","key":"id","type":"Note","prefix":"UsersTable"}}', '', '', '', '{"formFile":"administrator\\/components\\/com_users\\/models\\/forms\\/note.xml", "hideFields":["checked_out","checked_out_time", "publish_up", "publish_down"],"ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time"], "convertToInt":["publish_up", "publish_down"],"displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}, {"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}'), -('User Notes Category', 'com_users.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special":{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}', '', '{"formFile":"administrator\\/components\\/com_categories\\/models\\/forms\\/category.xml", "hideFields":["checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"], "convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"parent_id","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}]}'); - -UPDATE `#__extensions` SET `params` = '{"template_positions_display":"0","upload_limit":"2","image_formats":"gif,bmp,jpg,jpeg,png","source_formats":"txt,less,ini,xml,js,php,css","font_formats":"woff,ttf,otf","compressed_formats":"zip"}' WHERE `extension_id` = 20; -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 - 2018 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 - 2018 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), -(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 - 2018 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 - 2018 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 - 2018 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); - -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`; - -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', - `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', - `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', - PRIMARY KEY (`postinstall_message_id`) -) DEFAULT CHARSET=utf8; - -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_TWOFACTORAUTH_TOTP_POSTINSTALL_TITLE', 'PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_BODY', 'PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_ACTION', 'plg_twofactorauth_totp', 1, 'action', 'site://plugins/twofactorauth/totp/postinstall/actions.php', 'twofactorauth_postinstall_action', 'site://plugins/twofactorauth/totp/postinstall/actions.php', 'twofactorauth_postinstall_condition', '3.2.0', 1), -(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_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.', - `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', - PRIMARY KEY (`version_id`), - KEY `idx_ucm_item_id` (`ucm_type_id`,`ucm_item_id`), - KEY `idx_save_date` (`save_date`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -ALTER TABLE `#__users` ADD COLUMN `otpKey` varchar(1000) NOT NULL DEFAULT '' COMMENT 'Two factor authentication encrypted keys'; -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, - `user_id` varchar(255) NOT NULL, - `token` varchar(255) NOT NULL, - `series` varchar(255) NOT NULL, - `invalid` tinyint(4) NOT NULL, - `time` varchar(200) NOT NULL, - `uastring` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `series` (`series`), - UNIQUE KEY `series_2` (`series`), - UNIQUE KEY `series_3` (`series`), - KEY `user_id` (`user_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/* Update bad params for two cpanel modules */ - -UPDATE `#__modules` SET `params` = REPLACE(`params`, '"bootstrap_size":"1"', '"bootstrap_size":"0"') WHERE `id` IN (3,4); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.1.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.1.sql deleted file mode 100644 index 94857f9297651..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.1.sql +++ /dev/null @@ -1 +0,0 @@ -DELETE FROM `#__postinstall_messages` WHERE `title_key` = 'PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_TITLE'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2013-12-22.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.2-2013-12-22.sql deleted file mode 100644 index d372260e60626..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2013-12-22.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `#__update_sites` ADD COLUMN `extra_query` VARCHAR(1000) DEFAULT ''; -ALTER TABLE `#__updates` ADD COLUMN `extra_query` VARCHAR(1000) DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2013-12-28.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.2-2013-12-28.sql deleted file mode 100644 index 2da6b1f7b01a8..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2013-12-28.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE `#__menu` SET `component_id` = (SELECT `extension_id` FROM `#__extensions` WHERE `element` = 'com_joomlaupdate') WHERE `link` = 'index.php?option=com_joomlaupdate'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-08.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-08.sql deleted file mode 100644 index c80b1b2115899..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-08.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(403, 'plg_content_contact', 'plugin', 'contact', 'content', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 1, 0); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-15.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-15.sql deleted file mode 100644 index 852f9ec39afac..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-15.sql +++ /dev/null @@ -1,2 +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, 'COM_CPANEL_MSG_PHPVERSION_TITLE', 'COM_CPANEL_MSG_PHPVERSION_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/phpversion.php', 'admin_postinstall_phpversion_condition', '3.2.2', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-18.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-18.sql deleted file mode 100644 index fa4aff3fd5904..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-18.sql +++ /dev/null @@ -1,2 +0,0 @@ -/* Update updates version length */ -ALTER TABLE `#__updates` MODIFY `version` varchar(32) DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-23.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-23.sql deleted file mode 100644 index a6563541f45ac..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.2-2014-01-23.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(106, 'PHPass', 'library', 'phpass', '', 0, 1, 1, 1, '{"legacy":false,"name":"PHPass","type":"library","creationDate":"2004-2006","author":"Solar Designer","authorEmail":"solar@openwall.com","authorUrl":"http:\/\/www.openwall.com/phpass","version":"0.3","description":"LIB_PHPASS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.3-2014-02-20.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.3-2014-02-20.sql deleted file mode 100644 index 0bd96df127480..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.2.3-2014-02-20.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE `#__extensions` ext1, `#__extensions` ext2 SET ext1.`params` = ext2.`params` WHERE ext1.`name` = 'plg_authentication_cookie' AND ext2.`name` = 'plg_system_remember'; 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 deleted file mode 100644 index e280281553ad3..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.3.0-2014-02-16.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `#__users` ADD COLUMN `requireReset` tinyint(4) 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.0-2014-04-02.sql b/administrator/components/com_admin/sql/updates/mysql/3.3.0-2014-04-02.sql deleted file mode 100644 index 9bbacff997bbb..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.3.0-2014-04-02.sql +++ /dev/null @@ -1,3 +0,0 @@ -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 -(451, 'plg_search_tags', 'plugin', 'tags', 'search', 0, 0, 1, 0, '', '{"search_limit":"50","show_tagged_items":"1"}', '', '', 0, '0000-00-00 00:00:00', 0, 0); - diff --git a/administrator/components/com_admin/sql/updates/mysql/3.3.4-2014-08-03.sql b/administrator/components/com_admin/sql/updates/mysql/3.3.4-2014-08-03.sql deleted file mode 100644 index 1ab0a8fd90dd0..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.3.4-2014-08-03.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `#__user_profiles` CHANGE `profile_value` `profile_value` TEXT NOT NULL; 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 deleted file mode 100644 index eb7048877c84c..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.3.6-2014-09-30.sql +++ /dev/null @@ -1,5 +0,0 @@ -INSERT INTO `#__update_sites` (`name`, `type`, `location`, `enabled`) VALUES -('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-08-24.sql b/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-08-24.sql deleted file mode 100644 index d227c42440473..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-08-24.sql +++ /dev/null @@ -1,3 +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, 'COM_CPANEL_MSG_HTACCESS_TITLE', 'COM_CPANEL_MSG_HTACCESS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/htaccess.php', 'admin_postinstall_htaccess_condition', '3.4.0', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-01.sql b/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-01.sql deleted file mode 100644 index 0c95ea5c69643..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-01.sql +++ /dev/null @@ -1,8 +0,0 @@ -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 -(801, 'weblinks', 'package', 'pkg_weblinks', '', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); - -INSERT INTO `#__update_sites` (`name`, `type`, `location`, `enabled`) VALUES -('Weblinks Update Site', 'extension', 'https://raw.githubusercontent.com/joomla-extensions/weblinks/master/manifest.xml', 1); - -INSERT INTO `#__update_sites_extensions` (`update_site_id`, `extension_id`) VALUES -((SELECT `update_site_id` FROM `#__update_sites` WHERE `name` = 'Weblinks Update Site'), 801); 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 deleted file mode 100644 index 37620c9c50f00..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-09-16.sql +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE `#__redirect_links` ADD COLUMN `header` smallint(3) 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 --- --- ALTER TABLE `#__redirect_links` MODIFY `new_url` varchar(255); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-10-20.sql b/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-10-20.sql deleted file mode 100644 index 958778d59f983..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-10-20.sql +++ /dev/null @@ -1 +0,0 @@ -DELETE FROM `#__extensions` WHERE `extension_id` = 100; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-12-03.sql b/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-12-03.sql deleted file mode 100644 index 1b272c13a6678..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2014-12-03.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE `#__extensions` SET `protected` = '0' WHERE `name` = 'plg_editors-xtd_article' AND `type` = "plugin" AND `element` = "article" AND `folder` = "editors-xtd"; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2015-01-21.sql b/administrator/components/com_admin/sql/updates/mysql/3.4.0-2015-01-21.sql deleted file mode 100644 index 96adfe3d927fa..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2015-01-21.sql +++ /dev/null @@ -1,2 +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, 'COM_CPANEL_MSG_ROBOTS_TITLE', 'COM_CPANEL_MSG_ROBOTS_BODY', '', 'com_cpanel', 1, 'message', '', '', '', '', '3.3.0', 1); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2015-02-26.sql b/administrator/components/com_admin/sql/updates/mysql/3.4.0-2015-02-26.sql deleted file mode 100644 index da3cc8c50ab48..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.4.0-2015-02-26.sql +++ /dev/null @@ -1,2 +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, 'COM_CPANEL_MSG_LANGUAGEACCESS340_TITLE', 'COM_CPANEL_MSG_LANGUAGEACCESS340_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/languageaccess340.php', 'admin_postinstall_languageaccess340_condition', '3.4.1', 1); 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 deleted file mode 100644 index e76947836f087..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-07-01.sql +++ /dev/null @@ -1,2 +0,0 @@ -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-2015-10-13.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-13.sql deleted file mode 100644 index 688f19313e186..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-13.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(453, 'plg_editors-xtd_module', 'plugin', 'module', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-26.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-26.sql deleted file mode 100644 index dfc9043ae9c8b..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-26.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE `#__contentitem_tag_map` DROP INDEX `idx_tag`; -ALTER TABLE `#__contentitem_tag_map` DROP INDEX `idx_type`; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-30.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-30.sql deleted file mode 100644 index 299347e6d56e5..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-10-30.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE `#__menu` SET `title` = 'com_contact_contacts' WHERE `client_id` = 1 AND `level` = 2 AND `title` = 'com_contact'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-11-04.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-11-04.sql deleted file mode 100644 index 41eb98fccb3b7..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-11-04.sql +++ /dev/null @@ -1,4 +0,0 @@ -DELETE FROM `#__menu` WHERE `title` = 'com_messages_read' AND `client_id` = 1; - -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 -(452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-11-05.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-11-05.sql deleted file mode 100644 index 4f75f640e3a56..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2015-11-05.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 -(454, 'plg_system_stats', 'plugin', 'stats', '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, 'COM_CPANEL_MSG_STATS_COLLECTION_TITLE', 'COM_CPANEL_MSG_STATS_COLLECTION_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/statscollection.php', 'admin_postinstall_statscollection_condition', '3.5.0', 1); 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 deleted file mode 100644 index 0aa843cbfbc91..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2016-02-26.sql +++ /dev/null @@ -1,14 +0,0 @@ --- --- Create a table for UTF-8 Multibyte (utf8mb4) conversion for MySQL in --- order to check if the conversion has been performed and if not show a --- message about database problem in the database schema view. --- --- The value of `converted` can be 0 (not converted yet after update), --- 1 (converted to utf8), or 2 (converted to utf8mb4). --- - -CREATE TABLE IF NOT EXISTS `#__utf8_conversion` ( - `converted` tinyint(4) 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.5.0-2016-03-01.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.0-2016-03-01.sql deleted file mode 100644 index ff8c69105f07d..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.0-2016-03-01.sql +++ /dev/null @@ -1,12 +0,0 @@ -ALTER TABLE `#__redirect_links` DROP INDEX `idx_link_old`; -ALTER TABLE `#__redirect_links` MODIFY `old_url` VARCHAR(2048) NOT NULL; - --- --- The following statement had to be modified for 3.6.0 by removing the --- NOT NULL, which was wrong because not consistent with new install. --- See also 3.6.0-2016-04-06.sql for updating 3.5.0 or 3.5.1 --- -ALTER TABLE `#__redirect_links` MODIFY `new_url` VARCHAR(2048); - -ALTER TABLE `#__redirect_links` MODIFY `referer` VARCHAR(2048) NOT NULL; -ALTER TABLE `#__redirect_links` ADD INDEX `idx_old_url` (`old_url`(100)); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.5.1-2016-03-25.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.1-2016-03-25.sql deleted file mode 100644 index f6c320b8cc24e..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.1-2016-03-25.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- Make #__user_keys.user_id fit to #__users.username --- - -ALTER TABLE `#__user_keys` MODIFY `user_id` varchar(150) NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.5.1-2016-03-29.sql b/administrator/components/com_admin/sql/updates/mysql/3.5.1-2016-03-29.sql deleted file mode 100644 index 86ecda89c6258..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.5.1-2016-03-29.sql +++ /dev/null @@ -1,7 +0,0 @@ --- --- Reset UTF-8 Multibyte (utf8mb4) or UTF-8 conversion status --- to force a new conversion when updating from version 3.5.0 --- - -UPDATE `#__utf8_conversion` SET `converted` = 0 - WHERE (SELECT COUNT(*) FROM `#__schemas` WHERE `extension_id`=700 AND `version_id` LIKE '3.5.0%') = 1; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-01.sql b/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-01.sql deleted file mode 100644 index 0ac34df324f64..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-01.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Rename update site names -UPDATE `#__update_sites` SET `name` = 'Joomla! Core' WHERE `name` = 'Joomla Core' AND `type` = 'collection'; -UPDATE `#__update_sites` SET `name` = 'Joomla! Extension Directory' WHERE `name` = 'Joomla Extension Directory' AND `type` = 'collection'; - -UPDATE `#__update_sites` SET `location` = 'https://update.joomla.org/core/list.xml' WHERE `name` = 'Joomla! Core' AND `type` = 'collection'; -UPDATE `#__update_sites` SET `location` = 'https://update.joomla.org/jed/list.xml' WHERE `name` = 'Joomla! Extension Directory' AND `type` = 'collection'; -UPDATE `#__update_sites` SET `location` = 'https://update.joomla.org/language/translationlist_3.xml' WHERE `name` = 'Accredited Joomla! Translations' AND `type` = 'collection'; -UPDATE `#__update_sites` SET `location` = 'https://update.joomla.org/core/extensions/com_joomlaupdate.xml' WHERE `name` = 'Joomla! Update Component Update Site' AND `type` = 'extension'; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-06.sql b/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-06.sql deleted file mode 100644 index e7df517ad4ee6..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-06.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `#__redirect_links` MODIFY `new_url` VARCHAR(2048); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-08.sql b/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-08.sql deleted file mode 100644 index 6714529c323c6..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-08.sql +++ /dev/null @@ -1,14 +0,0 @@ --- Insert the missing en-GB package extension. -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 (802, 'English (United Kingdom)', 'package', 'pkg_en-GB', '', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); - --- Change update site extension id to the new extension. -UPDATE `#__update_sites_extensions` -SET `extension_id` = 802 -WHERE `update_site_id` IN ( - SELECT `update_site_id` - FROM `#__update_sites` - WHERE `name` = 'Accredited Joomla! Translations' - AND `type` = 'collection' - ) -AND `extension_id` = 600; 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 deleted file mode 100644 index 95678415b6501..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-04-09.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- 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 diff --git a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-05-06.sql b/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-05-06.sql deleted file mode 100644 index a53c9b18e40ae..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-05-06.sql +++ /dev/null @@ -1,5 +0,0 @@ -DELETE FROM `#__extensions` WHERE `type` = 'library' AND `element` = 'simplepie'; -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 -(455, 'plg_installer_packageinstaller', 'plugin', 'packageinstaller', 'installer', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 1, 0), -(456, 'plg_installer_folderinstaller', 'plugin', 'folderinstaller', 'installer', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 2, 0), -(457, 'plg_installer_urlinstaller', 'plugin', 'urlinstaller', 'installer', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 3, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-01.sql b/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-01.sql deleted file mode 100644 index 511d7cbac13e5..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-01.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE `#__extensions` SET `protected` = 1, `enabled` = 1 WHERE `name` = 'com_ajax'; 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 deleted file mode 100644 index 4fcc47c42f600..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.0-2016-06-05.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- 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 diff --git a/administrator/components/com_admin/sql/updates/mysql/3.6.3-2016-08-15.sql b/administrator/components/com_admin/sql/updates/mysql/3.6.3-2016-08-15.sql deleted file mode 100644 index 586c542e30e92..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.3-2016-08-15.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- Increasing size of the URL field in com_newsfeeds --- - -ALTER TABLE `#__newsfeeds` MODIFY `link` VARCHAR(2048) NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.6.3-2016-08-16.sql b/administrator/components/com_admin/sql/updates/mysql/3.6.3-2016-08-16.sql deleted file mode 100644 index 06d2c9e9565ce..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.6.3-2016-08-16.sql +++ /dev/null @@ -1,2 +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_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_BODY', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_ACTION', 'plg_system_updatenotification', 1, 'action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_condition', '3.6.3', 1); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-06.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-06.sql deleted file mode 100644 index 1a861d18009bd..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-06.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(458, 'plg_quickicon_phpversioncheck', 'plugin', 'phpversioncheck', 'quickicon', 0, 1, 1, 1, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-22.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-22.sql deleted file mode 100644 index 02ec2ac98f912..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-22.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(459, 'plg_editors-xtd_menu', 'plugin', 'menu', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); 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 deleted file mode 100644 index 2525369981db7..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-08-29.sql +++ /dev/null @@ -1,93 +0,0 @@ -CREATE TABLE IF NOT EXISTS `#__fields` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `asset_id` int(10) unsigned NOT NULL DEFAULT 0, - `context` varchar(255) NOT NULL DEFAULT '', - `group_id` int(10) 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 '', - `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', - `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `ordering` int(11) 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', - `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', - PRIMARY KEY (`id`), - KEY `idx_checkout` (`checked_out`), - KEY `idx_state` (`state`), - KEY `idx_created_user_id` (`created_user_id`), - KEY `idx_access` (`access`), - KEY `idx_context` (`context`(191)), - KEY `idx_language` (`language`) -) 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, - 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, - `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', - `checked_out_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `ordering` int(11) 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', - `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', - PRIMARY KEY (`id`), - KEY `idx_checkout` (`checked_out`), - KEY `idx_state` (`state`), - KEY `idx_created_by` (`created_by`), - KEY `idx_access` (`access`), - KEY `idx_context` (`context`(191)), - KEY `idx_language` (`language`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; - -CREATE TABLE IF NOT EXISTS `#__fields_values` ( - `field_id` int(10) 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 '', - KEY `idx_field_id` (`field_id`), - KEY `idx_item_id` (`item_id`(191)) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; - -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 -(33, 'com_fields', 'component', 'com_fields', '', 1, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); -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 -(461, 'plg_system_fields', 'plugin', 'fields', 'system', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(462, 'plg_fields_calendar', 'plugin', 'calendar', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(463, 'plg_fields_checkboxes', 'plugin', 'checkboxes', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(464, 'plg_fields_color', 'plugin', 'color', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(465, 'plg_fields_editor', 'plugin', 'editor', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(466, 'plg_fields_imagelist', 'plugin', 'imagelist', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(467, 'plg_fields_integer', 'plugin', 'integer', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(468, 'plg_fields_list', 'plugin', 'list', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(469, 'plg_fields_media', 'plugin', 'media', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(470, 'plg_fields_radio', 'plugin', 'radio', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(471, 'plg_fields_sql', 'plugin', 'sql', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(472, 'plg_fields_text', 'plugin', 'text', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(473, 'plg_fields_textarea', 'plugin', 'textarea', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(474, 'plg_fields_url', 'plugin', 'url', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(475, 'plg_fields_user', 'plugin', 'user', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), -(476, 'plg_fields_usergrouplist', 'plugin', 'usergrouplist', '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.7.0-2016-09-29.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-09-29.sql deleted file mode 100644 index 6ee23ef7b0d3c..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-09-29.sql +++ /dev/null @@ -1,3 +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, 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE', 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/joomla40checks.php', 'admin_postinstall_joomla40checks_condition', '3.7.0', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-01.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-01.sql deleted file mode 100644 index 0eac30c0aa2ef..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-01.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(460, 'plg_editors-xtd_contact', 'plugin', 'contact', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); 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 deleted file mode 100644 index 73fd38ff7dd95..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-10-02.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `#__session` MODIFY `client_id` tinyint(3) 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 deleted file mode 100644 index 0281c97232aaa..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-04.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `#__extensions` CHANGE `enabled` `enabled` TINYINT(3) 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 deleted file mode 100644 index fe2029766a597..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-19.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE `#__menu_types` ADD COLUMN `client_id` int(11) 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-21.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-21.sql deleted file mode 100644 index e066845064b4b..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-21.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Replace language image UNIQUE index for a normal INDEX. -ALTER TABLE `#__languages` DROP INDEX `idx_image`; 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 deleted file mode 100644 index 2b2a91013014a..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-24.sql +++ /dev/null @@ -1,6 +0,0 @@ -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`; - -UPDATE `#__extensions` AS `e1` -INNER JOIN (SELECT `extension_id` FROM `#__extensions` WHERE `type` = 'package' AND `element` = 'pkg_en-GB') AS `e2` -SET `e1`.`package_id` = `e2`.`extension_id` -WHERE `e1`.`type`= 'language' AND `e1`.`element` = 'en-GB'; 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 deleted file mode 100644 index f6874ee5a5c36..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2016-11-27.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Normalize modules content field with other db systems. Add default value. -ALTER TABLE `#__modules` MODIFY `content` text NOT NULL DEFAULT ''; 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 deleted file mode 100644 index 6836086861ca5..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-08.sql +++ /dev/null @@ -1,18 +0,0 @@ --- 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_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_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_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; 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 deleted file mode 100644 index 162635df1fbe5..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-09.sql +++ /dev/null @@ -1,8 +0,0 @@ --- 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 `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.'; -ALTER TABLE `#__categories` MODIFY `language` char(7) NOT NULL DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-15.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-15.sql deleted file mode 100644 index 5b309f020fa4a..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-15.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(34, 'com_associations', 'component', 'com_associations', '', 1, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); 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 deleted file mode 100644 index fe041e904b7e5..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-17.sql +++ /dev/null @@ -1,58 +0,0 @@ --- Sync menutype for admin menu and set client_id correct - --- 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-01-31.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-31.sql deleted file mode 100644 index 225fba49c8347..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-01-31.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(477, 'plg_content_fields', 'plugin', 'fields', 'content', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-02.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-02.sql deleted file mode 100644 index 67860a91b7140..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-02.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(478, 'plg_editors-xtd_fields', 'plugin', 'fields', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-15.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-15.sql deleted file mode 100644 index 5026504a74ffb..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-15.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Normalize redirect_links table default values. -ALTER TABLE `#__redirect_links` MODIFY `comment` varchar(255) NOT NULL DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-17.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-17.sql deleted file mode 100644 index 9ff8df9851305..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-02-17.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Normalize contact_details table default values. -ALTER TABLE `#__contact_details` MODIFY `name` varchar(255) NOT NULL; -ALTER TABLE `#__contact_details` MODIFY `alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL; -ALTER TABLE `#__contact_details` MODIFY `sortname1` varchar(255) NOT NULL DEFAULT ''; -ALTER TABLE `#__contact_details` MODIFY `sortname2` varchar(255) NOT NULL DEFAULT ''; -ALTER TABLE `#__contact_details` MODIFY `sortname3` varchar(255) NOT NULL DEFAULT ''; -ALTER TABLE `#__contact_details` MODIFY `language` varchar(7) NOT NULL; -ALTER TABLE `#__contact_details` MODIFY `xreference` varchar(50) NOT NULL DEFAULT '' COMMENT 'A reference to enable linkages to external data sets.'; 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 deleted file mode 100644 index ada236b5889cf..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-03.sql +++ /dev/null @@ -1,5 +0,0 @@ -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 `#__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.0-2017-03-09.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-09.sql deleted file mode 100644 index 84100ee83ce63..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-09.sql +++ /dev/null @@ -1,17 +0,0 @@ -UPDATE `#__categories` SET `published` = 1 WHERE `alias` = 'root'; -UPDATE `#__categories` AS `c` INNER JOIN ( - SELECT c2.id, CASE WHEN MIN(p.published) > 0 THEN MAX(p.published) ELSE MIN(p.published) END AS newPublished - FROM `#__categories` AS `c2` - INNER JOIN `#__categories` AS `p` ON p.lft <= c2.lft AND c2.rgt <= p.rgt - GROUP BY c2.id) c2 -ON c.id = c2.id -SET published = c2.newPublished; - -UPDATE `#__menu` SET `published` = 1 WHERE `alias` = 'root'; -UPDATE `#__menu` AS `c` INNER JOIN ( - SELECT c2.id, CASE WHEN MIN(p.published) > 0 THEN MAX(p.published) ELSE MIN(p.published) END AS newPublished - FROM `#__menu` AS `c2` - INNER JOIN `#__menu` AS `p` ON p.lft <= c2.lft AND c2.rgt <= p.rgt - GROUP BY c2.id) c2 -ON c.id = c2.id -SET published = c2.newPublished; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-19.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-19.sql deleted file mode 100644 index f7f3c552d02e6..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-03-19.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `#__finder_links` MODIFY `description` text; diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-04-10.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-04-10.sql deleted file mode 100644 index 11ec271337c0a..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-04-10.sql +++ /dev/null @@ -1,3 +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, 'TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE', 'TPL_HATHOR_MESSAGE_POSTINSTALL_BODY', 'TPL_HATHOR_MESSAGE_POSTINSTALL_ACTION', 'tpl_hathor', 1, 'action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_condition', '3.7.0', 1); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-04-19.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-04-19.sql deleted file mode 100644 index 35327661646c8..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.0-2017-04-19.sql +++ /dev/null @@ -1,3 +0,0 @@ --- Set integer field default values. -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/mysql/3.7.3-2017-06-03.sql b/administrator/components/com_admin/sql/updates/mysql/3.7.3-2017-06-03.sql deleted file mode 100644 index eac66fa67b28e..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.3-2017-06-03.sql +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 0c4bb1b3b6d9e..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.7.4-2017-07-05.sql +++ /dev/null @@ -1 +0,0 @@ -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.6-2018-02-14.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.6-2018-02-14.sql deleted file mode 100644 index b88087a13504f..0000000000000 --- a/administrator/components/com_admin/sql/updates/mysql/3.8.6-2018-02-14.sql +++ /dev/null @@ -1,6 +0,0 @@ -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/4.0.0-2016-07-03.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-07-03.sql new file mode 100644 index 0000000000000..78ec385137e3f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-07-03.sql @@ -0,0 +1,3 @@ +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 +(458, 'plg_behaviour_taggable', 'plugin', 'taggable', 'behaviour', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(459, 'plg_behaviour_versionable', 'plugin', 'versionable', 'behaviour', 0, 1, 1, 0, '', '{}', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-09-22.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-09-22.sql new file mode 100644 index 0000000000000..6e2b931e05c2f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-09-22.sql @@ -0,0 +1 @@ +DELETE FROM `#__extensions` WHERE `extension_id` = 102; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-09-28.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-09-28.sql new file mode 100644 index 0000000000000..9afcdd4654722 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-09-28.sql @@ -0,0 +1 @@ +DELETE FROM `#__extensions` WHERE `extension_id` = 423; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-10-02.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-10-02.sql new file mode 100644 index 0000000000000..965182690d2e2 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-10-02.sql @@ -0,0 +1,3 @@ +DELETE FROM `#__extensions` WHERE `extension_id` = 504; +DELETE FROM `#__template_styles` WHERE `template` = 'hathor'; +ALTER TABLE `#__user_keys` DROP COLUMN `invalid`; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-10-03.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-10-03.sql new file mode 100644 index 0000000000000..ed5a9bac5700e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-10-03.sql @@ -0,0 +1 @@ +DELETE FROM `#__extensions` WHERE `name` = 'mod_submenu'; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-19-03.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-19-03.sql new file mode 100644 index 0000000000000..cd5f393e72e10 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2016-19-03.sql @@ -0,0 +1 @@ +ALTER TABLE `#__extensions` ADD namespace VARCHAR(500) NOT NULL DEFAULT '' AFTER params; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-03-18.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-03-18.sql new file mode 100644 index 0000000000000..0c8be59987646 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-03-18.sql @@ -0,0 +1,2 @@ +ALTER TABLE `#__extensions` DROP COLUMN `custom_data`; +ALTER TABLE `#__extensions` DROP COLUMN `system_data`; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-04-25.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-04-25.sql new file mode 100644 index 0000000000000..4821e1462132a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-04-25.sql @@ -0,0 +1,5 @@ +INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(481, 'plg_filesystem_local', 'plugin', 'local', 'filesystem', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0), +(482, 'plg_media-action_crop', 'plugin', 'crop', 'media-action', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0), +(483, 'plg_media-action_resize', 'plugin', 'resize', 'media-action', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0), +(484, 'plg_media-action_rotate', 'plugin', 'rotate', 'media-action', 0, 1, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-05-31.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-05-31.sql new file mode 100644 index 0000000000000..6581c7c799f40 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-05-31.sql @@ -0,0 +1,2 @@ +UPDATE `#__menu` SET `link` = 'index.php?option=com_config&view=config' WHERE `link` = 'index.php?option=com_config&view=config&controller=config.display.config'; +UPDATE `#__menu` SET `link` = 'index.php?option=com_config&view=templates' WHERE `link` = 'index.php?option=com_config&view=templates&controller=config.display.templates'; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-10-10.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-10-10.sql new file mode 100644 index 0000000000000..d50f4cf946753 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2017-10-10.sql @@ -0,0 +1,6 @@ +INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(487, 'plg_system_httpheaders', 'plugin', 'httpheaders', 'system', 0, 0, 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_SYSTEM_HTTPHEADERS_POSTINSTALL_INTRODUCTION_TITLE', 'PLG_SYSTEM_HTTPHEADERS_POSTINSTALL_INTRODUCTION_BODY', 'PLG_SYSTEM_HTTPHEADERS_POSTINSTALL_INTRODUCTION_ACTION', 'plg_system_httpheaders', 1, 'action', 'site://plugins/system/httpheaders/postinstall/introduction.php', 'httpheaders_postinstall_action', 'site://plugins/system/httpheaders/postinstall/introduction.php', 'httpheaders_postinstall_condition', '4.0.0', 1); diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-02-24.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-02-24.sql new file mode 100644 index 0000000000000..4efbd594747fa --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-02-24.sql @@ -0,0 +1 @@ +DELETE FROM `#__extensions` WHERE `extension_id` = 104; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-03-05.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-03-05.sql new file mode 100644 index 0000000000000..d84f23c5c9b7a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-03-05.sql @@ -0,0 +1 @@ +ALTER TABLE `#__modules` CHANGE `content` `content` TEXT NULL; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-04-14.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-04-14.sql new file mode 100644 index 0000000000000..fd0a64d0ab00d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-04-14.sql @@ -0,0 +1,37 @@ +CREATE TABLE `#__finder_links_terms` ( + `link_id` INT(10) UNSIGNED NOT NULL, + `term_id` INT(10) UNSIGNED NOT NULL, + `weight` FLOAT UNSIGNED NOT NULL, + PRIMARY KEY (`link_id`, `term_id`), + INDEX `idx_term_weight` (`term_id`, `weight`), + INDEX `idx_link_term_weight` (`link_id`, `term_id`, `weight`) +) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB; + +DROP TABLE #__finder_links_terms0; +DROP TABLE #__finder_links_terms1; +DROP TABLE #__finder_links_terms2; +DROP TABLE #__finder_links_terms3; +DROP TABLE #__finder_links_terms4; +DROP TABLE #__finder_links_terms5; +DROP TABLE #__finder_links_terms6; +DROP TABLE #__finder_links_terms7; +DROP TABLE #__finder_links_terms8; +DROP TABLE #__finder_links_terms9; +DROP TABLE #__finder_links_termsa; +DROP TABLE #__finder_links_termsb; +DROP TABLE #__finder_links_termsc; +DROP TABLE #__finder_links_termsd; +DROP TABLE #__finder_links_termse; +DROP TABLE #__finder_links_termsf; + +ALTER TABLE `#__finder_terms` CHANGE `language` `language` CHAR(7) NOT NULL DEFAULT '' AFTER `links`; + +ALTER TABLE `#__finder_terms_common` CHANGE `language` `language` CHAR(7) NOT NULL DEFAULT '' AFTER `term`; + +ALTER TABLE `#__finder_tokens` CHANGE `language` `language` CHAR(7) NOT NULL DEFAULT '' AFTER `context`; + +ALTER TABLE `#__finder_tokens_aggregate` DROP COLUMN `map_suffix`; + +ALTER TABLE `#__finder_tokens_aggregate` CHANGE `language` `language` CHAR(7) NOT NULL DEFAULT '' AFTER `total_weight`; + +ALTER TABLE `#__finder_links` CHANGE `language` `language` CHAR(7) NOT NULL DEFAULT '' AFTER `access`; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql new file mode 100644 index 0000000000000..bb83d8df34341 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-05-15.sql @@ -0,0 +1,124 @@ +-- +-- Table structure for table `#__workflows` +-- + +CREATE TABLE IF NOT EXISTS `#__workflows` ( + `id` int(10) NOT NULL AUTO_INCREMENT, + `asset_id` int(10) DEFAULT 0, + `published` tinyint(1) NOT NULL DEFAULT 0, + `title` varchar(255) NOT NULL, + `description` text NOT NULL, + `extension` varchar(50) NOT NULL, + `default` tinyint(1) NOT NULL DEFAULT 0, + `ordering` int(11) NOT NULL DEFAULT 0, + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `created_by` int(10) NOT NULL DEFAULT 0, + `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified_by` int(10) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `idx_asset_id` (`asset_id`), + KEY `idx_title` (`title`(191)), + KEY `idx_extension` (`extension`), + KEY `idx_default` (`default`), + KEY `idx_created` (`created`), + KEY `idx_created_by` (`created_by`), + KEY `idx_modified` (`modified`), + KEY `idx_modified_by` (`modified_by`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +-- +-- Dumping data for table `#__workflows` +-- + +INSERT INTO `#__workflows` (`id`, `asset_id`, `published`, `title`, `description`, `extension`, `default`, `ordering`, `created`, `created_by`, `modified`, `modified_by`) VALUES +(1, 0, 1, 'Joomla! Default', '', 'com_content', 1, 1, '0000-00-00 00:00:00', 0, '0000-00-00 00:00:00', 0); + +-- +-- Table structure for table `#__workflow_associations` +-- + +CREATE TABLE IF NOT EXISTS `#__workflow_associations` ( + `item_id` int(10) NOT NULL DEFAULT 0 COMMENT 'Extension table id value', + `stage_id` int(10) NOT NULL COMMENT 'Foreign Key to #__workflow_stages.id', + `extension` varchar(50) NOT NULL, + PRIMARY KEY (`item_id`, `stage_id`, `extension`), + KEY `idx_item_id` (`item_id`), + KEY `idx_stage_id` (`stage_id`), + KEY `idx_extension` (`extension`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +-- +-- Table structure for table `#__workflow_stages` +-- + +CREATE TABLE IF NOT EXISTS `#__workflow_stages` ( + `id` int(10) NOT NULL AUTO_INCREMENT, + `asset_id` int(10) DEFAULT 0, + `ordering` int(11) NOT NULL DEFAULT 0, + `workflow_id` int(10) NOT NULL, + `published` tinyint(1) NOT NULL DEFAULT 0, + `title` varchar(255) NOT NULL, + `description` text NOT NULL, + `condition` int(10) DEFAULT 0, + `default` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + KEY `idx_workflow_id` (`workflow_id`), + KEY `idx_title` (`title`(191)), + KEY `idx_asset_id` (`asset_id`), + KEY `idx_default` (`default`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +-- +-- Dumping data for table `#__workflow_stages` +-- + +INSERT INTO `#__workflow_stages` (`id`, `asset_id`, `ordering`, `workflow_id`, `published`, `title`, `description`, `condition`, `default`) VALUES +(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 0, 0), +(2, 0, 2, 1, 1, 'JPUBLISHED', '', 1, 1), +(3, 0, 3, 1, 1, 'JTRASHED', '', -2, 0), +(4, 0, 4, 1, 1, 'JARCHIVED', '', 2, 0); + +-- +-- Table structure for table `#__workflow_transitions` +-- + +CREATE TABLE IF NOT EXISTS `#__workflow_transitions` ( + `id` int(10) NOT NULL AUTO_INCREMENT, + `asset_id` int(10) DEFAULT 0, + `ordering` int(11) NOT NULL DEFAULT 0, + `workflow_id` int(10) NOT NULL, + `published` tinyint(1) NOT NULL DEFAULT 0, + `title` varchar(255) NOT NULL, + `description` text NOT NULL, + `from_stage_id` int(10) NOT NULL, + `to_stage_id` int(10) NOT NULL, + PRIMARY KEY (`id`), + KEY `idx_title` (`title`(191)), + KEY `idx_asset_id` (`asset_id`), + KEY `idx_from_stage_id` (`from_stage_id`), + KEY `idx_to_stage_id` (`to_stage_id`), + KEY `idx_workflow_id` (`workflow_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +-- +-- Dumping data for table `#__workflow_transitions` +-- + +INSERT INTO `#__workflow_transitions` (`id`, `asset_id`, `published`, `ordering`, `workflow_id`, `title`, `description`, `from_stage_id`, `to_stage_id`) VALUES +(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1), +(2, 0, 1, 2, 1, 'Publish', '', -1, 2), +(3, 0, 1, 3, 1, 'Trash', '', -1, 3), +(4, 0, 1, 4, 1, 'Archive', '', -1, 4); + +-- +-- Creating extension entry +-- + +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`, `namespace`) VALUES +(35, 0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0, 'Joomla\\Component\\Workflow'); + +-- +-- Creating Associations for existing content +-- +INSERT INTO `#__workflow_associations` (`item_id`, `stage_id`, `extension`) +SELECT `id`, CASE WHEN `state` = -2 THEN 3 WHEN `state` = 0 THEN 1 WHEN `state` = 2 THEN 4 ELSE 2 END, 'com_content' FROM `#__content`; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-03.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-03.sql new file mode 100644 index 0000000000000..04332e563ba47 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-03.sql @@ -0,0 +1,18 @@ +-- +-- Table structure for table `#__csp` +-- + +CREATE TABLE IF NOT EXISTS `#__csp` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `document_uri` varchar(500) NOT NULL DEFAULT '', + `blocked_uri` varchar(500) NOT NULL DEFAULT '', + `directive` varchar(500) NOT NULL DEFAULT '', + `client` varchar(500) NOT NULL DEFAULT '', + `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `published` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci; + +INSERT INTO `#__extensions` (`extension_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`, `namespace`) VALUES +(35, 'com_csp', 'component', 'com_csp', '', 0, 0, 1, 0, '', '{}', 0, '0000-00-00 00:00:00', 0, 0, 'Joomla\\Component\\Csp'); diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-06.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-06.sql new file mode 100644 index 0000000000000..222b11d060977 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-06.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS `#__finder_logging` ( + `searchterm` VARCHAR(255) NOT NULL DEFAULT '', + `md5sum` VARCHAR(32) NOT NULL DEFAULT '', + `query` BLOB NOT NULL, + `hits` INT(11) NOT NULL DEFAULT '1', + `results` INT(11) NOT NULL DEFAULT '0', + PRIMARY KEY `md5sum` (`md5sum`), + INDEX `searchterm` (`searchterm`(191)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-11.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-11.sql new file mode 100644 index 0000000000000..f29eb4df240ce --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-11.sql @@ -0,0 +1,4 @@ +INSERT INTO `#__extensions` +(`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `checked_out`, `checked_out_time`, `ordering`, `state`) +VALUES + (488, 0, 'plg_sampledata_multilang', 'plugin', 'multilang', 'sampledata', 0, 0, 1, 0, '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-26.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-26.sql new file mode 100644 index 0000000000000..b73da8fd482c4 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-06-26.sql @@ -0,0 +1 @@ +ALTER TABLE `#__user_notes` CHANGE `modified_user_id` `modified_user_id` int(10) unsigned NOT NULL DEFAULT 0; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-07-02.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-07-02.sql new file mode 100644 index 0000000000000..bfe42ef67760d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-07-02.sql @@ -0,0 +1 @@ +UPDATE `#__extensions` SET `protected` = 1 WHERE `name` = 'plg_extension_namespacemap'; diff --git a/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-07-09.sql b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-07-09.sql new file mode 100644 index 0000000000000..5ff17f12d00db --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/4.0.0-2018-07-09.sql @@ -0,0 +1 @@ +UPDATE `#__extensions` SET `namespace` = 'Joomla\\Module\\Multilangstatus' WHERE `name` = 'mod_multilangstatus'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.0.0.sql b/administrator/components/com_admin/sql/updates/postgresql/3.0.0.sql deleted file mode 100644 index 9a6e816e7276e..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.0.0.sql +++ /dev/null @@ -1 +0,0 @@ --- Placeholder file for database changes for version 3.0.0 \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.0.1.sql b/administrator/components/com_admin/sql/updates/postgresql/3.0.1.sql deleted file mode 100644 index c9f8fdaa6ed4b..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.0.1.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.0.1 \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.0.2.sql b/administrator/components/com_admin/sql/updates/postgresql/3.0.2.sql deleted file mode 100644 index df708fc2fcea7..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.0.2.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.0.2 \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.0.3.sql b/administrator/components/com_admin/sql/updates/postgresql/3.0.3.sql deleted file mode 100644 index a20a8364b69a9..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.0.3.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "#__associations" ALTER COLUMN id TYPE integer; 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 deleted file mode 100644 index 1893538b9d3b9..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.1.0.sql +++ /dev/null @@ -1,196 +0,0 @@ -/* 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 ''; - -/* Tags database schema */ - --- --- Table: #__content_types --- -CREATE TABLE "#__content_types" ( - "type_id" serial NOT NULL, - "type_title" character varying(255) NOT NULL DEFAULT '', - "type_alias" character varying(255) NOT NULL DEFAULT '', - "table" character varying(255) NOT NULL DEFAULT '', - "rules" text NOT NULL, - "field_mappings" text NOT NULL, - "router" character varying(255) NOT NULL DEFAULT '', - PRIMARY KEY ("type_id") -); -CREATE INDEX "#__content_types_idx_alias" ON "#__content_types" ("type_alias"); - --- --- Dumping data for table #__content_types --- -INSERT INTO "#__content_types" ("type_id", "type_title", "type_alias", "table", "rules", "field_mappings", "router") VALUES -(1, 'Article', 'com_content.article', '{"special":{"dbtable":"#__content","key":"id","type":"Content","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"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"}], "special": [{"fulltext":"fulltext"}]}','ContentHelperRoute::getArticleRoute'), -(2, 'Contact', 'com_contact.contact', '{"special":{"dbtable":"#__contact_details","key":"id","type":"Contact","prefix":"ContactTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"address", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"image", "core_urls":"webpage", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}], "special": [{"con_position":"con_position","suburb":"suburb","state":"state","country":"country","postcode":"postcode","telephone":"telephone","fax":"fax","misc":"misc","email_to":"email_to","default_con":"default_con","user_id":"user_id","mobile":"mobile","sortname1":"sortname1","sortname2":"sortname2","sortname3":"sortname3"}]}','ContactHelperRoute::getContactRoute'), -(3, 'Newsfeed', 'com_newsfeeds.newsfeed', '{"special":{"dbtable":"#__newsfeeds","key":"id","type":"Newsfeed","prefix":"NewsfeedsTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"description", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"link", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}], "special": [{"numarticles":"numarticles","cache_time":"cache_time","rtl":"rtl"}]}','NewsfeedsHelperRoute::getNewsfeedRoute'), -(4, 'User', 'com_users.user', '{"special":{"dbtable":"#__users","key":"id","type":"User","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"name","core_state":"null","core_alias":"username","core_created_time":"registerdate","core_modified_time":"lastvisitDate","core_body":"null", "core_hits":"null","core_publish_up":"null","core_publish_down":"null","access":"null", "core_params":"params", "core_featured":"null", "core_metadata":"null", "core_language":"null", "core_images":"null", "core_urls":"null", "core_version":"null", "core_ordering":"null", "core_metakey":"null", "core_metadesc":"null", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}], "special": [{}]}','UsersHelperRoute::getUserRoute'), -(5, 'Article Category', 'com_content.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}]}','ContentHelperRoute::getCategoryRoute'), -(6, 'Contact Category', 'com_contact.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}]}','ContactHelperRoute::getCategoryRoute'), -(7, 'Newsfeeds Category', 'com_newsfeeds.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}]}','NewsfeedsHelperRoute::getCategoryRoute'), -(8, 'Tag', 'com_tags.tag', '{"special":{"dbtable":"#__tags","key":"tag_id","type":"Tag","prefix":"TagsTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"urls", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path"}]}','TagsHelperRoute::getTagRoute'); - -SELECT nextval('#__content_types_type_id_seq'); -SELECT setval('#__content_types_type_id_seq', 10000, false); - --- --- Table: #__contentitem_tag_map --- -CREATE TABLE "#__contentitem_tag_map" ( - "type_alias" character varying(255) NOT NULL DEFAULT '', - "core_content_id" integer NOT NULL, - "content_item_id" integer NOT NULL, - "tag_id" integer NOT NULL, - "tag_date" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - CONSTRAINT "uc_ItemnameTagid" UNIQUE ("type_alias", "content_item_id", "tag_id") -); - -CREATE INDEX "#__contentitem_tag_map_idx_tag_type" ON "#__contentitem_tag_map" ("tag_id", "type_alias"); -CREATE INDEX "#__contentitem_tag_map_idx_date_id" ON "#__contentitem_tag_map" ("tag_date", "tag_id"); -CREATE INDEX "#__contentitem_tag_map_idx_tag" ON "#__contentitem_tag_map" ("tag_id"); -CREATE INDEX "#__contentitem_tag_map_idx_core_content_id" ON "#__contentitem_tag_map" ("core_content_id"); - -COMMENT ON COLUMN "#__contentitem_tag_map"."core_content_id" IS 'PK from the core content table'; -COMMENT ON COLUMN "#__contentitem_tag_map"."content_item_id" IS 'PK from the content type table'; -COMMENT ON COLUMN "#__contentitem_tag_map"."tag_id" IS 'PK from the tag table'; -COMMENT ON COLUMN "#__contentitem_tag_map"."tag_date" IS 'Date of most recent save for this tag-item'; - --- -------------------------------------------------------- - --- --- Table: #__tags --- -CREATE TABLE "#__tags" ( - "id" serial NOT NULL, - "parent_id" bigint DEFAULT 0 NOT NULL, - "lft" bigint DEFAULT 0 NOT NULL, - "rgt" bigint DEFAULT 0 NOT NULL, - "level" integer DEFAULT 0 NOT NULL, - "path" character varying(255) DEFAULT '' NOT NULL, - "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, - "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, - "access" bigint DEFAULT 0 NOT NULL, - "params" text NOT NULL, - "metadesc" character varying(1024) NOT NULL, - "metakey" character varying(1024) NOT NULL, - "metadata" character varying(2048) NOT NULL, - "created_user_id" integer DEFAULT 0 NOT NULL, - "created_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "created_by_alias" character varying(255) DEFAULT '' NOT NULL, - "modified_user_id" integer DEFAULT 0 NOT NULL, - "modified_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "images" text NOT NULL, - "urls" text NOT NULL, - "hits" integer DEFAULT 0 NOT NULL, - "language" character varying(7) DEFAULT '' NOT NULL, - "version" bigint DEFAULT 1 NOT NULL, - "publish_up" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "publish_down" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - PRIMARY KEY ("id") -); -CREATE INDEX "#__tags_cat_idx" ON "#__tags" ("published", "access"); -CREATE INDEX "#__tags_idx_access" ON "#__tags" ("access"); -CREATE INDEX "#__tags_idx_checkout" ON "#__tags" ("checked_out"); -CREATE INDEX "#__tags_idx_path" ON "#__tags" ("path"); -CREATE INDEX "#__tags_idx_left_right" ON "#__tags" ("lft", "rgt"); -CREATE INDEX "#__tags_idx_alias" ON "#__tags" ("alias"); -CREATE INDEX "#__tags_idx_language" ON "#__tags" ("language"); - --- --- Dumping data for table #__tags --- - -INSERT INTO "#__tags" ("id", "parent_id", "lft", "rgt", "level", "path", "title", "alias", "note", "description", "published", "checked_out", "checked_out_time", "access", "params", "metadesc", "metakey", "metadata", "created_user_id", "created_time", "created_by_alias", "modified_user_id", "modified_time", "images", "urls", "hits", "language", "version") VALUES -(1, 0, 0, 1, 0, '', 'ROOT', 'root', '', '', 1, 0, '1970-01-01 00:00:00', 1, '{}', '', '', '', 42, '1970-01-01 00:00:00', '', 0, '1970-01-01 00:00:00', '', '', 0, '*', 1); - -SELECT nextval('#__tags_id_seq'); -SELECT setval('#__tags_id_seq', 2, false); - --- --- Table: #__ucm_base --- -CREATE TABLE "#__ucm_base" ( - "ucm_id" serial NOT NULL, - "ucm_item_id" bigint NOT NULL, - "ucm_type_id" bigint NOT NULL, - "ucm_language_id" bigint NOT NULL, - PRIMARY KEY ("ucm_id") -); -CREATE INDEX "#__ucm_base_ucm_item_id" ON "#__ucm_base" ("ucm_item_id"); -CREATE INDEX "#__ucm_base_ucm_type_id" ON "#__ucm_base" ("ucm_type_id"); -CREATE INDEX "#__ucm_base_ucm_language_id" ON "#__ucm_base" ("ucm_language_id"); - --- --- Table: #__ucm_content --- -CREATE TABLE "#__ucm_content" ( - "core_content_id" serial NOT NULL, - "core_type_alias" character varying(255) DEFAULT '' NOT NULL, - "core_title" character varying(255) NOT NULL, - "core_alias" character varying(255) DEFAULT '' NOT NULL, - "core_body" text NOT NULL, - "core_state" smallint DEFAULT 0 NOT NULL, - "core_checked_out_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "core_checked_out_user_id" bigint DEFAULT 0 NOT NULL, - "core_access" bigint DEFAULT 0 NOT NULL, - "core_params" text NOT NULL, - "core_featured" smallint DEFAULT 0 NOT NULL, - "core_metadata" text NOT NULL, - "core_created_user_id" bigint DEFAULT 0 NOT NULL, - "core_created_by_alias" character varying(255) DEFAULT '' NOT NULL, - "core_created_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "core_modified_user_id" bigint DEFAULT 0 NOT NULL, - "core_modified_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "core_language" character varying(7) DEFAULT '' NOT NULL, - "core_publish_up" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "core_publish_down" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "core_content_item_id" bigint DEFAULT 0 NOT NULL, - "asset_id" bigint DEFAULT 0 NOT NULL, - "core_images" text NOT NULL, - "core_urls" text NOT NULL, - "core_hits" bigint DEFAULT 0 NOT NULL, - "core_version" bigint DEFAULT 1 NOT NULL, - "core_ordering" bigint DEFAULT 0 NOT NULL, - "core_metakey" text NOT NULL, - "core_metadesc" text NOT NULL, - "core_catid" bigint DEFAULT 0 NOT NULL, - "core_xreference" character varying(50) DEFAULT '' NOT NULL, - "core_type_id" bigint DEFAULT 0 NOT NULL, - PRIMARY KEY ("core_content_id"), - CONSTRAINT "#__ucm_content_idx_type_alias_item_id" UNIQUE ("core_type_alias", "core_content_item_id") -); -CREATE INDEX "#__ucm_content_tag_idx" ON "#__ucm_content" ("core_state", "core_access"); -CREATE INDEX "#__ucm_content_idx_access" ON "#__ucm_content" ("core_access"); -CREATE INDEX "#__ucm_content_idx_alias" ON "#__ucm_content" ("core_alias"); -CREATE INDEX "#__ucm_content_idx_language" ON "#__ucm_content" ("core_language"); -CREATE INDEX "#__ucm_content_idx_title" ON "#__ucm_content" ("core_title"); -CREATE INDEX "#__ucm_content_idx_modified_time" ON "#__ucm_content" ("core_modified_time"); -CREATE INDEX "#__ucm_content_idx_created_time" ON "#__ucm_content" ("core_created_time"); -CREATE INDEX "#__ucm_content_idx_content_type" ON "#__ucm_content" ("core_type_alias"); -CREATE INDEX "#__ucm_content_idx_core_modified_user_id" ON "#__ucm_content" ("core_modified_user_id"); -CREATE INDEX "#__ucm_content_idx_core_checked_out_user_id" ON "#__ucm_content" ("core_checked_out_user_id"); -CREATE INDEX "#__ucm_content_idx_core_created_user_id" ON "#__ucm_content" ("core_created_user_id"); -CREATE INDEX "#__ucm_content_idx_core_type_id" ON "#__ucm_content" ("core_type_id"); - --- --- 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 - 2018 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 - 2018 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 - 2018 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 - 2018 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 - 2018 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); - --- --- Add menu table records --- -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, '1970-01-01 00:00:00', 0, 1, 'class:tags', 0, '', 45, 46, 0, '', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.1.1.sql b/administrator/components/com_admin/sql/updates/postgresql/3.1.1.sql deleted file mode 100644 index df442faa0ef8d..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.1.1.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.1.1 \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.1.2.sql b/administrator/components/com_admin/sql/updates/postgresql/3.1.2.sql deleted file mode 100644 index 3ce0eac3e8868..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.1.2.sql +++ /dev/null @@ -1,16 +0,0 @@ -UPDATE "#__content_types" SET "table" = '{"special":{"dbtable":"#__content","key":"id","type":"Content","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE "type_title" = 'Article'; -UPDATE "#__content_types" SET "table" = '{"special":{"dbtable":"#__contact_details","key":"id","type":"Contact","prefix":"ContactTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE "type_title" = 'Contact'; -UPDATE "#__content_types" SET "table" = '{"special":{"dbtable":"#__newsfeeds","key":"id","type":"Newsfeed","prefix":"NewsfeedsTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE "type_title" = 'Newsfeed'; -UPDATE "#__content_types" SET "table" = '{"special":{"dbtable":"#__users","key":"id","type":"User","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE "type_title" = 'User'; -UPDATE "#__content_types" SET "table" = '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE "type_title" = 'Article Category'; -UPDATE "#__content_types" SET "table" = '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE "type_title" = 'Contact Category'; -UPDATE "#__content_types" SET "table" = '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE "type_title" = 'Newsfeeds Category'; -UPDATE "#__content_types" SET "table" = '{"special":{"dbtable":"#__tags","key":"tag_id","type":"Tag","prefix":"TagsTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE "type_title" = 'Tag'; -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"}, "special": {"fulltext":"fulltext"}}' WHERE "type_title" = 'Article'; -UPDATE "#__content_types" SET "field_mappings" = '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"address", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"image", "core_urls":"webpage", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}, "special": {"con_position":"con_position","suburb":"suburb","state":"state","country":"country","postcode":"postcode","telephone":"telephone","fax":"fax","misc":"misc","email_to":"email_to","default_con":"default_con","user_id":"user_id","mobile":"mobile","sortname1":"sortname1","sortname2":"sortname2","sortname3":"sortname3"}}' WHERE "type_title" = 'Contact'; -UPDATE "#__content_types" SET "field_mappings" = '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"description", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"link", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}, "special": {"numarticles":"numarticles","cache_time":"cache_time","rtl":"rtl"}}' WHERE "type_title" = 'Newsfeed'; -UPDATE "#__content_types" SET "field_mappings" = '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"null","core_alias":"username","core_created_time":"registerdate","core_modified_time":"lastvisitDate","core_body":"null", "core_hits":"null","core_publish_up":"null","core_publish_down":"null","access":"null", "core_params":"params", "core_featured":"null", "core_metadata":"null", "core_language":"null", "core_images":"null", "core_urls":"null", "core_version":"null", "core_ordering":"null", "core_metakey":"null", "core_metadesc":"null", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}, "special": {}}' WHERE "type_title" = 'User'; -UPDATE "#__content_types" SET "field_mappings" = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}' WHERE "type_title" = 'Article Category'; -UPDATE "#__content_types" SET "field_mappings" = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}' WHERE "type_title" = 'Contact Category'; -UPDATE "#__content_types" SET "field_mappings" = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}' WHERE "type_title" = 'Newsfeeds Category'; -UPDATE "#__content_types" SET "field_mappings" = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"urls", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path"}}' WHERE "type_title" = 'Tag'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.1.3.sql b/administrator/components/com_admin/sql/updates/postgresql/3.1.3.sql deleted file mode 100644 index ebc1102eb1eeb..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.1.3.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.1.3 diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.1.4.sql b/administrator/components/com_admin/sql/updates/postgresql/3.1.4.sql deleted file mode 100644 index 6014cdba5aa0c..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.1.4.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(104, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.1.5.sql b/administrator/components/com_admin/sql/updates/postgresql/3.1.5.sql deleted file mode 100644 index 2c9caba74fc12..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.1.5.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.1.5 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 deleted file mode 100644 index bc22cf3698af2..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.0.sql +++ /dev/null @@ -1,121 +0,0 @@ -/* Core 3.2 schema updates */ - -ALTER TABLE "#__content_types" ADD COLUMN "content_history_options" varchar(5120) DEFAULT NULL; - -UPDATE "#__content_types" SET "content_history_options" = '{"formFile":"administrator\\/components\\/com_content\\/models\\/forms\\/article.xml", "hideFields":["asset_id","checked_out","checked_out_time","version"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "hits"],"convertToInt":["publish_up", "publish_down", "featured", "ordering"],"displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"} ]}' WHERE "type_alias" = 'com_content.article'; -UPDATE "#__content_types" SET "content_history_options" = '{"formFile":"administrator\\/components\\/com_contact\\/models\\/forms\\/contact.xml","hideFields":["default_con","checked_out","checked_out_time","version","xreference"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "hits"],"convertToInt":["publish_up", "publish_down", "featured", "ordering"], "displayLookup":[ {"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"} ] }' WHERE "type_alias" = 'com_contact.contact'; -UPDATE "#__content_types" SET "content_history_options" = '{"formFile":"administrator\\/components\\/com_categories\\/models\\/forms\\/category.xml", "hideFields":["asset_id","checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"],"convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"parent_id","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}]}' WHERE "type_alias" IN ('com_content.category', 'com_contact.category', 'com_newsfeeds.category'); -UPDATE "#__content_types" SET "content_history_options" = '{"formFile":"administrator\\/components\\/com_newsfeeds\\/models\\/forms\\/newsfeed.xml","hideFields":["asset_id","checked_out","checked_out_time","version"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "hits"],"convertToInt":["publish_up", "publish_down", "featured", "ordering"],"displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}' WHERE "type_alias" = 'com_newsfeeds.newsfeed'; -UPDATE "#__content_types" SET "content_history_options" = '{"formFile":"administrator\\/components\\/com_tags\\/models\\/forms\\/tag.xml", "hideFields":["checked_out","checked_out_time","version", "lft", "rgt", "level", "path", "urls", "publish_up", "publish_down"],"ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"],"convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"}, {"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}' WHERE "type_alias" = 'com_tags.tag'; - -INSERT INTO "#__content_types" ("type_title", "type_alias", "table", "rules", "field_mappings", "router", "content_history_options") VALUES -('Banner', 'com_banners.banner', '{"special":{"dbtable":"#__banners","key":"id","type":"Banner","prefix":"BannersTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"description", "core_hits":"null","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"link", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"null", "asset_id":"null"}, "special":{"imptotal":"imptotal", "impmade":"impmade", "clicks":"clicks", "clickurl":"clickurl", "custombannercode":"custombannercode", "cid":"cid", "purchase_type":"purchase_type", "track_impressions":"track_impressions", "track_clicks":"track_clicks"}}', '', '{"formFile":"administrator\\/components\\/com_banners\\/models\\/forms\\/banner.xml", "hideFields":["checked_out","checked_out_time","version", "reset"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "imptotal", "impmade", "reset"], "convertToInt":["publish_up", "publish_down", "ordering"], "displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}, {"sourceColumn":"cid","targetTable":"#__banner_clients","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}'), -('Banners Category', 'com_banners.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}', '', '{"formFile":"administrator\\/components\\/com_categories\\/models\\/forms\\/category.xml", "hideFields":["asset_id","checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"], "convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"parent_id","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}]}'), -('Banner Client', 'com_banners.client', '{"special":{"dbtable":"#__banner_clients","key":"id","type":"Client","prefix":"BannersTable"}}', '', '', '', '{"formFile":"administrator\\/components\\/com_banners\\/models\\/forms\\/client.xml", "hideFields":["checked_out","checked_out_time"], "ignoreChanges":["checked_out", "checked_out_time"], "convertToInt":[], "displayLookup":[]}'), -('User Notes', 'com_users.note', '{"special":{"dbtable":"#__user_notes","key":"id","type":"Note","prefix":"UsersTable"}}', '', '', '', '{"formFile":"administrator\\/components\\/com_users\\/models\\/forms\\/note.xml", "hideFields":["checked_out","checked_out_time", "publish_up", "publish_down"],"ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time"], "convertToInt":["publish_up", "publish_down"],"displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}, {"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}'), -('User Notes Category', 'com_users.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special":{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}', '', '{"formFile":"administrator\\/components\\/com_categories\\/models\\/forms\\/category.xml", "hideFields":["checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"], "convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"parent_id","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}]}'); - -UPDATE "#__extensions" SET "params" = '{"template_positions_display":"0","upload_limit":"2","image_formats":"gif,bmp,jpg,jpeg,png","source_formats":"txt,less,ini,xml,js,php,css","font_formats":"woff,ttf,otf","compressed_formats":"zip"}' WHERE "extension_id" = 20; -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 - 2018 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 - 2018 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), -(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 - 2018 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 - 2018 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 - 2018 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); - -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); - -ALTER TABLE "#__modules" ADD COLUMN "asset_id" bigint DEFAULT 0 NOT NULL; - -CREATE TABLE "#__postinstall_messages" ( - "postinstall_message_id" serial NOT NULL, - "extension_id" bigint NOT NULL DEFAULT 700, - "title_key" varchar(255) NOT NULL DEFAULT '', - "description_key" varchar(255) NOT NULL DEFAULT '', - "action_key" varchar(255) NOT NULL DEFAULT '', - "language_extension" varchar(255) NOT NULL DEFAULT 'com_postinstall', - "language_client_id" smallint NOT NULL DEFAULT 1, - "type" varchar(10) NOT NULL DEFAULT 'link', - "action_file" varchar(255) DEFAULT '', - "action" varchar(255) DEFAULT '', - "condition_file" varchar(255) DEFAULT NULL, - "condition_method" varchar(255) DEFAULT NULL, - "version_introduced" varchar(255) NOT NULL DEFAULT '3.2.0', - "enabled" smallint NOT NULL DEFAULT 1, - PRIMARY KEY ("postinstall_message_id") -); - -COMMENT ON COLUMN "#__postinstall_messages"."extension_id" IS 'FK to jos_extensions'; -COMMENT ON COLUMN "#__postinstall_messages"."title_key" IS 'Lang key for the title'; -COMMENT ON COLUMN "#__postinstall_messages"."description_key" IS 'Lang key for description'; -COMMENT ON COLUMN "#__postinstall_messages"."language_extension" IS 'Extension holding lang keys'; -COMMENT ON COLUMN "#__postinstall_messages"."type" IS 'Message type - message, link, action'; -COMMENT ON COLUMN "#__postinstall_messages"."action_file" IS 'RAD URI to the PHP file containing action method'; -COMMENT ON COLUMN "#__postinstall_messages"."action" IS 'Action method name or URL'; -COMMENT ON COLUMN "#__postinstall_messages"."condition_file" IS 'RAD URI to file holding display condition method'; -COMMENT ON COLUMN "#__postinstall_messages"."condition_method" IS 'Display condition method, must return boolean'; -COMMENT ON COLUMN "#__postinstall_messages"."version_introduced" IS 'Version when this message was introduced'; - -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_TWOFACTORAUTH_TOTP_POSTINSTALL_TITLE', 'PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_BODY', 'PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_ACTION', 'plg_twofactorauth_totp', 1, 'action', 'site://plugins/twofactorauth/totp/postinstall/actions.php', 'twofactorauth_postinstall_action', 'site://plugins/twofactorauth/totp/postinstall/actions.php', 'twofactorauth_postinstall_condition', '3.2.0', 1), -(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 "#__ucm_history" ( - "version_id" serial NOT NULL, - "ucm_item_id" integer NOT NULL, - "ucm_type_id" integer NOT NULL, - "version_note" varchar(255) NOT NULL DEFAULT '', - "save_date" timestamp with time zone NOT NULL DEFAULT '1970-01-01 00:00:00', - "editor_user_id" integer NOT NULL DEFAULT 0, - "character_count" integer NOT NULL DEFAULT 0, - "sha1_hash" varchar(50) NOT NULL DEFAULT '', - "version_data" text NOT NULL, - "keep_forever" smallint NOT NULL DEFAULT 0, - PRIMARY KEY ("version_id") -); -CREATE INDEX "#__ucm_history_idx_ucm_item_id" ON "#__ucm_history" ("ucm_type_id", "ucm_item_id"); -CREATE INDEX "#__ucm_history_idx_save_date" ON "#__ucm_history" ("save_date"); - -COMMENT ON COLUMN "#__ucm_history"."version_note" IS 'Optional version name'; -COMMENT ON COLUMN "#__ucm_history"."character_count" IS 'Number of characters in this version.'; -COMMENT ON COLUMN "#__ucm_history"."sha1_hash" IS 'SHA1 hash of the version_data column.'; -COMMENT ON COLUMN "#__ucm_history"."version_data" IS 'json-encoded string of version data'; -COMMENT ON COLUMN "#__ucm_history"."keep_forever" IS '0=auto delete; 1=keep'; - -ALTER TABLE "#__users" ADD COLUMN "otpKey" varchar(1000) DEFAULT '' NOT NULL; -ALTER TABLE "#__users" ADD COLUMN "otep" varchar(1000) DEFAULT '' NOT NULL; - -CREATE TABLE "#__user_keys" ( - "id" serial NOT NULL, - "user_id" varchar(255) NOT NULL, - "token" varchar(255) NOT NULL, - "series" varchar(255) NOT NULL, - "invalid" smallint NOT NULL, - "time" varchar(200) NOT NULL, - "uastring" varchar(255) NOT NULL, - PRIMARY KEY ("id"), - CONSTRAINT "#__user_keys_series" UNIQUE ("series"), - CONSTRAINT "#__user_keys_series_2" UNIQUE ("series"), - CONSTRAINT "#__user_keys_series_3" UNIQUE ("series") -); -CREATE INDEX "#__user_keys_idx_user_id" ON "#__user_keys" ("user_id"); - -/* Queries below sync the schema to MySQL where able without causing errors */ - -ALTER TABLE "#__contentitem_tag_map" ADD COLUMN "type_id" integer NOT NULL; - -CREATE INDEX "#__contentitem_tag_map_idx_tag_type" ON "#__contentitem_tag_map" ("tag_id", "type_id"); -CREATE INDEX "#__contentitem_tag_map_idx_type" ON "#__contentitem_tag_map" ("type_id"); - -COMMENT ON COLUMN "#__contentitem_tag_map"."type_id" IS 'PK from the content_type table'; - -ALTER TABLE "#__session" DROP COLUMN "usertype"; - -ALTER TABLE "#__updates" DROP COLUMN "categoryid"; - -ALTER TABLE "#__users" DROP COLUMN "usertype"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.1.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.1.sql deleted file mode 100644 index d74876dad9b91..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.1.sql +++ /dev/null @@ -1 +0,0 @@ -DELETE FROM "#__postinstall_messages" WHERE "title_key" = 'PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_TITLE'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2013-12-22.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2013-12-22.sql deleted file mode 100644 index 38df3ba7328b2..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2013-12-22.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "#__update_sites" ADD COLUMN "extra_query" varchar(1000) DEFAULT ''; -ALTER TABLE "#__updates" ADD COLUMN "extra_query" varchar(1000) DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2013-12-28.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2013-12-28.sql deleted file mode 100644 index 0ea89b8ea1344..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2013-12-28.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE "#__menu" SET "component_id" = (SELECT "extension_id" FROM "#__extensions" WHERE "element" = 'com_joomlaupdate') WHERE "link" = 'index.php?option=com_joomlaupdate'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-08.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-08.sql deleted file mode 100644 index bcd3f697169e6..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-08.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(403, 'plg_content_contact', 'plugin', 'contact', 'content', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 1, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-15.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-15.sql deleted file mode 100644 index 023e460279712..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-15.sql +++ /dev/null @@ -1,2 +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, 'COM_CPANEL_MSG_PHPVERSION_TITLE', 'COM_CPANEL_MSG_PHPVERSION_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/phpversion.php', 'admin_postinstall_phpversion_condition', '3.2.2', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-18.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-18.sql deleted file mode 100644 index 6b34d648e7e78..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-18.sql +++ /dev/null @@ -1,2 +0,0 @@ -/* Update updates version length */ -ALTER TABLE "#__updates" ALTER COLUMN "version" TYPE character varying(32); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-23.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-23.sql deleted file mode 100644 index 6b506f25687b1..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.2-2014-01-23.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(106, 'PHPass', 'library', 'phpass', '', 0, 1, 1, 1, '{"legacy":false,"name":"PHPass","type":"library","creationDate":"2004-2006","author":"Solar Designer","authorEmail":"solar@openwall.com","authorUrl":"http:\/\/www.openwall.com/phpass","version":"0.3","description":"LIB_PHPASS_XML_DESCRIPTION","group":""}', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.3-2014-02-20.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.3-2014-02-20.sql deleted file mode 100644 index 9f69a3f91e358..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.2.3-2014-02-20.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE "#__extensions" SET "params" = (SELECT "params" FROM "#__extensions" WHERE "name" = 'plg_system_remember') WHERE "name" = 'plg_authentication_cookie'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2013-12-21.sql b/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2013-12-21.sql deleted file mode 100644 index 7c9f774db1aa9..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2013-12-21.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file to set the database schema for 3.3.0 diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2014-02-16.sql b/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2014-02-16.sql deleted file mode 100644 index 01dca6beeb049..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2014-02-16.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "#__users" ADD COLUMN "requireReset" smallint DEFAULT 0; -COMMENT ON COLUMN "#__users"."requireReset" IS 'Require user to reset password on next login'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2014-04-02.sql b/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2014-04-02.sql deleted file mode 100644 index 328dd673ae676..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.3.0-2014-04-02.sql +++ /dev/null @@ -1,3 +0,0 @@ -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 -(451, 'plg_search_tags', 'plugin', 'tags', 'search', 0, 0, 1, 0, '', '{"search_limit":"50","show_tagged_items":"1"}', '', '', 0, '1970-01-01 00:00:00', 0, 0); - diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.3.4-2014-08-03.sql b/administrator/components/com_admin/sql/updates/postgresql/3.3.4-2014-08-03.sql deleted file mode 100644 index f803f5fefbfbe..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.3.4-2014-08-03.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "#__user_profiles" ALTER COLUMN "profile_value" TYPE text; 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 deleted file mode 100644 index d54a13381e721..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.3.6-2014-09-30.sql +++ /dev/null @@ -1,5 +0,0 @@ -INSERT INTO "#__update_sites" ("name", "type", "location", "enabled") VALUES -('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.4.0-2014-08-24.sql b/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-08-24.sql deleted file mode 100644 index 77e6bd8a37cf5..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-08-24.sql +++ /dev/null @@ -1,2 +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, 'COM_CPANEL_MSG_HTACCESS_TITLE', 'COM_CPANEL_MSG_HTACCESS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/htaccess.php', 'admin_postinstall_htaccess_condition', '3.4.0', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-09-01.sql b/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-09-01.sql deleted file mode 100644 index e55d2206bb2c8..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-09-01.sql +++ /dev/null @@ -1,8 +0,0 @@ -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 -(801, 'weblinks', 'package', 'pkg_weblinks', '', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); - -INSERT INTO "#__update_sites" ("name", "type", "location", "enabled") VALUES -('Weblinks Update Site', 'extension', 'https://raw.githubusercontent.com/joomla-extensions/weblinks/master/manifest.xml', 1); - -INSERT INTO "#__update_sites_extensions" ("update_site_id", "extension_id") VALUES -((SELECT "update_site_id" FROM "#__update_sites" WHERE "name" = 'Weblinks Update Site'), 801); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-09-16.sql b/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-09-16.sql deleted file mode 100644 index 0419468e8bb46..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-09-16.sql +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE "#__redirect_links" ADD COLUMN "header" INTEGER DEFAULT 301 NOT NULL; --- --- 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 --- --- ALTER TABLE "#__redirect_links" ALTER COLUMN "new_url" DROP NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-10-20.sql b/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-10-20.sql deleted file mode 100644 index 3f63a4b186670..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-10-20.sql +++ /dev/null @@ -1 +0,0 @@ -DELETE FROM "#__extensions" WHERE "extension_id" = 100; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-12-03.sql b/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-12-03.sql deleted file mode 100644 index dca06cc1242be..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2014-12-03.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE "#__extensions" SET "protected" = '0' WHERE "name" = 'plg_editors-xtd_article' AND "type" = 'plugin' AND "element" = 'article' AND "folder" = 'editors-xtd'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2015-01-21.sql b/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2015-01-21.sql deleted file mode 100644 index 1e855e0c7b364..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2015-01-21.sql +++ /dev/null @@ -1,2 +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, 'COM_CPANEL_MSG_ROBOTS_TITLE', 'COM_CPANEL_MSG_ROBOTS_BODY', '', 'com_cpanel', 1, 'message', '', '', '', '', '3.3.0', 1); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2015-02-26.sql b/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2015-02-26.sql deleted file mode 100644 index 5ec99c96ed3c8..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.4.0-2015-02-26.sql +++ /dev/null @@ -1,2 +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, 'COM_CPANEL_MSG_LANGUAGEACCESS340_TITLE', 'COM_CPANEL_MSG_LANGUAGEACCESS340_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/languageaccess340.php', 'admin_postinstall_languageaccess340_condition', '3.4.1', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.4.4-2015-07-11.sql b/administrator/components/com_admin/sql/updates/postgresql/3.4.4-2015-07-11.sql deleted file mode 100644 index fd15f849e41a5..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.4.4-2015-07-11.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "#__contentitem_tag_map" DROP CONSTRAINT "#__uc_ItemnameTagid", ADD CONSTRAINT "#__uc_ItemnameTagid" UNIQUE ("type_id", "content_item_id", "tag_id"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-13.sql b/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-13.sql deleted file mode 100644 index 7300198d443a7..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-13.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(453, 'plg_editors-xtd_module', 'plugin', 'module', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-26.sql b/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-26.sql deleted file mode 100644 index 05080ce112570..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-26.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP INDEX "#__contentitem_tag_map_idx_tag"; -DROP INDEX "#__contentitem_tag_map_idx_type"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-30.sql b/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-30.sql deleted file mode 100644 index ae4b418e3b138..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-10-30.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE "#__menu" SET "title" = 'com_contact_contacts' WHERE "client_id" = 1 AND "level" = 2 AND "title" = 'com_contact'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-11-04.sql b/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-11-04.sql deleted file mode 100644 index 492e6a06219fd..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-11-04.sql +++ /dev/null @@ -1,4 +0,0 @@ -DELETE FROM "#__menu" WHERE "title" = 'com_messages_read' AND "client_id" = 1; - -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 -(452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-11-05.sql b/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-11-05.sql deleted file mode 100644 index e099d77e49c1d..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2015-11-05.sql +++ /dev/null @@ -1,5 +0,0 @@ -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 -(454, 'plg_system_stats', 'plugin', 'stats', '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, 'COM_CPANEL_MSG_STATS_COLLECTION_TITLE', 'COM_CPANEL_MSG_STATS_COLLECTION_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/statscollection.php', 'admin_postinstall_statscollection_condition', '3.5.0', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2016-03-01.sql b/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2016-03-01.sql deleted file mode 100644 index 804efa3edd1dc..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.5.0-2016-03-01.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE "#__redirect_links" DROP CONSTRAINT "#__redirect_links_idx_link_old"; -ALTER TABLE "#__redirect_links" ALTER COLUMN "old_url" TYPE character varying(2048); -ALTER TABLE "#__redirect_links" ALTER COLUMN "new_url" TYPE character varying(2048); -ALTER TABLE "#__redirect_links" ALTER COLUMN "referer" TYPE character varying(2048); -CREATE INDEX "#__idx_link_old" ON "#__redirect_links" ("old_url"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-01.sql b/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-01.sql deleted file mode 100644 index 50d35bbd85db7..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-01.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Rename update site names -UPDATE "#__update_sites" SET "name" = 'Joomla! Core' WHERE "name" = 'Joomla Core' AND "type" = 'collection'; -UPDATE "#__update_sites" SET "name" = 'Joomla! Extension Directory' WHERE "name" = 'Joomla Extension Directory' AND "type" = 'collection'; - -UPDATE "#__update_sites" SET "location" = 'https://update.joomla.org/core/list.xml' WHERE "name" = 'Joomla! Core' AND "type" = 'collection'; -UPDATE "#__update_sites" SET "location" = 'https://update.joomla.org/jed/list.xml' WHERE "name" = 'Joomla! Extension Directory' AND "type" = 'collection'; -UPDATE "#__update_sites" SET "location" = 'https://update.joomla.org/language/translationlist_3.xml' WHERE "name" = 'Accredited Joomla! Translations' AND "type" = 'collection'; -UPDATE "#__update_sites" SET "location" = 'https://update.joomla.org/core/extensions/com_joomlaupdate.xml' WHERE "name" = 'Joomla! Update Component Update Site' AND "type" = 'extension'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-08.sql b/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-08.sql deleted file mode 100644 index a9b1bfea2652f..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-08.sql +++ /dev/null @@ -1,12 +0,0 @@ -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 -(802, 'English (United Kingdom)', 'package', 'pkg_en-GB', '', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); - -UPDATE "#__update_sites_extensions" -SET "extension_id" = 802 -WHERE "update_site_id" IN ( - SELECT "update_site_id" - FROM "#__update_sites" - WHERE "name" = 'Accredited Joomla! Translations' - AND "type" = 'collection' - ) -AND "extension_id" = 600; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-09.sql b/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-09.sql deleted file mode 100644 index 31b785b059d73..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-04-09.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- Add ACL check for to #__menu_types --- - -ALTER TABLE "#__menu_types" ADD COLUMN "asset_id" bigint DEFAULT 0 NOT NULL; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-05-06.sql b/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-05-06.sql deleted file mode 100644 index 9d58322a8803b..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-05-06.sql +++ /dev/null @@ -1,6 +0,0 @@ -DELETE FROM "#__extensions" WHERE "type" = 'library' AND "element" = 'simplepie'; - -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 -(455, 'plg_installer_packageinstaller', 'plugin', 'packageinstaller', 'installer', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 1, 0), -(456, 'plg_installer_folderinstaller', 'plugin', 'folderinstaller', 'installer', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 2, 0), -(457, 'plg_installer_urlinstaller', 'plugin', 'urlinstaller', 'installer', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 3, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-06-01.sql b/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-06-01.sql deleted file mode 100644 index a8c3f145ab347..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-06-01.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE "#__extensions" SET "protected" = 1, "enabled" = 1 WHERE "name" = 'com_ajax'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-06-05.sql b/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-06-05.sql deleted file mode 100644 index 3d4aac89763e6..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.0-2016-06-05.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- Add ACL check for to #__languages --- - -ALTER TABLE "#__languages" ADD COLUMN "asset_id" bigint DEFAULT 0 NOT NULL; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-08-15.sql b/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-08-15.sql deleted file mode 100644 index 6ece41aed6f3a..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-08-15.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- Increasing size of the URL field in com_newsfeeds --- - -ALTER TABLE "#__newsfeeds" ALTER COLUMN "link" TYPE character varying(2048); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-08-16.sql b/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-08-16.sql deleted file mode 100644 index 2fd8013e07427..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-08-16.sql +++ /dev/null @@ -1,2 +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_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_BODY', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_ACTION', 'plg_system_updatenotification', 1, 'action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_condition', '3.6.3', 1); \ No newline at end of file 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 deleted file mode 100644 index 5a4262f94e7a1..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.6.3-2016-10-04.sql +++ /dev/null @@ -1,3 +0,0 @@ -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; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-06.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-06.sql deleted file mode 100644 index 9d4e415850218..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-06.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(458, 'plg_quickicon_phpversioncheck', 'plugin', 'phpversioncheck', 'quickicon', 0, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-22.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-22.sql deleted file mode 100644 index 2f3349e752c58..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-22.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(459, 'plg_editors-xtd_menu', 'plugin', 'menu', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); 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 deleted file mode 100644 index 1676d972db1fa..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-08-29.sql +++ /dev/null @@ -1,105 +0,0 @@ --- --- Table: #__fields --- -CREATE TABLE "#__fields" ( - "id" serial NOT NULL, - "asset_id" bigint DEFAULT 0 NOT NULL, - "context" varchar(255) DEFAULT '' NOT NULL, - "group_id" bigint DEFAULT 0 NOT NULL, - "title" varchar(255) DEFAULT '' NOT NULL, - "name" varchar(255) DEFAULT '' NOT NULL, - "label" varchar(255) DEFAULT '' NOT NULL, - "default_value" text DEFAULT '' NOT NULL, - "type" varchar(255) DEFAULT 'text' NOT NULL, - "note" varchar(255) DEFAULT '' NOT NULL, - "description" text DEFAULT '' NOT NULL, - "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, - "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, - "modified_time" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "modified_by" bigint DEFAULT 0 NOT NULL, - "access" bigint DEFAULT 0 NOT NULL, - PRIMARY KEY ("id") -); -CREATE INDEX "#__fields_idx_checked_out" ON "#__fields" ("checked_out"); -CREATE INDEX "#__fields_idx_state" ON "#__fields" ("state"); -CREATE INDEX "#__fields_idx_created_user_id" ON "#__fields" ("created_user_id"); -CREATE INDEX "#__fields_idx_access" ON "#__fields" ("access"); -CREATE INDEX "#__fields_idx_context" ON "#__fields" ("context"); -CREATE INDEX "#__fields_idx_language" ON "#__fields" ("language"); - --- --- Table: #__fields_categories --- -CREATE TABLE "#__fields_categories" ( - "field_id" bigint DEFAULT 0 NOT NULL, - "category_id" bigint DEFAULT 0 NOT NULL, - PRIMARY KEY ("field_id", "category_id") -); - --- --- Table: #__fields_groups --- -CREATE TABLE "#__fields_groups" ( - "id" serial NOT NULL, - "asset_id" bigint DEFAULT 0 NOT NULL, - "context" varchar(255) DEFAULT '' NOT NULL, - "title" varchar(255) DEFAULT '' NOT NULL, - "note" varchar(255) DEFAULT '' NOT NULL, - "description" text DEFAULT '' NOT NULL, - "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, - "ordering" bigint DEFAULT 0 NOT NULL, - "language" varchar(7) DEFAULT '' NOT NULL, - "created" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "created_by" bigint DEFAULT 0 NOT NULL, - "modified" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, - "modified_by" bigint DEFAULT 0 NOT NULL, - "access" bigint DEFAULT 0 NOT NULL, - PRIMARY KEY ("id") -); -CREATE INDEX "#__fields_groups_idx_checked_out" ON "#__fields_groups" ("checked_out"); -CREATE INDEX "#__fields_groups_idx_state" ON "#__fields_groups" ("state"); -CREATE INDEX "#__fields_groups_idx_created_by" ON "#__fields_groups" ("created_by"); -CREATE INDEX "#__fields_groups_idx_access" ON "#__fields_groups" ("access"); -CREATE INDEX "#__fields_groups_idx_context" ON "#__fields_groups" ("context"); -CREATE INDEX "#__fields_groups_idx_language" ON "#__fields_groups" ("language"); - --- --- Table: #__fields_values --- -CREATE TABLE "#__fields_values" ( -"field_id" bigint DEFAULT 0 NOT NULL, -"item_id" varchar(255) DEFAULT '' NOT NULL, -"value" text DEFAULT '' NOT NULL -); -CREATE INDEX "#__fields_values_idx_field_id" ON "#__fields_values" ("field_id"); -CREATE INDEX "#__fields_values_idx_item_id" ON "#__fields_values" ("item_id"); - -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 -(33, 'com_fields', 'component', 'com_fields', '', 1, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(461, 'plg_system_fields', 'plugin', 'fields', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(462, 'plg_fields_calendar', 'plugin', 'calendar', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(463, 'plg_fields_checkboxes', 'plugin', 'checkboxes', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(464, 'plg_fields_color', 'plugin', 'color', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(465, 'plg_fields_editor', 'plugin', 'editor', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(466, 'plg_fields_imagelist', 'plugin', 'imagelist', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(467, 'plg_fields_integer', 'plugin', 'integer', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(468, 'plg_fields_list', 'plugin', 'list', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(469, 'plg_fields_media', 'plugin', 'media', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(470, 'plg_fields_radio', 'plugin', 'radio', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(471, 'plg_fields_sql', 'plugin', 'sql', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(472, 'plg_fields_text', 'plugin', 'text', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(473, 'plg_fields_textarea', 'plugin', 'textarea', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(474, 'plg_fields_url', 'plugin', 'url', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(475, 'plg_fields_user', 'plugin', 'user', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), -(476, 'plg_fields_usergrouplist', 'plugin', 'usergrouplist', '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.7.0-2016-09-29.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-09-29.sql deleted file mode 100644 index 4bfd02b6a7e36..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-09-29.sql +++ /dev/null @@ -1,3 +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, 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE', 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/joomla40checks.php', 'admin_postinstall_joomla40checks_condition', '3.7.0', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-10-01.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-10-01.sql deleted file mode 100644 index 3e5604675df12..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-10-01.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(460, 'plg_editors-xtd_contact', 'plugin', 'contact', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-10-02.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-10-02.sql deleted file mode 100644 index b50a60ae930de..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-10-02.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "#__session" ALTER COLUMN "client_id" DROP NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-04.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-04.sql deleted file mode 100644 index f423add87448a..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-04.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "#__extensions" ALTER COLUMN "enabled" SET DEFAULT 0; \ No newline at end of file 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 deleted file mode 100644 index 1711f5761e2e9..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-19.sql +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100644 index e68abd215444d..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-21.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Replace language image UNIQUE index for a normal INDEX. -ALTER TABLE "#__languages" DROP CONSTRAINT "#__languages_idx_image"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-24.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-24.sql deleted file mode 100644 index 1670758b7ad4c..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2016-11-24.sql +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE "#__extensions" ADD COLUMN "package_id" bigint DEFAULT 0 NOT NULL; - -UPDATE "#__extensions" -SET "package_id" = sub.extension_id -FROM (SELECT "extension_id" FROM "#__extensions" WHERE "type" = 'package' AND "element" = 'pkg_en-GB') AS sub -WHERE "type"= 'language' AND "element" = 'en-GB'; 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 deleted file mode 100644 index 35cbc78a02002..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-08.sql +++ /dev/null @@ -1,9 +0,0 @@ --- 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 ''; 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 deleted file mode 100644 index 8d4895fb4d79f..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-09.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Normalize categories table default values. -ALTER TABLE "#__categories" ALTER COLUMN "title" SET DEFAULT ''; -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-15.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-15.sql deleted file mode 100644 index f244b43bedf4e..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-15.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(34, 'com_associations', 'component', 'com_associations', '', 1, 1, 1, 1, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); 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 deleted file mode 100644 index 3009938a54d1c..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-17.sql +++ /dev/null @@ -1,58 +0,0 @@ --- Sync menutype for admin menu and set client_id correct - --- 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-01-31.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-31.sql deleted file mode 100644 index 692f8e79e0ddd..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-01-31.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(477, 'plg_content_fields', 'plugin', 'fields', 'content', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-02.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-02.sql deleted file mode 100644 index 4e23ad5a1f0fa..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-02.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 -(478, 'plg_editors-xtd_fields', 'plugin', 'fields', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-15.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-15.sql deleted file mode 100644 index e24971bf845ba..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-15.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Normalize redirect_links table default values. -ALTER TABLE "#__redirect_links" ALTER COLUMN "comment" SET DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-17.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-17.sql deleted file mode 100644 index d3542a8193bce..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-02-17.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Normalize contact_details table default values. -ALTER TABLE "#__contact_details" ALTER COLUMN "name" DROP DEFAULT; -ALTER TABLE "#__contact_details" ALTER COLUMN "alias" DROP DEFAULT; -ALTER TABLE "#__contact_details" ALTER COLUMN "sortname1" SET DEFAULT ''; -ALTER TABLE "#__contact_details" ALTER COLUMN "sortname2" SET DEFAULT ''; -ALTER TABLE "#__contact_details" ALTER COLUMN "sortname3" SET DEFAULT ''; -ALTER TABLE "#__contact_details" ALTER COLUMN "language" DROP DEFAULT; -ALTER TABLE "#__contact_details" ALTER COLUMN "xreference" SET DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-03-03.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-03-03.sql deleted file mode 100644 index 806caf88b09f8..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-03-03.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE "#__extensions" ALTER COLUMN "custom_data" DROP DEFAULT; -ALTER TABLE "#__extensions" ALTER COLUMN "system_data" DROP DEFAULT; -ALTER TABLE "#__updates" ALTER COLUMN "data" DROP DEFAULT; - -ALTER TABLE "#__newsfeeds" ALTER COLUMN "xreference" SET DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-03-09.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-03-09.sql deleted file mode 100644 index 08aa07b95e254..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-03-09.sql +++ /dev/null @@ -1,19 +0,0 @@ -UPDATE "#__categories" SET published = 1 WHERE alias = 'root'; -UPDATE "#__categories" AS "c" -SET published = c2.newPublished -FROM ( -SELECT c2.id, CASE WHEN MIN(p.published) > 0 THEN MAX(p.published) ELSE MIN(p.published) END AS newPublished -FROM "#__categories" AS "c2" -INNER JOIN "#__categories" AS "p" ON p.lft <= c2.lft AND c2.rgt <= p.rgt -GROUP BY c2.id) AS c2 -WHERE c2.id = c.id; - -UPDATE "#__menu" SET published = 1 WHERE alias = 'root'; -UPDATE "#__menu" AS "c" -SET published = c2.newPublished -FROM ( -SELECT c2.id, CASE WHEN MIN(p.published) > 0 THEN MAX(p.published) ELSE MIN(p.published) END AS newPublished -FROM "#__menu" AS "c2" -INNER JOIN "#__menu" AS "p" ON p.lft <= c2.lft AND c2.rgt <= p.rgt -GROUP BY c2.id) AS c2 -WHERE c2.id = c.id; diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-10.sql b/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-10.sql deleted file mode 100644 index c8a2f4d934ab8..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-10.sql +++ /dev/null @@ -1,3 +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, 'TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE', 'TPL_HATHOR_MESSAGE_POSTINSTALL_BODY', 'TPL_HATHOR_MESSAGE_POSTINSTALL_ACTION', 'tpl_hathor', 1, 'action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_condition', '3.7.0', 1); \ No newline at end of file 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 deleted file mode 100644 index a71c3e11b2db5..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.0-2017-04-19.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Set integer field default values. -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 deleted file mode 100644 index e9f5f2b099a0f..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.7.4-2017-07-05.sql +++ /dev/null @@ -1 +0,0 @@ -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.6-2018-02-14.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.6-2018-02-14.sql deleted file mode 100644 index bd70f521d3872..0000000000000 --- a/administrator/components/com_admin/sql/updates/postgresql/3.8.6-2018-02-14.sql +++ /dev/null @@ -1,6 +0,0 @@ -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/4.0.0-2016-07-03.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-07-03.sql new file mode 100644 index 0000000000000..9540431d11de3 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-07-03.sql @@ -0,0 +1,3 @@ +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 +(458, 'plg_behaviour_taggable', 'plugin', 'taggable', 'behaviour', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(459, 'plg_behaviour_versionable', 'plugin', 'versionable', 'behaviour', 0, 1, 1, 0, '', '{}', '', '', 0, '1970-01-01 00:00:00', 0, 0); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-09-22.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-09-22.sql new file mode 100644 index 0000000000000..0ff2762def48a --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-09-22.sql @@ -0,0 +1 @@ +DELETE FROM "#__extensions" WHERE "extension_id" = 102; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-09-28.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-09-28.sql new file mode 100644 index 0000000000000..d320a23002a7f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-09-28.sql @@ -0,0 +1 @@ +DELETE FROM "#__extensions" WHERE "extension_id" = 423; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-10-02.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-10-02.sql new file mode 100644 index 0000000000000..4db320a8af832 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-10-02.sql @@ -0,0 +1,3 @@ +DELETE FROM "#__extensions" WHERE "extension_id" = 504; +DELETE FROM "#__template_styles" WHERE "template" = 'hathor'; +ALTER TABLE "#__user_keys" DROP COLUMN "invalid"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-10-03.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-10-03.sql new file mode 100644 index 0000000000000..1dabb6772d22b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-10-03.sql @@ -0,0 +1 @@ +DELETE FROM "#__extensions" WHERE "name" = "mod_submenu"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-10-19.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-10-19.sql new file mode 100644 index 0000000000000..7abed7beeebcb --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2016-10-19.sql @@ -0,0 +1 @@ +ALTER TABLE ""#__extensions" ADD "namespace"" VARCHAR(500) NOT NULL DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-03-18.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-03-18.sql new file mode 100644 index 0000000000000..4c69dc296a528 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-03-18.sql @@ -0,0 +1,2 @@ +ALTER TABLE "#__extensions" DROP COLUMN "custom_data"; +ALTER TABLE "#__extensions" DROP COLUMN "system_data"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-04-25.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-04-25.sql new file mode 100644 index 0000000000000..c2b2bef81945b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-04-25.sql @@ -0,0 +1,5 @@ +INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "checked_out", "checked_out_time", "ordering", "state") VALUES +(481, 'plg_filesystem_local', 'plugin', 'local', 'filesystem', 0, 1, 1, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0), +(482, 'plg_media-action_crop', 'plugin', 'crop', 'media-action', 0, 1, 1, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0), +(483, 'plg_media-action_resize', 'plugin', 'resize', 'media-action', 0, 1, 1, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0), +(484, 'plg_media-action_rotate', 'plugin', 'rotate', 'media-action', 0, 1, 1, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0),; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-05-31.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-05-31.sql new file mode 100644 index 0000000000000..0ae293150458e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-05-31.sql @@ -0,0 +1,2 @@ +UPDATE "#__menu" SET "link" = 'index.php?option=com_config&view=config' WHERE "link" = 'index.php?option=com_config&view=config&controller=config.display.config'; +UPDATE "#__menu" SET "link" = 'index.php?option=com_config&view=templates' WHERE "link" = 'index.php?option=com_config&view=templates&controller=config.display.templates'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-10-10.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-10-10.sql new file mode 100644 index 0000000000000..f9321eed78908 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2017-10-10.sql @@ -0,0 +1,6 @@ +INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "checked_out", "checked_out_time", "ordering", "state") VALUES +(487, 'plg_system_httpheaders', 'plugin', 'httpheaders', 'system', 0, 0, 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_SYSTEM_HTTPHEADERS_POSTINSTALL_INTRODUCTION_TITLE', 'PLG_SYSTEM_HTTPHEADERS_POSTINSTALL_INTRODUCTION_BODY', 'PLG_SYSTEM_HTTPHEADERS_POSTINSTALL_INTRODUCTION_ACTION', 'plg_system_httpheaders', 1, 'action', 'site://plugins/system/httpheaders/postinstall/introduction.php', 'httpheaders_postinstall_action', 'site://plugins/system/httpheaders/postinstall/introduction.php', 'httpheaders_postinstall_condition', '4.0.0', 1); diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-02-24.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-02-24.sql new file mode 100644 index 0000000000000..896c862d21f14 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-02-24.sql @@ -0,0 +1 @@ +DELETE FROM "#__extensions" WHERE "extension_id" = 104; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-03-05.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-03-05.sql new file mode 100644 index 0000000000000..dbab0bc9ecbe8 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-03-05.sql @@ -0,0 +1 @@ +ALTER TABLE "#__modules" ALTER COLUMN "content" DROP NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-04-14.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-04-14.sql new file mode 100644 index 0000000000000..2c009f23c5a1b --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-04-14.sql @@ -0,0 +1,48 @@ +CREATE TABLE "#__finder_links_terms" ( + "link_id" bigint NOT NULL, + "term_id" bigint NOT NULL, + "weight" REAL NOT NULL, + PRIMARY KEY ("link_id", "term_id") +); +CREATE INDEX "idx_term_weight" ("term_id", "weight"); +CREATE INDEX "idx_link_term_weight" ("link_id", "term_id", "weight"); + +DROP TABLE "#__finder_links_terms0" CASCADE; +DROP TABLE "#__finder_links_terms1" CASCADE; +DROP TABLE "#__finder_links_terms2" CASCADE; +DROP TABLE "#__finder_links_terms3" CASCADE; +DROP TABLE "#__finder_links_terms4" CASCADE; +DROP TABLE "#__finder_links_terms5" CASCADE; +DROP TABLE "#__finder_links_terms6" CASCADE; +DROP TABLE "#__finder_links_terms7" CASCADE; +DROP TABLE "#__finder_links_terms8" CASCADE; +DROP TABLE "#__finder_links_terms9" CASCADE; +DROP TABLE "#__finder_links_termsa" CASCADE; +DROP TABLE "#__finder_links_termsb" CASCADE; +DROP TABLE "#__finder_links_termsc" CASCADE; +DROP TABLE "#__finder_links_termsd" CASCADE; +DROP TABLE "#__finder_links_termse" CASCADE; +DROP TABLE "#__finder_links_termsf" CASCADE; + +ALTER TABLE "#__finder_terms" + ALTER COLUMN "language" TYPE CHAR(7), + ALTER COLUMN "language" SET DEFAULT ''; + +ALTER TABLE "#__finder_common" + ALTER COLUMN "language" TYPE CHAR(7), + ALTER COLUMN "language" SET DEFAULT ''; + +ALTER TABLE "#__finder_tokens" + ALTER COLUMN "language" TYPE CHAR(7), + ALTER COLUMN "language" SET DEFAULT ''; + +ALTER TABLE "#__finder_tokens_aggregate" + ALTER COLUMN "language" TYPE CHAR(7), + ALTER COLUMN "language" SET DEFAULT ''; + +ALTER TABLE "#__finder_tokens_aggregate" + DROP COLUMN "map_suffix"; + +ALTER TABLE "#__finder_links" + ALTER COLUMN "language" TYPE CHAR(7), + ALTER COLUMN "language" SET DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql new file mode 100644 index 0000000000000..4b9bf1e53e3cf --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-05-15.sql @@ -0,0 +1,120 @@ +-- +-- Table structure for table "#__workflows" +-- + +CREATE TABLE IF NOT EXISTS "#__workflows" ( + "id" serial NOT NULL, + "asset_id" bigint DEFAULT 0 NOT NULL, + "published" smallint DEFAULT 0 NOT NULL, + "title" varchar(255) DEFAULT '' NOT NULL, + "description" text NOT NULL, + "extension" varchar(50) NOT NULL, + "default" smallint NOT NULL DEFAULT 0, + "ordering" bigint NOT NULL DEFAULT 0, + "created" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "created_by" bigint DEFAULT 0 NOT NULL, + "modified" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "modified_by" bigint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") + ); + +CREATE INDEX "#__workflows_idx_asset_id" ON "#__workflows" ("asset_id"); +CREATE INDEX "#__workflows_idx_title" ON "#__workflows" ("title"); +CREATE INDEX "#__workflows_idx_extension" ON "#__workflows" ("extension"); +CREATE INDEX "#__workflows_idx_default" ON "#__workflows" ("default"); +CREATE INDEX "#__workflows_idx_created" ON "#__workflows" ("created"); +CREATE INDEX "#__workflows_idx_created_by" ON "#__workflows" ("created_by"); +CREATE INDEX "#__workflows_idx_modified" ON "#__workflows" ("modified"); +CREATE INDEX "#__workflows_idx_modified_by" ON "#__workflows" ("modified_by"); + +INSERT INTO "#__workflows" ("id", "asset_id", "published", "title", "description", "extension", "default", "ordering", "created", "created_by", "modified", "modified_by") VALUES +(1, 0, 1, 'Joomla! Default', '', 'com_content', 1, 1, '1970-01-01 00:00:00', 0, '1970-01-01 00:00:00', 0); + +-- +-- Table structure for table "#__workflow_associations" +-- + +CREATE TABLE IF NOT EXISTS "#__workflow_associations" ( + "item_id" bigint DEFAULT 0 NOT NULL, + "stage_id" bigint DEFAULT 0 NOT NULL, + "extension" varchar(50) NOT NULL, + PRIMARY KEY ("item_id", "stage_id", "extension") +); +CREATE INDEX "#__workflow_associations_idx_item_id" ON "#__workflow_associations" ("item_id"); +CREATE INDEX "#__workflow_associations_idx_stage_id" ON "#__workflow_associations" ("stage_id"); +CREATE INDEX "#__workflow_associations_idx_extension" ON "#__workflow_associations" ("extension"); + +COMMENT ON COLUMN "#__workflow_associations"."item_id" IS 'Extension table id value'; +COMMENT ON COLUMN "#__workflow_associations"."stage_id" IS 'Foreign Key to #__workflow_stages.id'; + +-- +-- Table structure for table "#__workflow_stages" +-- + +CREATE TABLE IF NOT EXISTS "#__workflow_stages" ( + "id" serial NOT NULL, + "asset_id" bigint DEFAULT 0 NOT NULL, + "ordering" bigint DEFAULT 0 NOT NULL, + "workflow_id" bigint DEFAULT 0 NOT NULL, + "published" smallint NOT NULL DEFAULT 0, + "title" varchar(255) NOT NULL, + "description" text NOT NULL, + "condition" bigint DEFAULT 0 NOT NULL, + "default" smallint NOT NULL DEFAULT 0, + PRIMARY KEY ("id") +); +CREATE INDEX "#__workflow_stages_idx_workflow_id" ON "#__workflow_stages" ("workflow_id"); +CREATE INDEX "#__workflow_stages_idx_title" ON "#__workflow_stages" ("title"); +CREATE INDEX "#__workflow_stages_idx_asset_id" ON "#__workflow_stages" ("asset_id"); +CREATE INDEX "#__workflow_stages_idx_default" ON "#__workflow_stages" ("default"); + +-- +-- Dumping data for table "#__workflow_stages" +-- + +INSERT INTO "#__workflow_stages" ("id", "asset_id", "ordering", "workflow_id", "published", "title", "description", "condition", "default") VALUES +(1, 0, 1, 1, 1, 'JUNPUBLISHED', '', 0, 0), +(2, 0, 2, 1, 1, 'JPUBLISHED', '', 1, 1), +(3, 0, 3, 1, 1, 'JTRASHED', '', -2, 0), +(4, 0, 4, 1, 1, 'JARCHIVED', '', 2, 0); + +-- +-- Table structure for table "#__workflow_transitions" +-- + +CREATE TABLE IF NOT EXISTS "#__workflow_transitions" ( + "id" serial NOT NULL, + "asset_id" bigint DEFAULT 0 NOT NULL, + "ordering" bigint DEFAULT 0 NOT NULL, + "workflow_id" bigint DEFAULT 0 NOT NULL, + "published" smallint NOT NULL DEFAULT 0, + "title" varchar(255) NOT NULL, + "description" text NOT NULL, + "from_stage_id" bigint DEFAULT 0 NOT NULL, + "to_stage_id" bigint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") + ); +CREATE INDEX "#__workflow_transitions_idx_title" ON "#__workflow_transitions" ("title"); +CREATE INDEX "#__workflow_transitions_idx_asset_id" ON "#__workflow_transitions" ("asset_id"); +CREATE INDEX "#__workflow_transitions_idx_from_stage_id" ON "#__workflow_transitions" ("from_stage_id"); +CREATE INDEX "#__workflow_transitions_idx_to_stage_id" ON "#__workflow_transitions" ("to_stage_id"); +CREATE INDEX "#__workflow_transitions_idx_workflow_id" ON "#__workflow_transitions" ("workflow_id"); + +INSERT INTO "#__workflow_transitions" ("id", "asset_id", "published", "ordering", "workflow_id", "title", "description", "from_stage_id", "to_stage_id") VALUES +(1, 0, 1, 1, 1, 'Unpublish', '', -1, 1), +(2, 0, 1, 2, 1, 'Publish', '', -1, 2), +(3, 0, 1, 3, 1, 'Trash', '', -1, 3), +(4, 0, 1, 4, 1, 'Archive', '', -1, 4); + +-- +-- Creating extension entry +-- + +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "checked_out", "checked_out_time", "ordering", "state", "namespace") VALUES +(35, 0, 'com_workflow', 'component', 'com_workflow', '', 1, 1, 0, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0, 'Joomla\\Component\\Workflow'); + +-- +-- Creating Associations for existing content +-- +INSERT INTO "#__workflow_associations" ("item_id", "stage_id", "extension") +SELECT "id", CASE WHEN "state" = -2 THEN 3 WHEN "state" = 0 THEN 1 WHEN "state" = 2 THEN 4 ELSE 2 END, 'com_content' FROM "#__content"; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-03.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-03.sql new file mode 100644 index 0000000000000..05b766dec0f1f --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-03.sql @@ -0,0 +1,18 @@ +-- +-- Table structure for table `#__csp` +-- + +CREATE TABLE IF NOT EXISTS "#__csp" ( + "id" serial NOT NULL, + "document_uri" varchar(500) NOT NULL DEFAULT '', + "blocked_uri" varchar(500) NOT NULL DEFAULT '', + "directive" varchar(500) NOT NULL DEFAULT '', + "client" varchar(500) NOT NULL DEFAULT '', + "created" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "modified" timestamp without time zone DEFAULT '1970-01-01 00:00:00' NOT NULL, + "published" smallint DEFAULT 0 NOT NULL, + PRIMARY KEY ("id") +); + +INSERT INTO "#__extensions" ("extension_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "checked_out", "checked_out_time", "ordering", "state", "namespace") VALUES +(35, 'com_csp', 'component', 'com_csp', ' ', 0, 0, 1, 0, '', '{}', 0, '1970-01-01 00:00:00', 0, 0, 'Joomla\\Component\\Csp'); diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-06.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-06.sql new file mode 100644 index 0000000000000..b0a99aacc38c1 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-06.sql @@ -0,0 +1,10 @@ +CREATE TABLE IF NOT EXISTS "#__finder_logging" ( + "searchterm" character varying(255) NOT NULL DEFAULT '', + "md5sum" character varying(32) NOT NULL DEFAULT '', + "query" bytea NOT NULL, + "hits" integer NOT NULL DEFAULT 1, + "results" integer NOT NULL DEFAULT 0, + PRIMARY KEY ("md5sum") +); +CREATE INDEX "#__finder_logging_idx_md5sum" on "#__finder_logging" ("md5sum"); +CREATE INDEX "#__finder_logging_idx_searchterm" on "#__finder_logging" ("searchterm"); diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-11.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-11.sql new file mode 100644 index 0000000000000..4d4ddb987927d --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-11.sql @@ -0,0 +1,4 @@ +INSERT INTO "#__extensions" +("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "checked_out", "checked_out_time", "ordering", "state") +VALUES + (488, 0, 'plg_sampledata_blog', 'plugin', 'multilang', 'sampledata', 0, 0, 1, 0, '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-26.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-26.sql new file mode 100644 index 0000000000000..b66ff55c8b147 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-06-26.sql @@ -0,0 +1 @@ +ALTER TABLE "#__user_notes" ALTER COLUMN "modified_user_id" SET DEFAULT 0; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-07-02.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-07-02.sql new file mode 100644 index 0000000000000..c1604cb30bb3c --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-07-02.sql @@ -0,0 +1 @@ +UPDATE "#__extensions" SET "protected" = 1 WHERE "name" = 'plg_extension_namespacemap'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-07-09.sql b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-07-09.sql new file mode 100644 index 0000000000000..e681b715a946e --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/4.0.0-2018-07-09.sql @@ -0,0 +1 @@ +UPDATE "#__extensions" SET "namespace" = 'Joomla\\Module\\Multilangstatus' WHERE "name" = 'mod_multilangstatus'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/2.5.2-2012-03-05.sql b/administrator/components/com_admin/sql/updates/sqlazure/2.5.2-2012-03-05.sql deleted file mode 100644 index 1c06a396e19e2..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/2.5.2-2012-03-05.sql +++ /dev/null @@ -1 +0,0 @@ -# Dummy SQL file to set schema version \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/2.5.3-2012-03-13.sql b/administrator/components/com_admin/sql/updates/sqlazure/2.5.3-2012-03-13.sql deleted file mode 100644 index 1c06a396e19e2..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/2.5.3-2012-03-13.sql +++ /dev/null @@ -1 +0,0 @@ -# Dummy SQL file to set schema version \ No newline at end of file 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 deleted file mode 100644 index 310ec720750bc..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-18.sql +++ /dev/null @@ -1,9 +0,0 @@ -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 - 2018 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; - -SET IDENTITY_INSERT [#__extensions] OFF; - -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]) -SELECT 'menu', 'com_joomlaupdate', 'Joomla! Update', '', 'Joomla! Update', 'index.php?option=com_joomlaupdate', 'component', 0, 1, 1, 28, 0, 0, '1900-01-01 00:00:00', 0, 0, 'class:joomlaupdate', 0, '', 41, 42, 0, '*', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-19.sql b/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-19.sql deleted file mode 100644 index c703548907b87..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/2.5.4-2012-03-19.sql +++ /dev/null @@ -1,7 +0,0 @@ -ALTER TABLE [#__languages] ADD [access] INTEGER CONSTRAINT DF_languages_access DEFAULT '' NOT NULL - -CREATE UNIQUE INDEX idx_access ON [#__languages] (access); - -UPDATE [#__categories] SET [extension] = 'com_users.notes' WHERE [extension] = 'com_users'; - -UPDATE [#__extensions] SET [enabled] = '1' WHERE [protected] = '1' AND [type] <> 'plugin'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/2.5.5.sql b/administrator/components/com_admin/sql/updates/sqlazure/2.5.5.sql deleted file mode 100644 index d85ed92773443..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/2.5.5.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE [#__redirect_links] ADD [hits] INTEGER CONSTRAINT DF_redirect_links_hits DEFAULT '' NOT NULL; -ALTER TABLE [#__users] ADD [lastResetTime] [datetime] NOT NULL; -ALTER TABLE [#__users] ADD [resetCount] [int] NOT NULL; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/2.5.6.sql b/administrator/components/com_admin/sql/updates/sqlazure/2.5.6.sql deleted file mode 100644 index ff1afae20a6df..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/2.5.6.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 2.5.6 \ No newline at end of file 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 deleted file mode 100644 index b249c8a8cbbef..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/2.5.7.sql +++ /dev/null @@ -1,8 +0,0 @@ -INSERT INTO [#__update_sites] ([name], [type], [location], [enabled], [last_check_timestamp]) -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; - -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'); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.0.0.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.0.0.sql deleted file mode 100644 index b2aa72ce27783..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.0.0.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.0.0 diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.0.1.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.0.1.sql deleted file mode 100644 index d1c142050af85..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.0.1.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.0.1 diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.0.2.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.0.2.sql deleted file mode 100644 index df708fc2fcea7..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.0.2.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.0.2 \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.0.3.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.0.3.sql deleted file mode 100644 index 4f6e1b358247e..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.0.3.sql +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE [#__associations] DROP CONSTRAINT [PK_#__associations_context]; -ALTER TABLE [#__associations] ALTER COLUMN [id] INT NOT NULL; -ALTER TABLE [#__associations] ADD CONSTRAINT [PK_#__associations_context] PRIMARY KEY CLUSTERED( - [context] ASC, - [id] ASC -)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]; 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 deleted file mode 100644 index 4ca149cecb628..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.1.0.sql +++ /dev/null @@ -1,326 +0,0 @@ -/* Changes to Smart Search tables for driver compatibility */ -ALTER TABLE [#__finder_tokens_aggregate] ALTER COLUMN [term_id] [bigint] NULL; -ALTER TABLE [#__finder_tokens_aggregate] ALTER COLUMN [map_suffix] [nchar](1) NULL; -ALTER TABLE [#__finder_tokens_aggregate] ADD DEFAULT ((0)) FOR [term_id]; -ALTER TABLE [#__finder_tokens_aggregate] ADD DEFAULT ((0)) FOR [total_weight]; - -/* Changes to tables where data type conflicts exist with MySQL (mainly dealing with null values */ -ALTER TABLE [#__extensions] ADD DEFAULT (N'') FOR [system_data]; -ALTER TABLE [#__modules] ADD DEFAULT (N'') FOR [content]; -ALTER TABLE [#__updates] ADD DEFAULT (N'') FOR [data]; - -/* Tags database schema */ - -/****** Object: Table [#__content_types] ******/ -SET QUOTED_IDENTIFIER ON; - -CREATE TABLE [#__content_types] ( - [type_id] [bigint] IDENTITY(1,1) NOT NULL, - [type_title] [nvarchar](255) NOT NULL DEFAULT '', - [type_alias] [nvarchar](255) NOT NULL DEFAULT '', - [table] [nvarchar](255) NOT NULL DEFAULT '', - [rules] [nvarchar](max) NOT NULL, - [field_mappings] [nvarchar](max) NOT NULL, - [router] [nvarchar](255) NOT NULL DEFAULT '', - CONSTRAINT [PK_#__content_types_type_id] PRIMARY KEY CLUSTERED -( - [type_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_alias] ON [#__content_types] -( - [type_alias] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -SET IDENTITY_INSERT [#__content_types] ON; - -INSERT INTO [#__content_types] ([type_id], [type_title], [type_alias], [table], [rules], [field_mappings], [router]) -SELECT 1, 'Article', 'com_content.article', '{"special":{"dbtable":"#__content","key":"id","type":"Content","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"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"}], "special": [{"fulltext":"fulltext"}]}', 'ContentHelperRoute::getArticleRoute' -UNION ALL -SELECT 2, 'Contact', 'com_contact.contact', '{"special":{"dbtable":"#__contact_details","key":"id","type":"Contact","prefix":"ContactTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"address", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"image", "core_urls":"webpage", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}], "special": [{"con_position":"con_position","suburb":"suburb","state":"state","country":"country","postcode":"postcode","telephone":"telephone","fax":"fax","misc":"misc","email_to":"email_to","default_con":"default_con","user_id":"user_id","mobile":"mobile","sortname1":"sortname1","sortname2":"sortname2","sortname3":"sortname3"}]}', 'ContactHelperRoute::getContactRoute' -UNION ALL -SELECT 3, 'Newsfeed', 'com_newsfeeds.newsfeed', '{"special":{"dbtable":"#__newsfeeds","key":"id","type":"Newsfeed","prefix":"NewsfeedsTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"description", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"link", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}], "special": [{"numarticles":"numarticles","cache_time":"cache_time","rtl":"rtl"}]}', 'NewsfeedsHelperRoute::getNewsfeedRoute' -UNION ALL -SELECT 4, 'User', 'com_users.user', '{"special":{"dbtable":"#__users","key":"id","type":"User","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"name","core_state":"null","core_alias":"username","core_created_time":"registerdate","core_modified_time":"lastvisitDate","core_body":"null", "core_hits":"null","core_publish_up":"null","core_publish_down":"null","access":"null", "core_params":"params", "core_featured":"null", "core_metadata":"null", "core_language":"null", "core_images":"null", "core_urls":"null", "core_version":"null", "core_ordering":"null", "core_metakey":"null", "core_metadesc":"null", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}], "special": [{}]}', 'UsersHelperRoute::getUserRoute' -UNION ALL -SELECT 5, 'Article Category', 'com_content.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}]}', 'ContentHelperRoute::getCategoryRoute' -UNION ALL -SELECT 6, 'Contact Category', 'com_contact.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}]}', 'ContactHelperRoute::getCategoryRoute' -UNION ALL -SELECT 7, 'Newsfeeds Category', 'com_newsfeeds.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}]}', 'NewsfeedsHelperRoute::getCategoryRoute' -UNION ALL -SELECT 8, 'Tag', 'com_tags.tag', '{"special":{"dbtable":"#__tags","key":"tag_id","type":"Tag","prefix":"TagsTable","config":"array()"},"common":{"dbtable":"#__core_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":[{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"urls", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}], "special": [{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path"}]}', 'TagsHelperRoute::getTagRoute'; - -SET IDENTITY_INSERT [#__content_types] OFF; - -/****** Object: Table [#__contentitem_tag_map] ******/ -SET QUOTED_IDENTIFIER ON; - -CREATE TABLE [#__contentitem_tag_map] ( - [type_alias] [nvarchar](255) NOT NULL DEFAULT '', - [core_content_id] [bigint] NOT NULL, - [content_item_id] [int] NOT NULL, - [tag_id] [bigint] NOT NULL, - [tag_date] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - CONSTRAINT [#__contentitem_tag_map$uc_ItemnameTagid] UNIQUE NONCLUSTERED -( - [type_alias] ASC, - [content_item_id] ASC, - [tag_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_tag_name] ON [#__contentitem_tag_map] -( - [tag_id] ASC, - [type_alias] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_date_id] ON [#__contentitem_tag_map] -( - [tag_date] ASC, - [tag_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_tag] ON [#__contentitem_tag_map] -( - [tag_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_core_content_id] ON [#__contentitem_tag_map] -( - [core_content_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -/****** Object: Table [#__tags] ******/ -SET QUOTED_IDENTIFIER ON; - -CREATE TABLE [#__tags] ( - [id] [int] IDENTITY(1,1) NOT NULL , - [parent_id] [bigint] NOT NULL DEFAULT '0', - [lft] [int] NOT NULL DEFAULT '0', - [rgt] [int] NOT NULL DEFAULT '0', - [level] [bigint] NOT NULL DEFAULT '0', - [path] [nvarchar](255) NOT NULL DEFAULT '', - [title] [nvarchar](255) NOT NULL, - [alias] [nvarchar](255) NOT NULL DEFAULT '', - [note] [nvarchar](255) NOT NULL DEFAULT '', - [description] [nvarchar](max) NOT NULL, - [published] [smallint] NOT NULL DEFAULT '0', - [checked_out] [bigint] NOT NULL DEFAULT '0', - [checked_out_time] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [access] [int] NOT NULL DEFAULT '0', - [params] [nvarchar](max) NOT NULL, - [metadesc] [nvarchar](1024) NOT NULL, - [metakey] [nvarchar](1024) NOT NULL, - [metadata] [nvarchar](2048) NOT NULL, - [created_user_id] [bigint] NOT NULL DEFAULT '0', - [created_time] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [created_by_alias] [nvarchar](255) NOT NULL DEFAULT '', - [modified_user_id] [bigint] NOT NULL DEFAULT '0', - [modified_time] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [images] [nvarchar](max) NOT NULL, - [urls] [nvarchar](max) NOT NULL, - [hits] [bigint] NOT NULL DEFAULT '0', - [language] [nvarchar](7) NOT NULL, - [version] [bigint] NOT NULL DEFAULT '1', - [publish_up] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [publish_down] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - CONSTRAINT [PK_#__tags_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 [tag_idx] ON [#__tags] -( - [published] ASC, - [access] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_access] ON [#__tags] -( - [access] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_checkout] ON [#__tags] -( - [checked_out] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_path] ON [#__tags] -( - [path] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_left_right] ON [#__tags] -( - [lft] ASC, - [rgt] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_alias] ON [#__tags] -( - [alias] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_language] ON [#__tags] -( - [language] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -SET IDENTITY_INSERT [#__tags] ON; - -INSERT INTO [#__tags] ([id], [parent_id], [lft], [rgt], [level], [path], [title], [alias], [note], [description], [published], [checked_out], [checked_out_time], [access], [params], [metadesc], [metakey], [metadata], [created_user_id], [created_time], [modified_user_id], [modified_time], [images], [urls], [hits], [language]) -SELECT 1, 0, 0, 1, 0, '', 'ROOT', 'root', '', '', 1, 0, '1900-01-01 00:00:00', 1, '{}', '', '', '', 0, '2009-10-18 16:07:09', 0, '1900-01-01 00:00:00', '', '', 0, '*'; - -SET IDENTITY_INSERT [#__tags] OFF; - -/****** Object: Table [#__ucm_base] ******/ -SET QUOTED_IDENTIFIER ON; - -CREATE TABLE [#__ucm_base] ( - [ucm_id] [bigint] IDENTITY(1,1) NOT NULL, - [ucm_item_id] [bigint] NOT NULL, - [ucm_type_id] [bigint] NOT NULL, - [ucm_language_id] [bigint] NOT NULL, - CONSTRAINT [PK_#__ucm_base_ucm_id] PRIMARY KEY CLUSTERED - ( - [ucm_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 [ucm_item_id] ON [#__ucm_base] -( - [ucm_item_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [ucm_type_id] ON [#__ucm_base] -( - [ucm_type_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [ucm_language_id] ON [#__ucm_base] -( - [ucm_language_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -/****** Object: Table [#__ucm_content] ******/ -SET QUOTED_IDENTIFIER ON; - -CREATE TABLE [#__ucm_content] ( - [core_content_id] [bigint] IDENTITY(1,1) NOT NULL, - [core_type_alias] [nvarchar](255) NOT NULL, - [core_title] [nvarchar](255) NOT NULL DEFAULT '', - [core_alias] [nvarchar](255) NOT NULL DEFAULT '', - [core_body] [nvarchar](max) NOT NULL, - [core_state] [smallint] NOT NULL DEFAULT '0', - [core_checked_out_time] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [core_checked_out_user_id] [bigint] NOT NULL DEFAULT '0', - [core_access] [bigint] NOT NULL DEFAULT '0', - [core_params] [nvarchar](max) NOT NULL, - [core_featured] [tinyint] NOT NULL DEFAULT '0', - [core_metadata] [nvarchar](max) NOT NULL, - [core_created_user_id] [bigint] NOT NULL DEFAULT '0', - [core_created_by_alias] [nvarchar](255) NOT NULL DEFAULT '', - [core_created_time] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [core_modified_user_id] [bigint] NOT NULL DEFAULT '0', - [core_modified_time] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [core_language] [nvarchar](7) NOT NULL, - [core_publish_up] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [core_publish_down] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [core_content_item_id] [bigint] NOT NULL DEFAULT '0', - [asset_id] [bigint] NOT NULL DEFAULT '0', - [core_images] [nvarchar](max) NOT NULL, - [core_urls] [nvarchar](max) NOT NULL, - [core_hits] [bigint] NOT NULL DEFAULT '0', - [core_version] [bigint] NOT NULL DEFAULT '1', - [core_ordering] [int] NOT NULL DEFAULT '0', - [core_metakey] [nvarchar](max) NOT NULL, - [core_metadesc] [nvarchar](max) NOT NULL, - [core_catid] [bigint] NOT NULL DEFAULT '0', - [core_xreference] [nvarchar](50) NOT NULL, - [core_type_id] [bigint] NOT NULL DEFAULT '0', - CONSTRAINT [PK_#__ucm_content_core_content_id] PRIMARY KEY CLUSTERED - ( - [core_content_id] ASC - )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], - CONSTRAINT [#__ucm_content_core_content_id$idx_type_alias_item_id] UNIQUE NONCLUSTERED - ( - [core_type_alias] ASC, - [core_content_item_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 [tag_idx] ON [#__ucm_content] -( - [core_state] ASC, - [core_access] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_access] ON [#__ucm_content] -( - [core_access] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_alias] ON [#__ucm_content] -( - [core_alias] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_language] ON [#__ucm_content] -( - [core_language] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_title] ON [#__ucm_content] -( - [core_title] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_modified_time] ON [#__ucm_content] -( - [core_modified_time] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_created_time] ON [#__ucm_content] -( - [core_created_time] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_content_type] ON [#__ucm_content] -( - [core_type_alias] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_core_modified_user_id] ON [#__ucm_content] -( - [core_modified_user_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_core_checked_out_user_id] ON [#__ucm_content] -( - [core_checked_out_user_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_core_created_user_id] ON [#__ucm_content] -( - [core_created_user_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_core_type_id] ON [#__ucm_content] -( - [core_type_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - - -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 - 2018 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; - -SET IDENTITY_INSERT [#__extensions] OFF; - -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]) -SELECT 'menu', 'com_tags', 'Tags', '', 'Tags', 'index.php?option=com_tags', 'component', 0, 1, 1, 29, 0, '1900-01-01 00:00:00', 0, 0, 'class:tags', 0, '', 43, 44, 0, '*', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.1.1.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.1.1.sql deleted file mode 100644 index df442faa0ef8d..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.1.1.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.1.1 \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.1.2.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.1.2.sql deleted file mode 100644 index 9e4e64ffbffed..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.1.2.sql +++ /dev/null @@ -1,16 +0,0 @@ -UPDATE [#__content_types] SET [table] = '{"special":{"dbtable":"#__content","key":"id","type":"Content","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE [type_title] = 'Article'; -UPDATE [#__content_types] SET [table] = '{"special":{"dbtable":"#__contact_details","key":"id","type":"Contact","prefix":"ContactTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE [type_title] = 'Contact'; -UPDATE [#__content_types] SET [table] = '{"special":{"dbtable":"#__newsfeeds","key":"id","type":"Newsfeed","prefix":"NewsfeedsTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE [type_title] = 'Newsfeed'; -UPDATE [#__content_types] SET [table] = '{"special":{"dbtable":"#__users","key":"id","type":"User","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE [type_title] = 'User'; -UPDATE [#__content_types] SET [table] = '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE [type_title] = 'Article Category'; -UPDATE [#__content_types] SET [table] = '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE [type_title] = 'Contact Category'; -UPDATE [#__content_types] SET [table] = '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE [type_title] = 'Newsfeeds Category'; -UPDATE [#__content_types] SET [table] = '{"special":{"dbtable":"#__tags","key":"tag_id","type":"Tag","prefix":"TagsTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}' WHERE [type_title] = 'Tag'; -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"}, "special": {"fulltext":"fulltext"}}' WHERE [type_title] = 'Article'; -UPDATE [#__content_types] SET [field_mappings] = '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"address", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"image", "core_urls":"webpage", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}, "special": {"con_position":"con_position","suburb":"suburb","state":"state","country":"country","postcode":"postcode","telephone":"telephone","fax":"fax","misc":"misc","email_to":"email_to","default_con":"default_con","user_id":"user_id","mobile":"mobile","sortname1":"sortname1","sortname2":"sortname2","sortname3":"sortname3"}}' WHERE [type_title] = 'Contact'; -UPDATE [#__content_types] SET [field_mappings] = '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"description", "core_hits":"hits","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"link", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}, "special": {"numarticles":"numarticles","cache_time":"cache_time","rtl":"rtl"}}' WHERE [type_title] = 'Newsfeed'; -UPDATE [#__content_types] SET [field_mappings] = '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"null","core_alias":"username","core_created_time":"registerdate","core_modified_time":"lastvisitDate","core_body":"null", "core_hits":"null","core_publish_up":"null","core_publish_down":"null","access":"null", "core_params":"params", "core_featured":"null", "core_metadata":"null", "core_language":"null", "core_images":"null", "core_urls":"null", "core_version":"null", "core_ordering":"null", "core_metakey":"null", "core_metadesc":"null", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}, "special": {}}' WHERE [type_title] = 'User'; -UPDATE [#__content_types] SET [field_mappings] = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}' WHERE [type_title] = 'Article Category'; -UPDATE [#__content_types] SET [field_mappings] = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}' WHERE [type_title] = 'Contact Category'; -UPDATE [#__content_types] SET [field_mappings] = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}' WHERE [type_title] = 'Newsfeeds Category'; -UPDATE [#__content_types] SET [field_mappings] = '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"featured", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"urls", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"null", "core_xreference":"null", "asset_id":"null"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path"}}' WHERE [type_title] = 'Tag'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.1.3.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.1.3.sql deleted file mode 100644 index ebc1102eb1eeb..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.1.3.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.1.3 diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.1.4.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.1.4.sql deleted file mode 100644 index 1521a450952fb..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.1.4.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 104, 'IDNA Convert', 'library', 'idna_convert', '', 0, 1, 1, 1, '', '', '', '', 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.1.5.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.1.5.sql deleted file mode 100644 index 2c9caba74fc12..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.1.5.sql +++ /dev/null @@ -1 +0,0 @@ -# Placeholder file for database changes for version 3.1.5 diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.2.0.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.0.sql deleted file mode 100644 index 1d7fcff2a325c..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.2.0.sql +++ /dev/null @@ -1,184 +0,0 @@ -/* Core 3.2 schema updates */ - -ALTER TABLE [#__content_types] ADD [content_history_options] [nvarchar] (max) NULL; - -UPDATE [#__content_types] SET [content_history_options] = '{"formFile":"administrator\/components\/com_content\/models\/forms\/article.xml", "hideFields":["asset_id","checked_out","checked_out_time","version"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "hits"],"convertToInt":["publish_up", "publish_down", "featured", "ordering"],"displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"} ]}' WHERE [type_alias] = 'com_content.article'; -UPDATE [#__content_types] SET [content_history_options] = '{"formFile":"administrator\/components\/com_contact\/models\/forms\/contact.xml","hideFields":["default_con","checked_out","checked_out_time","version","xreference"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "hits"],"convertToInt":["publish_up", "publish_down", "featured", "ordering"], "displayLookup":[ {"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"} ] }' WHERE [type_alias] = 'com_contact.contact'; -UPDATE [#__content_types] SET [content_history_options] = '{"formFile":"administrator\/components\/com_categories\/models\/forms\/category.xml", "hideFields":["asset_id","checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"],"convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"parent_id","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}]}' WHERE [type_alias] IN ('com_content.category', 'com_contact.category', 'com_newsfeeds.category'); -UPDATE [#__content_types] SET [content_history_options] = '{"formFile":"administrator\/components\/com_newsfeeds\/models\/forms\/newsfeed.xml","hideFields":["asset_id","checked_out","checked_out_time","version"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "hits"],"convertToInt":["publish_up", "publish_down", "featured", "ordering"],"displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}' WHERE [type_alias] = 'com_newsfeeds.newsfeed'; -UPDATE [#__content_types] SET [content_history_options] = '{"formFile":"administrator\/components\/com_tags\/models\/forms\/tag.xml", "hideFields":["checked_out","checked_out_time","version", "lft", "rgt", "level", "path", "urls", "publish_up", "publish_down"],"ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"],"convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"}, {"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}' WHERE [type_alias] = 'com_tags.tag'; - -INSERT INTO [#__content_types] ([type_title], [type_alias], [table], [rules], [field_mappings], [router], [content_history_options]) -SELECT 'Banner', 'com_banners.banner', '{"special":{"dbtable":"#__banners","key":"id","type":"Banner","prefix":"BannersTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":{"core_content_item_id":"id","core_title":"name","core_state":"published","core_alias":"alias","core_created_time":"created","core_modified_time":"modified","core_body":"description", "core_hits":"null","core_publish_up":"publish_up","core_publish_down":"publish_down","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"images", "core_urls":"link", "core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"catid", "core_xreference":"null", "asset_id":"null"}, "special":{"imptotal":"imptotal", "impmade":"impmade", "clicks":"clicks", "clickurl":"clickurl", "custombannercode":"custombannercode", "cid":"cid", "purchase_type":"purchase_type", "track_impressions":"track_impressions", "track_clicks":"track_clicks"}}', '', '{"formFile":"administrator\/components\/com_banners\/models\/forms\/banner.xml", "hideFields":["checked_out","checked_out_time","version", "reset"],"ignoreChanges":["modified_by", "modified", "checked_out", "checked_out_time", "version", "imptotal", "impmade", "reset"], "convertToInt":["publish_up", "publish_down", "ordering"], "displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}, {"sourceColumn":"cid","targetTable":"#__banner_clients","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"created_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"modified_by","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}' -UNION ALL -SELECT 'Banners Category', 'com_banners.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special": {"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}', '', '{"formFile":"administrator\/components\/com_categories\/models\/forms\/category.xml", "hideFields":["asset_id","checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"], "convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"parent_id","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}]}' -UNION ALL -SELECT 'Banner Client', 'com_banners.client', '{"special":{"dbtable":"#__banner_clients","key":"id","type":"Client","prefix":"BannersTable"}}', '', '', '', '{"formFile":"administrator\/components\/com_banners\/models\/forms\/client.xml", "hideFields":["checked_out","checked_out_time"], "ignoreChanges":["checked_out", "checked_out_time"], "convertToInt":[], "displayLookup":[]}' -UNION ALL -SELECT 'User Notes', 'com_users.note', '{"special":{"dbtable":"#__user_notes","key":"id","type":"Note","prefix":"UsersTable"}}', '', '', '', '{"formFile":"administrator\/components\/com_users\/models\/forms\/note.xml", "hideFields":["checked_out","checked_out_time", "publish_up", "publish_down"],"ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time"], "convertToInt":["publish_up", "publish_down"],"displayLookup":[{"sourceColumn":"catid","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}, {"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}]}' -UNION ALL -SELECT 'User Notes Category', 'com_users.category', '{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}', '', '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"published","core_alias":"alias","core_created_time":"created_time","core_modified_time":"modified_time","core_body":"description", "core_hits":"hits","core_publish_up":"null","core_publish_down":"null","core_access":"access", "core_params":"params", "core_featured":"null", "core_metadata":"metadata", "core_language":"language", "core_images":"null", "core_urls":"null", "core_version":"version", "core_ordering":"null", "core_metakey":"metakey", "core_metadesc":"metadesc", "core_catid":"parent_id", "core_xreference":"null", "asset_id":"asset_id"}, "special":{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}', '', '{"formFile":"administrator\/components\/com_categories\/models\/forms\/category.xml", "hideFields":["checked_out","checked_out_time","version","lft","rgt","level","path","extension"], "ignoreChanges":["modified_user_id", "modified_time", "checked_out", "checked_out_time", "version", "hits", "path"], "convertToInt":["publish_up", "publish_down"], "displayLookup":[{"sourceColumn":"created_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"}, {"sourceColumn":"access","targetTable":"#__viewlevels","targetColumn":"id","displayColumn":"title"},{"sourceColumn":"modified_user_id","targetTable":"#__users","targetColumn":"id","displayColumn":"name"},{"sourceColumn":"parent_id","targetTable":"#__categories","targetColumn":"id","displayColumn":"title"}]}'; - -UPDATE [#__extensions] SET [params] = '{"template_positions_display":"0","upload_limit":"2","image_formats":"gif,bmp,jpg,jpeg,png","source_formats":"txt,less,ini,xml,js,php,css","font_formats":"woff,ttf,otf","compressed_formats":"zip"}' WHERE [extension_id] = 20; -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; - -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 30, 'com_contenthistory', 'component', 'com_contenthistory', '', 1, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 31, 'com_ajax', 'component', 'com_ajax', '', 1, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 32, 'com_postinstall', 'component', 'com_postinstall', '', 1, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 105, 'FOF', 'library', 'fof', '', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 448, 'plg_twofactorauth_totp', 'plugin', 'totp', 'twofactorauth', 0, 0, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 449, 'plg_authentication_cookie', 'plugin', 'cookie', 'authentication', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 450, 'plg_twofactorauth_yubikey', 'plugin', 'yubikey', 'twofactorauth', 0, 0, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0; - -SET IDENTITY_INSERT [#__extensions] OFF; - -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]) -SELECT 'menu', 'com_postinstall', 'Post-installation messages', '', 'Post-installation messages', 'index.php?option=com_postinstall', 'component', 0, 1, 1, 32, 0, '1900-01-01 00:00:00', 0, 1, 'class:postinstall', 0, '', 45, 46, 0, '*', 1; - -ALTER TABLE [#__modules] ADD [asset_id] [bigint] NOT NULL DEFAULT 0; - -CREATE TABLE [#__postinstall_messages] ( - [postinstall_message_id] [bigint] IDENTITY(1,1) NOT NULL, - [extension_id] [bigint] NOT NULL DEFAULT 700, - [title_key] [nvarchar](255) NOT NULL DEFAULT '', - [description_key] [nvarchar](255) NOT NULL DEFAULT '', - [action_key] [nvarchar](255) NOT NULL DEFAULT '', - [language_extension] [nvarchar](255) NOT NULL DEFAULT 'com_postinstall', - [language_client_id] [int] NOT NULL DEFAULT 1, - [type] [nvarchar](10) NOT NULL DEFAULT 'link', - [action_file] [nvarchar](255) DEFAULT '', - [action] [nvarchar](255) DEFAULT '', - [condition_file] [nvarchar](255) DEFAULT NULL, - [condition_method] [nvarchar](255) DEFAULT NULL, - [version_introduced] [nvarchar](50) NOT NULL DEFAULT '3.2.0', - [enabled] [int] NOT NULL DEFAULT 1, - CONSTRAINT [PK_#__postinstall_message_id] PRIMARY KEY CLUSTERED - ( - [postinstall_message_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]; - -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, 'PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_TITLE', 'PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_BODY', 'PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_ACTION', 'plg_twofactorauth_totp', 1, 'action', 'site://plugins/twofactorauth/totp/postinstall/actions.php', 'twofactorauth_postinstall_action', 'site://plugins/twofactorauth/totp/postinstall/actions.php', 'twofactorauth_postinstall_condition', '3.2.0', 1 -UNION ALL -SELECT 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 [#__ucm_history] ( - [version_id] [bigint] IDENTITY(1,1) NOT NULL, - [ucm_item_id] [bigint] NOT NULL, - [ucm_type_id] [bigint] NOT NULL, - [version_note] [nvarchar](255) NOT NULL DEFAULT '', - [save_date] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [editor_user_id] [bigint] NOT NULL DEFAULT 0, - [character_count] [bigint] NOT NULL DEFAULT 0, - [sha1_hash] [nvarchar](50) NOT NULL DEFAULT '', - [version_data] [nvarchar](max) NOT NULL, - [keep_forever] [smallint] NOT NULL DEFAULT 0, - CONSTRAINT [PK_#__ucm_history_version_id] PRIMARY KEY CLUSTERED - ( - [version_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] TEXTIMAGE_ON [PRIMARY]; - -CREATE NONCLUSTERED INDEX [idx_ucm_item_id] ON [#__ucm_history] -( - [ucm_type_id] ASC, - [ucm_item_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_save_date] ON [#__ucm_history] -( - [save_date] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -ALTER TABLE [#__users] ADD [otpKey] [nvarchar](1000) NOT NULL DEFAULT ''; - -ALTER TABLE [#__users] ADD [otep] [nvarchar](1000) NOT NULL DEFAULT ''; - -CREATE TABLE [#__user_keys] ( - [id] [bigint] IDENTITY(1,1) NOT NULL, - [user_id] [nvarchar](255) NOT NULL, - [token] [nvarchar](255) NOT NULL, - [series] [nvarchar](255) NOT NULL, - [invalid] [smallint] NOT NULL, - [time] [nvarchar](200) NOT NULL, - [uastring] [nvarchar](255) NOT NULL, - CONSTRAINT [PK_#__user_keys_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], - CONSTRAINT [#__user_keys$series] UNIQUE NONCLUSTERED - ( - [series] ASC - )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], - CONSTRAINT [#__user_keys$series_2] UNIQUE NONCLUSTERED - ( - [series] ASC - )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], - CONSTRAINT [#__user_keys$series_3] UNIQUE NONCLUSTERED - ( - [series] 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 [user_id] ON [#__user_keys] -( - [user_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -/* Queries below sync the schema to MySQL where able without causing errors */ - -ALTER TABLE [#__contentitem_tag_map] ADD [type_id] [int] NOT NULL; - -CREATE NONCLUSTERED INDEX [idx_type] ON [#__contentitem_tag_map] -( - [type_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -ALTER TABLE [#__newsfeeds] ALTER COLUMN [alias] [nvarchar](255) NOT NULL; - -ALTER TABLE [#__overrider] ALTER COLUMN [constant] [nvarchar](255) NOT NULL; -ALTER TABLE [#__overrider] ALTER COLUMN [string] [nvarchar](max) NOT NULL; -ALTER TABLE [#__overrider] ALTER COLUMN [file] [nvarchar](255) NOT NULL; - -ALTER TABLE [#__session] DROP COLUMN [usertype]; - -ALTER TABLE [#__ucm_content] ALTER COLUMN [core_metadata] [nvarchar](2048) NOT NULL; - -CREATE PROCEDURE "#removeDefault" -( - @table NVARCHAR(100), - @column NVARCHAR(100) -) -AS -BEGIN - DECLARE @constraintName AS nvarchar(100) - DECLARE @constraintQuery AS nvarchar(1000) - SELECT @constraintName = name FROM sys.default_constraints - WHERE parent_object_id = object_id(@table) - AND parent_column_id = columnproperty(object_id(@table), @column, 'ColumnId') - SET @constraintQuery = 'ALTER TABLE [' + @table + '] DROP CONSTRAINT [' + @constraintName + ']' - EXECUTE sp_executesql @constraintQuery -END; - -EXECUTE "#removeDefault" "#__ucm_content", 'core_content_item_id'; -EXECUTE "#removeDefault" "#__ucm_content", 'asset_id'; -EXECUTE "#removeDefault" "#__ucm_content", 'core_type_id'; - -EXECUTE "#removeDefault" "#__updates", 'categoryid'; -ALTER TABLE [#__updates] DROP COLUMN [categoryid]; - -ALTER TABLE [#__updates] ALTER COLUMN [infourl] [nvarchar](max) NOT NULL; - -/* Update bad params for two cpanel modules */ - -UPDATE [#__modules] SET [params] = REPLACE([params], '"bootstrap_size":"1"', '"bootstrap_size":"0"') WHERE [id] IN (3,4); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.2.1.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.1.sql deleted file mode 100644 index e7e9002f8f11b..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.2.1.sql +++ /dev/null @@ -1 +0,0 @@ -DELETE FROM [#__postinstall_messages] WHERE [title_key] = 'PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_TITLE'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2013-12-22.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2013-12-22.sql deleted file mode 100644 index b629a80676c11..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2013-12-22.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE [#__update_sites] ADD [extra_query] [nvarchar](1000) NULL DEFAULT ''; -ALTER TABLE [#__updates] ADD [extra_query] [nvarchar](1000) NULL DEFAULT ''; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2013-12-28.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2013-12-28.sql deleted file mode 100644 index ec8916d02c164..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2013-12-28.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE [#__menu] SET [component_id] = (SELECT [extension_id] FROM [#__extensions] WHERE [element] = 'com_joomlaupdate') WHERE [link] = 'index.php?option=com_joomlaupdate'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-08.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-08.sql deleted file mode 100644 index fbe9b6afbc511..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-08.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 403, 'plg_content_contact', 'plugin', 'contact', 'content', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 1, 0; - -SET IDENTITY_INSERT [#__extensions] OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-15.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-15.sql deleted file mode 100644 index 9903a08b0e6e4..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-15.sql +++ /dev/null @@ -1,2 +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]) -SELECT 700, 'COM_CPANEL_MSG_PHPVERSION_TITLE', 'COM_CPANEL_MSG_PHPVERSION_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/phpversion.php', 'admin_postinstall_phpversion_condition', '3.2.2', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-18.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-18.sql deleted file mode 100644 index f190ea7fa0140..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-18.sql +++ /dev/null @@ -1,2 +0,0 @@ -/* Update updates version length */ -ALTER TABLE [#__updates] ALTER COLUMN [version] [nvarchar](32); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-23.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-23.sql deleted file mode 100644 index 57e62d7b2a894..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.2.2-2014-01-23.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 106, 'PHPass', 'library', 'phpass', '', 0, 1, 1, 1, '', '', '', '', 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.2.3-2014-02-20.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.3-2014-02-20.sql deleted file mode 100644 index 0c4ac188da3c8..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.2.3-2014-02-20.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE [#__extensions] SET [params] = (SELECT [params] FROM [#__extensions] WHERE [name] = 'plg_system_remember') WHERE [name] = 'plg_authentication_cookie'; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.3.0-2014-02-16.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.3.0-2014-02-16.sql deleted file mode 100644 index bc5de3d53721a..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.3.0-2014-02-16.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE [#__users] ADD [requireReset] [smallint] NULL DEFAULT 0; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.3.0-2014-04-02.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.3.0-2014-04-02.sql deleted file mode 100644 index 40d8bda560390..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.3.0-2014-04-02.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 451, 'plg_search_tags', 'plugin', 'tags', 'search', 0, 0, 1, 0, '', '{"search_limit":"50","show_tagged_items":"1"}', '', '', 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.3.4-2014-08-03.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.3.4-2014-08-03.sql deleted file mode 100644 index b807ea75025b6..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.3.4-2014-08-03.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE [#__user_profiles] ALTER COLUMN [profile_value] [nvarchar](max) NOT NULL; 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 deleted file mode 100644 index 1ff46584f11cd..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.3.6-2014-09-30.sql +++ /dev/null @@ -1,5 +0,0 @@ -INSERT INTO [#__update_sites] ([name], [type], [location], [enabled]) -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.4.0-2014-08-24.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-08-24.sql deleted file mode 100644 index 3927cec9af5dd..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-08-24.sql +++ /dev/null @@ -1,2 +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]) -SELECT 700, 'COM_CPANEL_MSG_HTACCESS_TITLE', 'COM_CPANEL_MSG_HTACCESS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/htaccess.php', 'admin_postinstall_htaccess_condition', '3.4.0', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-09-01.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-09-01.sql deleted file mode 100644 index da5e9371f4d0b..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-09-01.sql +++ /dev/null @@ -1,12 +0,0 @@ -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 801, 'weblinks', 'package', 'pkg_weblinks', '', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0; - -SET IDENTITY_INSERT [#__extensions] OFF; - -INSERT INTO [#__update_sites] ([name], [type], [location], [enabled]) -SELECT 'Weblinks Update Site', 'extension', 'https://raw.githubusercontent.com/joomla-extensions/weblinks/master/manifest.xml', 1; - -INSERT INTO [#__update_sites_extensions] ([update_site_id], [extension_id]) -SELECT (SELECT [update_site_id] FROM [#__update_sites] WHERE [name] = 'Weblinks Update Site'), 801; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-09-16.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-09-16.sql deleted file mode 100644 index 0238aa251b9b7..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-09-16.sql +++ /dev/null @@ -1,6 +0,0 @@ -ALTER TABLE [#__redirect_links] ADD [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 --- --- ALTER TABLE [#__redirect_links] ALTER COLUMN [new_url] [nvarchar](255) NULL; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-10-20.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-10-20.sql deleted file mode 100644 index 2cb4da10c7b79..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-10-20.sql +++ /dev/null @@ -1 +0,0 @@ -DELETE FROM [#__extensions] WHERE [extension_id] = 100; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-12-03.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-12-03.sql deleted file mode 100644 index 1fe05e9e99028..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2014-12-03.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE [#__extensions] SET [protected] = '0' WHERE [name] = 'plg_editors-xtd_article' AND [type] = 'plugin' AND [element] = 'article' AND [folder] = 'editors-xtd'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2015-01-21.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2015-01-21.sql deleted file mode 100644 index 555a71c1af192..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2015-01-21.sql +++ /dev/null @@ -1,2 +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]) -SELECT 700, 'COM_CPANEL_MSG_ROBOTS_TITLE', 'COM_CPANEL_MSG_ROBOTS_BODY', '', 'com_cpanel', 1, 'message', '', '', '', '', '3.3.0', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2015-02-26.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2015-02-26.sql deleted file mode 100644 index 3125cd02f79bb..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.4.0-2015-02-26.sql +++ /dev/null @@ -1,2 +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]) -SELECT 700, 'COM_CPANEL_MSG_LANGUAGEACCESS340_TITLE', 'COM_CPANEL_MSG_LANGUAGEACCESS340_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/languageaccess340.php', 'admin_postinstall_languageaccess340_condition', '3.4.1', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.4.4-2015-07-11.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.4.4-2015-07-11.sql deleted file mode 100644 index de9ce373a4d3f..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.4.4-2015-07-11.sql +++ /dev/null @@ -1,8 +0,0 @@ -ALTER TABLE [#__contentitem_tag_map] DROP CONSTRAINT [#__contentitem_tag_map$uc_ItemnameTagid]; - -ALTER TABLE [#__contentitem_tag_map] ADD CONSTRAINT [#__contentitem_tag_map$uc_ItemnameTagid] UNIQUE NONCLUSTERED -( - [type_id] ASC, - [content_item_id] ASC, - [tag_id] ASC -)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-13.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-13.sql deleted file mode 100644 index b58a8e7a0f236..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-13.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 453, 'plg_editors-xtd_module', 'plugin', 'module', 'editors-xtd', 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.5.0-2015-10-26.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-26.sql deleted file mode 100644 index c908def7263ec..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-26.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP INDEX [idx_tag_name] ON [#__contentitem_tag_map]; -DROP INDEX [idx_tag] ON [#__contentitem_tag_map]; -DROP INDEX [idx_type] ON [#__contentitem_tag_map]; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-30.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-30.sql deleted file mode 100644 index 48ddf71b98fa9..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-10-30.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE [#__menu] SET [title] = 'com_contact_contacts' WHERE [client_id] = 1 AND [level] = 2 AND [title] = 'com_contact'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-11-04.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-11-04.sql deleted file mode 100644 index 1de0da4e7967e..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-11-04.sql +++ /dev/null @@ -1,8 +0,0 @@ -DELETE FROM [#__menu] WHERE [title] = 'com_messages_read' AND [client_id] = 1; - -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 452, 'plg_system_updatenotification', 'plugin', 'updatenotification', 'system', 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.5.0-2015-11-05.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-11-05.sql deleted file mode 100644 index 3ff42e5f136f0..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2015-11-05.sql +++ /dev/null @@ -1,9 +0,0 @@ -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 454, 'plg_system_stats', 'plugin', 'stats', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0; - -SET IDENTITY_INSERT [#__extensions] OFF; - -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_STATS_COLLECTION_TITLE', 'COM_CPANEL_MSG_STATS_COLLECTION_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/statscollection.php', 'admin_postinstall_statscollection_condition', '3.5.0', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2016-03-01.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2016-03-01.sql deleted file mode 100644 index 898025eaf94eb..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.5.0-2016-03-01.sql +++ /dev/null @@ -1,15 +0,0 @@ -ALTER TABLE [#__redirect_links] DROP CONSTRAINT [#__redirect_links$idx_link_old]; -ALTER TABLE [#__redirect_links] ALTER COLUMN [old_url] [nvarchar](2048) NOT NULL; - --- --- The following statement had to be modified for 3.6.0 by removing the --- NOT NULL, which was wrong because not consistent with new install. --- See also 3.6.0-2016-04-06.sql for updating 3.5.0 or 3.5.1 --- -ALTER TABLE [#__redirect_links] ALTER COLUMN [new_url] [nvarchar](2048); - -ALTER TABLE [#__redirect_links] ALTER COLUMN [referer] [nvarchar](2048) NOT NULL; -CREATE NONCLUSTERED INDEX [idx_old_url] ON [#__redirect_links] -( - [old_url] 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.6.0-2016-04-01.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-01.sql deleted file mode 100644 index 45dcf467e5c19..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-01.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Rename update site names -UPDATE [#__update_sites] SET [name] = 'Joomla! Core' WHERE [name] = 'Joomla Core' AND [type] = 'collection'; -UPDATE [#__update_sites] SET [name] = 'Joomla! Extension Directory' WHERE [name] = 'Joomla Extension Directory' AND [type] = 'collection'; - -UPDATE [#__update_sites] SET [location] = 'https://update.joomla.org/core/list.xml' WHERE [name] = 'Joomla! Core' AND [type] = 'collection'; -UPDATE [#__update_sites] SET [location] = 'https://update.joomla.org/jed/list.xml' WHERE [name] = 'Joomla! Extension Directory' AND [type] = 'collection'; -UPDATE [#__update_sites] SET [location] = 'https://update.joomla.org/language/translationlist_3.xml' WHERE [name] = 'Accredited Joomla! Translations' AND [type] = 'collection'; -UPDATE [#__update_sites] SET [location] = 'https://update.joomla.org/core/extensions/com_joomlaupdate.xml' WHERE [name] = 'Joomla! Update Component Update Site' AND [type] = 'extension'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-06.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-06.sql deleted file mode 100644 index fe7dc8e6b9ec2..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-06.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE [#__redirect_links] ALTER COLUMN [new_url] [nvarchar](2048); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-08.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-08.sql deleted file mode 100644 index c343067a9eb2d..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-08.sql +++ /dev/null @@ -1,16 +0,0 @@ -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 802, 'English (United Kingdom)', 'package', 'pkg_en-GB', '', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0; - -SET IDENTITY_INSERT [#__extensions] OFF; - -UPDATE [#__update_sites_extensions] -SET [extension_id] = 802 -WHERE [update_site_id] IN ( - SELECT [update_site_id] - FROM [#__update_sites] - WHERE [name] = 'Accredited Joomla! Translations' - AND [type] = 'collection' - ) -AND [extension_id] = 600; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-09.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-09.sql deleted file mode 100644 index 33fab71ec62ac..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-04-09.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- Add ACL check for to #__menu_types --- - -ALTER TABLE [#__menu_types] ADD [asset_id] [bigint] NOT NULL DEFAULT 0; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-05-06.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-05-06.sql deleted file mode 100644 index 18665f63f01ba..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-05-06.sql +++ /dev/null @@ -1,12 +0,0 @@ -DELETE FROM [#__extensions] WHERE [type] = 'library' AND [element] = 'simplepie'; - -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 455, 'plg_installer_packageinstaller', 'plugin', 'packageinstaller', 'installer', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 1, 0 -UNION ALL -SELECT 456, 'plg_installer_folderinstaller', 'plugin', 'folderinstaller', 'installer', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 2, 0 -UNION ALL -SELECT 457, 'plg_installer_urlinstaller', 'plugin', 'urlinstaller', 'installer', 0, 1, 1, 1, '', '', '', '', 0, '1900-01-01 00:00:00', 3, 0; - -SET IDENTITY_INSERT [#__extensions] OFF; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-06-01.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-06-01.sql deleted file mode 100644 index 3a547b55371be..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-06-01.sql +++ /dev/null @@ -1 +0,0 @@ -UPDATE [#__extensions] SET [protected] = 1, [enabled] = 1 WHERE [name] = 'com_ajax'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-06-05.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-06-05.sql deleted file mode 100644 index 9355db71a3667..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.6.0-2016-06-05.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- Add ACL check for to #__languages --- - -ALTER TABLE [#__languages] ADD [asset_id] [bigint] NOT NULL DEFAULT 0; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.6.3-2016-08-15.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.6.3-2016-08-15.sql deleted file mode 100644 index 515854cd88735..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.6.3-2016-08-15.sql +++ /dev/null @@ -1,5 +0,0 @@ --- --- Increasing size of the URL field in com_newsfeeds --- - -ALTER TABLE [#__newsfeeds] ALTER COLUMN [link] [nvarchar](2048) NOT NULL; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.6.3-2016-08-16.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.6.3-2016-08-16.sql deleted file mode 100644 index c54563d9b41ed..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.6.3-2016-08-16.sql +++ /dev/null @@ -1,2 +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]) -SELECT 700, 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_BODY', 'PLG_SYSTEM_UPDATENOTIFICATION_POSTINSTALL_UPDATECACHETIME_ACTION', 'plg_system_updatenotification', 1, 'action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_action', 'site://plugins/system/updatenotification/postinstall/updatecachetime.php', 'updatecachetime_postinstall_condition', '3.6.3', 1; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-06.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-06.sql deleted file mode 100644 index feec2ca85b9fe..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-06.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 458, 'plg_quickicon_phpversioncheck', 'plugin', 'phpversioncheck', 'quickicon', 0, 1, 1, 1, '', '', '', '', 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.7.0-2016-08-22.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-22.sql deleted file mode 100644 index 6a9744ef65189..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-22.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 459, 'plg_editors-xtd_menu', 'plugin', 'menu', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0; - -SET IDENTITY_INSERT [#__extensions] OFF; \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-29.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-29.sql deleted file mode 100644 index 8562696647e42..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-08-29.sql +++ /dev/null @@ -1,144 +0,0 @@ -/****** Object: Table [#__fields] ******/ - -SET QUOTED_IDENTIFIER ON; - -CREATE TABLE [#__fields] ( - [id] [int] IDENTITY(1,1) NOT NULL, - [asset_id] [int] NOT NULL DEFAULT 0, - [context] [nvarchar](255) NOT NULL DEFAULT '', - [group_id] [int] NOT NULL DEFAULT 0, - [title] [nvarchar](255) NOT NULL DEFAULT '', - [name] [nvarchar](255) NOT NULL DEFAULT '', - [label] [nvarchar](255) NOT NULL DEFAULT '', - [default_value] [nvarchar](max) NOT NULL DEFAULT '', - [type] [nvarchar](255) NOT NULL DEFAULT '', - [note] [nvarchar](255) NOT NULL DEFAULT '', - [description] [nvarchar](max) NOT NULL DEFAULT '', - [state] [smallint] NOT NULL DEFAULT 0, - [required] [smallint] NOT NULL DEFAULT 0, - [checked_out] [bigint] NOT NULL DEFAULT 0, - [checked_out_time] [datetime] NOT NULL DEFAULT '1900-01-01 00:00:00', - [ordering] [int] NOT NULL DEFAULT 0, - [params] [nvarchar](max) NOT NULL DEFAULT '', - [fieldparams] [nvarchar](max) NOT NULL DEFAULT '', - [language] [nvarchar](7) NOT NULL DEFAULT '', - [created_time] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [created_user_id] [bigint] NOT NULL DEFAULT 0, - [modified_time] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [modified_by] [bigint] NOT NULL DEFAULT 0, - [access] [int] NOT NULL DEFAULT 1, -CONSTRAINT [PK_#__fields_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 [#__fields]( - [checked_out] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_state] ON [#__fields]( - [state] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_access] ON [#__fields]( - [access] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_context] ON [#__fields]( - [context] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_language] ON [#__fields]( - [language] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -/****** Object: Table [#__fields_categories] ******/ - -SET QUOTED_IDENTIFIER ON; - -CREATE TABLE [#__fields_categories] ( - [field_id] [int] NOT NULL DEFAULT 0, - [category_id] [int] NOT NULL DEFAULT 0, -CONSTRAINT [PK_#__fields_categories_id] PRIMARY KEY CLUSTERED( - [field_id] ASC, - [category_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]; - -/****** Object: Table [#__fields_groups] ******/ - -SET QUOTED_IDENTIFIER ON; - -CREATE TABLE [#__fields_groups] ( - [id] [int] IDENTITY(1,1) NOT NULL, - [asset_id] [int] NOT NULL DEFAULT 0, - [context] [nvarchar](255) NOT NULL DEFAULT '', - [title] [nvarchar](255) NOT NULL DEFAULT '', - [note] [nvarchar](255) NOT NULL DEFAULT '', - [description] [nvarchar](max) NOT NULL DEFAULT '', - [state] [smallint] NOT NULL DEFAULT 0, - [checked_out] [bigint] NOT NULL DEFAULT 0, - [checked_out_time] [datetime] NOT NULL DEFAULT '1900-01-01 00:00:00', - [ordering] [int] NOT NULL DEFAULT 0, - [language] [nvarchar](7) NOT NULL DEFAULT '', - [created] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [created_by] [bigint] NOT NULL DEFAULT 0, - [modified] [datetime] NOT NULL DEFAULT '1900-01-01T00:00:00.000', - [modified_by] [bigint] NOT NULL DEFAULT 0, - [access] [int] NOT NULL DEFAULT 1, -CONSTRAINT [PK_#__fields_groups_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 [#__fields_groups]( - [checked_out] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_state] ON [#__fields_groups]( - [state] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_created_by] ON [#__fields_groups]( - [created_by] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_access] ON [#__fields_groups]( - [access] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_context] ON [#__fields_groups]( - [context] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_language] ON [#__fields_groups]( - [language] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -/****** Object: Table [#__fields_values] ******/ - -SET QUOTED_IDENTIFIER ON; - -CREATE TABLE [#__fields_values] ( - [field_id] [bigint] NOT NULL DEFAULT 1, - [item_id] [nvarchar](255) NOT NULL DEFAULT '', - [value] [nvarchar](max) NOT NULL DEFAULT '', -) ON [PRIMARY]; - -CREATE NONCLUSTERED INDEX [idx_field_id] ON [#__fields_values]( - [field_id] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE NONCLUSTERED INDEX [idx_item_id] ON [#__fields_values]( - [item_id] ASC) -WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -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 33, 'com_fields', 'component', 'com_fields', '', 1, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 461, 'plg_system_fields', 'plugin', 'fields', 'system', 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.7.0-2016-09-29.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-09-29.sql deleted file mode 100644 index 9cede5db91507..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-09-29.sql +++ /dev/null @@ -1,3 +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]) -SELECT 700, 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE', 'COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_BODY', '', 'com_cpanel', 1, 'message', '', '', 'admin://components/com_admin/postinstall/joomla40checks.php', 'admin_postinstall_joomla40checks_condition', '3.7.0', 1; - diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-10-01.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-10-01.sql deleted file mode 100644 index d975345be02cb..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-10-01.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 460, 'plg_editors-xtd_contact', 'plugin', 'contact', 'editors-xtd', 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.7.0-2016-10-02.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-10-02.sql deleted file mode 100644 index 1373275218f65..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-10-02.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE [#__session] ALTER COLUMN [client_id] [tinyint] NULL; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-04.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-04.sql deleted file mode 100644 index 8b40b5e1de68b..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-04.sql +++ /dev/null @@ -1,13 +0,0 @@ --- Change default value for enabled column. -DECLARE @table AS nvarchar(100) -DECLARE @constraintName AS nvarchar(100) -DECLARE @constraintQuery AS nvarchar(1000) -SET QUOTED_IDENTIFIER OFF -SET @table = "#__extensions" -SET QUOTED_IDENTIFIER ON -SELECT @constraintName = name FROM sys.default_constraints -WHERE parent_object_id = object_id(@table) -AND parent_column_id = columnproperty(object_id(@table), 'enabled', 'ColumnId') -SET @constraintQuery = 'ALTER TABLE [' + @table + '] DROP CONSTRAINT [' + @constraintName -+ ']; ALTER TABLE [' + @table + '] ADD CONSTRAINT [' + @constraintName + '] DEFAULT 0 FOR [enabled]' -EXECUTE sp_executesql @constraintQuery; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-19.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-19.sql deleted file mode 100644 index 01bd65750ac80..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-19.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE [#__menu_types] ADD [client_id] [tinyint] NOT NULL DEFAULT 0; - -UPDATE [#__menu] SET [published] = 1 WHERE [menutype] = 'main' OR [menutype] = 'menu'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-24.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-24.sql deleted file mode 100644 index 68d6dc8b541f2..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2016-11-24.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE [#__extensions] ADD [package_id] [bigint] NOT NULL DEFAULT 0; - -UPDATE [#__extensions] -SET [package_id] = (SELECT [extension_id] FROM [#__extensions] WHERE [type] = 'package' AND [element] = 'pkg_en-GB') -WHERE [type]= 'language' AND [element] = 'en-GB'; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-08.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-08.sql deleted file mode 100644 index d9b39bc584d13..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-08.sql +++ /dev/null @@ -1,32 +0,0 @@ --- Normalize ucm_content_table default values. -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_type_alias]; -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_body]; -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_params]; -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_metadata]; -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_language]; - -ALTER TABLE [#__ucm_content] DROP CONSTRAINT [#__ucm_content_core_content_id$idx_type_alias_item_id]; -ALTER TABLE [#__ucm_content] ALTER COLUMN [core_content_item_id] [bigint] NOT NULL; -ALTER TABLE [#__ucm_content] ADD CONSTRAINT [#__ucm_content_core_content_id$idx_type_alias_item_id] UNIQUE NONCLUSTERED -( - [core_type_alias] ASC, - [core_content_item_id] ASC -) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]; -ALTER TABLE [#__ucm_content] ADD DEFAULT (0) FOR [core_content_item_id]; - -ALTER TABLE [#__ucm_content] ALTER COLUMN [asset_id] [bigint] NOT NULL; -ALTER TABLE [#__ucm_content] ADD DEFAULT (0) FOR [asset_id]; - -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_images]; -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_urls]; -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_metakey]; -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_metadesc]; -ALTER TABLE [#__ucm_content] ADD DEFAULT ('') FOR [core_xreference]; - -DROP INDEX [idx_core_type_id] ON [#__ucm_content]; -ALTER TABLE [#__ucm_content] ALTER COLUMN [core_type_id] [bigint] NOT NULL; -CREATE NONCLUSTERED INDEX [idx_core_type_id] ON [#__ucm_content] -( - [core_type_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); -ALTER TABLE [#__ucm_content] ADD DEFAULT (0) FOR [core_type_id]; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-09.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-09.sql deleted file mode 100644 index 51ce67e0e420e..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-09.sql +++ /dev/null @@ -1,8 +0,0 @@ --- Normalize categories table default values. -ALTER TABLE [#__categories] ADD DEFAULT ('') FOR [title]; -ALTER TABLE [#__categories] ADD DEFAULT ('') FOR [description]; -ALTER TABLE [#__categories] ADD DEFAULT ('') FOR [params]; -ALTER TABLE [#__categories] ADD DEFAULT ('') FOR [metadesc]; -ALTER TABLE [#__categories] ADD DEFAULT ('') FOR [metakey]; -ALTER TABLE [#__categories] ADD DEFAULT ('') FOR [metadata]; -ALTER TABLE [#__categories] ADD DEFAULT ('') FOR [language]; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-15.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-15.sql deleted file mode 100644 index 802e5800ff11f..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-15.sql +++ /dev/null @@ -1,6 +0,0 @@ -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]) VALUES -(34, 'com_associations', 'component', 'com_associations', '', 1, 1, 1, 1, '', '', '', '', 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.7.0-2017-01-17.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-17.sql deleted file mode 100644 index 86ffa3836f9d5..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-17.sql +++ /dev/null @@ -1,95 +0,0 @@ --- Sync menutype for admin menu and set client_id correct --- 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; - -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 462, 'plg_fields_calendar', 'plugin', 'calendar', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 463, 'plg_fields_checkboxes', 'plugin', 'checkboxes', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 464, 'plg_fields_color', 'plugin', 'color', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 465, 'plg_fields_editor', 'plugin', 'editor', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 466, 'plg_fields_imagelist', 'plugin', 'imagelist', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 467, 'plg_fields_integer', 'plugin', 'integer', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 468, 'plg_fields_list', 'plugin', 'list', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 469, 'plg_fields_media', 'plugin', 'media', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 470, 'plg_fields_radio', 'plugin', 'radio', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 471, 'plg_fields_sql', 'plugin', 'sql', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 472, 'plg_fields_text', 'plugin', 'text', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 473, 'plg_fields_textarea', 'plugin', 'textarea', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 474, 'plg_fields_url', 'plugin', 'url', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 475, 'plg_fields_user', 'plugin', 'user', 'fields', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0 -UNION ALL -SELECT 476, 'plg_fields_usergrouplist', 'plugin', 'usergrouplist', '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.7.0-2017-01-31.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-31.sql deleted file mode 100644 index 9360176ab9bd9..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-01-31.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 477, 'plg_content_fields', 'plugin', 'fields', 'content', 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.7.0-2017-02-02.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-02.sql deleted file mode 100644 index 3261b8fb701e2..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-02.sql +++ /dev/null @@ -1,6 +0,0 @@ -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 478, 'plg_editors-xtd_fields', 'plugin', 'fields', 'editors-xtd', 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.7.0-2017-02-15.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-15.sql deleted file mode 100644 index 2ea8376cb5c2d..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-15.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Normalize redirect_links table default values. -ALTER TABLE [#__redirect_links] ADD DEFAULT ('') FOR [comment]; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-16.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-16.sql deleted file mode 100644 index 2f49b7268f8d3..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-16.sql +++ /dev/null @@ -1,329 +0,0 @@ --- Replace datetime to datetime2(0) type for all columns. -DROP INDEX [idx_track_date] ON [#__banner_tracks]; -ALTER TABLE [#__banner_tracks] DROP CONSTRAINT [PK_#__banner_tracks_track_date]; -ALTER TABLE [#__banner_tracks] ALTER COLUMN [track_date] [datetime2](0) NOT NULL; -ALTER TABLE [#__banner_tracks] ADD CONSTRAINT [PK_#__banner_tracks_track_date_type_id] PRIMARY KEY CLUSTERED -( - [track_date] ASC, - [track_type] ASC, - [banner_id] ASC -) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]; -CREATE NONCLUSTERED INDEX [idx_track_date2] ON [#__banner_tracks] -( - [track_date] ASC -) WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -CREATE PROCEDURE "#removeDefault" -( - @table NVARCHAR(100), - @column NVARCHAR(100) -) -AS -BEGIN - DECLARE @constraintName AS nvarchar(100) - DECLARE @constraintQuery AS nvarchar(1000) - SELECT @constraintName = name FROM sys.default_constraints - WHERE parent_object_id = object_id(@table) - AND parent_column_id = columnproperty(object_id(@table), @column, 'ColumnId') - SET @constraintQuery = 'ALTER TABLE [' + @table + '] DROP CONSTRAINT [' + @constraintName + ']' - EXECUTE sp_executesql @constraintQuery -END; - -EXECUTE "#removeDefault" "#__banner_clients", 'checked_out_time'; -ALTER TABLE [#__banner_clients] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__banner_clients] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__banners", 'checked_out_time'; -ALTER TABLE [#__banners] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__banners] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__banners", 'publish_up'; -ALTER TABLE [#__banners] ALTER COLUMN [publish_up] [datetime2](0) NOT NULL; -ALTER TABLE [#__banners] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_up]; - -EXECUTE "#removeDefault" "#__banners", 'publish_down'; -ALTER TABLE [#__banners] ALTER COLUMN [publish_down] [datetime2](0) NOT NULL; -ALTER TABLE [#__banners] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_down]; - -EXECUTE "#removeDefault" "#__banners", 'reset'; -ALTER TABLE [#__banners] ALTER COLUMN [reset] [datetime2](0) NOT NULL; -ALTER TABLE [#__banners] ADD DEFAULT '1900-01-01 00:00:00' FOR [reset]; - -EXECUTE "#removeDefault" "#__banners", 'created'; -ALTER TABLE [#__banners] ALTER COLUMN [created] [datetime2](0) NOT NULL; -ALTER TABLE [#__banners] ADD DEFAULT '1900-01-01 00:00:00' FOR [created]; - -EXECUTE "#removeDefault" "#__banners", 'modified'; -ALTER TABLE [#__banners] ALTER COLUMN [modified] [datetime2](0) NOT NULL; -ALTER TABLE [#__banners] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified]; - -DROP INDEX [idx_checked_out_time] ON [#__categories]; -EXECUTE "#removeDefault" "#__categories", 'checked_out_time'; -ALTER TABLE [#__categories] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__categories] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; -CREATE NONCLUSTERED INDEX [idx_checked_out_time2] ON [#__categories]( - [checked_out_time] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -EXECUTE "#removeDefault" "#__categories", 'created_time'; -ALTER TABLE [#__categories] ALTER COLUMN [created_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__categories] ADD DEFAULT '1900-01-01 00:00:00' FOR [created_time]; - -EXECUTE "#removeDefault" "#__categories", 'modified_time'; -ALTER TABLE [#__categories] ALTER COLUMN [modified_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__categories] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified_time]; - -EXECUTE "#removeDefault" "#__contact_details", 'checked_out_time'; -ALTER TABLE [#__contact_details] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__contact_details] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__contact_details", 'created'; -ALTER TABLE [#__contact_details] ALTER COLUMN [created] [datetime2](0) NOT NULL; -ALTER TABLE [#__contact_details] ADD DEFAULT '1900-01-01 00:00:00' FOR [created]; - -EXECUTE "#removeDefault" "#__contact_details", 'modified'; -ALTER TABLE [#__contact_details] ALTER COLUMN [modified] [datetime2](0) NOT NULL; -ALTER TABLE [#__contact_details] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified]; - -EXECUTE "#removeDefault" "#__contact_details", 'publish_up'; -ALTER TABLE [#__contact_details] ALTER COLUMN [publish_up] [datetime2](0) NOT NULL; -ALTER TABLE [#__contact_details] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_up]; - -EXECUTE "#removeDefault" "#__contact_details", 'publish_down'; -ALTER TABLE [#__contact_details] ALTER COLUMN [publish_down] [datetime2](0) NOT NULL; -ALTER TABLE [#__contact_details] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_down]; - -EXECUTE "#removeDefault" "#__content", 'created'; -ALTER TABLE [#__content] ALTER COLUMN [created] [datetime2](0) NOT NULL; -ALTER TABLE [#__content] ADD DEFAULT '1900-01-01 00:00:00' FOR [created]; - -EXECUTE "#removeDefault" "#__content", 'modified'; -ALTER TABLE [#__content] ALTER COLUMN [modified] [datetime2](0) NOT NULL; -ALTER TABLE [#__content] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified]; - -EXECUTE "#removeDefault" "#__content", 'checked_out_time'; -ALTER TABLE [#__content] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__content] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__content", 'publish_up'; -ALTER TABLE [#__content] ALTER COLUMN [publish_up] [datetime2](0) NOT NULL; -ALTER TABLE [#__content] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_up]; - -EXECUTE "#removeDefault" "#__content", 'publish_down'; -ALTER TABLE [#__content] ALTER COLUMN [publish_down] [datetime2](0) NOT NULL; -ALTER TABLE [#__content] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_down]; - -DROP INDEX [idx_date_id] ON [#__contentitem_tag_map]; -EXECUTE "#removeDefault" "#__contentitem_tag_map", 'tag_date'; -ALTER TABLE [#__contentitem_tag_map] ALTER COLUMN [tag_date] [datetime2](0) NOT NULL; -ALTER TABLE [#__contentitem_tag_map] ADD DEFAULT '1900-01-01 00:00:00' FOR [tag_date]; -CREATE NONCLUSTERED INDEX [idx_date_id2] ON [#__contentitem_tag_map]( - [tag_date] ASC, - [tag_id] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -EXECUTE "#removeDefault" "#__extensions", 'checked_out_time'; -ALTER TABLE [#__extensions] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__extensions] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__fields", 'checked_out_time'; -ALTER TABLE [#__fields] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__fields] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__fields", 'created_time'; -ALTER TABLE [#__fields] ALTER COLUMN [created_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__fields] ADD DEFAULT '1900-01-01 00:00:00' FOR [created_time]; - -EXECUTE "#removeDefault" "#__fields", 'modified_time'; -ALTER TABLE [#__fields] ALTER COLUMN [modified_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__fields] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified_time]; - -EXECUTE "#removeDefault" "#__fields_groups", 'checked_out_time'; -ALTER TABLE [#__fields_groups] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__fields_groups] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__fields_groups", 'created'; -ALTER TABLE [#__fields_groups] ALTER COLUMN [created] [datetime2](0) NOT NULL; -ALTER TABLE [#__fields_groups] ADD DEFAULT '1900-01-01 00:00:00' FOR [created]; - -EXECUTE "#removeDefault" "#__fields_groups", 'modified'; -ALTER TABLE [#__fields_groups] ALTER COLUMN [modified] [datetime2](0) NOT NULL; -ALTER TABLE [#__fields_groups] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified]; - -EXECUTE "#removeDefault" "#__finder_filters", 'created'; -ALTER TABLE [#__finder_filters] ALTER COLUMN [created] [datetime2](0) NOT NULL; -ALTER TABLE [#__finder_filters] ADD DEFAULT '1900-01-01 00:00:00' FOR [created]; - -EXECUTE "#removeDefault" "#__finder_filters", 'modified'; -ALTER TABLE [#__finder_filters] ALTER COLUMN [modified] [datetime2](0) NOT NULL; -ALTER TABLE [#__finder_filters] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified]; - -EXECUTE "#removeDefault" "#__finder_filters", 'checked_out_time'; -ALTER TABLE [#__finder_filters] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__finder_filters] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__finder_links", 'indexdate'; -ALTER TABLE [#__finder_links] ALTER COLUMN [indexdate] [datetime2](0) NOT NULL; -ALTER TABLE [#__finder_links] ADD DEFAULT '1900-01-01 00:00:00' FOR [indexdate]; - -EXECUTE "#removeDefault" "#__finder_links", 'publish_start_date'; -ALTER TABLE [#__finder_links] ALTER COLUMN [publish_start_date] [datetime2](0) NOT NULL; -ALTER TABLE [#__finder_links] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_start_date]; - -EXECUTE "#removeDefault" "#__finder_links", 'publish_end_date'; -ALTER TABLE [#__finder_links] ALTER COLUMN [publish_end_date] [datetime2](0) NOT NULL; -ALTER TABLE [#__finder_links] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_end_date]; - -EXECUTE "#removeDefault" "#__finder_links", 'start_date'; -ALTER TABLE [#__finder_links] ALTER COLUMN [start_date] [datetime2](0) NOT NULL; -ALTER TABLE [#__finder_links] ADD DEFAULT '1900-01-01 00:00:00' FOR [start_date]; - -EXECUTE "#removeDefault" "#__finder_links", 'end_date'; -ALTER TABLE [#__finder_links] ALTER COLUMN [end_date] [datetime2](0) NOT NULL; -ALTER TABLE [#__finder_links] ADD DEFAULT '1900-01-01 00:00:00' FOR [end_date]; - -EXECUTE "#removeDefault" "#__menu", 'checked_out_time'; -ALTER TABLE [#__menu] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__menu] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__messages", 'date_time'; -ALTER TABLE [#__messages] ALTER COLUMN [date_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__messages] ADD DEFAULT '1900-01-01 00:00:00' FOR [date_time]; - -EXECUTE "#removeDefault" "#__modules", 'checked_out_time'; -ALTER TABLE [#__modules] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__modules] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__modules", 'publish_up'; -ALTER TABLE [#__modules] ALTER COLUMN [publish_up] [datetime2](0) NOT NULL; -ALTER TABLE [#__modules] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_up]; - -EXECUTE "#removeDefault" "#__modules", 'publish_down'; -ALTER TABLE [#__modules] ALTER COLUMN [publish_down] [datetime2](0) NOT NULL; -ALTER TABLE [#__modules] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_down]; - -EXECUTE "#removeDefault" "#__newsfeeds", 'checked_out_time'; -ALTER TABLE [#__newsfeeds] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__newsfeeds] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__newsfeeds", 'created'; -ALTER TABLE [#__newsfeeds] ALTER COLUMN [created] [datetime2](0) NOT NULL; -ALTER TABLE [#__newsfeeds] ADD DEFAULT '1900-01-01 00:00:00' FOR [created]; - -EXECUTE "#removeDefault" "#__newsfeeds", 'modified'; -ALTER TABLE [#__newsfeeds] ALTER COLUMN [modified] [datetime2](0) NOT NULL; -ALTER TABLE [#__newsfeeds] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified]; - -EXECUTE "#removeDefault" "#__newsfeeds", 'publish_up'; -ALTER TABLE [#__newsfeeds] ALTER COLUMN [publish_up] [datetime2](0) NOT NULL; -ALTER TABLE [#__newsfeeds] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_up]; - -EXECUTE "#removeDefault" "#__newsfeeds", 'publish_down'; -ALTER TABLE [#__newsfeeds] ALTER COLUMN [publish_down] [datetime2](0) NOT NULL; -ALTER TABLE [#__newsfeeds] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_down]; - -EXECUTE "#removeDefault" "#__redirect_links", 'created_date'; -ALTER TABLE [#__redirect_links] ALTER COLUMN [created_date] [datetime2](0) NOT NULL; -ALTER TABLE [#__redirect_links] ADD DEFAULT '1900-01-01 00:00:00' FOR [created_date]; - -DROP INDEX [idx_link_modifed] ON [#__redirect_links]; -EXECUTE "#removeDefault" "#__redirect_links", 'modified_date'; -ALTER TABLE [#__redirect_links] ALTER COLUMN [modified_date] [datetime2](0) NOT NULL; -ALTER TABLE [#__redirect_links] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified_date]; -CREATE NONCLUSTERED INDEX [idx_link_modifed2] ON [#__redirect_links]( - [modified_date] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -EXECUTE "#removeDefault" "#__tags", 'checked_out_time'; -ALTER TABLE [#__tags] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__tags] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__tags", 'created_time'; -ALTER TABLE [#__tags] ALTER COLUMN [created_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__tags] ADD DEFAULT '1900-01-01 00:00:00' FOR [created_time]; - -EXECUTE "#removeDefault" "#__tags", 'modified_time'; -ALTER TABLE [#__tags] ALTER COLUMN [modified_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__tags] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified_time]; - -EXECUTE "#removeDefault" "#__tags", 'publish_up'; -ALTER TABLE [#__tags] ALTER COLUMN [publish_up] [datetime2](0) NOT NULL; -ALTER TABLE [#__tags] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_up]; - -EXECUTE "#removeDefault" "#__tags", 'publish_down'; -ALTER TABLE [#__tags] ALTER COLUMN [publish_down] [datetime2](0) NOT NULL; -ALTER TABLE [#__tags] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_down]; - -EXECUTE "#removeDefault" "#__ucm_content", 'core_checked_out_time'; -ALTER TABLE [#__ucm_content] ALTER COLUMN [core_checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__ucm_content] ADD DEFAULT '1900-01-01 00:00:00' FOR [core_checked_out_time]; - -DROP INDEX [idx_created_time] ON [#__ucm_content]; -EXECUTE "#removeDefault" "#__ucm_content", 'core_created_time'; -ALTER TABLE [#__ucm_content] ALTER COLUMN [core_created_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__ucm_content] ADD DEFAULT '1900-01-01 00:00:00' FOR [core_created_time]; -CREATE NONCLUSTERED INDEX [idx_created_time2] ON [#__ucm_content]( - [core_created_time] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -DROP INDEX [idx_modified_time] ON [#__ucm_content]; -EXECUTE "#removeDefault" "#__ucm_content", 'core_modified_time'; -ALTER TABLE [#__ucm_content] ALTER COLUMN [core_modified_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__ucm_content] ADD DEFAULT '1900-01-01 00:00:00' FOR [core_modified_time]; -CREATE NONCLUSTERED INDEX [idx_modified_time2] ON [#__ucm_content]( - [core_modified_time] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -EXECUTE "#removeDefault" "#__ucm_content", 'core_publish_up'; -ALTER TABLE [#__ucm_content] ALTER COLUMN [core_publish_up] [datetime2](0) NOT NULL; -ALTER TABLE [#__ucm_content] ADD DEFAULT '1900-01-01 00:00:00' FOR [core_publish_up]; - -EXECUTE "#removeDefault" "#__ucm_content", 'core_publish_down'; -ALTER TABLE [#__ucm_content] ALTER COLUMN [core_publish_down] [datetime2](0) NOT NULL; -ALTER TABLE [#__ucm_content] ADD DEFAULT '1900-01-01 00:00:00' FOR [core_publish_down]; - -DROP INDEX [idx_save_date] ON [#__ucm_history]; -EXECUTE "#removeDefault" "#__ucm_history", 'save_date'; -ALTER TABLE [#__ucm_history] ALTER COLUMN [save_date] [datetime2](0) NOT NULL; -ALTER TABLE [#__ucm_history] ADD DEFAULT '1900-01-01 00:00:00' FOR [save_date]; -CREATE NONCLUSTERED INDEX [idx_save_date2] ON [#__ucm_history]( - [save_date] ASC -)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF); - -EXECUTE "#removeDefault" "#__user_notes", 'checked_out_time'; -ALTER TABLE [#__user_notes] ALTER COLUMN [checked_out_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__user_notes] ADD DEFAULT '1900-01-01 00:00:00' FOR [checked_out_time]; - -EXECUTE "#removeDefault" "#__user_notes", 'created_time'; -ALTER TABLE [#__user_notes] ALTER COLUMN [created_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__user_notes] ADD DEFAULT '1900-01-01 00:00:00' FOR [created_time]; - -EXECUTE "#removeDefault" "#__user_notes", 'modified_time'; -ALTER TABLE [#__user_notes] ALTER COLUMN [modified_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__user_notes] ADD DEFAULT '1900-01-01 00:00:00' FOR [modified_time]; - -EXECUTE "#removeDefault" "#__user_notes", 'review_time'; -ALTER TABLE [#__user_notes] ALTER COLUMN [review_time] [datetime2](0) NOT NULL; -ALTER TABLE [#__user_notes] ADD DEFAULT '1900-01-01 00:00:00' FOR [review_time]; - -EXECUTE "#removeDefault" "#__user_notes", 'publish_up'; -ALTER TABLE [#__user_notes] ALTER COLUMN [publish_up] [datetime2](0) NOT NULL; -ALTER TABLE [#__user_notes] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_up]; - -EXECUTE "#removeDefault" "#__user_notes", 'publish_down'; -ALTER TABLE [#__user_notes] ALTER COLUMN [publish_down] [datetime2](0) NOT NULL; -ALTER TABLE [#__user_notes] ADD DEFAULT '1900-01-01 00:00:00' FOR [publish_down]; - -EXECUTE "#removeDefault" "#__users", 'registerDate'; -ALTER TABLE [#__users] ALTER COLUMN [registerDate] [datetime2](0) NOT NULL; -ALTER TABLE [#__users] ADD DEFAULT '1900-01-01 00:00:00' FOR [registerDate]; - -EXECUTE "#removeDefault" "#__users", 'lastvisitDate'; -ALTER TABLE [#__users] ALTER COLUMN [lastvisitDate] [datetime2](0) NOT NULL; -ALTER TABLE [#__users] ADD DEFAULT '1900-01-01 00:00:00' FOR [lastvisitDate]; - -EXECUTE "#removeDefault" "#__users", 'lastResetTime'; -ALTER TABLE [#__users] ALTER COLUMN [lastResetTime] [datetime2](0) NOT NULL; -ALTER TABLE [#__users] ADD DEFAULT '1900-01-01 00:00:00' FOR [lastResetTime]; - -DROP PROCEDURE "#removeDefault"; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-17.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-17.sql deleted file mode 100644 index aaf6bf4a20f08..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-02-17.sql +++ /dev/null @@ -1,21 +0,0 @@ --- Normalize contact_details table default values. -DECLARE @table AS nvarchar(32) -DECLARE @constraintName AS nvarchar(100) -DECLARE @constraintQuery AS nvarchar(1000) -SET QUOTED_IDENTIFIER OFF -SET @table = "#__contact_details" -SET QUOTED_IDENTIFIER ON -SELECT @constraintName = name FROM sys.default_constraints -WHERE parent_object_id = object_id(@table) -AND parent_column_id = columnproperty(object_id(@table), 'name', 'ColumnId') -SET @constraintQuery = 'ALTER TABLE [' + @table + '] DROP CONSTRAINT [' + @constraintName + ']' -EXECUTE sp_executesql @constraintQuery; - -ALTER TABLE [#__contact_details] ADD DEFAULT (0) FOR [published]; -ALTER TABLE [#__contact_details] ADD DEFAULT (0) FOR [checked_out]; -ALTER TABLE [#__contact_details] ADD DEFAULT ('') FOR [created_by_alias]; - -ALTER TABLE [#__contact_details] ADD DEFAULT ('') FOR [sortname1]; -ALTER TABLE [#__contact_details] ADD DEFAULT ('') FOR [sortname2]; -ALTER TABLE [#__contact_details] ADD DEFAULT ('') FOR [sortname3]; -ALTER TABLE [#__contact_details] ADD DEFAULT ('') FOR [xreference]; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-03-03.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-03-03.sql deleted file mode 100644 index 94af5bdc08153..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-03-03.sql +++ /dev/null @@ -1,31 +0,0 @@ -CREATE PROCEDURE "#removeDefault" -( - @table NVARCHAR(100), - @column NVARCHAR(100) -) -AS -BEGIN - DECLARE @constraintName AS nvarchar(100) - DECLARE @constraintQuery AS nvarchar(1000) - SELECT @constraintName = name FROM sys.default_constraints - WHERE parent_object_id = object_id(@table) - AND parent_column_id = columnproperty(object_id(@table), @column, 'ColumnId') - SET @constraintQuery = 'ALTER TABLE [' + @table + '] DROP CONSTRAINT [' + @constraintName + ']' - EXECUTE sp_executesql @constraintQuery -END; - -EXECUTE "#removeDefault" "#__extensions", 'system_data'; -EXECUTE "#removeDefault" "#__updates", 'data'; - -ALTER TABLE "#__content" ADD DEFAULT ('') FOR "xreference"; -ALTER TABLE "#__newsfeeds" ADD DEFAULT ('') FOR "xreference"; - --- Delete wrong unique index -DROP INDEX "idx_access" ON "#__languages"; - --- Add missing unique index -ALTER TABLE "#__languages" ADD CONSTRAINT "#__languages$idx_langcode" UNIQUE ("lang_code") ON [PRIMARY]; - --- Add missing index keys -CREATE INDEX "idx_access" ON "#__languages" ("access"); -CREATE INDEX "idx_ordering" ON "#__languages" ("ordering"); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-03-09.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-03-09.sql deleted file mode 100644 index feb0fc106b9f7..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-03-09.sql +++ /dev/null @@ -1,19 +0,0 @@ -UPDATE "#__categories" SET published = 1 WHERE alias = 'root'; -UPDATE "c" -SET published = c2.newPublished -FROM "#__categories" AS "c" -INNER JOIN ( -SELECT c2.id,CASE WHEN MIN(p.published) > 0 THEN MAX(p.published) ELSE MIN(p.published) END AS newPublished -FROM "#__categories" AS "c2" -INNER JOIN "#__categories" AS "p" ON p.lft <= c2.lft AND c2.rgt <= p.rgt -GROUP BY c2.id) AS c2 ON c2.id = c.id; - -UPDATE "#__menu" SET published = 1 WHERE alias = 'root'; -UPDATE "c" -SET published = c2.newPublished -FROM "#__menu" AS "c" -INNER JOIN ( -SELECT c2.id,CASE WHEN MIN(p.published) > 0 THEN MAX(p.published) ELSE MIN(p.published) END AS newPublished -FROM "#__menu" AS "c2" -INNER JOIN "#__menu" AS "p" ON p.lft <= c2.lft AND c2.rgt <= p.rgt -GROUP BY c2.id) AS c2 ON c2.id = c.id; diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-04-10.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-04-10.sql deleted file mode 100644 index c8a2f4d934ab8..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-04-10.sql +++ /dev/null @@ -1,3 +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, 'TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE', 'TPL_HATHOR_MESSAGE_POSTINSTALL_BODY', 'TPL_HATHOR_MESSAGE_POSTINSTALL_ACTION', 'tpl_hathor', 1, 'action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_action', 'admin://templates/hathor/postinstall/hathormessage.php', 'hathormessage_postinstall_condition', '3.7.0', 1); \ No newline at end of file diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-04-19.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-04-19.sql deleted file mode 100644 index 042487bcbc4d3..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.0-2017-04-19.sql +++ /dev/null @@ -1,3 +0,0 @@ --- Set integer field default values. -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/sqlazure/3.7.4-2017-07-05.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.7.4-2017-07-05.sql deleted file mode 100644 index 5fa10e2f7f73b..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.7.4-2017-07-05.sql +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index b25399e2478ec..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-28.sql +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index b9ed858fcd02b..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.8.0-2017-07-31.sql +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index 72df8133711c1..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.8.2-2017-10-14.sql +++ /dev/null @@ -1,8 +0,0 @@ --- --- 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 deleted file mode 100644 index 15c43cf51df1c..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.8.4-2018-01-16.sql +++ /dev/null @@ -1,2 +0,0 @@ -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 deleted file mode 100644 index 29ad515aec05a..0000000000000 --- a/administrator/components/com_admin/sql/updates/sqlazure/3.8.6-2018-02-14.sql +++ /dev/null @@ -1,6 +0,0 @@ -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/tmpl/help/default.php b/administrator/components/com_admin/tmpl/help/default.php new file mode 100644 index 0000000000000..cdb73458308a8 --- /dev/null +++ b/administrator/components/com_admin/tmpl/help/default.php @@ -0,0 +1,43 @@ + +
+
+ +
+ +
+
+ +
diff --git a/administrator/components/com_admin/views/help/tmpl/default.xml b/administrator/components/com_admin/tmpl/help/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_admin/views/help/tmpl/default.xml rename to administrator/components/com_admin/tmpl/help/default.xml diff --git a/administrator/components/com_admin/tmpl/help/langforum.php b/administrator/components/com_admin/tmpl/help/langforum.php new file mode 100644 index 0000000000000..2d568aa3f0b77 --- /dev/null +++ b/administrator/components/com_admin/tmpl/help/langforum.php @@ -0,0 +1,26 @@ +load('mod_menu', JPATH_ADMINISTRATOR, null, false, true); + +$forumId = (int) Text::_('MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM_VALUE'); + +if (empty($forumId)) +{ + $forumId = 511; +} + +$forum_url = 'https://forum.joomla.org/viewforum.php?f=' . $forumId; + +Factory::getApplication()->redirect($forum_url); diff --git a/administrator/components/com_admin/tmpl/profile/edit.php b/administrator/components/com_admin/tmpl/profile/edit.php new file mode 100644 index 0000000000000..812a4dc5622d9 --- /dev/null +++ b/administrator/components/com_admin/tmpl/profile/edit.php @@ -0,0 +1,72 @@ +form->getFieldsets(); +?> + +
+ 'account')); ?> + + + form->getFieldset('user_details') as $field) : ?> +
+
+ label; ?> +
+
+ fieldname == 'password2') : ?> + + + input; ?> +
+
+ + + + + name == 'user_details') + { + continue; + } + ?> + name, Text::_($fieldset->label)); ?> + form->getFieldset($fieldset->name) as $field) : ?> + hidden) : ?> +
+
input; ?>
+
+ +
+
+ label; ?> +
+
input; ?>
+
+ + + + + + + + +
diff --git a/administrator/components/com_admin/tmpl/sysinfo/default.php b/administrator/components/com_admin/tmpl/sysinfo/default.php new file mode 100644 index 0000000000000..fa4227ef82c04 --- /dev/null +++ b/administrator/components/com_admin/tmpl/sysinfo/default.php @@ -0,0 +1,54 @@ + + +
+
+ +
+ 'site')); ?> + + + loadTemplate('system'); ?> + + + + loadTemplate('phpsettings'); ?> + + + + loadTemplate('config'); ?> + + + + loadTemplate('directory'); ?> + + + + loadTemplate('phpinfo'); ?> + + + +
+ + + +
+
diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default.xml b/administrator/components/com_admin/tmpl/sysinfo/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_admin/views/sysinfo/tmpl/default.xml rename to administrator/components/com_admin/tmpl/sysinfo/default.xml diff --git a/administrator/components/com_admin/tmpl/sysinfo/default_config.php b/administrator/components/com_admin/tmpl/sysinfo/default_config.php new file mode 100644 index 0000000000000..6eb271a6d4ef1 --- /dev/null +++ b/administrator/components/com_admin/tmpl/sysinfo/default_config.php @@ -0,0 +1,46 @@ + +
+ + + + + + + + + + + + + + + config as $key => $value) : ?> + + + + + + +
+ + + +
 
+ + + +
+
diff --git a/administrator/components/com_admin/tmpl/sysinfo/default_directory.php b/administrator/components/com_admin/tmpl/sysinfo/default_directory.php new file mode 100644 index 0000000000000..ed71ca1c13ffe --- /dev/null +++ b/administrator/components/com_admin/tmpl/sysinfo/default_directory.php @@ -0,0 +1,47 @@ + +
+ + + + + + + + + + + + + + + directory as $dir => $info) : ?> + + + + + + +
+ + + +
 
+ + + +
+
diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpinfo.php b/administrator/components/com_admin/tmpl/sysinfo/default_phpinfo.php similarity index 77% rename from administrator/components/com_admin/views/sysinfo/tmpl/default_phpinfo.php rename to administrator/components/com_admin/tmpl/sysinfo/default_phpinfo.php index 76050b4f658ca..87c4bd14c71fc 100644 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpinfo.php +++ b/administrator/components/com_admin/tmpl/sysinfo/default_phpinfo.php @@ -8,8 +8,11 @@ */ defined('_JEXEC') or die; + +use Joomla\CMS\Language\Text; + ?>
- + php_info; ?>
diff --git a/administrator/components/com_admin/tmpl/sysinfo/default_phpsettings.php b/administrator/components/com_admin/tmpl/sysinfo/default_phpsettings.php new file mode 100644 index 0000000000000..9dc773c145b19 --- /dev/null +++ b/administrator/components/com_admin/tmpl/sysinfo/default_phpsettings.php @@ -0,0 +1,150 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
  +
+ + + php_settings['open_basedir']); ?> +
+ + + php_settings['display_errors']); ?> +
+ + + php_settings['short_open_tag']); ?> +
+ + + php_settings['file_uploads']); ?> +
+ + + php_settings['output_buffering']); ?> +
+ + + php_settings['session.save_path']); ?> +
+ + + php_settings['session.auto_start']); ?> +
+ + + php_settings['xml']); ?> +
+ + + php_settings['zlib']); ?> +
+ + + php_settings['zip']); ?> +
+ + + php_settings['disable_functions']); ?> +
+ + + php_settings['mbstring']); ?> +
+ + + php_settings['iconv']); ?> +
+ + + php_settings['max_input_vars']); ?> +
+
diff --git a/administrator/components/com_admin/tmpl/sysinfo/default_system.php b/administrator/components/com_admin/tmpl/sysinfo/default_system.php new file mode 100644 index 0000000000000..c8bec2a2c3348 --- /dev/null +++ b/administrator/components/com_admin/tmpl/sysinfo/default_system.php @@ -0,0 +1,117 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
 
+ + + info['php']; ?> +
+ + + info['dbserver']; ?> +
+ + + info['dbversion']; ?> +
+ + + info['dbcollation']; ?> +
+ + + info['dbconnectioncollation']; ?> +
+ + + info['phpversion']; ?> +
+ + + info['server']); ?> +
+ + + info['sapi_name']; ?> +
+ + + info['version']; ?> +
+ + + info['useragent'], ENT_COMPAT, 'UTF-8'); ?> +
+
diff --git a/administrator/components/com_admin/views/help/tmpl/default.php b/administrator/components/com_admin/views/help/tmpl/default.php deleted file mode 100644 index f839eac951c3a..0000000000000 --- a/administrator/components/com_admin/views/help/tmpl/default.php +++ /dev/null @@ -1,40 +0,0 @@ - -
-
- -
- -
-
- -
diff --git a/administrator/components/com_admin/views/help/tmpl/langforum.php b/administrator/components/com_admin/views/help/tmpl/langforum.php deleted file mode 100644 index a090003330b21..0000000000000 --- a/administrator/components/com_admin/views/help/tmpl/langforum.php +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 0c1ae713774f2..0000000000000 --- a/administrator/components/com_admin/views/help/view.html.php +++ /dev/null @@ -1,100 +0,0 @@ -help_search = $this->get('HelpSearch'); - $this->page = $this->get('Page'); - $this->toc = $this->get('Toc'); - $this->lang_tag = $this->get('LangTag'); - $this->latest_version_check = $this->get('LatestVersionCheck'); - - $this->addToolbar(); - - return parent::display($tpl); - } - - /** - * Setup the Toolbar - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JToolbarHelper::title(JText::_('COM_ADMIN_HELP'), 'support help_header'); - } -} diff --git a/administrator/components/com_admin/views/profile/tmpl/edit.php b/administrator/components/com_admin/views/profile/tmpl/edit.php deleted file mode 100644 index e21f3367135dc..0000000000000 --- a/administrator/components/com_admin/views/profile/tmpl/edit.php +++ /dev/null @@ -1,77 +0,0 @@ -addScriptDeclaration(' - Joomla.submitbutton = function(task) - { - if (task == "profile.cancel" || document.formvalidator.isValid(document.getElementById("profile-form"))) - { - Joomla.submitform(task, document.getElementById("profile-form")); - } - }; -'); - -// Load chosen.css -JHtml::_('formbehavior.chosen', 'select'); - -// Get the form fieldsets. -$fieldsets = $this->form->getFieldsets(); -?> - -
- 'account')); ?> - - - form->getFieldset('user_details') as $field) : ?> -
-
label; ?>
-
- fieldname == 'password2') : ?> - - - input; ?> -
-
- - - - - name == 'user_details') - { - continue; - } - ?> - name, JText::_($fieldset->label)); ?> - form->getFieldset($fieldset->name) as $field) : ?> - hidden) : ?> -
-
input; ?>
-
- -
-
label; ?>
-
input; ?>
-
- - - - - - - - -
diff --git a/administrator/components/com_admin/views/profile/view.html.php b/administrator/components/com_admin/views/profile/view.html.php deleted file mode 100644 index 3184d7d60a5e1..0000000000000 --- a/administrator/components/com_admin/views/profile/view.html.php +++ /dev/null @@ -1,90 +0,0 @@ -form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->form->setValue('password', null); - $this->form->setValue('password2', null); - - $this->addToolbar(); - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', 1); - - JToolbarHelper::title(JText::_('COM_ADMIN_VIEW_PROFILE_TITLE'), 'user user-profile'); - JToolbarHelper::apply('profile.apply'); - JToolbarHelper::save('profile.save'); - JToolbarHelper::cancel('profile.cancel', 'JTOOLBAR_CLOSE'); - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_ADMIN_USER_PROFILE_EDIT'); - } -} diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default.php b/administrator/components/com_admin/views/sysinfo/tmpl/default.php deleted file mode 100644 index 66a2774f85292..0000000000000 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default.php +++ /dev/null @@ -1,48 +0,0 @@ - - -
-
- -
- 'site')); ?> - - - loadTemplate('system'); ?> - - - - loadTemplate('phpsettings'); ?> - - - - loadTemplate('config'); ?> - - - - loadTemplate('directory'); ?> - - - - loadTemplate('phpinfo'); ?> - - - -
- - - -
-
diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_config.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_config.php deleted file mode 100644 index 12c59f96f7750..0000000000000 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_config.php +++ /dev/null @@ -1,43 +0,0 @@ - -
- - - - - - - - - - - - - - - config as $key => $value) : ?> - - - - - - -
- - - -
 
- - - -
-
diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_directory.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_directory.php deleted file mode 100644 index 2e5686af81138..0000000000000 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_directory.php +++ /dev/null @@ -1,43 +0,0 @@ - -
- - - - - - - - - - - - - - - directory as $dir => $info) : ?> - - - - - - -
- - - -
 
- - - -
-
diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php deleted file mode 100644 index b34fe0e1b467d..0000000000000 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_phpsettings.php +++ /dev/null @@ -1,170 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
  -
- - - php_settings['safe_mode']); ?> -
- - - php_settings['open_basedir']); ?> -
- - - php_settings['display_errors']); ?> -
- - - php_settings['short_open_tag']); ?> -
- - - php_settings['file_uploads']); ?> -
- - - php_settings['magic_quotes_gpc']); ?> -
- - - php_settings['register_globals']); ?> -
- - - php_settings['output_buffering']); ?> -
- - - php_settings['session.save_path']); ?> -
- - - php_settings['session.auto_start']); ?> -
- - - php_settings['xml']); ?> -
- - - php_settings['zlib']); ?> -
- - - php_settings['zip']); ?> -
- - - php_settings['disable_functions']); ?> -
- - - php_settings['mbstring']); ?> -
- - - php_settings['iconv']); ?> -
- - - php_settings['max_input_vars']); ?> -
-
diff --git a/administrator/components/com_admin/views/sysinfo/tmpl/default_system.php b/administrator/components/com_admin/views/sysinfo/tmpl/default_system.php deleted file mode 100644 index 3fe026dc4658a..0000000000000 --- a/administrator/components/com_admin/views/sysinfo/tmpl/default_system.php +++ /dev/null @@ -1,121 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
 
- - - info['php']; ?> -
- - - info['dbserver']; ?> -
- - - info['dbversion']; ?> -
- - - info['dbcollation']; ?> -
- - - info['dbconnectioncollation']; ?> -
- - - info['phpversion']; ?> -
- - - info['server']); ?> -
- - - info['sapi_name']; ?> -
- - - info['version']; ?> -
- - - info['platform']; ?> -
- - - info['useragent'], ENT_COMPAT, 'UTF-8'); ?> -
-
diff --git a/administrator/components/com_admin/views/sysinfo/view.html.php b/administrator/components/com_admin/views/sysinfo/view.html.php deleted file mode 100644 index 6997bddf3e5f0..0000000000000 --- a/administrator/components/com_admin/views/sysinfo/view.html.php +++ /dev/null @@ -1,124 +0,0 @@ -authorise('core.admin')) - { - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); - } - - $this->php_settings = $this->get('PhpSettings'); - $this->config = $this->get('config'); - $this->info = $this->get('info'); - $this->php_info = $this->get('PhpInfo'); - $this->directory = $this->get('directory'); - - $this->addToolbar(); - $this->_setSubMenu(); - - return parent::display($tpl); - } - - /** - * Setup the SubMenu - * - * @return void - * - * @since 1.6 - * @note Necessary for Hathor compatibility - * @deprecated 4.0 To be removed with Hathor - */ - protected function _setSubMenu() - { - try - { - $contents = $this->loadTemplate('navigation'); - $document = JFactory::getDocument(); - $document->setBuffer($contents, 'modules', 'submenu'); - } - catch (Exception $e) - { - } - } - - /** - * Setup the Toolbar - * - * @return void - * - * @since 1.6 - */ - 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::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 deleted file mode 100644 index c3f010b1b8a8c..0000000000000 --- a/administrator/components/com_admin/views/sysinfo/view.json.php +++ /dev/null @@ -1,67 +0,0 @@ -authorise('core.admin')) - { - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); - } - - header('MIME-Version: 1.0'); - header('Content-Disposition: attachment; filename="systeminfo-' . date('c') . '.json"'); - header('Content-Transfer-Encoding: binary'); - - $data = $this->getLayoutData(); - - echo json_encode($data); - - JFactory::getApplication()->close(); - } - - /** - * Get the data for the view - * - * @return array - * - * @since 3.5 - */ - protected function getLayoutData() - { - $model = $this->getModel(); - - return array( - 'info' => $model->getSafeData('info'), - 'phpSettings' => $model->getSafeData('phpSettings'), - 'config' => $model->getSafeData('config'), - 'directories' => $model->getSafeData('directory', true), - 'phpInfo' => $model->getSafeData('phpInfoArray'), - 'extensions' => $model->getSafeData('extensions') - ); - } -} diff --git a/administrator/components/com_admin/views/sysinfo/view.text.php b/administrator/components/com_admin/views/sysinfo/view.text.php deleted file mode 100644 index dd8c833a06e83..0000000000000 --- a/administrator/components/com_admin/views/sysinfo/view.text.php +++ /dev/null @@ -1,176 +0,0 @@ -authorise('core.admin')) - { - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); - } - - header('Content-Type: text/plain; charset=utf-8'); - header('Content-Description: File Transfer'); - header('Content-Disposition: attachment; filename="systeminfo-' . date('c') . '.txt"'); - header('Cache-Control: must-revalidate'); - - $data = $this->getLayoutData(); - - $lines = array(); - - foreach ($data as $sectionName => $section) - { - $customRenderingMethod = 'render' . ucfirst($sectionName); - - if (method_exists($this, $customRenderingMethod)) - { - $lines[] = $this->$customRenderingMethod($section['title'], $section['data']); - } - else - { - $lines[] = $this->renderSection($section['title'], $section['data']); - } - } - - echo str_replace(JPATH_ROOT, 'xxxxxx', implode("\n\n", $lines)); - - JFactory::getApplication()->close(); - } - - /** - * Get the data for the view - * - * @return array - * - * @since 3.5 - */ - protected function getLayoutData() - { - $model = $this->getModel(); - - return array( - 'info' => array( - 'title' => JText::_('COM_ADMIN_SYSTEM_INFORMATION', true), - 'data' => $model->getSafeData('info') - ), - 'phpSettings' => array( - 'title' => JText::_('COM_ADMIN_PHP_SETTINGS', true), - 'data' => $model->getSafeData('phpSettings') - ), - 'config' => array( - 'title' => JText::_('COM_ADMIN_CONFIGURATION_FILE', true), - 'data' => $model->getSafeData('config') - ), - 'directories' => array( - 'title' => JText::_('COM_ADMIN_DIRECTORY_PERMISSIONS', true), - 'data' => $model->getSafeData('directory', true) - ), - 'phpInfo' => array( - 'title' => JText::_('COM_ADMIN_PHP_INFORMATION', true), - 'data' => $model->getSafeData('phpInfoArray') - ), - 'extensions' => array( - 'title' => JText::_('COM_ADMIN_EXTENSIONS', true), - 'data' => $model->getSafeData('extensions') - ) - ); - } - - /** - * Render a section - * - * @param string $sectionName Name of the section to render - * @param array $sectionData Data of the section to render - * @param integer $level Depth level for indentation - * - * @return string - * - * @since 3.5 - */ - protected function renderSection($sectionName, $sectionData, $level = 0) - { - $lines = array(); - - $margin = ($level > 0) ? str_repeat("\t", $level) : null; - - $lines[] = $margin . '============='; - $lines[] = $margin . $sectionName; - $lines[] = $margin . '============='; - $level++; - - foreach ($sectionData as $name => $value) - { - if (is_array($value)) - { - if ($name == 'Directive') - { - continue; - } - - $lines[] = ''; - $lines[] = $this->renderSection($name, $value, $level); - } - else - { - if (is_bool($value)) - { - $value = $value ? 'true' : 'false'; - } - - if (is_int($name) && ($name == 0 || $name == 1)) - { - $name = ($name == 0 ? 'Local Value' : 'Master Value'); - } - - $lines[] = $margin . $name . ': ' . $value; - } - } - - return implode("\n", $lines); - } - - /** - * Specific rendering for directories - * - * @param string $sectionName Name of the section - * @param array $sectionData Directories information - * @param integer $level Starting level - * - * @return string - * - * @since 3.5 - */ - protected function renderDirectories($sectionName, $sectionData, $level = -1) - { - foreach ($sectionData as $directory => $data) - { - $sectionData[$directory] = $data['writable'] ? ' writable' : ' NOT writable'; - } - - return $this->renderSection($sectionName, $sectionData, $level); - } -} diff --git a/administrator/components/com_associations/Controller/AssociationController.php b/administrator/components/com_associations/Controller/AssociationController.php new file mode 100644 index 0000000000000..ecb45be2ac040 --- /dev/null +++ b/administrator/components/com_associations/Controller/AssociationController.php @@ -0,0 +1,92 @@ +input->get('itemtype', '', 'string'), 2); + + $id = $this->input->get('id', 0, 'int'); + + // Check if reference item can be edited. + if (!AssociationsHelper::allowEdit($extensionName, $typeName, $id)) + { + $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'), 'error'); + $this->setRedirect(Route::_('index.php?option=com_associations&view=associations', false)); + + return false; + } + + return parent::display(); + } + + /** + * Method for canceling the edit action + * + * @param string $key The name of the primary key of the URL variable. + * + * @return void + * + * @since 3.7.0 + */ + public function cancel($key = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + list($extensionName, $typeName) = explode('.', $this->input->get('itemtype', '', 'string'), 2); + + // Only check in, if component item type allows to check out. + if (AssociationsHelper::typeSupportsCheckout($extensionName, $typeName)) + { + $ids = array(); + $targetId = $this->input->get('target-id', '', 'string'); + + if ($targetId !== '') + { + $ids = array_unique(explode(',', $targetId)); + } + + $ids[] = $this->input->get('id', 0, 'int'); + + foreach ($ids as $key => $id) + { + AssociationsHelper::getItem($extensionName, $typeName, $id)->checkin(); + } + } + + $this->setRedirect(Route::_('index.php?option=com_associations&view=associations', false)); + } +} diff --git a/administrator/components/com_associations/Controller/AssociationsController.php b/administrator/components/com_associations/Controller/AssociationsController.php new file mode 100644 index 0000000000000..204162c474cc3 --- /dev/null +++ b/administrator/components/com_associations/Controller/AssociationsController.php @@ -0,0 +1,135 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to purge the associations table. + * + * @return void + * + * @since 3.7.0 + */ + public function purge() + { + $this->getModel('associations')->purge(); + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); + } + + /** + * Method to delete the orphans from the associations table. + * + * @return void + * + * @since 3.7.0 + */ + public function clean() + { + $this->getModel('associations')->clean(); + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); + } + + /** + * Method to check in an item from the association item overview. + * + * @return void + * + * @since 3.7.1 + */ + public function checkin() + { + // Set the redirect so we can just stop processing when we find a condition we can't process + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); + + // Figure out if the item supports checking and check it in + $type = null; + + list($extensionName, $typeName) = explode('.', $this->input->get('itemtype')); + + $extension = AssociationsHelper::getSupportedExtension($extensionName); + $types = $extension->get('types'); + + if (!array_key_exists($typeName, $types)) + { + return; + } + + if (AssociationsHelper::typeSupportsCheckout($extensionName, $typeName) === false) + { + // How on earth we came to that point, eject internet + return; + } + + $cid = $this->input->get('cid', array(), 'array'); + + if (empty($cid)) + { + // Seems we don't have an id to work with. + return; + } + + // We know the first element is the one we need because we don't allow multi selection of rows + $id = $cid[0]; + + if (AssociationsHelper::canCheckinItem($extensionName, $typeName, $id) === true) + { + $item = AssociationsHelper::getItem($extensionName, $typeName, $id); + + $item->checkIn($id); + + return; + } + + $this->setRedirect( + Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list), + Text::_('COM_ASSOCIATIONS_YOU_ARE_NOT_ALLOWED_TO_CHECKIN_THIS_ITEM') + ); + + return; + } +} diff --git a/administrator/components/com_associations/Controller/DisplayController.php b/administrator/components/com_associations/Controller/DisplayController.php new file mode 100644 index 0000000000000..c4d3d01ce63af --- /dev/null +++ b/administrator/components/com_associations/Controller/DisplayController.php @@ -0,0 +1,31 @@ +input->get('itemtype', '', 'string'); + + if ($itemType !== '') + { + list($extensionName, $typeName) = explode('.', $itemType); + + if (!AssociationsHelper::hasSupport($extensionName)) + { + throw new \Exception( + Text::sprintf('COM_ASSOCIATIONS_COMPONENT_NOT_SUPPORTED', $this->app->getLanguage()->_($extensionName)), + 404 + ); + } + + if (!$this->app->getIdentity()->authorise('core.manage', $extensionName)) + { + throw new NotAllowed($this->app->getLanguage()->_('JERROR_ALERTNOAUTHOR'), 403); + } + } + } +} diff --git a/administrator/components/com_associations/Field/ItemlanguageField.php b/administrator/components/com_associations/Field/ItemlanguageField.php new file mode 100644 index 0000000000000..2e2d2cfb3d0a6 --- /dev/null +++ b/administrator/components/com_associations/Field/ItemlanguageField.php @@ -0,0 +1,108 @@ +input; + + list($extensionName, $typeName) = explode('.', $input->get('itemtype', '', 'string'), 2); + + // Get the extension specific helper method + $helper = AssociationsHelper::getExtensionHelper($extensionName); + + $languageField = $helper->getTypeFieldName($typeName, 'language'); + $referenceId = $input->get('id', 0, 'int'); + $reference = ArrayHelper::fromObject(AssociationsHelper::getItem($extensionName, $typeName, $referenceId)); + $referenceLang = $reference[$languageField]; + + // Get item associations given ID and item type + $associations = AssociationsHelper::getAssociationList($extensionName, $typeName, $referenceId); + + // Check if user can create items in this component item type. + $canCreate = AssociationsHelper::allowAdd($extensionName, $typeName); + + // Gets existing languages. + $existingLanguages = LanguageHelper::getContentLanguages(array(0, 1)); + + $options = array(); + + // Each option has the format "|", example: "en-GB|1" + foreach ($existingLanguages as $langCode => $language) + { + // If language code is equal to reference language we don't need it. + if ($language->lang_code == $referenceLang) + { + continue; + } + + $options[$langCode] = new \stdClass; + $options[$langCode]->text = $language->title; + + // If association exists in this language. + if (isset($associations[$language->lang_code])) + { + $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. + $canEdit = AssociationsHelper::allowEdit($extensionName, $typeName, $itemId); + + // Check if item can be checked out + $canCheckout = AssociationsHelper::canCheckinItem($extensionName, $typeName, $itemId); + + // Disable language if user is not allowed to edit the item associated to it. + $options[$langCode]->disable = !($canEdit && $canCheckout); + } + else + { + // New item, id = 0 and disabled if user is not allowed to create new items. + $options[$langCode]->value = $language->lang_code . ':0:add'; + + // Disable language if user is not allowed to create items. + $options[$langCode]->disable = !$canCreate; + } + } + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_associations/Field/ItemtypeField.php b/administrator/components/com_associations/Field/ItemtypeField.php new file mode 100644 index 0000000000000..dd1d18921075e --- /dev/null +++ b/administrator/components/com_associations/Field/ItemtypeField.php @@ -0,0 +1,68 @@ +get('associationssupport') === true) + { + foreach ($extension->get('types') as $type) + { + $context = $extension->get('component') . '.' . $type->get('name'); + $options[$extension->get('title')][] = HTMLHelper::_('select.option', $context, $type->get('title')); + } + } + } + + // Sort by alpha order. + uksort($options, 'strnatcmp'); + + // Add options to parent array. + return array_merge(parent::getGroups(), $options); + } +} diff --git a/administrator/components/com_associations/Field/Modal/AssociationField.php b/administrator/components/com_associations/Field/Modal/AssociationField.php new file mode 100644 index 0000000000000..d767f954c1f8c --- /dev/null +++ b/administrator/components/com_associations/Field/Modal/AssociationField.php @@ -0,0 +1,103 @@ +value > 0 ? (int) $this->value : ''; + + Factory::getDocument()->addScriptOptions('modal-associations', ['itemId' => $value]); + HTMLHelper::_('script', 'com_associations/modal-associations.min.js', false, true); + + // Setup variables for display. + $html = array(); + + $linkAssociations = 'index.php?option=com_associations&view=associations&layout=modal&tmpl=component' + . '&forcedItemType=' . Factory::getApplication()->input->get('itemtype', '', 'string') . '&function=jSelectAssociation_' . $this->id; + + $linkAssociations .= "&forcedLanguage=' + document.getElementById('target-association').getAttribute('data-language') + '"; + + $urlSelect = $linkAssociations . '&' . Session::getFormToken() . '=1'; + + // Select custom association button + $html[] = '' + . ' ' + . '' + . ''; + + // Clear association button + $html[] = '' + . ' ' . Text::_('JCLEAR') + . ''; + + $html[] = ''; + + // Select custom association modal + $html[] = HTMLHelper::_( + 'bootstrap.renderModal', + 'associationSelect' . $this->id . 'Modal', + array( + 'title' => Text::_('COM_ASSOCIATIONS_SELECT_TARGET'), + 'backdrop' => 'static', + 'url' => $urlSelect, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '', + ) + ); + + return implode("\n", $html); + } +} diff --git a/administrator/components/com_associations/Helper/AssociationsHelper.php b/administrator/components/com_associations/Helper/AssociationsHelper.php new file mode 100644 index 0000000000000..4711ceb39a137 --- /dev/null +++ b/administrator/components/com_associations/Helper/AssociationsHelper.php @@ -0,0 +1,702 @@ +getAssociationList($typeName, $itemId); + + } + + /** + * Get the the instance of the extension helper class + * + * @param string $extensionName The extension name with com_ + * + * @return \Joomla\CMS\Association\AssociationExtensionHelper|null + * + * @since 3.7.0 + */ + public static function getExtensionHelper($extensionName) + { + if (!self::hasSupport($extensionName)) + { + return null; + } + + $support = self::$extensionsSupport[$extensionName]; + + return $support->get('helper'); + } + + /** + * Get item information + * + * @param string $extensionName The extension name with com_ + * @param string $typeName The item type + * @param int $itemId The id of item for which we need the associated items + * + * @return \Joomla\CMS\Table\Table|null + * + * @since 3.7.0 + */ + public static function getItem($extensionName, $typeName, $itemId) + { + if (!self::hasSupport($extensionName)) + { + return array(); + } + + // Get the extension specific helper method + $helper = self::getExtensionHelper($extensionName); + + return $helper->getItem($typeName, $itemId); + } + + /** + * Check if extension supports associations + * + * @param string $extensionName The extension name with com_ + * + * @return boolean + * + * @since 3.7.0 + */ + public static function hasSupport($extensionName) + { + if (is_null(self::$extensionsSupport)) + { + self::getSupportedExtensions(); + } + + return in_array($extensionName, self::$supportedExtensionsList); + } + + /** + * Loads the helper for the given class. + * + * @param string $extensionName The extension name with com_ + * + * @return AssociationExtensionInterface|null + * + * @since 4.0.0 + */ + private static function loadHelper($extensionName) + { + $component = Factory::getApplication()->bootComponent($extensionName); + + if ($component instanceof AssociationServiceInterface) + { + return $component->getAssociationsExtension(); + } + + // Check if associations helper exists + if (!file_exists(JPATH_ADMINISTRATOR . '/components/' . $extensionName . '/helpers/associations.php')) + { + return null; + } + + require_once JPATH_ADMINISTRATOR . '/components/' . $extensionName . '/helpers/associations.php'; + + $componentAssociationsHelperClassName = self::getExtensionHelperClassName($extensionName); + + if (!class_exists($componentAssociationsHelperClassName, false)) + { + return null; + } + + // Create an instance of the helper class + return new $componentAssociationsHelperClassName; + } + + /** + * Get the extension specific helper class name + * + * @param string $extensionName The extension name with com_ + * + * @return boolean + * + * @since 3.7.0 + */ + private static function getExtensionHelperClassName($extensionName) + { + $realName = self::getExtensionRealName($extensionName); + + return ucfirst($realName) . 'AssociationsHelper'; + } + + /** + * Get the real extension name. This means without com_ + * + * @param string $extensionName The extension name with com_ + * + * @return string + * + * @since 3.7.0 + */ + private static function getExtensionRealName($extensionName) + { + return strpos($extensionName, 'com_') === false ? $extensionName : substr($extensionName, 4); + } + + /** + * Get the associated language edit links Html. + * + * @param string $extensionName Extension Name + * @param string $typeName ItemType + * @param integer $itemId Item id. + * @param string $itemLanguage Item language code. + * @param boolean $addLink True for adding edit links. False for just text. + * @param boolean $assocLanguages True for showing non associated content languages. False only languages with associations. + * + * @return string The language HTML + * + * @since 3.7.0 + */ + public static function getAssociationHtmlList($extensionName, $typeName, $itemId, $itemLanguage, $addLink = true, $assocLanguages = true) + { + // Get the associations list for this item. + $items = self::getAssociationList($extensionName, $typeName, $itemId); + + $titleFieldName = self::getTypeFieldName($extensionName, $typeName, 'title'); + + // Get all content languages. + $languages = LanguageHelper::getContentLanguages(array(0, 1)); + + $canEditReference = self::allowEdit($extensionName, $typeName, $itemId); + $canCreate = self::allowAdd($extensionName, $typeName); + + // Create associated items list. + foreach ($languages as $langCode => $language) + { + // Don't do for the reference language. + if ($langCode == $itemLanguage) + { + continue; + } + + // Don't show languages with associations, if we don't want to show them. + if ($assocLanguages && isset($items[$langCode])) + { + unset($items[$langCode]); + continue; + } + + // Don't show languages without associations, if we don't want to show them. + if (!$assocLanguages && !isset($items[$langCode])) + { + continue; + } + + // Get html parameters. + if (isset($items[$langCode])) + { + $title = $items[$langCode][$titleFieldName]; + $additional = ''; + + if (isset($items[$langCode]['catid'])) + { + $db = Factory::getDbo(); + + // Get the category name + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__categories')) + ->where($db->quoteName('id') . ' = ' . $db->quote($items[$langCode]['catid'])); + + $db->setQuery($query); + $category_title = $db->loadResult(); + + $additional = '' . Text::sprintf('JCATEGORY_SPRINTF', $category_title) . '
'; + } + elseif (isset($items[$langCode]['menutype'])) + { + $db = Factory::getDbo(); + + // Get the menutype name + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__menu_types')) + ->where($db->quoteName('menutype') . ' = ' . $db->quote($items[$langCode]['menutype'])); + + $db->setQuery($query); + $menutype_title = $db->loadResult(); + + $additional = '' . Text::sprintf('COM_MENUS_MENU_SPRINTF', $menutype_title) . '
'; + } + + $labelClass = 'badge-secondary'; + $target = $langCode . ':' . $items[$langCode]['id'] . ':edit'; + $allow = $canEditReference + && self::allowEdit($extensionName, $typeName, $items[$langCode]['id']) + && self::canCheckinItem($extensionName, $typeName, $items[$langCode]['id']); + + $additional .= $addLink && $allow ? Text::_('COM_ASSOCIATIONS_EDIT_ASSOCIATION') : ''; + } + else + { + $items[$langCode] = array(); + + $title = Text::_('COM_ASSOCIATIONS_NO_ASSOCIATION'); + $additional = $addLink ? Text::_('COM_ASSOCIATIONS_ADD_NEW_ASSOCIATION') : ''; + $labelClass = 'badge-warning'; + $target = $langCode . ':0:add'; + $allow = $canCreate; + } + + // Generate item Html. + $options = array( + 'option' => 'com_associations', + 'view' => 'association', + 'layout' => 'edit', + 'itemtype' => $extensionName . '.' . $typeName, + 'task' => 'association.edit', + 'id' => $itemId, + 'target' => $target, + ); + + $url = Route::_('index.php?' . http_build_query($options)); + $url = $allow && $addLink ? $url : ''; + $text = strtoupper($language->sef); + + $tooltip = htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '

' . $additional; + $classes = 'hasPopover badge ' . $labelClass; + + $items[$langCode]['link'] = '' + . $text . ''; + } + + HTMLHelper::_('bootstrap.popover'); + + return LayoutHelper::render('joomla.content.associations', $items); + } + + /** + * Get all extensions with associations support. + * + * @return array The extensions. + * + * @since 3.7.0 + */ + public static function getSupportedExtensions() + { + if (!is_null(self::$extensionsSupport)) + { + return self::$extensionsSupport; + } + + self::$extensionsSupport = array(); + + $extensions = self::getEnabledExtensions(); + + foreach ($extensions as $extension) + { + $support = self::getSupportedExtension($extension->element); + + if ($support->get('associationssupport') === true) + { + self::$supportedExtensionsList[] = $extension->element; + } + + self::$extensionsSupport[$extension->element] = $support; + } + + return self::$extensionsSupport; + } + + /** + * Get item context based on the item key. + * + * @param string $extensionName The extension identifier. + * + * @return \Joomla\Registry\Registry The item properties. + * + * @since 3.7.0 + */ + public static function getSupportedExtension($extensionName) + { + $result = new Registry; + + $result->def('component', $extensionName); + $result->def('associationssupport', false); + $result->def('helper', null); + + $helper = self::loadHelper($extensionName); + + if (!$helper) + { + return $result; + } + + $result->set('helper', $helper); + + if ($helper->hasAssociationsSupport() === false) + { + return $result; + } + + $result->set('associationssupport', true); + + // Get the translated titles. + $languagePath = JPATH_ADMINISTRATOR . '/components/' . $extensionName; + $lang = Factory::getLanguage(); + + $lang->load($extensionName . '.sys', JPATH_ADMINISTRATOR); + $lang->load($extensionName . '.sys', $languagePath); + $lang->load($extensionName, JPATH_ADMINISTRATOR); + $lang->load($extensionName, $languagePath); + + $result->def('title', Text::_(strtoupper($extensionName))); + + // Get the supported types + $types = $helper->getItemTypes(); + $rTypes = array(); + + foreach ($types as $typeName) + { + $details = $helper->getType($typeName); + $context = 'component'; + $title = $helper->getTypeTitle($typeName); + $languageKey = $typeName; + + $typeNameExploded = explode('.', $typeName); + if (array_pop($typeNameExploded) === 'category') + { + $languageKey = strtoupper($extensionName) . '_CATEGORIES'; + $context = 'category'; + } + + if ($lang->hasKey(strtoupper($extensionName . '_' . $title . 'S'))) + { + $languageKey = strtoupper($extensionName . '_' . $title . 'S'); + } + + $title = $lang->hasKey($languageKey) ? Text::_($languageKey) : Text::_('COM_ASSOCIATIONS_ITEMS'); + + $rType = new Registry; + + $rType->def('name', $typeName); + $rType->def('details', $details); + $rType->def('title', $title); + $rType->def('context', $context); + + $rTypes[$typeName] = $rType; + } + + $result->def('types', $rTypes); + + return $result; + } + + /** + * Get all installed and enabled extensions + * + * @return mixed + * + * @since 3.7.0 + */ + private static function getEnabledExtensions() + { + $db = Factory::getDbo(); + + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('component')) + ->where($db->quoteName('enabled') . ' = 1'); + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Get all the content languages. + * + * @return array Array of objects all content languages by language code. + * + * @since 3.7.0 + */ + public static function getContentLanguages() + { + return LanguageHelper::getContentLanguages(array(0, 1)); + } + + /** + * Get the associated items for an item + * + * @param string $extensionName The extension name with com_ + * @param string $typeName The item type + * @param int $itemId The id of item for which we need the associated items + * + * @return boolean + * + * @since 3.7.0 + */ + public static function allowEdit($extensionName, $typeName, $itemId) + { + if (!self::hasSupport($extensionName)) + { + return false; + } + + // Get the extension specific helper method + $helper = self::getExtensionHelper($extensionName); + + if (method_exists($helper, 'allowEdit')) + { + return $helper->allowEdit($typeName, $itemId); + } + + return Factory::getUser()->authorise('core.edit', $extensionName); + } + + /** + * Check if user is allowed to create items. + * + * @param string $extensionName The extension name with com_ + * @param string $typeName The item type + * + * @return boolean True on allowed. + * + * @since 3.7.0 + */ + public static function allowAdd($extensionName, $typeName) + { + if (!self::hasSupport($extensionName)) + { + return false; + } + + // Get the extension specific helper method + $helper = self::getExtensionHelper($extensionName); + + if (method_exists($helper, 'allowAdd')) + { + return $helper->allowAdd($typeName); + } + + return Factory::getUser()->authorise('core.create', $extensionName); + } + + /** + * Check if an item is checked out + * + * @param string $extensionName The extension name with com_ + * @param string $typeName The item type + * @param int $itemId The id of item for which we need the associated items + * + * @return boolean True if item is checked out. + * + * @since 3.7.0 + */ + public static function isCheckoutItem($extensionName, $typeName, $itemId) + { + if (!self::hasSupport($extensionName)) + { + return false; + } + + if (!self::typeSupportsCheckout($extensionName, $typeName)) + { + return false; + } + + // Get the extension specific helper method + $helper = self::getExtensionHelper($extensionName); + + if (method_exists($helper, 'isCheckoutItem')) + { + return $helper->isCheckoutItem($typeName, $itemId); + } + + $item = self::getItem($extensionName, $typeName, $itemId); + + $checkedOutFieldName = $helper->getTypeFieldName($typeName, 'checked_out'); + + return $item->{$checkedOutFieldName} != 0; + } + + /** + * Check if user can checkin an item. + * + * @param string $extensionName The extension name with com_ + * @param string $typeName The item type + * @param int $itemId The id of item for which we need the associated items + * + * @return boolean True on allowed. + * + * @since 3.7.0 + */ + public static function canCheckinItem($extensionName, $typeName, $itemId) + { + if (!self::hasSupport($extensionName)) + { + return false; + } + + if (!self::typeSupportsCheckout($extensionName, $typeName)) + { + return true; + } + + // Get the extension specific helper method + $helper = self::getExtensionHelper($extensionName); + + if (method_exists($helper, 'canCheckinItem')) + { + return $helper->canCheckinItem($typeName, $itemId); + } + + $item = self::getItem($extensionName, $typeName, $itemId); + + $checkedOutFieldName = $helper->getTypeFieldName($typeName, 'checked_out'); + + $userId = Factory::getUser()->id; + + return ($item->{$checkedOutFieldName} == $userId || $item->{$checkedOutFieldName} == 0); + } + + /** + * Check if the type supports checkout + * + * @param string $extensionName The extension name with com_ + * @param string $typeName The item type + * + * @return boolean True on allowed. + * + * @since 3.7.0 + */ + public static function typeSupportsCheckout($extensionName, $typeName) + { + if (!self::hasSupport($extensionName)) + { + return false; + } + + // Get the extension specific helper method + $helper = self::getExtensionHelper($extensionName); + + $support = $helper->getTypeSupport($typeName); + + return !empty($support['checkout']); + } + + /** + * Get a table field name for a type + * + * @param string $extensionName The extension name with com_ + * @param string $typeName The item type + * @param string $fieldName The item type + * + * @return boolean True on allowed. + * + * @since 3.7.0 + */ + public static function getTypeFieldName($extensionName, $typeName, $fieldName) + { + if (!self::hasSupport($extensionName)) + { + return false; + } + + // Get the extension specific helper method + $helper = self::getExtensionHelper($extensionName); + + return $helper->getTypeFieldName($typeName, $fieldName); + } + + /** + * Gets the language filter system plugin extension id. + * + * @return integer The language filter system plugin extension id. + * + * @since 3.7.2 + */ + public static function getLanguagefilterPluginId() + { + $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('languagefilter')); + $db->setQuery($query); + + try + { + $result = (int) $db->loadResult(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + return $result; + } +} diff --git a/administrator/components/com_associations/Model/AssociationModel.php b/administrator/components/com_associations/Model/AssociationModel.php new file mode 100644 index 0000000000000..24d075be85b03 --- /dev/null +++ b/administrator/components/com_associations/Model/AssociationModel.php @@ -0,0 +1,40 @@ +loadForm('com_associations.association', 'association', array('control' => 'jform', 'load_data' => $loadData)); + + return !empty($form) ? $form : false; + } +} diff --git a/administrator/components/com_associations/Model/AssociationsModel.php b/administrator/components/com_associations/Model/AssociationsModel.php new file mode 100644 index 0000000000000..21e30656808b6 --- /dev/null +++ b/administrator/components/com_associations/Model/AssociationsModel.php @@ -0,0 +1,564 @@ +input->get('forcedLanguage', '', 'cmd'); + $forcedItemType = $app->input->get('forcedItemType', '', 'string'); + + // Adjust the context to support modal layouts. + if ($layout = $app->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + // Adjust the context to support forced languages. + if ($forcedLanguage) + { + $this->context .= '.' . $forcedLanguage; + } + + // Adjust the context to support forced component item types. + if ($forcedItemType) + { + $this->context .= '.' . $forcedItemType; + } + + $this->setState('itemtype', $this->getUserStateFromRequest($this->context . '.itemtype', 'itemtype', '', 'string')); + $this->setState('language', $this->getUserStateFromRequest($this->context . '.language', 'language', '', 'string')); + + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + $this->setState('filter.category_id', $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', '', 'cmd')); + $this->setState('filter.menutype', $this->getUserStateFromRequest($this->context . '.filter.menutype', 'filter_menutype', '', 'string')); + $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'string')); + $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); + + // List state information. + parent::populateState($ordering, $direction); + + // Force a language. + if (!empty($forcedLanguage)) + { + $this->setState('language', $forcedLanguage); + } + + // Force a component item type. + if (!empty($forcedItemType)) + { + $this->setState('itemtype', $forcedItemType); + } + } + + /** + * 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 A store id. + * + * @since 3.7.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('itemtype'); + $id .= ':' . $this->getState('language'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.category_id'); + $id .= ':' . $this->getState('filter.menutype'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.level'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery|boolean + * + * @since 3.7.0 + */ + protected function getListQuery() + { + $type = null; + + list($extensionName, $typeName) = explode('.', $this->state->get('itemtype'), 2); + + $extension = AssociationsHelper::getSupportedExtension($extensionName); + $types = $extension->get('types'); + + if (array_key_exists($typeName, $types)) + { + $type = $types[$typeName]; + } + + if (is_null($type)) + { + return false; + } + + // Create a new query object. + $user = Factory::getUser(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $details = $type->get('details'); + + if (!array_key_exists('support', $details)) + { + return false; + } + + $support = $details['support']; + + if (!array_key_exists('fields', $details)) + { + return false; + } + + $fields = $details['fields']; + + // Main query. + $query->select($db->quoteName($fields['id'], 'id')) + ->select($db->quoteName($fields['title'], 'title')) + ->select($db->quoteName($fields['alias'], 'alias')); + + if (!array_key_exists('tables', $details)) + { + return false; + } + + $tables = $details['tables']; + + foreach ($tables as $key => $table) + { + $query->from($db->quoteName($table, $key)); + } + + if (!array_key_exists('joins', $details)) + { + return false; + } + + $joins = $details['joins']; + + foreach ($joins as $join) + { + $query->join($join['type'], $db->quoteName($join['condition'])); + } + + // Join over the language. + $query->select($db->quoteName($fields['language'], 'language')) + ->select($db->quoteName('l.title', 'language_title')) + ->select($db->quoteName('l.image', 'language_image')) + ->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName($fields['language'])); + + // Join over the associations. + $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($fields['id']) + . ' AND ' . $db->quoteName('asso.context') . ' = ' . $db->quote($extensionName . '.' . 'item') + ) + ->join('LEFT', $db->quoteName('#__associations', 'asso2') . ' ON ' . $db->quoteName('asso2.key') . ' = ' . $db->quoteName('asso.key')); + + // Prepare the group by clause. + $groupby = array( + $fields['id'], + $fields['title'], + $fields['alias'], + $fields['language'], + 'l.title', + 'l.image', + ); + + // Select author for ACL checks. + if (!empty($fields['created_user_id'])) + { + $query->select($db->quoteName($fields['created_user_id'], 'created_user_id')); + + $groupby[] = $fields['created_user_id']; + } + + // Select checked out data for check in checkins. + if (!empty($fields['checked_out']) && !empty($fields['checked_out_time'])) + { + $query->select($db->quoteName($fields['checked_out'], 'checked_out')) + ->select($db->quoteName($fields['checked_out_time'], 'checked_out_time')); + + // Join over the users. + $query->select($db->quoteName('u.name', 'editor')) + ->join('LEFT', $db->quoteName('#__users', 'u') . ' ON ' . $db->quoteName('u.id') . ' = ' . $db->quoteName($fields['checked_out'])); + + $groupby[] = 'u.name'; + $groupby[] = $fields['checked_out']; + $groupby[] = $fields['checked_out_time']; + } + + // If component item type supports ordering, select the ordering also. + if (!empty($fields['ordering'])) + { + $query->select($db->quoteName($fields['ordering'], 'ordering')); + + $groupby[] = $fields['ordering']; + } + + // If component item type supports state, select the item state also. + if (!empty($fields['state'])) + { + $query->select($db->quoteName($fields['state'], 'state')); + + $groupby[] = $fields['state']; + } + + // If component item type supports level, select the level also. + if (!empty($fields['level'])) + { + $query->select($db->quoteName($fields['level'], 'level')); + + $groupby[] = $fields['level']; + } + + // If component item type supports categories, select the category also. + if (!empty($fields['catid'])) + { + $query->select($db->quoteName($fields['catid'], 'catid')); + + // Join over the categories. + $query->select($db->quoteName('c.title', 'category_title')) + ->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName($fields['catid'])); + + $groupby[] = 'c.title'; + $groupby[] = $fields['catid']; + } + + // If component item type supports menu type, select the menu type also. + if (!empty($fields['menutype'])) + { + $query->select($db->quoteName($fields['menutype'], 'menutype')); + + // Join over the menu types. + $query->select($db->quoteName('mt.title', 'menutype_title')) + ->select($db->quoteName('mt.id', 'menutypeid')) + ->join('LEFT', $db->quoteName('#__menu_types', 'mt') . ' ON ' . $db->quoteName('mt.menutype') . ' = ' . $db->quoteName($fields['menutype'])); + + $groupby[] = 'mt.title'; + $groupby[] = 'mt.id'; + $groupby[] = $fields['menutype']; + } + + // If component item type supports access level, select the access level also. + if (array_key_exists('acl', $support) && $support['acl'] == true && !empty($fields['access'])) + { + $query->select($db->quoteName($fields['access'], 'access')); + + // Join over the access levels. + $query->select($db->quoteName('ag.title', 'access_level')) + ->join('LEFT', $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->quoteName('ag.id') . ' = ' . $db->quoteName($fields['access'])); + + $groupby[] = 'ag.title'; + $groupby[] = $fields['access']; + + // Implement View Level Access. + if (!$user->authorise('core.admin', $extensionName)) + { + $query->where($fields['access'] . ' IN (' . implode(',', $user->getAuthorisedViewLevels()) . ')'); + } + } + + // If component item type is menus we need to remove the root item and the administrator menu. + if ($extensionName === 'com_menus') + { + $query->where($db->quoteName($fields['id']) . ' > 1') + ->where($db->quoteName('a.client_id') . ' = 0'); + } + + // If component item type is category we need to remove all other component categories. + if ($typeName === 'category') + { + $query->where($db->quoteName('a.extension') . ' = ' . $db->quote($extensionName)); + } + elseif ($typeNameExploded = explode('.', $typeName)) + { + if (count($typeNameExploded) > 1 && array_pop($typeNameExploded) === 'category') + { + $section = implode('.', $typeNameExploded); + $query->where($db->quoteName('a.extension') . ' = ' . $db->quote($extensionName . '.' . $section)); + } + } + + // Filter on the language. + if ($language = $this->getState('language')) + { + $query->where($db->quoteName($fields['language']) . ' = ' . $db->quote($language)); + } + + // Filter by item state. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where($db->quoteName($fields['state']) . ' = ' . (int) $state); + } + elseif ($state === '') + { + $query->where($db->quoteName($fields['state']) . ' IN (0, 1)'); + } + + // Filter on the category. + $baselevel = 1; + + if ($categoryId = $this->getState('filter.category_id')) + { + $categoryTable = Table::getInstance('Category', 'JTable'); + $categoryTable->load($categoryId); + $baselevel = (int) $categoryTable->level; + + $query->where($db->quoteName('c.lft') . ' >= ' . (int) $categoryTable->lft) + ->where($db->quoteName('c.rgt') . ' <= ' . (int) $categoryTable->rgt); + } + + // Filter on the level. + if ($level = $this->getState('filter.level')) + { + $query->where($db->quoteName('a.level') . ' <= ' . ((int) $level + (int) $baselevel - 1)); + } + + // Filter by menu type. + if ($menutype = $this->getState('filter.menutype')) + { + $query->where($fields['menutype'] . ' = ' . $db->quote($menutype)); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where($fields['access'] . ' = ' . (int) $access); + } + + // Filter by search in name. + if ($search = $this->getState('filter.search')) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName($fields['id']) . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(' . $db->quoteName($fields['title']) . ' LIKE ' . $search + . ' OR ' . $db->quoteName($fields['alias']) . ' LIKE ' . $search . ')' + ); + } + } + + // Add the group by clause + $query->group($db->quoteName($groupby)); + + // Add the list ordering clause + $listOrdering = $this->state->get('list.ordering', 'id'); + $orderDirn = $this->state->get('list.direction', 'ASC'); + + $query->order($db->escape($listOrdering) . ' ' . $db->escape($orderDirn)); + + return $query; + } + + /** + * Delete associations from #__associations table. + * + * @param string $context The associations context. Empty for all. + * @param string $key The associations key. Empty for all. + * + * @return boolean True on success. + * + * @since 3.7.0 + */ + public function purge($context = '', $key = '') + { + $app = Factory::getApplication(); + $db = $this->getDbo(); + $query = $db->getQuery(true)->delete($db->quoteName('#__associations')); + + // Filter by associations context. + if ($context) + { + $query->where($db->quoteName('context') . ' = ' . $db->quote($context)); + } + + // Filter by key. + if ($key) + { + $query->where($db->quoteName('key') . ' = ' . $db->quote($key)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (ExecutionFailureException $e) + { + $app->enqueueMessage(Text::_('COM_ASSOCIATIONS_PURGE_FAILED'), 'error'); + + return false; + } + + $app->enqueueMessage( + Text::_((int) $db->getAffectedRows() > 0 ? 'COM_ASSOCIATIONS_PURGE_SUCCESS' : 'COM_ASSOCIATIONS_PURGE_NONE'), + 'message' + ); + + return true; + } + + /** + * Delete orphans from the #__associations table. + * + * @param string $context The associations context. Empty for all. + * @param string $key The associations key. Empty for all. + * + * @return boolean True on success + * + * @since 3.7.0 + */ + public function clean($context = '', $key = '') + { + $app = Factory::getApplication(); + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('key') . ', COUNT(*)') + ->from($db->quoteName('#__associations')) + ->group($db->quoteName('key')) + ->having('COUNT(*) = 1'); + + // Filter by associations context. + if ($context) + { + $query->where($db->quoteName('context') . ' = ' . $db->quote($context)); + } + + // Filter by key. + if ($key) + { + $query->where($db->quoteName('key') . ' = ' . $db->quote($key)); + } + + $db->setQuery($query); + + $assocKeys = $db->loadObjectList(); + + $count = 0; + + // We have orphans. Let's delete them. + foreach ($assocKeys as $value) + { + $query->clear() + ->delete($db->quoteName('#__associations')) + ->where($db->quoteName('key') . ' = ' . $db->quote($value->key)); + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (ExecutionFailureException $e) + { + $app->enqueueMessage(Text::_('COM_ASSOCIATIONS_DELETE_ORPHANS_FAILED'), 'error'); + + return false; + } + + $count += (int) $db->getAffectedRows(); + } + + $app->enqueueMessage( + Text::_($count > 0 ? 'COM_ASSOCIATIONS_DELETE_ORPHANS_SUCCESS' : 'COM_ASSOCIATIONS_DELETE_ORPHANS_NONE'), + 'message' + ); + + return true; + } +} diff --git a/administrator/components/com_associations/View/Association/HtmlView.php b/administrator/components/com_associations/View/Association/HtmlView.php new file mode 100644 index 0000000000000..361b3d3a62f13 --- /dev/null +++ b/administrator/components/com_associations/View/Association/HtmlView.php @@ -0,0 +1,250 @@ +get('Errors'))) + { + throw new \Exception(implode("\n", $errors), 500); + } + + $this->app = Factory::getApplication(); + $this->form = $this->get('Form'); + $input = $this->app->input; + $this->referenceId = $input->get('id', 0, 'int'); + + list($extensionName, $typeName) = explode('.', $input->get('itemtype', '', 'string'), 2); + + $extension = AssociationsHelper::getSupportedExtension($extensionName); + $types = $extension->get('types'); + + if (array_key_exists($typeName, $types)) + { + $this->type = $types[$typeName]; + $this->typeSupports = array(); + $details = $this->type->get('details'); + $this->save2copy = false; + + if (array_key_exists('support', $details)) + { + $support = $details['support']; + $this->typeSupports = $support; + } + + if (!empty($this->typeSupports['save2copy'])) + { + $this->save2copy = true; + } + } + + $this->extensionName = $extensionName; + $this->typeName = $typeName; + $this->itemtype = $extensionName . '.' . $typeName; + + $languageField = AssociationsHelper::getTypeFieldName($extensionName, $typeName, 'language'); + $referenceId = $input->get('id', 0, 'int'); + $reference = ArrayHelper::fromObject(AssociationsHelper::getItem($extensionName, $typeName, $referenceId)); + + $this->referenceLanguage = $reference[$languageField]; + + // Check for special case category + $typeNameExploded = explode('.', $typeName); + if (array_pop($typeNameExploded) === 'category') + { + $this->typeName = 'category'; + + if ($typeNameExploded) + { + $extensionName .= '.' . implode('.', $typeNameExploded); + } + + $options = array( + 'option' => 'com_categories', + 'view' => 'category', + 'extension' => $extensionName, + 'tmpl' => 'component', + ); + } + else + { + $options = array( + 'option' => $extensionName, + 'view' => $typeName, + 'extension' => $extensionName, + 'tmpl' => 'component', + ); + } + + // Reference and target edit links. + $this->editUri = 'index.php?' . http_build_query($options); + + // Get target language. + $this->targetId = '0'; + $this->targetLanguage = ''; + $this->defaultTargetSrc = ''; + $this->targetAction = ''; + + if ($target = $input->get('target', '', 'string')) + { + $matches = preg_split("#[\:]+#", $target); + $this->targetAction = $matches[2]; + $this->targetId = $matches[1]; + $this->targetLanguage = $matches[0]; + $task = $this->typeName . '.' . $this->targetAction; + $this->defaultTargetSrc = Route::_($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(); + } + 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 = Factory::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 a 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'); + } + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.7.0 + */ + protected function addToolbar() + { + // Hide main menu. + Factory::getApplication()->input->set('hidemainmenu', 1); + + $helper = AssociationsHelper::getExtensionHelper($this->extensionName); + $title = $helper->getTypeTitle($this->typeName); + + $languageKey = strtoupper($this->extensionName . '_' . $title . 'S'); + + if ($this->typeName === 'category') + { + $languageKey = strtoupper($this->extensionName) . '_CATEGORIES'; + } + + ToolbarHelper::title(Text::sprintf('COM_ASSOCIATIONS_TITLE_EDIT', Text::_($this->extensionName), Text::_($languageKey)), 'contract assoc'); + + $bar = Toolbar::getInstance('toolbar'); + + $bar->appendButton( + 'Custom', '', 'reference' + ); + + $bar->appendButton( + 'Custom', '', 'target' + ); + + if ($this->typeName === 'category' || $this->extensionName === 'com_menus' || $this->save2copy === true) + { + ToolbarHelper::custom('copy', 'copy.png', '', 'COM_ASSOCIATIONS_COPY_REFERENCE', false); + } + + ToolbarHelper::cancel('association.cancel', 'JTOOLBAR_CLOSE'); + ToolbarHelper::help('JHELP_COMPONENTS_ASSOCIATIONS_EDIT'); + + \JHtmlSidebar::setAction('index.php?option=com_associations'); + } +} diff --git a/administrator/components/com_associations/View/Associations/HtmlView.php b/administrator/components/com_associations/View/Associations/HtmlView.php new file mode 100644 index 0000000000000..6b1dc2a5156cc --- /dev/null +++ b/administrator/components/com_associations/View/Associations/HtmlView.php @@ -0,0 +1,245 @@ +state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + if (!Associations::isEnabled()) + { + $link = Route::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . AssociationsHelper::getLanguagefilterPluginId()); + Factory::getApplication()->enqueueMessage(Text::sprintf('COM_ASSOCIATIONS_ERROR_NO_ASSOC', $link), 'warning'); + } + elseif ($this->state->get('itemtype') == '' || $this->state->get('language') == '') + { + Factory::getApplication()->enqueueMessage(Text::_('COM_ASSOCIATIONS_NOTICE_NO_SELECTORS'), 'notice'); + } + else + { + $type = null; + + list($extensionName, $typeName) = explode('.', $this->state->get('itemtype'), 2); + + $extension = AssociationsHelper::getSupportedExtension($extensionName); + + $types = $extension->get('types'); + + if (array_key_exists($typeName, $types)) + { + $type = $types[$typeName]; + } + + $this->itemType = $type; + + if (is_null($type)) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_ASSOCIATIONS_ERROR_NO_TYPE'), 'warning'); + } + else + { + $this->extensionName = $extensionName; + $this->typeName = $typeName; + $this->typeSupports = array(); + $this->typeFields = array(); + + $details = $type->get('details'); + + if (array_key_exists('support', $details)) + { + $support = $details['support']; + $this->typeSupports = $support; + } + + if (array_key_exists('fields', $details)) + { + $fields = $details['fields']; + $this->typeFields = $fields; + } + + // Dynamic filter form. + // This selectors doesn't have to activate the filter bar. + unset($this->activeFilters['itemtype']); + unset($this->activeFilters['language']); + + // Remove filters options depending on selected type. + if (empty($support['state'])) + { + 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']); + $this->filterForm->removeField('access', 'filter'); + } + + // Add extension attribute to category filter. + if (empty($support['catid'])) + { + $this->filterForm->setFieldAttribute('category_id', 'extension', $extensionName, 'filter'); + } + + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + + $linkParameters = array( + 'layout' => 'edit', + 'itemtype' => $extensionName . '.' . $typeName, + 'task' => 'association.edit', + ); + + $this->editUri = 'index.php?option=com_associations&view=association&' . http_build_query($linkParameters); + } + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \Exception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + // Will add sidebar if needed $this->sidebar = \JHtmlSidebar::render(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.7.0 + */ + protected function addToolbar() + { + $user = Factory::getUser(); + + if (isset($this->typeName) && isset($this->extensionName)) + { + $helper = AssociationsHelper::getExtensionHelper($this->extensionName); + $title = $helper->getTypeTitle($this->typeName); + + $languageKey = strtoupper($this->extensionName . '_' . $title . 'S'); + + if ($this->typeName === 'category') + { + $languageKey = strtoupper($this->extensionName) . '_CATEGORIES'; + } + + ToolbarHelper::title( + Text::sprintf( + 'COM_ASSOCIATIONS_TITLE_LIST', Text::_($this->extensionName), Text::_($languageKey) + ), 'contract assoc' + ); + } + else + { + ToolbarHelper::title(Text::_('COM_ASSOCIATIONS_TITLE_LIST_SELECT'), 'contract assoc'); + } + + if ($user->authorise('core.admin', 'com_associations') || $user->authorise('core.options', 'com_associations')) + { + if (!isset($this->typeName)) + { + ToolbarHelper::custom('associations.purge', 'purge', 'purge', 'COM_ASSOCIATIONS_PURGE', false, false); + ToolbarHelper::custom('associations.clean', 'refresh', 'refresh', 'COM_ASSOCIATIONS_DELETE_ORPHANS', false, false); + } + + ToolbarHelper::preferences('com_associations'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_ASSOCIATIONS'); + } +} diff --git a/administrator/components/com_associations/access.xml b/administrator/components/com_associations/access.xml index e6fd1ec5258d2..5f4d60de794cc 100644 --- a/administrator/components/com_associations/access.xml +++ b/administrator/components/com_associations/access.xml @@ -1,8 +1,8 @@
- - - + + +
diff --git a/administrator/components/com_associations/associations.php b/administrator/components/com_associations/associations.php deleted file mode 100644 index 67bbd2551e0bb..0000000000000 --- a/administrator/components/com_associations/associations.php +++ /dev/null @@ -1,41 +0,0 @@ -authorise('core.manage', 'com_associations')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -JLoader::register('AssociationsHelper', __DIR__ . '/helpers/associations.php'); - -// Check if user has permission to access the component item type. -$itemtype = JFactory::getApplication()->input->get('itemtype', '', 'string'); - -if ($itemtype !== '') -{ - list($extensionName, $typeName) = explode('.', $itemtype); - - if (!AssociationsHelper::hasSupport($extensionName)) - { - throw new Exception(JText::sprintf('COM_ASSOCIATIONS_COMPONENT_NOT_SUPPORTED', JText::_($extensionName)), 404); - } - - if (!JFactory::getUser()->authorise('core.manage', $extensionName)) - { - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); - } -} - -$controller = JControllerLegacy::getInstance('Associations'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_associations/associations.xml b/administrator/components/com_associations/associations.xml index 751df652d825f..d569f4f1c0634 100644 --- a/administrator/components/com_associations/associations.xml +++ b/administrator/components/com_associations/associations.xml @@ -9,6 +9,7 @@ www.joomla.org 3.7.0 COM_ASSOCIATIONS_XML_DESCRIPTION + Joomla\Component\Associations COM_ASSOCIATIONS diff --git a/administrator/components/com_associations/controller.php b/administrator/components/com_associations/controller.php deleted file mode 100644 index f6dd3579a81c3..0000000000000 --- a/administrator/components/com_associations/controller.php +++ /dev/null @@ -1,27 +0,0 @@ -input->get('itemtype', '', 'string')); - - $id = $this->input->get('id', 0, 'int'); - - // Check if reference item can be edited. - if (!AssociationsHelper::allowEdit($extensionName, $typeName, $id)) - { - JFactory::getApplication()->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_associations&view=associations', false)); - - return false; - } - - return parent::display(); - } - - /** - * Method for canceling the edit action - * - * @param string $key The name of the primary key of the URL variable. - * - * @return void - * - * @since 3.7.0 - */ - public function cancel($key = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - list($extensionName, $typeName) = explode('.', $this->input->get('itemtype', '', 'string')); - - // Only check in, if component item type allows to check out. - if (AssociationsHelper::typeSupportsCheckout($extensionName, $typeName)) - { - $ids = array(); - $targetId = $this->input->get('target-id', '', 'string'); - - if ($targetId !== '') - { - $ids = array_unique(explode(',', $targetId)); - } - - $ids[] = $this->input->get('id', 0, 'int'); - - foreach ($ids as $key => $id) - { - AssociationsHelper::getItem($extensionName, $typeName, $id)->checkin(); - } - } - - $this->setRedirect(JRoute::_('index.php?option=com_associations&view=associations', false)); - } -} diff --git a/administrator/components/com_associations/controllers/associations.php b/administrator/components/com_associations/controllers/associations.php deleted file mode 100644 index 6ef44726748b4..0000000000000 --- a/administrator/components/com_associations/controllers/associations.php +++ /dev/null @@ -1,130 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Method to purge the associations table. - * - * @return void - * - * @since 3.7.0 - */ - public function purge() - { - $this->getModel('associations')->purge(); - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); - } - - /** - * Method to delete the orphans from the associations table. - * - * @return void - * - * @since 3.7.0 - */ - public function clean() - { - $this->getModel('associations')->clean(); - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); - } - - /** - * Method to check in an item from the association item overview. - * - * @return void - * - * @since 3.7.1 - */ - public function checkin() - { - // Set the redirect so we can just stop processing when we find a condition we can't process - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); - - // Figure out if the item supports checking and check it in - $type = null; - - list($extensionName, $typeName) = explode('.', $this->input->get('itemtype')); - - $extension = AssociationsHelper::getSupportedExtension($extensionName); - $types = $extension->get('types'); - - if (!array_key_exists($typeName, $types)) - { - return; - } - - if (AssociationsHelper::typeSupportsCheckout($extensionName, $typeName) === false) - { - // How on earth we came to that point, eject internet - return; - } - - $cid = $this->input->get('cid', array(), 'array'); - - if (empty($cid)) - { - // Seems we don't have an id to work with. - return; - } - - // We know the first element is the one we need because we don't allow multi selection of rows - $id = $cid[0]; - - if (AssociationsHelper::canCheckinItem($extensionName, $typeName, $id) === true) - { - $item = AssociationsHelper::getItem($extensionName, $typeName, $id); - - $item->checkIn($id); - - return; - } - - $this->setRedirect( - JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list), - JText::_('COM_ASSOCIATIONS_YOU_ARE_NOT_ALLOWED_TO_CHECKIN_THIS_ITEM') - ); - - return; - } -} diff --git a/administrator/components/com_associations/models/forms/association.xml b/administrator/components/com_associations/forms/association.xml similarity index 77% rename from administrator/components/com_associations/models/forms/association.xml rename to administrator/components/com_associations/forms/association.xml index 9e8d880e22984..2ef5807a3ea02 100644 --- a/administrator/components/com_associations/models/forms/association.xml +++ b/administrator/components/com_associations/forms/association.xml @@ -1,18 +1,17 @@ -
+
diff --git a/administrator/components/com_associations/models/forms/filter_associations.xml b/administrator/components/com_associations/forms/filter_associations.xml similarity index 79% rename from administrator/components/com_associations/models/forms/filter_associations.xml rename to administrator/components/com_associations/forms/filter_associations.xml index 9563de4489650..e5f25f9ff1e52 100644 --- a/administrator/components/com_associations/models/forms/filter_associations.xml +++ b/administrator/components/com_associations/forms/filter_associations.xml @@ -1,10 +1,8 @@ - + @@ -14,8 +12,6 @@ @@ -34,8 +30,6 @@ @@ -44,8 +38,6 @@ @@ -67,8 +57,6 @@ @@ -77,8 +65,6 @@ getAssociationList($typeName, $itemId); - - } - - /** - * Get the the instance of the extension helper class - * - * @param string $extensionName The extension name with com_ - * - * @return HelperClass|null - * - * @since 3.7.0 - */ - public static function getExtensionHelper($extensionName) - { - if (!self::hasSupport($extensionName)) - { - return null; - } - - $support = self::$extensionsSupport[$extensionName]; - - return $support->get('helper'); - } - - /** - * Get item information - * - * @param string $extensionName The extension name with com_ - * @param string $typeName The item type - * @param int $itemId The id of item for which we need the associated items - * - * @return JTable|null - * - * @since 3.7.0 - */ - public static function getItem($extensionName, $typeName, $itemId) - { - if (!self::hasSupport($extensionName)) - { - return array(); - } - - // Get the extension specific helper method - $helper = self::getExtensionHelper($extensionName); - - return $helper->getItem($typeName, $itemId); - } - - /** - * Check if extension supports associations - * - * @param string $extensionName The extension name with com_ - * - * @return boolean - * - * @since 3.7.0 - */ - public static function hasSupport($extensionName) - { - if (is_null(self::$extensionsSupport)) - { - self::getSupportedExtensions(); - } - - return in_array($extensionName, self::$supportedExtensionsList); - } - - /** - * Get the extension specific helper class name - * - * @param string $extensionName The extension name with com_ - * - * @return boolean - * - * @since 3.7.0 - */ - private static function getExtensionHelperClassName($extensionName) - { - $realName = self::getExtensionRealName($extensionName); - - return ucfirst($realName) . 'AssociationsHelper'; - } - - /** - * Get the real extension name. This means without com_ - * - * @param string $extensionName The extension name with com_ - * - * @return string - * - * @since 3.7.0 - */ - private static function getExtensionRealName($extensionName) - { - return strpos($extensionName, 'com_') === false ? $extensionName : substr($extensionName, 4); - } - - /** - * Get the associated language edit links Html. - * - * @param string $extensionName Extension Name - * @param string $typeName ItemType - * @param integer $itemId Item id. - * @param string $itemLanguage Item language code. - * @param boolean $addLink True for adding edit links. False for just text. - * @param boolean $assocLanguages True for showing non associated content languages. False only languages with associations. - * - * @return string The language HTML - * - * @since 3.7.0 - */ - public static function getAssociationHtmlList($extensionName, $typeName, $itemId, $itemLanguage, $addLink = true, $assocLanguages = true) - { - // Get the associations list for this item. - $items = self::getAssociationList($extensionName, $typeName, $itemId); - - $titleFieldName = self::getTypeFieldName($extensionName, $typeName, 'title'); - - // Get all content languages. - $languages = LanguageHelper::getContentLanguages(array(0, 1)); - - $canEditReference = self::allowEdit($extensionName, $typeName, $itemId); - $canCreate = self::allowAdd($extensionName, $typeName); - - // Create associated items list. - foreach ($languages as $langCode => $language) - { - // Don't do for the reference language. - if ($langCode == $itemLanguage) - { - continue; - } - - // Don't show languages with associations, if we don't want to show them. - if ($assocLanguages && isset($items[$langCode])) - { - unset($items[$langCode]); - continue; - } - - // Don't show languages without associations, if we don't want to show them. - if (!$assocLanguages && !isset($items[$langCode])) - { - continue; - } - - // Get html parameters. - if (isset($items[$langCode])) - { - $title = $items[$langCode][$titleFieldName]; - $additional = ''; - - if (isset($items[$langCode]['catid'])) - { - $db = JFactory::getDbo(); - - // Get the category name - $query = $db->getQuery(true) - ->select($db->quoteName('title')) - ->from($db->quoteName('#__categories')) - ->where($db->quoteName('id') . ' = ' . $db->quote($items[$langCode]['catid'])); - - $db->setQuery($query); - $category_title = $db->loadResult(); - - $additional = '' . JText::sprintf('JCATEGORY_SPRINTF', $category_title) . '
'; - } - elseif (isset($items[$langCode]['menutype'])) - { - $db = JFactory::getDbo(); - - // Get the menutype name - $query = $db->getQuery(true) - ->select($db->quoteName('title')) - ->from($db->quoteName('#__menu_types')) - ->where($db->quoteName('menutype') . ' = ' . $db->quote($items[$langCode]['menutype'])); - - $db->setQuery($query); - $menutype_title = $db->loadResult(); - - $additional = '' . JText::sprintf('COM_MENUS_MENU_SPRINTF', $menutype_title) . '
'; - } - - $labelClass = ''; - $target = $langCode . ':' . $items[$langCode]['id'] . ':edit'; - $allow = $canEditReference - && self::allowEdit($extensionName, $typeName, $items[$langCode]['id']) - && self::canCheckinItem($extensionName, $typeName, $items[$langCode]['id']); - - $additional .= $addLink && $allow ? JText::_('COM_ASSOCIATIONS_EDIT_ASSOCIATION') : ''; - } - else - { - $items[$langCode] = array(); - - $title = JText::_('COM_ASSOCIATIONS_NO_ASSOCIATION'); - $additional = $addLink ? JText::_('COM_ASSOCIATIONS_ADD_NEW_ASSOCIATION') : ''; - $labelClass = 'label-warning'; - $target = $langCode . ':0:add'; - $allow = $canCreate; - } - - // Generate item Html. - $options = array( - 'option' => 'com_associations', - 'view' => 'association', - 'layout' => 'edit', - 'itemtype' => $extensionName . '.' . $typeName, - 'task' => 'association.edit', - 'id' => $itemId, - 'target' => $target, - ); - - $url = JRoute::_('index.php?' . http_build_query($options)); - $url = $allow && $addLink ? $url : ''; - $text = strtoupper($language->sef); - - $tooltip = htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '

' . $additional; - $classes = 'hasPopover label ' . $labelClass . ' label-' . $language->sef; - - $items[$langCode]['link'] = '' - . $text . ''; - } - - JHtml::_('bootstrap.popover'); - - return JLayoutHelper::render('joomla.content.associations', $items); - } - - /** - * Get all extensions with associations support. - * - * @return array The extensions. - * - * @since 3.7.0 - */ - public static function getSupportedExtensions() - { - if (!is_null(self::$extensionsSupport)) - { - return self::$extensionsSupport; - } - - self::$extensionsSupport = array(); - - $extensions = self::getEnabledExtensions(); - - foreach ($extensions as $extension) - { - $support = self::getSupportedExtension($extension->element); - - if ($support->get('associationssupport') === true) - { - self::$supportedExtensionsList[] = $extension->element; - } - - self::$extensionsSupport[$extension->element] = $support; - } - - return self::$extensionsSupport; - } - - /** - * Get item context based on the item key. - * - * @param string $extensionName The extension identifier. - * - * @return Joomla\Registry\Registry The item properties. - * - * @since 3.7.0 - */ - public static function getSupportedExtension($extensionName) - { - $result = new Registry; - - $result->def('component', $extensionName); - $result->def('associationssupport', false); - $result->def('helper', null); - - // Check if associations helper exists - if (!file_exists(JPATH_ADMINISTRATOR . '/components/' . $extensionName . '/helpers/associations.php')) - { - return $result; - } - - require_once JPATH_ADMINISTRATOR . '/components/' . $extensionName . '/helpers/associations.php'; - - $componentAssociationsHelperClassName = self::getExtensionHelperClassName($extensionName); - - if (!class_exists($componentAssociationsHelperClassName, false)) - { - return $result; - } - - // Create an instance of the helper class - $helper = new $componentAssociationsHelperClassName; - $result->set('helper', $helper); - - if ($helper->hasAssociationsSupport() === false) - { - return $result; - } - - $result->set('associationssupport', true); - - // Get the translated titles. - $languagePath = JPATH_ADMINISTRATOR . '/components/' . $extensionName; - $lang = JFactory::getLanguage(); - - $lang->load($extensionName . '.sys', JPATH_ADMINISTRATOR); - $lang->load($extensionName . '.sys', $languagePath); - $lang->load($extensionName, JPATH_ADMINISTRATOR); - $lang->load($extensionName, $languagePath); - - $result->def('title', JText::_(strtoupper($extensionName))); - - // Get the supported types - $types = $helper->getItemTypes(); - $rTypes = array(); - - foreach ($types as $typeName) - { - $details = $helper->getType($typeName); - $context = 'component'; - $title = $helper->getTypeTitle($typeName); - $languageKey = $typeName; - - if ($typeName === 'category') - { - $languageKey = strtoupper($extensionName) . '_CATEGORIES'; - $context = 'category'; - } - - if ($lang->hasKey(strtoupper($extensionName . '_' . $title . 'S'))) - { - $languageKey = strtoupper($extensionName . '_' . $title . 'S'); - } - - $title = $lang->hasKey($languageKey) ? JText::_($languageKey) : JText::_('COM_ASSOCIATIONS_ITEMS'); - - $rType = new Registry; - - $rType->def('name', $typeName); - $rType->def('details', $details); - $rType->def('title', $title); - $rType->def('context', $context); - - $rTypes[$typeName] = $rType; - } - - $result->def('types', $rTypes); - - return $result; - } - - /** - * Get all installed and enabled extensions - * - * @return mixed - * - * @since 3.7.0 - */ - private static function getEnabledExtensions() - { - $db = JFactory::getDbo(); - - $query = $db->getQuery(true) - ->select('*') - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('type') . ' = ' . $db->quote('component')) - ->where($db->quoteName('enabled') . ' = 1'); - - $db->setQuery($query); - - return $db->loadObjectList(); - } - - /** - * Get all the content languages. - * - * @return array Array of objects all content languages by language code. - * - * @since 3.7.0 - */ - public static function getContentLanguages() - { - return LanguageHelper::getContentLanguages(array(0, 1)); - } - - /** - * Get the associated items for an item - * - * @param string $extensionName The extension name with com_ - * @param string $typeName The item type - * @param int $itemId The id of item for which we need the associated items - * - * @return boolean - * - * @since 3.7.0 - */ - public static function allowEdit($extensionName, $typeName, $itemId) - { - if (!self::hasSupport($extensionName)) - { - return false; - } - - // Get the extension specific helper method - $helper = self::getExtensionHelper($extensionName); - - if (method_exists($helper, 'allowEdit')) - { - return $helper->allowEdit($typeName, $itemId); - } - - return JFactory::getUser()->authorise('core.edit', $extensionName); - } - - /** - * Check if user is allowed to create items. - * - * @param string $extensionName The extension name with com_ - * @param string $typeName The item type - * - * @return boolean True on allowed. - * - * @since 3.7.0 - */ - public static function allowAdd($extensionName, $typeName) - { - if (!self::hasSupport($extensionName)) - { - return false; - } - - // Get the extension specific helper method - $helper = self::getExtensionHelper($extensionName); - - if (method_exists($helper, 'allowAdd')) - { - return $helper->allowAdd($typeName); - } - - return JFactory::getUser()->authorise('core.create', $extensionName); - } - - /** - * Check if an item is checked out - * - * @param string $extensionName The extension name with com_ - * @param string $typeName The item type - * @param int $itemId The id of item for which we need the associated items - * - * @return boolean True if item is checked out. - * - * @since 3.7.0 - */ - public static function isCheckoutItem($extensionName, $typeName, $itemId) - { - if (!self::hasSupport($extensionName)) - { - return false; - } - - if (!self::typeSupportsCheckout($extensionName, $typeName)) - { - return false; - } - - // Get the extension specific helper method - $helper = self::getExtensionHelper($extensionName); - - if (method_exists($helper, 'isCheckoutItem')) - { - return $helper->isCheckoutItem($typeName, $itemId); - } - - $item = self::getItem($extensionName, $typeName, $itemId); - - $checkedOutFieldName = $helper->getTypeFieldName($typeName, 'checked_out'); - - return $item->{$checkedOutFieldName} != 0; - } - - /** - * Check if user can checkin an item. - * - * @param string $extensionName The extension name with com_ - * @param string $typeName The item type - * @param int $itemId The id of item for which we need the associated items - * - * @return boolean True on allowed. - * - * @since 3.7.0 - */ - public static function canCheckinItem($extensionName, $typeName, $itemId) - { - if (!self::hasSupport($extensionName)) - { - return false; - } - - if (!self::typeSupportsCheckout($extensionName, $typeName)) - { - return true; - } - - // Get the extension specific helper method - $helper = self::getExtensionHelper($extensionName); - - if (method_exists($helper, 'canCheckinItem')) - { - return $helper->canCheckinItem($typeName, $itemId); - } - - $item = self::getItem($extensionName, $typeName, $itemId); - - $checkedOutFieldName = $helper->getTypeFieldName($typeName, 'checked_out'); - - $userId = JFactory::getUser()->id; - - return ($item->{$checkedOutFieldName} == $userId || $item->{$checkedOutFieldName} == 0); - } - - /** - * Check if the type supports checkout - * - * @param string $extensionName The extension name with com_ - * @param string $typeName The item type - * - * @return boolean True on allowed. - * - * @since 3.7.0 - */ - public static function typeSupportsCheckout($extensionName, $typeName) - { - if (!self::hasSupport($extensionName)) - { - return false; - } - - // Get the extension specific helper method - $helper = self::getExtensionHelper($extensionName); - - $support = $helper->getTypeSupport($typeName); - - return !empty($support['checkout']); - } - - /** - * Get a table field name for a type - * - * @param string $extensionName The extension name with com_ - * @param string $typeName The item type - * @param string $fieldName The item type - * - * @return boolean True on allowed. - * - * @since 3.7.0 - */ - public static function getTypeFieldName($extensionName, $typeName, $fieldName) - { - if (!self::hasSupport($extensionName)) - { - return false; - } - - // Get the extension specific helper method - $helper = self::getExtensionHelper($extensionName); - - return $helper->getTypeFieldName($typeName, $fieldName); - } - - /** - * Gets the language filter system plugin extension id. - * - * @return integer The language filter system plugin extension id. - * - * @since 3.7.2 - */ - public static function getLanguagefilterPluginId() - { - $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('languagefilter')); - $db->setQuery($query); - - try - { - $result = (int) $db->loadResult(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - return $result; - } -} diff --git a/administrator/components/com_associations/layouts/joomla/searchtools/default.php b/administrator/components/com_associations/layouts/joomla/searchtools/default.php new file mode 100644 index 0000000000000..1c4f03bfc0e2e --- /dev/null +++ b/administrator/components/com_associations/layouts/joomla/searchtools/default.php @@ -0,0 +1,69 @@ +activeFilters['itemtype']); + + // Menutype filter doesn't have to activate the filter bar + unset($data['view']->activeFilters['language']); +} + +// Set some basic options +$customOptions = array( + 'filtersHidden' => $data['options']['filtersHidden'] ?? empty($data['view']->activeFilters), + 'defaultLimit' => $data['options']['defaultLimit'] ?? JFactory::getApplication()->get('list_limit', 20), + 'searchFieldSelector' => '#filter_search', + 'orderFieldSelector' => '#list_fullordering', + 'formSelector' => !empty($data['options']['formSelector']) ? $data['options']['formSelector'] : '#adminForm', +); + +$data['options'] = array_merge($customOptions, $data['options']); + +// Load search tools +JHtml::_('searchtools.form', $data['options']['formSelector'], $data['options']); + +$filtersClass = isset($data['view']->activeFilters) && $data['view']->activeFilters ? ' js-stools-container-filters-visible' : ''; +?> + diff --git a/administrator/components/com_associations/layouts/joomla/searchtools/default/bar.php b/administrator/components/com_associations/layouts/joomla/searchtools/default/bar.php deleted file mode 100644 index db174b29dc7b9..0000000000000 --- a/administrator/components/com_associations/layouts/joomla/searchtools/default/bar.php +++ /dev/null @@ -1,32 +0,0 @@ - - - - - input->get('forcedItemType', '', 'string') == '') : ?> - filterForm->getField('itemtype'); ?> -
- input; ?> -
- - input->get('forcedLanguage', '', 'cmd') == '') : ?> - filterForm->getField('language'); ?> -
- input; ?> -
- - - - 'none')); ?> diff --git a/administrator/components/com_associations/models/association.php b/administrator/components/com_associations/models/association.php deleted file mode 100644 index 79b39ef910f59..0000000000000 --- a/administrator/components/com_associations/models/association.php +++ /dev/null @@ -1,36 +0,0 @@ -loadForm('com_associations.association', 'association', array('control' => 'jform', 'load_data' => $loadData)); - - return !empty($form) ? $form : false; - } -} diff --git a/administrator/components/com_associations/models/associations.php b/administrator/components/com_associations/models/associations.php deleted file mode 100644 index bee4212e780ce..0000000000000 --- a/administrator/components/com_associations/models/associations.php +++ /dev/null @@ -1,532 +0,0 @@ -input->get('forcedLanguage', '', 'cmd'); - $forcedItemType = $app->input->get('forcedItemType', '', 'string'); - - // Adjust the context to support modal layouts. - if ($layout = $app->input->get('layout')) - { - $this->context .= '.' . $layout; - } - - // Adjust the context to support forced languages. - if ($forcedLanguage) - { - $this->context .= '.' . $forcedLanguage; - } - - // Adjust the context to support forced component item types. - if ($forcedItemType) - { - $this->context .= '.' . $forcedItemType; - } - - $this->setState('itemtype', $this->getUserStateFromRequest($this->context . '.itemtype', 'itemtype', '', 'string')); - $this->setState('language', $this->getUserStateFromRequest($this->context . '.language', 'language', '', 'string')); - - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); - $this->setState('filter.category_id', $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', '', 'cmd')); - $this->setState('filter.menutype', $this->getUserStateFromRequest($this->context . '.filter.menutype', 'filter_menutype', '', 'string')); - $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'string')); - $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); - - // List state information. - parent::populateState($ordering, $direction); - - // Force a language. - if (!empty($forcedLanguage)) - { - $this->setState('language', $forcedLanguage); - } - - // Force a component item type. - if (!empty($forcedItemType)) - { - $this->setState('itemtype', $forcedItemType); - } - } - - /** - * 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 A store id. - * - * @since 3.7.0 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('itemtype'); - $id .= ':' . $this->getState('language'); - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.state'); - $id .= ':' . $this->getState('filter.category_id'); - $id .= ':' . $this->getState('filter.menutype'); - $id .= ':' . $this->getState('filter.access'); - $id .= ':' . $this->getState('filter.level'); - - return parent::getStoreId($id); - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery|boolean - * - * @since 3.7.0 - */ - protected function getListQuery() - { - $type = null; - - list($extensionName, $typeName) = explode('.', $this->state->get('itemtype')); - - $extension = AssociationsHelper::getSupportedExtension($extensionName); - $types = $extension->get('types'); - - if (array_key_exists($typeName, $types)) - { - $type = $types[$typeName]; - } - - if (is_null($type)) - { - return false; - } - - // Create a new query object. - $user = JFactory::getUser(); - $db = $this->getDbo(); - $query = $db->getQuery(true); - - $details = $type->get('details'); - - if (!array_key_exists('support', $details)) - { - return false; - } - - $support = $details['support']; - - if (!array_key_exists('fields', $details)) - { - return false; - } - - $fields = $details['fields']; - - // Main query. - $query->select($db->qn($fields['id'], 'id')) - ->select($db->qn($fields['title'], 'title')) - ->select($db->qn($fields['alias'], 'alias')); - - if (!array_key_exists('tables', $details)) - { - return false; - } - - $tables = $details['tables']; - - foreach ($tables as $key => $table) - { - $query->from($db->qn($table, $key)); - } - - if (!array_key_exists('joins', $details)) - { - return false; - } - - $joins = $details['joins']; - - foreach ($joins as $join) - { - $query->join($join['type'], $db->qn($join['condition'])); - } - - // Join over the language. - $query->select($db->qn($fields['language'], 'language')) - ->select($db->qn('l.title', 'language_title')) - ->select($db->qn('l.image', 'language_image')) - ->join('LEFT', $db->qn('#__languages', 'l') . ' ON ' . $db->qn('l.lang_code') . ' = ' . $db->qn($fields['language'])); - - // Join over the associations. - $query->select('COUNT(' . $db->qn('asso2.id') . ') > 1 AS ' . $db->qn('association')) - ->join( - 'LEFT', - $db->qn('#__associations', 'asso') . ' ON ' . $db->qn('asso.id') . ' = ' . $db->qn($fields['id']) - . ' AND ' . $db->qn('asso.context') . ' = ' . $db->quote($extensionName . '.' . 'item') - ) - ->join('LEFT', $db->qn('#__associations', 'asso2') . ' ON ' . $db->qn('asso2.key') . ' = ' . $db->qn('asso.key')); - - // Prepare the group by clause. - $groupby = array( - $fields['id'], - $fields['title'], - $fields['language'], - 'l.title', - 'l.image', - ); - - // Select author for ACL checks. - if (!empty($fields['created_user_id'])) - { - $query->select($db->qn($fields['created_user_id'], 'created_user_id')); - } - - // Select checked out data for check in checkins. - if (!empty($fields['checked_out']) && !empty($fields['checked_out_time'])) - { - $query->select($db->qn($fields['checked_out'], 'checked_out')) - ->select($db->qn($fields['checked_out_time'], 'checked_out_time')); - - // Join over the users. - $query->select($db->qn('u.name', 'editor')) - ->join('LEFT', $db->qn('#__users', 'u') . ' ON ' . $db->qn('u.id') . ' = ' . $db->qn($fields['checked_out'])); - - $groupby[] = 'u.name'; - } - - // If component item type supports ordering, select the ordering also. - if (!empty($fields['ordering'])) - { - $query->select($db->qn($fields['ordering'], 'ordering')); - } - - // If component item type supports state, select the item state also. - if (!empty($fields['state'])) - { - $query->select($db->qn($fields['state'], 'state')); - } - - // If component item type supports level, select the level also. - if (!empty($fields['level'])) - { - $query->select($db->qn($fields['level'], 'level')); - } - - // If component item type supports categories, select the category also. - if (!empty($fields['catid'])) - { - $query->select($db->qn($fields['catid'], 'catid')); - - // Join over the categories. - $query->select($db->qn('c.title', 'category_title')) - ->join('LEFT', $db->qn('#__categories', 'c') . ' ON ' . $db->qn('c.id') . ' = ' . $db->qn($fields['catid'])); - - $groupby[] = 'c.title'; - } - - // If component item type supports menu type, select the menu type also. - if (!empty($fields['menutype'])) - { - $query->select($db->qn($fields['menutype'], 'menutype')); - - // Join over the menu types. - $query->select($db->qn('mt.title', 'menutype_title')) - ->select($db->qn('mt.id', 'menutypeid')) - ->join('LEFT', $db->qn('#__menu_types', 'mt') . ' ON ' . $db->qn('mt.menutype') . ' = ' . $db->qn($fields['menutype'])); - - $groupby[] = 'mt.title'; - $groupby[] = 'mt.id'; - } - - // If component item type supports access level, select the access level also. - if (array_key_exists('acl', $support) && $support['acl'] == true && !empty($fields['access'])) - { - $query->select($db->qn($fields['access'], 'access')); - - // Join over the access levels. - $query->select($db->qn('ag.title', 'access_level')) - ->join('LEFT', $db->qn('#__viewlevels', 'ag') . ' ON ' . $db->qn('ag.id') . ' = ' . $db->qn($fields['access'])); - - $groupby[] = 'ag.title'; - - // Implement View Level Access. - if (!$user->authorise('core.admin', $extensionName)) - { - $query->where($fields['access'] . ' IN (' . implode(',', $user->getAuthorisedViewLevels()) . ')'); - } - } - - // If component item type is menus we need to remove the root item and the administrator menu. - if ($extensionName === 'com_menus') - { - $query->where($db->qn($fields['id']) . ' > 1') - ->where($db->qn('a.client_id') . ' = 0'); - } - - // If component item type is category we need to remove all other component categories. - if ($typeName === 'category') - { - $query->where($db->qn('a.extension') . ' = ' . $db->quote($extensionName)); - } - - // Filter on the language. - if ($language = $this->getState('language')) - { - $query->where($db->qn($fields['language']) . ' = ' . $db->quote($language)); - } - - // Filter by item state. - $state = $this->getState('filter.state'); - - if (is_numeric($state)) - { - $query->where($db->qn($fields['state']) . ' = ' . (int) $state); - } - elseif ($state === '') - { - $query->where($db->qn($fields['state']) . ' IN (0, 1)'); - } - - // Filter on the category. - $baselevel = 1; - - if ($categoryId = $this->getState('filter.category_id')) - { - $categoryTable = JTable::getInstance('Category', 'JTable'); - $categoryTable->load($categoryId); - $baselevel = (int) $categoryTable->level; - - $query->where($db->qn('c.lft') . ' >= ' . (int) $categoryTable->lft) - ->where($db->qn('c.rgt') . ' <= ' . (int) $categoryTable->rgt); - } - - // Filter on the level. - if ($level = $this->getState('filter.level')) - { - $query->where($db->qn('a.level') . ' <= ' . ((int) $level + (int) $baselevel - 1)); - } - - // Filter by menu type. - if ($menutype = $this->getState('filter.menutype')) - { - $query->where($fields['menutype'] . ' = ' . $db->quote($menutype)); - } - - // Filter by access level. - if ($access = $this->getState('filter.access')) - { - $query->where($fields['access'] . ' = ' . (int) $access); - } - - // Filter by search in name. - if ($search = $this->getState('filter.search')) - { - if (stripos($search, 'id:') === 0) - { - $query->where($db->qn($fields['id']) . ' = ' . (int) substr($search, 3)); - } - else - { - $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 . ')' - ); - } - } - - // Add the group by clause - $query->group($db->qn($groupby)); - - // Add the list ordering clause - $listOrdering = $this->state->get('list.ordering', 'id'); - $orderDirn = $this->state->get('list.direction', 'ASC'); - - $query->order($db->escape($listOrdering) . ' ' . $db->escape($orderDirn)); - - return $query; - } - - /** - * Delete associations from #__associations table. - * - * @param string $context The associations context. Empty for all. - * @param string $key The associations key. Empty for all. - * - * @return boolean True on success. - * - * @since 3.7.0 - */ - public function purge($context = '', $key = '') - { - $app = JFactory::getApplication(); - $db = $this->getDbo(); - $query = $db->getQuery(true)->delete($db->qn('#__associations')); - - // Filter by associations context. - if ($context) - { - $query->where($db->qn('context') . ' = ' . $db->quote($context)); - } - - // Filter by key. - if ($key) - { - $query->where($db->qn('key') . ' = ' . $db->quote($key)); - } - - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (JDatabaseExceptionExecuting $e) - { - $app->enqueueMessage(JText::_('COM_ASSOCIATIONS_PURGE_FAILED'), 'error'); - - return false; - } - - $app->enqueueMessage( - JText::_((int) $db->getAffectedRows() > 0 ? 'COM_ASSOCIATIONS_PURGE_SUCCESS' : 'COM_ASSOCIATIONS_PURGE_NONE'), - 'message' - ); - - return true; - } - - /** - * Delete orphans from the #__associations table. - * - * @param string $context The associations context. Empty for all. - * @param string $key The associations key. Empty for all. - * - * @return boolean True on success - * - * @since 3.7.0 - */ - public function clean($context = '', $key = '') - { - $app = JFactory::getApplication(); - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select($db->qn('key') . ', COUNT(*)') - ->from($db->qn('#__associations')) - ->group($db->qn('key')) - ->having('COUNT(*) = 1'); - - // Filter by associations context. - if ($context) - { - $query->where($db->qn('context') . ' = ' . $db->quote($context)); - } - - // Filter by key. - if ($key) - { - $query->where($db->qn('key') . ' = ' . $db->quote($key)); - } - - $db->setQuery($query); - - $assocKeys = $db->loadObjectList(); - - $count = 0; - - // We have orphans. Let's delete them. - foreach ($assocKeys as $value) - { - $query->clear() - ->delete($db->qn('#__associations')) - ->where($db->qn('key') . ' = ' . $db->quote($value->key)); - - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (JDatabaseExceptionExecuting $e) - { - $app->enqueueMessage(JText::_('COM_ASSOCIATIONS_DELETE_ORPHANS_FAILED'), 'error'); - - return false; - } - - $count += (int) $db->getAffectedRows(); - } - - $app->enqueueMessage( - JText::_($count > 0 ? 'COM_ASSOCIATIONS_DELETE_ORPHANS_SUCCESS' : 'COM_ASSOCIATIONS_DELETE_ORPHANS_NONE'), - 'message' - ); - - return true; - } -} diff --git a/administrator/components/com_associations/models/fields/itemlanguage.php b/administrator/components/com_associations/models/fields/itemlanguage.php deleted file mode 100644 index 1c8ddf46d52ec..0000000000000 --- a/administrator/components/com_associations/models/fields/itemlanguage.php +++ /dev/null @@ -1,104 +0,0 @@ -input; - - list($extensionName, $typeName) = explode('.', $input->get('itemtype', '', 'string')); - - // Get the extension specific helper method - $helper = AssociationsHelper::getExtensionHelper($extensionName); - - $languageField = $helper->getTypeFieldName($typeName, 'language'); - $referenceId = $input->get('id', 0, 'int'); - $reference = ArrayHelper::fromObject(AssociationsHelper::getItem($extensionName, $typeName, $referenceId)); - $referenceLang = $reference[$languageField]; - - // Get item associations given ID and item type - $associations = AssociationsHelper::getAssociationList($extensionName, $typeName, $referenceId); - - // Check if user can create items in this component item type. - $canCreate = AssociationsHelper::allowAdd($extensionName, $typeName); - - // Gets existing languages. - $existingLanguages = LanguageHelper::getContentLanguages(array(0, 1)); - - $options = array(); - - // Each option has the format "|", example: "en-GB|1" - foreach ($existingLanguages as $langCode => $language) - { - // If language code is equal to reference language we don't need it. - if ($language->lang_code == $referenceLang) - { - continue; - } - - $options[$langCode] = new stdClass; - $options[$langCode]->text = $language->title; - - // If association exists in this language. - if (isset($associations[$language->lang_code])) - { - $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. - $canEdit = AssociationsHelper::allowEdit($extensionName, $typeName, $itemId); - - // Check if item can be checked out - $canCheckout = AssociationsHelper::canCheckinItem($extensionName, $typeName, $itemId); - - // Disable language if user is not allowed to edit the item associated to it. - $options[$langCode]->disable = !($canEdit && $canCheckout); - } - else - { - // New item, id = 0 and disabled if user is not allowed to create new items. - $options[$langCode]->value = $language->lang_code . ':0:add'; - - // Disable language if user is not allowed to create items. - $options[$langCode]->disable = !$canCreate; - } - } - - return array_merge(parent::getOptions(), $options); - } -} diff --git a/administrator/components/com_associations/models/fields/itemtype.php b/administrator/components/com_associations/models/fields/itemtype.php deleted file mode 100644 index f3335c6e6c68d..0000000000000 --- a/administrator/components/com_associations/models/fields/itemtype.php +++ /dev/null @@ -1,62 +0,0 @@ -get('associationssupport') === true) - { - foreach ($extension->get('types') as $type) - { - $context = $extension->get('component') . '.' . $type->get('name'); - $options[$extension->get('title')][] = JHtml::_('select.option', $context, $type->get('title')); - } - } - } - - // Sort by alpha order. - uksort($options, 'strnatcmp'); - - // Add options to parent array. - return array_merge(parent::getGroups(), $options); - } -} diff --git a/administrator/components/com_associations/models/fields/modalassociation.php b/administrator/components/com_associations/models/fields/modalassociation.php deleted file mode 100644 index 85dae7257a4ec..0000000000000 --- a/administrator/components/com_associations/models/fields/modalassociation.php +++ /dev/null @@ -1,105 +0,0 @@ -value > 0 ? (int) $this->value : ''; - - // Build the script. - $script = array(); - - // Select button script - $script[] = 'function jSelectAssociation_' . $this->id . '(id) {'; - $script[] = ' target = document.getElementById("target-association");'; - $script[] = ' document.getElementById("target-association").src = target.getAttribute("data-editurl") + ' - . '"&task=" + target.getAttribute("data-item") + ".edit" + "&id=" + id'; - $script[] = ' jQuery("#associationSelect' . $this->id . 'Modal").modal("hide");'; - $script[] = '}'; - - // Add the script to the document head. - JFactory::getDocument()->addScriptDeclaration(implode("\n", $script)); - - // Setup variables for display. - $html = array(); - - $linkAssociations = 'index.php?option=com_associations&view=associations&layout=modal&tmpl=component' - . '&forcedItemType=' . JFactory::getApplication()->input->get('itemtype', '', 'string') . '&function=jSelectAssociation_' . $this->id; - - $linkAssociations .= "&forcedLanguage=' + document.getElementById('target-association').getAttribute('data-language') + '"; - - $urlSelect = $linkAssociations . '&' . JSession::getFormToken() . '=1'; - - // Select custom association button - $html[] = '' - . '' - . '' - . ''; - - // Clear association button - $html[] = '' - . '' . JText::_('JCLEAR') - . ''; - - $html[] = ''; - - // Select custom association modal - $html[] = JHtml::_( - 'bootstrap.renderModal', - 'associationSelect' . $this->id . 'Modal', - array( - 'title' => JText::_('COM_ASSOCIATIONS_SELECT_TARGET'), - 'backdrop' => 'static', - 'url' => $urlSelect, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '', - ) - ); - - return implode("\n", $html); - } -} diff --git a/administrator/components/com_associations/services/provider.php b/administrator/components/com_associations/services/provider.php new file mode 100644 index 0000000000000..ffeb36bbacd8c --- /dev/null +++ b/administrator/components/com_associations/services/provider.php @@ -0,0 +1,54 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Associations')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Associations')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_associations/tmpl/association/edit.php b/administrator/components/com_associations/tmpl/association/edit.php new file mode 100644 index 0000000000000..8efb4c7387170 --- /dev/null +++ b/administrator/components/com_associations/tmpl/association/edit.php @@ -0,0 +1,74 @@ + $this->app->input->get('layout', '', 'string'), + 'itemtype' => $this->itemtype, + 'id' => $this->referenceId, + ); +?> + + + +
+
+
+

+ +
+
+
+
+
+

+ form->getInput('modalassociation'); ?> + form->getInput('itemlanguage'); ?> +
+ +
+
+ +
+ + + + + diff --git a/administrator/components/com_associations/tmpl/associations/default.php b/administrator/components/com_associations/tmpl/associations/default.php new file mode 100644 index 0000000000000..4b361bfe57899 --- /dev/null +++ b/administrator/components/com_associations/tmpl/associations/default.php @@ -0,0 +1,153 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canManageCheckin = Factory::getUser()->authorise('core.manage', 'com_checkin'); + +$iconStates = array( + -2 => 'icon-trash', + 0 => 'icon-unpublish', + 1 => 'icon-publish', + 2 => 'icon-archive', +); + +Text::script('COM_ASSOCIATIONS_PURGE_CONFIRM_PROMPT', true); +HTMLHelper::_('script', 'com_associations/admin-associations-default.min.js', false, true); +?> +
+
+
+
+ $this)); ?> + items)) : ?> + + + + + + typeSupports['state'])) : ?> + + + + + + + typeFields['menutype'])) : ?> + + + typeFields['access'])) : ?> + + + + + + + items as $i => $item) : + $canCheckin = true; + $canEdit = AssociationsHelper::allowEdit($this->extensionName, $this->typeName, $item->id); + $canCheckin = $canManageCheckin || AssociationsHelper::canCheckinItem($this->extensionName, $this->typeName, $item->id); + $isCheckout = AssociationsHelper::isCheckoutItem($this->extensionName, $this->typeName, $item->id); + ?> + + typeSupports['state'])) : ?> + + + + + + + typeFields['menutype'])) : ?> + + + typeFields['access'])) : ?> + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + level)) : ?> + $item->level)); ?> + + + editor, $item->checked_out_time, 'associations.', $canCheckin); ?> + + + '; ?> + + escape($item->title); ?> + + escape($item->title); ?> + + typeFields['alias'])) : ?> + + escape($item->alias)); ?> + + + typeFields['catid'])) : ?> +
+ escape($item->category_title); ?> +
+ +
+ + + extensionName, $this->typeName, (int) $item->id, $item->language, !$isCheckout, false); ?> + + extensionName, $this->typeName, (int) $item->id, $item->language, !$isCheckout, true); ?> + + escape($item->menutype_title); ?> + + escape($item->access_level); ?> + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + + +
+
+
+
diff --git a/administrator/components/com_associations/views/associations/tmpl/default.xml b/administrator/components/com_associations/tmpl/associations/default.xml similarity index 100% rename from administrator/components/com_associations/views/associations/tmpl/default.xml rename to administrator/components/com_associations/tmpl/associations/default.xml diff --git a/administrator/components/com_associations/tmpl/associations/modal.php b/administrator/components/com_associations/tmpl/associations/modal.php new file mode 100644 index 0000000000000..585e68c168a58 --- /dev/null +++ b/administrator/components/com_associations/tmpl/associations/modal.php @@ -0,0 +1,165 @@ +isClient('site')) +{ + Session::checkToken('get') or die(Text::_('JINVALID_TOKEN')); +} + +HTMLHelper::_('behavior.multiselect'); + +$function = $app->input->getCmd('function', 'jSelectAssociation'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$canManageCheckin = Factory::getUser()->authorise('core.manage', 'com_checkin'); + +$iconStates = array( + -2 => 'icon-trash', + 0 => 'icon-unpublish', + 1 => 'icon-publish', + 2 => 'icon-archive', +); + +Factory::getDocument()->addScriptOptions('assosiations-modal', ['func' => $function]); +HTMLHelper::_('script', 'com_associations/admin-associations-modal.min.js', false, true); +?> +
+ +sidebar)) : ?> +
+ sidebar; ?> +
+
+ +
+ + $this)); ?> + items)) : ?> + + + + + + typeSupports['state'])) : ?> + + + + + + typeFields['menutype'])) : ?> + + + typeSupports['acl'])) : ?> + + + + + + + items as $i => $item) : + $canEdit = AssociationsHelper::allowEdit($this->extensionName, $this->typeName, $item->id); + $canCheckin = $canManageCheckin || AssociationsHelper::canCheckinItem($this->extensionName, $this->typeName, $item->id); + $isCheckout = AssociationsHelper::isCheckoutItem($this->extensionName, $this->typeName, $item->id); + ?> + + typeSupports['state'])) : ?> + + + + + + typeFields['menutype'])) : ?> + + + typeSupports['acl'])) : ?> + + + + + + +
+ + + + + + + + + + + + + +
+ + + level)) : ?> + $item->level)); ?> + + + + escape($item->title); ?> + + editor, $item->checked_out_time, 'associations.'); ?> + + escape($item->title); ?> + + + escape($item->title); ?> + + typeFields['alias'])) : ?> + + escape($item->alias)); ?> + + + typeFields['catid'])) : ?> +
+ escape($item->category_title); ?> +
+ +
+ + + association) : ?> + extensionName, $this->typeName, (int) $item->id, $item->language, false, false); ?> + + + escape($item->menutype_title); ?> + + escape($item->access_level); ?> + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + + + +
+ diff --git a/administrator/components/com_associations/views/association/tmpl/edit.php b/administrator/components/com_associations/views/association/tmpl/edit.php deleted file mode 100644 index 408033369d06c..0000000000000 --- a/administrator/components/com_associations/views/association/tmpl/edit.php +++ /dev/null @@ -1,70 +0,0 @@ - $this->app->input->get('layout', '', 'string'), - 'itemtype' => $this->itemtype, - 'id' => $this->referenceId, - ); -?> - - -
-
-
-
-

- -
-
-
-
-
-

- 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 deleted file mode 100644 index b82f2634f1c13..0000000000000 --- a/administrator/components/com_associations/views/association/view.html.php +++ /dev/null @@ -1,220 +0,0 @@ -get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->app = JFactory::getApplication(); - $this->form = $this->get('Form'); - $input = $this->app->input; - $this->referenceId = $input->get('id', 0, 'int'); - - list($extensionName, $typeName) = explode('.', $input->get('itemtype', '', 'string')); - - $extension = AssociationsHelper::getSupportedExtension($extensionName); - $types = $extension->get('types'); - - if (array_key_exists($typeName, $types)) - { - $this->type = $types[$typeName]; - $this->typeSupports = array(); - $details = $this->type->get('details'); - $this->save2copy = false; - - if (array_key_exists('support', $details)) - { - $support = $details['support']; - $this->typeSupports = $support; - } - - if (!empty($this->typeSupports['save2copy'])) - { - $this->save2copy = true; - } - } - - $this->extensionName = $extensionName; - $this->typeName = $typeName; - $this->itemtype = $extensionName . '.' . $typeName; - - $languageField = AssociationsHelper::getTypeFieldName($extensionName, $typeName, 'language'); - $referenceId = $input->get('id', 0, 'int'); - $reference = ArrayHelper::fromObject(AssociationsHelper::getItem($extensionName, $typeName, $referenceId)); - - $this->referenceLanguage = $reference[$languageField]; - - $options = array( - 'option' => $typeName === 'category' ? 'com_categories' : $extensionName, - 'view' => $typeName, - 'extension' => $extensionName, - 'tmpl' => 'component', - ); - - // Reference and target edit links. - $this->editUri = 'index.php?' . http_build_query($options); - - // Get target language. - $this->targetId = '0'; - $this->targetLanguage = ''; - $this->defaultTargetSrc = ''; - $this->targetAction = ''; - - if ($target = $input->get('target', '', 'string')) - { - $matches = preg_split("#[\:]+#", $target); - $this->targetAction = $matches[2]; - $this->targetId = $matches[1]; - $this->targetLanguage = $matches[0]; - $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(); - } - 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 a 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'); - } - } - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 3.7.0 - */ - protected function addToolbar() - { - // Hide main menu. - JFactory::getApplication()->input->set('hidemainmenu', 1); - - $helper = AssociationsHelper::getExtensionHelper($this->extensionName); - $title = $helper->getTypeTitle($this->typeName); - - $languageKey = strtoupper($this->extensionName . '_' . $title . 'S'); - - if ($this->typeName === 'category') - { - $languageKey = strtoupper($this->extensionName) . '_CATEGORIES'; - } - - JToolbarHelper::title(JText::sprintf('COM_ASSOCIATIONS_TITLE_EDIT', JText::_($this->extensionName), JText::_($languageKey)), 'contract assoc'); - - $bar = JToolbar::getInstance('toolbar'); - - $bar->appendButton( - 'Custom', '', 'reference' - ); - - $bar->appendButton( - 'Custom', '', 'target' - ); - - if ($this->typeName === 'category' || $this->extensionName === 'com_menus' || $this->save2copy === true) - { - JToolBarHelper::custom('copy', 'copy.png', '', 'COM_ASSOCIATIONS_COPY_REFERENCE', false); - } - - JToolbarHelper::cancel('association.cancel', 'JTOOLBAR_CLOSE'); - JToolbarHelper::help('JHELP_COMPONENTS_ASSOCIATIONS_EDIT'); - - JHtmlSidebar::setAction('index.php?option=com_associations'); - } -} diff --git a/administrator/components/com_associations/views/associations/tmpl/default.php b/administrator/components/com_associations/views/associations/tmpl/default.php deleted file mode 100644 index c33f6cf041dc9..0000000000000 --- a/administrator/components/com_associations/views/associations/tmpl/default.php +++ /dev/null @@ -1,182 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$canManageCheckin = JFactory::getUser()->authorise('core.manage', 'com_checkin'); -$colSpan = 5; - -$iconStates = array( - -2 => 'icon-trash', - 0 => 'icon-unpublish', - 1 => 'icon-publish', - 2 => 'icon-archive', -); - -JText::script('COM_ASSOCIATIONS_PURGE_CONFIRM_PROMPT'); - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(pressbutton) - { - if (pressbutton == "associations.purge") - { - if (confirm(Joomla.JText._("COM_ASSOCIATIONS_PURGE_CONFIRM_PROMPT"))) - { - Joomla.submitform(pressbutton); - } - else - { - return false; - } - } - else - { - Joomla.submitform(pressbutton); - } - }; -'); -?> -
-sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> - items)) : ?> -
- -
- - - - - typeSupports['state'])) : ?> - - - - - - - typeFields['menutype'])) : ?> - - - typeFields['access'])) : ?> - - - - - - - - - - - - items as $i => $item) : - $canEdit = AssociationsHelper::allowEdit($this->extensionName, $this->typeName, $item->id); - $canCheckin = $canManageCheckin || AssociationsHelper::canCheckinItem($this->extensionName, $this->typeName, $item->id); - $isCheckout = AssociationsHelper::isCheckoutItem($this->extensionName, $this->typeName, $item->id); - ?> - - typeSupports['state'])) : ?> - - - - - - - typeFields['menutype'])) : ?> - - - typeFields['access'])) : ?> - - - - - - -
- - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - 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); ?> -
- -
- - - extensionName, $this->typeName, (int) $item->id, $item->language, !$isCheckout, false); ?> - - extensionName, $this->typeName, (int) $item->id, $item->language, !$isCheckout, true); ?> - - escape($item->menutype_title); ?> - - escape($item->access_level); ?> - - id; ?> -
- - - - -
- diff --git a/administrator/components/com_associations/views/associations/tmpl/modal.php b/administrator/components/com_associations/views/associations/tmpl/modal.php deleted file mode 100644 index 6d21097cac952..0000000000000 --- a/administrator/components/com_associations/views/associations/tmpl/modal.php +++ /dev/null @@ -1,176 +0,0 @@ -isClient('site')) -{ - JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); -} - -JHtml::_('jquery.framework'); -JHtml::_('bootstrap.tooltip', '.hasTooltip', array('placement' => 'bottom')); -JHtml::_('behavior.multiselect'); -JHtml::_('formbehavior.chosen', 'select'); - -$function = $app->input->getCmd('function', 'jSelectAssociation'); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$canManageCheckin = JFactory::getUser()->authorise('core.manage', 'com_checkin'); -$colSpan = 4; - -$iconStates = array( - -2 => 'icon-trash', - 0 => 'icon-unpublish', - 1 => 'icon-publish', - 2 => 'icon-archive', -); - -$app->getDocument()->addScriptDeclaration( - "jQuery(document).ready(function($) { - // Run function on parent window. - $('.select-link').on('click', function() { - if (self != top) - { - window.parent." . $function . "(this.getAttribute('data-id')); - } - }); - });" -); -?> -
- -sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> - items)) : ?> -
- -
- - - - - typeSupports['state'])) : ?> - - - - - - typeFields['menutype'])) : ?> - - - typeSupports['acl'])) : ?> - - - - - - - - - - - - items as $i => $item) : - $canEdit = AssociationsHelper::allowEdit($this->extensionName, $this->typeName, $item->id); - $canCheckin = $canManageCheckin || AssociationsHelper::canCheckinItem($this->extensionName, $this->typeName, $item->id); - $isCheckout = AssociationsHelper::isCheckoutItem($this->extensionName, $this->typeName, $item->id); - ?> - - typeSupports['state'])) : ?> - - - - - - typeFields['menutype'])) : ?> - - - typeSupports['acl'])) : ?> - - - - - - -
- - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - level)) : ?> - $item->level)); ?> - - - - escape($item->title); ?> - - editor, $item->checked_out_time, 'associations.'); ?> - - escape($item->title); ?> - - - escape($item->title); ?> - - typeFields['alias'])) : ?> - - escape($item->alias)); ?> - - - typeFields['catid'])) : ?> -
- escape($item->category_title); ?> -
- -
- - - association) : ?> - extensionName, $this->typeName, (int) $item->id, $item->language, false, false); ?> - - - escape($item->menutype_title); ?> - - escape($item->access_level); ?> - - id; ?> -
- - - - - - - -
- diff --git a/administrator/components/com_associations/views/associations/view.html.php b/administrator/components/com_associations/views/associations/view.html.php deleted file mode 100644 index 92e5d7b916a4c..0000000000000 --- a/administrator/components/com_associations/views/associations/view.html.php +++ /dev/null @@ -1,235 +0,0 @@ -state = $this->get('State'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - if (!JLanguageAssociations::isEnabled()) - { - $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . AssociationsHelper::getLanguagefilterPluginId()); - JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_ASSOCIATIONS_ERROR_NO_ASSOC', $link), 'warning'); - } - elseif ($this->state->get('itemtype') == '' || $this->state->get('language') == '') - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_ASSOCIATIONS_NOTICE_NO_SELECTORS'), 'notice'); - } - else - { - $type = null; - - list($extensionName, $typeName) = explode('.', $this->state->get('itemtype')); - - $extension = AssociationsHelper::getSupportedExtension($extensionName); - - $types = $extension->get('types'); - - if (array_key_exists($typeName, $types)) - { - $type = $types[$typeName]; - } - - $this->itemType = $type; - - if (is_null($type)) - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_ASSOCIATIONS_ERROR_NO_TYPE'), 'warning'); - } - else - { - $this->extensionName = $extensionName; - $this->typeName = $typeName; - $this->typeSupports = array(); - $this->typeFields = array(); - - $details = $type->get('details'); - - if (array_key_exists('support', $details)) - { - $support = $details['support']; - $this->typeSupports = $support; - } - - if (array_key_exists('fields', $details)) - { - $fields = $details['fields']; - $this->typeFields = $fields; - } - - // Dynamic filter form. - // This selectors doesn't have to activate the filter bar. - unset($this->activeFilters['itemtype']); - unset($this->activeFilters['language']); - - // Remove filters options depending on selected type. - if (empty($support['state'])) - { - 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']); - $this->filterForm->removeField('access', 'filter'); - } - - // Add extension attribute to category filter. - if (empty($support['catid'])) - { - $this->filterForm->setFieldAttribute('category_id', 'extension', $extensionName, 'filter'); - } - - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - - $linkParameters = array( - 'layout' => 'edit', - 'itemtype' => $extensionName . '.' . $typeName, - 'task' => 'association.edit', - ); - - $this->editUri = 'index.php?option=com_associations&view=association&' . http_build_query($linkParameters); - } - } - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->addToolbar(); - - // Will add sidebar if needed $this->sidebar = JHtmlSidebar::render(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 3.7.0 - */ - protected function addToolbar() - { - $user = JFactory::getUser(); - - if (isset($this->typeName) && isset($this->extensionName)) - { - $helper = AssociationsHelper::getExtensionHelper($this->extensionName); - $title = $helper->getTypeTitle($this->typeName); - - $languageKey = strtoupper($this->extensionName . '_' . $title . 'S'); - - if ($this->typeName === 'category') - { - $languageKey = strtoupper($this->extensionName) . '_CATEGORIES'; - } - - JToolbarHelper::title( - JText::sprintf( - 'COM_ASSOCIATIONS_TITLE_LIST', JText::_($this->extensionName), JText::_($languageKey) - ), 'contract assoc' - ); - } - else - { - JToolbarHelper::title(JText::_('COM_ASSOCIATIONS_TITLE_LIST_SELECT'), 'contract assoc'); - } - - if ($user->authorise('core.admin', 'com_associations') || $user->authorise('core.options', 'com_associations')) - { - if (!isset($this->typeName)) - { - 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'); - } - - JToolbarHelper::help('JHELP_COMPONENTS_ASSOCIATIONS'); - } -} diff --git a/administrator/components/com_banners/Controller/BannerController.php b/administrator/components/com_banners/Controller/BannerController.php new file mode 100644 index 0000000000000..9a22342404de5 --- /dev/null +++ b/administrator/components/com_banners/Controller/BannerController.php @@ -0,0 +1,116 @@ +input->getInt('filter_category_id'); + $categoryId = ArrayHelper::getValue($data, 'catid', $filter, 'int'); + $allow = null; + + if ($categoryId) + { + // If the category has been passed in the URL check it. + $allow = $this->app->getIdentity()->authorise('core.create', $this->option . '.category.' . $categoryId); + } + + if ($allow !== null) + { + return $allow; + } + + // In the absence of better information, revert to the component permissions. + return parent::allowAdd($data); + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $categoryId = 0; + + if ($recordId) + { + $categoryId = (int) $this->getModel()->getItem($recordId)->catid; + } + + if ($categoryId) + { + // The category has been set. Check the category permissions. + return $this->app->getIdentity()->authorise('core.edit', $this->option . '.category.' . $categoryId); + } + + // Since there is no asset tracking, revert to the component permissions. + return parent::allowEdit($data, $key); + } + + /** + * Method to run batch operations. + * + * @param string $model The model + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function batch($model = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Banner', '', array()); + + // Preset the redirect + $this->setRedirect(Route::_('index.php?option=com_banners&view=banners' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } +} diff --git a/administrator/components/com_banners/Controller/BannersController.php b/administrator/components/com_banners/Controller/BannersController.php new file mode 100644 index 0000000000000..71aa9458f7e1c --- /dev/null +++ b/administrator/components/com_banners/Controller/BannersController.php @@ -0,0 +1,118 @@ +registerTask('sticky_unpublish', 'sticky_publish'); + } + + /** + * 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 \Joomla\CMS\MVC\Model\BaseDatabaseModel The model. + * + * @since 1.6 + */ + public function getModel($name = 'Banner', $prefix = 'Administrator', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Stick items + * + * @return void + * + * @since 1.6 + */ + public function sticky_publish() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + $values = array('sticky_publish' => 1, 'sticky_unpublish' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($values, $task, 0, 'int'); + + if (empty($ids)) + { + $this->app->enqueueMessage(Text::_('COM_BANNERS_NO_BANNERS_SELECTED'), 'warning'); + } + else + { + // Get the model. + /** @var \Joomla\Component\Banners\Administrator\Model\BannerModel $model */ + $model = $this->getModel(); + + // Change the state of the records. + if (!$model->stick($ids, $value)) + { + $this->app->enqueueMessage($model->getError(), 'warning'); + } + else + { + if ($value == 1) + { + $ntext = 'COM_BANNERS_N_BANNERS_STUCK'; + } + else + { + $ntext = 'COM_BANNERS_N_BANNERS_UNSTUCK'; + } + + $this->setMessage(Text::plural($ntext, count($ids))); + } + } + + $this->setRedirect('index.php?option=com_banners&view=banners'); + } +} diff --git a/administrator/components/com_banners/Controller/ClientController.php b/administrator/components/com_banners/Controller/ClientController.php new file mode 100644 index 0000000000000..214e211c0a990 --- /dev/null +++ b/administrator/components/com_banners/Controller/ClientController.php @@ -0,0 +1,30 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_banners/Controller/DisplayController.php b/administrator/components/com_banners/Controller/DisplayController.php new file mode 100644 index 0000000000000..c1e648acbc158 --- /dev/null +++ b/administrator/components/com_banners/Controller/DisplayController.php @@ -0,0 +1,72 @@ +input->get('view', 'banners'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($view == 'banner' && $layout == 'edit' && !$this->checkEditId('com_banners.edit.banner', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_banners&view=banners', false)); + + return false; + } + elseif ($view == 'client' && $layout == 'edit' && !$this->checkEditId('com_banners.edit.client', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_banners&view=clients', false)); + + return false; + } + + return parent::display(); + } +} diff --git a/administrator/components/com_banners/Controller/TracksController.php b/administrator/components/com_banners/Controller/TracksController.php new file mode 100644 index 0000000000000..60b665f9884c4 --- /dev/null +++ b/administrator/components/com_banners/Controller/TracksController.php @@ -0,0 +1,171 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to remove a record. + * + * @return void + * + * @since 1.6 + */ + public function delete() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Get the model. + /** @var \Joomla\Component\Banners\Administrator\Model\TracksModel $model */ + $model = $this->getModel(); + + // Load the filter state. + $model->setState('filter.type', $this->app->getUserState($this->context . '.filter.type')); + $model->setState('filter.begin', $this->app->getUserState($this->context . '.filter.begin')); + $model->setState('filter.end', $this->app->getUserState($this->context . '.filter.end')); + $model->setState('filter.category_id', $this->app->getUserState($this->context . '.filter.category_id')); + $model->setState('filter.client_id', $this->app->getUserState($this->context . '.filter.client_id')); + $model->setState('list.limit', 0); + $model->setState('list.start', 0); + + $count = $model->getTotal(); + + // Remove the items. + if (!$model->delete()) + { + $this->app->enqueueMessage($model->getError(), 'warning'); + } + elseif ($count > 0) + { + $this->setMessage(Text::plural('COM_BANNERS_TRACKS_N_ITEMS_DELETED', $count)); + } + else + { + $this->setMessage(Text::_('COM_BANNERS_TRACKS_NO_ITEMS_DELETED')); + } + + $this->setRedirect('index.php?option=com_banners&view=tracks'); + } + + /** + * Display method for the raw track data. + * + * @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 static This object to support chaining. + * + * @since 1.5 + * @todo This should be done as a view, not here! + */ + public function display($cachable = false, $urlparams = array()) + { + // Get the document object. + $vName = 'tracks'; + + // Get and render the view. + if ($view = $this->getView($vName, 'raw')) + { + // Get the model for the view. + /** @var \Joomla\Component\Banners\Administrator\Model\TracksModel $model */ + $model = $this->getModel($vName); + + // Load the filter state. + $app = Factory::getApplication(); + + $model->setState('filter.type', $app->getUserState($this->context . '.filter.type')); + $model->setState('filter.begin', $app->getUserState($this->context . '.filter.begin')); + $model->setState('filter.end', $app->getUserState($this->context . '.filter.end')); + $model->setState('filter.category_id', $app->getUserState($this->context . '.filter.category_id')); + $model->setState('filter.client_id', $app->getUserState($this->context . '.filter.client_id')); + $model->setState('list.limit', 0); + $model->setState('list.start', 0); + + $form = $this->input->get('jform', array(), 'array'); + + $model->setState('basename', $form['basename']); + $model->setState('compressed', $form['compressed']); + + // Create one year cookies. + $cookieLifeTime = time() + 365 * 86400; + $cookieDomain = $app->get('cookie_domain', ''); + $cookiePath = $app->get('cookie_path', '/'); + $isHttpsForced = $app->isHttpsForced(); + + $app->input->cookie->set( + ApplicationHelper::getHash($this->context . '.basename'), + $form['basename'], + $cookieLifeTime, + $cookiePath, + $cookieDomain, + $isHttpsForced, + true + ); + + $app->input->cookie->set( + ApplicationHelper::getHash($this->context . '.compressed'), + $form['compressed'], + $cookieLifeTime, + $cookiePath, + $cookieDomain, + $isHttpsForced, + true + ); + + // Push the model into the view (as default). + $view->setModel($model, true); + + // Push document object into the view. + $view->document = Factory::getDocument(); + + $view->display(); + } + + return $this; + } +} diff --git a/administrator/components/com_banners/Extension/BannersComponent.php b/administrator/components/com_banners/Extension/BannersComponent.php new file mode 100644 index 0000000000000..cbdbf53e49fb8 --- /dev/null +++ b/administrator/components/com_banners/Extension/BannersComponent.php @@ -0,0 +1,77 @@ +getRegistry()->register('banner', new Banner); + } + + /** + * Returns the table for the count items functions for the given section. + * + * @param string $section The section + * + * @return string|null + * + * @since 4.0.0 + */ + protected function getTableNameForSection(string $section = null) + { + return '#__banners'; + } + + /** + * Returns the state column for the count items functions for the given section. + * + * @param string $section The section + * + * @return string|null + * + * @since 4.0.0 + */ + protected function getStateColumnForSection(string $section = null) + { + return 'published as state'; + } +} diff --git a/administrator/components/com_banners/Field/BannerclientField.php b/administrator/components/com_banners/Field/BannerclientField.php new file mode 100644 index 0000000000000..83ecb99cd5c54 --- /dev/null +++ b/administrator/components/com_banners/Field/BannerclientField.php @@ -0,0 +1,46 @@ +id . '\').value=\'0\';"'; + + return ''; + } +} diff --git a/administrator/components/com_banners/Field/ImpmadeField.php b/administrator/components/com_banners/Field/ImpmadeField.php new file mode 100644 index 0000000000000..e8bcd3fcf4314 --- /dev/null +++ b/administrator/components/com_banners/Field/ImpmadeField.php @@ -0,0 +1,48 @@ +id . '\').value=\'0\';"'; + + return ''; + } +} diff --git a/administrator/components/com_banners/Field/ImptotalField.php b/administrator/components/com_banners/Field/ImptotalField.php new file mode 100644 index 0000000000000..3f58f7101c215 --- /dev/null +++ b/administrator/components/com_banners/Field/ImptotalField.php @@ -0,0 +1,54 @@ +id . '_unlimited\').checked=document.getElementById(\'' . $this->id + . '\').value==\'\';"'; + $onclick = ' onclick="if (document.getElementById(\'' . $this->id . '_unlimited\').checked) document.getElementById(\'' . $this->id + . '\').value=\'\';"'; + $value = empty($this->value) ? '' : $this->value; + $checked = empty($this->value) ? ' checked="checked"' : ''; + + return '' + . '
' + . '
'; + } +} diff --git a/administrator/components/com_banners/Helper/BannersHelper.php b/administrator/components/com_banners/Helper/BannersHelper.php new file mode 100644 index 0000000000000..540865d6de84c --- /dev/null +++ b/administrator/components/com_banners/Helper/BannersHelper.php @@ -0,0 +1,194 @@ +getNullDate(); + $query = $db->getQuery(true) + ->select('*') + ->from('#__banners') + ->where($db->quote(Factory::getDate()) . ' >= ' . $db->quote('reset')) + ->where($db->quoteName('reset') . ' != ' . $db->quote($nullDate) . ' AND ' . $db->quoteName('reset') . '!= NULL') + ->where( + '(' . $db->quoteName('checked_out') . ' = 0 OR ' . $db->quoteName('checked_out') . ' = ' + . (int) $db->quote(Factory::getUser()->id) . ')' + ); + $db->setQuery($query); + + try + { + $rows = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + foreach ($rows as $row) + { + $purchaseType = $row->purchase_type; + + if ($purchaseType < 0 && $row->cid) + { + /** @var \Joomla\Component\Banners\Administrator\Table\Client $client */ + $client = Table::getInstance('Client', '\\Joomla\\Component\\Banners\\Administrator\\Table\\'); + $client->load($row->cid); + $purchaseType = $client->purchase_type; + } + + if ($purchaseType < 0) + { + $params = ComponentHelper::getParams('com_banners'); + $purchaseType = $params->get('purchase_type'); + } + + switch ($purchaseType) + { + case 1: + $reset = $nullDate; + break; + case 2: + $date = Factory::getDate('+1 year ' . date('Y-m-d')); + $reset = $db->quote($date->toSql()); + break; + case 3: + $date = Factory::getDate('+1 month ' . date('Y-m-d')); + $reset = $db->quote($date->toSql()); + break; + case 4: + $date = Factory::getDate('+7 day ' . date('Y-m-d')); + $reset = $db->quote($date->toSql()); + break; + case 5: + $date = Factory::getDate('+1 day ' . date('Y-m-d')); + $reset = $db->quote($date->toSql()); + break; + } + + // Update the row ordering field. + $query->clear() + ->update($db->quoteName('#__banners')) + ->set($db->quoteName('reset') . ' = ' . $db->quote($reset)) + ->set($db->quoteName('impmade') . ' = ' . $db->quote(0)) + ->set($db->quoteName('clicks') . ' = ' . $db->quote(0)) + ->where($db->quoteName('id') . ' = ' . $db->quote($row->id)); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + } + + return true; + } + + /** + * Get client list in text/value format for a select field + * + * @return array + */ + public static function getClientOptions() + { + $options = array(); + + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('id AS value, name AS text') + ->from('#__banner_clients AS a') + ->where('a.state = 1') + ->order('a.name'); + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + array_unshift($options, HTMLHelper::_('select.option', '0', Text::_('COM_BANNERS_NO_CLIENT'))); + + return $options; + } +} diff --git a/administrator/components/com_banners/Model/BannerModel.php b/administrator/components/com_banners/Model/BannerModel.php new file mode 100644 index 0000000000000..5725a06cf1f3f --- /dev/null +++ b/administrator/components/com_banners/Model/BannerModel.php @@ -0,0 +1,564 @@ + 'batchClient', + 'language_id' => 'batchLanguage' + ); + + /** + * Batch client changes for a group of banners. + * + * @param string $value The new value matching a client. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 2.5 + */ + protected function batchClient($value, $pks, $contexts) + { + // Set the variables + $user = Factory::getUser(); + + /** @var \Joomla\Component\Banners\Administrator\Table\Banner $table */ + $table = $this->getTable(); + + foreach ($pks as $pk) + { + if (!$user->authorise('core.edit', $contexts[$pk])) + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + + $table->reset(); + $table->load($pk); + $table->cid = (int) $value; + + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * 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 2.5 + */ + protected function batchCopy($value, $pks, $contexts) + { + $categoryId = (int) $value; + + /** @var \Joomla\Component\Banners\Administrator\Table\Banner $table */ + $table = $this->getTable(); + $newIds = array(); + + // Check that the category exists + if ($categoryId) + { + $categoryTable = Table::getInstance('Category'); + + if (!$categoryTable->load($categoryId)) + { + if ($error = $categoryTable->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + + $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + + return false; + } + } + + if (empty($categoryId)) + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); + + return false; + } + + // Check that the user has create permission for the component + if (!Factory::getUser()->authorise('core.create', 'com_banners.category.' . $categoryId)) + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + + return false; + } + + // 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(Text::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; + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canDelete($record) + { + if (!empty($record->id)) + { + if ($record->state != -2) + { + return false; + } + + if (!empty($record->catid)) + { + return Factory::getUser()->authorise('core.delete', 'com_banners.category.' . (int) $record->catid); + } + + return parent::canDelete($record); + } + } + + /** + * 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 1.6 + */ + protected function canEditState($record) + { + // Check against the category. + if (!empty($record->catid)) + { + return Factory::getUser()->authorise('core.edit.state', 'com_banners.category.' . (int) $record->catid); + } + + // Default to component settings if category not known. + return parent::canEditState($record); + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. [optional] + * @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional] + * + * @return \JForm|boolean A \JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_banners.banner', 'banner', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Determine correct permissions to check. + if ($this->getState('banner.id')) + { + // Existing record. Can only edit in selected categories. + $form->setFieldAttribute('catid', 'action', 'core.edit'); + } + else + { + // New record. Can only create in selected categories. + $form->setFieldAttribute('catid', 'action', 'core.create'); + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('publish_up', 'disabled', 'true'); + $form->setFieldAttribute('publish_down', 'disabled', 'true'); + $form->setFieldAttribute('state', 'disabled', 'true'); + $form->setFieldAttribute('sticky', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('publish_up', 'filter', 'unset'); + $form->setFieldAttribute('publish_down', 'filter', 'unset'); + $form->setFieldAttribute('state', 'filter', 'unset'); + $form->setFieldAttribute('sticky', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $app = Factory::getApplication(); + $data = $app->getUserState('com_banners.edit.banner.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + + // Prime some default values. + if ($this->getState('banner.id') == 0) + { + $filters = (array) $app->getUserState('com_banners.banners.filter'); + $filterCatId = $filters['category_id'] ?? null; + + $data->set('catid', $app->input->getInt('catid', $filterCatId)); + } + } + + $this->preprocessData('com_banners.banner', $data); + + return $data; + } + + /** + * Method to stick records. + * + * @param array &$pks The ids of the items to publish. + * @param integer $value The value of the published state + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function stick(&$pks, $value = 1) + { + /** @var \Joomla\Component\Banners\Administrator\Table\Banner $table */ + $table = $this->getTable(); + $pks = (array) $pks; + + // Access checks. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if (!$this->canEditState($table)) + { + // Prune items that you can't change. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'error'); + } + } + } + + // Attempt to change the state of the records. + if (!$table->stick($pks, $value, Factory::getUser()->id)) + { + $this->setError($table->getError()); + + return false; + } + + return true; + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param Table $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 + */ + protected function getReorderConditions($table) + { + return array( + 'catid = ' . (int) $table->catid, + 'state >= 0' + ); + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @param Table $table A Table object. + * + * @return void + * + * @since 1.6 + */ + protected function prepareTable($table) + { + $date = Factory::getDate(); + $user = Factory::getUser(); + + if (empty($table->id)) + { + // Set the values + $table->created = $date->toSql(); + $table->created_by = $user->id; + + // Set ordering to the last item if not set + if (empty($table->ordering)) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('MAX(ordering)') + ->from('#__banners'); + + $db->setQuery($query); + $max = $db->loadResult(); + + $table->ordering = $max + 1; + } + } + else + { + // Set the values + $table->modified = $date->toSql(); + $table->modified_by = $user->id; + } + + // Increment the content version number. + $table->version++; + } + + /** + * Allows preprocessing of the \JForm object. + * + * @param \JForm $form The form object + * @param array $data The data to be merged into the form object + * @param string $group The plugin group to be executed + * + * @return void + * + * @since 3.6.1 + */ + protected function preprocessForm(\JForm $form, $data, $group = 'content') + { + if ($this->canCreateCategory()) + { + $form->setFieldAttribute('catid', 'allowAdd', 'true'); + } + + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $input = Factory::getApplication()->input; + + \JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); + + // Cast catid to integer for comparison + $catid = (int) $data['catid']; + + // Check if New Category exists + if ($catid > 0) + { + $catid = \CategoriesHelper::validateCategoryId($data['catid'], 'com_banners'); + } + + // Save New Category + if ($catid == 0 && $this->canCreateCategory()) + { + $table = array(); + $table['title'] = $data['catid']; + $table['parent_id'] = 1; + $table['extension'] = 'com_banners'; + $table['language'] = $data['language']; + $table['published'] = 1; + + // Create new category and get catid back + $data['catid'] = \CategoriesHelper::createCategory($table); + } + + // Alter the name for save as copy + if ($input->get('task') == 'save2copy') + { + /** @var \Joomla\Component\Banners\Administrator\Table\Banner $origTable */ + $origTable = clone $this->getTable(); + $origTable->load($input->getInt('id')); + + if ($data['name'] == $origTable->name) + { + list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']); + $data['name'] = $name; + $data['alias'] = $alias; + } + else + { + if ($data['alias'] == $origTable->alias) + { + $data['alias'] = ''; + } + } + + $data['state'] = 0; + } + + return parent::save($data); + } + + /** + * Is the user allowed to create an on the fly category? + * + * @return boolean + * + * @since 3.6.1 + */ + private function canCreateCategory() + { + return Factory::getUser()->authorise('core.create', 'com_banners'); + } +} diff --git a/administrator/components/com_banners/Model/BannersModel.php b/administrator/components/com_banners/Model/BannersModel.php new file mode 100644 index 0000000000000..e9f204dfc371b --- /dev/null +++ b/administrator/components/com_banners/Model/BannersModel.php @@ -0,0 +1,280 @@ +cache['categoryorders'])) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('MAX(ordering) as ' . $db->quoteName('max') . ', catid') + ->select('catid') + ->from('#__banners') + ->group('catid'); + $db->setQuery($query); + $this->cache['categoryorders'] = $db->loadAssocList('catid', 0); + } + + return $this->cache['categoryorders']; + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.id AS id,' + . 'a.name AS name,' + . 'a.alias AS alias,' + . 'a.checked_out AS checked_out,' + . 'a.checked_out_time AS checked_out_time,' + . 'a.catid AS catid,' + . 'a.clicks AS clicks,' + . 'a.metakey AS metakey,' + . 'a.sticky AS sticky,' + . 'a.impmade AS impmade,' + . 'a.imptotal AS imptotal,' + . 'a.state AS state,' + . 'a.ordering AS ordering,' + . 'a.purchase_type AS purchase_type,' + . 'a.language,' + . 'a.publish_up,' + . 'a.publish_down' + ) + ); + $query->from($db->quoteName('#__banners', 'a')); + + // Join over the language + $query->select('l.title AS language_title, l.image AS language_image') + ->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON l.lang_code = a.language'); + + // Join over the users for the checked out user. + $query->select($db->quoteName('uc.name', 'editor')) + ->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON uc.id = a.checked_out'); + + // Join over the categories. + $query->select($db->quoteName('c.title', 'category_title')) + ->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON c.id = a.catid'); + + // Join over the clients. + $query->select($db->quoteName('cl.name', 'client_name')) + ->select($db->quoteName('cl.purchase_type', 'client_purchase_type')) + ->join('LEFT', $db->quoteName('#__banner_clients', 'cl') . ' ON cl.id = a.cid'); + + // Filter by published state + $published = (string) $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where($db->quoteName('a.state') . ' = ' . (int) $published); + } + elseif ($published === '') + { + $query->where($db->quoteName('a.state') . ' IN (0, 1)'); + } + + // Filter by category. + $categoryId = $this->getState('filter.category_id'); + + if (is_numeric($categoryId)) + { + $query->where($db->quoteName('a.catid') . ' = ' . (int) $categoryId); + } + + // Filter by client. + $clientId = $this->getState('filter.client_id'); + + if (is_numeric($clientId)) + { + $query->where($db->quoteName('a.cid') . ' = ' . (int) $clientId); + } + + // Filter by search in title + $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('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(a.name LIKE ' . $search . ' OR a.alias LIKE ' . $search . ')'); + } + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + $query->where($db->quoteName('a.language') . ' = ' . $db->quote($language)); + } + + // Filter on the level. + if ($level = $this->getState('filter.level')) + { + $query->where($db->quoteName('c.level') . ' <= ' . (int) $level); + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering', 'a.name'); + $orderDirn = $this->state->get('list.direction', 'ASC'); + + if ($orderCol == 'a.ordering' || $orderCol == 'category_title') + { + $orderCol = 'c.title ' . $orderDirn . ', a.ordering'; + } + + if ($orderCol == 'client_name') + { + $orderCol = 'cl.name'; + } + + $query->order($db->escape($orderCol . ' ' . $orderDirn)); + + 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 A store id. + * + * @since 1.6 + */ + 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 .= ':' . $this->getState('filter.client_id'); + $id .= ':' . $this->getState('filter.language'); + $id .= ':' . $this->getState('filter.level'); + + return parent::getStoreId($id); + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @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 Table A Table object + * + * @since 1.6 + */ + public function getTable($type = 'Banner', $prefix = 'Administrator', $config = array()) + { + return parent::getTable($type, $prefix, $config); + } + + /** + * 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 1.6 + */ + protected function populateState($ordering = 'a.name', $direction = 'asc') + { + // Load the parameters. + $this->setState('params', ComponentHelper::getParams('com_banners')); + + // List state information. + parent::populateState($ordering, $direction); + } +} diff --git a/administrator/components/com_banners/Model/ClientModel.php b/administrator/components/com_banners/Model/ClientModel.php new file mode 100644 index 0000000000000..8d7b359bd31fc --- /dev/null +++ b/administrator/components/com_banners/Model/ClientModel.php @@ -0,0 +1,142 @@ +id)) + { + if ($record->state != -2) + { + return false; + } + + $user = Factory::getUser(); + + if (!empty($record->catid)) + { + return $user->authorise('core.delete', 'com_banners.category.' . (int) $record->catid); + } + + return $user->authorise('core.delete', 'com_banners'); + } + } + + /** + * 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 1.6 + */ + protected function canEditState($record) + { + $user = Factory::getUser(); + + if (!empty($record->catid)) + { + return $user->authorise('core.edit.state', 'com_banners.category.' . (int) $record->catid); + } + + return $user->authorise('core.edit.state', 'com_banners'); + } + + /** + * Method to get the record form. + * + * @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 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_banners.client', 'client', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_banners.edit.client.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_banners.client', $data); + + return $data; + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @param Table $table A Table object. + * + * @return void + * + * @since 1.6 + */ + protected function prepareTable($table) + { + $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); + } +} diff --git a/administrator/components/com_banners/Model/ClientsModel.php b/administrator/components/com_banners/Model/ClientsModel.php new file mode 100644 index 0000000000000..c68592e35d7ae --- /dev/null +++ b/administrator/components/com_banners/Model/ClientsModel.php @@ -0,0 +1,308 @@ +setState('params', ComponentHelper::getParams('com_banners')); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.purchase_type'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $defaultPurchase = ComponentHelper::getParams('com_banners')->get('purchase_type', 3); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.id AS id,' + . 'a.name AS name,' + . 'a.contact AS contact,' + . 'a.checked_out AS checked_out,' + . 'a.checked_out_time AS checked_out_time, ' + . 'a.state AS state,' + . 'a.metakey AS metakey,' + . 'a.purchase_type as purchase_type' + ) + ); + + $query->from($db->quoteName('#__banner_clients') . ' AS a'); + + // Join over the banners for counting + $query->select('COUNT(b.id) as nbanners') + ->join('LEFT', '#__banners AS b ON a.id = b.cid'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor') + ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); + + // Filter by published state + $published = (string) $this->getState('filter.state'); + + if (is_numeric($published)) + { + $query->where('a.state = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.state IN (0, 1))'); + } + + $query->group('a.id, a.name, a.contact, a.checked_out, a.checked_out_time, a.state, a.metakey, a.purchase_type, uc.name'); + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.name LIKE ' . $search); + } + } + + // Filter by purchase type + $purchaseType = $this->getState('filter.purchase_type'); + + if (!empty($purchaseType)) + { + if ($defaultPurchase == $purchaseType) + { + $query->where('(a.purchase_type = ' . (int) $purchaseType . ' OR a.purchase_type = -1)'); + } + else + { + $query->where('a.purchase_type = ' . (int) $purchaseType); + } + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.name')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Overrides the getItems method to attach additional metrics to the list. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 3.6 + */ + public function getItems() + { + // Get a storage key. + $store = $this->getStoreId('getItems'); + + // Try to load the data from internal storage. + if (!empty($this->cache[$store])) + { + return $this->cache[$store]; + } + + // Load the list items. + $items = parent::getItems(); + + // If emtpy or an error, just return. + if (empty($items)) + { + return array(); + } + + // Getting the following metric by joins is WAY TOO SLOW. + // Faster to do three queries for very large banner trees. + + // Get the clients in the list. + $db = $this->getDbo(); + $clientIds = ArrayHelper::getColumn($items, 'id'); + + // Quote the strings. + $clientIds = implode( + ',', + array_map(array($db, 'quote'), $clientIds) + ); + + // Get the published banners count. + $query = $db->getQuery(true) + ->select('cid, COUNT(cid) AS count_published') + ->from('#__banners') + ->where('state = 1') + ->where('cid IN (' . $clientIds . ')') + ->group('cid'); + + $db->setQuery($query); + + try + { + $countPublished = $db->loadAssocList('cid', 'count_published'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Get the unpublished banners count. + $query->clear('where') + ->where('state = 0') + ->where('cid IN (' . $clientIds . ')'); + $db->setQuery($query); + + try + { + $countUnpublished = $db->loadAssocList('cid', 'count_published'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Get the trashed banners count. + $query->clear('where') + ->where('state = -2') + ->where('cid IN (' . $clientIds . ')'); + $db->setQuery($query); + + try + { + $countTrashed = $db->loadAssocList('cid', 'count_published'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Get the archived banners count. + $query->clear('where') + ->where('state = 2') + ->where('cid IN (' . $clientIds . ')'); + $db->setQuery($query); + + try + { + $countArchived = $db->loadAssocList('cid', 'count_published'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Inject the values back into the array. + foreach ($items as $item) + { + $item->count_published = isset($countPublished[$item->id]) ? $countPublished[$item->id] : 0; + $item->count_unpublished = isset($countUnpublished[$item->id]) ? $countUnpublished[$item->id] : 0; + $item->count_trashed = isset($countTrashed[$item->id]) ? $countTrashed[$item->id] : 0; + $item->count_archived = isset($countArchived[$item->id]) ? $countArchived[$item->id] : 0; + } + + // Add the items to the internal cache. + $this->cache[$store] = $items; + + return $this->cache[$store]; + } +} diff --git a/administrator/components/com_banners/Model/DownloadModel.php b/administrator/components/com_banners/Model/DownloadModel.php new file mode 100644 index 0000000000000..94ff1303bafc6 --- /dev/null +++ b/administrator/components/com_banners/Model/DownloadModel.php @@ -0,0 +1,90 @@ +input; + + $this->setState('basename', $input->cookie->getString(ApplicationHelper::getHash($this->_context . '.basename'), '__SITE__')); + $this->setState('compressed', $input->cookie->getInt(ApplicationHelper::getHash($this->_context . '.compressed'), 1)); + } + + /** + * Method to get the record form. + * + * @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 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_banners.download', 'download', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + $data = array( + 'basename' => $this->getState('basename'), + 'compressed' => $this->getState('compressed'), + ); + + $this->preprocessData('com_banners.download', $data); + + return $data; + } +} diff --git a/administrator/components/com_banners/Model/TracksModel.php b/administrator/components/com_banners/Model/TracksModel.php new file mode 100644 index 0000000000000..ce98ac548fb3b --- /dev/null +++ b/administrator/components/com_banners/Model/TracksModel.php @@ -0,0 +1,537 @@ +setState('params', ComponentHelper::getParams('com_banners')); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select($db->quoteName(array('a.track_date', 'a.track_type', 'a.count'))) + ->select($db->quoteName('b.name', 'banner_name')) + ->select($db->quoteName('cl.name', 'client_name')) + ->select($db->quoteName('c.title', 'category_title')); + + // From tracks table. + $query->from($db->quoteName('#__banner_tracks', 'a')); + + // Join with the banners. + $query->join('LEFT', $db->quoteName('#__banners', 'b') . ' ON ' . $db->quoteName('b.id') . ' = ' . $db->quoteName('a.banner_id')); + + // Join with the client. + $query->join('LEFT', $db->quoteName('#__banner_clients', 'cl') . ' ON ' . $db->quoteName('cl.id') . ' = ' . $db->quoteName('b.cid')); + + // Join with the category. + $query->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('b.catid')); + + // Filter by type. + $type = $this->getState('filter.type'); + + if (!empty($type)) + { + $query->where($db->quoteName('a.track_type') . ' = ' . (int) $type); + } + + // Filter by client. + $clientId = $this->getState('filter.client_id'); + + if (is_numeric($clientId)) + { + $query->where($db->quoteName('b.cid') . ' = ' . (int) $clientId); + } + + // Filter by category. + $categoryId = $this->getState('filter.category_id'); + + if (is_numeric($categoryId)) + { + $query->where($db->quoteName('b.catid') . ' = ' . (int) $categoryId); + } + + // Filter by begin date. + + $begin = $this->getState('filter.begin'); + + if (!empty($begin)) + { + $query->where($db->quoteName('a.track_date') . ' >= ' . $db->quote($begin)); + } + + // Filter by end date. + $end = $this->getState('filter.end'); + + if (!empty($end)) + { + $query->where($db->quoteName('a.track_date') . ' <= ' . $db->quote($end)); + } + + // Filter on the level. + if ($level = $this->getState('filter.level')) + { + $query->where($db->quoteName('c.level') . ' <= ' . (int) $level); + } + + // Filter by search in banner name or client name. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + $search = $db->quote('%' . strtolower($search) . '%'); + $query->where('(LOWER(b.name) LIKE ' . $search . ' OR LOWER(cl.name) LIKE ' . $search . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'b.name')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to delete rows. + * + * @return boolean Returns true on success, false on failure. + */ + public function delete() + { + $user = Factory::getUser(); + $categoryId = $this->getState('category_id'); + + // Access checks. + if ($categoryId) + { + $allow = $user->authorise('core.delete', 'com_banners.category.' . (int) $categoryId); + } + else + { + $allow = $user->authorise('core.delete', 'com_banners'); + } + + if ($allow) + { + // Delete tracks from this banner + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__banner_tracks')); + + // Filter by type + $type = $this->getState('filter.type'); + + if (!empty($type)) + { + $query->where('track_type = ' . (int) $type); + } + + // Filter by begin date + $begin = $this->getState('filter.begin'); + + if (!empty($begin)) + { + $query->where('track_date >= ' . $db->quote($begin)); + } + + // Filter by end date + $end = $this->getState('filter.end'); + + if (!empty($end)) + { + $query->where('track_date <= ' . $db->quote($end)); + } + + $where = '1'; + + // Filter by client + $clientId = $this->getState('filter.client_id'); + + if (!empty($clientId)) + { + $where .= ' AND cid = ' . (int) $clientId; + } + + // Filter by category + if (!empty($categoryId)) + { + $where .= ' AND catid = ' . (int) $categoryId; + } + + $query->where('banner_id IN (SELECT id FROM ' . $db->quoteName('#__banners') . ' WHERE ' . $where . ')'); + + $db->setQuery($query); + $this->setError((string) $query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + else + { + Factory::getApplication()->enqueueMessage(Text::_('JERROR_CORE_DELETE_NOT_PERMITTED'), 'error'); + } + + return true; + } + + /** + * Get file name + * + * @return string The file name + * + * @since 1.6 + */ + public function getBaseName() + { + if (!isset($this->basename)) + { + $basename = str_replace('__SITE__', Factory::getApplication()->get('sitename'), $this->getState('basename')); + $categoryId = $this->getState('filter.category_id'); + + if (is_numeric($categoryId)) + { + if ($categoryId > 0) + { + $basename = str_replace('__CATID__', $categoryId, $basename); + } + else + { + $basename = str_replace('__CATID__', '', $basename); + } + + $categoryName = $this->getCategoryName(); + $basename = str_replace('__CATNAME__', $categoryName, $basename); + } + else + { + $basename = str_replace(array('__CATID__', '__CATNAME__'), '', $basename); + } + + $clientId = $this->getState('filter.client_id'); + + if (is_numeric($clientId)) + { + if ($clientId > 0) + { + $basename = str_replace('__CLIENTID__', $clientId, $basename); + } + else + { + $basename = str_replace('__CLIENTID__', '', $basename); + } + + $clientName = $this->getClientName(); + $basename = str_replace('__CLIENTNAME__', $clientName, $basename); + } + else + { + $basename = str_replace(array('__CLIENTID__', '__CLIENTNAME__'), '', $basename); + } + + $type = $this->getState('filter.type'); + + if ($type > 0) + { + $basename = str_replace('__TYPE__', $type, $basename); + $typeName = Text::_('COM_BANNERS_TYPE' . $type); + $basename = str_replace('__TYPENAME__', $typeName, $basename); + } + else + { + $basename = str_replace(array('__TYPE__', '__TYPENAME__'), '', $basename); + } + + $begin = $this->getState('filter.begin'); + + if (!empty($begin)) + { + $basename = str_replace('__BEGIN__', $begin, $basename); + } + else + { + $basename = str_replace('__BEGIN__', '', $basename); + } + + $end = $this->getState('filter.end'); + + if (!empty($end)) + { + $basename = str_replace('__END__', $end, $basename); + } + else + { + $basename = str_replace('__END__', '', $basename); + } + + $this->basename = $basename; + } + + return $this->basename; + } + + /** + * Get the category name. + * + * @return string The category name + * + * @since 1.6 + */ + protected function getCategoryName() + { + $categoryId = $this->getState('filter.category_id'); + + if ($categoryId) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('title') + ->from($db->quoteName('#__categories')) + ->where($db->quoteName('id') . '=' . $db->quote($categoryId)); + $db->setQuery($query); + + try + { + $name = $db->loadResult(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $name; + } + + return Text::_('COM_BANNERS_NOCATEGORYNAME'); + } + + /** + * Get the category name + * + * @return string The category name. + * + * @since 1.6 + */ + protected function getClientName() + { + $clientId = $this->getState('filter.client_id'); + + if ($clientId) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('name') + ->from($db->quoteName('#__banner_clients')) + ->where($db->quoteName('id') . '=' . $db->quote($clientId)); + $db->setQuery($query); + + try + { + $name = $db->loadResult(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $name; + } + + return Text::_('COM_BANNERS_NOCLIENTNAME'); + } + + /** + * Get the file type. + * + * @return string The file type + * + * @since 1.6 + */ + public function getFileType() + { + return $this->getState('compressed') ? 'zip' : 'csv'; + } + + /** + * Get the mime type. + * + * @return string The mime type. + * + * @since 1.6 + */ + public function getMimeType() + { + return $this->getState('compressed') ? 'application/zip' : 'text/csv'; + } + + /** + * Get the content + * + * @return string The content. + * + * @since 1.6 + */ + public function getContent() + { + if (!isset($this->content)) + { + $this->content = '"' . str_replace('"', '""', Text::_('COM_BANNERS_HEADING_NAME')) . '","' + . str_replace('"', '""', Text::_('COM_BANNERS_HEADING_CLIENT')) . '","' + . str_replace('"', '""', Text::_('JCATEGORY')) . '","' + . str_replace('"', '""', Text::_('COM_BANNERS_HEADING_TYPE')) . '","' + . str_replace('"', '""', Text::_('COM_BANNERS_HEADING_COUNT')) . '","' + . str_replace('"', '""', Text::_('JDATE')) . '"' . "\n"; + + foreach ($this->getItems() as $item) + { + $this->content .= '"' . str_replace('"', '""', $item->banner_name) . '","' + . str_replace('"', '""', $item->client_name) . '","' + . str_replace('"', '""', $item->category_title) . '","' + . str_replace('"', '""', ($item->track_type == 1 ? Text::_('COM_BANNERS_IMPRESSION') : Text::_('COM_BANNERS_CLICK'))) . '","' + . str_replace('"', '""', $item->count) . '","' + . str_replace('"', '""', $item->track_date) . '"' . "\n"; + } + + if ($this->getState('compressed')) + { + $app = Factory::getApplication(); + + $files = array( + 'track' => array( + 'name' => $this->getBasename() . '.csv', + 'data' => $this->content, + 'time' => time() + ) + ); + $ziproot = $app->get('tmp_path') . '/' . uniqid('banners_tracks_') . '.zip'; + + // Run the packager + $delete = Folder::files($app->get('tmp_path') . '/', uniqid('banners_tracks_'), false, true); + + if (!empty($delete)) + { + if (!File::delete($delete)) + { + // File::delete throws an error + $this->setError(Text::_('COM_BANNERS_ERR_ZIP_DELETE_FAILURE')); + + return false; + } + } + + $archive = new Archive; + + if (!$packager = $archive->getAdapter('zip')) + { + $this->setError(Text::_('COM_BANNERS_ERR_ZIP_ADAPTER_FAILURE')); + + return false; + } + elseif (!$packager->create($ziproot, $files)) + { + $this->setError(Text::_('COM_BANNERS_ERR_ZIP_CREATE_FAILURE')); + + return false; + } + + $this->content = file_get_contents($ziproot); + } + } + + return $this->content; + } +} diff --git a/administrator/components/com_banners/Service/Html/Banner.php b/administrator/components/com_banners/Service/Html/Banner.php new file mode 100644 index 0000000000000..f1cc73883da07 --- /dev/null +++ b/administrator/components/com_banners/Service/Html/Banner.php @@ -0,0 +1,120 @@ +', + Text::_('COM_BANNERS_BATCH_CLIENT_LABEL'), + '', + '' + ) + ); + } + + /** + * Method to get the field options. + * + * @return array The field option objects. + * + * @since 1.6 + */ + public function clientlist() + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('id As value, name As text') + ->from('#__banner_clients AS a') + ->order('a.name'); + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + return $options; + } + + /** + * Returns a pinned state on a grid + * + * @param integer $value The state value. + * @param integer $i The row index + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The Html code + * + * @see HTMLHelperJGrid::state + * @since 2.5.5 + */ + public function pinned($value, $i, $enabled = true, $checkbox = 'cb') + { + $states = array( + 1 => array( + 'sticky_unpublish', + 'COM_BANNERS_BANNERS_PINNED', + 'COM_BANNERS_BANNERS_HTML_PIN_BANNER', + 'COM_BANNERS_BANNERS_PINNED', + true, + 'publish', + 'publish' + ), + 0 => array( + 'sticky_publish', + 'COM_BANNERS_BANNERS_UNPINNED', + 'COM_BANNERS_BANNERS_HTML_UNPIN_BANNER', + 'COM_BANNERS_BANNERS_UNPINNED', + true, + 'unpublish', + 'unpublish' + ), + ); + + return HTMLHelper::_('jgrid.state', $states, $value, $i, 'banners.', $enabled, true, $checkbox); + } +} diff --git a/administrator/components/com_banners/Table/BannerTable.php b/administrator/components/com_banners/Table/BannerTable.php new file mode 100644 index 0000000000000..47b69deaa5fe2 --- /dev/null +++ b/administrator/components/com_banners/Table/BannerTable.php @@ -0,0 +1,348 @@ +typeAlias = 'com_banners.banner'; + + parent::__construct('#__banners', 'id', $db); + + $this->created = Factory::getDate()->toSql(); + $this->setColumnAlias('published', 'state'); + } + + /** + * Increase click count + * + * @return void + */ + public function clicks() + { + $query = 'UPDATE #__banners' + . ' SET clicks = (clicks + 1)' + . ' WHERE id = ' . (int) $this->id; + + $this->_db->setQuery($query); + $this->_db->execute(); + } + + /** + * Overloaded check function + * + * @return boolean + * + * @see Table::check + * @since 1.5 + */ + public function check() + { + try + { + parent::check(); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Set name + $this->name = htmlspecialchars_decode($this->name, ENT_QUOTES); + + // Set alias + if (trim($this->alias) == '') + { + $this->alias = $this->name; + } + + $this->alias = ApplicationHelper::stringURLSafe($this->alias, $this->language); + + if (trim(str_replace('-', '', $this->alias)) == '') + { + $this->alias = Factory::getDate()->format('Y-m-d-H-i-s'); + } + + // Check the publish down date is not earlier than publish up. + if ($this->publish_down > $this->_db->getNullDate() && $this->publish_down < $this->publish_up) + { + $this->setError(Text::_('JGLOBAL_START_PUBLISH_AFTER_FINISH')); + + return false; + } + + // Set ordering + if ($this->state < 0) + { + // Set ordering to 0 if state is archived or trashed + $this->ordering = 0; + } + elseif (empty($this->ordering)) + { + // Set ordering to last if ordering was 0 + $this->ordering = self::getNextOrder($this->_db->quoteName('catid') . '=' . $this->_db->quote($this->catid) . ' AND state>=0'); + } + + if (empty($this->publish_up)) + { + $this->publish_up = $this->getDbo()->getNullDate(); + } + + if (empty($this->publish_down)) + { + $this->publish_down = $this->getDbo()->getNullDate(); + } + + if (empty($this->modified)) + { + $this->modified = $this->getDbo()->getNullDate(); + } + + return true; + } + + /** + * Overloaded bind function + * + * @param mixed $array An associative array or object to bind to the \JTable instance. + * @param mixed $ignore An optional array or space separated list of properties to ignore while binding. + * + * @return boolean True on success + * + * @since 1.5 + */ + public function bind($array, $ignore = array()) + { + if (isset($array['params']) && is_array($array['params'])) + { + $registry = new Registry($array['params']); + + if ((int) $registry->get('width', 0) < 0) + { + $this->setError(Text::sprintf('JLIB_DATABASE_ERROR_NEGATIVE_NOT_PERMITTED', Text::_('COM_BANNERS_FIELD_WIDTH_LABEL'))); + + return false; + } + + if ((int) $registry->get('height', 0) < 0) + { + $this->setError(Text::sprintf('JLIB_DATABASE_ERROR_NEGATIVE_NOT_PERMITTED', Text::_('COM_BANNERS_FIELD_HEIGHT_LABEL'))); + + return false; + } + + // Converts the width and height to an absolute numeric value: + $width = abs((int) $registry->get('width', 0)); + $height = abs((int) $registry->get('height', 0)); + + // Sets the width and height to an empty string if = 0 + $registry->set('width', $width ?: ''); + $registry->set('height', $height ?: ''); + + $array['params'] = (string) $registry; + } + + if (isset($array['imptotal'])) + { + $array['imptotal'] = abs((int) $array['imptotal']); + } + + return parent::bind($array, $ignore); + } + + /** + * Method to store a row + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return boolean True on success, false on failure. + */ + public function store($updateNulls = false) + { + $db = $this->getDbo(); + + if (empty($this->id)) + { + $purchaseType = $this->purchase_type; + + if ($purchaseType < 0 && $this->cid) + { + /** @var ClientTable $client */ + $client = Table::getInstance('Client', __NAMESPACE__ . '\\', array('dbo' => $db)); + $client->load($this->cid); + $purchaseType = $client->purchase_type; + } + + if ($purchaseType < 0) + { + $purchaseType = ComponentHelper::getParams('com_banners')->get('purchase_type'); + } + + switch ($purchaseType) + { + case 1: + $this->reset = $this->_db->getNullDate(); + break; + case 2: + $date = Factory::getDate('+1 year ' . date('Y-m-d')); + $this->reset = $date->toSql(); + break; + case 3: + $date = Factory::getDate('+1 month ' . date('Y-m-d')); + $this->reset = $date->toSql(); + break; + case 4: + $date = Factory::getDate('+7 day ' . date('Y-m-d')); + $this->reset = $date->toSql(); + break; + case 5: + $date = Factory::getDate('+1 day ' . date('Y-m-d')); + $this->reset = $date->toSql(); + break; + } + + // Store the row + parent::store($updateNulls); + } + else + { + // Get the old row + /** @var BannerTable $oldrow */ + $oldrow = Table::getInstance('BannerTable', __NAMESPACE__ . '\\', array('dbo' => $db)); + + if (!$oldrow->load($this->id) && $oldrow->getError()) + { + $this->setError($oldrow->getError()); + } + + // Verify that the alias is unique + /** @var BannerTable $table */ + $table = Table::getInstance('BannerTable', __NAMESPACE__ . '\\', array('dbo' => $db)); + + if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) + { + $this->setError(Text::_('COM_BANNERS_ERROR_UNIQUE_ALIAS')); + + return false; + } + + // Store the new row + parent::store($updateNulls); + + // Need to reorder ? + if ($oldrow->state >= 0 && ($this->state < 0 || $oldrow->catid != $this->catid)) + { + // Reorder the oldrow + $this->reorder($this->_db->quoteName('catid') . '=' . $this->_db->quote($oldrow->catid) . ' AND state>=0'); + } + } + + return count($this->getErrors()) == 0; + } + + /** + * Method to set the sticky state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. + * @param integer $state The sticky state. eg. [0 = unsticked, 1 = sticked] + * @param integer $userId The user id of the user performing the operation. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function stick($pks = null, $state = 1, $userId = 0) + { + $k = $this->_tbl_key; + + // Sanitize input. + $pks = ArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(Text::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + // Get an instance of the table + /** @var BannerTable $table */ + $table = Table::getInstance('BannerTable', __NAMESPACE__ . '\\', array('dbo' => $db)); + + // For all keys + foreach ($pks as $pk) + { + // Load the banner + if (!$table->load($pk)) + { + $this->setError($table->getError()); + } + + // Verify checkout + if ($table->checked_out == 0 || $table->checked_out == $userId) + { + // Change the state + $table->sticky = $state; + $table->checked_out = 0; + $table->checked_out_time = $this->_db->getNullDate(); + + // Check the row + $table->check(); + + // Store the row + if (!$table->store()) + { + $this->setError($table->getError()); + } + } + } + + return count($this->getErrors()) == 0; + } +} diff --git a/administrator/components/com_banners/Table/ClientTable.php b/administrator/components/com_banners/Table/ClientTable.php new file mode 100644 index 0000000000000..53f28c7e5cfd5 --- /dev/null +++ b/administrator/components/com_banners/Table/ClientTable.php @@ -0,0 +1,131 @@ +typeAlias = 'com_banners.client'; + $this->checked_out_time = $db->getNullDate(); + + parent::__construct('#__banner_clients', 'id', $db); + } + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. + * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published, 2=archived, -2=trashed] + * @param integer $userId The user id of the user performing the operation. + * + * @return boolean True on success. + * + * @since 1.0.4 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + $k = $this->_tbl_key; + + // Sanitize input. + $pks = ArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(Text::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k . '=' . implode(' OR ' . $k . '=', $pks); + + // Determine if there is checkin support for the table. + if (!$this->hasField('checked_out') || !$this->hasField('checked_out_time')) + { + $checkin = ''; + } + else + { + $checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')'; + } + + // Update the publishing state for rows with the given primary keys. + $this->_db->setQuery( + 'UPDATE ' . $this->_db->quoteName($this->_tbl) + . ' SET ' . $this->_db->quoteName('state') . ' = ' . (int) $state + . ' WHERE (' . $where . ')' + . $checkin + ); + + try + { + $this->_db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && (count($pks) == $this->_db->getAffectedRows())) + { + // Checkin the rows. + foreach ($pks as $pk) + { + $this->checkin($pk); + } + } + + // If the \JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } +} diff --git a/administrator/components/com_banners/View/Banner/HtmlView.php b/administrator/components/com_banners/View/Banner/HtmlView.php new file mode 100644 index 0000000000000..7eb1302d12cb8 --- /dev/null +++ b/administrator/components/com_banners/View/Banner/HtmlView.php @@ -0,0 +1,137 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $user = Factory::getUser(); + $userId = $user->id; + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); + + // Since we don't track these assets at the item level, use the category id. + $canDo = ContentHelper::getActions('com_banners', 'category', $this->item->catid); + + ToolbarHelper::title($isNew ? Text::_('COM_BANNERS_MANAGER_BANNER_NEW') : Text::_('COM_BANNERS_MANAGER_BANNER_EDIT'), 'bookmark banners'); + + $toolbarButtons = []; + + // If not checked out, can save the item. + if (!$checkedOut && ($canDo->get('core.edit') || count($user->getAuthorisedCategories('com_banners', 'core.create')) > 0)) + { + $toolbarButtons[] = ['apply', 'banner.apply']; + $toolbarButtons[] = ['save', 'banner.save']; + + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2new', 'banner.save2new']; + } + } + + // If an existing item, can save to a copy. + if (!$isNew && $canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'banner.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (empty($this->item->id)) + { + ToolbarHelper::cancel('banner.cancel'); + } + else + { + if (ComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $canDo->get('core.edit')) + { + ToolbarHelper::versions('com_banners.banner', $this->item->id); + } + + ToolbarHelper::cancel('banner.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_COMPONENTS_BANNERS_BANNERS_EDIT'); + } +} diff --git a/administrator/components/com_banners/View/Banners/HtmlView.php b/administrator/components/com_banners/View/Banners/HtmlView.php new file mode 100644 index 0000000000000..3f7aed74bd5e3 --- /dev/null +++ b/administrator/components/com_banners/View/Banners/HtmlView.php @@ -0,0 +1,202 @@ +categories = $this->get('CategoryOrders'); + $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 \JViewGenericdataexception(implode("\n", $errors), 500); + } + + BannersHelper::addSubmenu('banners'); + + $this->addToolbar(); + + // Include the component HTML helpers. + HTMLHelper::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + $this->sidebar = \JHtmlSidebar::render(); + + // We do not need to filter by language when multilingual is disabled + if (!Multilanguage::isEnabled()) + { + unset($this->activeFilters['language']); + $this->filterForm->removeField('language', 'filter'); + } + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + \JLoader::register('BannersHelper', JPATH_ADMINISTRATOR . '/components/com_banners/helpers/banners.php'); + + $canDo = ContentHelper::getActions('com_banners', 'category', $this->state->get('filter.category_id')); + $user = Factory::getUser(); + + ToolbarHelper::title(Text::_('COM_BANNERS_MANAGER_BANNERS'), 'bookmark banners'); + + if (count($user->getAuthorisedCategories('com_banners', 'core.create')) > 0) + { + ToolbarHelper::addNew('banner.add'); + } + + if ($canDo->get('core.edit.state')) + { + if ($this->state->get('filter.published') != 2) + { + ToolbarHelper::publish('banners.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('banners.unpublish', 'JTOOLBAR_UNPUBLISH', true); + } + + if ($this->state->get('filter.published') != -1) + { + if ($this->state->get('filter.published') != 2) + { + ToolbarHelper::archiveList('banners.archive'); + } + elseif ($this->state->get('filter.published') == 2) + { + ToolbarHelper::unarchiveList('banners.publish'); + } + } + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::checkin('banners.checkin'); + } + + // Add a batch button + if ($user->authorise('core.create', 'com_banners') + && $user->authorise('core.edit', 'com_banners') + && $user->authorise('core.edit.state', 'com_banners')) + { + $title = Text::_('JTOOLBAR_BATCH'); + + // Instantiate a new FileLayout instance and render the batch button + $layout = new FileLayout('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + Toolbar::getInstance('toolbar')->appendButton('Custom', $dhtml, 'batch'); + } + + if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'banners.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('banners.trash'); + } + + if ($user->authorise('core.admin', 'com_banners') || $user->authorise('core.options', 'com_banners')) + { + ToolbarHelper::preferences('com_banners'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_BANNERS_BANNERS'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'ordering' => Text::_('JGRID_HEADING_ORDERING'), + 'a.state' => Text::_('JSTATUS'), + 'a.name' => Text::_('COM_BANNERS_HEADING_NAME'), + 'a.sticky' => Text::_('COM_BANNERS_HEADING_STICKY'), + 'client_name' => Text::_('COM_BANNERS_HEADING_CLIENT'), + 'impmade' => Text::_('COM_BANNERS_HEADING_IMPRESSIONS'), + 'clicks' => Text::_('COM_BANNERS_HEADING_CLICKS'), + 'a.language' => Text::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_banners/View/Client/HtmlView.php b/administrator/components/com_banners/View/Client/HtmlView.php new file mode 100644 index 0000000000000..3e5932fc9a7a0 --- /dev/null +++ b/administrator/components/com_banners/View/Client/HtmlView.php @@ -0,0 +1,146 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + $this->canDo = ContentHelper::getActions('com_banners'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $user = Factory::getUser(); + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->id); + $canDo = $this->canDo; + + ToolbarHelper::title( + $isNew ? Text::_('COM_BANNERS_MANAGER_CLIENT_NEW') : Text::_('COM_BANNERS_MANAGER_CLIENT_EDIT'), + 'bookmark banners-clients' + ); + + $toolbarButtons = []; + + // If not checked out, can save the item. + if (!$checkedOut && ($canDo->get('core.edit') || $canDo->get('core.create'))) + { + $toolbarButtons[] = ['apply', 'client.apply']; + $toolbarButtons[] = ['save', 'client.save']; + } + + if (!$checkedOut && $canDo->get('core.create')) + { + $toolbarButtons[] = ['save2new', 'client.save2new']; + } + + // If an existing item, can save to a copy. + if (!$isNew && $canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'client.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (empty($this->item->id)) + { + ToolbarHelper::cancel('client.cancel'); + } + else + { + if (ComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $canDo->get('core.edit')) + { + ToolbarHelper::versions('com_banners.client', $this->item->id); + } + + ToolbarHelper::cancel('client.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_COMPONENTS_BANNERS_CLIENTS_EDIT'); + } +} diff --git a/administrator/components/com_banners/View/Clients/HtmlView.php b/administrator/components/com_banners/View/Clients/HtmlView.php new file mode 100644 index 0000000000000..cb90923f2fe80 --- /dev/null +++ b/administrator/components/com_banners/View/Clients/HtmlView.php @@ -0,0 +1,138 @@ +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 \JViewGenericdataexception(implode("\n", $errors), 500); + } + + BannersHelper::addSubmenu('clients'); + + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_banners'); + + ToolbarHelper::title(Text::_('COM_BANNERS_MANAGER_CLIENTS'), 'bookmark banners-clients'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('client.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publish('clients.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('clients.unpublish', 'JTOOLBAR_UNPUBLISH', true); + ToolbarHelper::archiveList('clients.archive'); + ToolbarHelper::checkin('clients.checkin'); + } + + if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'clients.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('clients.trash'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_banners'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_BANNERS_CLIENTS'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.status' => Text::_('JSTATUS'), + 'a.name' => Text::_('COM_BANNERS_HEADING_CLIENT'), + 'contact' => Text::_('COM_BANNERS_HEADING_CONTACT'), + 'client_name' => Text::_('COM_BANNERS_HEADING_CLIENT'), + 'nbanners' => Text::_('COM_BANNERS_HEADING_ACTIVE'), + 'a.id' => Text::_('JGRID_HEADING_ID') + ); + } +} diff --git a/administrator/components/com_banners/View/Download/HtmlView.php b/administrator/components/com_banners/View/Download/HtmlView.php new file mode 100644 index 0000000000000..b727005dc0d62 --- /dev/null +++ b/administrator/components/com_banners/View/Download/HtmlView.php @@ -0,0 +1,49 @@ +form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + return parent::display($tpl); + } +} diff --git a/administrator/components/com_banners/View/Tracks/HtmlView.php b/administrator/components/com_banners/View/Tracks/HtmlView.php new file mode 100644 index 0000000000000..7c7346b4749ad --- /dev/null +++ b/administrator/components/com_banners/View/Tracks/HtmlView.php @@ -0,0 +1,142 @@ +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 \JViewGenericdataexception(implode("\n", $errors), 500); + } + + BannersHelper::addSubmenu('tracks'); + + $this->addToolbar(); + + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_banners', 'category', $this->state->get('filter.category_id')); + + ToolbarHelper::title(Text::_('COM_BANNERS_MANAGER_TRACKS'), 'bookmark banners-tracks'); + + $bar = Toolbar::getInstance('toolbar'); + + // Instantiate a new FileLayout instance and render the export button + $layout = new FileLayout('joomla.toolbar.modal'); + + $dhtml = $layout->render( + array( + 'selector' => 'downloadModal', + 'icon' => 'download', + 'text' => Text::_('JTOOLBAR_EXPORT'), + 'doTask' => Route::_('index.php?option=com_banners&view=download&tmpl=component'), + ) + ); + + $bar->appendButton('Custom', $dhtml, 'download'); + + if ($canDo->get('core.delete')) + { + $bar->appendButton('Confirm', 'COM_BANNERS_DELETE_MSG', 'delete', 'COM_BANNERS_TRACKS_DELETE', 'tracks.delete', false); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_banners'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_BANNERS_TRACKS'); + + \JHtmlSidebar::setAction('index.php?option=com_banners&view=tracks'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'b.name' => Text::_('COM_BANNERS_HEADING_NAME'), + 'cl.name' => Text::_('COM_BANNERS_HEADING_CLIENT'), + 'track_type' => Text::_('COM_BANNERS_HEADING_TYPE'), + 'count' => Text::_('COM_BANNERS_HEADING_COUNT'), + 'track_date' => Text::_('JDATE') + ); + } +} diff --git a/administrator/components/com_banners/View/Tracks/RawView.php b/administrator/components/com_banners/View/Tracks/RawView.php new file mode 100644 index 0000000000000..d663de861fe89 --- /dev/null +++ b/administrator/components/com_banners/View/Tracks/RawView.php @@ -0,0 +1,54 @@ +get('BaseName'); + $filetype = $this->get('FileType'); + $mimetype = $this->get('MimeType'); + $content = $this->get('Content'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $document = Factory::getDocument(); + $document->setMimeEncoding($mimetype); + Factory::getApplication() + ->setHeader( + 'Content-disposition', + 'attachment; filename="' . $basename . '.' . $filetype . '"; creation-date="' . Factory::getDate()->toRFC822() . '"', + true + ); + echo $content; + } +} diff --git a/administrator/components/com_banners/access.xml b/administrator/components/com_banners/access.xml index d81db5fbe78ee..8ac1d3710951d 100644 --- a/administrator/components/com_banners/access.xml +++ b/administrator/components/com_banners/access.xml @@ -3,43 +3,36 @@
@@ -47,25 +40,21 @@
diff --git a/administrator/components/com_banners/banners.php b/administrator/components/com_banners/banners.php deleted file mode 100644 index df7d18bf53a95..0000000000000 --- a/administrator/components/com_banners/banners.php +++ /dev/null @@ -1,21 +0,0 @@ -authorise('core.manage', 'com_banners')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -// Execute the task. -$controller = JControllerLegacy::getInstance('Banners'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_banners/banners.xml b/administrator/components/com_banners/banners.xml index e2bda0c984173..44b861dfa6b11 100644 --- a/administrator/components/com_banners/banners.xml +++ b/administrator/components/com_banners/banners.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 COM_BANNERS_XML_DESCRIPTION + Joomla\Component\Banners @@ -22,11 +23,12 @@ - banners.php - controller.php + dispatcher.php router.php + Controller + Helper helpers - models + Model com_banners @@ -72,11 +74,14 @@ access.xml banners.php config.xml - controller.php - controllers + dispatcher.php + Controller + Helper helpers + Model models - tables + Table + View views diff --git a/administrator/components/com_banners/config.xml b/administrator/components/com_banners/config.xml index 6d55b5decf705..b78872872f613 100644 --- a/administrator/components/com_banners/config.xml +++ b/administrator/components/com_banners/config.xml @@ -10,7 +10,6 @@ name="purchase_type" type="list" label="COM_BANNERS_FIELD_PURCHASETYPE_LABEL" - description="COM_BANNERS_FIELD_PURCHASETYPE_DESC" id="purchase_type" default="1" > @@ -24,25 +23,23 @@ - + - + - + input->get('view', 'banners'); - $layout = $this->input->get('layout', 'default'); - $id = $this->input->getInt('id'); - - // Check for edit form. - if ($view == 'banner' && $layout == 'edit' && !$this->checkEditId('com_banners.edit.banner', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_banners&view=banners', false)); - - return false; - } - elseif ($view == 'client' && $layout == 'edit' && !$this->checkEditId('com_banners.edit.client', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_banners&view=clients', false)); - - return false; - } - - return parent::display(); - } -} diff --git a/administrator/components/com_banners/controllers/banner.php b/administrator/components/com_banners/controllers/banner.php deleted file mode 100644 index eb48772f981df..0000000000000 --- a/administrator/components/com_banners/controllers/banner.php +++ /dev/null @@ -1,110 +0,0 @@ -input->getInt('filter_category_id'); - $categoryId = ArrayHelper::getValue($data, 'catid', $filter, 'int'); - $allow = null; - - if ($categoryId) - { - // If the category has been passed in the URL check it. - $allow = JFactory::getUser()->authorise('core.create', $this->option . '.category.' . $categoryId); - } - - if ($allow !== null) - { - return $allow; - } - - // In the absence of better information, revert to the component permissions. - return parent::allowAdd($data); - } - - /** - * Method override to check if you can edit an existing record. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. - * - * @return boolean - * - * @since 1.6 - */ - protected function allowEdit($data = array(), $key = 'id') - { - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; - $categoryId = 0; - - if ($recordId) - { - $categoryId = (int) $this->getModel()->getItem($recordId)->catid; - } - - if ($categoryId) - { - // The category has been set. Check the category permissions. - return JFactory::getUser()->authorise('core.edit', $this->option . '.category.' . $categoryId); - } - - // Since there is no asset tracking, revert to the component permissions. - return parent::allowEdit($data, $key); - } - - /** - * Method to run batch operations. - * - * @param string $model The model - * - * @return boolean True on success. - * - * @since 2.5 - */ - public function batch($model = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Set the model - $model = $this->getModel('Banner', '', array()); - - // Preset the redirect - $this->setRedirect(JRoute::_('index.php?option=com_banners&view=banners' . $this->getRedirectToListAppend(), false)); - - return parent::batch($model); - } -} diff --git a/administrator/components/com_banners/controllers/banners.php b/administrator/components/com_banners/controllers/banners.php deleted file mode 100644 index 89f6c9864ac8f..0000000000000 --- a/administrator/components/com_banners/controllers/banners.php +++ /dev/null @@ -1,109 +0,0 @@ -registerTask('sticky_unpublish', 'sticky_publish'); - } - - /** - * 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 The model. - * - * @since 1.6 - */ - public function getModel($name = 'Banner', $prefix = 'BannersModel', $config = array('ignore_request' => true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Stick items - * - * @return void - * - * @since 1.6 - */ - public function sticky_publish() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = $this->input->get('cid', array(), 'array'); - $values = array('sticky_publish' => 1, 'sticky_unpublish' => 0); - $task = $this->getTask(); - $value = ArrayHelper::getValue($values, $task, 0, 'int'); - - if (empty($ids)) - { - JError::raiseWarning(500, JText::_('COM_BANNERS_NO_BANNERS_SELECTED')); - } - else - { - // Get the model. - /** @var BannersModelBanner $model */ - $model = $this->getModel(); - - // Change the state of the records. - if (!$model->stick($ids, $value)) - { - JError::raiseWarning(500, $model->getError()); - } - else - { - if ($value == 1) - { - $ntext = 'COM_BANNERS_N_BANNERS_STUCK'; - } - else - { - $ntext = 'COM_BANNERS_N_BANNERS_UNSTUCK'; - } - - $this->setMessage(JText::plural($ntext, count($ids))); - } - } - - $this->setRedirect('index.php?option=com_banners&view=banners'); - } -} diff --git a/administrator/components/com_banners/controllers/client.php b/administrator/components/com_banners/controllers/client.php deleted file mode 100644 index 290d9d6579efe..0000000000000 --- a/administrator/components/com_banners/controllers/client.php +++ /dev/null @@ -1,26 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_banners/controllers/tracks.php b/administrator/components/com_banners/controllers/tracks.php deleted file mode 100644 index 92c6deda16be7..0000000000000 --- a/administrator/components/com_banners/controllers/tracks.php +++ /dev/null @@ -1,88 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Method to remove a record. - * - * @return void - * - * @since 1.6 - */ - public function delete() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Get the model. - /** @var BannersModelTracks $model */ - $model = $this->getModel(); - - // Load the filter state. - $app = JFactory::getApplication(); - - $model->setState('filter.type', $app->getUserState($this->context . '.filter.type')); - $model->setState('filter.begin', $app->getUserState($this->context . '.filter.begin')); - $model->setState('filter.end', $app->getUserState($this->context . '.filter.end')); - $model->setState('filter.category_id', $app->getUserState($this->context . '.filter.category_id')); - $model->setState('filter.client_id', $app->getUserState($this->context . '.filter.client_id')); - $model->setState('list.limit', 0); - $model->setState('list.start', 0); - - $count = $model->getTotal(); - - // Remove the items. - if (!$model->delete()) - { - JError::raiseWarning(500, $model->getError()); - } - elseif ($count > 0) - { - $this->setMessage(JText::plural('COM_BANNERS_TRACKS_N_ITEMS_DELETED', $count)); - } - else - { - $this->setMessage(JText::_('COM_BANNERS_TRACKS_NO_ITEMS_DELETED')); - } - - $this->setRedirect('index.php?option=com_banners&view=tracks'); - } -} diff --git a/administrator/components/com_banners/controllers/tracks.raw.php b/administrator/components/com_banners/controllers/tracks.raw.php deleted file mode 100644 index aac0452009a4a..0000000000000 --- a/administrator/components/com_banners/controllers/tracks.raw.php +++ /dev/null @@ -1,119 +0,0 @@ - true)); - } - - /** - * Display method for the raw track data. - * - * @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 BannersControllerTracks This object to support chaining. - * - * @since 1.5 - * @todo This should be done as a view, not here! - */ - public function display($cachable = false, $urlparams = array()) - { - // Get the document object. - $vName = 'tracks'; - - // Get and render the view. - if ($view = $this->getView($vName, 'raw')) - { - // Get the model for the view. - /** @var BannersModelTracks $model */ - $model = $this->getModel($vName); - - // Load the filter state. - $app = JFactory::getApplication(); - - $model->setState('filter.type', $app->getUserState($this->context . '.filter.type')); - $model->setState('filter.begin', $app->getUserState($this->context . '.filter.begin')); - $model->setState('filter.end', $app->getUserState($this->context . '.filter.end')); - $model->setState('filter.category_id', $app->getUserState($this->context . '.filter.category_id')); - $model->setState('filter.client_id', $app->getUserState($this->context . '.filter.client_id')); - $model->setState('list.limit', 0); - $model->setState('list.start', 0); - - $form = $this->input->get('jform', array(), 'array'); - - $model->setState('basename', $form['basename']); - $model->setState('compressed', $form['compressed']); - - // Create one year cookies. - $cookieLifeTime = time() + 365 * 86400; - $cookieDomain = $app->get('cookie_domain', ''); - $cookiePath = $app->get('cookie_path', '/'); - $isHttpsForced = $app->isHttpsForced(); - - $app->input->cookie->set( - JApplicationHelper::getHash($this->context . '.basename'), - $form['basename'], - $cookieLifeTime, - $cookiePath, - $cookieDomain, - $isHttpsForced, - true - ); - - $app->input->cookie->set( - JApplicationHelper::getHash($this->context . '.compressed'), - $form['compressed'], - $cookieLifeTime, - $cookiePath, - $cookieDomain, - $isHttpsForced, - true - ); - - // Push the model into the view (as default). - $view->setModel($model, true); - - // Push document object into the view. - $view->document = JFactory::getDocument(); - - $view->display(); - } - - return $this; - } -} diff --git a/administrator/components/com_banners/models/forms/banner.xml b/administrator/components/com_banners/forms/banner.xml similarity index 76% rename from administrator/components/com_banners/models/forms/banner.xml rename to administrator/components/com_banners/forms/banner.xml index ed79d80450594..b76b022aeee89 100644 --- a/administrator/components/com_banners/models/forms/banner.xml +++ b/administrator/components/com_banners/forms/banner.xml @@ -1,12 +1,11 @@ -
-
+ +
@@ -35,19 +32,18 @@ name="catid" type="categoryedit" label="JCATEGORY" - description="COM_BANNERS_FIELD_CATEGORY_DESC" extension="com_banners" required="true" - addfieldpath="/administrator/components/com_categories/models/fields" + addfieldprefix="Joomla\Component\Categories\Administrator\Field" default="" + class="advancedSelect" /> @@ -61,7 +57,6 @@ name="ordering" type="ordering" label="JFIELD_ORDERING_LABEL" - description="JFIELD_ORDERING_DESC" table="#__banners" /> @@ -69,7 +64,6 @@ name="language" type="contentlanguage" label="JFIELD_LANGUAGE_LABEL" - description="COM_BANNERS_FIELD_LANGUAGE_DESC" > @@ -78,9 +72,7 @@ name="version_note" type="text" label="JGLOBAL_FIELD_VERSION_NOTE_LABEL" - description="JGLOBAL_FIELD_VERSION_NOTE_DESC" maxlength="255" - class="span12" size="45" labelclass="control-label" /> @@ -89,7 +81,6 @@ name="description" type="editor" label="JGLOBAL_DESCRIPTION" - description="COM_BANNERS_FIELD_DESCRIPTION_DESC" filter="JComponentHelper::filterText" buttons="true" hide="readmore,pagebreak,module,article,contact,menu" @@ -99,7 +90,6 @@ name="type" type="list" label="COM_BANNERS_FIELD_TYPE_LABEL" - description="COM_BANNERS_FIELD_TYPE_DESC" default="0" > @@ -110,7 +100,6 @@ name="custombannercode" type="textarea" label="COM_BANNERS_FIELD_CUSTOMCODE_LABEL" - description="COM_BANNERS_FIELD_CUSTOMCODE_DESC" rows="3" cols="30" filter="raw" @@ -120,7 +109,6 @@ name="clickurl" type="url" label="COM_BANNERS_FIELD_CLICKURL_LABEL" - description="COM_BANNERS_FIELD_CLICKURL_DESC" filter="url" />
@@ -131,7 +119,6 @@ name="created" type="calendar" label="COM_BANNERS_FIELD_CREATED_LABEL" - description="COM_BANNERS_FIELD_CREATED_DESC" size="22" translateformat="true" showtime="true" @@ -142,14 +129,12 @@ name="created_by" type="user" label="COM_BANNERS_FIELD_CREATED_BY_LABEL" - description="COM_BANNERS_FIELD_CREATED_BY_DESC" /> @@ -157,7 +142,6 @@ name="modified" type="calendar" label="JGLOBAL_FIELD_MODIFIED_LABEL" - description="COM_BANNERS_FIELD_MODIFIED_DESC" class="readonly" size="22" readonly="true" @@ -170,7 +154,6 @@ name="modified_by" type="user" label="JGLOBAL_FIELD_MODIFIED_BY_LABEL" - description="COM_BANNERS_FIELD_MODIFIED_BY_DESC" class="readonly" readonly="true" filter="unset" @@ -180,7 +163,6 @@ name="version" type="text" label="COM_BANNERS_FIELD_VERSION_LABEL" - description="COM_BANNERS_FIELD_VERSION_DESC" class="readonly" size="6" readonly="true" @@ -191,7 +173,6 @@ name="publish_up" type="calendar" label="COM_BANNERS_FIELD_PUBLISH_UP_LABEL" - description="COM_BANNERS_FIELD_PUBLISH_UP_DESC" translateformat="true" showtime="true" size="22" @@ -202,7 +183,6 @@ name="publish_down" type="calendar" label="COM_BANNERS_FIELD_PUBLISH_DOWN_LABEL" - description="COM_BANNERS_FIELD_PUBLISH_DOWN_DESC" translateformat="true" showtime="true" size="22" @@ -215,13 +195,13 @@ - +
@@ -230,7 +210,6 @@ name="imptotal" type="imptotal" label="COM_BANNERS_FIELD_IMPTOTAL_LABEL" - description="COM_BANNERS_FIELD_IMPTOTAL_DESC" default="0" /> @@ -238,7 +217,6 @@ name="impmade" type="impmade" label="COM_BANNERS_FIELD_IMPMADE_LABEL" - description="COM_BANNERS_FIELD_IMPMADE_DESC" default="0" /> @@ -246,7 +224,6 @@ name="clicks" type="clicks" label="COM_BANNERS_FIELD_CLICKS_LABEL" - description="COM_BANNERS_FIELD_CLICKS_DESC" default="0" /> @@ -254,14 +231,12 @@ name="cid" type="bannerclient" label="COM_BANNERS_FIELD_CLIENT_LABEL" - description="COM_BANNERS_FIELD_CLIENT_DESC" /> @@ -276,7 +251,6 @@ name="track_impressions" type="list" label="COM_BANNERS_FIELD_TRACKIMPRESSION_LABEL" - description="COM_BANNERS_FIELD_TRACKIMPRESSION_DESC" default="0" > @@ -288,7 +262,6 @@ name="track_clicks" type="list" label="COM_BANNERS_FIELD_TRACKCLICK_LABEL" - description="COM_BANNERS_FIELD_TRACKCLICK_DESC" default="0" > @@ -303,7 +276,6 @@ name="metakey" type="textarea" label="JFIELD_META_KEYWORDS_LABEL" - description="COM_BANNERS_FIELD_METAKEYWORDS_DESC" rows="3" cols="30" /> @@ -311,13 +283,12 @@ - + @@ -352,7 +321,6 @@ name="height" type="number" label="COM_BANNERS_FIELD_HEIGHT_LABEL" - description="COM_BANNERS_FIELD_HEIGHT_DESC" class="input-mini validate-numeric" /> @@ -360,7 +328,6 @@ name="alt" type="text" label="COM_BANNERS_FIELD_ALT_LABEL" - description="COM_BANNERS_FIELD_ALT_DESC" /> @@ -370,7 +337,6 @@ name="bannercode" type="textarea" label="COM_BANNERS_FIELD_CUSTOMCODE_LABEL" - description="COM_BANNERS_FIELD_CUSTOMCODE_DESC" rows="3" cols="30" filter="raw" diff --git a/administrator/components/com_banners/models/forms/client.xml b/administrator/components/com_banners/forms/client.xml similarity index 76% rename from administrator/components/com_banners/models/forms/client.xml rename to administrator/components/com_banners/forms/client.xml index a3bb8f7010089..fb8f62c550ce6 100644 --- a/administrator/components/com_banners/models/forms/client.xml +++ b/administrator/components/com_banners/forms/client.xml @@ -1,11 +1,10 @@ - -
+ +
@@ -34,7 +31,6 @@ name="email" type="email" label="COM_BANNERS_FIELD_EMAIL_LABEL" - description="COM_BANNERS_FIELD_EMAIL_DESC" size="40" validate="email" /> @@ -43,8 +39,7 @@ name="state" type="list" label="JSTATUS" - description="COM_BANNERS_FIELD_CLIENT_STATE_DESC" - class="chzn-color-state" + class="custom-select-color-state" size="1" default="1" > @@ -58,7 +53,6 @@ name="version_note" type="text" label="JGLOBAL_FIELD_VERSION_NOTE_LABEL" - description="JGLOBAL_FIELD_VERSION_NOTE_DESC" maxlength="255" size="45" labelclass="control-label" @@ -68,7 +62,6 @@ name="purchase_type" type="list" label="COM_BANNERS_FIELD_PURCHASETYPE_LABEL" - description="COM_BANNERS_FIELD_PURCHASETYPE_DESC" default="0" > @@ -83,9 +76,7 @@ name="track_impressions" type="list" label="COM_BANNERS_FIELD_TRACKIMPRESSION_LABEL" - description="COM_BANNERS_FIELD_TRACKIMPRESSION_DESC" default="0" - class="chzn-color" > @@ -96,9 +87,7 @@ name="track_clicks" type="list" label="COM_BANNERS_FIELD_TRACKCLICK_LABEL" - description="COM_BANNERS_FIELD_TRACKCLICK_DESC" default="0" - class="chzn-color" > @@ -112,7 +101,6 @@ name="metakey" type="textarea" label="JFIELD_META_KEYWORDS_LABEL" - description="COM_BANNERS_FIELD_CLIENT_METAKEYWORDS_DESC" rows="3" cols="30" /> @@ -120,13 +108,12 @@ - + diff --git a/administrator/components/com_banners/models/forms/download.xml b/administrator/components/com_banners/forms/download.xml similarity index 85% rename from administrator/components/com_banners/models/forms/download.xml rename to administrator/components/com_banners/forms/download.xml index 17c0cc6ec96de..f74c0633ad54d 100644 --- a/administrator/components/com_banners/models/forms/download.xml +++ b/administrator/components/com_banners/forms/download.xml @@ -6,13 +6,12 @@ - + - - + + @@ -22,10 +20,9 @@ @@ -33,8 +30,6 @@ @@ -44,8 +39,6 @@ @@ -55,8 +48,6 @@ COM_BANNERS_HEADING_IMPRESSIONS_DESC - - + + @@ -102,9 +91,7 @@ diff --git a/administrator/components/com_banners/models/forms/filter_clients.xml b/administrator/components/com_banners/forms/filter_clients.xml similarity index 84% rename from administrator/components/com_banners/models/forms/filter_clients.xml rename to administrator/components/com_banners/forms/filter_clients.xml index 1552335b63704..831d658197811 100644 --- a/administrator/components/com_banners/models/forms/filter_clients.xml +++ b/administrator/components/com_banners/forms/filter_clients.xml @@ -12,8 +12,6 @@ @@ -22,8 +20,6 @@ @@ -39,8 +35,6 @@ diff --git a/administrator/components/com_banners/models/forms/filter_tracks.xml b/administrator/components/com_banners/forms/filter_tracks.xml similarity index 79% rename from administrator/components/com_banners/models/forms/filter_tracks.xml rename to administrator/components/com_banners/forms/filter_tracks.xml index 449c4e574b1f7..46bb018c1625c 100644 --- a/administrator/components/com_banners/models/forms/filter_tracks.xml +++ b/administrator/components/com_banners/forms/filter_tracks.xml @@ -1,6 +1,6 @@ - - + + @@ -23,8 +22,6 @@ @@ -44,8 +41,6 @@ @@ -104,9 +93,6 @@ diff --git a/administrator/components/com_banners/helpers/banners.php b/administrator/components/com_banners/helpers/banners.php index 951a364fe93c2..443a949152a9c 100644 --- a/administrator/components/com_banners/helpers/banners.php +++ b/administrator/components/com_banners/helpers/banners.php @@ -12,288 +12,11 @@ /** * Banners component helper. * - * @since 1.6 + * @since 1.6 + * + * @deprecated 5.0 Use \Joomla\Component\Banners\Administrator\Helper\BannersHelper instead */ -class BannersHelper extends JHelperContent +class BannersHelper extends \Joomla\Component\Banners\Administrator\Helper\BannersHelper { - /** - * Configure the Linkbar. - * - * @param string $vName The name of the active view. - * - * @return void - * - * @since 1.6 - */ - public static function addSubmenu($vName) - { - JHtmlSidebar::addEntry( - JText::_('COM_BANNERS_SUBMENU_BANNERS'), - 'index.php?option=com_banners&view=banners', - $vName == 'banners' - ); - - JHtmlSidebar::addEntry( - JText::_('COM_BANNERS_SUBMENU_CATEGORIES'), - 'index.php?option=com_categories&extension=com_banners', - $vName == 'categories' - ); - - JHtmlSidebar::addEntry( - JText::_('COM_BANNERS_SUBMENU_CLIENTS'), - 'index.php?option=com_banners&view=clients', - $vName == 'clients' - ); - - JHtmlSidebar::addEntry( - JText::_('COM_BANNERS_SUBMENU_TRACKS'), - 'index.php?option=com_banners&view=tracks', - $vName == 'tracks' - ); - } - - /** - * Update / reset the banners - * - * @return boolean - * - * @since 1.6 - */ - public static function updateReset() - { - $db = JFactory::getDbo(); - $nullDate = $db->getNullDate(); - $query = $db->getQuery(true) - ->select('*') - ->from('#__banners') - ->where($db->quote(JFactory::getDate()) . ' >= ' . $db->quote('reset')) - ->where($db->quoteName('reset') . ' != ' . $db->quote($nullDate) . ' AND ' . $db->quoteName('reset') . '!= NULL') - ->where( - '(' . $db->quoteName('checked_out') . ' = 0 OR ' . $db->quoteName('checked_out') . ' = ' - . (int) $db->quote(JFactory::getUser()->id) . ')' - ); - $db->setQuery($query); - - try - { - $rows = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - - return false; - } - - JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR . '/tables'); - - foreach ($rows as $row) - { - $purchaseType = $row->purchase_type; - - if ($purchaseType < 0 && $row->cid) - { - /** @var BannersTableClient $client */ - $client = JTable::getInstance('Client', 'BannersTable'); - $client->load($row->cid); - $purchaseType = $client->purchase_type; - } - - if ($purchaseType < 0) - { - $params = JComponentHelper::getParams('com_banners'); - $purchaseType = $params->get('purchase_type'); - } - - switch ($purchaseType) - { - case 1: - $reset = $nullDate; - break; - case 2: - $date = JFactory::getDate('+1 year ' . date('Y-m-d')); - $reset = $db->quote($date->toSql()); - break; - case 3: - $date = JFactory::getDate('+1 month ' . date('Y-m-d')); - $reset = $db->quote($date->toSql()); - break; - case 4: - $date = JFactory::getDate('+7 day ' . date('Y-m-d')); - $reset = $db->quote($date->toSql()); - break; - case 5: - $date = JFactory::getDate('+1 day ' . date('Y-m-d')); - $reset = $db->quote($date->toSql()); - break; - } - - // Update the row ordering field. - $query->clear() - ->update($db->quoteName('#__banners')) - ->set($db->quoteName('reset') . ' = ' . $db->quote($reset)) - ->set($db->quoteName('impmade') . ' = ' . $db->quote(0)) - ->set($db->quoteName('clicks') . ' = ' . $db->quote(0)) - ->where($db->quoteName('id') . ' = ' . $db->quote($row->id)); - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $db->getMessage()); - - return false; - } - } - - return true; - } - - /** - * Get client list in text/value format for a select field - * - * @return array - */ - public static function getClientOptions() - { - $options = array(); - - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('id AS value, name AS text') - ->from('#__banner_clients AS a') - ->where('a.state = 1') - ->order('a.name'); - - // Get the options. - $db->setQuery($query); - - try - { - $options = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - array_unshift($options, JHtml::_('select.option', '0', JText::_('COM_BANNERS_NO_CLIENT'))); - - return $options; - } - - /** - * Adds Count Items for Category Manager. - * - * @param stdClass[] &$items The banner category objects - * - * @return stdClass[] - * - * @since 3.5 - */ - 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; - } - } - } - return $items; - } } diff --git a/administrator/components/com_banners/helpers/html/banner.php b/administrator/components/com_banners/helpers/html/banner.php deleted file mode 100644 index fdbbebd273ca5..0000000000000 --- a/administrator/components/com_banners/helpers/html/banner.php +++ /dev/null @@ -1,116 +0,0 @@ -', - JText::_('COM_BANNERS_BATCH_CLIENT_LABEL'), - '', - '' - ) - ); - } - - /** - * Method to get the field options. - * - * @return array The field option objects. - * - * @since 1.6 - */ - public static function clientlist() - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('id As value, name As text') - ->from('#__banner_clients AS a') - ->order('a.name'); - - // Get the options. - $db->setQuery($query); - - try - { - $options = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - return $options; - } - - /** - * Returns a pinned state on a grid - * - * @param integer $value The state value. - * @param integer $i The row index - * @param boolean $enabled An optional setting for access control on the action. - * @param string $checkbox An optional prefix for checkboxes. - * - * @return string The Html code - * - * @see JHtmlJGrid::state - * @since 2.5.5 - */ - public static function pinned($value, $i, $enabled = true, $checkbox = 'cb') - { - $states = array( - 1 => array( - 'sticky_unpublish', - 'COM_BANNERS_BANNERS_PINNED', - 'COM_BANNERS_BANNERS_HTML_PIN_BANNER', - 'COM_BANNERS_BANNERS_PINNED', - true, - 'publish', - 'publish' - ), - 0 => array( - 'sticky_publish', - 'COM_BANNERS_BANNERS_UNPINNED', - 'COM_BANNERS_BANNERS_HTML_UNPIN_BANNER', - 'COM_BANNERS_BANNERS_UNPINNED', - true, - 'unpublish', - 'unpublish' - ), - ); - - return JHtml::_('jgrid.state', $states, $value, $i, 'banners.', $enabled, true, $checkbox); - } -} diff --git a/administrator/components/com_banners/models/banner.php b/administrator/components/com_banners/models/banner.php deleted file mode 100644 index 001353023eef8..0000000000000 --- a/administrator/components/com_banners/models/banner.php +++ /dev/null @@ -1,573 +0,0 @@ - 'batchClient', - 'language_id' => 'batchLanguage' - ); - - /** - * Batch client changes for a group of banners. - * - * @param string $value The new value matching a client. - * @param array $pks An array of row IDs. - * @param array $contexts An array of item contexts. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 2.5 - */ - protected function batchClient($value, $pks, $contexts) - { - // Set the variables - $user = JFactory::getUser(); - - /** @var BannersTableBanner $table */ - $table = $this->getTable(); - - foreach ($pks as $pk) - { - if (!$user->authorise('core.edit', $contexts[$pk])) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); - - return false; - } - - $table->reset(); - $table->load($pk); - $table->cid = (int) $value; - - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - } - - // Clean the cache - $this->cleanCache(); - - return true; - } - - /** - * 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 2.5 - */ - protected function batchCopy($value, $pks, $contexts) - { - $categoryId = (int) $value; - - /** @var BannersTableBanner $table */ - $table = $this->getTable(); - $newIds = array(); - - // Check that the category exists - if ($categoryId) - { - $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)) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); - - return false; - } - - // 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; - } - - /** - * Method to test whether a record can be deleted. - * - * @param object $record A record object. - * - * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. - * - * @since 1.6 - */ - protected function canDelete($record) - { - 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); - } - } - - /** - * 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 1.6 - */ - protected function canEditState($record) - { - // Check against the category. - if (!empty($record->catid)) - { - return JFactory::getUser()->authorise('core.edit.state', 'com_banners.category.' . (int) $record->catid); - } - - // Default to component settings if category not known. - return parent::canEditState($record); - } - - /** - * Returns a JTable object, always creating it. - * - * @param string $type The table type to instantiate. [optional] - * @param string $prefix A prefix for the table class name. [optional] - * @param array $config Configuration array for model. [optional] - * - * @return JTable A database object - * - * @since 1.6 - */ - public function getTable($type = 'Banner', $prefix = 'BannersTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Method to get the record form. - * - * @param array $data Data for the form. [optional] - * @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional] - * - * @return JForm|boolean A JForm object on success, false on failure - * - * @since 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - // Get the form. - $form = $this->loadForm('com_banners.banner', 'banner', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - // Determine correct permissions to check. - if ($this->getState('banner.id')) - { - // Existing record. Can only edit in selected categories. - $form->setFieldAttribute('catid', 'action', 'core.edit'); - } - else - { - // New record. Can only create in selected categories. - $form->setFieldAttribute('catid', 'action', 'core.create'); - } - - // Modify the form based on access controls. - if (!$this->canEditState((object) $data)) - { - // Disable fields for display. - $form->setFieldAttribute('ordering', 'disabled', 'true'); - $form->setFieldAttribute('publish_up', 'disabled', 'true'); - $form->setFieldAttribute('publish_down', 'disabled', 'true'); - $form->setFieldAttribute('state', 'disabled', 'true'); - $form->setFieldAttribute('sticky', 'disabled', 'true'); - - // Disable fields while saving. - // The controller has already verified this is a record you can edit. - $form->setFieldAttribute('ordering', 'filter', 'unset'); - $form->setFieldAttribute('publish_up', 'filter', 'unset'); - $form->setFieldAttribute('publish_down', 'filter', 'unset'); - $form->setFieldAttribute('state', 'filter', 'unset'); - $form->setFieldAttribute('sticky', 'filter', 'unset'); - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $app = JFactory::getApplication(); - $data = $app->getUserState('com_banners.edit.banner.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - - // Prime some default values. - if ($this->getState('banner.id') == 0) - { - $filters = (array) $app->getUserState('com_banners.banners.filter'); - $filterCatId = isset($filters['category_id']) ? $filters['category_id'] : null; - - $data->set('catid', $app->input->getInt('catid', $filterCatId)); - } - } - - $this->preprocessData('com_banners.banner', $data); - - return $data; - } - - /** - * Method to stick records. - * - * @param array &$pks The ids of the items to publish. - * @param integer $value The value of the published state - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function stick(&$pks, $value = 1) - { - /** @var BannersTableBanner $table */ - $table = $this->getTable(); - $pks = (array) $pks; - - // Access checks. - foreach ($pks as $i => $pk) - { - if ($table->load($pk)) - { - if (!$this->canEditState($table)) - { - // Prune items that you can't change. - unset($pks[$i]); - JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - } - } - } - - // Attempt to change the state of the records. - if (!$table->stick($pks, $value, JFactory::getUser()->id)) - { - $this->setError($table->getError()); - - return false; - } - - return true; - } - - /** - * A protected method to get a set of ordering conditions. - * - * @param JTable $table A record object. - * - * @return array An array of conditions to add to add to ordering queries. - * - * @since 1.6 - */ - protected function getReorderConditions($table) - { - return array( - 'catid = ' . (int) $table->catid, - 'state >= 0' - ); - } - - /** - * Prepare and sanitise the table prior to saving. - * - * @param JTable $table A JTable object. - * - * @return void - * - * @since 1.6 - */ - protected function prepareTable($table) - { - $date = JFactory::getDate(); - $user = JFactory::getUser(); - - if (empty($table->id)) - { - // Set the values - $table->created = $date->toSql(); - $table->created_by = $user->id; - - // Set ordering to the last item if not set - if (empty($table->ordering)) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('MAX(ordering)') - ->from('#__banners'); - - $db->setQuery($query); - $max = $db->loadResult(); - - $table->ordering = $max + 1; - } - } - else - { - // Set the values - $table->modified = $date->toSql(); - $table->modified_by = $user->id; - } - - // Increment the content version number. - $table->version++; - } - - /** - * Allows preprocessing of the JForm object. - * - * @param JForm $form The form object - * @param array $data The data to be merged into the form object - * @param string $group The plugin group to be executed - * - * @return void - * - * @since 3.6.1 - */ - protected function preprocessForm(JForm $form, $data, $group = 'content') - { - if ($this->canCreateCategory()) - { - $form->setFieldAttribute('catid', 'allowAdd', 'true'); - } - - parent::preprocessForm($form, $data, $group); - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function save($data) - { - $input = JFactory::getApplication()->input; - - JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - - // Cast catid to integer for comparison - $catid = (int) $data['catid']; - - // Check if New Category exists - if ($catid > 0) - { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_banners'); - } - - // Save New Category - if ($catid == 0 && $this->canCreateCategory()) - { - $table = array(); - $table['title'] = $data['catid']; - $table['parent_id'] = 1; - $table['extension'] = 'com_banners'; - $table['language'] = $data['language']; - $table['published'] = 1; - - // Create new category and get catid back - $data['catid'] = CategoriesHelper::createCategory($table); - } - - // Alter the name for save as copy - if ($input->get('task') == 'save2copy') - { - /** @var BannersTableBanner $origTable */ - $origTable = clone $this->getTable(); - $origTable->load($input->getInt('id')); - - if ($data['name'] == $origTable->name) - { - list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']); - $data['name'] = $name; - $data['alias'] = $alias; - } - else - { - if ($data['alias'] == $origTable->alias) - { - $data['alias'] = ''; - } - } - - $data['state'] = 0; - } - - return parent::save($data); - } - - /** - * Is the user allowed to create an on the fly category? - * - * @return boolean - * - * @since 3.6.1 - */ - private function canCreateCategory() - { - return JFactory::getUser()->authorise('core.create', 'com_banners'); - } -} diff --git a/administrator/components/com_banners/models/banners.php b/administrator/components/com_banners/models/banners.php deleted file mode 100644 index 6cb80bcf5c178..0000000000000 --- a/administrator/components/com_banners/models/banners.php +++ /dev/null @@ -1,282 +0,0 @@ -cache['categoryorders'])) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('MAX(ordering) as ' . $db->quoteName('max') . ', catid') - ->select('catid') - ->from('#__banners') - ->group('catid'); - $db->setQuery($query); - $this->cache['categoryorders'] = $db->loadAssocList('catid', 0); - } - - return $this->cache['categoryorders']; - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - * - * @since 1.6 - */ - protected function getListQuery() - { - $db = $this->getDbo(); - $query = $db->getQuery(true); - - // Select the required fields from the table. - $query->select( - $this->getState( - 'list.select', - 'a.id AS id,' - . 'a.name AS name,' - . 'a.alias AS alias,' - . 'a.checked_out AS checked_out,' - . 'a.checked_out_time AS checked_out_time,' - . 'a.catid AS catid,' - . 'a.clicks AS clicks,' - . 'a.metakey AS metakey,' - . 'a.sticky AS sticky,' - . 'a.impmade AS impmade,' - . 'a.imptotal AS imptotal,' - . 'a.state AS state,' - . 'a.ordering AS ordering,' - . 'a.purchase_type AS purchase_type,' - . 'a.language,' - . 'a.publish_up,' - . 'a.publish_down' - ) - ); - $query->from($db->quoteName('#__banners', 'a')); - - // Join over the language - $query->select('l.title AS language_title, l.image AS language_image') - ->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON l.lang_code = a.language'); - - // Join over the users for the checked out user. - $query->select($db->quoteName('uc.name', 'editor')) - ->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON uc.id = a.checked_out'); - - // Join over the categories. - $query->select($db->quoteName('c.title', 'category_title')) - ->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON c.id = a.catid'); - - // Join over the clients. - $query->select($db->quoteName('cl.name', 'client_name')) - ->select($db->quoteName('cl.purchase_type', 'client_purchase_type')) - ->join('LEFT', $db->quoteName('#__banner_clients', 'cl') . ' ON cl.id = a.cid'); - - // Filter by published state - $published = $this->getState('filter.published'); - - if (is_numeric($published)) - { - $query->where($db->quoteName('a.state') . ' = ' . (int) $published); - } - elseif ($published === '') - { - $query->where($db->quoteName('a.state') . ' IN (0, 1)'); - } - - // Filter by category. - $categoryId = $this->getState('filter.category_id'); - - if (is_numeric($categoryId)) - { - $query->where($db->quoteName('a.catid') . ' = ' . (int) $categoryId); - } - - // Filter by client. - $clientId = $this->getState('filter.client_id'); - - if (is_numeric($clientId)) - { - $query->where($db->quoteName('a.cid') . ' = ' . (int) $clientId); - } - - // Filter by search in title - $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('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('(a.name LIKE ' . $search . ' OR a.alias LIKE ' . $search . ')'); - } - } - - // Filter on the language. - if ($language = $this->getState('filter.language')) - { - $query->where($db->quoteName('a.language') . ' = ' . $db->quote($language)); - } - - // Filter on the level. - if ($level = $this->getState('filter.level')) - { - $query->where($db->quoteName('c.level') . ' <= ' . (int) $level); - } - - // Add the list ordering clause. - $orderCol = $this->state->get('list.ordering', 'a.name'); - $orderDirn = $this->state->get('list.direction', 'ASC'); - - if ($orderCol == 'a.ordering' || $orderCol == 'category_title') - { - $orderCol = 'c.title ' . $orderDirn . ', a.ordering'; - } - - if ($orderCol == 'client_name') - { - $orderCol = 'cl.name'; - } - - $query->order($db->escape($orderCol . ' ' . $orderDirn)); - - 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 A store id. - * - * @since 1.6 - */ - 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 .= ':' . $this->getState('filter.client_id'); - $id .= ':' . $this->getState('filter.language'); - $id .= ':' . $this->getState('filter.level'); - - return parent::getStoreId($id); - } - - /** - * Returns a reference to the a Table object, always creating it. - * - * @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 JTable object - * - * @since 1.6 - */ - public function getTable($type = 'Banner', $prefix = 'BannersTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * 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 1.6 - */ - protected function populateState($ordering = 'a.name', $direction = 'asc') - { - // Load the filter state. - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.published', $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string')); - $this->setState('filter.category_id', $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', '', 'cmd')); - $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', '', 'cmd')); - $this->setState('filter.language', $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', '', 'string')); - $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); - - // Load the parameters. - $this->setState('params', JComponentHelper::getParams('com_banners')); - - // List state information. - parent::populateState($ordering, $direction); - } -} diff --git a/administrator/components/com_banners/models/client.php b/administrator/components/com_banners/models/client.php deleted file mode 100644 index 557784839b37f..0000000000000 --- a/administrator/components/com_banners/models/client.php +++ /dev/null @@ -1,152 +0,0 @@ -id)) - { - 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 $user->authorise('core.delete', 'com_banners'); - } - } - - /** - * 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 1.6 - */ - protected function canEditState($record) - { - $user = JFactory::getUser(); - - if (!empty($record->catid)) - { - return $user->authorise('core.edit.state', 'com_banners.category.' . (int) $record->catid); - } - - return $user->authorise('core.edit.state', 'com_banners'); - } - - /** - * Returns a reference to the a Table object, always creating it. - * - * @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 JTable object - * - * @since 1.6 - */ - public function getTable($type = 'Client', $prefix = 'BannersTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Method to get the record form. - * - * @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 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - // Get the form. - $form = $this->loadForm('com_banners.client', 'client', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_banners.edit.client.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - $this->preprocessData('com_banners.client', $data); - - return $data; - } - - /** - * Prepare and sanitise the table prior to saving. - * - * @param JTable $table A JTable object. - * - * @return void - * - * @since 1.6 - */ - protected function prepareTable($table) - { - $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); - } -} diff --git a/administrator/components/com_banners/models/clients.php b/administrator/components/com_banners/models/clients.php deleted file mode 100644 index 5908ecf8f5ba7..0000000000000 --- a/administrator/components/com_banners/models/clients.php +++ /dev/null @@ -1,309 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string')); - $this->setState('filter.purchase_type', $this->getUserStateFromRequest($this->context . '.filter.purchase_type', 'filter_purchase_type')); - - // Load the parameters. - $this->setState('params', JComponentHelper::getParams('com_banners')); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.state'); - $id .= ':' . $this->getState('filter.purchase_type'); - - return parent::getStoreId($id); - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - */ - protected function getListQuery() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - - $defaultPurchase = JComponentHelper::getParams('com_banners')->get('purchase_type', 3); - - // Select the required fields from the table. - $query->select( - $this->getState( - 'list.select', - 'a.id AS id,' - . 'a.name AS name,' - . 'a.contact AS contact,' - . 'a.checked_out AS checked_out,' - . 'a.checked_out_time AS checked_out_time, ' - . 'a.state AS state,' - . 'a.metakey AS metakey,' - . 'a.purchase_type as purchase_type' - ) - ); - - $query->from($db->quoteName('#__banner_clients') . ' AS a'); - - // Join over the banners for counting - $query->select('COUNT(b.id) as nbanners') - ->join('LEFT', '#__banners AS b ON a.id = b.cid'); - - // Join over the users for the checked out user. - $query->select('uc.name AS editor') - ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); - - // Filter by published state - $published = $this->getState('filter.state'); - - if (is_numeric($published)) - { - $query->where('a.state = ' . (int) $published); - } - elseif ($published === '') - { - $query->where('(a.state IN (0, 1))'); - } - - $query->group('a.id, a.name, a.contact, a.checked_out, a.checked_out_time, a.state, a.metakey, a.purchase_type, uc.name'); - - // Filter by search in title - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('a.name LIKE ' . $search); - } - } - - // Filter by purchase type - $purchaseType = $this->getState('filter.purchase_type'); - - if (!empty($purchaseType)) - { - if ($defaultPurchase == $purchaseType) - { - $query->where('(a.purchase_type = ' . (int) $purchaseType . ' OR a.purchase_type = -1)'); - } - else - { - $query->where('a.purchase_type = ' . (int) $purchaseType); - } - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.name')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - return $query; - } - - /** - * Overrides the getItems method to attach additional metrics to the list. - * - * @return mixed An array of data items on success, false on failure. - * - * @since 3.6 - */ - public function getItems() - { - // Get a storage key. - $store = $this->getStoreId('getItems'); - - // Try to load the data from internal storage. - if (!empty($this->cache[$store])) - { - return $this->cache[$store]; - } - - // Load the list items. - $items = parent::getItems(); - - // If emtpy or an error, just return. - if (empty($items)) - { - return array(); - } - - // Getting the following metric by joins is WAY TOO SLOW. - // Faster to do three queries for very large banner trees. - - // Get the clients in the list. - $db = $this->getDbo(); - $clientIds = ArrayHelper::getColumn($items, 'id'); - - // Quote the strings. - $clientIds = implode( - ',', - array_map(array($db, 'quote'), $clientIds) - ); - - // Get the published banners count. - $query = $db->getQuery(true) - ->select('cid, COUNT(cid) AS count_published') - ->from('#__banners') - ->where('state = 1') - ->where('cid IN (' . $clientIds . ')') - ->group('cid'); - - $db->setQuery($query); - - try - { - $countPublished = $db->loadAssocList('cid', 'count_published'); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Get the unpublished banners count. - $query->clear('where') - ->where('state = 0') - ->where('cid IN (' . $clientIds . ')'); - $db->setQuery($query); - - try - { - $countUnpublished = $db->loadAssocList('cid', 'count_published'); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Get the trashed banners count. - $query->clear('where') - ->where('state = -2') - ->where('cid IN (' . $clientIds . ')'); - $db->setQuery($query); - - try - { - $countTrashed = $db->loadAssocList('cid', 'count_published'); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Get the archived banners count. - $query->clear('where') - ->where('state = 2') - ->where('cid IN (' . $clientIds . ')'); - $db->setQuery($query); - - try - { - $countArchived = $db->loadAssocList('cid', 'count_published'); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Inject the values back into the array. - foreach ($items as $item) - { - $item->count_published = isset($countPublished[$item->id]) ? $countPublished[$item->id] : 0; - $item->count_unpublished = isset($countUnpublished[$item->id]) ? $countUnpublished[$item->id] : 0; - $item->count_trashed = isset($countTrashed[$item->id]) ? $countTrashed[$item->id] : 0; - $item->count_archived = isset($countArchived[$item->id]) ? $countArchived[$item->id] : 0; - } - - // Add the items to the internal cache. - $this->cache[$store] = $items; - - return $this->cache[$store]; - } -} diff --git a/administrator/components/com_banners/models/download.php b/administrator/components/com_banners/models/download.php deleted file mode 100644 index ad6d613c0cd71..0000000000000 --- a/administrator/components/com_banners/models/download.php +++ /dev/null @@ -1,84 +0,0 @@ -input; - - $this->setState('basename', $input->cookie->getString(JApplicationHelper::getHash($this->_context . '.basename'), '__SITE__')); - $this->setState('compressed', $input->cookie->getInt(JApplicationHelper::getHash($this->_context . '.compressed'), 1)); - } - - /** - * Method to get the record form. - * - * @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 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - // Get the form. - $form = $this->loadForm('com_banners.download', 'download', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - $data = array( - 'basename' => $this->getState('basename'), - 'compressed' => $this->getState('compressed'), - ); - - $this->preprocessData('com_banners.download', $data); - - return $data; - } -} diff --git a/administrator/components/com_banners/models/fields/bannerclient.php b/administrator/components/com_banners/models/fields/bannerclient.php deleted file mode 100644 index 9fa42f3c31b1e..0000000000000 --- a/administrator/components/com_banners/models/fields/bannerclient.php +++ /dev/null @@ -1,42 +0,0 @@ -id . '\').value=\'0\';"'; - - return ' ' - . ' ' . JText::_('COM_BANNERS_RESET_CLICKS') . ''; - } -} diff --git a/administrator/components/com_banners/models/fields/impmade.php b/administrator/components/com_banners/models/fields/impmade.php deleted file mode 100644 index 6c2f9ea3f8212..0000000000000 --- a/administrator/components/com_banners/models/fields/impmade.php +++ /dev/null @@ -1,42 +0,0 @@ -id . '\').value=\'0\';"'; - - return ' ' - . ' ' . JText::_('COM_BANNERS_RESET_IMPMADE') . ''; - } -} diff --git a/administrator/components/com_banners/models/fields/imptotal.php b/administrator/components/com_banners/models/fields/imptotal.php deleted file mode 100644 index f0ce87ee802e0..0000000000000 --- a/administrator/components/com_banners/models/fields/imptotal.php +++ /dev/null @@ -1,49 +0,0 @@ -id . '_unlimited\').checked=document.getElementById(\'' . $this->id - . '\').value==\'\';"'; - $onclick = ' onclick="if (document.getElementById(\'' . $this->id . '_unlimited\').checked) document.getElementById(\'' . $this->id - . '\').value=\'\';"'; - $value = empty($this->value) ? '' : $this->value; - $checked = empty($this->value) ? ' checked="checked"' : ''; - - return '' - . '
' - . '
'; - } -} diff --git a/administrator/components/com_banners/models/tracks.php b/administrator/components/com_banners/models/tracks.php deleted file mode 100644 index 273f635cc11bd..0000000000000 --- a/administrator/components/com_banners/models/tracks.php +++ /dev/null @@ -1,542 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.category_id', $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', '', 'cmd')); - $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', '', 'cmd')); - $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'cmd')); - $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); - $this->setState('filter.begin', $this->getUserStateFromRequest($this->context . '.filter.begin', 'filter_begin', '', 'string')); - $this->setState('filter.end', $this->getUserStateFromRequest($this->context . '.filter.end', 'filter_end', '', 'string')); - - // Load the parameters. - $this->setState('params', JComponentHelper::getParams('com_banners')); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - * - * @since 1.6 - */ - protected function getListQuery() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - - // Select the required fields from the table. - $query->select($db->quoteName(array('a.track_date', 'a.track_type', 'a.count'))) - ->select($db->quoteName('b.name', 'banner_name')) - ->select($db->quoteName('cl.name', 'client_name')) - ->select($db->quoteName('c.title', 'category_title')); - - // From tracks table. - $query->from($db->quoteName('#__banner_tracks', 'a')); - - // Join with the banners. - $query->join('LEFT', $db->quoteName('#__banners', 'b') . ' ON ' . $db->quoteName('b.id') . ' = ' . $db->quoteName('a.banner_id')); - - // Join with the client. - $query->join('LEFT', $db->quoteName('#__banner_clients', 'cl') . ' ON ' . $db->quoteName('cl.id') . ' = ' . $db->quoteName('b.cid')); - - // Join with the category. - $query->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('b.catid')); - - // Filter by type. - $type = $this->getState('filter.type'); - - if (!empty($type)) - { - $query->where($db->quoteName('a.track_type') . ' = ' . (int) $type); - } - - // Filter by client. - $clientId = $this->getState('filter.client_id'); - - if (is_numeric($clientId)) - { - $query->where($db->quoteName('b.cid') . ' = ' . (int) $clientId); - } - - // Filter by category. - $categoryId = $this->getState('filter.category_id'); - - if (is_numeric($categoryId)) - { - $query->where($db->quoteName('b.catid') . ' = ' . (int) $categoryId); - } - - // Filter by begin date. - - $begin = $this->getState('filter.begin'); - - if (!empty($begin)) - { - $query->where($db->quoteName('a.track_date') . ' >= ' . $db->quote($begin)); - } - - // Filter by end date. - $end = $this->getState('filter.end'); - - if (!empty($end)) - { - $query->where($db->quoteName('a.track_date') . ' <= ' . $db->quote($end)); - } - - // Filter on the level. - if ($level = $this->getState('filter.level')) - { - $query->where($db->quoteName('c.level') . ' <= ' . (int) $level); - } - - // Filter by search in banner name or client name. - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - $search = $db->quote('%' . strtolower($search) . '%'); - $query->where('(LOWER(b.name) LIKE ' . $search . ' OR LOWER(cl.name) LIKE ' . $search . ')'); - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'b.name')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - return $query; - } - - /** - * Method to delete rows. - * - * @return boolean Returns true on success, false on failure. - */ - public function delete() - { - $user = JFactory::getUser(); - $categoryId = $this->getState('category_id'); - - // Access checks. - if ($categoryId) - { - $allow = $user->authorise('core.delete', 'com_banners.category.' . (int) $categoryId); - } - else - { - $allow = $user->authorise('core.delete', 'com_banners'); - } - - if ($allow) - { - // Delete tracks from this banner - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->delete($db->quoteName('#__banner_tracks')); - - // Filter by type - $type = $this->getState('filter.type'); - - if (!empty($type)) - { - $query->where('track_type = ' . (int) $type); - } - - // Filter by begin date - $begin = $this->getState('filter.begin'); - - if (!empty($begin)) - { - $query->where('track_date >= ' . $db->quote($begin)); - } - - // Filter by end date - $end = $this->getState('filter.end'); - - if (!empty($end)) - { - $query->where('track_date <= ' . $db->quote($end)); - } - - $where = '1'; - - // Filter by client - $clientId = $this->getState('filter.client_id'); - - if (!empty($clientId)) - { - $where .= ' AND cid = ' . (int) $clientId; - } - - // Filter by category - if (!empty($categoryId)) - { - $where .= ' AND catid = ' . (int) $categoryId; - } - - $query->where('banner_id IN (SELECT id FROM ' . $db->quoteName('#__banners') . ' WHERE ' . $where . ')'); - - $db->setQuery($query); - $this->setError((string) $query); - - try - { - $db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - } - else - { - JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); - } - - return true; - } - - /** - * Get file name - * - * @return string The file name - * - * @since 1.6 - */ - public function getBaseName() - { - if (!isset($this->basename)) - { - $basename = str_replace('__SITE__', JFactory::getApplication()->get('sitename'), $this->getState('basename')); - $categoryId = $this->getState('filter.category_id'); - - if (is_numeric($categoryId)) - { - if ($categoryId > 0) - { - $basename = str_replace('__CATID__', $categoryId, $basename); - } - else - { - $basename = str_replace('__CATID__', '', $basename); - } - - $categoryName = $this->getCategoryName(); - $basename = str_replace('__CATNAME__', $categoryName, $basename); - } - else - { - $basename = str_replace(array('__CATID__', '__CATNAME__'), '', $basename); - } - - $clientId = $this->getState('filter.client_id'); - - if (is_numeric($clientId)) - { - if ($clientId > 0) - { - $basename = str_replace('__CLIENTID__', $clientId, $basename); - } - else - { - $basename = str_replace('__CLIENTID__', '', $basename); - } - - $clientName = $this->getClientName(); - $basename = str_replace('__CLIENTNAME__', $clientName, $basename); - } - else - { - $basename = str_replace(array('__CLIENTID__', '__CLIENTNAME__'), '', $basename); - } - - $type = $this->getState('filter.type'); - - if ($type > 0) - { - $basename = str_replace('__TYPE__', $type, $basename); - $typeName = JText::_('COM_BANNERS_TYPE' . $type); - $basename = str_replace('__TYPENAME__', $typeName, $basename); - } - else - { - $basename = str_replace(array('__TYPE__', '__TYPENAME__'), '', $basename); - } - - $begin = $this->getState('filter.begin'); - - if (!empty($begin)) - { - $basename = str_replace('__BEGIN__', $begin, $basename); - } - else - { - $basename = str_replace('__BEGIN__', '', $basename); - } - - $end = $this->getState('filter.end'); - - if (!empty($end)) - { - $basename = str_replace('__END__', $end, $basename); - } - else - { - $basename = str_replace('__END__', '', $basename); - } - - $this->basename = $basename; - } - - return $this->basename; - } - - /** - * Get the category name. - * - * @return string The category name - * - * @since 1.6 - */ - protected function getCategoryName() - { - $categoryId = $this->getState('filter.category_id'); - - if ($categoryId) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('title') - ->from($db->quoteName('#__categories')) - ->where($db->quoteName('id') . '=' . $db->quote($categoryId)); - $db->setQuery($query); - - try - { - $name = $db->loadResult(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - return $name; - } - - return JText::_('COM_BANNERS_NOCATEGORYNAME'); - } - - /** - * Get the category name - * - * @return string The category name. - * - * @since 1.6 - */ - protected function getClientName() - { - $clientId = $this->getState('filter.client_id'); - - if ($clientId) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('name') - ->from($db->quoteName('#__banner_clients')) - ->where($db->quoteName('id') . '=' . $db->quote($clientId)); - $db->setQuery($query); - - try - { - $name = $db->loadResult(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - return $name; - } - - return JText::_('COM_BANNERS_NOCLIENTNAME'); - } - - /** - * Get the file type. - * - * @return string The file type - * - * @since 1.6 - */ - public function getFileType() - { - return $this->getState('compressed') ? 'zip' : 'csv'; - } - - /** - * Get the mime type. - * - * @return string The mime type. - * - * @since 1.6 - */ - public function getMimeType() - { - return $this->getState('compressed') ? 'application/zip' : 'text/csv'; - } - - /** - * Get the content - * - * @return string The content. - * - * @since 1.6 - */ - public function getContent() - { - if (!isset($this->content)) - { - $this->content = '"' . str_replace('"', '""', JText::_('COM_BANNERS_HEADING_NAME')) . '","' - . str_replace('"', '""', JText::_('COM_BANNERS_HEADING_CLIENT')) . '","' - . str_replace('"', '""', JText::_('JCATEGORY')) . '","' - . str_replace('"', '""', JText::_('COM_BANNERS_HEADING_TYPE')) . '","' - . str_replace('"', '""', JText::_('COM_BANNERS_HEADING_COUNT')) . '","' - . str_replace('"', '""', JText::_('JDATE')) . '"' . "\n"; - - foreach ($this->getItems() as $item) - { - $this->content .= '"' . str_replace('"', '""', $item->banner_name) . '","' - . str_replace('"', '""', $item->client_name) . '","' - . str_replace('"', '""', $item->category_title) . '","' - . str_replace('"', '""', ($item->track_type == 1 ? JText::_('COM_BANNERS_IMPRESSION') : JText::_('COM_BANNERS_CLICK'))) . '","' - . str_replace('"', '""', $item->count) . '","' - . str_replace('"', '""', $item->track_date) . '"' . "\n"; - } - - if ($this->getState('compressed')) - { - $app = JFactory::getApplication('administrator'); - - $files = array( - 'track' => array( - 'name' => $this->getBasename() . '.csv', - 'data' => $this->content, - 'time' => time() - ) - ); - $ziproot = $app->get('tmp_path') . '/' . uniqid('banners_tracks_') . '.zip'; - - // Run the packager - jimport('joomla.filesystem.folder'); - jimport('joomla.filesystem.file'); - $delete = JFolder::files($app->get('tmp_path') . '/', uniqid('banners_tracks_'), false, true); - - if (!empty($delete)) - { - if (!JFile::delete($delete)) - { - // JFile::delete throws an error - $this->setError(JText::_('COM_BANNERS_ERR_ZIP_DELETE_FAILURE')); - - return false; - } - } - - $archive = new Archive; - - if (!$packager = $archive->getAdapter('zip')) - { - $this->setError(JText::_('COM_BANNERS_ERR_ZIP_ADAPTER_FAILURE')); - - return false; - } - elseif (!$packager->create($ziproot, $files)) - { - $this->setError(JText::_('COM_BANNERS_ERR_ZIP_CREATE_FAILURE')); - - return false; - } - - $this->content = file_get_contents($ziproot); - } - } - - return $this->content; - } -} diff --git a/administrator/components/com_banners/services/provider.php b/administrator/components/com_banners/services/provider.php new file mode 100644 index 0000000000000..1c90d0ebc36fc --- /dev/null +++ b/administrator/components/com_banners/services/provider.php @@ -0,0 +1,61 @@ +set(Categories::class, ['' => new Category]); + + $container->registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Banners')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Banners')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new BannersComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setRegistry($container->get(Registry::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + $component->setCategories($container->get(Categories::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_banners/tables/banner.php b/administrator/components/com_banners/tables/banner.php deleted file mode 100644 index eadd70c12f4b7..0000000000000 --- a/administrator/components/com_banners/tables/banner.php +++ /dev/null @@ -1,329 +0,0 @@ - 'com_banners.banner')); - - $this->created = JFactory::getDate()->toSql(); - $this->setColumnAlias('published', 'state'); - } - - /** - * Increase click count - * - * @return void - */ - public function clicks() - { - $query = 'UPDATE #__banners' - . ' SET clicks = (clicks + 1)' - . ' WHERE id = ' . (int) $this->id; - - $this->_db->setQuery($query); - $this->_db->execute(); - } - - /** - * Overloaded check function - * - * @return boolean - * - * @see JTable::check - * @since 1.5 - */ - public function check() - { - // Set name - $this->name = htmlspecialchars_decode($this->name, ENT_QUOTES); - - // Set alias - if (trim($this->alias) == '') - { - $this->alias = $this->name; - } - - $this->alias = JApplicationHelper::stringURLSafe($this->alias, $this->language); - - if (trim(str_replace('-', '', $this->alias)) == '') - { - $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); - } - - // Check the publish down date is not earlier than publish up. - if ($this->publish_down > $this->_db->getNullDate() && $this->publish_down < $this->publish_up) - { - $this->setError(JText::_('JGLOBAL_START_PUBLISH_AFTER_FINISH')); - - return false; - } - - // Set ordering - if ($this->state < 0) - { - // Set ordering to 0 if state is archived or trashed - $this->ordering = 0; - } - elseif (empty($this->ordering)) - { - // Set ordering to last if ordering was 0 - $this->ordering = self::getNextOrder($this->_db->quoteName('catid') . '=' . $this->_db->quote($this->catid) . ' AND state>=0'); - } - - if (empty($this->publish_up)) - { - $this->publish_up = $this->getDbo()->getNullDate(); - } - - if (empty($this->publish_down)) - { - $this->publish_down = $this->getDbo()->getNullDate(); - } - - if (empty($this->modified)) - { - $this->modified = $this->getDbo()->getNullDate(); - } - - return true; - } - - /** - * Overloaded bind function - * - * @param mixed $array An associative array or object to bind to the JTable instance. - * @param mixed $ignore An optional array or space separated list of properties to ignore while binding. - * - * @return boolean True on success - * - * @since 1.5 - */ - public function bind($array, $ignore = array()) - { - if (isset($array['params']) && is_array($array['params'])) - { - $registry = new Registry($array['params']); - - if ((int) $registry->get('width', 0) < 0) - { - $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_NEGATIVE_NOT_PERMITTED', JText::_('COM_BANNERS_FIELD_WIDTH_LABEL'))); - - return false; - } - - if ((int) $registry->get('height', 0) < 0) - { - $this->setError(JText::sprintf('JLIB_DATABASE_ERROR_NEGATIVE_NOT_PERMITTED', JText::_('COM_BANNERS_FIELD_HEIGHT_LABEL'))); - - return false; - } - - // Converts the width and height to an absolute numeric value: - $width = abs((int) $registry->get('width', 0)); - $height = abs((int) $registry->get('height', 0)); - - // Sets the width and height to an empty string if = 0 - $registry->set('width', $width ?: ''); - $registry->set('height', $height ?: ''); - - $array['params'] = (string) $registry; - } - - if (isset($array['imptotal'])) - { - $array['imptotal'] = abs((int) $array['imptotal']); - } - - return parent::bind($array, $ignore); - } - - /** - * Method to store a row - * - * @param boolean $updateNulls True to update fields even if they are null. - * - * @return boolean True on success, false on failure. - */ - public function store($updateNulls = false) - { - $db = $this->getDbo(); - - if (empty($this->id)) - { - $purchaseType = $this->purchase_type; - - if ($purchaseType < 0 && $this->cid) - { - /** @var BannersTableClient $client */ - $client = JTable::getInstance('Client', 'BannersTable', array('dbo' => $db)); - $client->load($this->cid); - $purchaseType = $client->purchase_type; - } - - if ($purchaseType < 0) - { - $purchaseType = JComponentHelper::getParams('com_banners')->get('purchase_type'); - } - - switch ($purchaseType) - { - case 1: - $this->reset = $this->_db->getNullDate(); - break; - case 2: - $date = JFactory::getDate('+1 year ' . date('Y-m-d')); - $this->reset = $date->toSql(); - break; - case 3: - $date = JFactory::getDate('+1 month ' . date('Y-m-d')); - $this->reset = $date->toSql(); - break; - case 4: - $date = JFactory::getDate('+7 day ' . date('Y-m-d')); - $this->reset = $date->toSql(); - break; - case 5: - $date = JFactory::getDate('+1 day ' . date('Y-m-d')); - $this->reset = $date->toSql(); - break; - } - - // Store the row - parent::store($updateNulls); - } - else - { - // Get the old row - /** @var BannersTableBanner $oldrow */ - $oldrow = JTable::getInstance('Banner', 'BannersTable', array('dbo' => $db)); - - if (!$oldrow->load($this->id) && $oldrow->getError()) - { - $this->setError($oldrow->getError()); - } - - // Verify that the alias is unique - /** @var BannersTableBanner $table */ - $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)) - { - $this->setError(JText::_('COM_BANNERS_ERROR_UNIQUE_ALIAS')); - - return false; - } - - // Store the new row - parent::store($updateNulls); - - // Need to reorder ? - if ($oldrow->state >= 0 && ($this->state < 0 || $oldrow->catid != $this->catid)) - { - // Reorder the oldrow - $this->reorder($this->_db->quoteName('catid') . '=' . $this->_db->quote($oldrow->catid) . ' AND state>=0'); - } - } - - return count($this->getErrors()) == 0; - } - - /** - * Method to set the sticky state for a row or list of rows in the database - * table. The method respects checked out rows by other users and will attempt - * to checkin rows that it can after adjustments are made. - * - * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. - * @param integer $state The sticky state. eg. [0 = unsticked, 1 = sticked] - * @param integer $userId The user id of the user performing the operation. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function stick($pks = null, $state = 1, $userId = 0) - { - $k = $this->_tbl_key; - - // Sanitize input. - $pks = ArrayHelper::toInteger($pks); - $userId = (int) $userId; - $state = (int) $state; - - // If there are no primary keys set check to see if the instance key is set. - if (empty($pks)) - { - if ($this->$k) - { - $pks = array($this->$k); - } - // Nothing to set publishing state on, return false. - else - { - $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); - - return false; - } - } - - // Get an instance of the table - /** @var BannersTableBanner $table */ - $table = JTable::getInstance('Banner', 'BannersTable'); - - // For all keys - foreach ($pks as $pk) - { - // Load the banner - if (!$table->load($pk)) - { - $this->setError($table->getError()); - } - - // Verify checkout - if ($table->checked_out == 0 || $table->checked_out == $userId) - { - // Change the state - $table->sticky = $state; - $table->checked_out = 0; - $table->checked_out_time = $this->_db->getNullDate(); - - // Check the row - $table->check(); - - // Store the row - if (!$table->store()) - { - $this->setError($table->getError()); - } - } - } - - return count($this->getErrors()) == 0; - } -} diff --git a/administrator/components/com_banners/tables/client.php b/administrator/components/com_banners/tables/client.php deleted file mode 100644 index fe8a820488abf..0000000000000 --- a/administrator/components/com_banners/tables/client.php +++ /dev/null @@ -1,126 +0,0 @@ -checked_out_time = $db->getNullDate(); - parent::__construct('#__banner_clients', 'id', $db); - - JTableObserverContenthistory::createObserver($this, array('typeAlias' => 'com_banners.client')); - } - - /** - * Method to set the publishing state for a row or list of rows in the database - * table. The method respects checked out rows by other users and will attempt - * to checkin rows that it can after adjustments are made. - * - * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. - * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published, 2=archived, -2=trashed] - * @param integer $userId The user id of the user performing the operation. - * - * @return boolean True on success. - * - * @since 1.0.4 - */ - public function publish($pks = null, $state = 1, $userId = 0) - { - $k = $this->_tbl_key; - - // Sanitize input. - $pks = ArrayHelper::toInteger($pks); - $userId = (int) $userId; - $state = (int) $state; - - // If there are no primary keys set check to see if the instance key is set. - if (empty($pks)) - { - if ($this->$k) - { - $pks = array($this->$k); - } - // Nothing to set publishing state on, return false. - else - { - $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); - - return false; - } - } - - // Build the WHERE clause for the primary keys. - $where = $k . '=' . implode(' OR ' . $k . '=', $pks); - - // Determine if there is checkin support for the table. - if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) - { - $checkin = ''; - } - else - { - $checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')'; - } - - // Update the publishing state for rows with the given primary keys. - $this->_db->setQuery( - 'UPDATE ' . $this->_db->quoteName($this->_tbl) - . ' SET ' . $this->_db->quoteName('state') . ' = ' . (int) $state - . ' WHERE (' . $where . ')' - . $checkin - ); - - try - { - $this->_db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // If checkin is supported and all rows were adjusted, check them in. - if ($checkin && (count($pks) == $this->_db->getAffectedRows())) - { - // Checkin the rows. - foreach ($pks as $pk) - { - $this->checkin($pk); - } - } - - // If the JTable instance value is in the list of primary keys that were set, set the instance. - if (in_array($this->$k, $pks)) - { - $this->state = $state; - } - - $this->setError(''); - - return true; - } -} diff --git a/administrator/components/com_banners/tmpl/banner/edit.php b/administrator/components/com_banners/tmpl/banner/edit.php new file mode 100644 index 0000000000000..0e4b5db2e18ec --- /dev/null +++ b/administrator/components/com_banners/tmpl/banner/edit.php @@ -0,0 +1,78 @@ + 0 )); + +HTMLHelper::_('script', 'com_banners/admin-banner-edit.min.js', array('version' => 'auto', 'relative' => true)); +?> + + + + + +
+ 'details')); ?> + + +
+
+ form->renderField('type'); ?> +
+ form->renderFieldset('image'); ?> +
+
+ form->renderField('custombannercode'); ?> +
+ form->renderField('clickurl'); + echo $this->form->renderField('description'); + ?> +
+
+
+
+ +
+
+
+
+ + + + form->renderFieldset('otherparams'); ?> + + + +
+
+ +
+
+ form->renderFieldset('metadata'); ?> +
+
+ + + +
+ + + + diff --git a/administrator/components/com_banners/tmpl/banners/default.php b/administrator/components/com_banners/tmpl/banners/default.php new file mode 100644 index 0000000000000..84ed9e0ffd37c --- /dev/null +++ b/administrator/components/com_banners/tmpl/banners/default.php @@ -0,0 +1,198 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; + +if ($saveOrder && !empty($this->items)) +{ + $saveOrderingUrl = 'index.php?option=com_banners&task=banners.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); + ?> + items)) : ?> + + + + + + + + + + + + + + + + + + + + class="js-draggable" data-url="" data-direction="" data-nested="true"> + items as $i => $item) : + $ordering = ($listOrder == 'ordering'); + $item->cat_link = Route::_('index.php?option=com_categories&extension=com_banners&task=edit&type=other&cid[]=' . $item->catid); + $canCreate = $user->authorise('core.create', 'com_banners.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_banners.category.' . $item->catid); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_banners.category.' . $item->catid) && $canCheckin; + ?> + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + id); ?> + +
+ state, $i, 'banners.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> +
+
+
+ checked_out) : ?> + editor, $item->checked_out_time, 'banners.', $canCheckin); ?> + + + checked_out ? '' : ''; ?> + + escape($item->name); ?> + + escape($item->name); ?> + + + escape($item->alias)); ?> + +
+ escape($item->category_title); ?> +
+
+
+ sticky, $i, $canChange); ?> + + client_name; ?> + + impmade, $item->imptotal ?: Text::_('COM_BANNERS_UNLIMITED')); ?> + + clicks; ?> - + impmade ? 100 * $item->clicks / $item->impmade : 0); ?> + + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + authorise('core.create', 'com_banners') + && $user->authorise('core.edit', 'com_banners') + && $user->authorise('core.edit.state', 'com_banners')) : ?> + Text::_('COM_BANNERS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer') + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + +
+
+
+
diff --git a/administrator/components/com_banners/tmpl/banners/default_batch_body.php b/administrator/components/com_banners/tmpl/banners/default_batch_body.php new file mode 100644 index 0000000000000..ec469e39ed751 --- /dev/null +++ b/administrator/components/com_banners/tmpl/banners/default_batch_body.php @@ -0,0 +1,40 @@ +state->get('filter.published'); +?> + + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ = 0) : ?> +
+
+ +
+
+ +
+
diff --git a/administrator/components/com_banners/tmpl/banners/default_batch_footer.php b/administrator/components/com_banners/tmpl/banners/default_batch_footer.php new file mode 100644 index 0000000000000..e988e71dcbc01 --- /dev/null +++ b/administrator/components/com_banners/tmpl/banners/default_batch_footer.php @@ -0,0 +1,20 @@ + + + + + diff --git a/administrator/components/com_banners/tmpl/client/edit.php b/administrator/components/com_banners/tmpl/client/edit.php new file mode 100644 index 0000000000000..05b2a94644b6c --- /dev/null +++ b/administrator/components/com_banners/tmpl/client/edit.php @@ -0,0 +1,59 @@ + + +
+ + + +
+ 'general')); ?> + + item->id) ? Text::_('COM_BANNERS_NEW_CLIENT') : Text::_('COM_BANNERS_EDIT_CLIENT')); ?> +
+
+ form->renderField('contact'); + echo $this->form->renderField('email'); + echo $this->form->renderField('purchase_type'); + echo $this->form->renderField('track_impressions'); + echo $this->form->renderField('track_clicks'); + echo $this->form->renderFieldset('extra'); + ?> +
+
+
+
+ +
+
+
+
+ + + + form->renderFieldset('metadata'); ?> + + + +
+ + + +
diff --git a/administrator/components/com_banners/tmpl/clients/default.php b/administrator/components/com_banners/tmpl/clients/default.php new file mode 100644 index 0000000000000..71c893a5ce187 --- /dev/null +++ b/administrator/components/com_banners/tmpl/clients/default.php @@ -0,0 +1,168 @@ + 'UNLIMITED', + '2' => 'YEARLY', + '3' => 'MONTHLY', + '4' => 'WEEKLY', + '5' => 'DAILY', +); + +$user = Factory::getUser(); +$userId = $user->get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$params = $this->state->params ?? new JObject; +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); + ?> + items)) : ?> + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_banners'); + $canEdit = $user->authorise('core.edit', 'com_banners'); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_banners') && $canCheckin; + ?> + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ id); ?> + +
+ state, $i, 'clients.', $canChange); ?> +
+
+
+ checked_out) : ?> + editor, $item->checked_out_time, 'clients.', $canCheckin); ?> + + + checked_out ? '' : ''; ?> + + escape($item->name); ?> + + escape($item->name); ?> + +
+
+ contact; ?> + + + count_published; ?> + + + count_unpublished; ?> + + + count_archived; ?> + + + count_trashed; ?> + + purchase_type < 0) : ?> + get('purchase_type')])); ?> + + purchase_type]); ?> + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + + +
+
+
+
diff --git a/administrator/components/com_banners/tmpl/download/default.php b/administrator/components/com_banners/tmpl/download/default.php new file mode 100644 index 0000000000000..a72f377977424 --- /dev/null +++ b/administrator/components/com_banners/tmpl/download/default.php @@ -0,0 +1,33 @@ + +
+
+ + form->getFieldset() as $field) : ?> + form->renderField($field->fieldname); ?> + + + +
+
diff --git a/administrator/components/com_banners/tmpl/tracks/default.php b/administrator/components/com_banners/tmpl/tracks/default.php new file mode 100644 index 0000000000000..0dd5a7b53b3e9 --- /dev/null +++ b/administrator/components/com_banners/tmpl/tracks/default.php @@ -0,0 +1,105 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + items)) : ?> + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + +
+ + + + + + + + + +
+ banner_name; ?> +
+ escape($item->category_title); ?> +
+
+ client_name; ?> + + track_type == 1 ? Text::_('COM_BANNERS_IMPRESSION') : Text::_('COM_BANNERS_CLICK'); ?> + + count; ?> + + track_date, Text::_('DATE_FORMAT_LC5')); ?> +
+ + + pagination->getListFooter(); ?> + + + + Text::_('COM_BANNERS_TRACKS_DOWNLOAD'), + 'url' => Route::_('index.php?option=com_banners&view=download&tmpl=component'), + 'height' => '370px', + 'width' => '300px', + 'modalWidth' => '40', + 'footer' => '' + . Text::_('COM_BANNERS_CANCEL') . '' + . '', + ) + ); ?> + + + +
+
+
+
diff --git a/administrator/components/com_banners/views/banner/tmpl/edit.php b/administrator/components/com_banners/views/banner/tmpl/edit.php deleted file mode 100644 index 9d98677a35811..0000000000000 --- a/administrator/components/com_banners/views/banner/tmpl/edit.php +++ /dev/null @@ -1,100 +0,0 @@ - 0 )); -JHtml::_('formbehavior.chosen', 'select'); - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(task) - { - if (task == "banner.cancel" || document.formvalidator.isValid(document.getElementById("banner-form"))) - { - Joomla.submitform(task, document.getElementById("banner-form")); - } - }; - jQuery(document).ready(function ($){ - $("#jform_type").on("change", function (a, params) { - - var v = typeof(params) !== "object" ? $("#jform_type").val() : params.selected; - - var img_url = $("#image, #url"); - var custom = $("#custom"); - - switch (v) { - case "0": - // Image - img_url.show(); - custom.hide(); - break; - case "1": - // Custom - img_url.hide(); - custom.show(); - break; - } - }).trigger("change"); - }); -'); -?> - - diff --git a/administrator/components/com_banners/views/banner/view.html.php b/administrator/components/com_banners/views/banner/view.html.php deleted file mode 100644 index da154a92eb65f..0000000000000 --- a/administrator/components/com_banners/views/banner/view.html.php +++ /dev/null @@ -1,123 +0,0 @@ -form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - - // 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 1.6 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - - $user = JFactory::getUser(); - $userId = $user->id; - $isNew = ($this->item->id == 0); - $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); - - // Since we don't track these assets at the item level, use the category id. - $canDo = JHelperContent::getActions('com_banners', 'category', $this->item->catid); - - JToolbarHelper::title($isNew ? JText::_('COM_BANNERS_MANAGER_BANNER_NEW') : JText::_('COM_BANNERS_MANAGER_BANNER_EDIT'), 'bookmark banners'); - - // If not checked out, can save the item. - if (!$checkedOut && ($canDo->get('core.edit') || count($user->getAuthorisedCategories('com_banners', 'core.create')) > 0)) - { - JToolbarHelper::apply('banner.apply'); - JToolbarHelper::save('banner.save'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::save2new('banner.save2new'); - } - } - - // If an existing item, can save to a copy. - if (!$isNew && $canDo->get('core.create')) - { - JToolbarHelper::save2copy('banner.save2copy'); - } - - if (empty($this->item->id)) - { - JToolbarHelper::cancel('banner.cancel'); - } - else - { - if (JComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $canDo->get('core.edit')) - { - JToolbarHelper::versions('com_banners.banner', $this->item->id); - } - - JToolbarHelper::cancel('banner.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_BANNERS_EDIT'); - } -} diff --git a/administrator/components/com_banners/views/banners/tmpl/default.php b/administrator/components/com_banners/views/banners/tmpl/default.php deleted file mode 100644 index 01d348812c758..0000000000000 --- a/administrator/components/com_banners/views/banners/tmpl/default.php +++ /dev/null @@ -1,195 +0,0 @@ -get('id'); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$saveOrder = $listOrder == 'a.ordering'; - -if ($saveOrder) -{ - $saveOrderingUrl = 'index.php?option=com_banners&task=banners.saveOrderAjax&tmpl=component'; - JHtml::_('sortablelist.sortable', 'articleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); -} -?> -
-
- sidebar; ?> -
-
- $this)); - ?> - items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - - - - items as $i => $item) : - $ordering = ($listOrder == 'ordering'); - $item->cat_link = JRoute::_('index.php?option=com_categories&extension=com_banners&task=edit&type=other&cid[]=' . $item->catid); - $canCreate = $user->authorise('core.create', 'com_banners.category.' . $item->catid); - $canEdit = $user->authorise('core.edit', 'com_banners.category.' . $item->catid); - $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; - $canChange = $user->authorise('core.edit.state', 'com_banners.category.' . $item->catid) && $canCheckin; - ?> - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - - - - - - - id); ?> - -
- state, $i, 'banners.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> - state === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'banners'); - JHtml::_('actionsdropdown.' . ((int) $item->state === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'banners'); - echo JHtml::_('actionsdropdown.render', $this->escape($item->name)); - } - ?> -
-
-
- checked_out) : ?> - editor, $item->checked_out_time, 'banners.', $canCheckin); ?> - - - - escape($item->name); ?> - - escape($item->name); ?> - - - escape($item->alias)); ?> - -
- escape($item->category_title); ?> -
-
-
- sticky, $i, $canChange); ?> - - client_name; ?> - - impmade, $item->imptotal ?: JText::_('COM_BANNERS_UNLIMITED')); ?> - - clicks; ?> - - impmade ? 100 * $item->clicks / $item->impmade : 0); ?> - - - - id; ?> -
- - authorise('core.create', 'com_banners') - && $user->authorise('core.edit', 'com_banners') - && $user->authorise('core.edit.state', 'com_banners')) : ?> - JText::_('COM_BANNERS_BATCH_OPTIONS'), - 'footer' => $this->loadTemplate('batch_footer'), - ), - $this->loadTemplate('batch_body') - ); ?> - - - - - - -
-
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 deleted file mode 100644 index 2bbf95a642b1e..0000000000000 --- a/administrator/components/com_banners/views/banners/tmpl/default_batch_body.php +++ /dev/null @@ -1,37 +0,0 @@ -state->get('filter.published'); -?> - -
-
-
-
- -
-
-
-
- -
-
-
-
- = 0) : ?> -
-
- -
-
- -
-
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 deleted file mode 100644 index 9d985b15e27a2..0000000000000 --- a/administrator/components/com_banners/views/banners/tmpl/default_batch_footer.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/administrator/components/com_banners/views/banners/view.html.php b/administrator/components/com_banners/views/banners/view.html.php deleted file mode 100644 index 322dc269038b4..0000000000000 --- a/administrator/components/com_banners/views/banners/view.html.php +++ /dev/null @@ -1,187 +0,0 @@ -categories = $this->get('CategoryOrders'); - $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); - } - - BannersHelper::addSubmenu('banners'); - - $this->addToolbar(); - - // Include the component HTML helpers. - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - - $this->sidebar = JHtmlSidebar::render(); - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JLoader::register('BannersHelper', JPATH_ADMINISTRATOR . '/components/com_banners/helpers/banners.php'); - - $canDo = JHelperContent::getActions('com_banners', 'category', $this->state->get('filter.category_id')); - $user = JFactory::getUser(); - - JToolbarHelper::title(JText::_('COM_BANNERS_MANAGER_BANNERS'), 'bookmark banners'); - - if (count($user->getAuthorisedCategories('com_banners', 'core.create')) > 0) - { - JToolbarHelper::addNew('banner.add'); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('banner.edit'); - } - - if ($canDo->get('core.edit.state')) - { - if ($this->state->get('filter.published') != 2) - { - JToolbarHelper::publish('banners.publish', 'JTOOLBAR_PUBLISH', true); - JToolbarHelper::unpublish('banners.unpublish', 'JTOOLBAR_UNPUBLISH', true); - } - - if ($this->state->get('filter.published') != -1) - { - if ($this->state->get('filter.published') != 2) - { - JToolbarHelper::archiveList('banners.archive'); - } - elseif ($this->state->get('filter.published') == 2) - { - JToolbarHelper::unarchiveList('banners.publish'); - } - } - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::checkin('banners.checkin'); - } - - // Add a batch button - if ($user->authorise('core.create', 'com_banners') - && $user->authorise('core.edit', 'com_banners') - && $user->authorise('core.edit.state', 'com_banners')) - { - $title = JText::_('JTOOLBAR_BATCH'); - - // Instantiate a new JLayoutFile instance and render the batch button - $layout = new JLayoutFile('joomla.toolbar.batch'); - - $dhtml = $layout->render(array('title' => $title)); - JToolbar::getInstance('toolbar')->appendButton('Custom', $dhtml, 'batch'); - } - - if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'banners.delete', 'JTOOLBAR_EMPTY_TRASH'); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('banners.trash'); - } - - if ($user->authorise('core.admin', 'com_banners') || $user->authorise('core.options', 'com_banners')) - { - JToolbarHelper::preferences('com_banners'); - } - - JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_BANNERS'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'ordering' => JText::_('JGRID_HEADING_ORDERING'), - 'a.state' => JText::_('JSTATUS'), - 'a.name' => JText::_('COM_BANNERS_HEADING_NAME'), - 'a.sticky' => JText::_('COM_BANNERS_HEADING_STICKY'), - 'client_name' => JText::_('COM_BANNERS_HEADING_CLIENT'), - 'impmade' => JText::_('COM_BANNERS_HEADING_IMPRESSIONS'), - 'clicks' => JText::_('COM_BANNERS_HEADING_CLICKS'), - 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), - 'a.id' => JText::_('JGRID_HEADING_ID'), - ); - } -} diff --git a/administrator/components/com_banners/views/client/tmpl/edit.php b/administrator/components/com_banners/views/client/tmpl/edit.php deleted file mode 100644 index 0c55c5c21008b..0000000000000 --- a/administrator/components/com_banners/views/client/tmpl/edit.php +++ /dev/null @@ -1,61 +0,0 @@ -addScriptDeclaration(' - Joomla.submitbutton = function(task) - { - if (task == "client.cancel" || document.formvalidator.isValid(document.getElementById("client-form"))) - { - Joomla.submitform(task, document.getElementById("client-form")); - } - }; -'); -?> - -
- - - -
- 'general')); ?> - - item->id) ? JText::_('COM_BANNERS_NEW_CLIENT') : JText::_('COM_BANNERS_EDIT_CLIENT')); ?> -
-
- form->renderField('contact'); - echo $this->form->renderField('email'); - echo $this->form->renderField('purchase_type'); - echo $this->form->renderField('track_impressions'); - echo $this->form->renderField('track_clicks'); - echo $this->form->renderFieldset('extra'); - ?> -
-
- -
-
- - - - form->renderFieldset('metadata'); ?> - - - -
- - - -
diff --git a/administrator/components/com_banners/views/client/view.html.php b/administrator/components/com_banners/views/client/view.html.php deleted file mode 100644 index 269081b4658b8..0000000000000 --- a/administrator/components/com_banners/views/client/view.html.php +++ /dev/null @@ -1,130 +0,0 @@ -form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - $this->canDo = JHelperContent::getActions('com_banners'); - - // 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 1.6 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - - $user = JFactory::getUser(); - $isNew = ($this->item->id == 0); - $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->id); - $canDo = $this->canDo; - - JToolbarHelper::title( - $isNew ? JText::_('COM_BANNERS_MANAGER_CLIENT_NEW') : JText::_('COM_BANNERS_MANAGER_CLIENT_EDIT'), - 'bookmark banners-clients' - ); - - // If not checked out, can save the item. - if (!$checkedOut && ($canDo->get('core.edit') || $canDo->get('core.create'))) - { - JToolbarHelper::apply('client.apply'); - JToolbarHelper::save('client.save'); - } - - if (!$checkedOut && $canDo->get('core.create')) - { - JToolbarHelper::save2new('client.save2new'); - } - - // If an existing item, can save to a copy. - if (!$isNew && $canDo->get('core.create')) - { - JToolbarHelper::save2copy('client.save2copy'); - } - - if (empty($this->item->id)) - { - JToolbarHelper::cancel('client.cancel'); - } - else - { - if (JComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $canDo->get('core.edit')) - { - JToolbarHelper::versions('com_banners.client', $this->item->id); - } - - JToolbarHelper::cancel('client.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_CLIENTS_EDIT'); - } -} diff --git a/administrator/components/com_banners/views/clients/tmpl/default.php b/administrator/components/com_banners/views/clients/tmpl/default.php deleted file mode 100644 index 210d4de9a9f24..0000000000000 --- a/administrator/components/com_banners/views/clients/tmpl/default.php +++ /dev/null @@ -1,165 +0,0 @@ - 'UNLIMITED', - '2' => 'YEARLY', - '3' => 'MONTHLY', - '4' => 'WEEKLY', - '5' => 'DAILY', -); - -$user = JFactory::getUser(); -$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; -?> -
-
- sidebar; ?> -
-
- $this)); - ?> - items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - - - - items as $i => $item) : - $canCreate = $user->authorise('core.create', 'com_banners'); - $canEdit = $user->authorise('core.edit', 'com_banners'); - $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; - $canChange = $user->authorise('core.edit.state', 'com_banners') && $canCheckin; - ?> - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- id); ?> - -
- state, $i, 'clients.', $canChange); ?> - state === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'clients'); - JHtml::_('actionsdropdown.' . ((int) $item->state === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'clients'); - echo JHtml::_('actionsdropdown.render', $this->escape($item->name)); - } - ?> -
-
-
- checked_out) : ?> - editor, $item->checked_out_time, 'clients.', $canCheckin); ?> - - - - escape($item->name); ?> - - escape($item->name); ?> - -
-
- contact; ?> - - - count_published; ?> - - - count_unpublished; ?> - - - count_archived; ?> - - - count_trashed; ?> - - purchase_type < 0) : ?> - get('purchase_type')])); ?> - - purchase_type]); ?> - - - id; ?> -
- - - - - -
-
diff --git a/administrator/components/com_banners/views/clients/view.html.php b/administrator/components/com_banners/views/clients/view.html.php deleted file mode 100644 index 5d796e522ee20..0000000000000 --- a/administrator/components/com_banners/views/clients/view.html.php +++ /dev/null @@ -1,137 +0,0 @@ -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); - } - - BannersHelper::addSubmenu('clients'); - - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_banners'); - - JToolbarHelper::title(JText::_('COM_BANNERS_MANAGER_CLIENTS'), 'bookmark banners-clients'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('client.add'); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('client.edit'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publish('clients.publish', 'JTOOLBAR_PUBLISH', true); - JToolbarHelper::unpublish('clients.unpublish', 'JTOOLBAR_UNPUBLISH', true); - JToolbarHelper::archiveList('clients.archive'); - JToolbarHelper::checkin('clients.checkin'); - } - - if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'clients.delete', 'JTOOLBAR_EMPTY_TRASH'); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('clients.trash'); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_banners'); - } - - JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_CLIENTS'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'a.status' => JText::_('JSTATUS'), - 'a.name' => JText::_('COM_BANNERS_HEADING_CLIENT'), - 'contact' => JText::_('COM_BANNERS_HEADING_CONTACT'), - 'client_name' => JText::_('COM_BANNERS_HEADING_CLIENT'), - 'nbanners' => JText::_('COM_BANNERS_HEADING_ACTIVE'), - 'a.id' => JText::_('JGRID_HEADING_ID') - ); - } -} diff --git a/administrator/components/com_banners/views/download/tmpl/default.php b/administrator/components/com_banners/views/download/tmpl/default.php deleted file mode 100644 index 89f9aefb020fa..0000000000000 --- a/administrator/components/com_banners/views/download/tmpl/default.php +++ /dev/null @@ -1,37 +0,0 @@ - 'bottom')); -?> -
-
- - form->getFieldset() as $field) : ?> - form->renderField($field->fieldname); ?> - - - - -
-
diff --git a/administrator/components/com_banners/views/download/view.html.php b/administrator/components/com_banners/views/download/view.html.php deleted file mode 100644 index 4b72496970781..0000000000000 --- a/administrator/components/com_banners/views/download/view.html.php +++ /dev/null @@ -1,45 +0,0 @@ -form = $this->get('Form'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - return parent::display($tpl); - } -} diff --git a/administrator/components/com_banners/views/tracks/tmpl/default.php b/administrator/components/com_banners/views/tracks/tmpl/default.php deleted file mode 100644 index a41d327614272..0000000000000 --- a/administrator/components/com_banners/views/tracks/tmpl/default.php +++ /dev/null @@ -1,110 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
-sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> - items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - items as $i => $item) : ?> - - - - - - - - - -
- - - - - - - - - -
- pagination->getListFooter(); ?> -
- banner_name; ?> -
- escape($item->category_title); ?> -
-
- client_name; ?> - - track_type == 1 ? JText::_('COM_BANNERS_IMPRESSION') : JText::_('COM_BANNERS_CLICK'); ?> - - count; ?> - - track_date, JText::_('DATE_FORMAT_LC5')); ?> -
- - - - JText::_('COM_BANNERS_TRACKS_DOWNLOAD'), - 'url' => JRoute::_('index.php?option=com_banners&view=download&tmpl=component'), - 'height' => '370px', - 'width' => '300px', - 'modalWidth' => '40', - 'footer' => '' - . JText::_('COM_BANNERS_CANCEL') . '' - . '', - ) - ); ?> - - - - -
- diff --git a/administrator/components/com_banners/views/tracks/view.html.php b/administrator/components/com_banners/views/tracks/view.html.php deleted file mode 100644 index 768122d6f509a..0000000000000 --- a/administrator/components/com_banners/views/tracks/view.html.php +++ /dev/null @@ -1,134 +0,0 @@ -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); - } - - BannersHelper::addSubmenu('tracks'); - - $this->addToolbar(); - - $this->sidebar = JHtmlSidebar::render(); - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_banners', 'category', $this->state->get('filter.category_id')); - - JToolbarHelper::title(JText::_('COM_BANNERS_MANAGER_TRACKS'), 'bookmark banners-tracks'); - - $bar = JToolbar::getInstance('toolbar'); - - // Instantiate a new JLayoutFile instance and render the export button - $layout = new JLayoutFile('joomla.toolbar.modal'); - - $dhtml = $layout->render( - array( - 'selector' => 'downloadModal', - 'icon' => 'download', - 'text' => JText::_('JTOOLBAR_EXPORT'), - ) - ); - - $bar->appendButton('Custom', $dhtml, 'download'); - - if ($canDo->get('core.delete')) - { - $bar->appendButton('Confirm', 'COM_BANNERS_DELETE_MSG', 'delete', 'COM_BANNERS_TRACKS_DELETE', 'tracks.delete', false); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_banners'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_COMPONENTS_BANNERS_TRACKS'); - - JHtmlSidebar::setAction('index.php?option=com_banners&view=tracks'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'b.name' => JText::_('COM_BANNERS_HEADING_NAME'), - 'cl.name' => JText::_('COM_BANNERS_HEADING_CLIENT'), - 'track_type' => JText::_('COM_BANNERS_HEADING_TYPE'), - 'count' => JText::_('COM_BANNERS_HEADING_COUNT'), - 'track_date' => JText::_('JDATE') - ); - } -} diff --git a/administrator/components/com_banners/views/tracks/view.raw.php b/administrator/components/com_banners/views/tracks/view.raw.php deleted file mode 100644 index d4ffe1c6acfba..0000000000000 --- a/administrator/components/com_banners/views/tracks/view.raw.php +++ /dev/null @@ -1,49 +0,0 @@ -get('BaseName'); - $filetype = $this->get('FileType'); - $mimetype = $this->get('MimeType'); - $content = $this->get('Content'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $document = JFactory::getDocument(); - $document->setMimeEncoding($mimetype); - JFactory::getApplication() - ->setHeader( - 'Content-disposition', - 'attachment; filename="' . $basename . '.' . $filetype . '"; creation-date="' . JFactory::getDate()->toRFC822() . '"', - true - ); - echo $content; - } -} diff --git a/administrator/components/com_cache/Controller/DisplayController.php b/administrator/components/com_cache/Controller/DisplayController.php new file mode 100644 index 0000000000000..81f19a1529ae6 --- /dev/null +++ b/administrator/components/com_cache/Controller/DisplayController.php @@ -0,0 +1,171 @@ +input->get('view', 'cache'); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + switch ($vName) + { + case 'purge': + $this->app->enqueueMessage(Text::_('COM_CACHE_RESOURCE_INTENSIVE_WARNING'), 'warning'); + break; + case 'cache': + default: + $model = $this->getModel($vName); + $view->setModel($model, true); + break; + } + + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + + // Load the submenu. + CacheHelper::addSubmenu($this->input->get('view', 'cache')); + + $view->display(); + } + } + + /** + * Method to delete a list of cache groups. + * + * @return void + */ + public function delete() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $cid = $this->input->post->get('cid', array(), 'array'); + + if (empty($cid)) + { + $this->app->enqueueMessage(Text::_('JERROR_NO_ITEMS_SELECTED'), 'warning'); + } + else + { + $result = $this->getModel('cache')->cleanlist($cid); + + if ($result !== array()) + { + $this->app->enqueueMessage(Text::sprintf('COM_CACHE_EXPIRED_ITEMS_DELETE_ERROR', implode(', ', $result)), 'error'); + } + else + { + $this->app->enqueueMessage(Text::_('COM_CACHE_EXPIRED_ITEMS_HAVE_BEEN_DELETED'), 'message'); + } + } + + $this->setRedirect('index.php?option=com_cache'); + } + + /** + * Method to delete all cache groups. + * + * @return void + * + * @since 3.6.0 + */ + public function deleteAll() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $app = $this->app; + $model = $this->getModel('cache'); + $allCleared = true; + + $mCache = $model->getCache(); + + foreach ($mCache->getAll() as $cache) + { + if ($mCache->clean($cache->group) === false) + { + $app->enqueueMessage( + Text::sprintf( + 'COM_CACHE_EXPIRED_ITEMS_DELETE_ERROR', Text::_('JADMINISTRATOR') . ' > ' . $cache->group + ), 'error' + ); + $allCleared = false; + } + } + + if ($allCleared) + { + $app->enqueueMessage(Text::_('COM_CACHE_MSG_ALL_CACHE_GROUPS_CLEARED'), 'message'); + } + else + { + $app->enqueueMessage(Text::_('COM_CACHE_MSG_SOME_CACHE_GROUPS_CLEARED'), 'warning'); + } + + $this->setRedirect('index.php?option=com_cache&view=cache'); + } + + /** + * Purge the cache. + * + * @return void + */ + public function purge() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + if (!$this->getModel('cache')->purge()) + { + $this->app->enqueueMessage(Text::_('COM_CACHE_EXPIRED_ITEMS_PURGING_ERROR'), 'error'); + } + else + { + $this->app->enqueueMessage(Text::_('COM_CACHE_EXPIRED_ITEMS_HAVE_BEEN_PURGED'), 'message'); + } + + $this->setRedirect('index.php?option=com_cache&view=purge'); + } +} diff --git a/administrator/components/com_cache/Helper/CacheHelper.php b/administrator/components/com_cache/Helper/CacheHelper.php new file mode 100644 index 0000000000000..8a0f2a5795dcb --- /dev/null +++ b/administrator/components/com_cache/Helper/CacheHelper.php @@ -0,0 +1,51 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + * + * @since 3.5 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Method to get cache data + * + * @return array + */ + public function getData() + { + if (empty($this->_data)) + { + try + { + $cache = $this->getCache(); + $data = $cache->getAll(); + + if ($data && count($data) > 0) + { + // Process filter by search term. + if ($search = $this->getState('filter.search')) + { + foreach ($data as $key => $cacheItem) + { + if (stripos($cacheItem->group, $search) === false) + { + unset($data[$key]); + continue; + } + } + } + + // Process ordering. + $listOrder = $this->getState('list.ordering', 'group'); + $listDirn = $this->getState('list.direction', 'ASC'); + + $this->_data = ArrayHelper::sortObjects($data, $listOrder, strtolower($listDirn) === 'desc' ? -1 : 1, true, true); + + // Process pagination. + $limit = (int) $this->getState('list.limit', 25); + + if ($limit !== 0) + { + $start = (int) $this->getState('list.start', 0); + + return array_slice($this->_data, $start, $limit); + } + } + else + { + $this->_data = array(); + } + } + catch (CacheConnectingException $exception) + { + $this->setError(Text::_('COM_CACHE_ERROR_CACHE_CONNECTION_FAILED')); + $this->_data = array(); + } + catch (UnsupportedCacheException $exception) + { + $this->setError(Text::_('COM_CACHE_ERROR_CACHE_DRIVER_UNSUPPORTED')); + $this->_data = array(); + } + } + + return $this->_data; + } + + /** + * Method to get cache instance. + * + * @return CacheController + */ + public function getCache() + { + $conf = Factory::getConfig(); + + $options = array( + 'defaultgroup' => '', + 'storage' => $conf->get('cache_handler', ''), + 'caching' => true, + 'cachebase' => $conf->get('cache_path', JPATH_CACHE) + ); + + return Cache::getInstance('', $options); + } + + /** + * Get the number of current Cache Groups. + * + * @return integer + */ + public function getTotal() + { + if (empty($this->_total)) + { + $this->_total = count($this->getData()); + } + + return $this->_total; + } + + /** + * Method to get a pagination object for the cache. + * + * @return Pagination + */ + public function getPagination() + { + if (empty($this->_pagination)) + { + $this->_pagination = new Pagination($this->getTotal(), $this->getState('list.start'), $this->getState('list.limit')); + } + + return $this->_pagination; + } + + /** + * Clean out a cache group as named by param. + * If no param is passed clean all cache groups. + * + * @param string $group Cache group name. + * + * @return boolean True on success, false otherwise + */ + public function clean($group = '') + { + try + { + return $this->getCache()->clean($group); + } + catch (CacheConnectingException $exception) + { + return false; + } + catch (UnsupportedCacheException $exception) + { + return false; + } + } + + /** + * Purge an array of cache groups. + * + * @param array $array Array of cache group names. + * + * @return array Array with errors, if they exist. + */ + public function cleanlist($array) + { + $errors = array(); + + foreach ($array as $group) + { + if (!$this->clean($group)) + { + $errors[] = $group; + } + } + + return $errors; + } + + /** + * Purge all cache items. + * + * @return boolean True if successful; false otherwise. + */ + public function purge() + { + try + { + return Factory::getCache('')->gc(); + } + catch (CacheConnectingException $exception) + { + return false; + } + catch (UnsupportedCacheException $exception) + { + return false; + } + } +} diff --git a/administrator/components/com_cache/View/Cache/HtmlView.php b/administrator/components/com_cache/View/Cache/HtmlView.php new file mode 100644 index 0000000000000..96ddd13f2d657 --- /dev/null +++ b/administrator/components/com_cache/View/Cache/HtmlView.php @@ -0,0 +1,85 @@ +data = $this->get('Data'); + $this->pagination = $this->get('Pagination'); + $this->total = $this->get('Total'); + $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 \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + ToolbarHelper::title(Text::_('COM_CACHE_CLEAR_CACHE'), 'lightning clear'); + + ToolbarHelper::custom('delete', 'delete.png', 'delete_f2.png', 'JTOOLBAR_DELETE', true); + ToolbarHelper::custom('deleteAll', 'remove.png', 'delete_f2.png', 'JTOOLBAR_DELETE_ALL', false); + ToolbarHelper::divider(); + + if (Factory::getUser()->authorise('core.admin', 'com_cache')) + { + ToolbarHelper::preferences('com_cache'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_SITE_MAINTENANCE_CLEAR_CACHE'); + + \JHtmlSidebar::setAction('index.php?option=com_cache'); + } +} diff --git a/administrator/components/com_cache/View/Purge/HtmlView.php b/administrator/components/com_cache/View/Purge/HtmlView.php new file mode 100644 index 0000000000000..48bb00008c9f9 --- /dev/null +++ b/administrator/components/com_cache/View/Purge/HtmlView.php @@ -0,0 +1,62 @@ +addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + ToolbarHelper::title(Text::_('COM_CACHE_PURGE_EXPIRED_CACHE'), 'lightning purge'); + ToolbarHelper::custom('purge', 'delete.png', 'delete_f2.png', 'COM_CACHE_PURGE_EXPIRED', false); + ToolbarHelper::divider(); + + if (Factory::getUser()->authorise('core.admin', 'com_cache')) + { + ToolbarHelper::preferences('com_cache'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_SITE_MAINTENANCE_PURGE_EXPIRED_CACHE'); + } +} diff --git a/administrator/components/com_cache/cache.php b/administrator/components/com_cache/cache.php deleted file mode 100644 index 92ffc99e14f9b..0000000000000 --- a/administrator/components/com_cache/cache.php +++ /dev/null @@ -1,19 +0,0 @@ -authorise('core.manage', 'com_cache')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('Cache'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_cache/cache.xml b/administrator/components/com_cache/cache.xml index c9ef2a72fae35..9381f6cdd365d 100644 --- a/administrator/components/com_cache/cache.xml +++ b/administrator/components/com_cache/cache.xml @@ -9,12 +9,17 @@ www.joomla.org 3.0.0 COM_CACHE_XML_DESCRIPTION + Joomla\Component\Cache cache.php config.xml - controller.php + dispatcher.php + Controller + Helper + Model models + View views diff --git a/administrator/components/com_cache/controller.php b/administrator/components/com_cache/controller.php deleted file mode 100644 index b00b2c68a6421..0000000000000 --- a/administrator/components/com_cache/controller.php +++ /dev/null @@ -1,165 +0,0 @@ -input->get('view', 'cache'); - $vFormat = $document->getType(); - $lName = $this->input->get('layout', 'default', 'string'); - - // Get and render the view. - if ($view = $this->getView($vName, $vFormat)) - { - switch ($vName) - { - case 'purge': - break; - case 'cache': - default: - $model = $this->getModel($vName); - $view->setModel($model, true); - break; - } - - $view->setLayout($lName); - - // Push document object into the view. - $view->document = $document; - - // Load the submenu. - CacheHelper::addSubmenu($this->input->get('view', 'cache')); - - $view->display(); - } - } - - /** - * Method to delete a list of cache groups. - * - * @return void - */ - public function delete() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $cid = $this->input->post->get('cid', array(), 'array'); - - if (empty($cid)) - { - JFactory::getApplication()->enqueueMessage(JText::_('JERROR_NO_ITEMS_SELECTED'), 'warning'); - } - else - { - $result = $this->getModel('cache')->cleanlist($cid); - - if ($result !== array()) - { - JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_CACHE_EXPIRED_ITEMS_DELETE_ERROR', implode(', ', $result)), 'error'); - } - else - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_CACHE_EXPIRED_ITEMS_HAVE_BEEN_DELETED'), 'message'); - } - } - - $this->setRedirect('index.php?option=com_cache'); - } - - /** - * Method to delete all cache groups. - * - * @return void - * - * @since 3.6.0 - */ - public function deleteAll() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $model = $this->getModel('cache'); - $allCleared = true; - $clients = array(1, 0); - - foreach ($clients as $client) - { - $mCache = $model->getCache($client); - $clientStr = JText::_($client ? 'JADMINISTRATOR' : 'JSITE') .' > '; - - foreach ($mCache->getAll() as $cache) - { - if ($mCache->clean($cache->group) === false) - { - $app->enqueueMessage(JText::sprintf('COM_CACHE_EXPIRED_ITEMS_DELETE_ERROR', $clientStr . $cache->group), 'error'); - $allCleared = false; - } - } - } - - if ($allCleared) - { - $app->enqueueMessage(JText::_('COM_CACHE_MSG_ALL_CACHE_GROUPS_CLEARED'), 'message'); - } - else - { - $app->enqueueMessage(JText::_('COM_CACHE_MSG_SOME_CACHE_GROUPS_CLEARED'), 'warning'); - } - - $this->setRedirect('index.php?option=com_cache&view=cache'); - } - - /** - * Purge the cache. - * - * @return void - */ - public function purge() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - if (!$this->getModel('cache')->purge()) - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_CACHE_EXPIRED_ITEMS_PURGING_ERROR'), 'error'); - } - else - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_CACHE_EXPIRED_ITEMS_HAVE_BEEN_PURGED'), 'message'); - } - - $this->setRedirect('index.php?option=com_cache&view=purge'); - } -} diff --git a/administrator/components/com_cache/forms/filter_cache.xml b/administrator/components/com_cache/forms/filter_cache.xml new file mode 100644 index 0000000000000..aac4f747d5466 --- /dev/null +++ b/administrator/components/com_cache/forms/filter_cache.xml @@ -0,0 +1,35 @@ + +
+ + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_cache/helpers/cache.php b/administrator/components/com_cache/helpers/cache.php deleted file mode 100644 index 260f10b33b701..0000000000000 --- a/administrator/components/com_cache/helpers/cache.php +++ /dev/null @@ -1,64 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - - // Special case for client id. - $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); - $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; - $this->setState('client_id', $clientId); - - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - * - * @since 3.5 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('client_id'); - $id .= ':' . $this->getState('filter.search'); - - return parent::getStoreId($id); - } - - /** - * Method to get cache data - * - * @return array - */ - public function getData() - { - if (empty($this->_data)) - { - try - { - $cache = $this->getCache(); - $data = $cache->getAll(); - - if ($data && count($data) > 0) - { - // Process filter by search term. - if ($search = $this->getState('filter.search')) - { - foreach ($data as $key => $cacheItem) - { - if (stripos($cacheItem->group, $search) === false) - { - unset($data[$key]); - continue; - } - } - } - - // Process ordering. - $listOrder = $this->getState('list.ordering', 'group'); - $listDirn = $this->getState('list.direction', 'ASC'); - - $this->_data = ArrayHelper::sortObjects($data, $listOrder, strtolower($listDirn) === 'desc' ? -1 : 1, true, true); - - // Process pagination. - $limit = (int) $this->getState('list.limit', 25); - - if ($limit !== 0) - { - $start = (int) $this->getState('list.start', 0); - - return array_slice($this->_data, $start, $limit); - } - } - else - { - $this->_data = array(); - } - } - catch (JCacheExceptionConnecting $exception) - { - $this->setError(JText::_('COM_CACHE_ERROR_CACHE_CONNECTION_FAILED')); - $this->_data = array(); - } - catch (JCacheExceptionUnsupported $exception) - { - $this->setError(JText::_('COM_CACHE_ERROR_CACHE_DRIVER_UNSUPPORTED')); - $this->_data = array(); - } - } - - return $this->_data; - } - - /** - * Method to get cache instance. - * - * @return JCacheController - */ - public function getCache($clientId = null) - { - $conf = JFactory::getConfig(); - - if (is_null($clientId)) - { - $clientId = $this->getState('client_id'); - } - - $options = array( - 'defaultgroup' => '', - 'storage' => $conf->get('cache_handler', ''), - 'caching' => true, - 'cachebase' => (int) $clientId === 1 ? JPATH_ADMINISTRATOR . '/cache' : $conf->get('cache_path', JPATH_SITE . '/cache') - ); - - return JCache::getInstance('', $options); - } - - /** - * Method to get client data. - * - * @return array - * - * @deprecated 4.0 No replacement. - */ - public function getClient() - { - return JApplicationHelper::getClientInfo($this->getState('client_id', 0)); - } - - /** - * Get the number of current Cache Groups. - * - * @return integer - */ - public function getTotal() - { - if (empty($this->_total)) - { - $this->_total = count($this->getData()); - } - - return $this->_total; - } - - /** - * Method to get a pagination object for the cache. - * - * @return JPagination - */ - public function getPagination() - { - if (empty($this->_pagination)) - { - $this->_pagination = new JPagination($this->getTotal(), $this->getState('list.start'), $this->getState('list.limit')); - } - - return $this->_pagination; - } - - /** - * Clean out a cache group as named by param. - * If no param is passed clean all cache groups. - * - * @param string $group Cache group name. - * - * @return boolean True on success, false otherwise - */ - public function clean($group = '') - { - try - { - return $this->getCache()->clean($group); - } - catch (JCacheExceptionConnecting $exception) - { - return false; - } - catch (JCacheExceptionUnsupported $exception) - { - return false; - } - } - - /** - * Purge an array of cache groups. - * - * @param array $array Array of cache group names. - * - * @return array Array with errors, if they exist. - */ - public function cleanlist($array) - { - $errors = array(); - - foreach ($array as $group) - { - if (!$this->clean($group)) - { - $errors[] = $group; - } - } - - return $errors; - } - - /** - * Purge all cache items. - * - * @return boolean True if successful; false otherwise. - */ - public function purge() - { - try - { - return JFactory::getCache('')->gc(); - } - catch (JCacheExceptionConnecting $exception) - { - return false; - } - catch (JCacheExceptionUnsupported $exception) - { - return false; - } - } -} diff --git a/administrator/components/com_cache/models/forms/filter_cache.xml b/administrator/components/com_cache/models/forms/filter_cache.xml deleted file mode 100644 index 9e83948eaf031..0000000000000 --- a/administrator/components/com_cache/models/forms/filter_cache.xml +++ /dev/null @@ -1,49 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - -
diff --git a/administrator/components/com_cache/services/provider.php b/administrator/components/com_cache/services/provider.php new file mode 100644 index 0000000000000..c084d176c8bc9 --- /dev/null +++ b/administrator/components/com_cache/services/provider.php @@ -0,0 +1,54 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Cache')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Cache')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_cache/tmpl/cache/default.php b/administrator/components/com_cache/tmpl/cache/default.php new file mode 100644 index 0000000000000..38e5e6d3bfd2f --- /dev/null +++ b/administrator/components/com_cache/tmpl/cache/default.php @@ -0,0 +1,80 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +HTMLHelper::_('script', 'com_cache/admin-cache-default.js', ['relative' => true, 'version' => 'auto']); +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + data) > 0) : ?> + + + + + + + + + + + + data as $folder => $item) : ?> + + + + + + + + +
+ + + + + + + +
+ + + + + count; ?> + + size); ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_cache/views/cache/tmpl/default.xml b/administrator/components/com_cache/tmpl/cache/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_cache/views/cache/tmpl/default.xml rename to administrator/components/com_cache/tmpl/cache/default.xml diff --git a/administrator/components/com_cache/tmpl/purge/default.php b/administrator/components/com_cache/tmpl/purge/default.php new file mode 100644 index 0000000000000..13e8330609704 --- /dev/null +++ b/administrator/components/com_cache/tmpl/purge/default.php @@ -0,0 +1,33 @@ + + +
+
+
+ sidebar; ?> +
+
+
+
+

+ + +
+
+
+
+
diff --git a/administrator/components/com_cache/views/purge/tmpl/default.xml b/administrator/components/com_cache/tmpl/purge/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_cache/views/purge/tmpl/default.xml rename to administrator/components/com_cache/tmpl/purge/default.xml diff --git a/administrator/components/com_cache/views/cache/tmpl/default.php b/administrator/components/com_cache/views/cache/tmpl/default.php deleted file mode 100644 index b299ded846306..0000000000000 --- a/administrator/components/com_cache/views/cache/tmpl/default.php +++ /dev/null @@ -1,81 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> - total > 0) : ?> - - - - - - - - - - - - - - - - data as $folder => $item) : ?> - - - - - - - - -
- - - - - - - -
- pagination->getListFooter(); ?> -
- - - - - count; ?> - - size); ?> -
- - - - -
- diff --git a/administrator/components/com_cache/views/cache/view.html.php b/administrator/components/com_cache/views/cache/view.html.php deleted file mode 100644 index 6208442ca9ac5..0000000000000 --- a/administrator/components/com_cache/views/cache/view.html.php +++ /dev/null @@ -1,92 +0,0 @@ -data = $this->get('Data'); - $this->pagination = $this->get('Pagination'); - $this->total = $this->get('Total'); - $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(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $state = $this->get('State'); - - if ($state->get('client_id') == 1) - { - JToolbarHelper::title(JText::_('COM_CACHE_CLEAR_CACHE_ADMIN_TITLE'), 'lightning clear'); - } - else - { - JToolbarHelper::title(JText::_('COM_CACHE_CLEAR_CACHE_SITE_TITLE'), 'lightning clear'); - } - - JToolbarHelper::custom('delete', 'delete.png', 'delete_f2.png', 'JTOOLBAR_DELETE', true); - JToolbarHelper::custom('deleteAll', 'remove.png', 'delete_f2.png', 'JTOOLBAR_DELETE_ALL', false); - JToolbarHelper::divider(); - - if (JFactory::getUser()->authorise('core.admin', 'com_cache')) - { - JToolbarHelper::preferences('com_cache'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_SITE_MAINTENANCE_CLEAR_CACHE'); - - JHtmlSidebar::setAction('index.php?option=com_cache'); - } -} diff --git a/administrator/components/com_cache/views/purge/tmpl/default.php b/administrator/components/com_cache/views/purge/tmpl/default.php deleted file mode 100644 index 7391eca4d903f..0000000000000 --- a/administrator/components/com_cache/views/purge/tmpl/default.php +++ /dev/null @@ -1,22 +0,0 @@ - - -
-
- sidebar; ?> -
-
-

- - -
-
diff --git a/administrator/components/com_cache/views/purge/view.html.php b/administrator/components/com_cache/views/purge/view.html.php deleted file mode 100644 index ed1fbd42255a0..0000000000000 --- a/administrator/components/com_cache/views/purge/view.html.php +++ /dev/null @@ -1,57 +0,0 @@ -enqueueMessage(JText::_('COM_CACHE_RESOURCE_INTENSIVE_WARNING'), 'warning'); - - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JToolbarHelper::title(JText::_('COM_CACHE_PURGE_EXPIRED_CACHE'), 'lightning purge'); - JToolbarHelper::custom('purge', 'delete.png', 'delete_f2.png', 'COM_CACHE_PURGE_EXPIRED', false); - JToolbarHelper::divider(); - - if (JFactory::getUser()->authorise('core.admin', 'com_cache')) - { - JToolbarHelper::preferences('com_cache'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_SITE_MAINTENANCE_PURGE_EXPIRED_CACHE'); - } -} diff --git a/administrator/components/com_categories/Controller/CategoriesController.php b/administrator/components/com_categories/Controller/CategoriesController.php new file mode 100644 index 0000000000000..92dd04a987dbc --- /dev/null +++ b/administrator/components/com_categories/Controller/CategoriesController.php @@ -0,0 +1,136 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Rebuild the nested set tree. + * + * @return boolean False on failure or error, true on success. + * + * @since 1.6 + */ + public function rebuild() + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $extension = $this->input->get('extension'); + $this->setRedirect(Route::_('index.php?option=com_categories&view=categories&extension=' . $extension, false)); + + /** @var \Joomla\Component\Categories\Administrator\Model\CategoryModel $model */ + $model = $this->getModel(); + + if ($model->rebuild()) + { + // Rebuild succeeded. + $this->setMessage(Text::_('COM_CATEGORIES_REBUILD_SUCCESS')); + + return true; + } + + // Rebuild failed. + $this->setMessage(Text::_('COM_CATEGORIES_REBUILD_FAILURE')); + + return false; + } + + /** + * Deletes and returns correctly. + * + * @return void + * + * @since 3.1.2 + */ + public function delete() + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Get items to remove from the request. + $cid = $this->input->get('cid', array(), 'array'); + $extension = $this->input->getCmd('extension', null); + + if (!is_array($cid) || count($cid) < 1) + { + $this->app->enqueueMessage(Text::_($this->text_prefix . '_NO_ITEM_SELECTED'), 'warning'); + } + else + { + // Get the model. + /** @var \Joomla\Component\Categories\Administrator\Model\CategoryModel $model */ + $model = $this->getModel(); + + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Remove the items. + if ($model->delete($cid)) + { + $this->setMessage(Text::plural($this->text_prefix . '_N_ITEMS_DELETED', count($cid))); + } + else + { + $this->setMessage($model->getError()); + } + } + + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&extension=' . $extension, false)); + } + + /** + * Check in of one or more records. + * + * Overrides \JControllerAdmin::checkin to redirect to URL with extension. + * + * @return boolean True on success + * + * @since 3.6.0 + */ + public function checkin() + { + // Process parent checkin method. + $result = parent::checkin(); + + // Override the redirect Uri. + $redirectUri = 'index.php?option=' . $this->option . '&view=' . $this->view_list . '&extension=' . $this->input->get('extension', '', 'CMD'); + $this->setRedirect(Route::_($redirectUri, false), $this->message, $this->messageType); + + return $result; + } +} diff --git a/administrator/components/com_categories/Controller/CategoryController.php b/administrator/components/com_categories/Controller/CategoryController.php new file mode 100644 index 0000000000000..78968cc2f57f8 --- /dev/null +++ b/administrator/components/com_categories/Controller/CategoryController.php @@ -0,0 +1,200 @@ +extension)) + { + $this->extension = $this->input->get('extension', 'com_content'); + } + } + + /** + * Method to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowAdd($data = array()) + { + $user = Factory::getUser(); + + return ($user->authorise('core.create', $this->extension) || count($user->getAuthorisedCategories($this->extension, 'core.create'))); + } + + /** + * Method to check if you can edit a record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowEdit($data = array(), $key = 'parent_id') + { + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = Factory::getUser(); + + // Check "edit" permission on record asset (explicit or inherited) + if ($user->authorise('core.edit', $this->extension . '.category.' . $recordId)) + { + return true; + } + + // Check "edit own" permission on record asset (explicit or inherited) + if ($user->authorise('core.edit.own', $this->extension . '.category.' . $recordId)) + { + // Need to do a lookup from the model to get the owner + $record = $this->getModel()->getItem($recordId); + + if (empty($record)) + { + return false; + } + + $ownerId = $record->created_user_id; + + // If the owner matches 'me' then do the test. + if ($ownerId == $user->id) + { + return true; + } + } + + return false; + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 1.6 + */ + public function batch($model = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Set the model + /** @var \Joomla\Component\Categories\Administrator\Model\CategoryModel $model */ + $model = $this->getModel('Category'); + + // Preset the redirect + $this->setRedirect('index.php?option=com_categories&view=categories&extension=' . $this->extension); + + return parent::batch($model); + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since 1.6 + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') + { + $append = parent::getRedirectToItemAppend($recordId); + $append .= '&extension=' . $this->extension; + + return $append; + } + + /** + * Gets the URL arguments to append to a list redirect. + * + * @return string The arguments to append to the redirect URL. + * + * @since 1.6 + */ + protected function getRedirectToListAppend() + { + $append = parent::getRedirectToListAppend(); + $append .= '&extension=' . $this->extension; + + return $append; + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param \Joomla\CMS\MVC\Model\BaseDatabaseModel $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 3.1 + */ + protected function postSaveHook(BaseDatabaseModel $model, $validData = array()) + { + $item = $model->getItem(); + + if (isset($item->params) && is_array($item->params)) + { + $registry = new Registry($item->params); + $item->params = (string) $registry; + } + + if (isset($item->metadata) && is_array($item->metadata)) + { + $registry = new Registry($item->metadata); + $item->metadata = (string) $registry; + } + } +} diff --git a/administrator/components/com_categories/Controller/DisplayController.php b/administrator/components/com_categories/Controller/DisplayController.php new file mode 100644 index 0000000000000..16893be0ade7c --- /dev/null +++ b/administrator/components/com_categories/Controller/DisplayController.php @@ -0,0 +1,116 @@ +extension)) + { + $this->extension = $this->input->get('extension', 'com_content'); + } + } + + /** + * 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 static This object to support chaining. + * + * @since 1.5 + */ + public function display($cachable = false, $urlparams = array()) + { + // Get the document object. + $document = Factory::getDocument(); + + // Set the default view name and format from the Request. + $vName = $this->input->get('view', 'categories'); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($vName == 'category' && $lName == 'edit' && !$this->checkEditId('com_categories.edit.category', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_categories&view=categories&extension=' . $this->extension, false)); + + return false; + } + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + // Get the model for the view. + $model = $this->getModel($vName, 'Administrator', array('name' => $vName . '.' . substr($this->extension, 4))); + + // Push the model into the view (as default). + $view->setModel($model, true); + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + + // Load the submenu. + CategoriesHelper::addSubmenu($model->getState('filter.extension')); + $view->display(); + } + + return $this; + } +} diff --git a/administrator/components/com_categories/Field/CategoryeditField.php b/administrator/components/com_categories/Field/CategoryeditField.php new file mode 100644 index 0000000000000..49f7c6dda3d08 --- /dev/null +++ b/administrator/components/com_categories/Field/CategoryeditField.php @@ -0,0 +1,434 @@ + 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 FormField::setup() + * @since 3.2 + */ + public function setup(\SimpleXMLElement $element, $value, $group = null) + { + $return = parent::setup($element, $value, $group); + + if ($return) + { + $this->allowAdd = $this->element['allowAdd'] ?? ''; + } + + return $return; + } + + /** + * 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.6 + */ + public function __get($name) + { + switch ($name) + { + case 'allowAdd': + 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.6 + */ + public function __set($name, $value) + { + $value = (string) $value; + + switch ($name) + { + case 'allowAdd': + $value = (string) $value; + $this->$name = ($value === 'true' || $value === $name || $value === '1'); + break; + default: + parent::__set($name, $value); + } + } + + /** + * Method to get a list of categories that respects access controls and can be used for + * either category assignment or parent category assignment in edit screens. + * Use the parent element to indicate that the field will be used for assigning parent categories. + * + * @return array The field option objects. + * + * @since 1.6 + */ + protected function getOptions() + { + $options = array(); + $published = $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. + $jinput = Factory::getApplication()->input; + + // Load the category options for a given extension. + + // For categories the old category is the category id or 0 for new category. + if ($this->element['parent'] || $jinput->get('option') == 'com_categories') + { + $oldCat = $jinput->get('id', 0); + $oldParent = $this->form->getValue($name, 0); + $extension = $this->element['extension'] ? (string) $this->element['extension'] : (string) $jinput->get('extension', 'com_content'); + } + else + // For items the old category is the category they are in when opened or 0 if new. + { + $oldCat = $this->form->getValue($name, 0); + $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 = Factory::getDbo(); + $user = Factory::getUser(); + + $query = $db->getQuery(true) + ->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') + { + $query->where('(a.extension = ' . $db->quote($extension) . ' OR a.parent_id = 0)'); + } + else + { + $query->where('(a.extension = ' . $db->quote($extension) . ')'); + } + + // Filter language + if (!empty($this->element['language'])) + { + if (strpos($this->element['language'], ',') !== false) + { + $language = implode(',', $db->quote(explode(',', $this->element['language']))); + } + else + { + $language = $db->quote($this->element['language']); + } + + $query->where($db->quoteName('a.language') . ' IN (' . $language . ')'); + } + + // Filter on the published state + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif (is_array($published)) + { + $query->where('a.published IN (' . implode(',', ArrayHelper::toInteger($published)) . ')'); + } + + // Filter categories on User Access Level + // Filter by access level on categories. + if (!$user->authorise('core.admin')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + + $query->order('a.lft ASC'); + + // If parent isn't explicitly stated but we are in com_categories assume we want parents + if ($oldCat != 0 && ($this->element['parent'] == true || $jinput->get('option') == 'com_categories')) + { + // Prevent parenting to children of this item. + // To rearrange parents and children move the children up, not the parents down. + $query->join('LEFT', $db->quoteName('#__categories') . ' AS p ON p.id = ' . (int) $oldCat) + ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); + + $rowQuery = $db->getQuery(true); + $rowQuery->select('a.id AS value, a.title AS text, a.level, a.parent_id') + ->from('#__categories AS a') + ->where('a.id = ' . (int) $oldCat); + $db->setQuery($rowQuery); + $row = $db->loadObject(); + } + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + // Pad the option text with spaces using depth level as a multiplier. + for ($i = 0, $n = count($options); $i < $n; $i++) + { + // Translate ROOT + if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') + { + if ($options[$i]->level == 0) + { + $options[$i]->text = Text::_('JGLOBAL_ROOT_PARENT'); + } + } + + if ($options[$i]->published == 1) + { + $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 ? 0 : $options[$i]->level - 1) . '[' . $options[$i]->text . ']'; + } + + // Displays language code if not set to All + if ($options[$i]->language !== '*') + { + $options[$i]->text = $options[$i]->text . ' (' . $options[$i]->language . ')'; + } + } + + // For new items we want a list of categories you are allowed to create in. + if ($oldCat == 0) + { + foreach ($options as $i => $option) + { + /* + * To take save or create in a category you need to have create rights for that category unless the item is already in that category. + * Unset the option if the user isn't authorised for it. In this field assets are always categories. + */ + if ($option->level != 0 && !$user->authorise('core.create', $extension . '.category.' . $option->value)) + { + unset($options[$i]); + } + } + } + // If you have an existing category id things are more complex. + else + { + /* + * If you are only allowed to edit in this category but not edit.state, you should not get any + * option to change the category parent for a category or the category for a content item, + * but you should be able to save in that category. + */ + foreach ($options as $i => $option) + { + $assetKey = $extension . '.category.' . $oldCat; + + if ($option->level != 0 && !isset($oldParent) && $option->value != $oldCat && !$user->authorise('core.edit.state', $assetKey)) + { + unset($options[$i]); + continue; + } + + if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.edit.state', $assetKey)) + { + unset($options[$i]); + continue; + } + + /* + * However, if you can edit.state you can also move this to another category for which you have + * create permission and you should also still be able to save in the current category. + */ + $assetKey = $extension . '.category.' . $option->value; + + if ($option->level != 0 && !isset($oldParent) && $option->value != $oldCat && !$user->authorise('core.create', $assetKey)) + { + unset($options[$i]); + continue; + } + + if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.create', $assetKey)) + { + unset($options[$i]); + continue; + } + } + } + + if (($this->element['parent'] == true || $jinput->get('option') == 'com_categories') + && (isset($row) && !isset($options[0])) + && isset($this->element['show_root'])) + { + if ($row->parent_id == '1') + { + $parent = new \stdClass; + $parent->text = Text::_('JGLOBAL_ROOT_PARENT'); + array_unshift($options, $parent); + } + + array_unshift($options, HTMLHelper::_('select.option', '0', Text::_('JGLOBAL_ROOT'))); + } + + // Merge any additional options in the XML definition. + return array_merge(parent::getOptions(), $options); + } + + /** + * Method to get the field input markup for a generic list. + * Use the multiple attribute to enable multiselect. + * + * @return string The field input markup. + * + * @since 3.6 + */ + protected function getInput() + { + $html = array(); + $class = array(); + $attr = ''; + + // Initialize some field attributes. + $class[] = !empty($this->class) ? $this->class : ''; + + if ($this->allowAdd) + { + $customGroupText = Text::_('JGLOBAL_CUSTOM_CATEGORY'); + + $class[] = 'chzn-custom-value'; + $attr .= ' data-custom_group_text="' . $customGroupText . '" ' + . 'data-no_results_text="' . Text::_('JGLOBAL_ADD_CUSTOM_CATEGORY') . '" ' + . 'data-placeholder="' . Text::_('JGLOBAL_TYPE_OR_SELECT_CATEGORY') . '" '; + } + + if ($class) + { + $attr .= 'class="' . implode(' ', $class) . '"'; + } + + $attr .= !empty($this->size) ? ' size="' . $this->size . '"' : ''; + $attr .= $this->multiple ? ' multiple' : ''; + $attr .= $this->required ? ' required' : ''; + $attr .= $this->autofocus ? ' autofocus' : ''; + + // To avoid user's confusion, readonly="true" should imply disabled="true". + if ((string) $this->readonly == '1' + || (string) $this->readonly == 'true' + || (string) $this->disabled == '1' + || (string) $this->disabled == 'true') + { + $attr .= ' disabled="disabled"'; + } + + // Initialize JavaScript field attributes. + $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : ''; + + // Get the field options. + $options = (array) $this->getOptions(); + + // Create a read-only list (no name) with hidden input(s) to store the value(s). + if ((string) $this->readonly == '1' || (string) $this->readonly == 'true') + { + $html[] = HTMLHelper::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $this->value, $this->id); + + // E.g. form field type tag sends $this->value as array + if ($this->multiple && is_array($this->value)) + { + if (!count($this->value)) + { + $this->value[] = ''; + } + + foreach ($this->value as $value) + { + $html[] = ''; + } + } + else + { + $html[] = ''; + } + } + else + { + // 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[] = HTMLHelper::_('select.genericlist', $options, $this->name, trim($attr), 'value', 'text', $this->value, $this->id); + } + + return implode($html); + } +} diff --git a/administrator/components/com_categories/Field/Modal/CategoryField.php b/administrator/components/com_categories/Field/Modal/CategoryField.php new file mode 100644 index 0000000000000..a655ac0174660 --- /dev/null +++ b/administrator/components/com_categories/Field/Modal/CategoryField.php @@ -0,0 +1,302 @@ +element['extension']) + { + $extension = (string) $this->element['extension']; + } + else + { + $extension = (string) Factory::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'); + + // Load language. + Factory::getLanguage()->load('com_categories', JPATH_ADMINISTRATOR); + + // The active category id field. + $value = (int) $this->value > 0 ? (int) $this->value : ''; + + // Create the modal id. + $modalId = 'Category_' . $this->id; + + // Add the modal field script to the document head. + HTMLHelper::_('jquery.framework'); + HTMLHelper::_('script', 'system/fields/modal-fields.min.js', array('version' => 'auto', 'relative' => true)); + + // Script to proxy the select modal function to the modal-fields.js file. + if ($allowSelect) + { + static $scriptSelect = null; + + if (is_null($scriptSelect)) + { + $scriptSelect = array(); + } + + if (!isset($scriptSelect[$this->id])) + { + Factory::getDocument()->addScriptDeclaration(" + function jSelectCategory_" . $this->id . "(id, title, object) { + window.processModalSelect('Category', '" . $this->id . "', id, title, '', object); + } + "); + + $scriptSelect[$this->id] = true; + } + } + + // Setup variables for display. + $linkCategories = 'index.php?option=com_categories&view=categories&layout=modal&tmpl=component&' . Session::getFormToken() . '=1' + . '&extension=' . $extension; + $linkCategory = 'index.php?option=com_categories&view=category&layout=modal&tmpl=component&' . Session::getFormToken() . '=1' + . '&extension=' . $extension; + $modalTitle = Text::_('COM_CATEGORIES_CHANGE_CATEGORY'); + + if (isset($this->element['language'])) + { + $linkCategories .= '&forcedLanguage=' . $this->element['language']; + $linkCategory .= '&forcedLanguage=' . $this->element['language']; + $modalTitle .= ' — ' . $this->element['label']; + } + + $urlSelect = $linkCategories . '&function=jSelectCategory_' . $this->id; + $urlEdit = $linkCategory . '&task=category.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \''; + $urlNew = $linkCategory . '&task=category.add'; + + if ($value) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__categories')) + ->where($db->quoteName('id') . ' = ' . (int) $value); + $db->setQuery($query); + + try + { + $title = $db->loadResult(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + } + + $title = empty($title) ? Text::_('COM_CATEGORIES_SELECT_A_CATEGORY') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); + + // The current category display field. + $html = ''; + if ($allowSelect || $allowNew || $allowEdit || $allowClear) + { + $html .= ''; + } + + $html .= ''; + + if ($allowSelect || $allowNew || $allowEdit || $allowClear) + { + $html .= ''; + } + + // Select category button. + if ($allowSelect) + { + $html .= '' + . ' ' . Text::_('JSELECT') + . ''; + } + + // New category button. + if ($allowNew) + { + $html .= '' + . ' ' . Text::_('JACTION_CREATE') + . ''; + } + + // Edit category button. + if ($allowEdit) + { + $html .= '' + . ' ' . Text::_('JACTION_EDIT') + . ''; + } + + // Clear category button. + if ($allowClear) + { + $html .= '' + . '' . Text::_('JCLEAR') + . ''; + } + + if ($allowSelect || $allowNew || $allowEdit || $allowClear) + { + $html .= ''; + } + + // Select category modal. + if ($allowSelect) + { + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + 'ModalSelect' . $modalId, + array( + 'title' => $modalTitle, + 'url' => $urlSelect, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '', + ) + ); + } + + // New category modal. + if ($allowNew) + { + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + 'ModalNew' . $modalId, + array( + 'title' => Text::_('COM_CATEGORIES_NEW_CATEGORY'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlNew, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '' + . '' + . '', + ) + ); + } + + // Edit category modal. + if ($allowEdit) + { + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + 'ModalEdit' . $modalId, + array( + 'title' => Text::_('COM_CATEGORIES_EDIT_CATEGORY'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlEdit, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '' + . '' + . '', + ) + ); + } + + // Note: class='required' for client side validation + $class = $this->required ? ' class="required modal-value"' : ''; + + $html .= ''; + + return $html; + } + + /** + * Method to get the field label markup. + * + * @return string The field label markup. + * + * @since 3.7.0 + */ + protected function getLabel() + { + return str_replace($this->id, $this->id . '_id', parent::getLabel()); + } +} diff --git a/administrator/components/com_categories/Helper/CategoriesHelper.php b/administrator/components/com_categories/Helper/CategoriesHelper.php new file mode 100644 index 0000000000000..0900ffa6cdbd1 --- /dev/null +++ b/administrator/components/com_categories/Helper/CategoriesHelper.php @@ -0,0 +1,192 @@ + 1) + { + $section = $parts[1]; + } + + // 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)) + { + if (is_callable(array($cName, 'addSubmenu'))) + { + $lang = Factory::getLanguage(); + + // Loading language file from the administrator/language directory then + // loading language file from the administrator/components/*extension*/language directory + $lang->load($component, JPATH_BASE, null, false, true) + || $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); + + call_user_func(array($cName, 'addSubmenu'), 'categories' . (isset($section) ? '.' . $section : '')); + } + } + } + } + + /** + * Gets a list of the actions that can be performed. + * + * @param string $extension The extension. + * @param integer $categoryId The category ID. + * + * @return \JObject + * + * @since 1.6 + * @deprecated 3.2 Use ContentHelper::getActions() instead + */ + public static function getActions($extension, $categoryId = 0) + { + // Log usage of deprecated function + try + { + Log::add( + sprintf('%s() is deprecated, use JHelperContent::getActions() with new arguments order instead.', __METHOD__), + Log::WARNING, + 'deprecated' + ); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + // Get list of actions + return ContentHelper::getActions($extension, 'category', $categoryId); + } + + /** + * Gets a list of associations for a given item. + * + * @param integer $pk Content item key. + * @param string $extension Optional extension name. + * + * @return array of associations. + */ + public static function getAssociations($pk, $extension = 'com_content') + { + $langAssociations = Associations::getAssociations($extension, '#__categories', 'com_categories.item', $pk, 'id', 'alias', ''); + $associations = array(); + $user = Factory::getUser(); + $groups = implode(',', $user->getAuthorisedViewLevels()); + + foreach ($langAssociations as $langAssociation) + { + // Include only published categories with user access + $arrId = explode(':', $langAssociation->id); + $assocId = $arrId[0]; + $db = \JFactory::getDbo(); + + $query = $db->getQuery(true) + ->select($db->quoteName('published')) + ->from($db->quoteName('#__categories')) + ->where('access IN (' . $groups . ')') + ->where($db->quoteName('id') . ' = ' . (int) $assocId); + + $result = (int) $db->setQuery($query)->loadResult(); + + if ($result === 1) + { + $associations[$langAssociation->language] = $langAssociation->id; + } + } + + return $associations; + } + + /** + * Check if Category ID exists otherwise assign to ROOT category. + * + * @param mixed $catid Name or ID of category. + * @param string $extension Extension that triggers this function + * + * @return integer $catid Category ID. + */ + public static function validateCategoryId($catid, $extension) + { + $categoryTable = Table::getInstance('CategoryTable', '\\Joomla\\Component\\Categories\\Administrator\\Table\\'); + + $data = array(); + $data['id'] = $catid; + $data['extension'] = $extension; + + if (!$categoryTable->load($data)) + { + $catid = 0; + } + + return (int) $catid; + } + + /** + * Create new Category from within item view. + * + * @param array $data Array of data for new category. + * + * @return integer + */ + public static function createCategory($data) + { + $categoryModel = new CategoryModel(array('ignore_request' => true)); + $categoryModel->save($data); + + $catid = $categoryModel->getState('category.id'); + + return $catid; + } +} diff --git a/administrator/components/com_categories/Model/CategoriesModel.php b/administrator/components/com_categories/Model/CategoriesModel.php new file mode 100644 index 0000000000000..1fea193fa97ba --- /dev/null +++ b/administrator/components/com_categories/Model/CategoriesModel.php @@ -0,0 +1,405 @@ +input->get('forcedLanguage', '', 'cmd'); + + // Adjust the context to support modal layouts. + if ($layout = $app->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + // Adjust the context to support forced languages. + if ($forcedLanguage) + { + $this->context .= '.' . $forcedLanguage; + } + + $extension = $app->getUserStateFromRequest($this->context . '.filter.extension', 'extension', 'com_content', 'cmd'); + + $this->setState('filter.extension', $extension); + $parts = explode('.', $extension); + + // Extract the component name + $this->setState('filter.component', $parts[0]); + + // Extract the optional section name + $this->setState('filter.section', (count($parts) > 1) ? $parts[1] : null); + + // List state information. + parent::populateState($ordering, $direction); + + // Force a language. + if (!empty($forcedLanguage)) + { + $this->setState('filter.language', $forcedLanguage); + } + } + + /** + * 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 A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.extension'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.language'); + $id .= ':' . $this->getState('filter.level'); + $id .= ':' . $this->getState('filter.tag'); + + return parent::getStoreId($id); + } + + /** + * Method to get a database query to list categories. + * + * @return \JDatabaseQuery object. + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = Factory::getUser(); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + 'a.id, a.title, a.alias, a.note, a.published, a.access' . + ', a.checked_out, a.checked_out_time, a.created_user_id' . + ', a.path, a.parent_id, a.level, a.lft, a.rgt' . + ', a.language' + ) + ); + $query->from('#__categories AS a'); + + // Join over the language + $query->select('l.title AS language_title, l.image AS language_image') + ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor') + ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); + + // Join over the asset groups. + $query->select('ag.title AS access_level') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + + // Join over the users for the author. + $query->select('ua.name AS author_name') + ->join('LEFT', '#__users AS ua ON ua.id = a.created_user_id'); + + // Join over the associations. + $assoc = $this->getAssoc(); + + 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_categories.item')) + ->join('LEFT', '#__associations AS asso2 ON asso2.key = asso.key') + ->group('a.id, l.title, uc.name, ag.title, ua.name'); + } + + // Filter by extension + if ($extension = $this->getState('filter.extension')) + { + $query->where('a.extension = ' . $db->quote($extension)); + } + + // Filter on the level. + if ($level = $this->getState('filter.level')) + { + $query->where('a.level <= ' . (int) $level); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where('a.access = ' . (int) $access); + } + + // Implement View Level Access + if (!$user->authorise('core.admin')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + + // Filter by published state + $published = (string) $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.published IN (0, 1))'); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); + } + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + $query->where('a.language = ' . $db->quote($language)); + } + + // Filter by a single tag. + $tagId = $this->getState('filter.tag'); + + if (is_numeric($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($extension . '.category') + ); + } + + // Add the list ordering clause + $listOrdering = $this->getState('list.ordering', 'a.lft'); + $listDirn = $db->escape($this->getState('list.direction', 'ASC')); + + if ($listOrdering == 'a.access') + { + $query->order('a.access ' . $listDirn . ', a.lft ' . $listDirn); + } + else + { + $query->order($db->escape($listOrdering) . ' ' . $listDirn); + } + + // Group by on Categories for \JOIN with component tables to count items + $query->group('a.id, + a.title, + a.alias, + a.note, + a.published, + a.access, + a.checked_out, + a.checked_out_time, + a.created_user_id, + a.path, + a.parent_id, + a.level, + a.lft, + a.rgt, + a.language, + l.title, + l.image, + uc.name, + ag.title, + ua.name' + ); + + return $query; + } + + /** + * Method to determine if an association exists + * + * @return boolean True if the association exists + * + * @since 3.0 + */ + public function getAssoc() + { + static $assoc = null; + + if (!is_null($assoc)) + { + return $assoc; + } + + $extension = $this->getState('filter.extension'); + + $assoc = Associations::isEnabled(); + $extension = explode('.', $extension); + $component = array_shift($extension); + $cname = str_replace('com_', '', $component); + + if (!$assoc || !$component || !$cname) + { + $assoc = false; + + return $assoc; + } + + $componentObject = $this->bootComponent($component); + + if ($componentObject instanceof AssociationServiceInterface && $componentObject instanceof CategoriesServiceInterface) + { + $assoc = true; + + return $assoc; + } + + $hname = $cname . 'HelperAssociation'; + \JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); + + $assoc = class_exists($hname) && !empty($hname::$category_association); + + return $assoc; + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 12.2 + */ + public function getItems() + { + $items = parent::getItems(); + + if ($items != false) + { + $extension = $this->getState('filter.extension'); + + $this->countItems($items, $extension); + } + + return $items; + } + + /** + * Method to load the countItems method from the extensions + * + * @param \stdClass[] &$items The category items + * @param string $extension The category extension + * + * @return void + * + * @since 3.5 + */ + public function countItems(&$items, $extension) + { + $parts = explode('.', $extension, 2); + $section = ''; + + if (count($parts) > 1) + { + $section = $parts[1]; + } + + $component = Factory::getApplication()->bootComponent($parts[0]); + + if ($component instanceof CategoriesServiceInterface) + { + $component->countItems($items, $section); + } + } +} diff --git a/administrator/components/com_categories/Model/CategoryModel.php b/administrator/components/com_categories/Model/CategoryModel.php new file mode 100644 index 0000000000000..931f181c63487 --- /dev/null +++ b/administrator/components/com_categories/Model/CategoryModel.php @@ -0,0 +1,1320 @@ +input->get('extension', 'com_content'); + $this->typeAlias = $extension . '.category'; + + // Add a new batch command + $this->batch_commands['flip_ordering'] = 'batchFlipordering'; + + parent::__construct($config, $factory); + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canDelete($record) + { + if (empty($record->id) || $record->published != -2) + { + return false; + } + + return Factory::getUser()->authorise('core.delete', $record->extension . '.category.' . (int) $record->id); + } + + /** + * 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 1.6 + */ + protected function canEditState($record) + { + $user = Factory::getUser(); + + // Check for existing category. + if (!empty($record->id)) + { + return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->id); + } + + // New category, so check against the parent. + if (!empty($record->parent_id)) + { + return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->parent_id); + } + + // Default to component settings if neither category nor parent known. + return $user->authorise('core.edit.state', $record->extension); + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return \Joomla\CMS\Table\Table A JTable object + * + * @since 1.6 + */ + public function getTable($type = 'Category', $prefix = 'Administrator', $config = array()) + { + return parent::getTable($type, $prefix, $config); + } + + /** + * Auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = Factory::getApplication(); + + $parentId = $app->input->getInt('parent_id'); + $this->setState('category.parent_id', $parentId); + + // Load the User state. + $pk = $app->input->getInt('id'); + $this->setState($this->getName() . '.id', $pk); + + $extension = $app->input->get('extension', 'com_content'); + $this->setState('category.extension', $extension); + $parts = explode('.', $extension); + + // Extract the component name + $this->setState('category.component', $parts[0]); + + // Extract the optional section name + $this->setState('category.section', (count($parts) > 1) ? $parts[1] : null); + + // Load the parameters. + $params = ComponentHelper::getParams('com_categories'); + $this->setState('params', $params); + } + + /** + * Method to get a category. + * + * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. + * + * @return mixed Category data object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + if ($result = parent::getItem($pk)) + { + // Prime required properties. + if (empty($result->id)) + { + $result->parent_id = $this->getState('category.parent_id'); + $result->extension = $this->getState('category.extension'); + } + + // Convert the metadata field to an array. + $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(Factory::getApplication()->get('offset')); + + if ((int) $result->created_time) + { + $date = new Date($result->created_time); + $date->setTimezone($tz); + $result->created_time = $date->toSql(true); + } + else + { + $result->created_time = null; + } + + if ((int) $result->modified_time) + { + $date = new Date($result->modified_time); + $date->setTimezone($tz); + $result->modified_time = $date->toSql(true); + } + else + { + $result->modified_time = null; + } + + if (!empty($result->id)) + { + $result->tags = new TagsHelper; + $result->tags->getTagIds($result->id, $result->extension . '.category'); + } + } + + $assoc = $this->getAssoc(); + + if ($assoc) + { + if ($result->id != null) + { + $result->associations = ArrayHelper::toInteger(CategoriesHelper::getAssociations($result->id, $result->extension)); + } + else + { + $result->associations = array(); + } + } + + return $result; + } + + /** + * Method to get the row form. + * + * @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 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + $extension = $this->getState('category.extension'); + $jinput = Factory::getApplication()->input; + + // A workaround to get the extension into the model for save requests. + if (empty($extension) && isset($data['extension'])) + { + $extension = $data['extension']; + $parts = explode('.', $extension); + + $this->setState('category.extension', $extension); + $this->setState('category.component', $parts[0]); + $this->setState('category.section', @$parts[1]); + } + + // Get the form. + $form = $this->loadForm('com_categories.category' . $extension, 'category', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Modify the form based on Edit State access controls. + if (empty($data['extension'])) + { + $data['extension'] = $extension; + } + + $categoryId = $jinput->get('id'); + $parts = explode('.', $extension); + $assetKey = $categoryId ? $extension . '.category.' . $categoryId : $parts[0]; + + if (!Factory::getUser()->authorise('core.edit.state', $assetKey)) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + return $form; + } + + /** + * A protected method to get the where clause for the reorder + * This ensures that the row will be moved relative to a row with the same extension + * + * @param \JTableCategory $table Current table instance + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 + */ + protected function getReorderConditions($table) + { + return 'extension = ' . $this->_db->quote($table->extension); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $app = Factory::getApplication(); + $data = $app->getUserState('com_categories.edit.' . $this->getName() . '.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + + // Pre-select some filters (Status, Language, Access) in edit form if those have been selected in Category Manager + if (!$data->id) + { + // Check for which extension the Category Manager is used and get selected fields + $extension = substr($app->getUserState('com_categories.categories.filter.extension'), 4); + $filters = (array) $app->getUserState('com_categories.categories.' . $extension . '.filter'); + + $data->set( + 'published', + $app->input->getInt( + 'published', + ((isset($filters['published']) && $filters['published'] !== '') ? $filters['published'] : null) + ) + ); + $data->set('language', $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null))); + $data->set( + 'access', + $app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : Factory::getConfig()->get('access'))) + ); + } + } + + $this->preprocessData('com_categories.category', $data); + + return $data; + } + + /** + * Method to preprocess the form. + * + * @param \JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import. + * + * @return void + * + * @see \JFormField + * @since 1.6 + * @throws \Exception if there is an error in the form event. + */ + protected function preprocessForm(\JForm $form, $data, $group = 'content') + { + $lang = Factory::getLanguage(); + $component = $this->getState('category.component'); + $section = $this->getState('category.section'); + $extension = Factory::getApplication()->input->get('extension', null); + + // Get the component form if it exists + $name = 'category' . ($section ? ('.' . $section) : ''); + + // Looking first in the component forms folder + $path = Path::clean(JPATH_ADMINISTRATOR . "/components/$component/forms/$name.xml"); + + // Looking in the component models/forms folder (J! 3) + if (!file_exists($path)) + { + $path = Path::clean(JPATH_ADMINISTRATOR . "/components/$component/models/forms/$name.xml"); + } + + // Old way: looking in the component folder + if (!file_exists($path)) + { + $path = Path::clean(JPATH_ADMINISTRATOR . "/components/$component/$name.xml"); + } + + if (file_exists($path)) + { + $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(Text::_('JERROR_LOADFILE_FAILED')); + } + } + + $componentInterface = Factory::getApplication()->bootComponent($component); + + if ($componentInterface instanceof CategoriesServiceInterface) + { + $componentInterface->prepareForm($form, $data); + } + else + { + // Try to find the component helper. + $eName = str_replace('com_', '', $component); + $path = Path::clean(JPATH_ADMINISTRATOR . "/components/$component/helpers/category.php"); + + if (file_exists($path)) + { + $cName = ucfirst($eName) . ucfirst($section) . 'HelperCategory'; + + \JLoader::register($cName, $path); + + if (class_exists($cName) && is_callable(array($cName, 'onPrepareForm'))) + { + $lang->load($component, JPATH_BASE, null, false, false) + || $lang->load($component, JPATH_BASE . '/components/' . $component, null, false, false) + || $lang->load($component, JPATH_BASE, $lang->getDefault(), false, false) + || $lang->load($component, JPATH_BASE . '/components/' . $component, $lang->getDefault(), false, false); + call_user_func_array(array($cName, 'onPrepareForm'), array(&$form)); + + // Check for an error. + if ($form instanceof \Exception) + { + $this->setError($form->getMessage()); + + return false; + } + } + } + } + + // Set the access control rules field component value. + $form->setFieldAttribute('rules', 'component', $component); + $form->setFieldAttribute('rules', 'section', $name); + + // Association category items + if ($this->getAssoc()) + { + $languages = LanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc'); + + if (count($languages) > 1) + { + $addform = new \SimpleXMLElement('
'); + $fields = $addform->addChild('fields'); + $fields->addAttribute('name', 'associations'); + $fieldset = $fields->addChild('fieldset'); + $fieldset->addAttribute('name', 'item_associations'); + + foreach ($languages as $language) + { + $field = $fieldset->addChild('field'); + $field->addAttribute('name', $language->lang_code); + $field->addAttribute('type', 'modal_category'); + $field->addAttribute('language', $language->lang_code); + $field->addAttribute('label', $language->title); + $field->addAttribute('translate_label', 'false'); + $field->addAttribute('extension', $extension); + $field->addAttribute('select', 'true'); + $field->addAttribute('new', 'true'); + $field->addAttribute('edit', 'true'); + $field->addAttribute('clear', 'true'); + } + + $form->load($addform, false); + } + } + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $table = $this->getTable(); + $input = Factory::getApplication()->input; + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState($this->getName() . '.id'); + $isNew = true; + $context = $this->option . '.' . $this->name; + + if (!empty($data['tags']) && $data['tags'][0] != '') + { + $table->newTags = $data['tags']; + } + + // Include the plugins for the save events. + PluginHelper::importPlugin($this->events_map['save']); + + // Load the row if saving an existing category. + if ($pk > 0) + { + $table->load($pk); + $isNew = false; + } + + // Set the new parent id if parent id not matched OR while New/Save as Copy . + if ($table->parent_id != $data['parent_id'] || $data['id'] == 0) + { + $table->setLocation($data['parent_id'], 'last-child'); + } + + // Alter the title for save as copy + if ($input->get('task') == 'save2copy') + { + $origTable = clone $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; + } + else + { + if ($data['alias'] == $origTable->alias) + { + $data['alias'] = ''; + } + } + + $data['published'] = 0; + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Bind the rules. + if (isset($data['rules'])) + { + $rules = new Rules($data['rules']); + $table->setRules($rules); + } + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = Factory::getApplication()->triggerEvent($this->event_before_save, array($context, &$table, $isNew, $data)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Store the data. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + $assoc = $this->getAssoc(); + + if ($assoc) + { + // Adding self to the association + $associations = $data['associations'] ?? array(); + + // Unset any invalid associations + $associations = ArrayHelper::toInteger($associations); + + foreach ($associations as $tag => $id) + { + if (!$id) + { + unset($associations[$tag]); + } + } + + // Detecting all item menus + $allLanguage = $table->language == '*'; + + if ($allLanguage && !empty($associations)) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_CATEGORIES_ERROR_ALL_LANGUAGE_ASSOCIATED'), 'notice'); + } + + // Get associationskey for edited item + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('key')) + ->from($db->quoteName('#__associations')) + ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)) + ->where($db->quoteName('id') . ' = ' . (int) $table->id); + $db->setQuery($query); + $oldKey = $db->loadResult(); + + // Deleting old associations for the associated items + $query = $db->getQuery(true) + ->delete($db->quoteName('#__associations')) + ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)); + + if ($associations) + { + $query->where('(' . $db->quoteName('id') . ' IN (' . implode(',', $associations) . ') OR ' + . $db->quoteName('key') . ' = ' . $db->quote($oldKey) . ')'); + } + else + { + $query->where($db->quoteName('key') . ' = ' . $db->quote($oldKey)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Adding self to the association + if (!$allLanguage) + { + $associations[$table->language] = (int) $table->id; + } + + if (count($associations) > 1) + { + // Adding new association for these items + $key = md5(json_encode($associations)); + $query->clear() + ->insert('#__associations'); + + foreach ($associations as $id) + { + $query->values(((int) $id) . ',' . $db->quote($this->associationsContext) . ',' . $db->quote($key)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + } + + // Trigger the after save event. + Factory::getApplication()->triggerEvent($this->event_after_save, array($context, &$table, $isNew, $data)); + + // Rebuild the path for the category: + if (!$table->rebuildPath($table->id)) + { + $this->setError($table->getError()); + + return false; + } + + // Rebuild the paths of the category's children: + if (!$table->rebuild($table->id, $table->lft, $table->level, $table->path)) + { + $this->setError($table->getError()); + + return false; + } + + $this->setState($this->getName() . '.id', $table->id); + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the published state of one or more records. + * + * @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. + * + * @since 2.5 + */ + public function publish(&$pks, $value = 1) + { + if (parent::publish($pks, $value)) + { + $extension = Factory::getApplication()->input->get('extension'); + + // Include the content plugins for the change of category state event. + PluginHelper::importPlugin('content'); + + // Trigger the onCategoryChangeState event. + Factory::getApplication()->triggerEvent('onCategoryChangeState', array($extension, $pks, $value)); + + return true; + } + } + + /** + * Method rebuild the entire nested set tree. + * + * @return boolean False on failure or error, true otherwise. + * + * @since 1.6 + */ + public function rebuild() + { + // Get an instance of the table object. + $table = $this->getTable(); + + if (!$table->rebuild()) + { + $this->setError($table->getError()); + + return false; + } + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to save the reordered nested set tree. + * 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 + * + * @return boolean False on failure or error, True otherwise + * + * @since 1.6 + */ + public function saveorder($idArray = null, $lft_array = null) + { + // Get an instance of the table object. + $table = $this->getTable(); + + if (!$table->saveorder($idArray, $lft_array)) + { + $this->setError($table->getError()); + + return false; + } + + // Clear the cache + $this->cleanCache(); + + 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->quoteName('catid') . ' = ' . $db->quote($id)); + + $db->setQuery($query); + + $max = (int) $db->loadresult(); + $max++; + + $query->clear(); + + $query->update('#__content') + ->set($db->quoteName('ordering') . ' = ' . $max . ' - ' . $db->quoteName('ordering')) + ->where($db->quoteName('catid') . ' = ' . $db->quote($id)); + + $db->setQuery($query); + + if ($db->execute()) + { + $successful[] = $id; + } + } + + return empty($successful) ? false : $successful; + } + + /** + * Batch copy categories to a new category. + * + * @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 1.6 + */ + protected function batchCopy($value, $pks, $contexts) + { + $type = new UCMType; + $this->type = $type->getTypeByAlias($this->typeAlias); + + // $value comes as {parent_id}.{extension} + $parts = explode('.', $value); + $parentId = (int) ArrayHelper::getValue($parts, 0, 1); + + $db = $this->getDbo(); + $extension = Factory::getApplication()->input->get('extension', '', 'word'); + $newIds = array(); + + // Check that the parent exists + if ($parentId) + { + if (!$this->table->load($parentId)) + { + if ($error = $this->table->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // Non-fatal error + $this->setError(Text::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); + $parentId = 0; + } + } + + // Check that user has create permission for parent category + if ($parentId == $this->table->getRootId()) + { + $canCreate = $this->user->authorise('core.create', $extension); + } + else + { + $canCreate = $this->user->authorise('core.create', $extension . '.category.' . $parentId); + } + + if (!$canCreate) + { + // Error since user cannot create in parent category + $this->setError(Text::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); + + return false; + } + } + + // If the parent is 0, set it to the ID of the root item in the tree + if (empty($parentId)) + { + if (!$parentId = $this->table->getRootId()) + { + $this->setError($this->table->getError()); + + return false; + } + // Make sure we can create in root + elseif (!$this->user->authorise('core.create', $extension)) + { + $this->setError(Text::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); + + return false; + } + } + + // We need to log the parent ID + $parents = array(); + + // Calculate the emergency stop count as a precaution against a runaway loop bug + $query = $db->getQuery(true) + ->select('COUNT(id)') + ->from($db->quoteName('#__categories')); + $db->setQuery($query); + + try + { + $count = $db->loadResult(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Parent exists so let's proceed + while (!empty($pks) && $count > 0) + { + // 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(Text::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // Copy is a bit tricky, because we also need to copy the children + $query->clear() + ->select('id') + ->from($db->quoteName('#__categories')) + ->where('lft > ' . (int) $this->table->lft) + ->where('rgt < ' . (int) $this->table->rgt); + $db->setQuery($query); + $childIds = $db->loadColumn(); + + // Add child ID's to the array only if they aren't already there. + foreach ($childIds as $childId) + { + if (!in_array($childId, $pks)) + { + $pks[] = $childId; + } + } + + // Make a copy of the old ID and Parent ID + $oldId = $this->table->id; + $oldParentId = $this->table->parent_id; + + // Reset the id because we are making a copy. + $this->table->id = 0; + + // If we a copying children, the Old ID will turn up in the parents list + // otherwise it's a new top level item + $this->table->parent_id = $parents[$oldParentId] ?? $parentId; + + // Set the new location in the tree for the node. + $this->table->setLocation($this->table->parent_id, 'last-child'); + + // @TODO: Deal with ordering? + // $this->table->ordering = 1; + $this->table->level = null; + $this->table->asset_id = null; + $this->table->lft = null; + $this->table->rgt = null; + + // Alter the title & alias + list($title, $alias) = $this->generateNewTitle($this->table->parent_id, $this->table->alias, $this->table->title); + $this->table->title = $title; + $this->table->alias = $alias; + + // Unpublish because we are making a copy + $this->table->published = 0; + + // 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; + + // Now we log the old 'parent' to the new 'parent' + $parents[$oldId] = $this->table->id; + $count--; + } + + // Rebuild the hierarchy. + if (!$this->table->rebuild()) + { + $this->setError($this->table->getError()); + + return false; + } + + // Rebuild the tree path. + if (!$this->table->rebuildPath($this->table->id)) + { + $this->setError($this->table->getError()); + + return false; + } + + return $newIds; + } + + /** + * 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 boolean True on success. + * + * @since 1.6 + */ + protected function batchMove($value, $pks, $contexts) + { + $parentId = (int) $value; + $type = new UCMType; + $this->type = $type->getTypeByAlias($this->typeAlias); + + $db = $this->getDbo(); + $query = $db->getQuery(true); + $extension = Factory::getApplication()->input->get('extension', '', 'word'); + + // Check that the parent exists. + if ($parentId) + { + if (!$this->table->load($parentId)) + { + if ($error = $this->table->getError()) + { + // Fatal error. + $this->setError($error); + + return false; + } + else + { + // Non-fatal error. + $this->setError(Text::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); + $parentId = 0; + } + } + + // Check that user has create permission for parent category. + if ($parentId == $this->table->getRootId()) + { + $canCreate = $this->user->authorise('core.create', $extension); + } + else + { + $canCreate = $this->user->authorise('core.create', $extension . '.category.' . $parentId); + } + + if (!$canCreate) + { + // Error since user cannot create in parent category + $this->setError(Text::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); + + return false; + } + + // Check that user has edit permission for every category being moved + // Note that the entire batch operation fails if any category lacks edit permission + foreach ($pks as $pk) + { + if (!$this->user->authorise('core.edit', $extension . '.category.' . $pk)) + { + // Error since user cannot edit this category + $this->setError(Text::_('COM_CATEGORIES_BATCH_CANNOT_EDIT')); + + return false; + } + } + } + + // We are going to store all the children and just move the category + $children = array(); + + // Parent exists so let's proceed + foreach ($pks as $pk) + { + // 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(Text::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // Set the new location in the tree for the node. + $this->table->setLocation($parentId, 'last-child'); + + // Check if we are moving to a different parent + if ($parentId != $this->table->parent_id) + { + // Add the child node ids to the children array. + $query->clear() + ->select('id') + ->from($db->quoteName('#__categories')) + ->where($db->quoteName('lft') . ' BETWEEN ' . (int) $this->table->lft . ' AND ' . (int) $this->table->rgt); + $db->setQuery($query); + + try + { + $children = array_merge($children, (array) $db->loadColumn()); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + // Store the row. + if (!$this->table->store()) + { + $this->setError($this->table->getError()); + + return false; + } + + // Rebuild the tree path. + if (!$this->table->rebuildPath()) + { + $this->setError($this->table->getError()); + + return false; + } + } + + // Process the child rows + if (!empty($children)) + { + // Remove any duplicates and sanitize ids. + $children = array_unique($children); + $children = ArrayHelper::toInteger($children); + } + + return true; + } + + /** + * Custom clean the cache of com_content and content modules + * + * @param string $group Cache group name. + * @param integer $client_id Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $client_id = 0) + { + $extension = Factory::getApplication()->input->get('extension'); + + switch ($extension) + { + case 'com_content': + parent::cleanCache('com_content'); + parent::cleanCache('mod_articles_archive'); + parent::cleanCache('mod_articles_categories'); + parent::cleanCache('mod_articles_category'); + parent::cleanCache('mod_articles_latest'); + parent::cleanCache('mod_articles_news'); + parent::cleanCache('mod_articles_popular'); + break; + default: + parent::cleanCache($extension); + break; + } + } + + /** + * 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. + * + * @return array Contains the modified title and alias. + * + * @since 1.7 + */ + protected function generateNewTitle($parent_id, $alias, $title) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) + { + $title = StringHelper::increment($title); + $alias = StringHelper::increment($alias, 'dash'); + } + + return array($title, $alias); + } + + /** + * Method to determine if a category association is available. + * + * @return boolean True if a category association is available; false otherwise. + */ + public function getAssoc() + { + static $assoc = null; + + if (!is_null($assoc)) + { + return $assoc; + } + + $extension = $this->getState('category.extension'); + + $assoc = Associations::isEnabled(); + $extension = explode('.', $extension); + $component = array_shift($extension); + $cname = str_replace('com_', '', $component); + + if (!$assoc || !$component || !$cname) + { + $assoc = false; + + return $assoc; + } + + $componentObject = $this->bootComponent($component); + + if ($componentObject instanceof AssociationServiceInterface && $componentObject instanceof CategoriesServiceInterface) + { + $assoc = true; + + return $assoc; + } + + $hname = $cname . 'HelperAssociation'; + \JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); + + $assoc = class_exists($hname) && !empty($hname::$category_association); + + return $assoc; + } +} diff --git a/administrator/components/com_categories/Table/CategoryTable.php b/administrator/components/com_categories/Table/CategoryTable.php new file mode 100644 index 0000000000000..ed284901ae432 --- /dev/null +++ b/administrator/components/com_categories/Table/CategoryTable.php @@ -0,0 +1,35 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->assoc = $this->get('Assoc'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Preprocess the list of items to find ordering divisions. + foreach ($this->items as &$item) + { + $this->ordering[$item->parent_id][] = $item->id; + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + // We do not need to filter by language when multilingual is disabled + if (!Multilanguage::isEnabled()) + { + unset($this->activeFilters['language']); + $this->filterForm->removeField('language', 'filter'); + } + } + else + { + // In article associations modal we need to remove language filter if forcing a language. + if ($forcedLanguage = Factory::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 a 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']); + } + } + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $categoryId = $this->state->get('filter.category_id'); + $component = $this->state->get('filter.component'); + $section = $this->state->get('filter.section'); + $canDo = ContentHelper::getActions($component, 'category', $categoryId); + $user = Factory::getUser(); + + // Get the toolbar object instance + $bar = Toolbar::getInstance('toolbar'); + + // Avoid nonsense situation. + if ($component == 'com_categories') + { + return; + } + + // Need to load the menu language file as mod_menu hasn't been loaded yet. + $lang = Factory::getLanguage(); + $lang->load($component, JPATH_BASE, null, false, true) + || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); + + // If a component categories title string is present, let's use it. + if ($lang->hasKey($component_title_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORIES_TITLE')) + { + $title = Text::_($component_title_key); + } + elseif ($lang->hasKey($component_section_key = strtoupper($component . ($section ? "_$section" : '')))) + // Else if the component section string exits, let's use it + { + $title = Text::sprintf('COM_CATEGORIES_CATEGORIES_TITLE', $this->escape(Text::_($component_section_key))); + } + else + // Else use the base title + { + $title = Text::_('COM_CATEGORIES_CATEGORIES_BASE_TITLE'); + } + + // Load specific css component + HTMLHelper::_('stylesheet', $component . '/administrator/categories.css', array('version' => 'auto', 'relative' => true)); + + // Prepare the toolbar. + ToolbarHelper::title($title, 'folder categories ' . substr($component, 4) . ($section ? "-$section" : '') . '-categories'); + + if ($canDo->get('core.create') || count($user->getAuthorisedCategories($component, 'core.create')) > 0) + { + ToolbarHelper::addNew('category.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publish('categories.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('categories.unpublish', 'JTOOLBAR_UNPUBLISH', true); + ToolbarHelper::archiveList('categories.archive'); + } + + if (Factory::getUser()->authorise('core.admin')) + { + ToolbarHelper::checkin('categories.checkin'); + } + + // Add a batch button + if ($canDo->get('core.create') + && $canDo->get('core.edit') + && $canDo->get('core.edit.state')) + { + $title = Text::_('JTOOLBAR_BATCH'); + + // Instantiate a new \ileLayout instance and render the batch button + $layout = new FileLayout('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($canDo->get('core.admin')) + { + ToolbarHelper::custom('categories.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); + } + + if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete', $component)) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'categories.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('categories.trash'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences($component); + } + + // Compute the ref_key if it does exist in the component + if (!$lang->hasKey($ref_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORIES_HELP_KEY')) + { + $ref_key = 'JHELP_COMPONENTS_' . strtoupper(substr($component, 4) . ($section ? "_$section" : '')) . '_CATEGORIES'; + } + + /* + * Get help for the categories view for the component by + * -remotely searching in a language defined dedicated URL: *component*_HELP_URL + * -locally searching in a component help file if helpURL param exists in the component and is set to '' + * -remotely searching in a component URL if helpURL param exists in the component and is NOT set to '' + */ + if ($lang->hasKey($lang_help_url = strtoupper($component) . '_HELP_URL')) + { + $debug = $lang->setDebug(false); + $url = Text::_($lang_help_url); + $lang->setDebug($debug); + } + else + { + $url = null; + } + + ToolbarHelper::help($ref_key, ComponentHelper::getParams($component)->exists('helpURL'), $url); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.lft' => Text::_('JGRID_HEADING_ORDERING'), + 'a.published' => Text::_('JSTATUS'), + 'a.title' => Text::_('JGLOBAL_TITLE'), + 'a.access' => Text::_('JGRID_HEADING_ACCESS'), + 'language' => Text::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_categories/View/Category/HtmlView.php b/administrator/components/com_categories/View/Category/HtmlView.php new file mode 100644 index 0000000000000..89a1bca6400a9 --- /dev/null +++ b/administrator/components/com_categories/View/Category/HtmlView.php @@ -0,0 +1,274 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + $section = $this->state->get('category.section') ? $this->state->get('category.section') . '.' : ''; + $this->canDo = ContentHelper::getActions($this->state->get('category.component'), $section . 'category', $this->item->id); + $this->assoc = $this->get('Assoc'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Check if we have a content type for this alias + if (!empty(TagsHelper::getTypes('objectList', array($this->state->get('category.extension') . '.category'), true))) + { + $this->checkTags = true; + } + + Factory::getApplication()->input->set('hidemainmenu', true); + + // If we are forcing a language in modal (used for associations). + if ($this->getLayout() === 'modal' && $forcedLanguage = Factory::getApplication()->input->get('forcedLanguage', '', 'cmd')) + { + // Set the language field to the forcedLanguage and disable changing it. + $this->form->setValue('language', null, $forcedLanguage); + $this->form->setFieldAttribute('language', 'readonly', 'true'); + + // Only allow to select categories with All language or with the forced language. + $this->form->setFieldAttribute('parent_id', 'language', '*,' . $forcedLanguage); + + // Only allow to select tags with All language or with the forced language. + $this->form->setFieldAttribute('tags', 'language', '*,' . $forcedLanguage); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $extension = Factory::getApplication()->input->get('extension'); + $user = Factory::getUser(); + $userId = $user->id; + + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); + + // Avoid nonsense situation. + if ($extension == 'com_categories') + { + return; + } + + // The extension can be in the form com_foo.section + $parts = explode('.', $extension); + $component = $parts[0]; + $section = (count($parts) > 1) ? $parts[1] : null; + $componentParams = ComponentHelper::getParams($component); + + // Need to load the menu language file as mod_menu hasn't been loaded yet. + $lang = Factory::getLanguage(); + $lang->load($component, JPATH_BASE, null, false, true) + || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); + + // Get the results for each action. + $canDo = $this->canDo; + + // If a component categories title string is present, let's use it. + if ($lang->hasKey($component_title_key = $component . ($section ? "_$section" : '') . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE')) + { + $title = Text::_($component_title_key); + } + // Else if the component section string exits, let's use it + elseif ($lang->hasKey($component_section_key = $component . ($section ? "_$section" : ''))) + { + $title = Text::sprintf('COM_CATEGORIES_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') + . '_TITLE', $this->escape(Text::_($component_section_key)) + ); + } + // Else use the base title + else + { + $title = Text::_('COM_CATEGORIES_CATEGORY_BASE_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE'); + } + + // Load specific css component + HTMLHelper::_('stylesheet', $component . '/administrator/categories.css', array('version' => 'auto', 'relative' => true)); + + // Prepare the toolbar. + ToolbarHelper::title( + $title, + 'folder category-' . ($isNew ? 'add' : 'edit') + . ' ' . substr($component, 4) . ($section ? "-$section" : '') . '-category-' . ($isNew ? 'add' : 'edit') + ); + + // For new records, check the create permission. + if ($isNew && (count($user->getAuthorisedCategories($component, 'core.create')) > 0)) + { + ToolbarHelper::saveGroup( + [ + ['apply', 'category.apply'], + ['save', 'category.save'], + ['save2new', 'category.save2new'] + ], + 'btn-success' + ); + + ToolbarHelper::cancel('category.cancel'); + } + + // If not checked out, can save the item. + else + { + // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. + $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_user_id == $userId); + + $toolbarButtons = []; + + // Can't save the record if it's checked out and editable + if (!$checkedOut && $itemEditable) + { + $toolbarButtons[] = ['apply', 'category.apply']; + $toolbarButtons[] = ['save', 'category.save']; + + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2new', 'category.save2new']; + } + } + + // If an existing item, can save to a copy. + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'category.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (ComponentHelper::isEnabled('com_contenthistory') && $componentParams->get('save_history', 0) && $itemEditable) + { + $typeAlias = $extension . '.category'; + ToolbarHelper::versions($typeAlias, $this->item->id); + } + + ToolbarHelper::cancel('category.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + + // Compute the ref_key + $ref_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_HELP_KEY'; + + // Check if thr computed ref_key does exist in the component + if (!$lang->hasKey($ref_key)) + { + $ref_key = 'JHELP_COMPONENTS_' + . strtoupper(substr($component, 4) . ($section ? "_$section" : '')) + . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT'); + } + + /* + * Get help for the category/section view for the component by + * -remotely searching in a language defined dedicated URL: *component*_HELP_URL + * -locally searching in a component help file if helpURL param exists in the component and is set to '' + * -remotely searching in a component URL if helpURL param exists in the component and is NOT set to '' + */ + if ($lang->hasKey($lang_help_url = strtoupper($component) . '_HELP_URL')) + { + $debug = $lang->setDebug(false); + $url = Text::_($lang_help_url); + $lang->setDebug($debug); + } + else + { + $url = null; + } + + ToolbarHelper::help($ref_key, $componentParams->exists('helpURL'), $url, $component); + } +} diff --git a/administrator/components/com_categories/categories.php b/administrator/components/com_categories/categories.php deleted file mode 100644 index 979ee32f9a97a..0000000000000 --- a/administrator/components/com_categories/categories.php +++ /dev/null @@ -1,28 +0,0 @@ -input; - -// If you have a URL like this: com_categories&view=categories&extension=com_example.example_cat -$parts = explode('.', $input->get('extension')); -$component = $parts[0]; - -if (!JFactory::getUser()->authorise('core.manage', $component)) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -JLoader::register('JHtmlCategoriesAdministrator', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/html/categoriesadministrator.php'); - -$controller = JControllerLegacy::getInstance('Categories'); -$controller->execute($input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_categories/categories.xml b/administrator/components/com_categories/categories.xml index 56a5cb0d3743f..b88b79369bcfe 100644 --- a/administrator/components/com_categories/categories.xml +++ b/administrator/components/com_categories/categories.xml @@ -9,14 +9,18 @@ www.joomla.org 3.0.0 COM_CATEGORIES_XML_DESCRIPTION + Joomla\Component\Categories - categories.php - config.xml - controller.php - controllers + categories.xml + dispatcher.php + Controller + Helper helpers + Model models + Table + View views diff --git a/administrator/components/com_categories/controller.php b/administrator/components/com_categories/controller.php deleted file mode 100644 index baea25b846ea3..0000000000000 --- a/administrator/components/com_categories/controller.php +++ /dev/null @@ -1,100 +0,0 @@ -extension)) - { - $this->extension = $this->input->get('extension', 'com_content'); - } - } - - /** - * 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 CategoriesController This object to support chaining. - * - * @since 1.5 - */ - public function display($cachable = false, $urlparams = array()) - { - // Get the document object. - $document = JFactory::getDocument(); - - // Set the default view name and format from the Request. - $vName = $this->input->get('view', 'categories'); - $vFormat = $document->getType(); - $lName = $this->input->get('layout', 'default', 'string'); - $id = $this->input->getInt('id'); - - // Check for edit form. - if ($vName == 'category' && $lName == 'edit' && !$this->checkEditId('com_categories.edit.category', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_categories&view=categories&extension=' . $this->extension, false)); - - return false; - } - - // Get and render the view. - if ($view = $this->getView($vName, $vFormat)) - { - // Get the model for the view. - $model = $this->getModel($vName, 'CategoriesModel', array('name' => $vName . '.' . substr($this->extension, 4))); - - // Push the model into the view (as default). - $view->setModel($model, true); - $view->setLayout($lName); - - // Push document object into the view. - $view->document = $document; - - // Load the submenu. - JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - - CategoriesHelper::addSubmenu($model->getState('filter.extension')); - $view->display(); - } - - return $this; - } -} diff --git a/administrator/components/com_categories/controllers/categories.php b/administrator/components/com_categories/controllers/categories.php deleted file mode 100644 index c501c16677ccd..0000000000000 --- a/administrator/components/com_categories/controllers/categories.php +++ /dev/null @@ -1,170 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Rebuild the nested set tree. - * - * @return boolean False on failure or error, true on success. - * - * @since 1.6 - */ - public function rebuild() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $extension = $this->input->get('extension'); - $this->setRedirect(JRoute::_('index.php?option=com_categories&view=categories&extension=' . $extension, false)); - - /** @var CategoriesModelCategory $model */ - $model = $this->getModel(); - - if ($model->rebuild()) - { - // Rebuild succeeded. - $this->setMessage(JText::_('COM_CATEGORIES_REBUILD_SUCCESS')); - - return true; - } - - // Rebuild failed. - $this->setMessage(JText::_('COM_CATEGORIES_REBUILD_FAILURE')); - - return false; - } - - /** - * Save the manual order inputs from the categories list page. - * - * @return void - * - * @since 1.6 - * @see JControllerAdmin::saveorder() - * @deprecated 4.0 - */ - public function saveorder() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - try - { - JLog::add(sprintf('%s() is deprecated. Function will be removed in 4.0.', __METHOD__), JLog::WARNING, 'deprecated'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Get the arrays from the Request - $order = $this->input->post->get('order', null, 'array'); - $originalOrder = explode(',', $this->input->getString('original_order_values')); - - // Make sure something has changed - if (!($order === $originalOrder)) - { - parent::saveorder(); - } - else - { - // Nothing to reorder - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); - - return true; - } - } - - /** - * Deletes and returns correctly. - * - * @return void - * - * @since 3.1.2 - */ - public function delete() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Get items to remove from the request. - $cid = $this->input->get('cid', array(), 'array'); - $extension = $this->input->getCmd('extension', null); - - if (!is_array($cid) || count($cid) < 1) - { - JError::raiseWarning(500, JText::_($this->text_prefix . '_NO_ITEM_SELECTED')); - } - else - { - // Get the model. - /** @var CategoriesModelCategory $model */ - $model = $this->getModel(); - - // Make sure the item ids are integers - $cid = ArrayHelper::toInteger($cid); - - // Remove the items. - if ($model->delete($cid)) - { - $this->setMessage(JText::plural($this->text_prefix . '_N_ITEMS_DELETED', count($cid))); - } - else - { - $this->setMessage($model->getError()); - } - } - - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&extension=' . $extension, false)); - } - - /** - * Check in of one or more records. - * - * Overrides JControllerAdmin::checkin to redirect to URL with extension. - * - * @return boolean True on success - * - * @since 3.6.0 - */ - public function checkin() - { - // Process parent checkin method. - $result = parent::checkin(); - - // Override the redirect Uri. - $redirectUri = 'index.php?option=' . $this->option . '&view=' . $this->view_list . '&extension=' . $this->input->get('extension', '', 'CMD'); - $this->setRedirect(JRoute::_($redirectUri, false), $this->message, $this->messageType); - - return $result; - } -} diff --git a/administrator/components/com_categories/controllers/category.php b/administrator/components/com_categories/controllers/category.php deleted file mode 100644 index d63b1110a969a..0000000000000 --- a/administrator/components/com_categories/controllers/category.php +++ /dev/null @@ -1,190 +0,0 @@ -extension)) - { - $this->extension = $this->input->get('extension', 'com_content'); - } - } - - /** - * Method to check if you can add a new record. - * - * @param array $data An array of input data. - * - * @return boolean - * - * @since 1.6 - */ - protected function allowAdd($data = array()) - { - $user = JFactory::getUser(); - - return ($user->authorise('core.create', $this->extension) || count($user->getAuthorisedCategories($this->extension, 'core.create'))); - } - - /** - * Method to check if you can edit a record. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. - * - * @return boolean - * - * @since 1.6 - */ - protected function allowEdit($data = array(), $key = 'parent_id') - { - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; - $user = JFactory::getUser(); - - // Check "edit" permission on record asset (explicit or inherited) - if ($user->authorise('core.edit', $this->extension . '.category.' . $recordId)) - { - return true; - } - - // Check "edit own" permission on record asset (explicit or inherited) - if ($user->authorise('core.edit.own', $this->extension . '.category.' . $recordId)) - { - // Need to do a lookup from the model to get the owner - $record = $this->getModel()->getItem($recordId); - - if (empty($record)) - { - return false; - } - - $ownerId = $record->created_user_id; - - // If the owner matches 'me' then do the test. - if ($ownerId == $user->id) - { - return true; - } - } - - return false; - } - - /** - * Method to run batch operations. - * - * @param object $model The model. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 1.6 - */ - public function batch($model = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Set the model - /** @var CategoriesModelCategory $model */ - $model = $this->getModel('Category'); - - // Preset the redirect - $this->setRedirect('index.php?option=com_categories&view=categories&extension=' . $this->extension); - - return parent::batch($model); - } - - /** - * Gets the URL arguments to append to an item redirect. - * - * @param integer $recordId The primary key id for the item. - * @param string $urlVar The name of the URL variable for the id. - * - * @return string The arguments to append to the redirect URL. - * - * @since 1.6 - */ - protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') - { - $append = parent::getRedirectToItemAppend($recordId); - $append .= '&extension=' . $this->extension; - - return $append; - } - - /** - * Gets the URL arguments to append to a list redirect. - * - * @return string The arguments to append to the redirect URL. - * - * @since 1.6 - */ - protected function getRedirectToListAppend() - { - $append = parent::getRedirectToListAppend(); - $append .= '&extension=' . $this->extension; - - return $append; - } - - /** - * 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.1 - */ - protected function postSaveHook(JModelLegacy $model, $validData = array()) - { - $item = $model->getItem(); - - if (isset($item->params) && is_array($item->params)) - { - $registry = new Registry($item->params); - $item->params = (string) $registry; - } - - if (isset($item->metadata) && is_array($item->metadata)) - { - $registry = new Registry($item->metadata); - $item->metadata = (string) $registry; - } - } -} diff --git a/administrator/components/com_categories/dispatcher.php b/administrator/components/com_categories/dispatcher.php new file mode 100644 index 0000000000000..4e54a27f17c5b --- /dev/null +++ b/administrator/components/com_categories/dispatcher.php @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+
+ + + +
+ + + + + + + + + + +
+
+ diff --git a/administrator/components/com_categories/models/forms/filter_categories.xml b/administrator/components/com_categories/forms/filter_categories.xml similarity index 75% rename from administrator/components/com_categories/models/forms/filter_categories.xml rename to administrator/components/com_categories/forms/filter_categories.xml index 5573d4aba3f94..9bd646061fa7c 100644 --- a/administrator/components/com_categories/models/forms/filter_categories.xml +++ b/administrator/components/com_categories/forms/filter_categories.xml @@ -14,8 +14,6 @@ @@ -24,8 +22,6 @@ @@ -34,8 +30,6 @@ @@ -45,8 +39,6 @@ @@ -56,8 +48,6 @@ JGRID_HEADING_ACCESS_DESC - - + + @@ -99,10 +87,7 @@ diff --git a/administrator/components/com_categories/helpers/association.php b/administrator/components/com_categories/helpers/association.php index 67196ee95aa25..770af18d88076 100644 --- a/administrator/components/com_categories/helpers/association.php +++ b/administrator/components/com_categories/helpers/association.php @@ -9,7 +9,7 @@ defined('_JEXEC') or die; -JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); +use Joomla\Component\Categories\Administrator\Helper\CategoriesHelper; /** * Category Component Association Helper @@ -36,8 +36,6 @@ public static function getCategoryAssociations($id = 0, $extension = 'com_conten if ($id) { - // Load route helper - jimport('helper.route', JPATH_COMPONENT_SITE); $helperClassname = ucfirst(substr($extension, 4)) . 'HelperRoute'; $associations = CategoriesHelper::getAssociations($id, $extension); diff --git a/administrator/components/com_categories/helpers/categories.php b/administrator/components/com_categories/helpers/categories.php index 6b10a6c8dfe92..b2e1a279758f3 100644 --- a/administrator/components/com_categories/helpers/categories.php +++ b/administrator/components/com_categories/helpers/categories.php @@ -14,175 +14,7 @@ * * @since 1.6 */ -class CategoriesHelper +class CategoriesHelper extends \Joomla\Component\Categories\Administrator\Helper\CategoriesHelper { - /** - * Configure the Submenu links. - * - * @param string $extension The extension being used for the categories. - * - * @return void - * - * @since 1.6 - */ - public static function addSubmenu($extension) - { - // Avoid nonsense situation. - if ($extension == 'com_categories') - { - return; - } - $parts = explode('.', $extension); - $component = $parts[0]; - - if (count($parts) > 1) - { - $section = $parts[1]; - } - - // Try to find the component helper. - $eName = str_replace('com_', '', $component); - $file = JPath::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)) - { - if (is_callable(array($cName, 'addSubmenu'))) - { - $lang = JFactory::getLanguage(); - - // Loading language file from the administrator/language directory then - // loading language file from the administrator/components/*extension*/language directory - $lang->load($component, JPATH_BASE, null, false, true) - || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); - - call_user_func(array($cName, 'addSubmenu'), 'categories' . (isset($section) ? '.' . $section : '')); - } - } - } - } - - /** - * Gets a list of the actions that can be performed. - * - * @param string $extension The extension. - * @param integer $categoryId The category ID. - * - * @return JObject - * - * @since 1.6 - * @deprecated 3.2 Use JHelperContent::getActions() instead - */ - public static function getActions($extension, $categoryId = 0) - { - // Log usage of deprecated function - try - { - JLog::add( - sprintf('%s() is deprecated, use JHelperContent::getActions() with new arguments order instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Get list of actions - return JHelperContent::getActions($extension, 'category', $categoryId); - } - - /** - * Gets a list of associations for a given item. - * - * @param integer $pk Content item key. - * @param string $extension Optional extension name. - * - * @return array of associations. - */ - public static function getAssociations($pk, $extension = 'com_content') - { - $langAssociations = JLanguageAssociations::getAssociations($extension, '#__categories', 'com_categories.item', $pk, 'id', 'alias', ''); - $associations = array(); - $user = JFactory::getUser(); - $groups = implode(',', $user->getAuthorisedViewLevels()); - - foreach ($langAssociations as $langAssociation) - { - // 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; - } - - /** - * Check if Category ID exists otherwise assign to ROOT category. - * - * @param mixed $catid Name or ID of category. - * @param string $extension Extension that triggers this function - * - * @return integer $catid Category ID. - */ - public static function validateCategoryId($catid, $extension) - { - JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables'); - - $categoryTable = JTable::getInstance('Category'); - - $data = array(); - $data['id'] = $catid; - $data['extension'] = $extension; - - if (!$categoryTable->load($data)) - { - $catid = 0; - } - - return (int) $catid; - } - - /** - * Create new Category from within item view. - * - * @param array $data Array of data for new category. - * - * @return integer - */ - public static function createCategory($data) - { - JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/models'); - JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_categories/tables'); - - $categoryModel = JModelLegacy::getInstance('Category', 'CategoriesModel', array('ignore_request' => true)); - $categoryModel->save($data); - - $catid = $categoryModel->getState('category.id'); - - return $catid; - } } diff --git a/administrator/components/com_categories/helpers/html/categoriesadministrator.php b/administrator/components/com_categories/helpers/html/categoriesadministrator.php index 0d54843e86ecb..c0bd1e2d5ccc3 100644 --- a/administrator/components/com_categories/helpers/html/categoriesadministrator.php +++ b/administrator/components/com_categories/helpers/html/categoriesadministrator.php @@ -10,8 +10,10 @@ defined('_JEXEC') or die; use Joomla\Utilities\ArrayHelper; - -JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); +use Joomla\Component\Categories\Administrator\Helper\CategoriesHelper; +use Joomla\CMS\Router\Route; +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; /** * Administrator category HTML @@ -42,7 +44,7 @@ public static function association($catid, $extension = 'com_content') $associations = ArrayHelper::toInteger($associations); // Get the associated categories - $db = JFactory::getDbo(); + $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('c.id, c.title') ->select('l.sef as lang_sef') @@ -68,19 +70,18 @@ public static function association($catid, $extension = 'com_content') { foreach ($items as &$item) { - $text = $item->lang_sef ? strtoupper($item->lang_sef) : 'XX'; - $url = JRoute::_('index.php?option=com_categories&task=category.edit&id=' . (int) $item->id . '&extension=' . $extension); - $classes = 'hasPopover label label-association label-' . $item->lang_sef; - + $text = $item->lang_sef ? strtoupper($item->lang_sef) : 'XX'; + $url = Route::_('index.php?option=com_categories&task=category.edit&id=' . (int) $item->id . '&extension=' . $extension); + $classes = 'hasPopover badge badge-secondary'; $item->link = '' . $text . ''; } } - JHtml::_('bootstrap.popover'); + HTMLHelper::_('bootstrap.popover'); - $html = JLayoutHelper::render('joomla.content.associations', $items); + $html = \Joomla\CMS\Layout\LayoutHelper::render('joomla.content.associations', $items); } return $html; diff --git a/administrator/components/com_categories/models/categories.php b/administrator/components/com_categories/models/categories.php deleted file mode 100644 index 9f04ecae1e5df..0000000000000 --- a/administrator/components/com_categories/models/categories.php +++ /dev/null @@ -1,404 +0,0 @@ -input->get('forcedLanguage', '', 'cmd'); - - // Adjust the context to support modal layouts. - if ($layout = $app->input->get('layout')) - { - $this->context .= '.' . $layout; - } - - // Adjust the context to support forced languages. - if ($forcedLanguage) - { - $this->context .= '.' . $forcedLanguage; - } - - $extension = $app->getUserStateFromRequest($this->context . '.filter.extension', 'extension', 'com_content', 'cmd'); - - $this->setState('filter.extension', $extension); - $parts = explode('.', $extension); - - // Extract the component name - $this->setState('filter.component', $parts[0]); - - // Extract the optional section name - $this->setState('filter.section', (count($parts) > 1) ? $parts[1] : null); - - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.search', 'filter_search', '', 'string')); - $this->setState('filter.published', $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string')); - $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'cmd')); - $this->setState('filter.language', $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', '', 'string')); - $this->setState('filter.tag', $this->getUserStateFromRequest($this->context . '.filter.tag', 'filter_tag', '', 'string')); - $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'string')); - - // List state information. - parent::populateState($ordering, $direction); - - // Force a language. - if (!empty($forcedLanguage)) - { - $this->setState('filter.language', $forcedLanguage); - } - } - - /** - * 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 A store id. - * - * @since 1.6 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.extension'); - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.published'); - $id .= ':' . $this->getState('filter.access'); - $id .= ':' . $this->getState('filter.language'); - $id .= ':' . $this->getState('filter.level'); - $id .= ':' . $this->getState('filter.tag'); - - return parent::getStoreId($id); - } - - /** - * Method to get a database query to list categories. - * - * @return JDatabaseQuery object. - * - * @since 1.6 - */ - protected function getListQuery() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - $user = JFactory::getUser(); - - // Select the required fields from the table. - $query->select( - $this->getState( - 'list.select', - 'a.id, a.title, a.alias, a.note, a.published, a.access' . - ', a.checked_out, a.checked_out_time, a.created_user_id' . - ', a.path, a.parent_id, a.level, a.lft, a.rgt' . - ', a.language' - ) - ); - $query->from('#__categories AS a'); - - // Join over the language - $query->select('l.title AS language_title, l.image AS language_image') - ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); - - // Join over the users for the checked out user. - $query->select('uc.name AS editor') - ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); - - // Join over the asset groups. - $query->select('ag.title AS access_level') - ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); - - // Join over the users for the author. - $query->select('ua.name AS author_name') - ->join('LEFT', '#__users AS ua ON ua.id = a.created_user_id'); - - // Join over the associations. - $assoc = $this->getAssoc(); - - 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_categories.item')) - ->join('LEFT', '#__associations AS asso2 ON asso2.key = asso.key') - ->group('a.id, l.title, uc.name, ag.title, ua.name'); - } - - // Filter by extension - if ($extension = $this->getState('filter.extension')) - { - $query->where('a.extension = ' . $db->quote($extension)); - } - - // Filter on the level. - if ($level = $this->getState('filter.level')) - { - $query->where('a.level <= ' . (int) $level); - } - - // Filter by access level. - if ($access = $this->getState('filter.access')) - { - $query->where('a.access = ' . (int) $access); - } - - // Implement View Level Access - if (!$user->authorise('core.admin')) - { - $groups = implode(',', $user->getAuthorisedViewLevels()); - $query->where('a.access IN (' . $groups . ')'); - } - - // Filter by published state - $published = $this->getState('filter.published'); - - if (is_numeric($published)) - { - $query->where('a.published = ' . (int) $published); - } - elseif ($published === '') - { - $query->where('(a.published IN (0, 1))'); - } - - // Filter by search in title - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); - } - } - - // Filter on the language. - if ($language = $this->getState('filter.language')) - { - $query->where('a.language = ' . $db->quote($language)); - } - - // Filter by a single tag. - $tagId = $this->getState('filter.tag'); - - if (is_numeric($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($extension . '.category') - ); - } - - // Add the list ordering clause - $listOrdering = $this->getState('list.ordering', 'a.lft'); - $listDirn = $db->escape($this->getState('list.direction', 'ASC')); - - if ($listOrdering == 'a.access') - { - $query->order('a.access ' . $listDirn . ', a.lft ' . $listDirn); - } - else - { - $query->order($db->escape($listOrdering) . ' ' . $listDirn); - } - - // Group by on Categories for JOIN with component tables to count items - $query->group('a.id, - a.title, - a.alias, - a.note, - a.published, - a.access, - a.checked_out, - a.checked_out_time, - a.created_user_id, - a.path, - a.parent_id, - a.level, - a.lft, - a.rgt, - a.language, - l.title, - l.image, - uc.name, - ag.title, - ua.name' - ); - - return $query; - } - - /** - * Method to determine if an association exists - * - * @return boolean True if the association exists - * - * @since 3.0 - */ - public function getAssoc() - { - static $assoc = null; - - if (!is_null($assoc)) - { - return $assoc; - } - - $extension = $this->getState('filter.extension'); - - $assoc = JLanguageAssociations::isEnabled(); - $extension = explode('.', $extension); - $component = array_shift($extension); - $cname = str_replace('com_', '', $component); - - if (!$assoc || !$component || !$cname) - { - $assoc = false; - } - else - { - $hname = $cname . 'HelperAssociation'; - JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); - - $assoc = class_exists($hname) && !empty($hname::$category_association); - } - - return $assoc; - } - - /** - * Method to get an array of data items. - * - * @return mixed An array of data items on success, false on failure. - * - * @since 12.2 - */ - public function getItems() - { - $items = parent::getItems(); - - if ($items != false) - { - $extension = $this->getState('filter.extension'); - - $this->countItems($items, $extension); - } - - return $items; - } - - /** - * Method to load the countItems method from the extensions - * - * @param stdClass[] &$items The category items - * @param string $extension The category extension - * - * @return void - * - * @since 3.5 - */ - public function countItems(&$items, $extension) - { - $parts = explode('.', $extension, 2); - $component = $parts[0]; - $section = null; - - if (count($parts) > 1) - { - $section = $parts[1]; - } - - // Try to find the component helper. - $eName = str_replace('com_', '', $component); - $file = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php'); - - if (file_exists($file)) - { - $prefix = ucfirst($eName); - $cName = $prefix . 'Helper'; - - JLoader::register($cName, $file); - - if (class_exists($cName) && is_callable(array($cName, 'countItems'))) - { - $cName::countItems($items, $section); - } - } - } -} diff --git a/administrator/components/com_categories/models/category.php b/administrator/components/com_categories/models/category.php deleted file mode 100644 index 144ecd09e0a82..0000000000000 --- a/administrator/components/com_categories/models/category.php +++ /dev/null @@ -1,1332 +0,0 @@ -input->get('extension', 'com_content'); - $this->typeAlias = $extension . '.category'; - - // Add a new batch command - $this->batch_commands['flip_ordering'] = 'batchFlipordering'; - } - - /** - * Method to test whether a record can be deleted. - * - * @param object $record A record object. - * - * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. - * - * @since 1.6 - */ - protected function canDelete($record) - { - if (empty($record->id) || $record->published != -2) - { - return false; - } - - return JFactory::getUser()->authorise('core.delete', $record->extension . '.category.' . (int) $record->id); - } - - /** - * 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 1.6 - */ - protected function canEditState($record) - { - $user = JFactory::getUser(); - - // Check for existing category. - if (!empty($record->id)) - { - return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->id); - } - - // New category, so check against the parent. - if (!empty($record->parent_id)) - { - return $user->authorise('core.edit.state', $record->extension . '.category.' . (int) $record->parent_id); - } - - // Default to component settings if neither category nor parent known. - return $user->authorise('core.edit.state', $record->extension); - } - - /** - * Method to get a table object, load it if necessary. - * - * @param string $type The table name. Optional. - * @param string $prefix The class prefix. Optional. - * @param array $config Configuration array for model. Optional. - * - * @return JTable A JTable object - * - * @since 1.6 - */ - public function getTable($type = 'Category', $prefix = 'CategoriesTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Auto-populate the model state. - * - * Note. Calling getState in this method will result in recursion. - * - * @return void - * - * @since 1.6 - */ - protected function populateState() - { - $app = JFactory::getApplication('administrator'); - - $parentId = $app->input->getInt('parent_id'); - $this->setState('category.parent_id', $parentId); - - // Load the User state. - $pk = $app->input->getInt('id'); - $this->setState($this->getName() . '.id', $pk); - - $extension = $app->input->get('extension', 'com_content'); - $this->setState('category.extension', $extension); - $parts = explode('.', $extension); - - // Extract the component name - $this->setState('category.component', $parts[0]); - - // Extract the optional section name - $this->setState('category.section', (count($parts) > 1) ? $parts[1] : null); - - // Load the parameters. - $params = JComponentHelper::getParams('com_categories'); - $this->setState('params', $params); - } - - /** - * Method to get a category. - * - * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. - * - * @return mixed Category data object on success, false on failure. - * - * @since 1.6 - */ - public function getItem($pk = null) - { - if ($result = parent::getItem($pk)) - { - // Prime required properties. - if (empty($result->id)) - { - $result->parent_id = $this->getState('category.parent_id'); - $result->extension = $this->getState('category.extension'); - } - - // Convert the metadata field to an array. - $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; - $result->tags->getTagIds($result->id, $result->extension . '.category'); - } - } - - $assoc = $this->getAssoc(); - - if ($assoc) - { - if ($result->id != null) - { - $result->associations = ArrayHelper::toInteger(CategoriesHelper::getAssociations($result->id, $result->extension)); - } - else - { - $result->associations = array(); - } - } - - return $result; - } - - /** - * Method to get the row form. - * - * @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 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - $extension = $this->getState('category.extension'); - $jinput = JFactory::getApplication()->input; - - // A workaround to get the extension into the model for save requests. - if (empty($extension) && isset($data['extension'])) - { - $extension = $data['extension']; - $parts = explode('.', $extension); - - $this->setState('category.extension', $extension); - $this->setState('category.component', $parts[0]); - $this->setState('category.section', @$parts[1]); - } - - // Get the form. - $form = $this->loadForm('com_categories.category' . $extension, 'category', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - // Modify the form based on Edit State access controls. - if (empty($data['extension'])) - { - $data['extension'] = $extension; - } - - $categoryId = $jinput->get('id'); - $parts = explode('.', $extension); - $assetKey = $categoryId ? $extension . '.category.' . $categoryId : $parts[0]; - - if (!JFactory::getUser()->authorise('core.edit.state', $assetKey)) - { - // Disable fields for display. - $form->setFieldAttribute('ordering', 'disabled', 'true'); - $form->setFieldAttribute('published', 'disabled', 'true'); - - // Disable fields while saving. - // The controller has already verified this is a record you can edit. - $form->setFieldAttribute('ordering', 'filter', 'unset'); - $form->setFieldAttribute('published', 'filter', 'unset'); - } - - return $form; - } - - /** - * A protected method to get the where clause for the reorder - * This ensures that the row will be moved relative to a row with the same extension - * - * @param JTableCategory $table Current table instance - * - * @return array An array of conditions to add to add to ordering queries. - * - * @since 1.6 - */ - protected function getReorderConditions($table) - { - return 'extension = ' . $this->_db->quote($table->extension); - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $app = JFactory::getApplication(); - $data = $app->getUserState('com_categories.edit.' . $this->getName() . '.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - - // Pre-select some filters (Status, Language, Access) in edit form if those have been selected in Category Manager - if (!$data->id) - { - // Check for which extension the Category Manager is used and get selected fields - $extension = substr($app->getUserState('com_categories.categories.filter.extension'), 4); - $filters = (array) $app->getUserState('com_categories.categories.' . $extension . '.filter'); - - $data->set( - 'published', - $app->input->getInt( - 'published', - ((isset($filters['published']) && $filters['published'] !== '') ? $filters['published'] : null) - ) - ); - $data->set('language', $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null))); - $data->set( - 'access', - $app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access'))) - ); - } - } - - $this->preprocessData('com_categories.category', $data); - - return $data; - } - - /** - * Method to preprocess the form. - * - * @param JForm $form A JForm object. - * @param mixed $data The data expected for the form. - * @param string $group The name of the plugin group to import. - * - * @return void - * - * @see JFormField - * @since 1.6 - * @throws Exception if there is an error in the form event. - */ - protected function preprocessForm(JForm $form, $data, $group = 'content') - { - jimport('joomla.filesystem.path'); - - $lang = JFactory::getLanguage(); - $component = $this->getState('category.component'); - $section = $this->getState('category.section'); - $extension = JFactory::getApplication()->input->get('extension', null); - - // Get the component form if it exists - $name = 'category' . ($section ? ('.' . $section) : ''); - - // Looking first in the component models/forms folder - $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/models/forms/$name.xml"); - - // Old way: looking in the component folder - if (!file_exists($path)) - { - $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/$name.xml"); - } - - if (file_exists($path)) - { - $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')); - } - } - - // Try to find the component helper. - $eName = str_replace('com_', '', $component); - $path = JPath::clean(JPATH_ADMINISTRATOR . "/components/$component/helpers/category.php"); - - if (file_exists($path)) - { - $cName = ucfirst($eName) . ucfirst($section) . 'HelperCategory'; - - JLoader::register($cName, $path); - - if (class_exists($cName) && is_callable(array($cName, 'onPrepareForm'))) - { - $lang->load($component, JPATH_BASE, null, false, false) - || $lang->load($component, JPATH_BASE . '/components/' . $component, null, false, false) - || $lang->load($component, JPATH_BASE, $lang->getDefault(), false, false) - || $lang->load($component, JPATH_BASE . '/components/' . $component, $lang->getDefault(), false, false); - call_user_func_array(array($cName, 'onPrepareForm'), array(&$form)); - - // Check for an error. - if ($form instanceof Exception) - { - $this->setError($form->getMessage()); - - return false; - } - } - } - - // Set the access control rules field component value. - $form->setFieldAttribute('rules', 'component', $component); - $form->setFieldAttribute('rules', 'section', $name); - - // Association category items - if ($this->getAssoc()) - { - $languages = JLanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc'); - - if (count($languages) > 1) - { - $addform = new SimpleXMLElement('
'); - $fields = $addform->addChild('fields'); - $fields->addAttribute('name', 'associations'); - $fieldset = $fields->addChild('fieldset'); - $fieldset->addAttribute('name', 'item_associations'); - - foreach ($languages as $language) - { - $field = $fieldset->addChild('field'); - $field->addAttribute('name', $language->lang_code); - $field->addAttribute('type', 'modal_category'); - $field->addAttribute('language', $language->lang_code); - $field->addAttribute('label', $language->title); - $field->addAttribute('translate_label', 'false'); - $field->addAttribute('extension', $extension); - $field->addAttribute('select', 'true'); - $field->addAttribute('new', 'true'); - $field->addAttribute('edit', 'true'); - $field->addAttribute('clear', 'true'); - } - - $form->load($addform, false); - } - } - - // Trigger the default form events. - parent::preprocessForm($form, $data, $group); - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function save($data) - { - $dispatcher = JEventDispatcher::getInstance(); - $table = $this->getTable(); - $input = JFactory::getApplication()->input; - $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState($this->getName() . '.id'); - $isNew = true; - $context = $this->option . '.' . $this->name; - - if (!empty($data['tags']) && $data['tags'][0] != '') - { - $table->newTags = $data['tags']; - } - - // Include the plugins for the save events. - JPluginHelper::importPlugin($this->events_map['save']); - - // Load the row if saving an existing category. - if ($pk > 0) - { - $table->load($pk); - $isNew = false; - } - - // Set the new parent id if parent id not matched OR while New/Save as Copy . - if ($table->parent_id != $data['parent_id'] || $data['id'] == 0) - { - $table->setLocation($data['parent_id'], 'last-child'); - } - - // Alter the title for save as copy - if ($input->get('task') == 'save2copy') - { - $origTable = clone $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; - } - else - { - if ($data['alias'] == $origTable->alias) - { - $data['alias'] = ''; - } - } - - $data['published'] = 0; - } - - // Bind the data. - if (!$table->bind($data)) - { - $this->setError($table->getError()); - - return false; - } - - // Bind the rules. - if (isset($data['rules'])) - { - $rules = new JAccessRules($data['rules']); - $table->setRules($rules); - } - - // Check the data. - if (!$table->check()) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the before save event. - $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, $isNew, $data)); - - if (in_array(false, $result, true)) - { - $this->setError($table->getError()); - - return false; - } - - // Store the data. - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - - $assoc = $this->getAssoc(); - - if ($assoc) - { - // Adding self to the association - $associations = isset($data['associations']) ? $data['associations'] : array(); - - // Unset any invalid associations - $associations = Joomla\Utilities\ArrayHelper::toInteger($associations); - - foreach ($associations as $tag => $id) - { - if (!$id) - { - unset($associations[$tag]); - } - } - - // Detecting all item menus - $allLanguage = $table->language == '*'; - - if ($allLanguage && !empty($associations)) - { - JError::raiseNotice(403, JText::_('COM_CATEGORIES_ERROR_ALL_LANGUAGE_ASSOCIATED')); - } - - // Get associationskey for edited item - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('key')) - ->from($db->quoteName('#__associations')) - ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)) - ->where($db->quoteName('id') . ' = ' . (int) $table->id); - $db->setQuery($query); - $oldKey = $db->loadResult(); - - // Deleting old associations for the associated items - $query = $db->getQuery(true) - ->delete($db->quoteName('#__associations')) - ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)); - - if ($associations) - { - $query->where('(' . $db->quoteName('id') . ' IN (' . implode(',', $associations) . ') OR ' - . $db->quoteName('key') . ' = ' . $db->quote($oldKey) . ')'); - } - else - { - $query->where($db->quoteName('key') . ' = ' . $db->quote($oldKey)); - } - - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Adding self to the association - if (!$allLanguage) - { - $associations[$table->language] = (int) $table->id; - } - - if (count($associations) > 1) - { - // Adding new association for these items - $key = md5(json_encode($associations)); - $query->clear() - ->insert('#__associations'); - - foreach ($associations as $id) - { - $query->values(((int) $id) . ',' . $db->quote($this->associationsContext) . ',' . $db->quote($key)); - } - - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - } - } - - // Trigger the after save event. - $dispatcher->trigger($this->event_after_save, array($context, &$table, $isNew, $data)); - - // Rebuild the path for the category: - if (!$table->rebuildPath($table->id)) - { - $this->setError($table->getError()); - - return false; - } - - // Rebuild the paths of the category's children: - if (!$table->rebuild($table->id, $table->lft, $table->level, $table->path)) - { - $this->setError($table->getError()); - - return false; - } - - $this->setState($this->getName() . '.id', $table->id); - - // Clear the cache - $this->cleanCache(); - - return true; - } - - /** - * Method to change the published state of one or more records. - * - * @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. - * - * @since 2.5 - */ - public function publish(&$pks, $value = 1) - { - if (parent::publish($pks, $value)) - { - $dispatcher = JEventDispatcher::getInstance(); - $extension = JFactory::getApplication()->input->get('extension'); - - // Include the content plugins for the change of category state event. - JPluginHelper::importPlugin('content'); - - // Trigger the onCategoryChangeState event. - $dispatcher->trigger('onCategoryChangeState', array($extension, $pks, $value)); - - return true; - } - } - - /** - * Method rebuild the entire nested set tree. - * - * @return boolean False on failure or error, true otherwise. - * - * @since 1.6 - */ - public function rebuild() - { - // Get an instance of the table object. - $table = $this->getTable(); - - if (!$table->rebuild()) - { - $this->setError($table->getError()); - - return false; - } - - // Clear the cache - $this->cleanCache(); - - return true; - } - - /** - * Method to save the reordered nested set tree. - * 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 - * - * @return boolean False on failure or error, True otherwise - * - * @since 1.6 - */ - public function saveorder($idArray = null, $lft_array = null) - { - // Get an instance of the table object. - $table = $this->getTable(); - - if (!$table->saveorder($idArray, $lft_array)) - { - $this->setError($table->getError()); - - return false; - } - - // Clear the cache - $this->cleanCache(); - - return true; - } - - /** - * Batch tag a list of categories. - * - * @param integer $value The value of the new tag. - * @param array $pks An array of row IDs. - * @param array $contexts An array of item contexts. - * - * @return boolean true if successful; false otherwise. - */ - protected function batchTag($value, $pks, $contexts) - { - // Set the variables - $user = JFactory::getUser(); - $table = $this->getTable(); - - foreach ($pks as $pk) - { - if ($user->authorise('core.edit', $contexts[$pk])) - { - $table->reset(); - $table->load($pk); - $tags = array($value); - - /** @var JTableObserverTags $tagsObserver */ - $tagsObserver = $table->getObserverOfClass('JTableObserverTags'); - $result = $tagsObserver->setNewTags($tags, false); - - if (!$result) - { - $this->setError($table->getError()); - - return false; - } - } - else - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); - - return false; - } - } - - // Clean the cache - $this->cleanCache(); - - 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. - * - * @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 1.6 - */ - protected function batchCopy($value, $pks, $contexts) - { - $type = new JUcmType; - $this->type = $type->getTypeByAlias($this->typeAlias); - - // $value comes as {parent_id}.{extension} - $parts = explode('.', $value); - $parentId = (int) ArrayHelper::getValue($parts, 0, 1); - - $db = $this->getDbo(); - $extension = JFactory::getApplication()->input->get('extension', '', 'word'); - $newIds = array(); - - // Check that the parent exists - if ($parentId) - { - if (!$this->table->load($parentId)) - { - if ($error = $this->table->getError()) - { - // Fatal error - $this->setError($error); - - return false; - } - else - { - // Non-fatal error - $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); - $parentId = 0; - } - } - - // Check that user has create permission for parent category - if ($parentId == $this->table->getRootId()) - { - $canCreate = $this->user->authorise('core.create', $extension); - } - else - { - $canCreate = $this->user->authorise('core.create', $extension . '.category.' . $parentId); - } - - if (!$canCreate) - { - // Error since user cannot create in parent category - $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); - - return false; - } - } - - // If the parent is 0, set it to the ID of the root item in the tree - if (empty($parentId)) - { - if (!$parentId = $this->table->getRootId()) - { - $this->setError($db->getErrorMsg()); - - return false; - } - // Make sure we can create in root - elseif (!$this->user->authorise('core.create', $extension)) - { - $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); - - return false; - } - } - - // We need to log the parent ID - $parents = array(); - - // Calculate the emergency stop count as a precaution against a runaway loop bug - $query = $db->getQuery(true) - ->select('COUNT(id)') - ->from($db->quoteName('#__categories')); - $db->setQuery($query); - - try - { - $count = $db->loadResult(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Parent exists so let's proceed - while (!empty($pks) && $count > 0) - { - // 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('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); - continue; - } - } - - // Copy is a bit tricky, because we also need to copy the children - $query->clear() - ->select('id') - ->from($db->quoteName('#__categories')) - ->where('lft > ' . (int) $this->table->lft) - ->where('rgt < ' . (int) $this->table->rgt); - $db->setQuery($query); - $childIds = $db->loadColumn(); - - // Add child ID's to the array only if they aren't already there. - foreach ($childIds as $childId) - { - if (!in_array($childId, $pks)) - { - $pks[] = $childId; - } - } - - // Make a copy of the old ID and Parent ID - $oldId = $this->table->id; - $oldParentId = $this->table->parent_id; - - // Reset the id because we are making a copy. - $this->table->id = 0; - - // If we a copying children, the Old ID will turn up in the parents list - // otherwise it's a new top level item - $this->table->parent_id = isset($parents[$oldParentId]) ? $parents[$oldParentId] : $parentId; - - // Set the new location in the tree for the node. - $this->table->setLocation($this->table->parent_id, 'last-child'); - - // @TODO: Deal with ordering? - // $this->table->ordering = 1; - $this->table->level = null; - $this->table->asset_id = null; - $this->table->lft = null; - $this->table->rgt = null; - - // Alter the title & alias - list($title, $alias) = $this->generateNewTitle($this->table->parent_id, $this->table->alias, $this->table->title); - $this->table->title = $title; - $this->table->alias = $alias; - - // Unpublish because we are making a copy - $this->table->published = 0; - - $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; - - // Now we log the old 'parent' to the new 'parent' - $parents[$oldId] = $this->table->id; - $count--; - } - - // Rebuild the hierarchy. - if (!$this->table->rebuild()) - { - $this->setError($this->table->getError()); - - return false; - } - - // Rebuild the tree path. - if (!$this->table->rebuildPath($this->table->id)) - { - $this->setError($this->table->getError()); - - return false; - } - - return $newIds; - } - - /** - * 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 boolean True on success. - * - * @since 1.6 - */ - protected function batchMove($value, $pks, $contexts) - { - $parentId = (int) $value; - $type = new JUcmType; - $this->type = $type->getTypeByAlias($this->typeAlias); - - $db = $this->getDbo(); - $query = $db->getQuery(true); - $extension = JFactory::getApplication()->input->get('extension', '', 'word'); - - // Check that the parent exists. - if ($parentId) - { - if (!$this->table->load($parentId)) - { - if ($error = $this->table->getError()) - { - // Fatal error. - $this->setError($error); - - return false; - } - else - { - // Non-fatal error. - $this->setError(JText::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); - $parentId = 0; - } - } - - // Check that user has create permission for parent category. - if ($parentId == $this->table->getRootId()) - { - $canCreate = $this->user->authorise('core.create', $extension); - } - else - { - $canCreate = $this->user->authorise('core.create', $extension . '.category.' . $parentId); - } - - if (!$canCreate) - { - // Error since user cannot create in parent category - $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_CREATE')); - - return false; - } - - // Check that user has edit permission for every category being moved - // Note that the entire batch operation fails if any category lacks edit permission - foreach ($pks as $pk) - { - if (!$this->user->authorise('core.edit', $extension . '.category.' . $pk)) - { - // Error since user cannot edit this category - $this->setError(JText::_('COM_CATEGORIES_BATCH_CANNOT_EDIT')); - - return false; - } - } - } - - // We are going to store all the children and just move the category - $children = array(); - - // Parent exists so let's proceed - foreach ($pks as $pk) - { - // 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('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); - continue; - } - } - - // Set the new location in the tree for the node. - $this->table->setLocation($parentId, 'last-child'); - - // Check if we are moving to a different parent - if ($parentId != $this->table->parent_id) - { - // Add the child node ids to the children array. - $query->clear() - ->select('id') - ->from($db->quoteName('#__categories')) - ->where($db->quoteName('lft') . ' BETWEEN ' . (int) $this->table->lft . ' AND ' . (int) $this->table->rgt); - $db->setQuery($query); - - try - { - $children = array_merge($children, (array) $db->loadColumn()); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - 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; - } - - // Rebuild the tree path. - if (!$this->table->rebuildPath()) - { - $this->setError($this->table->getError()); - - return false; - } - } - - // Process the child rows - if (!empty($children)) - { - // Remove any duplicates and sanitize ids. - $children = array_unique($children); - $children = ArrayHelper::toInteger($children); - } - - return true; - } - - /** - * Custom clean the cache of com_content and content modules - * - * @param string $group Cache group name. - * @param integer $client_id Application client id. - * - * @return void - * - * @since 1.6 - */ - protected function cleanCache($group = null, $client_id = 0) - { - $extension = JFactory::getApplication()->input->get('extension'); - - switch ($extension) - { - case 'com_content': - parent::cleanCache('com_content'); - parent::cleanCache('mod_articles_archive'); - parent::cleanCache('mod_articles_categories'); - parent::cleanCache('mod_articles_category'); - parent::cleanCache('mod_articles_latest'); - parent::cleanCache('mod_articles_news'); - parent::cleanCache('mod_articles_popular'); - break; - default: - parent::cleanCache($extension); - break; - } - } - - /** - * 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. - * - * @return array Contains the modified title and alias. - * - * @since 1.7 - */ - protected function generateNewTitle($parent_id, $alias, $title) - { - // Alter the title & alias - $table = $this->getTable(); - - while ($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) - { - $title = StringHelper::increment($title); - $alias = StringHelper::increment($alias, 'dash'); - } - - return array($title, $alias); - } - - /** - * Method to determine if a category association is available. - * - * @return boolean True if a category association is available; false otherwise. - */ - public function getAssoc() - { - static $assoc = null; - - if (!is_null($assoc)) - { - return $assoc; - } - - $extension = $this->getState('category.extension'); - - $assoc = JLanguageAssociations::isEnabled(); - $extension = explode('.', $extension); - $component = array_shift($extension); - $cname = str_replace('com_', '', $component); - - if (!$assoc || !$component || !$cname) - { - $assoc = false; - } - else - { - $hname = $cname . 'HelperAssociation'; - JLoader::register($hname, JPATH_SITE . '/components/' . $component . '/helpers/association.php'); - - $assoc = class_exists($hname) && !empty($hname::$category_association); - } - - return $assoc; - } -} diff --git a/administrator/components/com_categories/models/fields/categoryedit.php b/administrator/components/com_categories/models/fields/categoryedit.php deleted file mode 100644 index f655a6ab2f0e1..0000000000000 --- a/administrator/components/com_categories/models/fields/categoryedit.php +++ /dev/null @@ -1,428 +0,0 @@ - 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.2 - */ - public function setup(SimpleXMLElement $element, $value, $group = null) - { - $return = parent::setup($element, $value, $group); - - if ($return) - { - $this->allowAdd = isset($this->element['allowAdd']) ? $this->element['allowAdd'] : ''; - } - - return $return; - } - - /** - * 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.6 - */ - public function __get($name) - { - switch ($name) - { - case 'allowAdd': - 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.6 - */ - public function __set($name, $value) - { - $value = (string) $value; - - switch ($name) - { - case 'allowAdd': - $value = (string) $value; - $this->$name = ($value === 'true' || $value === $name || $value === '1'); - break; - default: - parent::__set($name, $value); - } - } - - /** - * Method to get a list of categories that respects access controls and can be used for - * either category assignment or parent category assignment in edit screens. - * Use the parent element to indicate that the field will be used for assigning parent categories. - * - * @return array The field option objects. - * - * @since 1.6 - */ - protected function getOptions() - { - $options = array(); - $published = $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. - $jinput = JFactory::getApplication()->input; - - // Load the category options for a given extension. - - // For categories the old category is the category id or 0 for new category. - if ($this->element['parent'] || $jinput->get('option') == 'com_categories') - { - $oldCat = $jinput->get('id', 0); - $oldParent = $this->form->getValue($name, 0); - $extension = $this->element['extension'] ? (string) $this->element['extension'] : (string) $jinput->get('extension', 'com_content'); - } - else - // For items the old category is the category they are in when opened or 0 if new. - { - $oldCat = $this->form->getValue($name, 0); - $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(); - - $query = $db->getQuery(true) - ->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') - { - $query->where('(a.extension = ' . $db->quote($extension) . ' OR a.parent_id = 0)'); - } - else - { - $query->where('(a.extension = ' . $db->quote($extension) . ')'); - } - - // Filter language - if (!empty($this->element['language'])) - { - if (strpos($this->element['language'], ',') !== false) - { - $language = implode(',', $db->quote(explode(',', $this->element['language']))); - } - else - { - $language = $db->quote($this->element['language']); - } - - $query->where($db->quoteName('a.language') . ' IN (' . $language . ')'); - } - - // Filter on the published state - if (is_numeric($published)) - { - $query->where('a.published = ' . (int) $published); - } - elseif (is_array($published)) - { - $query->where('a.published IN (' . implode(',', ArrayHelper::toInteger($published)) . ')'); - } - - // Filter categories on User Access Level - // Filter by access level on categories. - if (!$user->authorise('core.admin')) - { - $groups = implode(',', $user->getAuthorisedViewLevels()); - $query->where('a.access IN (' . $groups . ')'); - } - - $query->order('a.lft ASC'); - - // If parent isn't explicitly stated but we are in com_categories assume we want parents - if ($oldCat != 0 && ($this->element['parent'] == true || $jinput->get('option') == 'com_categories')) - { - // Prevent parenting to children of this item. - // To rearrange parents and children move the children up, not the parents down. - $query->join('LEFT', $db->quoteName('#__categories') . ' AS p ON p.id = ' . (int) $oldCat) - ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); - - $rowQuery = $db->getQuery(true); - $rowQuery->select('a.id AS value, a.title AS text, a.level, a.parent_id') - ->from('#__categories AS a') - ->where('a.id = ' . (int) $oldCat); - $db->setQuery($rowQuery); - $row = $db->loadObject(); - } - - // Get the options. - $db->setQuery($query); - - try - { - $options = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - // Pad the option text with spaces using depth level as a multiplier. - for ($i = 0, $n = count($options); $i < $n; $i++) - { - // Translate ROOT - if ($this->element['parent'] == true || $jinput->get('option') == 'com_categories') - { - if ($options[$i]->level == 0) - { - $options[$i]->text = JText::_('JGLOBAL_ROOT_PARENT'); - } - } - - if ($options[$i]->published == 1) - { - $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 ? 0 : $options[$i]->level - 1) . '[' . $options[$i]->text . ']'; - } - - // Displays language code if not set to All - if ($options[$i]->language !== '*') - { - $options[$i]->text = $options[$i]->text . ' (' . $options[$i]->language . ')'; - } - } - - // For new items we want a list of categories you are allowed to create in. - if ($oldCat == 0) - { - foreach ($options as $i => $option) - { - /* - * To take save or create in a category you need to have create rights for that category unless the item is already in that category. - * Unset the option if the user isn't authorised for it. In this field assets are always categories. - */ - if ($option->level != 0 && !$user->authorise('core.create', $extension . '.category.' . $option->value)) - { - unset($options[$i]); - } - } - } - // If you have an existing category id things are more complex. - else - { - /* - * If you are only allowed to edit in this category but not edit.state, you should not get any - * option to change the category parent for a category or the category for a content item, - * but you should be able to save in that category. - */ - foreach ($options as $i => $option) - { - $assetKey = $extension . '.category.' . $oldCat; - - if ($option->level != 0 && !isset($oldParent) && $option->value != $oldCat && !$user->authorise('core.edit.state', $assetKey)) - { - unset($options[$i]); - continue; - } - - if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.edit.state', $assetKey)) - { - unset($options[$i]); - continue; - } - - /* - * However, if you can edit.state you can also move this to another category for which you have - * create permission and you should also still be able to save in the current category. - */ - $assetKey = $extension . '.category.' . $option->value; - - if ($option->level != 0 && !isset($oldParent) && $option->value != $oldCat && !$user->authorise('core.create', $assetKey)) - { - unset($options[$i]); - continue; - } - - if ($option->level != 0 && isset($oldParent) && $option->value != $oldParent && !$user->authorise('core.create', $assetKey)) - { - unset($options[$i]); - continue; - } - } - } - - if (($this->element['parent'] == true || $jinput->get('option') == 'com_categories') - && (isset($row) && !isset($options[0])) - && isset($this->element['show_root'])) - { - if ($row->parent_id == '1') - { - $parent = new stdClass; - $parent->text = JText::_('JGLOBAL_ROOT_PARENT'); - array_unshift($options, $parent); - } - - array_unshift($options, JHtml::_('select.option', '0', JText::_('JGLOBAL_ROOT'))); - } - - // Merge any additional options in the XML definition. - return array_merge(parent::getOptions(), $options); - } - - /** - * Method to get the field input markup for a generic list. - * Use the multiple attribute to enable multiselect. - * - * @return string The field input markup. - * - * @since 3.6 - */ - protected function getInput() - { - $html = array(); - $class = array(); - $attr = ''; - - // Initialize some field attributes. - $class[] = !empty($this->class) ? $this->class : ''; - - if ($this->allowAdd) - { - $customGroupText = JText::_('JGLOBAL_CUSTOM_CATEGORY'); - - $class[] = 'chzn-custom-value'; - $attr .= ' data-custom_group_text="' . $customGroupText . '" ' - . 'data-no_results_text="' . JText::_('JGLOBAL_ADD_CUSTOM_CATEGORY') . '" ' - . 'data-placeholder="' . JText::_('JGLOBAL_TYPE_OR_SELECT_CATEGORY') . '" '; - } - - if ($class) - { - $attr .= 'class="' . implode(' ', $class) . '"'; - } - - $attr .= !empty($this->size) ? ' size="' . $this->size . '"' : ''; - $attr .= $this->multiple ? ' multiple' : ''; - $attr .= $this->required ? ' required aria-required="true"' : ''; - $attr .= $this->autofocus ? ' autofocus' : ''; - - // To avoid user's confusion, readonly="true" should imply disabled="true". - if ((string) $this->readonly == '1' - || (string) $this->readonly == 'true' - || (string) $this->disabled == '1' - || (string) $this->disabled == 'true') - { - $attr .= ' disabled="disabled"'; - } - - // Initialize JavaScript field attributes. - $attr .= $this->onchange ? ' onchange="' . $this->onchange . '"' : ''; - - // Get the field options. - $options = (array) $this->getOptions(); - - // Create a read-only list (no name) with hidden input(s) to store the value(s). - if ((string) $this->readonly == '1' || (string) $this->readonly == 'true') - { - $html[] = JHtml::_('select.genericlist', $options, '', trim($attr), 'value', 'text', $this->value, $this->id); - - // E.g. form field type tag sends $this->value as array - if ($this->multiple && is_array($this->value)) - { - if (!count($this->value)) - { - $this->value[] = ''; - } - - foreach ($this->value as $value) - { - $html[] = ''; - } - } - else - { - $html[] = ''; - } - } - else - { - // 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); - } - - return implode($html); - } -} diff --git a/administrator/components/com_categories/models/fields/categoryparent.php b/administrator/components/com_categories/models/fields/categoryparent.php deleted file mode 100644 index 3aae6dc264c96..0000000000000 --- a/administrator/components/com_categories/models/fields/categoryparent.php +++ /dev/null @@ -1,192 +0,0 @@ -element['name']; - - // Let's get the id for the current item, either category or content item. - $jinput = JFactory::getApplication()->input; - - // For categories the old category is the category id 0 for new category. - if ($this->element['parent']) - { - $oldCat = $jinput->get('id', 0); - } - else - // For items the old category is the category they are in when opened or 0 if new. - { - $oldCat = $this->form->getValue($name); - } - - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('a.id AS value, a.title AS text, a.level') - ->from('#__categories AS a') - ->join('LEFT', $db->quoteName('#__categories') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); - - // Filter by the type - if ($extension = $this->form->getValue('extension')) - { - $query->where('(a.extension = ' . $db->quote($extension) . ' OR a.parent_id = 0)'); - } - - if ($this->element['parent']) - { - // Prevent parenting to children of this item. - if ($id = $this->form->getValue('id')) - { - $query->join('LEFT', $db->quoteName('#__categories') . ' AS p ON p.id = ' . (int) $id) - ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); - - $rowQuery = $db->getQuery(true); - $rowQuery->select('a.id AS value, a.title AS text, a.level, a.parent_id') - ->from('#__categories AS a') - ->where('a.id = ' . (int) $id); - $db->setQuery($rowQuery); - $row = $db->loadObject(); - } - } - - $query->where('a.published IN (0,1)') - ->group('a.id, a.title, a.level, a.lft, a.rgt, a.extension, a.parent_id') - ->order('a.lft ASC'); - - // Get the options. - $db->setQuery($query); - - try - { - $options = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - // Pad the option text with spaces using depth level as a multiplier. - for ($i = 0, $n = count($options); $i < $n; $i++) - { - // Translate ROOT - if ($options[$i]->level == 0) - { - $options[$i]->text = JText::_('JGLOBAL_ROOT_PARENT'); - } - - // 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(); - - $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; - - if ($language !== '*') - { - $options[$i]->text = $options[$i]->text . ' (' . $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) - { - foreach ($options as $i => $option) - { - /* - * To take save or create in a category you need to have create rights for that category unless the item is already in that category. - * Unset the option if the user isn't authorised for it. In this field assets are always categories. - */ - if ($user->authorise('core.create', $extension . '.category.' . $option->value) != true) - { - unset($options[$i]); - } - } - } - // If you have an existing category id things are more complex. - else - { - foreach ($options as $i => $option) - { - /* - * If you are only allowed to edit in this category but not edit.state, you should not get any - * option to change the category parent for a category or the category for a content item, - * but you should be able to save in that category. - */ - if ($user->authorise('core.edit.state', $extension . '.category.' . $oldCat) != true) - { - if ($option->value != $oldCat) - { - echo 'y'; - unset($options[$i]); - } - } - /* - * However, if you can edit.state you can also move this to another category for which you have - * create permission and you should also still be able to save in the current category. - */ - elseif (($user->authorise('core.create', $extension . '.category.' . $option->value) != true) - && $option->value != $oldCat - ) - { - echo 'x'; - unset($options[$i]); - } - } - } - - if (isset($row) && !isset($options[0])) - { - if ($row->parent_id == '1') - { - $parent = new stdClass; - $parent->text = JText::_('JGLOBAL_ROOT_PARENT'); - array_unshift($options, $parent); - } - } - - // Merge any additional options in the XML definition. - return array_merge(parent::getOptions(), $options); - } -} diff --git a/administrator/components/com_categories/models/fields/modal/category.php b/administrator/components/com_categories/models/fields/modal/category.php deleted file mode 100644 index 0b77986150697..0000000000000 --- a/administrator/components/com_categories/models/fields/modal/category.php +++ /dev/null @@ -1,280 +0,0 @@ -element['extension']) - { - $extension = (string) $this->element['extension']; - } - else - { - $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'); - - // Load language. - JFactory::getLanguage()->load('com_categories', JPATH_ADMINISTRATOR); - - // The active category id field. - $value = (int) $this->value > 0 ? (int) $this->value : ''; - - // Create the modal id. - $modalId = 'Category_' . $this->id; - - // Add the modal field script to the document head. - JHtml::_('jquery.framework'); - JHtml::_('script', 'system/modal-fields.js', array('version' => 'auto', 'relative' => true)); - - // Script to proxy the select modal function to the modal-fields.js file. - if ($allowSelect) - { - static $scriptSelect = null; - - if (is_null($scriptSelect)) - { - $scriptSelect = array(); - } - - if (!isset($scriptSelect[$this->id])) - { - JFactory::getDocument()->addScriptDeclaration(" - function jSelectCategory_" . $this->id . "(id, title, object) { - window.processModalSelect('Category', '" . $this->id . "', id, title, '', object); - } - "); - - $scriptSelect[$this->id] = true; - } - } - - // Setup variables for display. - $linkCategories = 'index.php?option=com_categories&view=categories&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1' - . '&extension=' . $extension; - $linkCategory = 'index.php?option=com_categories&view=category&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1' - . '&extension=' . $extension; - $modalTitle = JText::_('COM_CATEGORIES_CHANGE_CATEGORY'); - - if (isset($this->element['language'])) - { - $linkCategories .= '&forcedLanguage=' . $this->element['language']; - $linkCategory .= '&forcedLanguage=' . $this->element['language']; - $modalTitle .= ' — ' . $this->element['label']; - } - - $urlSelect = $linkCategories . '&function=jSelectCategory_' . $this->id; - $urlEdit = $linkCategory . '&task=category.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \''; - $urlNew = $linkCategory . '&task=category.add'; - - if ($value) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('title')) - ->from($db->quoteName('#__categories')) - ->where($db->quoteName('id') . ' = ' . (int) $value); - $db->setQuery($query); - - try - { - $title = $db->loadResult(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - } - - $title = empty($title) ? JText::_('COM_CATEGORIES_SELECT_A_CATEGORY') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); - - // The current category display field. - $html = ''; - $html .= ''; - - // 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') - . ''; - } - - $html .= ''; - - // Select category modal. - if ($allowSelect) - { - $html .= JHtml::_( - 'bootstrap.renderModal', - 'ModalSelect' . $modalId, - array( - 'title' => $modalTitle, - 'url' => $urlSelect, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '', - ) - ); - } - - // New category modal. - if ($allowNew) - { - $html .= JHtml::_( - 'bootstrap.renderModal', - 'ModalNew' . $modalId, - array( - 'title' => JText::_('COM_CATEGORIES_NEW_CATEGORY'), - 'backdrop' => 'static', - 'keyboard' => false, - 'closeButton' => false, - 'url' => $urlNew, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '' - . '' - . '', - ) - ); - } - - // Edit category modal. - if ($allowEdit) - { - $html .= JHtml::_( - 'bootstrap.renderModal', - 'ModalEdit' . $modalId, - array( - 'title' => JText::_('COM_CATEGORIES_EDIT_CATEGORY'), - 'backdrop' => 'static', - 'keyboard' => false, - 'closeButton' => false, - 'url' => $urlEdit, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '' - . '' - . '', - ) - ); - } - - // Note: class='required' for client side validation - $class = $this->required ? ' class="required modal-value"' : ''; - - $html .= ''; - - return $html; - } - - /** - * Method to get the field label markup. - * - * @return string The field label markup. - * - * @since 3.7.0 - */ - protected function getLabel() - { - return str_replace($this->id, $this->id . '_id', parent::getLabel()); - } -} diff --git a/administrator/components/com_categories/models/forms/category.xml b/administrator/components/com_categories/models/forms/category.xml deleted file mode 100644 index b249d0235f926..0000000000000 --- a/administrator/components/com_categories/models/forms/category.xml +++ /dev/null @@ -1,300 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - -
-
- - - -
- - - - - - - - - - -
-
- diff --git a/administrator/components/com_categories/tables/category.php b/administrator/components/com_categories/tables/category.php deleted file mode 100644 index 014619eac6831..0000000000000 --- a/administrator/components/com_categories/tables/category.php +++ /dev/null @@ -1,33 +0,0 @@ -get('id'); +$extension = $this->escape($this->state->get('filter.extension')); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); +$parts = explode('.', $extension, 2); +$component = $parts[0]; +$section = null; + +if (count($parts) > 1) +{ + $section = $parts[1]; + + $inflector = Inflector::getInstance(); + + if (!$inflector->isPlural($section)) + { + $section = $inflector->toPlural($section); + } +} + +if ($saveOrder && !empty($this->items)) +{ + $saveOrderingUrl = 'index.php?option=com_categories&task=categories.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} +?> +
+
+ sidebar)) { ?> +
+ sidebar; ?> +
+ +
+
+ $this)); + ?> + items)) : ?> + + + + + + + + + + items[0]) && property_exists($this->items[0], 'count_published')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_archived')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> + + + + assoc) : ?> + + + + + + + + + class="js-draggable" data-url="" data-direction="" data-nested="false"> + items as $i => $item) : ?> + 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; + $canChange = $user->authorise('core.edit.state', $extension . '.category.' . $item->id) && $canCheckin; + + // Get the parents of item for sorting + if ($item->level > 1) + { + $parentsStr = ''; + $_currentParentId = $item->parent_id; + $parentsStr = ' ' . $_currentParentId; + for ($i2 = 0; $i2 < $item->level; $i2++) + { + foreach ($this->ordering as $k => $v) + { + $v = implode('-', $v); + $v = '-' . $v . '-'; + if (strpos($v, '-' . $_currentParentId . '-') !== false) + { + $parentsStr .= ' ' . $k; + $_currentParentId = $k; + break; + } + } + } + } + else + { + $parentsStr = ''; + } + ?> + + + + + + items[0]) && property_exists($this->items[0], 'count_published')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_archived')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> + + + + + assoc) : ?> + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + id); ?> + +
+ published, $i, 'categories.', $canChange); ?> +
+
+ $item->level)); ?> + checked_out) : ?> + editor, $item->checked_out_time, 'categories.', $canCheckin); ?> + + + checked_out ? '' : ''; ?> + + escape($item->title); ?> + + escape($item->title); ?> + + + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + + + + + count_published; ?> + + + count_unpublished; ?> + + + count_archived; ?> + + + count_trashed; ?> + + escape($item->access_level); ?> + + association) : ?> + id, $extension); ?> + + + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + authorise('core.create', $extension) + && $user->authorise('core.edit', $extension) + && $user->authorise('core.edit.state', $extension)) : ?> + Text::_('COM_CATEGORIES_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + + +
+
+
+
diff --git a/administrator/components/com_categories/tmpl/categories/default.xml b/administrator/components/com_categories/tmpl/categories/default.xml new file mode 100644 index 0000000000000..3503ec6ff6983 --- /dev/null +++ b/administrator/components/com_categories/tmpl/categories/default.xml @@ -0,0 +1,20 @@ + + + + + + + +
+ + + + + +
+
diff --git a/administrator/components/com_categories/tmpl/categories/default_batch_body.php b/administrator/components/com_categories/tmpl/categories/default_batch_body.php new file mode 100644 index 0000000000000..701fbbc0c5b92 --- /dev/null +++ b/administrator/components/com_categories/tmpl/categories/default_batch_body.php @@ -0,0 +1,58 @@ +state->get('filter.published'); +$extension = $this->escape($this->state->get('filter.extension')); + +?> + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ = 0) : ?> +
+
+ $extension)); ?> +
+
+ +
+
+ +
+
+
+
+
+
+ + +
+
+
+
+ diff --git a/administrator/components/com_categories/tmpl/categories/default_batch_footer.php b/administrator/components/com_categories/tmpl/categories/default_batch_footer.php new file mode 100644 index 0000000000000..a35314fd419c7 --- /dev/null +++ b/administrator/components/com_categories/tmpl/categories/default_batch_footer.php @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/administrator/components/com_categories/tmpl/categories/modal.php b/administrator/components/com_categories/tmpl/categories/modal.php new file mode 100644 index 0000000000000..59f15dc880693 --- /dev/null +++ b/administrator/components/com_categories/tmpl/categories/modal.php @@ -0,0 +1,142 @@ +isClient('site')) +{ + Session::checkToken('get') or die(Text::_('JINVALID_TOKEN')); +} + +JLoader::register('ContentHelperRoute', JPATH_ROOT . '/components/com_content/helpers/route.php'); + +// Include the component HTML helpers. +HTMLHelper::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + +HTMLHelper::_('behavior.core'); +HTMLHelper::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); + +$extension = $this->escape($this->state->get('filter.extension')); +$function = $app->input->getCmd('function', 'jSelectCategory'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+ +
+ + $this)); ?> + + items)) : ?> + + + + + + + + + + + + + + 'icon-trash', + 0 => 'icon-unpublish', + 1 => 'icon-publish', + 2 => 'icon-archive', + ); + ?> + items as $i => $item) : ?> + language && Multilanguage::isEnabled()) + { + $tag = strlen($item->language); + if ($tag == 5) + { + $lang = substr($item->language, 0, 2); + } + elseif ($tag == 6) + { + $lang = substr($item->language, 0, 3); + } + else + { + $lang = ''; + } + } + elseif (!Multilanguage::isEnabled()) + { + $lang = ''; + } + ?> + + + + + + + + + +
+ + + + + + + + + +
+ + + $item->level)); ?> + + escape($item->title); ?> + + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + + + + escape($item->access_level); ?> + + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + + + + + +
+
diff --git a/administrator/components/com_categories/tmpl/category/edit.php b/administrator/components/com_categories/tmpl/category/edit.php new file mode 100644 index 0000000000000..8dc06848e7674 --- /dev/null +++ b/administrator/components/com_categories/tmpl/category/edit.php @@ -0,0 +1,102 @@ +input; + +$assoc = Associations::isEnabled(); +// Are associations implemented for this extension? +$extensionassoc = array_key_exists('item_associations', $this->form->getFieldsets()); + +// Fieldsets to not automatically render by /layouts/joomla/edit/params.php +$this->ignore_fieldsets = array('jmetadata', 'item_associations'); +$this->useCoreUI = true; + +// In case of modal +$isModal = $input->get('layout') == 'modal' ? true : false; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; +?> + +
+ + + +
+ 'general')); ?> + +
+
+ form->getLabel('description'); ?> + form->getInput('description'); ?> +
+
+
+
+ +
+
+
+
+ + + + + + +
+
+ +
+
+ +
+
+ + + + + + loadTemplate('associations'); ?> + + + + + + canDo->get('core.admin')) : ?> + + + form->getInput('rules'); ?> + + + + + + form->getInput('extension'); ?> + + + +
+
diff --git a/administrator/components/com_categories/tmpl/category/edit.xml b/administrator/components/com_categories/tmpl/category/edit.xml new file mode 100644 index 0000000000000..f5dc6a5e46d71 --- /dev/null +++ b/administrator/components/com_categories/tmpl/category/edit.xml @@ -0,0 +1,25 @@ + + + + + + + +
+ + + + + + +
+
diff --git a/administrator/components/com_categories/tmpl/category/edit_associations.php b/administrator/components/com_categories/tmpl/category/edit_associations.php new file mode 100644 index 0000000000000..b6e6c5f359070 --- /dev/null +++ b/administrator/components/com_categories/tmpl/category/edit_associations.php @@ -0,0 +1,14 @@ + +
+ setLayout('edit'); ?> + loadTemplate(); ?> +
diff --git a/administrator/components/com_categories/tmpl/category/modal_associations.php b/administrator/components/com_categories/tmpl/category/modal_associations.php new file mode 100644 index 0000000000000..b6e6c5f359070 --- /dev/null +++ b/administrator/components/com_categories/tmpl/category/modal_associations.php @@ -0,0 +1,14 @@ + 'collapse0')); +$fieldSets = $this->form->getFieldsets('params'); +$i = 0; +?> + $fieldSet) : ?> + label) ? $fieldSet->label : 'COM_CATEGORIES_' . $name . '_FIELDSET_LABEL'; + echo HTMLHelper::_('bootstrap.addSlide', 'categoryOptions', Text::_($label), 'collapse' . ($i++)); + if (isset($fieldSet->description) && trim($fieldSet->description)) + { + echo '

' . $this->escape(Text::_($fieldSet->description)) . '

'; + } + ?> + form->getFieldset($name) as $field) : ?> +
+
+ label; ?> +
+
+ input; ?> +
+
+ + + +
+
+ form->getLabel('note'); ?> +
+
+ form->getInput('note'); ?> +
+
+ + + + diff --git a/administrator/components/com_categories/views/categories/tmpl/default.php b/administrator/components/com_categories/views/categories/tmpl/default.php deleted file mode 100644 index 5ad84b77391b8..0000000000000 --- a/administrator/components/com_categories/views/categories/tmpl/default.php +++ /dev/null @@ -1,287 +0,0 @@ -get('id'); -$extension = $this->escape($this->state->get('filter.extension')); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); -$parts = explode('.', $extension, 2); -$component = $parts[0]; -$section = null; -$columns = 7; - -if (count($parts) > 1) -{ - $section = $parts[1]; - - $inflector = Inflector::getInstance(); - - if (!$inflector->isPlural($section)) - { - $section = $inflector->toPlural($section); - } -} - -if ($saveOrder) -{ - $saveOrderingUrl = 'index.php?option=com_categories&task=categories.saveOrderAjax&tmpl=component'; - JHtml::_('sortablelist.sortable', 'categoryList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); -} -?> -
-
- sidebar; ?> -
-
- $this)); - ?> - items)) : ?> -
- -
- - - - - - - - - items[0]) && property_exists($this->items[0], 'count_published')) : - $columns++; ?> - - - items[0]) && property_exists($this->items[0], 'count_unpublished')) : - $columns++; ?> - - - items[0]) && property_exists($this->items[0], 'count_archived')) : - $columns++; ?> - - - items[0]) && property_exists($this->items[0], 'count_trashed')) : - $columns++; ?> - - - - assoc) : - $columns++; ?> - - - - - - - - - - - - - items as $i => $item) : ?> - 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; - $canChange = $user->authorise('core.edit.state', $extension . '.category.' . $item->id) && $canCheckin; - - // Get the parents of item for sorting - if ($item->level > 1) - { - $parentsStr = ''; - $_currentParentId = $item->parent_id; - $parentsStr = ' ' . $_currentParentId; - for ($i2 = 0; $i2 < $item->level; $i2++) - { - foreach ($this->ordering as $k => $v) - { - $v = implode('-', $v); - $v = '-' . $v . '-'; - if (strpos($v, '-' . $_currentParentId . '-') !== false) - { - $parentsStr .= ' ' . $k; - $_currentParentId = $k; - break; - } - } - } - } - else - { - $parentsStr = ''; - } - ?> - - - - - - items[0]) && property_exists($this->items[0], 'count_published')) : ?> - - - items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> - - - items[0]) && property_exists($this->items[0], 'count_archived')) : ?> - - - items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> - - - - - assoc) : ?> - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - - - - - - - id); ?> - -
- published, $i, 'categories.', $canChange); ?> - published === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'categories'); - JHtml::_('actionsdropdown.' . ((int) $item->published === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'categories'); - - // Render dropdown list - echo JHtml::_('actionsdropdown.render', $this->escape($item->title)); - } - ?> -
-
- $item->level)); ?> - checked_out) : ?> - editor, $item->checked_out_time, 'categories.', $canCheckin); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - - note)) : ?> - escape($item->alias)); ?> - - escape($item->alias), $this->escape($item->note)); ?> - - - - - count_published; ?> - - - count_unpublished; ?> - - - count_archived; ?> - - - count_trashed; ?> - - escape($item->access_level); ?> - - association) : ?> - id, $extension); ?> - - - - - - id; ?> -
- - authorise('core.create', $extension) - && $user->authorise('core.edit', $extension) - && $user->authorise('core.edit.state', $extension)) : ?> - JText::_('COM_CATEGORIES_BATCH_OPTIONS'), - 'footer' => $this->loadTemplate('batch_footer'), - ), - $this->loadTemplate('batch_body') - ); ?> - - - - - - - -
-
diff --git a/administrator/components/com_categories/views/categories/tmpl/default.xml b/administrator/components/com_categories/views/categories/tmpl/default.xml deleted file mode 100755 index ae87868da7242..0000000000000 --- a/administrator/components/com_categories/views/categories/tmpl/default.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - -
- - - - - -
-
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 deleted file mode 100644 index 1307d418e608b..0000000000000 --- a/administrator/components/com_categories/views/categories/tmpl/default_batch_body.php +++ /dev/null @@ -1,69 +0,0 @@ -state->get('filter.published'); -$extension = $this->escape($this->state->get('filter.extension')); -?> - -
-
-
-
- -
-
-
-
- -
-
-
-
- = 0) : ?> -
-
- -
- -
-
-
- - -
-
- -
-
- -
-
-
-
-
-
- - -
-
-
-
- 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 deleted file mode 100644 index 2530fc28554eb..0000000000000 --- a/administrator/components/com_categories/views/categories/tmpl/default_batch_footer.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ 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 deleted file mode 100644 index 436dff200da84..0000000000000 --- a/administrator/components/com_categories/views/categories/tmpl/modal.php +++ /dev/null @@ -1,147 +0,0 @@ -isClient('site')) -{ - JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); -} - -JLoader::register('ContentHelperRoute', JPATH_ROOT . '/components/com_content/helpers/route.php'); - -// Include the component HTML helpers. -JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - -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. -$searchFilterDesc = $this->filterForm->getFieldAttribute('search', 'description', null, 'filter'); -JHtml::_('bootstrap.tooltip', '#filter_search', array('title' => JText::_($searchFilterDesc), 'placement' => 'bottom')); - -$extension = $this->escape($this->state->get('filter.extension')); -$function = $app->input->getCmd('function', 'jSelectCategory'); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
- -
- - $this)); ?> - -
- - items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - 'icon-trash', - 0 => 'icon-unpublish', - 1 => 'icon-publish', - 2 => 'icon-archive', - ); - ?> - items as $i => $item) : ?> - language && JLanguageMultilang::isEnabled()) - { - $tag = strlen($item->language); - if ($tag == 5) - { - $lang = substr($item->language, 0, 2); - } - elseif ($tag == 6) - { - $lang = substr($item->language, 0, 3); - } - else - { - $lang = ''; - } - } - elseif (!JLanguageMultilang::isEnabled()) - { - $lang = ''; - } - ?> - - - - - - - - - -
- - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - $item->level)); ?> - - escape($item->title); ?> - - note)) : ?> - escape($item->alias)); ?> - - escape($item->alias), $this->escape($item->note)); ?> - - - - escape($item->access_level); ?> - - - - id; ?> -
- - - - - - - - -
-
diff --git a/administrator/components/com_categories/views/categories/view.html.php b/administrator/components/com_categories/views/categories/view.html.php deleted file mode 100644 index 4428001631ab6..0000000000000 --- a/administrator/components/com_categories/views/categories/view.html.php +++ /dev/null @@ -1,286 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->assoc = $this->get('Assoc'); - $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); - } - - // Preprocess the list of items to find ordering divisions. - foreach ($this->items as &$item) - { - $this->ordering[$item->parent_id][] = $item->id; - } - - // Levels filter - Used in Hathor. - $this->f_levels = array( - JHtml::_('select.option', '1', JText::_('J1')), - JHtml::_('select.option', '2', JText::_('J2')), - JHtml::_('select.option', '3', JText::_('J3')), - JHtml::_('select.option', '4', JText::_('J4')), - JHtml::_('select.option', '5', JText::_('J5')), - JHtml::_('select.option', '6', JText::_('J6')), - JHtml::_('select.option', '7', JText::_('J7')), - JHtml::_('select.option', '8', JText::_('J8')), - JHtml::_('select.option', '9', JText::_('J9')), - JHtml::_('select.option', '10', JText::_('J10')), - ); - - // We don't need toolbar in the modal window. - if ($this->getLayout() !== 'modal') - { - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - } - else - { - // 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 a 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']); - } - } - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $categoryId = $this->state->get('filter.category_id'); - $component = $this->state->get('filter.component'); - $section = $this->state->get('filter.section'); - $canDo = JHelperContent::getActions($component, 'category', $categoryId); - $user = JFactory::getUser(); - - // Get the toolbar object instance - $bar = JToolbar::getInstance('toolbar'); - - // Avoid nonsense situation. - if ($component == 'com_categories') - { - return; - } - - // Need to load the menu language file as mod_menu hasn't been loaded yet. - $lang = JFactory::getLanguage(); - $lang->load($component, JPATH_BASE, null, false, true) - || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); - - // Load the category helper. - JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - - // If a component categories title string is present, let's use it. - if ($lang->hasKey($component_title_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORIES_TITLE')) - { - $title = JText::_($component_title_key); - } - elseif ($lang->hasKey($component_section_key = strtoupper($component . ($section ? "_$section" : '')))) - // Else if the component section string exits, let's use it - { - $title = JText::sprintf('COM_CATEGORIES_CATEGORIES_TITLE', $this->escape(JText::_($component_section_key))); - } - else - // Else use the base title - { - $title = JText::_('COM_CATEGORIES_CATEGORIES_BASE_TITLE'); - } - - // Load specific css component - JHtml::_('stylesheet', $component . '/administrator/categories.css', array('version' => 'auto', 'relative' => true)); - - // 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) - { - JToolbarHelper::addNew('category.add'); - } - - if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) - { - JToolbarHelper::editList('category.edit'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publish('categories.publish', 'JTOOLBAR_PUBLISH', true); - JToolbarHelper::unpublish('categories.unpublish', 'JTOOLBAR_UNPUBLISH', true); - JToolbarHelper::archiveList('categories.archive'); - } - - if (JFactory::getUser()->authorise('core.admin')) - { - JToolbarHelper::checkin('categories.checkin'); - } - - // Add a batch button - if ($canDo->get('core.create') - && $canDo->get('core.edit') - && $canDo->get('core.edit.state')) - { - $title = JText::_('JTOOLBAR_BATCH'); - - // Instantiate a new JLayoutFile instance and render the batch button - $layout = new JLayoutFile('joomla.toolbar.batch'); - - $dhtml = $layout->render(array('title' => $title)); - $bar->appendButton('Custom', $dhtml, 'batch'); - } - - if ($canDo->get('core.admin')) - { - JToolbarHelper::custom('categories.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences($component); - } - - if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete', $component)) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'categories.delete', 'JTOOLBAR_EMPTY_TRASH'); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('categories.trash'); - } - - // Compute the ref_key if it does exist in the component - if (!$lang->hasKey($ref_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORIES_HELP_KEY')) - { - $ref_key = 'JHELP_COMPONENTS_' . strtoupper(substr($component, 4) . ($section ? "_$section" : '')) . '_CATEGORIES'; - } - - /* - * Get help for the categories view for the component by - * -remotely searching in a language defined dedicated URL: *component*_HELP_URL - * -locally searching in a component help file if helpURL param exists in the component and is set to '' - * -remotely searching in a component URL if helpURL param exists in the component and is NOT set to '' - */ - if ($lang->hasKey($lang_help_url = strtoupper($component) . '_HELP_URL')) - { - $debug = $lang->setDebug(false); - $url = JText::_($lang_help_url); - $lang->setDebug($debug); - } - else - { - $url = null; - } - - JToolbarHelper::help($ref_key, JComponentHelper::getParams($component)->exists('helpURL'), $url); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'a.lft' => JText::_('JGRID_HEADING_ORDERING'), - 'a.published' => JText::_('JSTATUS'), - 'a.title' => JText::_('JGLOBAL_TITLE'), - 'a.access' => JText::_('JGRID_HEADING_ACCESS'), - 'language' => JText::_('JGRID_HEADING_LANGUAGE'), - 'a.id' => JText::_('JGRID_HEADING_ID'), - ); - } -} diff --git a/administrator/components/com_categories/views/category/tmpl/edit.php b/administrator/components/com_categories/views/category/tmpl/edit.php deleted file mode 100644 index 54dbeeb267f0e..0000000000000 --- a/administrator/components/com_categories/views/category/tmpl/edit.php +++ /dev/null @@ -1,106 +0,0 @@ -input; - -$assoc = JLanguageAssociations::isEnabled(); -// Are associations implemented for this extension? -$extensionassoc = array_key_exists('item_associations', $this->form->getFieldsets()); - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(task) - { - if (task == "category.cancel" || document.formvalidator.isValid(document.getElementById("item-form"))) - { - jQuery("#permissions-sliders select").attr("disabled", "disabled"); - ' . $this->form->getField('description')->save() . ' - Joomla.submitform(task, document.getElementById("item-form")); - - // @deprecated 4.0 The following js is not needed since 3.7.0. - if (task !== "category.apply") - { - window.parent.jQuery("#categoryEdit' . $this->item->id . 'Modal").modal("hide"); - } - } - }; -'); - -// Fieldsets to not automatically render by /layouts/joomla/edit/params.php -$this->ignore_fieldsets = array('jmetadata', 'item_associations'); - -// In case of modal -$isModal = $input->get('layout') == 'modal' ? true : false; -$layout = $isModal ? 'modal' : 'edit'; -$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; -?> - -
- - - -
- 'general')); ?> - - -
-
- form->getLabel('description'); ?> - form->getInput('description'); ?> -
-
- -
-
- - - - - -
-
- -
-
- -
-
- - - - - loadTemplate('associations'); ?> - - - - - - canDo->get('core.admin')) : ?> - - form->getInput('rules'); ?> - - - - - - form->getInput('extension'); ?> - - - -
-
diff --git a/administrator/components/com_categories/views/category/tmpl/edit.xml b/administrator/components/com_categories/views/category/tmpl/edit.xml deleted file mode 100755 index f96948e4ad153..0000000000000 --- a/administrator/components/com_categories/views/category/tmpl/edit.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - -
- - - - - - -
-
diff --git a/administrator/components/com_categories/views/category/tmpl/edit_associations.php b/administrator/components/com_categories/views/category/tmpl/edit_associations.php deleted file mode 100644 index f422019e008d1..0000000000000 --- a/administrator/components/com_categories/views/category/tmpl/edit_associations.php +++ /dev/null @@ -1,12 +0,0 @@ - 'bottom')); - -// @deprecated 4.0 the function parameter, the inline js and the buttons are not needed since 3.7.0. -$function = JFactory::getApplication()->input->getCmd('function', 'jEditCategory_' . (int) $this->item->id); - -// Function to update input title when changed -JFactory::getDocument()->addScriptDeclaration(' - function jEditCategoryModal() { - if (window.parent && document.formvalidator.isValid(document.getElementById("item-form"))) { - return window.parent.' . $this->escape($function) . '(document.getElementById("jform_title").value); - } - } -'); -?> - - - - -
- setLayout('edit'); ?> - loadTemplate(); ?> -
diff --git a/administrator/components/com_categories/views/category/tmpl/modal_associations.php b/administrator/components/com_categories/views/category/tmpl/modal_associations.php deleted file mode 100644 index f422019e008d1..0000000000000 --- a/administrator/components/com_categories/views/category/tmpl/modal_associations.php +++ /dev/null @@ -1,12 +0,0 @@ - 'collapse0')); -$fieldSets = $this->form->getFieldsets('params'); -$i = 0; -?> - $fieldSet) : ?> - label) ? $fieldSet->label : 'COM_CATEGORIES_' . $name . '_FIELDSET_LABEL'; - echo JHtml::_('bootstrap.addSlide', 'categoryOptions', JText::_($label), 'collapse' . ($i++)); - if (isset($fieldSet->description) && trim($fieldSet->description)) - { - echo '

' . $this->escape(JText::_($fieldSet->description)) . '

'; - } - ?> - form->getFieldset($name) as $field) : ?> -
-
- label; ?> -
-
- input; ?> -
-
- - - -
-
- form->getLabel('note'); ?> -
-
- form->getInput('note'); ?> -
-
- - - - diff --git a/administrator/components/com_categories/views/category/view.html.php b/administrator/components/com_categories/views/category/view.html.php deleted file mode 100644 index c24b32c1444d7..0000000000000 --- a/administrator/components/com_categories/views/category/view.html.php +++ /dev/null @@ -1,245 +0,0 @@ -form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - $section = $this->state->get('category.section') ? $this->state->get('category.section') . '.' : ''; - $this->canDo = JHelperContent::getActions($this->state->get('category.component'), $section . 'category', $this->item->id); - $this->assoc = $this->get('Assoc'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - // Check for tag type - $this->checkTags = JHelperTags::getTypes('objectList', array($this->state->get('category.extension') . '.category'), true); - - JFactory::getApplication()->input->set('hidemainmenu', true); - - // If we are forcing a language in modal (used for associations). - if ($this->getLayout() === 'modal' && $forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'cmd')) - { - // Set the language field to the forcedLanguage and disable changing it. - $this->form->setValue('language', null, $forcedLanguage); - $this->form->setFieldAttribute('language', 'readonly', 'true'); - - // Only allow to select categories with All language or with the forced language. - $this->form->setFieldAttribute('parent_id', 'language', '*,' . $forcedLanguage); - - // Only allow to select tags with All language or with the forced language. - $this->form->setFieldAttribute('tags', 'language', '*,' . $forcedLanguage); - } - - $this->addToolbar(); - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $extension = JFactory::getApplication()->input->get('extension'); - $user = JFactory::getUser(); - $userId = $user->id; - - $isNew = ($this->item->id == 0); - $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); - - // Check to see if the type exists - $ucmType = new JUcmType; - $this->typeId = $ucmType->getTypeId($extension . '.category'); - - // Avoid nonsense situation. - if ($extension == 'com_categories') - { - return; - } - - // The extension can be in the form com_foo.section - $parts = explode('.', $extension); - $component = $parts[0]; - $section = (count($parts) > 1) ? $parts[1] : null; - $componentParams = JComponentHelper::getParams($component); - - // Need to load the menu language file as mod_menu hasn't been loaded yet. - $lang = JFactory::getLanguage(); - $lang->load($component, JPATH_BASE, null, false, true) - || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); - - // Load the category helper. - JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - - // Get the results for each action. - $canDo = $this->canDo; - - // If a component categories title string is present, let's use it. - if ($lang->hasKey($component_title_key = $component . ($section ? "_$section" : '') . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE')) - { - $title = JText::_($component_title_key); - } - // Else if the component section string exits, let's use it - elseif ($lang->hasKey($component_section_key = $component . ($section ? "_$section" : ''))) - { - $title = JText::sprintf('COM_CATEGORIES_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') - . '_TITLE', $this->escape(JText::_($component_section_key)) - ); - } - // Else use the base title - else - { - $title = JText::_('COM_CATEGORIES_CATEGORY_BASE_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE'); - } - - // Load specific css component - JHtml::_('stylesheet', $component . '/administrator/categories.css', array('version' => 'auto', 'relative' => true)); - - // Prepare the toolbar. - JToolbarHelper::title( - $title, - 'folder category-' . ($isNew ? 'add' : 'edit') - . ' ' . substr($component, 4) . ($section ? "-$section" : '') . '-category-' . ($isNew ? 'add' : 'edit') - ); - - // For new records, check the create permission. - if ($isNew && (count($user->getAuthorisedCategories($component, 'core.create')) > 0)) - { - JToolbarHelper::apply('category.apply'); - JToolbarHelper::save('category.save'); - JToolbarHelper::save2new('category.save2new'); - JToolbarHelper::cancel('category.cancel'); - } - - // If not checked out, can save the item. - else - { - // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. - $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_user_id == $userId); - - // Can't save the record if it's checked out and editable - if (!$checkedOut && $itemEditable) - { - JToolbarHelper::apply('category.apply'); - JToolbarHelper::save('category.save'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::save2new('category.save2new'); - } - } - - // If an existing item, can save to a copy. - if ($canDo->get('core.create')) - { - JToolbarHelper::save2copy('category.save2copy'); - } - - if (JComponentHelper::isEnabled('com_contenthistory') && $componentParams->get('save_history', 0) && $itemEditable) - { - $typeAlias = $extension . '.category'; - JToolbarHelper::versions($typeAlias, $this->item->id); - } - - JToolbarHelper::cancel('category.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - - // Compute the ref_key - $ref_key = strtoupper($component . ($section ? "_$section" : '')) . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT') . '_HELP_KEY'; - - // Check if thr computed ref_key does exist in the component - if (!$lang->hasKey($ref_key)) - { - $ref_key = 'JHELP_COMPONENTS_' - . strtoupper(substr($component, 4) . ($section ? "_$section" : '')) - . '_CATEGORY_' . ($isNew ? 'ADD' : 'EDIT'); - } - - /* - * Get help for the category/section view for the component by - * -remotely searching in a language defined dedicated URL: *component*_HELP_URL - * -locally searching in a component help file if helpURL param exists in the component and is set to '' - * -remotely searching in a component URL if helpURL param exists in the component and is NOT set to '' - */ - if ($lang->hasKey($lang_help_url = strtoupper($component) . '_HELP_URL')) - { - $debug = $lang->setDebug(false); - $url = JText::_($lang_help_url); - $lang->setDebug($debug); - } - else - { - $url = null; - } - - JToolbarHelper::help($ref_key, $componentParams->exists('helpURL'), $url, $component); - } -} diff --git a/administrator/components/com_checkin/Controller/DisplayController.php b/administrator/components/com_checkin/Controller/DisplayController.php new file mode 100644 index 0000000000000..3b2e9a5d2d543 --- /dev/null +++ b/administrator/components/com_checkin/Controller/DisplayController.php @@ -0,0 +1,106 @@ +addSubmenu($this->input->getWord('option', 'com_checkin')); + + return parent::display(); + } + + /** + * Check in a list of items. + * + * @return void + */ + public function checkin() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + + if (empty($ids)) + { + $this->app->enqueueMessage(Text::_('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'), 'warning'); + } + else + { + // Get the model. + /** @var \Joomla\Component\Checkin\Administrator\Model\CheckinModel $model */ + $model = $this->getModel('Checkin'); + + // Checked in the items. + $this->setMessage(Text::plural('COM_CHECKIN_N_ITEMS_CHECKED_IN', $model->checkin($ids))); + } + + $this->setRedirect('index.php?option=com_checkin'); + } + + /** + * Configure the Linkbar. + * + * @param string $vName The name of the active view. + * + * @return void + * + * @since 1.6 + */ + protected function addSubmenu($vName) + { + \JHtmlSidebar::addEntry( + Text::_('JGLOBAL_SUBMENU_CHECKIN'), + 'index.php?option=com_checkin', + $vName == 'com_checkin' + ); + + \JHtmlSidebar::addEntry( + Text::_('JGLOBAL_SUBMENU_CLEAR_CACHE'), + 'index.php?option=com_cache', + $vName == 'cache' + ); + \JHtmlSidebar::addEntry( + Text::_('JGLOBAL_SUBMENU_PURGE_EXPIRED_CACHE'), + 'index.php?option=com_cache&view=purge', + $vName == 'purge' + ); + } +} diff --git a/administrator/components/com_checkin/Model/CheckinModel.php b/administrator/components/com_checkin/Model/CheckinModel.php new file mode 100644 index 0000000000000..57804dbc6776a --- /dev/null +++ b/administrator/components/com_checkin/Model/CheckinModel.php @@ -0,0 +1,259 @@ +getDbo(); + $nullDate = $db->getNullDate(); + + if (!is_array($ids)) + { + return 0; + } + + // This int will hold the checked item count. + $results = 0; + + foreach ($ids as $tn) + { + // Make sure we get the right tables based on prefix. + if (stripos($tn, Factory::getApplication()->get('dbprefix')) !== 0) + { + continue; + } + + $fields = $db->getTableColumns($tn); + + if (!(isset($fields['checked_out']) && isset($fields['checked_out_time']))) + { + continue; + } + + $query = $db->getQuery(true) + ->update($db->quoteName($tn)) + ->set('checked_out = 0') + ->set('checked_out_time = ' . $db->quote($nullDate)) + ->where('checked_out > 0'); + + $db->setQuery($query); + + if ($db->execute()) + { + $results = $results + $db->getAffectedRows(); + } + } + + return $results; + } + + /** + * Get total of tables + * + * @return integer Total to check-in tables + * + * @since 1.6 + */ + public function getTotal() + { + if (!isset($this->total)) + { + $this->getItems(); + } + + return $this->total; + } + + /** + * Get tables + * + * @return array Checked in table names as keys and checked in item count as values. + * + * @since 1.6 + */ + public function getItems() + { + if (!isset($this->items)) + { + $db = $this->getDbo(); + $tables = $db->getTableList(); + + // This array will hold table name as key and checked in item count as value. + $results = array(); + + foreach ($tables as $i => $tn) + { + // Make sure we get the right tables based on prefix. + if (stripos($tn, Factory::getApplication()->get('dbprefix')) !== 0) + { + unset($tables[$i]); + continue; + } + + if ($this->getState('filter.search') && stripos($tn, $this->getState('filter.search')) === false) + { + unset($tables[$i]); + continue; + } + + $fields = $db->getTableColumns($tn); + + if (!(isset($fields['checked_out']) && isset($fields['checked_out_time']))) + { + unset($tables[$i]); + continue; + } + } + + foreach ($tables as $tn) + { + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName($tn)) + ->where('checked_out > 0'); + + $db->setQuery($query); + + if ($db->execute()) + { + $results[$tn] = $db->loadResult(); + + // Show only tables with items to checkin. + if ((int) $results[$tn] === 0) + { + unset($results[$tn]); + } + } + else + { + continue; + } + } + + $this->total = count($results); + + // Order items by table + if ($this->getState('list.ordering') == 'table') + { + if (strtolower($this->getState('list.direction')) == 'asc') + { + ksort($results); + } + else + { + krsort($results); + } + } + // Order items by number of items + else + { + if (strtolower($this->getState('list.direction')) == 'asc') + { + asort($results); + } + else + { + arsort($results); + } + } + + // Pagination + $limit = (int) $this->getState('list.limit'); + + if ($limit !== 0) + { + $this->items = array_slice($results, $this->getState('list.start'), $limit); + } + else + { + $this->items = $results; + } + } + + return $this->items; + } +} diff --git a/administrator/components/com_checkin/View/Checkin/HtmlView.php b/administrator/components/com_checkin/View/Checkin/HtmlView.php new file mode 100644 index 0000000000000..4bee85de74fea --- /dev/null +++ b/administrator/components/com_checkin/View/Checkin/HtmlView.php @@ -0,0 +1,120 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->total = $this->get('Total'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + ToolbarHelper::title(Text::_('COM_CHECKIN_GLOBAL_CHECK_IN'), 'checkin'); + + ToolbarHelper::custom('checkin', 'checkin.png', 'checkin_f2.png', 'JTOOLBAR_CHECKIN', true); + + if (Factory::getUser()->authorise('core.admin', 'com_checkin')) + { + ToolbarHelper::divider(); + ToolbarHelper::preferences('com_checkin'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_SITE_MAINTENANCE_GLOBAL_CHECK-IN'); + } +} diff --git a/administrator/components/com_checkin/checkin.php b/administrator/components/com_checkin/checkin.php deleted file mode 100644 index 0e07b11dc54d6..0000000000000 --- a/administrator/components/com_checkin/checkin.php +++ /dev/null @@ -1,19 +0,0 @@ -authorise('core.manage', 'com_checkin')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('Checkin'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_checkin/checkin.xml b/administrator/components/com_checkin/checkin.xml index 338dfbd5562fd..d562de7114e05 100644 --- a/administrator/components/com_checkin/checkin.xml +++ b/administrator/components/com_checkin/checkin.xml @@ -9,12 +9,16 @@ www.joomla.org 3.0.0 COM_CHECKIN_XML_DESCRIPTION + Joomla\Component\Checkin - checkin.php + checkin.xml config.xml - controller.php + dispatcher.php + Controller + Model models + View views diff --git a/administrator/components/com_checkin/config.xml b/administrator/components/com_checkin/config.xml index 2a2238ff53755..6507e3488258c 100644 --- a/administrator/components/com_checkin/config.xml +++ b/administrator/components/com_checkin/config.xml @@ -17,11 +17,11 @@ + /> + />
diff --git a/administrator/components/com_checkin/controller.php b/administrator/components/com_checkin/controller.php deleted file mode 100644 index 66ddd9bc8f639..0000000000000 --- a/administrator/components/com_checkin/controller.php +++ /dev/null @@ -1,92 +0,0 @@ -addSubmenu($this->input->getWord('option', 'com_checkin')); - - return parent::display(); - } - - /** - * Check in a list of items. - * - * @return void - */ - public function checkin() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = $this->input->get('cid', array(), 'array'); - - if (empty($ids)) - { - JError::raiseWarning(500, JText::_('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST')); - } - else - { - // Get the model. - /** @var CheckinModelCheckin $model */ - $model = $this->getModel(); - - // Checked in the items. - $this->setMessage(JText::plural('COM_CHECKIN_N_ITEMS_CHECKED_IN', $model->checkin($ids))); - } - - $this->setRedirect('index.php?option=com_checkin'); - } - - /** - * Configure the Linkbar. - * - * @param string $vName The name of the active view. - * - * @return void - * - * @since 1.6 - */ - protected function addSubmenu($vName) - { - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_SUBMENU_CHECKIN'), - 'index.php?option=com_checkin', - $vName == 'com_checkin' - ); - - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_SUBMENU_CLEAR_CACHE'), - 'index.php?option=com_cache', - $vName == 'cache' - ); - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_SUBMENU_PURGE_EXPIRED_CACHE'), - 'index.php?option=com_cache&view=purge', - $vName == 'purge' - ); - } -} diff --git a/administrator/components/com_checkin/models/forms/filter_checkin.xml b/administrator/components/com_checkin/forms/filter_checkin.xml similarity index 86% rename from administrator/components/com_checkin/models/forms/filter_checkin.xml rename to administrator/components/com_checkin/forms/filter_checkin.xml index e203f51ae1af2..e9dbb85997ae3 100644 --- a/administrator/components/com_checkin/models/forms/filter_checkin.xml +++ b/administrator/components/com_checkin/forms/filter_checkin.xml @@ -14,8 +14,6 @@ @@ -28,9 +26,6 @@ diff --git a/administrator/components/com_checkin/models/checkin.php b/administrator/components/com_checkin/models/checkin.php deleted file mode 100644 index 2affd1593ad12..0000000000000 --- a/administrator/components/com_checkin/models/checkin.php +++ /dev/null @@ -1,254 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search')); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * Checks in requested tables - * - * @param array $ids An array of table names. Optional. - * - * @return integer Checked in item count - * - * @since 1.6 - */ - public function checkin($ids = array()) - { - $db = $this->getDbo(); - $nullDate = $db->getNullDate(); - - if (!is_array($ids)) - { - return 0; - } - - // This int will hold the checked item count. - $results = 0; - - foreach ($ids as $tn) - { - // Make sure we get the right tables based on prefix. - if (stripos($tn, JFactory::getApplication()->get('dbprefix')) !== 0) - { - continue; - } - - $fields = $db->getTableColumns($tn); - - if (!(isset($fields['checked_out']) && isset($fields['checked_out_time']))) - { - continue; - } - - $query = $db->getQuery(true) - ->update($db->quoteName($tn)) - ->set('checked_out = 0') - ->set('checked_out_time = ' . $db->quote($nullDate)) - ->where('checked_out > 0'); - - $db->setQuery($query); - - if ($db->execute()) - { - $results = $results + $db->getAffectedRows(); - } - } - - return $results; - } - - /** - * Get total of tables - * - * @return integer Total to check-in tables - * - * @since 1.6 - */ - public function getTotal() - { - if (!isset($this->total)) - { - $this->getItems(); - } - - return $this->total; - } - - /** - * Get tables - * - * @return array Checked in table names as keys and checked in item count as values. - * - * @since 1.6 - */ - public function getItems() - { - if (!isset($this->items)) - { - $db = $this->getDbo(); - $tables = $db->getTableList(); - - // This array will hold table name as key and checked in item count as value. - $results = array(); - - foreach ($tables as $i => $tn) - { - // Make sure we get the right tables based on prefix. - if (stripos($tn, JFactory::getApplication()->get('dbprefix')) !== 0) - { - unset($tables[$i]); - continue; - } - - if ($this->getState('filter.search') && stripos($tn, $this->getState('filter.search')) === false) - { - unset($tables[$i]); - continue; - } - - $fields = $db->getTableColumns($tn); - - if (!(isset($fields['checked_out']) && isset($fields['checked_out_time']))) - { - unset($tables[$i]); - continue; - } - } - - foreach ($tables as $tn) - { - $query = $db->getQuery(true) - ->select('COUNT(*)') - ->from($db->quoteName($tn)) - ->where('checked_out > 0'); - - $db->setQuery($query); - - if ($db->execute()) - { - $results[$tn] = $db->loadResult(); - - // Show only tables with items to checkin. - if ((int) $results[$tn] === 0) - { - unset($results[$tn]); - } - } - else - { - continue; - } - } - - $this->total = count($results); - - // Order items by table - if ($this->getState('list.ordering') == 'table') - { - if (strtolower($this->getState('list.direction')) == 'asc') - { - ksort($results); - } - else - { - krsort($results); - } - } - // Order items by number of items - else - { - if (strtolower($this->getState('list.direction')) == 'asc') - { - asort($results); - } - else - { - arsort($results); - } - } - - // Pagination - $limit = (int) $this->getState('list.limit'); - - if ($limit !== 0) - { - $this->items = array_slice($results, $this->getState('list.start'), $limit); - } - else - { - $this->items = $results; - } - } - - return $this->items; - } -} diff --git a/administrator/components/com_checkin/services/provider.php b/administrator/components/com_checkin/services/provider.php new file mode 100644 index 0000000000000..371d200d35f86 --- /dev/null +++ b/administrator/components/com_checkin/services/provider.php @@ -0,0 +1,54 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Checkin')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Checkin')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_checkin/tmpl/checkin/default.php b/administrator/components/com_checkin/tmpl/checkin/default.php new file mode 100644 index 0000000000000..9ba57100894fc --- /dev/null +++ b/administrator/components/com_checkin/tmpl/checkin/default.php @@ -0,0 +1,76 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + total > 0) : ?> + + + + + + + + + + + items as $table => $count) : ?> + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_checkin/views/checkin/tmpl/default.xml b/administrator/components/com_checkin/tmpl/checkin/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_checkin/views/checkin/tmpl/default.xml rename to administrator/components/com_checkin/tmpl/checkin/default.xml diff --git a/administrator/components/com_checkin/views/checkin/tmpl/default.php b/administrator/components/com_checkin/views/checkin/tmpl/default.php deleted file mode 100644 index 374fed70a9c34..0000000000000 --- a/administrator/components/com_checkin/views/checkin/tmpl/default.php +++ /dev/null @@ -1,68 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
-sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> - total > 0) : ?> - - - - - - - - - - - - - - - - items as $table => $count) : ?> - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - -
- - - - -
- diff --git a/administrator/components/com_checkin/views/checkin/view.html.php b/administrator/components/com_checkin/views/checkin/view.html.php deleted file mode 100644 index 12c16424360e7..0000000000000 --- a/administrator/components/com_checkin/views/checkin/view.html.php +++ /dev/null @@ -1,105 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->total = $this->get('Total'); - $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 1.6 - */ - protected function addToolbar() - { - JToolbarHelper::title(JText::_('COM_CHECKIN_GLOBAL_CHECK_IN'), 'checkin'); - - JToolbarHelper::custom('checkin', 'checkin.png', 'checkin_f2.png', 'JTOOLBAR_CHECKIN', true); - - if (JFactory::getUser()->authorise('core.admin', 'com_checkin')) - { - JToolbarHelper::divider(); - JToolbarHelper::preferences('com_checkin'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_SITE_MAINTENANCE_GLOBAL_CHECK-IN'); - } -} diff --git a/administrator/components/com_config/Controller/ApplicationController.php b/administrator/components/com_config/Controller/ApplicationController.php new file mode 100644 index 0000000000000..193fe8ef760ef --- /dev/null +++ b/administrator/components/com_config/Controller/ApplicationController.php @@ -0,0 +1,266 @@ +registerTask('apply', 'save'); + } + + /** + * Cancel operation. + * + * @return void + * + * @since 3.0.0 + */ + public function cancel() + { + $this->setRedirect(Route::_('index.php?option=com_cpanel')); + } + + /** + * Saves the form + * + * @return mixed + * + * @since 4.0.0 + */ + public function save() + { + // Check for request forgeries. + if (!Session::checkToken()) + { + $this->setRedirect('index.php', Text::_('JINVALID_TOKEN'), 'error'); + } + + // Check if the user is authorized to do this. + if (!$this->app->getIdentity()->authorise('core.admin')) + { + $this->setRedirect('index.php', Text::_('JERROR_ALERTNOAUTHOR'), 'error'); + } + + // Set FTP credentials, if given. + ClientHelper::setCredentialsFromRequest('ftp'); + + /** @var \Joomla\Component\Config\Administrator\Model\ApplicationModel $model */ + $model = $this->getModel('Application', 'Administrator'); + + $data = $this->input->post->get('jform', array(), 'array'); + + // Complete data array if needed + $oldData = $model->getData(); + $data = array_replace($oldData, $data); + + // Get request type + $saveFormat = Factory::getDocument()->getType(); + + // Handle service requests + if ($saveFormat == 'json') + { + return $model->save($data); + } + + // Must load after serving service-requests + $form = $model->getForm(); + + // 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) + { + /* + * The validate method enqueued all messages for us, so we just need to redirect back. + */ + + // Redirect back to the edit screen. + $this->setRedirect(Route::_('index.php?option=com_config', false)); + } + + // Attempt to save the configuration. + $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) + { + /* + * The save method enqueued all messages for us, so we just need to redirect back. + */ + + // Save failed, go back to the screen and display a notice. + $this->app->redirect(Route::_('index.php?option=com_config', false)); + } + + // Set the success message. + $this->app->enqueueMessage(Text::_('COM_CONFIG_SAVE_SUCCESS'), 'message'); + + // Set the redirect based on the task. + switch ($this->input->getCmd('task')) + { + case 'apply': + $this->setRedirect(Route::_('index.php?option=com_config', false)); + break; + + case 'save': + default: + $this->setRedirect(Route::_('index.php', false)); + break; + } + } + + /** + * Method to remove root in global configuration. + * + * @return boolean True on success. + * + * @since 3.2 + */ + public function removeroot() + { + // Check for request forgeries. + if (!Session::checkToken('get')) + { + $this->setRedirect('index.php', Text::_('JINVALID_TOKEN'), 'error'); + } + + // Check if the user is authorized to do this. + if (!$this->app->getIdentity()->authorise('core.admin')) + { + $this->setRedirect('index.php', Text::_('JERROR_ALERTNOAUTHOR'), 'error'); + } + + // Initialise model. + + /** @var \Joomla\Component\Config\Administrator\Model\ApplicationModel $model */ + $model = $this->getModel('Application', 'Administrator'); + + // Attempt to save the configuration and remove root. + try + { + $model->removeroot(); + } + catch (\RuntimeException $e) + { + // Save failed, go back to the screen and display a notice. + $this->setRedirect('index.php', Text::_('JERROR_SAVE_FAILED', $e->getMessage()), 'error'); + } + + // Set the redirect based on the task. + $this->setRedirect(Route::_('index.php'), Text::_('COM_CONFIG_SAVE_SUCCESS')); + } + + /** + * Method to send the test mail. + * + * @return string + * + * @since 3.5 + */ + public function sendtestmail() + { + // Send json mime type. + $this->app->mimeType = 'application/json'; + $this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet); + $this->app->sendHeaders(); + + // Check if user token is valid. + if (!Session::checkToken('get')) + { + $this->app->enqueueMessage(Text::_('JINVALID_TOKEN'), 'error'); + echo new JsonResponse; + $this->app->close(); + } + + // Check if the user is authorized to do this. + if (!$this->app->getIdentity()->authorise('core.admin')) + { + $this->app->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'error'); + echo new JsonResponse; + $this->app->close(); + } + + /** @var \Joomla\Component\Config\Administrator\Model\ApplicationModel $model */ + $model = $this->getModel('Application', 'Administrator'); + + echo new JsonResponse($model->sendTestMail()); + + $this->app->close(); + } + + /** + * Method to GET permission value and give it to the model for storing in the database. + * + * @return boolean true on success, false when failed + * + * @since 3.5 + */ + public function store() + { + // Send json mime type. + $this->app->mimeType = 'application/json'; + $this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet); + $this->app->sendHeaders(); + + // Check if user token is valid. + if (!Session::checkToken('get')) + { + $this->app->enqueueMessage(Text::_('JINVALID_TOKEN'), 'error'); + echo new JsonResponse; + $this->app->close(); + } + + /** @var \Joomla\Component\Config\Administrator\Model\Application $model */ + $model = $this->getModel('Application', 'Administrator'); + echo new JsonResponse($model->storePermissions()); + $this->app->close(); + } +} diff --git a/administrator/components/com_config/Controller/ComponentController.php b/administrator/components/com_config/Controller/ComponentController.php new file mode 100644 index 0000000000000..c0b89b624970e --- /dev/null +++ b/administrator/components/com_config/Controller/ComponentController.php @@ -0,0 +1,182 @@ +registerTask('apply', 'save'); + } + + /** + * Method to save global configuration. + * + * @return mixed Calls $app->redirect() + * + * @since 3.2 + */ + public function save() + { + // Check for request forgeries. + if (!Session::checkToken()) + { + $this->setRedirect(Route::_('index.php'), Text::_('JINVALID_TOKEN'), 'error'); + } + + // Set FTP credentials, if given. + ClientHelper::setCredentialsFromRequest('ftp'); + + /** @var \Joomla\Component\Config\Administrator\Model\ComponentModel $model */ + $model = $this->getModel('Component', 'Administrator'); + $form = $model->getForm(); + $data = $this->input->get('jform', array(), 'array'); + $id = $this->input->getInt('id'); + $option = $this->input->get('component'); + $user = $this->app->getIdentity(); + + // Check if the user is authorised to do this. + if (!$user->authorise('core.admin', $option) && !$user->authorise('core.options', $option)) + { + $this->setRedirect(Route::_('index.php'), Text::_('JERROR_ALERTNOAUTHOR'), 'error'); + } + + // Remove the permissions rules data if user isn't allowed to edit them. + if (!$user->authorise('core.admin', $option) && isset($data['params']) && isset($data['params']['rules'])) + { + unset($data['params']['rules']); + } + + $returnUri = $this->input->post->get('return', null, 'base64'); + + $redirect = ''; + + if (!empty($returnUri)) + { + $redirect = '&return=' . urlencode($returnUri); + } + + // Validate the posted data. + $return = $model->validate($form, $data); + + // Check for validation errors. + if ($return === false) + { + /* + * The validate method enqueued all messages for us, so we just need to redirect back. + */ + + // Save the data in the session. + $this->app->setUserState('com_config.config.global.data', $data); + + // Redirect back to the edit screen. + $this->setRedirect(Route::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false)); + } + + // Attempt to save the configuration. + $data = array( + 'params' => $return, + 'id' => $id, + 'option' => $option + ); + + try + { + $model->save($data); + } + catch (\RuntimeException $e) + { + // Save the 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->setRedirect( + Route::_('index.php?option=com_config&view=component&component=' . $option . $redirect), + Text::_('JERROR_SAVE_FAILED', $e->getMessage()), + 'error' + ); + } + + // Set the redirect based on the task. + switch ($this->input->getCmd('task')) + { + case 'apply': + $this->app->enqueueMessage(Text::_('COM_CONFIG_SAVE_SUCCESS'), 'message'); + $this->app->redirect(Route::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false)); + + break; + + case 'save': + default: + $redirect = 'index.php?option=' . $option; + + if (!empty($returnUri)) + { + $redirect = base64_decode($returnUri); + } + + // Don't redirect to an external URL. + if (!Uri::isInternal($redirect)) + { + $redirect = Uri::base(); + } + + $this->setRedirect(Route::_($redirect, false)); + + break; + } + + return true; + } + + /** + * Method to cancel global configuration component. + * + * @return void + * + * @since 3.2 + */ + public function cancel() + { + $component = $this->input->getCmd('component'); + + $this->setRedirect('index.php?option=' . $component); + } +} diff --git a/administrator/components/com_config/Controller/DisplayController.php b/administrator/components/com_config/Controller/DisplayController.php new file mode 100644 index 0000000000000..3841ce95623dd --- /dev/null +++ b/administrator/components/com_config/Controller/DisplayController.php @@ -0,0 +1,31 @@ +input->getWord('option', 'com_config'); + + if ($this->app->isClient('administrator')) + { + $viewName = $this->input->getWord('view', 'application'); + } + else + { + $viewName = $this->input->getWord('view', 'config'); + } + + // Register the layout paths for the view + $paths = new \SplPriorityQueue; + + if ($this->app->isClient('administrator')) + { + $paths->insert(JPATH_ADMINISTRATOR . '/components/' . $componentFolder . '/view/' . $viewName . '/tmpl', 1); + } + else + { + $paths->insert(JPATH_BASE . '/components/' . $componentFolder . '/view/' . $viewName . '/tmpl', 1); + } + + $model = new \Joomla\Component\Config\Administrator\Model\ApplicationModel; + $component = $model->getState()->get('component.option'); + + // Access check. + if (!$this->app->getIdentity()->authorise('core.admin', $component) + && !$this->app->getIdentity()->authorise('core.options', $component)) + { + $this->app->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'error'); + + return; + } + + try + { + $data = $model->getData(); + $user = $this->app->getIdentity(); + } + catch (\Exception $e) + { + $this->app->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + $this->userIsSuperAdmin = $user->authorise('core.admin'); + + // Required data + $requiredData = array( + 'sitename' => null, + 'offline' => null, + 'access' => null, + 'list_limit' => null, + 'MetaDesc' => null, + 'MetaKeys' => null, + 'MetaRights' => null, + 'sef' => null, + 'sitename_pagetitles' => null, + 'debug' => null, + 'debug_lang' => null, + 'error_reporting' => null, + 'mailfrom' => null, + 'fromname' => null + ); + + $data = array_intersect_key($data, $requiredData); + + return json_encode($data); + } +} diff --git a/administrator/components/com_config/Field/ConfigComponentsField.php b/administrator/components/com_config/Field/ConfigComponentsField.php new file mode 100644 index 0000000000000..4dff28f1ff625 --- /dev/null +++ b/administrator/components/com_config/Field/ConfigComponentsField.php @@ -0,0 +1,87 @@ +getQuery(true) + ->select('name AS text, element AS value') + ->from('#__extensions') + ->where('enabled >= 1') + ->where('type =' . $db->quote('component')); + + $items = $db->setQuery($query)->loadObjectList(); + + if ($items) + { + $lang = Factory::getLanguage(); + + foreach ($items as &$item) + { + // Load language + $extension = $item->value; + + if (File::exists(JPATH_ADMINISTRATOR . '/components/' . $extension . '/config.xml')) + { + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + + // Translate component name + $item->text = Text::_($item->text); + } + else + { + $item = null; + } + } + + // Sort by component name + $items = ArrayHelper::sortObjects(array_filter($items), 'text', 1, true, true); + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $items); + + return $options; + } +} diff --git a/administrator/components/com_config/Field/FiltersField.php b/administrator/components/com_config/Field/FiltersField.php new file mode 100644 index 0000000000000..c325aa78d0e68 --- /dev/null +++ b/administrator/components/com_config/Field/FiltersField.php @@ -0,0 +1,171 @@ +getUserGroups(); + + // Build the form control. + $html = array(); + + // Open the table. + $html[] = ''; + + // The table heading. + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + + // The table body. + $html[] = ' '; + + foreach ($groups as $group) + { + if (!isset($this->value[$group->value])) + { + $this->value[$group->value] = array('filter_type' => 'BL', 'filter_tags' => '', 'filter_attributes' => ''); + } + + $group_filter = $this->value[$group->value]; + + $group_filter['filter_tags'] = !empty($group_filter['filter_tags']) ? $group_filter['filter_tags'] : ''; + $group_filter['filter_attributes'] = !empty($group_filter['filter_attributes']) ? $group_filter['filter_attributes'] : ''; + + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + } + + $html[] = ' '; + + // Close the table. + $html[] = '
'; + $html[] = ' ' . Text::_('JGLOBAL_FILTER_GROUPS_LABEL') . ''; + $html[] = ' '; + $html[] = ' ' . Text::_('JGLOBAL_FILTER_TYPE_LABEL') . ''; + $html[] = ' '; + $html[] = ' ' . Text::_('JGLOBAL_FILTER_TAGS_LABEL') . ''; + $html[] = ' '; + $html[] = ' ' . Text::_('JGLOBAL_FILTER_ATTRIBUTES_LABEL') . ''; + $html[] = '
'; + $html[] = ' ' . LayoutHelper::render('joomla.html.treeprefix', array('level' => $group->level + 1)) . $group->text; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = ' '; + $html[] = '
'; + + // Add notes + $html[] = '
'; + $html[] = '

' . Text::_('JGLOBAL_FILTER_TYPE_DESC') . '

'; + $html[] = '

' . Text::_('JGLOBAL_FILTER_TAGS_DESC') . '

'; + $html[] = '

' . Text::_('JGLOBAL_FILTER_ATTRIBUTES_DESC') . '

'; + $html[] = '
'; + + return implode("\n", $html); + } + + /** + * A helper to get the list of user groups. + * + * @return array + * + * @since 1.6 + */ + protected function getUserGroups() + { + // Get a database object. + $db = Factory::getDbo(); + + // Get the user groups from the database. + $query = $db->getQuery(true); + $query->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level'); + $query->from('#__usergroups AS a'); + $query->join('LEFT', '#__usergroups AS b on a.lft > b.lft AND a.rgt < b.rgt'); + $query->group('a.id, a.title, a.lft'); + $query->order('a.lft ASC'); + $db->setQuery($query); + $options = $db->loadObjectList(); + + return $options; + } +} diff --git a/administrator/components/com_config/Helper/ConfigHelper.php b/administrator/components/com_config/Helper/ConfigHelper.php new file mode 100644 index 0000000000000..3241bb1143071 --- /dev/null +++ b/administrator/components/com_config/Helper/ConfigHelper.php @@ -0,0 +1,134 @@ +getQuery(true) + ->select('element') + ->from('#__extensions') + ->where('type = ' . $db->quote('component')) + ->where('enabled = 1'); + $db->setQuery($query); + $result = $db->loadColumn(); + + return $result; + } + + /** + * Returns true if the component has configuration options. + * + * @param string $component Component name + * + * @return boolean + * + * @since 3.0 + */ + public static function hasComponentConfig($component) + { + return is_file(JPATH_ADMINISTRATOR . '/components/' . $component . '/config.xml'); + } + + /** + * Returns an array of all components with configuration options. + * Optionally return only those components for which the current user has 'core.manage' rights. + * + * @param boolean $authCheck True to restrict to components where current user has 'core.manage' rights. + * + * @return array + * + * @since 3.0 + */ + public static function getComponentsWithConfig($authCheck = true) + { + $result = array(); + $components = self::getAllComponents(); + $user = Factory::getUser(); + + // Remove com_config from the array as that may have weird side effects + $components = array_diff($components, array('com_config')); + + foreach ($components as $component) + { + if (self::hasComponentConfig($component) && (!$authCheck || $user->authorise('core.manage', $component))) + { + self::loadLanguageForComponent($component); + $result[$component] = ApplicationHelper::stringURLSafe(Text::_($component)) . '_' . $component; + } + } + + asort($result); + + return array_keys($result); + } + + /** + * Load the sys language for the given component. + * + * @param array $components Array of component names. + * + * @return void + * + * @since 3.0 + */ + public static function loadLanguageForComponents($components) + { + foreach ($components as $component) + { + self::loadLanguageForComponent($component); + } + } + + /** + * Load the sys language for the given component. + * + * @param string $component component name. + * + * @return void + * + * @since 3.5 + */ + public static function loadLanguageForComponent($component) + { + if (empty($component)) + { + return; + } + + $lang = Factory::getLanguage(); + + // Load the core file then + // Load extension-local file. + $lang->load($component . '.sys', JPATH_BASE, null, false, true) + || $lang->load($component . '.sys', JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); + } +} diff --git a/administrator/components/com_config/Model/ApplicationModel.php b/administrator/components/com_config/Model/ApplicationModel.php new file mode 100644 index 0000000000000..ba84eaa6b71ce --- /dev/null +++ b/administrator/components/com_config/Model/ApplicationModel.php @@ -0,0 +1,1008 @@ +loadForm('com_config.application', 'application', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the configuration data. + * + * This method will load the global configuration data straight from + * 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. + * + * @since 1.6 + */ + public function getData() + { + // Get the config data. + $config = new \JConfig; + $data = ArrayHelper::fromObject($config); + + // Prime the asset_id for the rules. + $data['asset_id'] = 1; + + // Get the text filter data + $params = ComponentHelper::getParams('com_config'); + $data['filters'] = ArrayHelper::fromObject($params->get('filters')); + + // If no filter data found, get from com_content (update of 1.6/1.7 site) + if (empty($data['filters'])) + { + $contentParams = ComponentHelper::getParams('com_content'); + $data['filters'] = ArrayHelper::fromObject($contentParams->get('filters')); + } + + // Check for data in the session. + $temp = Factory::getApplication()->getUserState('com_config.config.global.data'); + + // Merge in the session data. + if (!empty($temp)) + { + $data = array_merge($data, $temp); + } + + return $data; + } + + /** + * Method to save the configuration data. + * + * @param array $data An array containing all global config data. + * + * @return boolean True on success, false on failure. + * + * @since 1.6 + */ + public function save($data) + { + $app = Factory::getApplication(); + + // Check that we aren't setting wrong database configuration + $options = array( + 'driver' => $data['dbtype'], + 'host' => $data['host'], + 'user' => $data['user'], + 'password' => Factory::getConfig()->get('password'), + 'database' => $data['db'], + 'prefix' => $data['dbprefix'] + ); + + try + { + $revisedDbo = DatabaseDriver::getInstance($options); + $revisedDbo->getVersion(); + } + catch (\Exception $e) + { + $app->enqueueMessage(Text::_('JLIB_DATABASE_ERROR_DATABASE_CONNECT'), 'error'); + + return false; + } + + // Check if we can set the Force SSL option + if ((int) $data['force_ssl'] !== 0 && (int) $data['force_ssl'] !== (int) Factory::getConfig()->get('force_ssl', '0')) + { + try + { + // Make an HTTPS request to check if the site is available in HTTPS. + $host = Uri::getInstance()->getHost(); + $options = new Registry; + $options->set('userAgent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0'); + + // Do not check for valid server certificate here, leave this to the user, moreover disable using a proxy if any is configured. + $options->set('transport.curl', + array( + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_PROXY => null, + CURLOPT_PROXYUSERPWD => null, + ) + ); + $response = HttpFactory::getHttp($options)->get('https://' . $host . Uri::root(true) . '/', array('Host' => $host), 10); + + // If available in HTTPS check also the status code. + if (!in_array($response->code, array(200, 503, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 401), true)) + { + throw new \RuntimeException(Text::_('COM_CONFIG_ERROR_SSL_NOT_AVAILABLE_HTTP_CODE')); + } + } + catch (\RuntimeException $e) + { + $data['force_ssl'] = 0; + + // Also update the user state + $app->setUserState('com_config.config.global.data.force_ssl', 0); + + // Inform the user + $app->enqueueMessage(Text::sprintf('COM_CONFIG_ERROR_SSL_NOT_AVAILABLE', $e->getMessage()), 'warning'); + } + } + + // Save the rules + if (isset($data['rules'])) + { + $rules = new Rules($data['rules']); + + // Check that we aren't removing our Super User permission + // Need to get groups from database, since they might have changed + $myGroups = Access::getGroupsByUser(Factory::getUser()->get('id')); + $myRules = $rules->getData(); + $hasSuperAdmin = $myRules['core.admin']->allow($myGroups); + + if (!$hasSuperAdmin) + { + $app->enqueueMessage(Text::_('COM_CONFIG_ERROR_REMOVING_SUPER_ADMIN'), 'error'); + + return false; + } + + $asset = Table::getInstance('asset'); + + if ($asset->loadByName('root.1')) + { + $asset->rules = (string) $rules; + + if (!$asset->check() || !$asset->store()) + { + $app->enqueueMessage($asset->getError(), 'error'); + + return false; + } + } + else + { + $app->enqueueMessage(Text::_('COM_CONFIG_ERROR_ROOT_ASSET_NOT_FOUND'), 'error'); + + return false; + } + + unset($data['rules']); + } + + // Save the text filters + if (isset($data['filters'])) + { + $registry = new Registry(array('filters' => $data['filters'])); + + $extension = Table::getInstance('extension'); + + // Get extension_id + $extensionId = $extension->find(array('name' => 'com_config')); + + if ($extension->load((int) $extensionId)) + { + $extension->params = (string) $registry; + + if (!$extension->check() || !$extension->store()) + { + $app->enqueueMessage($extension->getError(), 'error'); + + return false; + } + } + else + { + $app->enqueueMessage(Text::_('COM_CONFIG_ERROR_CONFIG_EXTENSION_NOT_FOUND'), 'error'); + + return false; + } + + unset($data['filters']); + } + + // Get the previous configuration. + $prev = new \JConfig; + $prev = ArrayHelper::fromObject($prev); + + // Merge the new data in. We do this to preserve values that were not in the form. + $data = array_merge($prev, $data); + + /* + * Perform miscellaneous options based on configuration settings/changes. + */ + + // Escape the offline message if present. + if (isset($data['offline_message'])) + { + $data['offline_message'] = \JFilterOutput::ampReplace($data['offline_message']); + } + + // Purge the database session table if we are changing to the database handler. + if ($prev['session_handler'] != 'database' && $data['session_handler'] == 'database') + { + $query = $this->_db->getQuery(true) + ->delete($this->_db->quoteName('#__session')) + ->where($this->_db->quoteName('time') . ' < ' . (time() - 1)); + $this->_db->setQuery($query); + $this->_db->execute(); + } + + // Purge the database session table if we are disabling session metadata + if ($prev['session_metadata'] == 1 && $data['session_metadata'] == 0) + { + try + { + // If we are are using the session handler, purge the extra columns, otherwise truncate the whole session table + if ($data['session_handler'] === 'database') + { + $revisedDbo->setQuery( + $revisedDbo->getQuery(true) + ->update('#__session') + ->set( + [ + $revisedDbo->quoteName('client_id') . ' = 0', + $revisedDbo->quoteName('guest') . ' = NULL', + $revisedDbo->quoteName('userid') . ' = NULL', + $revisedDbo->quoteName('username') . ' = NULL', + ] + ) + )->execute(); + } + else + { + $revisedDbo->truncateTable('#__session'); + } + } + catch (RuntimeException $e) + { + /* + * The database API logs errors on failures so we don't need to add any error handling mechanisms here. + * Also, this data won't be added or checked anymore once the configuration is saved, so it'll purge itself + * through normal garbage collection anyway or if not using the database handler someone can purge the + * table on their own. Either way, carry on Soldier! + */ + } + } + + // Ensure custom session file path exists or try to create it if changed + if (!empty($data['session_filesystem_path'])) + { + $currentPath = $prev['session_filesystem_path'] ?? null; + + if ($currentPath) + { + $currentPath = Path::clean($currentPath); + } + + $data['session_filesystem_path'] = Path::clean($data['session_filesystem_path']); + + if ($currentPath !== $data['session_filesystem_path']) + { + if (!Folder::exists($data['session_filesystem_path']) && !Folder::create($data['session_filesystem_path'])) + { + try + { + \JLog::add( + \JText::sprintf('COM_CONFIG_ERROR_CUSTOM_SESSION_FILESYSTEM_PATH_NOTWRITABLE_USING_DEFAULT', $data['session_filesystem_path']), + \JLog::WARNING, + 'jerror' + ); + } + catch (\RuntimeException $logException) + { + $app->enqueueMessage( + \JText::sprintf('COM_CONFIG_ERROR_CUSTOM_SESSION_FILESYSTEM_PATH_NOTWRITABLE_USING_DEFAULT', $data['session_filesystem_path']), + 'warning' + ); + } + + $data['session_filesystem_path'] = $currentPath; + } + } + } + + // Set the shared session configuration + if (isset($data['shared_session'])) + { + $currentShared = $prev['shared_session'] ?? '0'; + + // Has the user enabled shared sessions? + if ($data['shared_session'] == 1 && $currentShared == 0) + { + // Generate a random shared session name + $data['session_name'] = UserHelper::genRandomPassword(16); + } + + // Has the user disabled shared sessions? + if ($data['shared_session'] == 0 && $currentShared == 1) + { + // Remove the session name value + unset($data['session_name']); + } + } + + // Set the shared session configuration + if (isset($data['shared_session'])) + { + $currentShared = $prev['shared_session'] ?? '0'; + + // Has the user enabled shared sessions? + if ($data['shared_session'] == 1 && $currentShared == 0) + { + // Generate a random shared session name + $data['session_name'] = UserHelper::genRandomPassword(16); + } + + // Has the user disabled shared sessions? + if ($data['shared_session'] == 0 && $currentShared == 1) + { + // Remove the session name value + unset($data['session_name']); + } + } + + if (empty($data['cache_handler'])) + { + $data['caching'] = 0; + } + + /* + * Look for a custom cache_path + * First check if a path is given in the submitted data, then check if a path exists in the previous data, otherwise use the default + */ + if (!empty($data['cache_path'])) + { + $path = $data['cache_path']; + } + elseif (!empty($prev['cache_path'])) + { + $path = $prev['cache_path']; + } + else + { + $path = JPATH_CACHE; + } + + // Give a warning if the cache-folder can not be opened + if ($data['caching'] > 0 && $data['cache_handler'] == 'file' && @opendir($path) == false) + { + $error = true; + + // If a custom path is in use, try using the system default instead of disabling cache + if ($path !== JPATH_CACHE && @opendir(JPATH_CACHE) != false) + { + try + { + Log::add( + Text::sprintf('COM_CONFIG_ERROR_CUSTOM_CACHE_PATH_NOTWRITABLE_USING_DEFAULT', $path, JPATH_CACHE), + Log::WARNING, + 'jerror' + ); + } + catch (\RuntimeException $logException) + { + $app->enqueueMessage( + Text::sprintf('COM_CONFIG_ERROR_CUSTOM_CACHE_PATH_NOTWRITABLE_USING_DEFAULT', $path, JPATH_CACHE), + 'warning' + ); + } + + $path = JPATH_CACHE; + $error = false; + + $data['cache_path'] = ''; + } + + if ($error) + { + try + { + Log::add(Text::sprintf('COM_CONFIG_ERROR_CACHE_PATH_NOTWRITABLE', $path), Log::WARNING, 'jerror'); + } + catch (\RuntimeException $exception) + { + $app->enqueueMessage(Text::sprintf('COM_CONFIG_ERROR_CACHE_PATH_NOTWRITABLE', $path), 'warning'); + } + + $data['caching'] = 0; + } + } + + // Did the user remove their custom cache path? Don't save the variable to the config + if (empty($data['cache_path'])) + { + unset($data['cache_path']); + } + + // Clean the cache if disabled but previously enabled or changing cache handlers; these operations use the `$prev` data already in memory + if ((!$data['caching'] && $prev['caching']) || $data['cache_handler'] !== $prev['cache_handler']) + { + try + { + Factory::getCache()->clean(); + } + catch (CacheConnectingException $exception) + { + try + { + Log::add(Text::_('COM_CONFIG_ERROR_CACHE_CONNECTION_FAILED'), Log::WARNING, 'jerror'); + } + catch (\RuntimeException $logException) + { + $app->enqueueMessage(Text::_('COM_CONFIG_ERROR_CACHE_CONNECTION_FAILED'), 'warning'); + } + } + catch (UnsupportedCacheException $exception) + { + try + { + Log::add(Text::_('COM_CONFIG_ERROR_CACHE_DRIVER_UNSUPPORTED'), Log::WARNING, 'jerror'); + } + catch (\RuntimeException $logException) + { + $app->enqueueMessage(Text::_('COM_CONFIG_ERROR_CACHE_DRIVER_UNSUPPORTED'), 'warning'); + } + } + } + + // Create the new configuration object. + $config = new Registry($data); + + // Overwrite the old FTP credentials with the new ones. + $temp = Factory::getConfig(); + $temp->set('ftp_enable', $data['ftp_enable']); + $temp->set('ftp_host', $data['ftp_host']); + $temp->set('ftp_port', $data['ftp_port']); + $temp->set('ftp_user', $data['ftp_user']); + $temp->set('ftp_pass', $data['ftp_pass']); + $temp->set('ftp_root', $data['ftp_root']); + + // Clear cache of com_config component. + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + + // Write the configuration file. + return $this->writeConfigFile($config); + } + + /** + * Method to unset the root_user value from configuration data. + * + * This method will load the global configuration data straight from + * JConfig and remove the root_user value for security, then save the configuration. + * + * @return boolean True on success, false on failure. + * + * @since 1.6 + */ + public function removeroot() + { + // Get the previous configuration. + $prev = new \JConfig; + $prev = ArrayHelper::fromObject($prev); + + // Create the new configuration object, and unset the root_user property + unset($prev['root_user']); + $config = new Registry($prev); + + // Write the configuration file. + return $this->writeConfigFile($config); + } + + /** + * Method to write the configuration to a file. + * + * @param Registry $config A Registry object containing all global config data. + * + * @return boolean True on success, false on failure. + * + * @since 2.5.4 + * @throws \RuntimeException + */ + private function writeConfigFile(Registry $config) + { + // Set the configuration file path. + $file = JPATH_CONFIGURATION . '/configuration.php'; + + // Get the new FTP credentials. + $ftp = ClientHelper::getCredentials('ftp', true); + + $app = Factory::getApplication(); + + // Attempt to make the file writeable if using FTP. + if (!$ftp['enabled'] && Path::isOwner($file) && !Path::setPermissions($file, '0644')) + { + $app->enqueueMessage(Text::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE'), 'notice'); + } + + // 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)) + { + throw new \RuntimeException(Text::_('COM_CONFIG_ERROR_WRITE_FAILED')); + } + + // Attempt to make the file unwriteable if using FTP. + if (!$ftp['enabled'] && Path::isOwner($file) && !Path::setPermissions($file, '0444')) + { + $app->enqueueMessage(Text::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'), 'notice'); + } + + return true; + } + + /** + * Method to store the permission values in the asset table. + * + * This method will get an array with permission key value pairs and transform it + * into json and update the asset table in the database. + * + * @param string $permission Need an array with Permissions (component, rule, value and title) + * + * @return array|bool A list of result data or false on failure. + * + * @since 3.5 + */ + public function storePermissions($permission = null) + { + $app = Factory::getApplication(); + $user = Factory::getUser(); + + if (is_null($permission)) + { + // Get data from input. + $permission = array( + 'component' => $app->input->Json->get('comp'), + 'action' => $app->input->Json->get('action'), + 'rule' => $app->input->Json->get('rule'), + 'value' => $app->input->Json->get('value'), + 'title' => $app->input->Json->get('title', '', 'RAW') + ); + } + + // We are creating a new item so we don't have an item id so don't allow. + if (substr($permission['component'], -6) === '.false') + { + $app->enqueueMessage(Text::_('JLIB_RULES_SAVE_BEFORE_CHANGE_PERMISSIONS'), 'error'); + + return false; + } + + // Check if the user is authorized to do this. + if (!$user->authorise('core.admin', $permission['component'])) + { + $app->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'error'); + + return false; + } + + $permission['component'] = empty($permission['component']) ? 'root.1' : $permission['component']; + + // Current view is global config? + $isGlobalConfig = $permission['component'] === 'root.1'; + + // Check if changed group has Super User permissions. + $isSuperUserGroupBefore = Access::checkGroup($permission['rule'], 'core.admin'); + + // Check if current user belongs to changed group. + $currentUserBelongsToGroup = in_array((int) $permission['rule'], $user->groups) ? true : false; + + // Get current user groups tree. + $currentUserGroupsTree = Access::getGroupsByUser($user->id, true); + + // Check if current user belongs to changed group. + $currentUserSuperUser = $user->authorise('core.admin'); + + // If user is not Super User cannot change the permissions of a group it belongs to. + if (!$currentUserSuperUser && $currentUserBelongsToGroup) + { + $app->enqueueMessage(Text::_('JLIB_USER_ERROR_CANNOT_CHANGE_OWN_GROUPS'), 'error'); + + return false; + } + + // If user is not Super User cannot change the permissions of a group it belongs to. + if (!$currentUserSuperUser && in_array((int) $permission['rule'], $currentUserGroupsTree)) + { + $app->enqueueMessage(Text::_('JLIB_USER_ERROR_CANNOT_CHANGE_OWN_PARENT_GROUPS'), 'error'); + + return false; + } + + // If user is not Super User cannot change the permissions of a Super User Group. + if (!$currentUserSuperUser && $isSuperUserGroupBefore && !$currentUserBelongsToGroup) + { + $app->enqueueMessage(Text::_('JLIB_USER_ERROR_CANNOT_CHANGE_SUPER_USER'), 'error'); + + return false; + } + + // If user is not Super User cannot change the Super User permissions in any group it belongs to. + if ($isSuperUserGroupBefore && $currentUserBelongsToGroup && $permission['action'] === 'core.admin') + { + $app->enqueueMessage(Text::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF'), 'error'); + + return false; + } + + try + { + /** @var Asset $asset */ + $asset = Table::getInstance('asset'); + $result = $asset->loadByName($permission['component']); + + if ($result === false) + { + $data = array($permission['action'] => array($permission['rule'] => $permission['value'])); + + $rules = new Rules($data); + $asset->rules = (string) $rules; + $asset->name = (string) $permission['component']; + $asset->title = (string) $permission['title']; + + // Get the parent asset id so we have a correct tree. + /** @var Asset $parentAsset */ + $parentAsset = Table::getInstance('Asset'); + + if (strpos($asset->name, '.') !== false) + { + $assetParts = explode('.', $asset->name); + $parentAsset->loadByName($assetParts[0]); + $parentAssetId = $parentAsset->id; + } + else + { + $parentAssetId = $parentAsset->getRootId(); + } + + /** + * @to do: incorrect ACL stored + * When changing a permission of an item that doesn't have a row in the asset table the row a new row is created. + * This works fine for item <-> component <-> global config scenario and component <-> global config scenario. + * But doesn't work properly for item <-> section(s) <-> component <-> global config scenario, + * because a wrong parent asset id (the component) is stored. + * Happens when there is no row in the asset table (ex: deleted or not created on update). + */ + + $asset->setLocation($parentAssetId, 'last-child'); + } + else + { + // Decode the rule settings. + $temp = json_decode($asset->rules, true); + + // Check if a new value is to be set. + if (isset($permission['value'])) + { + // Check if we already have an action entry. + if (!isset($temp[$permission['action']])) + { + $temp[$permission['action']] = array(); + } + + // Check if we already have a rule entry. + if (!isset($temp[$permission['action']][$permission['rule']])) + { + $temp[$permission['action']][$permission['rule']] = array(); + } + + // Set the new permission. + $temp[$permission['action']][$permission['rule']] = (int) $permission['value']; + + // Check if we have an inherited setting. + if ($permission['value'] === '') + { + unset($temp[$permission['action']][$permission['rule']]); + } + + // Check if we have any rules. + if (!$temp[$permission['action']]) + { + unset($temp[$permission['action']]); + } + } + else + { + // There is no value so remove the action as it's not needed. + unset($temp[$permission['action']]); + } + + $asset->rules = json_encode($temp, JSON_FORCE_OBJECT); + } + + if (!$asset->check() || !$asset->store()) + { + $app->enqueueMessage(Text::_('JLIB_UNKNOWN'), 'error'); + + return false; + } + } + catch (\Exception $e) + { + $app->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + // All checks done. + $result = array( + 'text' => '', + 'class' => '', + 'result' => true, + ); + + // Show the current effective calculated permission considering current group, path and cascade. + + try + { + // Get the asset id by the name of the component. + $query = $this->getDbo()->getQuery(true) + ->select($this->getDbo()->quoteName('id')) + ->from($this->getDbo()->quoteName('#__assets')) + ->where($this->getDbo()->quoteName('name') . ' = ' . $this->getDbo()->quote($permission['component'])); + + $this->_db->setQuery($query); + + $assetId = (int) $this->_db->loadResult(); + + // Fetch the parent asset id. + $parentAssetId = null; + + /** + * @to do: incorrect info + * When creating a new item (not saving) it uses the calculated permissions from the component (item <-> component <-> global config). + * But if we have a section too (item <-> section(s) <-> component <-> global config) this is not correct. + * Also, currently it uses the component permission, but should use the calculated permissions for achild of the component/section. + */ + + // If not in global config we need the parent_id asset to calculate permissions. + if (!$isGlobalConfig) + { + // In this case we need to get the component rules too. + $query->clear() + ->select($this->_db->quoteName('parent_id')) + ->from($this->_db->quoteName('#__assets')) + ->where($this->_db->quoteName('id') . ' = ' . $assetId); + + $this->_db->setQuery($query); + + $parentAssetId = (int) $this->_db->loadResult(); + } + + // Get the group parent id of the current group. + $query->clear() + ->select($this->_db->quoteName('parent_id')) + ->from($this->_db->quoteName('#__usergroups')) + ->where($this->_db->quoteName('id') . ' = ' . (int) $permission['rule']); + + $this->_db->setQuery($query); + + $parentGroupId = (int) $this->_db->loadResult(); + + // Count the number of child groups of the current group. + $query->clear() + ->select('COUNT(' . $this->_db->quoteName('id') . ')') + ->from($this->_db->quoteName('#__usergroups')) + ->where($this->_db->quoteName('parent_id') . ' = ' . (int) $permission['rule']); + + $this->_db->setQuery($query); + + $totalChildGroups = (int) $this->_db->loadResult(); + } + catch (\Exception $e) + { + $app->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + // Clear access statistics. + Access::clearStatics(); + + // After current group permission is changed we need to check again if the group has Super User permissions. + $isSuperUserGroupAfter = Access::checkGroup($permission['rule'], 'core.admin'); + + // Get the rule for just this asset (non-recursive) and get the actual setting for the action for this group. + $assetRule = Access::getAssetRules($assetId, false, false)->allow($permission['action'], $permission['rule']); + + // Get the group, group parent id, and group global config recursive calculated permission for the chosen action. + $inheritedGroupRule = Access::checkGroup($permission['rule'], $permission['action'], $assetId); + + if (!empty($parentAssetId)) + { + $inheritedGroupParentAssetRule = Access::checkGroup($permission['rule'], $permission['action'], $parentAssetId); + } + else + { + $inheritedGroupParentAssetRule = null; + } + + $inheritedParentGroupRule = !empty($parentGroupId) ? Access::checkGroup($parentGroupId, $permission['action'], $assetId) : null; + + // Current group is a Super User group, so calculated setting is "Allowed (Super User)". + if ($isSuperUserGroupAfter) + { + $result['class'] = 'badge badge-success'; + $result['text'] = '' . Text::_('JLIB_RULES_ALLOWED_ADMIN'); + } + // Not super user. + else + { + // First get the real recursive calculated setting and add (Inherited) to it. + + // If recursive calculated setting is "Denied" or null. Calculated permission is "Not Allowed (Inherited)". + if ($inheritedGroupRule === null || $inheritedGroupRule === false) + { + $result['class'] = 'badge badge-danger'; + $result['text'] = Text::_('JLIB_RULES_NOT_ALLOWED_INHERITED'); + } + // If recursive calculated setting is "Allowed". Calculated permission is "Allowed (Inherited)". + else + { + $result['class'] = 'badge badge-success'; + $result['text'] = Text::_('JLIB_RULES_ALLOWED_INHERITED'); + } + + // Second part: Overwrite the calculated permissions labels if there is an explicity permission in the current group. + + /** + * @to do: incorect 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 ($assetRule === false) + { + $result['class'] = 'badge badge-danger'; + $result['text'] = Text::_('JLIB_RULES_NOT_ALLOWED'); + } + // If there is an explicity permission is "Allowed". Calculated permission is "Allowed". + elseif ($assetRule === true) + { + $result['class'] = 'badge badge-success'; + $result['text'] = Text::_('JLIB_RULES_ALLOWED'); + } + + // Third part: Overwrite the calculated permissions labels for special cases. + + // Global configuration with "Not Set" permission. Calculated permission is "Not Allowed (Default)". + if (empty($parentGroupId) && $isGlobalConfig === true && $assetRule === null) + { + $result['class'] = 'badge badge-danger'; + $result['text'] = Text::_('JLIB_RULES_NOT_ALLOWED_DEFAULT'); + } + + /** + * Component/Item with explicit "Denied" permission at parent Asset (Category, Component or Global config) configuration. + * Or some parent group has an explicit "Denied". + * Calculated permission is "Not Allowed (Locked)". + */ + elseif ($inheritedGroupParentAssetRule === false || $inheritedParentGroupRule === false) + { + $result['class'] = 'badge badge-danger'; + $result['text'] = '' . Text::_('JLIB_RULES_NOT_ALLOWED_LOCKED'); + } + } + + // If removed or added super user from group, we need to refresh the page to recalculate all settings. + if ($isSuperUserGroupBefore != $isSuperUserGroupAfter) + { + $app->enqueueMessage(Text::_('JLIB_RULES_NOTICE_RECALCULATE_GROUP_PERMISSIONS'), 'notice'); + } + + // If this group has child groups, we need to refresh the page to recalculate the child settings. + if ($totalChildGroups > 0) + { + $app->enqueueMessage(Text::_('JLIB_RULES_NOTICE_RECALCULATE_GROUP_CHILDS_PERMISSIONS'), 'notice'); + } + + return $result; + } + + /** + * Method to send a test mail which is called via an AJAX request + * + * @return boolean + * + * @since 3.5 + * @throws \Exception + */ + public function sendTestMail() + { + // Set the new values to test with the current settings + $app = Factory::getApplication(); + $input = $app->input->json; + + $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')); + $app->set('mailfrom', $input->get('mailfrom', '', 'STRING')); + $app->set('fromname', $input->get('fromname', '', 'STRING')); + $app->set('mailer', $input->get('mailer')); + $app->set('mailonline', $input->get('mailonline')); + + $mail = Factory::getMailer(); + + // Prepare email and send try to send it + $mailSubject = Text::sprintf('COM_CONFIG_SENDMAIL_SUBJECT', $app->get('sitename')); + $mailBody = Text::sprintf('COM_CONFIG_SENDMAIL_BODY', Text::_('COM_CONFIG_SENDMAIL_METHOD_' . strtoupper($mail->Mailer))); + + if ($mail->sendMail($app->get('mailfrom'), $app->get('fromname'), $app->get('mailfrom'), $mailSubject, $mailBody) === true) + { + $methodName = Text::_('COM_CONFIG_SENDMAIL_METHOD_' . strtoupper($mail->Mailer)); + + // If JMail send the mail using PHP Mail as fallback. + if ($mail->Mailer != $app->get('mailer')) + { + $app->enqueueMessage(Text::sprintf('COM_CONFIG_SENDMAIL_SUCCESS_FALLBACK', $app->get('mailfrom'), $methodName), 'warning'); + } + else + { + $app->enqueueMessage(Text::sprintf('COM_CONFIG_SENDMAIL_SUCCESS', $app->get('mailfrom'), $methodName), 'message'); + } + + return true; + } + + $app->enqueueMessage(Text::_('COM_CONFIG_SENDMAIL_ERROR'), 'error'); + + return false; + } +} diff --git a/administrator/components/com_config/Model/ComponentModel.php b/administrator/components/com_config/Model/ComponentModel.php new file mode 100644 index 0000000000000..21be8aa7a63f8 --- /dev/null +++ b/administrator/components/com_config/Model/ComponentModel.php @@ -0,0 +1,225 @@ +input; + + // Set the component (option) we are dealing with. + $component = $input->get('component'); + + $this->state->set('component.option', $component); + + // Set an alternative path for the configuration file. + if ($path = $input->getString('path')) + { + $path = Path::clean(JPATH_SITE . '/' . $path); + Path::check($path); + $this->state->set('component.path', $path); + } + } + + /** + * Method to get a form object. + * + * @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 mixed A JForm object on success, false on failure + * + * @since 3.2 + */ + public function getForm($data = array(), $loadData = true) + { + $state = $this->getState(); + $option = $state->get('component.option'); + + if ($path = $state->get('component.path')) + { + // Add the search path for the admin component config.xml file. + \JForm::addFormPath($path); + } + else + { + // Add the search path for the admin component config.xml file. + \JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/' . $option); + } + + // Get the form. + $form = $this->loadForm( + 'com_config.component', + 'config', + array('control' => 'jform', 'load_data' => $loadData), + false, + '/config' + ); + + if (empty($form)) + { + return false; + } + + $lang = Factory::getLanguage(); + $lang->load($option, JPATH_BASE, null, false, true) + || $lang->load($option, JPATH_BASE . "/components/$option", null, false, true); + + return $form; + } + + /** + * Get the component information. + * + * @return object + * + * @since 3.2 + */ + public function getComponent() + { + $state = $this->getState(); + $option = $state->get('component.option'); + + // Load common and local language files. + $lang = Factory::getLanguage(); + $lang->load($option, JPATH_BASE, null, false, true) + || $lang->load($option, JPATH_BASE . "/components/$option", null, false, true); + + $result = ComponentHelper::getComponent($option); + + return $result; + } + + /** + * Method to save the configuration data. + * + * @param array $data An array containing all global config data. + * + * @return boolean True on success, false on failure. + * + * @since 3.2 + * @throws \RuntimeException + */ + public function save($data) + { + $table = Table::getInstance('extension'); + $context = $this->option . '.' . $this->name; + PluginHelper::importPlugin('extension'); + + // Check super user group. + if (isset($data['params']) && !Factory::getUser()->authorise('core.admin')) + { + $form = $this->getForm(array(), false); + + foreach ($form->getFieldsets() as $fieldset) + { + foreach ($form->getFieldset($fieldset->name) as $field) + { + if ($field->type === 'UserGroupList' && isset($data['params'][$field->fieldname]) + && (int) $field->getAttribute('checksuperusergroup', 0) === 1 + && Access::checkGroup($data['params'][$field->fieldname], 'core.admin')) + { + throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); + } + } + } + } + + // Save the rules. + if (isset($data['params']) && isset($data['params']['rules'])) + { + $rules = new Rules($data['params']['rules']); + $asset = Table::getInstance('asset'); + + if (!$asset->loadByName($data['option'])) + { + $root = Table::getInstance('asset'); + $root->loadByName('root.1'); + $asset->name = $data['option']; + $asset->title = $data['option']; + $asset->setLocation($root->id, 'last-child'); + } + + $asset->rules = (string) $rules; + + if (!$asset->check() || !$asset->store()) + { + throw new \RuntimeException($asset->getError()); + } + + // We don't need this anymore + unset($data['option']); + unset($data['params']['rules']); + } + + // Load the previous Data + if (!$table->load($data['id'])) + { + throw new \RuntimeException($table->getError()); + } + + unset($data['id']); + + // Bind the data. + if (!$table->bind($data)) + { + throw new \RuntimeException($table->getError()); + } + + // Check the data. + if (!$table->check()) + { + throw new \RuntimeException($table->getError()); + } + + $result = Factory::getApplication()->triggerEvent('onExtensionBeforeSave', array($context, $table, false)); + + // Store the data. + if (in_array(false, $result, true) || !$table->store()) + { + throw new \RuntimeException($table->getError()); + } + + Factory::getApplication()->triggerEvent('onExtensionAfterSave', array($context, $table, false)); + + // Clean the component cache. + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + + return true; + } +} diff --git a/administrator/components/com_config/View/Application/HtmlView.php b/administrator/components/com_config/View/Application/HtmlView.php new file mode 100644 index 0000000000000..e0579c2324281 --- /dev/null +++ b/administrator/components/com_config/View/Application/HtmlView.php @@ -0,0 +1,116 @@ +get('form'); + $data = $this->get('data'); + $user = Factory::getUser(); + } + catch (\Exception $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + // Bind data + if ($form && $data) + { + $form->bind($data); + } + + // Get the params for com_users. + $usersParams = ComponentHelper::getParams('com_users'); + + // Get the params for com_media. + $mediaParams = ComponentHelper::getParams('com_media'); + + // Load settings for the FTP layer. + $ftp = ClientHelper::setCredentialsFromRequest('ftp'); + + $this->form = &$form; + $this->data = &$data; + $this->ftp = &$ftp; + $this->usersParams = &$usersParams; + $this->mediaParams = &$mediaParams; + $this->components = ConfigHelper::getComponentsWithConfig(); + ConfigHelper::loadLanguageForComponents($this->components); + + $this->userIsSuperAdmin = $user->authorise('core.admin'); + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.2 + */ + protected function addToolbar() + { + ToolbarHelper::title(Text::_('COM_CONFIG_GLOBAL_CONFIGURATION'), 'equalizer config'); + ToolbarHelper::saveGroup( + [ + ['apply', 'application.apply'], + ['save', 'application.save'] + ], + 'btn-success' + ); + ToolbarHelper::divider(); + ToolbarHelper::cancel('application.cancel'); + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_SITE_GLOBAL_CONFIGURATION'); + } +} diff --git a/administrator/components/com_config/View/Component/HtmlView.php b/administrator/components/com_config/View/Component/HtmlView.php new file mode 100644 index 0000000000000..7e5a02533048d --- /dev/null +++ b/administrator/components/com_config/View/Component/HtmlView.php @@ -0,0 +1,118 @@ +get('component'); + + if (!$component->enabled) + { + return false; + } + + $form = $this->get('form'); + $user = Factory::getUser(); + } + catch (\Exception $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + // Bind the form to the data. + if ($form && $component->params) + { + $form->bind($component->params); + } + + $this->fieldsets = $form ? $form->getFieldsets() : null; + $this->formControl = $form ? $form->getFormControl() : null; + + // Don't show permissions fieldset if not authorised. + if (!$user->authorise('core.admin', $component->option) && isset($this->fieldsets['permissions'])) + { + unset($this->fieldsets['permissions']); + } + + $this->form = &$form; + $this->component = &$component; + + $this->components = ConfigHelper::getComponentsWithConfig(); + + $this->userIsSuperAdmin = $user->authorise('core.admin'); + $this->currentComponent = Factory::getApplication()->input->get('component'); + $this->return = Factory::getApplication()->input->get('return', '', 'base64'); + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.2 + */ + protected function addToolbar() + { + ToolbarHelper::title(Text::_($this->component->option . '_configuration'), 'equalizer config'); + ToolbarHelper::saveGroup( + [ + ['apply', 'component.apply'], + ['save', 'component.save'] + ], + 'btn-success' + ); + ToolbarHelper::divider(); + ToolbarHelper::cancel('component.cancel'); + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_COMPONENTS_' . $this->currentComponent . '_OPTIONS'); + } +} diff --git a/administrator/components/com_config/access.xml b/administrator/components/com_config/access.xml index 861fef08ea0eb..7f5724e2caa09 100644 --- a/administrator/components/com_config/access.xml +++ b/administrator/components/com_config/access.xml @@ -1,6 +1,6 @@
- +
diff --git a/administrator/components/com_config/config.php b/administrator/components/com_config/config.php deleted file mode 100644 index 6b9c7e6576f2f..0000000000000 --- a/administrator/components/com_config/config.php +++ /dev/null @@ -1,31 +0,0 @@ -setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT', true); - -// Load classes -JLoader::registerPrefix('Config', JPATH_COMPONENT); -JLoader::registerPrefix('Config', JPATH_ROOT . '/components/com_config'); - -// Application -$app = JFactory::getApplication(); - -$controllerHelper = new ConfigControllerHelper; -$controller = $controllerHelper->parseController($app); - -$controller->prefix = 'Config'; - -// Perform the Request task -$controller->execute(); diff --git a/administrator/components/com_config/config.xml b/administrator/components/com_config/config.xml index bccece35f8ba1..1c50617618512 100644 --- a/administrator/components/com_config/config.xml +++ b/administrator/components/com_config/config.xml @@ -9,15 +9,18 @@ www.joomla.org 3.0.0 COM_CONFIG_XML_DESCRIPTION + Joomla\Component\Config config.php controller.php - controllers - models - controller - model - view + forms + tmpl + Controller + Field + Helper + Model + View language/en-GB.com_config.ini diff --git a/administrator/components/com_config/controller.php b/administrator/components/com_config/controller.php deleted file mode 100644 index d5f11a6cb0110..0000000000000 --- a/administrator/components/com_config/controller.php +++ /dev/null @@ -1,67 +0,0 @@ -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; - } - elseif (ucfirst($vName) == 'Component') - { - $controller = new ConfigControllerComponentDisplay; - } - - return $controller->execute(); - } -} diff --git a/administrator/components/com_config/controller/application/cancel.php b/administrator/components/com_config/controller/application/cancel.php deleted file mode 100644 index 06ef0a07c46d2..0000000000000 --- a/administrator/components/com_config/controller/application/cancel.php +++ /dev/null @@ -1,41 +0,0 @@ -authorise('core.admin', 'com_config')) - { - $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR')); - $this->app->redirect('index.php'); - } - - $this->context = 'com_config.config.global'; - - $this->redirect = 'index.php?option=com_cpanel'; - - parent::execute(); - } -} diff --git a/administrator/components/com_config/controller/application/display.php b/administrator/components/com_config/controller/application/display.php deleted file mode 100644 index 75ed0ea9d8032..0000000000000 --- a/administrator/components/com_config/controller/application/display.php +++ /dev/null @@ -1,27 +0,0 @@ -app->enqueueMessage(JText::_('JINVALID_TOKEN')); - $this->app->redirect('index.php'); - } - - // Check if the user is authorized to do this. - if (!JFactory::getUser()->authorise('core.admin')) - { - $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR')); - $this->app->redirect('index.php'); - } - - // Initialise model. - $model = new ConfigModelApplication; - - // Attempt to save the configuration and remove root. - try - { - $model->removeroot(); - } - catch (RuntimeException $e) - { - // Save failed, go back to the screen and display a notice. - $this->app->enqueueMessage(JText::sprintf('JERROR_SAVE_FAILED', $e->getMessage()), 'error'); - $this->app->redirect(JRoute::_('index.php', false)); - } - - // Set the redirect based on the task. - $this->app->enqueueMessage(JText::_('COM_CONFIG_SAVE_SUCCESS')); - $this->app->redirect(JRoute::_('index.php', false)); - } -} diff --git a/administrator/components/com_config/controller/application/save.php b/administrator/components/com_config/controller/application/save.php deleted file mode 100644 index fd6c78160e713..0000000000000 --- a/administrator/components/com_config/controller/application/save.php +++ /dev/null @@ -1,122 +0,0 @@ -redirect() for all cases except JSON - * - * @since 3.2 - */ - public function execute() - { - // Check for request forgeries. - if (!JSession::checkToken()) - { - $this->app->enqueueMessage(JText::_('JINVALID_TOKEN'), 'error'); - $this->app->redirect('index.php'); - } - - // Check if the user is authorized to do this. - if (!JFactory::getUser()->authorise('core.admin')) - { - $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); - $this->app->redirect('index.php'); - } - - // Set FTP credentials, if given. - JClientHelper::setCredentialsFromRequest('ftp'); - - $model = new ConfigModelApplication; - $data = $this->input->post->get('jform', array(), 'array'); - - // Complete data array if needed - $oldData = $model->getData(); - $data = array_replace($oldData, $data); - - // Get request type - $saveFormat = JFactory::getDocument()->getType(); - - // Handle service requests - if ($saveFormat == 'json') - { - return $model->save($data); - } - - // Must load after serving service-requests - $form = $model->getForm(); - - // 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) - { - /* - * The validate method enqueued all messages for us, so we just need to redirect back. - */ - - // Redirect back to the edit screen. - $this->app->redirect(JRoute::_('index.php?option=com_config&controller=config.display.application', false)); - } - - // Attempt to save the configuration. - $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) - { - /* - * The save method enqueued all messages for us, so we just need to redirect back. - */ - - // 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)); - } - - // Set the success message. - $this->app->enqueueMessage(JText::_('COM_CONFIG_SAVE_SUCCESS'), 'message'); - - // Set the redirect based on the task. - switch ($this->options[3]) - { - case 'apply': - $this->app->redirect(JRoute::_('index.php?option=com_config', false)); - break; - - case 'save': - default: - $this->app->redirect(JRoute::_('index.php', false)); - break; - } - } -} diff --git a/administrator/components/com_config/controller/application/sendtestmail.php b/administrator/components/com_config/controller/application/sendtestmail.php deleted file mode 100644 index 4de91c8814524..0000000000000 --- a/administrator/components/com_config/controller/application/sendtestmail.php +++ /dev/null @@ -1,52 +0,0 @@ -app->mimeType = 'application/json'; - $this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet); - $this->app->sendHeaders(); - - // Check if user token is valid. - if (!JSession::checkToken('get')) - { - $this->app->enqueueMessage(JText::_('JINVALID_TOKEN'), 'error'); - echo new JResponseJson; - $this->app->close(); - } - - // Check if the user is authorized to do this. - if (!JFactory::getUser()->authorise('core.admin')) - { - $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); - echo new JResponseJson; - $this->app->close(); - } - - $model = new ConfigModelApplication; - echo new JResponseJson($model->sendTestMail()); - $this->app->close(); - } -} diff --git a/administrator/components/com_config/controller/application/store.php b/administrator/components/com_config/controller/application/store.php deleted file mode 100644 index dcd8dc9184d81..0000000000000 --- a/administrator/components/com_config/controller/application/store.php +++ /dev/null @@ -1,44 +0,0 @@ -app->mimeType = 'application/json'; - $this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet); - $this->app->sendHeaders(); - - // Check if user token is valid. - if (!JSession::checkToken('get')) - { - $this->app->enqueueMessage(JText::_('JINVALID_TOKEN'), 'error'); - echo new JResponseJson; - $this->app->close(); - } - - $model = new ConfigModelApplication; - echo new JResponseJson($model->storePermissions()); - $this->app->close(); - } -} diff --git a/administrator/components/com_config/controller/component/cancel.php b/administrator/components/com_config/controller/component/cancel.php deleted file mode 100644 index 8d5919f1a06dc..0000000000000 --- a/administrator/components/com_config/controller/component/cancel.php +++ /dev/null @@ -1,36 +0,0 @@ -context = 'com_config.config.global'; - - $this->component = $this->input->get('component'); - - $this->redirect = 'index.php?option=' . $this->component; - - parent::execute(); - } -} diff --git a/administrator/components/com_config/controller/component/display.php b/administrator/components/com_config/controller/component/display.php deleted file mode 100644 index 456fcb788ec33..0000000000000 --- a/administrator/components/com_config/controller/component/display.php +++ /dev/null @@ -1,27 +0,0 @@ -redirect() - * - * @since 3.2 - */ - public function execute() - { - // Check for request forgeries. - if (!JSession::checkToken()) - { - $this->app->enqueueMessage(JText::_('JINVALID_TOKEN'), 'error'); - $this->app->redirect('index.php'); - } - - // Set FTP credentials, if given. - JClientHelper::setCredentialsFromRequest('ftp'); - - $model = new ConfigModelComponent; - $form = $model->getForm(); - $data = $this->input->get('jform', array(), 'array'); - $id = $this->input->getInt('id'); - $option = $this->input->get('component'); - $user = JFactory::getUser(); - - // Check if the user is authorised to do this. - if (!$user->authorise('core.admin', $option) && !$user->authorise('core.options', $option)) - { - $this->app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); - $this->app->redirect('index.php'); - } - - // Remove the permissions rules data if user isn't allowed to edit them. - if (!$user->authorise('core.admin', $option) && isset($data['params']) && isset($data['params']['rules'])) - { - unset($data['params']['rules']); - } - - $returnUri = $this->input->post->get('return', null, 'base64'); - - $redirect = ''; - - if (!empty($returnUri)) - { - $redirect = '&return=' . urlencode($returnUri); - } - - // Validate the posted data. - $return = $model->validate($form, $data); - - // Check for validation errors. - if ($return === false) - { - /* - * The validate method enqueued all messages for us, so we just need to redirect back. - */ - - // Save the 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&view=component&component=' . $option . $redirect, false)); - } - - // Attempt to save the configuration. - $data = array( - 'params' => $return, - 'id' => $id, - 'option' => $option - ); - - try - { - $model->save($data); - } - catch (RuntimeException $e) - { - // Save the 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->enqueueMessage(JText::sprintf('JERROR_SAVE_FAILED', $e->getMessage()), 'error'); - $this->app->redirect(JRoute::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false)); - } - - // Set the redirect based on the task. - switch ($this->options[3]) - { - case 'apply': - $this->app->enqueueMessage(JText::_('COM_CONFIG_SAVE_SUCCESS'), 'message'); - $this->app->redirect(JRoute::_('index.php?option=com_config&view=component&component=' . $option . $redirect, false)); - - break; - - case 'save': - default: - $redirect = 'index.php?option=' . $option; - - if (!empty($returnUri)) - { - $redirect = base64_decode($returnUri); - } - - // Don't redirect to an external URL. - if (!JUri::isInternal($redirect)) - { - $redirect = JUri::base(); - } - - $this->app->redirect(JRoute::_($redirect, false)); - - break; - } - - return true; - } -} diff --git a/administrator/components/com_config/controllers/application.php b/administrator/components/com_config/controllers/application.php deleted file mode 100644 index 33e3efae1d05b..0000000000000 --- a/administrator/components/com_config/controllers/application.php +++ /dev/null @@ -1,118 +0,0 @@ -registerTask('apply', 'save'); - } - - /** - * Method to save the configuration. - * - * @return boolean True on success, false on failure. - * - * @since 1.5 - * @deprecated 4.0 Use ConfigControllerApplicationSave instead. - */ - public function save() - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use ConfigControllerApplicationSave instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $controller = new ConfigControllerApplicationSave; - - return $controller->execute(); - } - - /** - * Cancel operation. - * - * @return boolean True if successful; false otherwise. - * - * @deprecated 4.0 Use ConfigControllerApplicationCancel instead. - */ - public function cancel() - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use ConfigControllerApplicationCancel instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $controller = new ConfigControllerApplicationCancel; - - return $controller->execute(); - } - - /** - * Method to remove the root property from the configuration. - * - * @return boolean True on success, false on failure. - * - * @since 1.5 - * @deprecated 4.0 Use ConfigControllerApplicationRemoveroot instead. - */ - public function removeroot() - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use ConfigControllerApplicationRemoveroot instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $controller = new ConfigControllerApplicationRemoveroot; - - return $controller->execute(); - } -} diff --git a/administrator/components/com_config/controllers/component.php b/administrator/components/com_config/controllers/component.php deleted file mode 100644 index a6800ce05cec8..0000000000000 --- a/administrator/components/com_config/controllers/component.php +++ /dev/null @@ -1,90 +0,0 @@ -registerTask('apply', 'save'); - } - - /** - * Cancel operation - * - * @return void - * - * @since 3.0 - * @deprecated 4.0 Use ConfigControllerComponentCancel instead. - */ - public function cancel() - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use ConfigControllerComponentCancel instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $controller = new ConfigControllerComponentCancel; - - $controller->execute(); - } - - /** - * Save the configuration. - * - * @return boolean True if successful; false otherwise. - * - * @deprecated 4.0 Use ConfigControllerComponentSave instead. - */ - public function save() - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use ConfigControllerComponentSave instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $controller = new ConfigControllerComponentSave; - - return $controller->execute(); - } -} diff --git a/administrator/components/com_config/forms/application.xml b/administrator/components/com_config/forms/application.xml new file mode 100644 index 0000000000000..bb9534a497d0f --- /dev/null +++ b/administrator/components/com_config/forms/application.xml @@ -0,0 +1,1175 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +
+ + + +
+
diff --git a/administrator/components/com_config/helper/config.php b/administrator/components/com_config/helper/config.php deleted file mode 100644 index 67bd435243830..0000000000000 --- a/administrator/components/com_config/helper/config.php +++ /dev/null @@ -1,127 +0,0 @@ -getQuery(true) - ->select('element') - ->from('#__extensions') - ->where('type = ' . $db->quote('component')) - ->where('enabled = 1'); - $db->setQuery($query); - $result = $db->loadColumn(); - - return $result; - } - - /** - * Returns true if the component has configuration options. - * - * @param string $component Component name - * - * @return boolean - * - * @since 3.0 - */ - public static function hasComponentConfig($component) - { - return is_file(JPATH_ADMINISTRATOR . '/components/' . $component . '/config.xml'); - } - - /** - * Returns an array of all components with configuration options. - * Optionally return only those components for which the current user has 'core.manage' rights. - * - * @param boolean $authCheck True to restrict to components where current user has 'core.manage' rights. - * - * @return array - * - * @since 3.0 - */ - public static function getComponentsWithConfig($authCheck = true) - { - $result = array(); - $components = self::getAllComponents(); - $user = JFactory::getUser(); - - // Remove com_config from the array as that may have weird side effects - $components = array_diff($components, array('com_config')); - - foreach ($components as $component) - { - if (self::hasComponentConfig($component) && (!$authCheck || $user->authorise('core.manage', $component))) - { - self::loadLanguageForComponent($component); - $result[$component] = JApplicationHelper::stringURLSafe(JText::_($component)) . '_' . $component; - } - } - - asort($result); - - return array_keys($result); - } - - /** - * Load the sys language for the given component. - * - * @param array $components Array of component names. - * - * @return void - * - * @since 3.0 - */ - public static function loadLanguageForComponents($components) - { - foreach ($components as $component) - { - self::loadLanguageForComponent($component); - } - } - - /** - * Load the sys language for the given component. - * - * @param string $component component name. - * - * @return void - * - * @since 3.5 - */ - public static function loadLanguageForComponent($component) - { - if (empty($component)) - { - return; - } - - $lang = JFactory::getLanguage(); - - // Load the core file then - // Load extension-local file. - $lang->load($component . '.sys', JPATH_BASE, null, false, true) - || $lang->load($component . '.sys', JPATH_ADMINISTRATOR . '/components/' . $component, null, false, true); - } -} diff --git a/administrator/components/com_config/model/application.php b/administrator/components/com_config/model/application.php deleted file mode 100644 index 4abbbfaebc07c..0000000000000 --- a/administrator/components/com_config/model/application.php +++ /dev/null @@ -1,890 +0,0 @@ -loadForm('com_config.application', 'application', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Method to get the configuration data. - * - * This method will load the global configuration data straight from - * 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. - * - * @since 1.6 - */ - public function getData() - { - // Get the config data. - $config = new JConfig; - $data = ArrayHelper::fromObject($config); - - // Prime the asset_id for the rules. - $data['asset_id'] = 1; - - // Get the text filter data - $params = JComponentHelper::getParams('com_config'); - $data['filters'] = ArrayHelper::fromObject($params->get('filters')); - - // If no filter data found, get from com_content (update of 1.6/1.7 site) - if (empty($data['filters'])) - { - $contentParams = JComponentHelper::getParams('com_content'); - $data['filters'] = ArrayHelper::fromObject($contentParams->get('filters')); - } - - // Check for data in the session. - $temp = JFactory::getApplication()->getUserState('com_config.config.global.data'); - - // Merge in the session data. - if (!empty($temp)) - { - $data = array_merge($data, $temp); - } - - return $data; - } - - /** - * Method to save the configuration data. - * - * @param array $data An array containing all global config data. - * - * @return boolean True on success, false on failure. - * - * @since 1.6 - */ - public function save($data) - { - $app = JFactory::getApplication(); - - // 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'), - 'database' => $data['db'], - 'prefix' => $data['dbprefix'] - ); - - try - { - JDatabaseDriver::getInstance($options)->getVersion(); - } - catch (Exception $e) - { - $app->enqueueMessage(JText::_('JLIB_DATABASE_ERROR_DATABASE_CONNECT'), 'error'); - - return false; - } - - // Check if we can set the Force SSL option - if ((int) $data['force_ssl'] !== 0 && (int) $data['force_ssl'] !== (int) JFactory::getConfig()->get('force_ssl', '0')) - { - try - { - // Make an HTTPS request to check if the site is available in HTTPS. - $host = JUri::getInstance()->getHost(); - $options = new \Joomla\Registry\Registry; - $options->set('userAgent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0'); - - // Do not check for valid server certificate here, leave this to the user, moreover disable using a proxy if any is configured. - $options->set('transport.curl', - array( - CURLOPT_SSL_VERIFYPEER => false, - CURLOPT_SSL_VERIFYHOST => false, - CURLOPT_PROXY => null, - CURLOPT_PROXYUSERPWD => null, - ) - ); - $response = JHttpFactory::getHttp($options)->get('https://' . $host . JUri::root(true) . '/', array('Host' => $host), 10); - - // If available in HTTPS check also the status code. - if (!in_array($response->code, array(200, 503, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 401), true)) - { - throw new RuntimeException(JText::_('COM_CONFIG_ERROR_SSL_NOT_AVAILABLE_HTTP_CODE')); - } - } - catch (RuntimeException $e) - { - $data['force_ssl'] = 0; - - // Also update the user state - $app->setUserState('com_config.config.global.data.force_ssl', 0); - - // Inform the user - $app->enqueueMessage(JText::sprintf('COM_CONFIG_ERROR_SSL_NOT_AVAILABLE', $e->getMessage()), 'warning'); - } - } - - // Save the rules - if (isset($data['rules'])) - { - $rules = new JAccessRules($data['rules']); - - // Check that we aren't removing our Super User permission - // Need to get groups from database, since they might have changed - $myGroups = JAccess::getGroupsByUser(JFactory::getUser()->get('id')); - $myRules = $rules->getData(); - $hasSuperAdmin = $myRules['core.admin']->allow($myGroups); - - if (!$hasSuperAdmin) - { - $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_REMOVING_SUPER_ADMIN'), 'error'); - - return false; - } - - $asset = JTable::getInstance('asset'); - - if ($asset->loadByName('root.1')) - { - $asset->rules = (string) $rules; - - if (!$asset->check() || !$asset->store()) - { - $app->enqueueMessage($asset->getError(), 'error'); - - return; - } - } - else - { - $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_ROOT_ASSET_NOT_FOUND'), 'error'); - - return false; - } - - unset($data['rules']); - } - - // Save the text filters - if (isset($data['filters'])) - { - $registry = new Registry(array('filters' => $data['filters'])); - - $extension = JTable::getInstance('extension'); - - // Get extension_id - $extensionId = $extension->find(array('name' => 'com_config')); - - if ($extension->load((int) $extensionId)) - { - $extension->params = (string) $registry; - - if (!$extension->check() || !$extension->store()) - { - $app->enqueueMessage($extension->getError(), 'error'); - - return; - } - } - else - { - $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_CONFIG_EXTENSION_NOT_FOUND'), 'error'); - - return false; - } - - unset($data['filters']); - } - - // Get the previous configuration. - $prev = new JConfig; - $prev = ArrayHelper::fromObject($prev); - - // Merge the new data in. We do this to preserve values that were not in the form. - $data = array_merge($prev, $data); - - /* - * Perform miscellaneous options based on configuration settings/changes. - */ - - // Escape the offline message if present. - if (isset($data['offline_message'])) - { - $data['offline_message'] = JFilterOutput::ampReplace($data['offline_message']); - } - - // Purge the database session table if we are changing to the database handler. - if ($prev['session_handler'] != 'database' && $data['session_handler'] == 'database') - { - $table = JTable::getInstance('session'); - $table->purge(-1); - } - - // Set the shared session configuration - if (isset($data['shared_session'])) - { - $currentShared = isset($prev['shared_session']) ? $prev['shared_session'] : '0'; - - // Has the user enabled shared sessions? - if ($data['shared_session'] == 1 && $currentShared == 0) - { - // Generate a random shared session name - $data['session_name'] = JUserHelper::genRandomPassword(16); - } - - // Has the user disabled shared sessions? - if ($data['shared_session'] == 0 && $currentShared == 1) - { - // Remove the session name value - unset($data['session_name']); - } - } - - if (empty($data['cache_handler'])) - { - $data['caching'] = 0; - } - - /* - * Look for a custom cache_path - * First check if a path is given in the submitted data, then check if a path exists in the previous data, otherwise use the default - */ - if (!empty($data['cache_path'])) - { - $path = $data['cache_path']; - } - elseif (!empty($prev['cache_path'])) - { - $path = $prev['cache_path']; - } - else - { - $path = JPATH_SITE . '/cache'; - } - - // Give a warning if the cache-folder can not be opened - if ($data['caching'] > 0 && $data['cache_handler'] == 'file' && @opendir($path) == false) - { - $error = true; - - // If a custom path is in use, try using the system default instead of disabling cache - if ($path !== JPATH_SITE . '/cache' && @opendir(JPATH_SITE . '/cache') != false) - { - try - { - JLog::add( - JText::sprintf('COM_CONFIG_ERROR_CUSTOM_CACHE_PATH_NOTWRITABLE_USING_DEFAULT', $path, JPATH_SITE . '/cache'), - JLog::WARNING, - 'jerror' - ); - } - catch (RuntimeException $logException) - { - $app->enqueueMessage( - JText::sprintf('COM_CONFIG_ERROR_CUSTOM_CACHE_PATH_NOTWRITABLE_USING_DEFAULT', $path, JPATH_SITE . '/cache'), - 'warning' - ); - } - - $path = JPATH_SITE . '/cache'; - $error = false; - - $data['cache_path'] = ''; - } - - if ($error) - { - try - { - JLog::add(JText::sprintf('COM_CONFIG_ERROR_CACHE_PATH_NOTWRITABLE', $path), JLog::WARNING, 'jerror'); - } - catch (RuntimeException $exception) - { - $app->enqueueMessage(JText::sprintf('COM_CONFIG_ERROR_CACHE_PATH_NOTWRITABLE', $path), 'warning'); - } - - $data['caching'] = 0; - } - } - - // Did the user remove their custom cache path? Don't save the variable to the config - if (empty($data['cache_path'])) - { - unset($data['cache_path']); - } - - // Clean the cache if disabled but previously enabled or changing cache handlers; these operations use the `$prev` data already in memory - if ((!$data['caching'] && $prev['caching']) || $data['cache_handler'] !== $prev['cache_handler']) - { - try - { - JFactory::getCache()->clean(); - } - catch (JCacheExceptionConnecting $exception) - { - try - { - JLog::add(JText::_('COM_CONFIG_ERROR_CACHE_CONNECTION_FAILED'), JLog::WARNING, 'jerror'); - } - catch (RuntimeException $logException) - { - $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_CACHE_CONNECTION_FAILED'), 'warning'); - } - } - catch (JCacheExceptionUnsupported $exception) - { - try - { - JLog::add(JText::_('COM_CONFIG_ERROR_CACHE_DRIVER_UNSUPPORTED'), JLog::WARNING, 'jerror'); - } - catch (RuntimeException $logException) - { - $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_CACHE_DRIVER_UNSUPPORTED'), 'warning'); - } - } - } - - // Create the new configuration object. - $config = new Registry($data); - - // Overwrite the old FTP credentials with the new ones. - $temp = JFactory::getConfig(); - $temp->set('ftp_enable', $data['ftp_enable']); - $temp->set('ftp_host', $data['ftp_host']); - $temp->set('ftp_port', $data['ftp_port']); - $temp->set('ftp_user', $data['ftp_user']); - $temp->set('ftp_pass', $data['ftp_pass']); - $temp->set('ftp_root', $data['ftp_root']); - - // Clear cache of com_config component. - $this->cleanCache('_system', 0); - $this->cleanCache('_system', 1); - - // Write the configuration file. - return $this->writeConfigFile($config); - } - - /** - * Method to unset the root_user value from configuration data. - * - * This method will load the global configuration data straight from - * JConfig and remove the root_user value for security, then save the configuration. - * - * @return boolean True on success, false on failure. - * - * @since 1.6 - */ - public function removeroot() - { - // Get the previous configuration. - $prev = new JConfig; - $prev = ArrayHelper::fromObject($prev); - - // Create the new configuration object, and unset the root_user property - unset($prev['root_user']); - $config = new Registry($prev); - - // Write the configuration file. - return $this->writeConfigFile($config); - } - - /** - * Method to write the configuration to a file. - * - * @param Registry $config A Registry object containing all global config data. - * - * @return boolean True on success, false on failure. - * - * @since 2.5.4 - * @throws RuntimeException - */ - private function writeConfigFile(Registry $config) - { - 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); - - $app = JFactory::getApplication(); - - // Attempt to make the file writeable if using FTP. - if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0644')) - { - $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE'), 'notice'); - } - - // Attempt to write the configuration file as a PHP class named JConfig. - $configuration = $config->toString('PHP', array('class' => 'JConfig', 'closingtag' => false)); - - if (!JFile::write($file, $configuration)) - { - throw new RuntimeException(JText::_('COM_CONFIG_ERROR_WRITE_FAILED')); - } - - // Attempt to make the file unwriteable if using FTP. - if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0444')) - { - $app->enqueueMessage(JText::_('COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE'), 'notice'); - } - - return true; - } - - /** - * Method to store the permission values in the asset table. - * - * This method will get an array with permission key value pairs and transform it - * into json and update the asset table in the database. - * - * @param string $permission Need an array with Permissions (component, rule, value and title) - * - * @return array A list of result data. - * - * @since 3.5 - */ - public function storePermissions($permission = null) - { - $app = JFactory::getApplication(); - $user = JFactory::getUser(); - - if (is_null($permission)) - { - // Get data from input. - $permission = array( - 'component' => $app->input->get('comp'), - 'action' => $app->input->get('action'), - 'rule' => $app->input->get('rule'), - 'value' => $app->input->get('value'), - 'title' => $app->input->get('title', '', 'RAW') - ); - } - - // We are creating a new item so we don't have an item id so don't allow. - if (substr($permission['component'], -6) === '.false') - { - $app->enqueueMessage(JText::_('JLIB_RULES_SAVE_BEFORE_CHANGE_PERMISSIONS'), 'error'); - - return false; - } - - // Check if the user is authorized to do this. - if (!$user->authorise('core.admin', $permission['component'])) - { - $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); - - return false; - } - - $permission['component'] = empty($permission['component']) ? 'root.1' : $permission['component']; - - // Current view is global config? - $isGlobalConfig = $permission['component'] === 'root.1'; - - // Check if changed group has Super User permissions. - $isSuperUserGroupBefore = JAccess::checkGroup($permission['rule'], 'core.admin'); - - // Check if current user belongs to changed group. - $currentUserBelongsToGroup = in_array((int) $permission['rule'], $user->groups) ? true : false; - - // Get current user groups tree. - $currentUserGroupsTree = JAccess::getGroupsByUser($user->id, true); - - // Check if current user belongs to changed group. - $currentUserSuperUser = $user->authorise('core.admin'); - - // If user is not Super User cannot change the permissions of a group it belongs to. - if (!$currentUserSuperUser && $currentUserBelongsToGroup) - { - $app->enqueueMessage(JText::_('JLIB_USER_ERROR_CANNOT_CHANGE_OWN_GROUPS'), 'error'); - - return false; - } - - // If user is not Super User cannot change the permissions of a group it belongs to. - if (!$currentUserSuperUser && in_array((int) $permission['rule'], $currentUserGroupsTree)) - { - $app->enqueueMessage(JText::_('JLIB_USER_ERROR_CANNOT_CHANGE_OWN_PARENT_GROUPS'), 'error'); - - return false; - } - - // If user is not Super User cannot change the permissions of a Super User Group. - if (!$currentUserSuperUser && $isSuperUserGroupBefore && !$currentUserBelongsToGroup) - { - $app->enqueueMessage(JText::_('JLIB_USER_ERROR_CANNOT_CHANGE_SUPER_USER'), 'error'); - - return false; - } - - // If user is not Super User cannot change the Super User permissions in any group it belongs to. - if ($isSuperUserGroupBefore && $currentUserBelongsToGroup && $permission['action'] === 'core.admin') - { - $app->enqueueMessage(JText::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF'), 'error'); - - return false; - } - - try - { - $asset = JTable::getInstance('asset'); - $result = $asset->loadByName($permission['component']); - - if ($result === false) - { - $data = array($permission['action'] => array($permission['rule'] => $permission['value'])); - - $rules = new JAccessRules($data); - $asset->rules = (string) $rules; - $asset->name = (string) $permission['component']; - $asset->title = (string) $permission['title']; - - // Get the parent asset id so we have a correct tree. - $parentAsset = JTable::getInstance('Asset'); - - if (strpos($asset->name, '.') !== false) - { - $assetParts = explode('.', $asset->name); - $parentAsset->loadByName($assetParts[0]); - $parentAssetId = $parentAsset->id; - } - else - { - $parentAssetId = $parentAsset->getRootId(); - } - - /** - * @to do: incorrect ACL stored - * When changing a permission of an item that doesn't have a row in the asset table the row a new row is created. - * This works fine for item <-> component <-> global config scenario and component <-> global config scenario. - * But doesn't work properly for item <-> section(s) <-> component <-> global config scenario, - * because a wrong parent asset id (the component) is stored. - * Happens when there is no row in the asset table (ex: deleted or not created on update). - */ - - $asset->setLocation($parentAssetId, 'last-child'); - } - else - { - // Decode the rule settings. - $temp = json_decode($asset->rules, true); - - // Check if a new value is to be set. - if (isset($permission['value'])) - { - // Check if we already have an action entry. - if (!isset($temp[$permission['action']])) - { - $temp[$permission['action']] = array(); - } - - // Check if we already have a rule entry. - if (!isset($temp[$permission['action']][$permission['rule']])) - { - $temp[$permission['action']][$permission['rule']] = array(); - } - - // Set the new permission. - $temp[$permission['action']][$permission['rule']] = (int) $permission['value']; - - // Check if we have an inherited setting. - if ($permission['value'] === '') - { - unset($temp[$permission['action']][$permission['rule']]); - } - - // Check if we have any rules. - if (!$temp[$permission['action']]) - { - unset($temp[$permission['action']]); - } - } - else - { - // There is no value so remove the action as it's not needed. - unset($temp[$permission['action']]); - } - - $asset->rules = json_encode($temp, JSON_FORCE_OBJECT); - } - - if (!$asset->check() || !$asset->store()) - { - $app->enqueueMessage(JText::_('JLIB_UNKNOWN'), 'error'); - - return false; - } - } - catch (Exception $e) - { - $app->enqueueMessage($e->getMessage(), 'error'); - - return false; - } - - // All checks done. - $result = array( - 'text' => '', - 'class' => '', - 'result' => true, - ); - - // Show the current effective calculated permission considering current group, path and cascade. - - try - { - // Get the asset id by the name of the component. - $query = $this->db->getQuery(true) - ->select($this->db->quoteName('id')) - ->from($this->db->quoteName('#__assets')) - ->where($this->db->quoteName('name') . ' = ' . $this->db->quote($permission['component'])); - - $this->db->setQuery($query); - - $assetId = (int) $this->db->loadResult(); - - // Fetch the parent asset id. - $parentAssetId = null; - - /** - * @to do: incorrect info - * When creating a new item (not saving) it uses the calculated permissions from the component (item <-> component <-> global config). - * But if we have a section too (item <-> section(s) <-> component <-> global config) this is not correct. - * Also, currently it uses the component permission, but should use the calculated permissions for achild of the component/section. - */ - - // If not in global config we need the parent_id asset to calculate permissions. - if (!$isGlobalConfig) - { - // In this case we need to get the component rules too. - $query->clear() - ->select($this->db->quoteName('parent_id')) - ->from($this->db->quoteName('#__assets')) - ->where($this->db->quoteName('id') . ' = ' . $assetId); - - $this->db->setQuery($query); - - $parentAssetId = (int) $this->db->loadResult(); - } - - // Get the group parent id of the current group. - $query->clear() - ->select($this->db->quoteName('parent_id')) - ->from($this->db->quoteName('#__usergroups')) - ->where($this->db->quoteName('id') . ' = ' . (int) $permission['rule']); - - $this->db->setQuery($query); - - $parentGroupId = (int) $this->db->loadResult(); - - // Count the number of child groups of the current group. - $query->clear() - ->select('COUNT(' . $this->db->quoteName('id') . ')') - ->from($this->db->quoteName('#__usergroups')) - ->where($this->db->quoteName('parent_id') . ' = ' . (int) $permission['rule']); - - $this->db->setQuery($query); - - $totalChildGroups = (int) $this->db->loadResult(); - } - catch (Exception $e) - { - $app->enqueueMessage($e->getMessage(), 'error'); - - return false; - } - - // Clear access statistics. - JAccess::clearStatics(); - - // After current group permission is changed we need to check again if the group has Super User permissions. - $isSuperUserGroupAfter = JAccess::checkGroup($permission['rule'], 'core.admin'); - - // Get the rule for just this asset (non-recursive) and get the actual setting for the action for this group. - $assetRule = JAccess::getAssetRules($assetId, false, false)->allow($permission['action'], $permission['rule']); - - // Get the group, group parent id, and group global config recursive calculated permission for the chosen action. - $inheritedGroupRule = JAccess::checkGroup($permission['rule'], $permission['action'], $assetId); - - if (!empty($parentAssetId)) - { - $inheritedGroupParentAssetRule = JAccess::checkGroup($permission['rule'], $permission['action'], $parentAssetId); - } - else - { - $inheritedGroupParentAssetRule = null; - } - - $inheritedParentGroupRule = !empty($parentGroupId) ? JAccess::checkGroup($parentGroupId, $permission['action'], $assetId) : null; - - // Current group is a Super User group, so calculated setting is "Allowed (Super User)". - if ($isSuperUserGroupAfter) - { - $result['class'] = 'label label-success'; - $result['text'] = '' . JText::_('JLIB_RULES_ALLOWED_ADMIN'); - } - // Not super user. - else - { - // First get the real recursive calculated setting and add (Inherited) to it. - - // If recursive calculated setting is "Denied" or null. Calculated permission is "Not Allowed (Inherited)". - if ($inheritedGroupRule === null || $inheritedGroupRule === false) - { - $result['class'] = 'label label-important'; - $result['text'] = JText::_('JLIB_RULES_NOT_ALLOWED_INHERITED'); - } - // If recursive calculated setting is "Allowed". Calculated permission is "Allowed (Inherited)". - else - { - $result['class'] = 'label label-success'; - $result['text'] = JText::_('JLIB_RULES_ALLOWED_INHERITED'); - } - - // Second part: Overwrite the calculated permissions labels if there is an explicity permission in the current group. - - /** - * @to do: incorect 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 ($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". - elseif ($assetRule === true) - { - $result['class'] = 'label label-success'; - $result['text'] = JText::_('JLIB_RULES_ALLOWED'); - } - - // Third part: Overwrite the calculated permissions labels for special cases. - - // Global configuration with "Not Set" permission. Calculated permission is "Not Allowed (Default)". - if (empty($parentGroupId) && $isGlobalConfig === true && $assetRule === null) - { - $result['class'] = 'label label-important'; - $result['text'] = JText::_('JLIB_RULES_NOT_ALLOWED_DEFAULT'); - } - - /** - * Component/Item with explicit "Denied" permission at parent Asset (Category, Component or Global config) configuration. - * Or some parent group has an explicit "Denied". - * Calculated permission is "Not Allowed (Locked)". - */ - elseif ($inheritedGroupParentAssetRule === false || $inheritedParentGroupRule === false) - { - $result['class'] = 'label label-important'; - $result['text'] = '' . JText::_('JLIB_RULES_NOT_ALLOWED_LOCKED'); - } - } - - // If removed or added super user from group, we need to refresh the page to recalculate all settings. - if ($isSuperUserGroupBefore != $isSuperUserGroupAfter) - { - $app->enqueueMessage(JText::_('JLIB_RULES_NOTICE_RECALCULATE_GROUP_PERMISSIONS'), 'notice'); - } - - // If this group has child groups, we need to refresh the page to recalculate the child settings. - if ($totalChildGroups > 0) - { - $app->enqueueMessage(JText::_('JLIB_RULES_NOTICE_RECALCULATE_GROUP_CHILDS_PERMISSIONS'), 'notice'); - } - - return $result; - } - - /** - * Method to send a test mail which is called via an AJAX request - * - * @return boolean - * - * @since 3.5 - * @throws Exception - */ - public function sendTestMail() - { - // Set the new values to test with the current settings - $app = JFactory::getApplication(); - $input = $app->input; - - $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')); - $app->set('mailfrom', $input->get('mailfrom', '', 'STRING')); - $app->set('fromname', $input->get('fromname', '', 'STRING')); - $app->set('mailer', $input->get('mailer')); - $app->set('mailonline', $input->get('mailonline')); - - $mail = JFactory::getMailer(); - - // Prepare email and send try to send it - $mailSubject = JText::sprintf('COM_CONFIG_SENDMAIL_SUBJECT', $app->get('sitename')); - $mailBody = JText::sprintf('COM_CONFIG_SENDMAIL_BODY', JText::_('COM_CONFIG_SENDMAIL_METHOD_' . strtoupper($mail->Mailer))); - - if ($mail->sendMail($app->get('mailfrom'), $app->get('fromname'), $app->get('mailfrom'), $mailSubject, $mailBody) === true) - { - $methodName = JText::_('COM_CONFIG_SENDMAIL_METHOD_' . strtoupper($mail->Mailer)); - - // If JMail send the mail using PHP Mail as fallback. - if ($mail->Mailer != $app->get('mailer')) - { - $app->enqueueMessage(JText::sprintf('COM_CONFIG_SENDMAIL_SUCCESS_FALLBACK', $app->get('mailfrom'), $methodName), 'warning'); - } - else - { - $app->enqueueMessage(JText::sprintf('COM_CONFIG_SENDMAIL_SUCCESS', $app->get('mailfrom'), $methodName), 'message'); - } - - return true; - } - - $app->enqueueMessage(JText::_('COM_CONFIG_SENDMAIL_ERROR'), 'error'); - - return false; - } -} diff --git a/administrator/components/com_config/model/component.php b/administrator/components/com_config/model/component.php deleted file mode 100644 index e6db1e48eedea..0000000000000 --- a/administrator/components/com_config/model/component.php +++ /dev/null @@ -1,217 +0,0 @@ -input; - - // Set the component (option) we are dealing with. - $component = $input->get('component'); - $state = $this->loadState(); - $state->set('component.option', $component); - - // Set an alternative path for the configuration file. - if ($path = $input->getString('path')) - { - $path = JPath::clean(JPATH_SITE . '/' . $path); - JPath::check($path); - $state->set('component.path', $path); - } - - $this->setState($state); - } - - /** - * Method to get a form object. - * - * @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 mixed A JForm object on success, false on failure - * - * @since 3.2 - */ - public function getForm($data = array(), $loadData = true) - { - $state = $this->getState(); - $option = $state->get('component.option'); - - if ($path = $state->get('component.path')) - { - // Add the search path for the admin component config.xml file. - JForm::addFormPath($path); - } - else - { - // Add the search path for the admin component config.xml file. - JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/' . $option); - } - - // Get the form. - $form = $this->loadForm( - 'com_config.component', - 'config', - array('control' => 'jform', 'load_data' => $loadData), - false, - '/config' - ); - - if (empty($form)) - { - return false; - } - - $lang = JFactory::getLanguage(); - $lang->load($option, JPATH_BASE, null, false, true) - || $lang->load($option, JPATH_BASE . "/components/$option", null, false, true); - - return $form; - } - - /** - * Get the component information. - * - * @return object - * - * @since 3.2 - */ - public function getComponent() - { - $state = $this->getState(); - $option = $state->get('component.option'); - - // Load common and local language files. - $lang = JFactory::getLanguage(); - $lang->load($option, JPATH_BASE, null, false, true) - || $lang->load($option, JPATH_BASE . "/components/$option", null, false, true); - - $result = JComponentHelper::getComponent($option); - - return $result; - } - - /** - * Method to save the configuration data. - * - * @param array $data An array containing all global config data. - * - * @return boolean True on success, false on failure. - * - * @since 3.2 - * @throws RuntimeException - */ - public function save($data) - { - $table = JTable::getInstance('extension'); - $dispatcher = JEventDispatcher::getInstance(); - $context = $this->option . '.' . $this->name; - JPluginHelper::importPlugin('extension'); - - // Check super user group. - if (isset($data['params']) && !JFactory::getUser()->authorise('core.admin')) - { - $form = $this->getForm(array(), false); - - foreach ($form->getFieldsets() as $fieldset) - { - foreach ($form->getFieldset($fieldset->name) as $field) - { - if ($field->type === 'UserGroupList' && isset($data['params'][$field->fieldname]) - && (int) $field->getAttribute('checksuperusergroup', 0) === 1 - && JAccess::checkGroup($data['params'][$field->fieldname], 'core.admin')) - { - throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); - } - } - } - } - - // Save the rules. - if (isset($data['params']) && isset($data['params']['rules'])) - { - $rules = new JAccessRules($data['params']['rules']); - $asset = JTable::getInstance('asset'); - - if (!$asset->loadByName($data['option'])) - { - $root = JTable::getInstance('asset'); - $root->loadByName('root.1'); - $asset->name = $data['option']; - $asset->title = $data['option']; - $asset->setLocation($root->id, 'last-child'); - } - - $asset->rules = (string) $rules; - - if (!$asset->check() || !$asset->store()) - { - throw new RuntimeException($asset->getError()); - } - - // We don't need this anymore - unset($data['option']); - unset($data['params']['rules']); - } - - // Load the previous Data - if (!$table->load($data['id'])) - { - throw new RuntimeException($table->getError()); - } - - unset($data['id']); - - // Bind the data. - if (!$table->bind($data)) - { - throw new RuntimeException($table->getError()); - } - - // Check the data. - if (!$table->check()) - { - throw new RuntimeException($table->getError()); - } - - $result = $dispatcher->trigger('onExtensionBeforeSave', array($context, $table, false)); - - // Store the data. - if (in_array(false, $result, true) || !$table->store()) - { - throw new RuntimeException($table->getError()); - } - - // Trigger the after save event. - $dispatcher->trigger('onExtensionAfterSave', array($context, $table, false)); - - // Clean the component cache. - $this->cleanCache('_system', 0); - $this->cleanCache('_system', 1); - - return true; - } -} diff --git a/administrator/components/com_config/model/field/configcomponents.php b/administrator/components/com_config/model/field/configcomponents.php deleted file mode 100644 index 550c66524f159..0000000000000 --- a/administrator/components/com_config/model/field/configcomponents.php +++ /dev/null @@ -1,82 +0,0 @@ -getQuery(true) - ->select('name AS text, element AS value') - ->from('#__extensions') - ->where('enabled >= 1') - ->where('type =' . $db->quote('component')); - - $items = $db->setQuery($query)->loadObjectList(); - - if ($items) - { - $lang = JFactory::getLanguage(); - - foreach ($items as &$item) - { - // Load language - $extension = $item->value; - - if (JFile::exists(JPATH_ADMINISTRATOR . '/components/' . $extension . '/config.xml')) - { - $source = JPATH_ADMINISTRATOR . '/components/' . $extension; - $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) - || $lang->load("$extension.sys", $source, null, false, true); - - // Translate component name - $item->text = JText::_($item->text); - } - else - { - $item = null; - } - } - - // Sort by component name - $items = ArrayHelper::sortObjects(array_filter($items), 'text', 1, true, true); - } - - // Merge any additional options in the XML definition. - $options = array_merge(parent::getOptions(), $items); - - return $options; - } -} diff --git a/administrator/components/com_config/model/field/filters.php b/administrator/components/com_config/model/field/filters.php deleted file mode 100644 index 204f59ad59747..0000000000000 --- a/administrator/components/com_config/model/field/filters.php +++ /dev/null @@ -1,160 +0,0 @@ -getUserGroups(); - - // Build the form control. - $html = array(); - - // Open the table. - $html[] = ''; - - // The table heading. - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - - // The table body. - $html[] = ' '; - - foreach ($groups as $group) - { - if (!isset($this->value[$group->value])) - { - $this->value[$group->value] = array('filter_type' => 'BL', 'filter_tags' => '', 'filter_attributes' => ''); - } - - $group_filter = $this->value[$group->value]; - - $group_filter['filter_tags'] = !empty($group_filter['filter_tags']) ? $group_filter['filter_tags'] : ''; - $group_filter['filter_attributes'] = !empty($group_filter['filter_attributes']) ? $group_filter['filter_attributes'] : ''; - - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - } - - $html[] = ' '; - - // Close the table. - $html[] = '
'; - $html[] = ' ' . JText::_('JGLOBAL_FILTER_GROUPS_LABEL') . ''; - $html[] = ' '; - $html[] = ' ' . JText::_('JGLOBAL_FILTER_TYPE_LABEL') . ''; - $html[] = ' '; - $html[] = ' ' . JText::_('JGLOBAL_FILTER_TAGS_LABEL') . ''; - $html[] = ' '; - $html[] = ' ' . JText::_('JGLOBAL_FILTER_ATTRIBUTES_LABEL') . ''; - $html[] = '
'; - $html[] = ' ' . JLayoutHelper::render('joomla.html.treeprefix', array('level' => $group->level + 1)) . $group->text; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = ' '; - $html[] = '
'; - - // Add notes - $html[] = '
'; - $html[] = '

' . JText::_('JGLOBAL_FILTER_TYPE_DESC') . '

'; - $html[] = '

' . JText::_('JGLOBAL_FILTER_TAGS_DESC') . '

'; - $html[] = '

' . JText::_('JGLOBAL_FILTER_ATTRIBUTES_DESC') . '

'; - $html[] = '
'; - - return implode("\n", $html); - } - - /** - * A helper to get the list of user groups. - * - * @return array - * - * @since 1.6 - */ - protected function getUserGroups() - { - // Get a database object. - $db = JFactory::getDbo(); - - // Get the user groups from the database. - $query = $db->getQuery(true); - $query->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level'); - $query->from('#__usergroups AS a'); - $query->join('LEFT', '#__usergroups AS b on a.lft > b.lft AND a.rgt < b.rgt'); - $query->group('a.id, a.title, a.lft'); - $query->order('a.lft ASC'); - $db->setQuery($query); - $options = $db->loadObjectList(); - - return $options; - } -} diff --git a/administrator/components/com_config/model/form/application.xml b/administrator/components/com_config/model/form/application.xml deleted file mode 100644 index 1dc1bc51543bb..0000000000000 --- a/administrator/components/com_config/model/form/application.xml +++ /dev/null @@ -1,1315 +0,0 @@ - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
- -
- - - - - - - - - - - -
- -
- - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - -
- -
- - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - -
- -
- - - - - -
- -
- - - - - - - - - - - - - - - - -
- -
- - - -
- -
- - - -
-
diff --git a/administrator/components/com_config/models/application.php b/administrator/components/com_config/models/application.php deleted file mode 100644 index 9263cf9bb6c5f..0000000000000 --- a/administrator/components/com_config/models/application.php +++ /dev/null @@ -1,25 +0,0 @@ -registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Config')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Config')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_config/tmpl/application/default.php b/administrator/components/com_config/tmpl/application/default.php new file mode 100644 index 0000000000000..843cca5957ceb --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default.php @@ -0,0 +1,124 @@ + + +
+
+ + + + +
+ +
+
+
+
+ loadTemplate('site'); ?> + loadTemplate('metadata'); ?> +
+
+ loadTemplate('seo'); ?> + loadTemplate('cookie'); ?> +
+
+
+
+
+
+ loadTemplate('system'); ?> + loadTemplate('debug'); ?> + loadTemplate('cache'); ?> + loadTemplate('session'); ?> +
+
+
+
+
+
+ loadTemplate('server'); ?> + loadTemplate('locale'); ?> + loadTemplate('ftp'); ?> + loadTemplate('proxy'); ?> +
+
+ loadTemplate('database'); ?> + loadTemplate('mail'); ?> +
+
+
+
+
+
+ loadTemplate('filters'); ?> +
+
+
+ ftp) : ?> +
+
+ loadTemplate('ftplogin'); ?> +
+
+ +
+
+ loadTemplate('permissions'); ?> +
+
+ + +
+
+ +
+
diff --git a/administrator/components/com_config/view/application/tmpl/default.xml b/administrator/components/com_config/tmpl/application/default.xml similarity index 100% rename from administrator/components/com_config/view/application/tmpl/default.xml rename to administrator/components/com_config/tmpl/application/default.xml diff --git a/administrator/components/com_config/tmpl/application/default_cache.php b/administrator/components/com_config/tmpl/application/default_cache.php new file mode 100644 index 0000000000000..fc10cfaa8d53f --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_cache.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_CACHE_SETTINGS'); +$this->fieldsname = 'cache'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_cookie.php b/administrator/components/com_config/tmpl/application/default_cookie.php new file mode 100644 index 0000000000000..a9156b33aec1c --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_cookie.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_COOKIE_SETTINGS'); +$this->fieldsname = 'cookie'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_database.php b/administrator/components/com_config/tmpl/application/default_database.php new file mode 100644 index 0000000000000..f575c2d7c93f0 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_database.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_DATABASE_SETTINGS'); +$this->fieldsname = 'database'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_debug.php b/administrator/components/com_config/tmpl/application/default_debug.php new file mode 100644 index 0000000000000..30af343bd7217 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_debug.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_DEBUG_SETTINGS'); +$this->fieldsname = 'debug'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_filters.php b/administrator/components/com_config/tmpl/application/default_filters.php new file mode 100644 index 0000000000000..513d5bd069b53 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_filters.php @@ -0,0 +1,18 @@ +name = Text::_('COM_CONFIG_TEXT_FILTER_SETTINGS'); +$this->fieldsname = 'filters'; +$this->description = Text::_('COM_CONFIG_TEXT_FILTERS_DESC'); +echo LayoutHelper::render('joomla.content.text_filters', $this); diff --git a/administrator/components/com_config/tmpl/application/default_ftp.php b/administrator/components/com_config/tmpl/application/default_ftp.php new file mode 100644 index 0000000000000..e9e68d20b61c4 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_ftp.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_FTP_SETTINGS'); +$this->fieldsname = 'ftp'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_ftplogin.php b/administrator/components/com_config/tmpl/application/default_ftplogin.php new file mode 100644 index 0000000000000..551698f68d926 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_ftplogin.php @@ -0,0 +1,37 @@ + +
+ + + ftp instanceof Exception) : ?> + +

ftp->message); ?>

+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
diff --git a/administrator/components/com_config/tmpl/application/default_locale.php b/administrator/components/com_config/tmpl/application/default_locale.php new file mode 100644 index 0000000000000..add6dfe5f8826 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_locale.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_LOCATION_SETTINGS'); +$this->fieldsname = 'locale'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_mail.php b/administrator/components/com_config/tmpl/application/default_mail.php new file mode 100644 index 0000000000000..cd0cf1fc3832c --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_mail.php @@ -0,0 +1,47 @@ + 'auto', 'relative' => true]); + +// Load JavaScript message titles +Text::script('ERROR'); +Text::script('WARNING'); +Text::script('NOTICE'); +Text::script('MESSAGE'); + +// Add strings for JavaScript error translations. +Text::script('JLIB_JS_AJAX_ERROR_CONNECTION_ABORT'); +Text::script('JLIB_JS_AJAX_ERROR_NO_CONTENT'); +Text::script('JLIB_JS_AJAX_ERROR_OTHER'); +Text::script('JLIB_JS_AJAX_ERROR_PARSE'); +Text::script('JLIB_JS_AJAX_ERROR_TIMEOUT'); + +// Ajax request data. +$ajaxUri = Route::_('index.php?option=com_config&task=application.sendtestmail&format=json&' . Session::getFormToken() . '=1'); + +$this->name = Text::_('COM_CONFIG_MAIL_SETTINGS'); +$this->fieldsname = 'mail'; +?> + + + + + + diff --git a/administrator/components/com_config/tmpl/application/default_metadata.php b/administrator/components/com_config/tmpl/application/default_metadata.php new file mode 100644 index 0000000000000..e10defca9f8f3 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_metadata.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_METADATA_SETTINGS'); +$this->fieldsname = 'metadata'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_navigation.php b/administrator/components/com_config/tmpl/application/default_navigation.php new file mode 100644 index 0000000000000..3365a1960fa83 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_navigation.php @@ -0,0 +1,28 @@ + + diff --git a/administrator/components/com_config/tmpl/application/default_permissions.php b/administrator/components/com_config/tmpl/application/default_permissions.php new file mode 100644 index 0000000000000..43e231b119387 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_permissions.php @@ -0,0 +1,20 @@ +name = Text::_('COM_CONFIG_PERMISSION_SETTINGS'); +$this->description = ''; +$this->fieldsname = 'permissions'; +$this->formclass = 'form-no-margin'; +$this->showlabel = false; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_proxy.php b/administrator/components/com_config/tmpl/application/default_proxy.php new file mode 100644 index 0000000000000..7916a1858259e --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_proxy.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_PROXY_SETTINGS'); +$this->fieldsname = 'proxy'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_seo.php b/administrator/components/com_config/tmpl/application/default_seo.php new file mode 100644 index 0000000000000..9668001f0618e --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_seo.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_SEO_SETTINGS'); +$this->fieldsname = 'seo'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_server.php b/administrator/components/com_config/tmpl/application/default_server.php new file mode 100644 index 0000000000000..cc1a4c3340bf9 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_server.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_SERVER_SETTINGS'); +$this->fieldsname = 'server'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_session.php b/administrator/components/com_config/tmpl/application/default_session.php new file mode 100644 index 0000000000000..7ff9935f50f6c --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_session.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_SESSION_SETTINGS'); +$this->fieldsname = 'session'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_site.php b/administrator/components/com_config/tmpl/application/default_site.php new file mode 100644 index 0000000000000..8b3f4b238e80a --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_site.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_SITE_SETTINGS'); +$this->fieldsname = 'site'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/application/default_system.php b/administrator/components/com_config/tmpl/application/default_system.php new file mode 100644 index 0000000000000..65e1c23d9d0d5 --- /dev/null +++ b/administrator/components/com_config/tmpl/application/default_system.php @@ -0,0 +1,17 @@ +name = Text::_('COM_CONFIG_SYSTEM_SETTINGS'); +$this->fieldsname = 'system'; +echo LayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/tmpl/component/default.php b/administrator/components/com_config/tmpl/component/default.php new file mode 100644 index 0000000000000..a5acee9f224d3 --- /dev/null +++ b/administrator/components/com_config/tmpl/component/default.php @@ -0,0 +1,109 @@ +getTemplate(); + +Text::script('ERROR'); +Text::script('WARNING'); +Text::script('NOTICE'); +Text::script('MESSAGE'); + +// Load the tooltip behavior. +HTMLHelper::_('behavior.formvalidator'); +HTMLHelper::_('behavior.keepalive'); +HTMLHelper::_('behavior.tabstate'); +HTMLHelper::_('formbehavior.chosen', '.chzn-custom-value', null, array('disable_search_threshold' => 0)); + +// @TODO delete this when custom elements modal is merged +HTMLHelper::_('script', 'com_config/admin-application-default.min.js', ['relative' => true, 'version' => 'auto']); +?> + +
+
+ + + + + +
+ + fieldsets): ?> + + +
+ fieldsets as $name => $fieldSet) : ?> +
+ description) && !empty($fieldSet->description)) : ?> + + description); ?> + + + form->getFieldset($name) as $field) : ?> + type === 'Spacer' ? ' field-spacer' : ''; + ?> + showon) : ?> + 'auto', 'relative' => true)); ?> + showon, $field->formControl, $field->group)) . '\''; ?> + + hidden) : ?> + input; ?> + +
> + +
+ label; ?> +
+ +
+ input; ?> +
+
+ + +
+ +
+ + + + +
+ + + + + + +
+
diff --git a/administrator/components/com_config/tmpl/component/default.xml b/administrator/components/com_config/tmpl/component/default.xml new file mode 100755 index 0000000000000..744fad2eeea6c --- /dev/null +++ b/administrator/components/com_config/tmpl/component/default.xml @@ -0,0 +1,18 @@ + + + + + + + + +
+ +
+
+
diff --git a/administrator/components/com_config/tmpl/component/default_navigation.php b/administrator/components/com_config/tmpl/component/default_navigation.php new file mode 100644 index 0000000000000..b4b884ddc8755 --- /dev/null +++ b/administrator/components/com_config/tmpl/component/default_navigation.php @@ -0,0 +1,33 @@ + + diff --git a/administrator/components/com_config/view/application/html.php b/administrator/components/com_config/view/application/html.php deleted file mode 100644 index 39957c6dcdb8e..0000000000000 --- a/administrator/components/com_config/view/application/html.php +++ /dev/null @@ -1,99 +0,0 @@ -model->getForm(); - $data = $this->model->getData(); - $user = JFactory::getUser(); - } - catch (Exception $e) - { - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); - - return false; - } - - // Bind data - if ($form && $data) - { - $form->bind($data); - } - - // Get the params for com_users. - $usersParams = JComponentHelper::getParams('com_users'); - - // Get the params for com_media. - $mediaParams = JComponentHelper::getParams('com_media'); - - // Load settings for the FTP layer. - $ftp = JClientHelper::setCredentialsFromRequest('ftp'); - - $this->form = &$form; - $this->data = &$data; - $this->ftp = &$ftp; - $this->usersParams = &$usersParams; - $this->mediaParams = &$mediaParams; - - $this->components = ConfigHelperConfig::getComponentsWithConfig(); - ConfigHelperConfig::loadLanguageForComponents($this->components); - - $this->userIsSuperAdmin = $user->authorise('core.admin'); - - $this->addToolbar(); - - return parent::render(); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 3.2 - */ - protected function addToolbar() - { - JToolbarHelper::title(JText::_('COM_CONFIG_GLOBAL_CONFIGURATION'), 'equalizer config'); - JToolbarHelper::apply('config.save.application.apply'); - JToolbarHelper::save('config.save.application.save'); - JToolbarHelper::divider(); - JToolbarHelper::cancel('config.cancel.application'); - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_SITE_GLOBAL_CONFIGURATION'); - } -} diff --git a/administrator/components/com_config/view/application/json.php b/administrator/components/com_config/view/application/json.php deleted file mode 100644 index cb814c0bb1b6f..0000000000000 --- a/administrator/components/com_config/view/application/json.php +++ /dev/null @@ -1,68 +0,0 @@ -data = $this->model->getData(); - $user = JFactory::getUser(); - } - catch (Exception $e) - { - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); - - return false; - } - - $this->userIsSuperAdmin = $user->authorise('core.admin'); - - // Required data - $requiredData = array( - 'sitename' => null, - 'offline' => null, - 'access' => null, - 'list_limit' => null, - 'MetaDesc' => null, - 'MetaKeys' => null, - 'MetaRights' => null, - 'sef' => null, - 'sitename_pagetitles' => null, - 'debug' => null, - 'debug_lang' => null, - 'error_reporting' => null, - 'mailfrom' => null, - 'fromname' => null - ); - - $this->data = array_intersect_key($this->data, $requiredData); - - return json_encode($this->data); - } -} diff --git a/administrator/components/com_config/view/application/tmpl/default.php b/administrator/components/com_config/view/application/tmpl/default.php deleted file mode 100644 index 0d1829869fa1a..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default.php +++ /dev/null @@ -1,127 +0,0 @@ -addScriptDeclaration(' - Joomla.submitbutton = function(task) - { - if (task === "config.cancel.application" || document.formvalidator.isValid(document.getElementById("application-form"))) - { - jQuery("#permissions-sliders select").attr("disabled", "disabled"); - Joomla.submitform(task, document.getElementById("application-form")); - } - }; -'); -?> - -
-
- - - - -
- -
-
-
-
- loadTemplate('site'); ?> - loadTemplate('metadata'); ?> -
-
- loadTemplate('seo'); ?> - loadTemplate('cookie'); ?> -
-
-
-
-
-
- loadTemplate('system'); ?> - loadTemplate('debug'); ?> - loadTemplate('cache'); ?> - loadTemplate('session'); ?> -
-
-
-
-
-
- loadTemplate('server'); ?> - loadTemplate('locale'); ?> - loadTemplate('ftp'); ?> - loadTemplate('proxy'); ?> -
-
- loadTemplate('database'); ?> - loadTemplate('mail'); ?> -
-
-
-
-
- loadTemplate('filters'); ?> -
-
- ftp) : ?> -
- loadTemplate('ftplogin'); ?> -
- -
-
- loadTemplate('permissions'); ?> -
-
- - -
-
- -
-
diff --git a/administrator/components/com_config/view/application/tmpl/default_cache.php b/administrator/components/com_config/view/application/tmpl/default_cache.php deleted file mode 100644 index c3dfffdd5f69b..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_cache.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_CACHE_SETTINGS'); -$this->fieldsname = 'cache'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_cookie.php b/administrator/components/com_config/view/application/tmpl/default_cookie.php deleted file mode 100644 index 1380984ec19b3..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_cookie.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_COOKIE_SETTINGS'); -$this->fieldsname = 'cookie'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_database.php b/administrator/components/com_config/view/application/tmpl/default_database.php deleted file mode 100644 index b667d365b3f83..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_database.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_DATABASE_SETTINGS'); -$this->fieldsname = 'database'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_debug.php b/administrator/components/com_config/view/application/tmpl/default_debug.php deleted file mode 100644 index 97882fa933dec..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_debug.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_DEBUG_SETTINGS'); -$this->fieldsname = 'debug'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_filters.php b/administrator/components/com_config/view/application/tmpl/default_filters.php deleted file mode 100644 index fb419a0b3dc0b..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_filters.php +++ /dev/null @@ -1,15 +0,0 @@ -name = JText::_('COM_CONFIG_TEXT_FILTER_SETTINGS'); -$this->fieldsname = 'filters'; -$this->description = JText::_('COM_CONFIG_TEXT_FILTERS_DESC'); -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 deleted file mode 100644 index 8f030252b6133..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_ftp.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_FTP_SETTINGS'); -$this->fieldsname = 'ftp'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_ftplogin.php b/administrator/components/com_config/view/application/tmpl/default_ftplogin.php deleted file mode 100644 index fdb4998d616db..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_ftplogin.php +++ /dev/null @@ -1,30 +0,0 @@ - -
- - - ftp instanceof Exception) : ?> -

ftp->message); ?>

- -
-
-
- -
-
-
-
-
- -
-
-
diff --git a/administrator/components/com_config/view/application/tmpl/default_locale.php b/administrator/components/com_config/view/application/tmpl/default_locale.php deleted file mode 100644 index 8b4aa72c0fb4e..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_locale.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_LOCATION_SETTINGS'); -$this->fieldsname = 'locale'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_mail.php b/administrator/components/com_config/view/application/tmpl/default_mail.php deleted file mode 100644 index e5151c1d7e44d..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_mail.php +++ /dev/null @@ -1,37 +0,0 @@ - 'auto', 'relative' => true)); - -// Load JavaScript message titles -JText::script('ERROR'); -JText::script('WARNING'); -JText::script('NOTICE'); -JText::script('MESSAGE'); - -// Add strings for JavaScript error translations. -JText::script('JLIB_JS_AJAX_ERROR_CONNECTION_ABORT'); -JText::script('JLIB_JS_AJAX_ERROR_NO_CONTENT'); -JText::script('JLIB_JS_AJAX_ERROR_OTHER'); -JText::script('JLIB_JS_AJAX_ERROR_PARSE'); -JText::script('JLIB_JS_AJAX_ERROR_TIMEOUT'); - -// Ajax request data. -$ajaxUri = JRoute::_('index.php?option=com_config&task=config.sendtestmail.application&format=json'); - -$this->name = JText::_('COM_CONFIG_MAIL_SETTINGS'); -$this->fieldsname = 'mail'; -echo JLayoutHelper::render('joomla.content.options_default', $this); - -echo ''; diff --git a/administrator/components/com_config/view/application/tmpl/default_metadata.php b/administrator/components/com_config/view/application/tmpl/default_metadata.php deleted file mode 100644 index 825383a6be21b..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_metadata.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_METADATA_SETTINGS'); -$this->fieldsname = 'metadata'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_navigation.php b/administrator/components/com_config/view/application/tmpl/default_navigation.php deleted file mode 100644 index 27e9272f9233e..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_navigation.php +++ /dev/null @@ -1,26 +0,0 @@ - - diff --git a/administrator/components/com_config/view/application/tmpl/default_permissions.php b/administrator/components/com_config/view/application/tmpl/default_permissions.php deleted file mode 100644 index cf5ece8b683ae..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_permissions.php +++ /dev/null @@ -1,17 +0,0 @@ -name = JText::_('COM_CONFIG_PERMISSION_SETTINGS'); -$this->description = ''; -$this->fieldsname = 'permissions'; -$this->formclass = 'form-vertical'; -$this->showlabel = false; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_proxy.php b/administrator/components/com_config/view/application/tmpl/default_proxy.php deleted file mode 100644 index 2fb9c48577a8e..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_proxy.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_PROXY_SETTINGS'); -$this->fieldsname = 'proxy'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_seo.php b/administrator/components/com_config/view/application/tmpl/default_seo.php deleted file mode 100644 index c54fd195aea72..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_seo.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_SEO_SETTINGS'); -$this->fieldsname = 'seo'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_server.php b/administrator/components/com_config/view/application/tmpl/default_server.php deleted file mode 100644 index 9b23386969611..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_server.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_SERVER_SETTINGS'); -$this->fieldsname = 'server'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_session.php b/administrator/components/com_config/view/application/tmpl/default_session.php deleted file mode 100644 index 4b6ccdaaafa5d..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_session.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_SESSION_SETTINGS'); -$this->fieldsname = 'session'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_site.php b/administrator/components/com_config/view/application/tmpl/default_site.php deleted file mode 100644 index 275274855e599..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_site.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_SITE_SETTINGS'); -$this->fieldsname = 'site'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/application/tmpl/default_system.php b/administrator/components/com_config/view/application/tmpl/default_system.php deleted file mode 100644 index de2ad23aba16f..0000000000000 --- a/administrator/components/com_config/view/application/tmpl/default_system.php +++ /dev/null @@ -1,14 +0,0 @@ -name = JText::_('COM_CONFIG_SYSTEM_SETTINGS'); -$this->fieldsname = 'system'; -echo JLayoutHelper::render('joomla.content.options_default', $this); diff --git a/administrator/components/com_config/view/component/html.php b/administrator/components/com_config/view/component/html.php deleted file mode 100644 index efc090ffaa115..0000000000000 --- a/administrator/components/com_config/view/component/html.php +++ /dev/null @@ -1,103 +0,0 @@ -model->getComponent(); - - if (!$component->enabled) - { - return false; - } - - $form = $this->model->getForm(); - $user = JFactory::getUser(); - } - catch (Exception $e) - { - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); - - return false; - } - - // Bind the form to the data. - if ($form && $component->params) - { - $form->bind($component->params); - } - - $this->fieldsets = $form ? $form->getFieldsets() : null; - $this->formControl = $form ? $form->getFormControl() : null; - - // Don't show permissions fieldset if not authorised. - if (!$user->authorise('core.admin', $component->option) && isset($this->fieldsets['permissions'])) - { - unset($this->fieldsets['permissions']); - } - - $this->form = &$form; - $this->component = &$component; - - $this->components = ConfigHelperConfig::getComponentsWithConfig(); - - $this->userIsSuperAdmin = $user->authorise('core.admin'); - $this->currentComponent = JFactory::getApplication()->input->get('component'); - $this->return = JFactory::getApplication()->input->get('return', '', 'base64'); - - $this->addToolbar(); - - return parent::render(); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 3.2 - */ - protected function addToolbar() - { - JToolbarHelper::title(JText::_($this->component->option . '_configuration'), 'equalizer config'); - JToolbarHelper::apply('config.save.component.apply'); - JToolbarHelper::save('config.save.component.save'); - JToolbarHelper::divider(); - JToolbarHelper::cancel('config.cancel.component'); - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_COMPONENTS_' . $this->currentComponent . '_OPTIONS'); - } -} diff --git a/administrator/components/com_config/view/component/tmpl/default.php b/administrator/components/com_config/view/component/tmpl/default.php deleted file mode 100644 index f52399e951c17..0000000000000 --- a/administrator/components/com_config/view/component/tmpl/default.php +++ /dev/null @@ -1,120 +0,0 @@ -getTemplate(); - -// Load the tooltip behavior. -JHtml::_('bootstrap.tooltip'); -JHtml::_('behavior.formvalidator'); -JHtml::_('behavior.keepalive'); -JHtml::_('formbehavior.chosen', '.chzn-custom-value', null, array('disable_search_threshold' => 0)); -JHtml::_('formbehavior.chosen', 'select'); - -// Load JS message titles -JText::script('ERROR'); -JText::script('WARNING'); -JText::script('NOTICE'); -JText::script('MESSAGE'); - -JFactory::getDocument()->addScriptDeclaration( - ' - Joomla.submitbutton = function(task) - { - if (task === "config.cancel.component" || document.formvalidator.isValid(document.getElementById("component-form"))) - { - jQuery("#permissions-sliders select").attr("disabled", "disabled"); - Joomla.submitform(task, document.getElementById("component-form")); - } - }; - - // Select first tab - jQuery(document).ready(function() { - jQuery("#configTabs a:first").tab("show"); - });' -); -?> - -
-
- - - - -
- - fieldsets): ?> - - -
- fieldsets as $name => $fieldSet) : ?> -
- description) && !empty($fieldSet->description)) : ?> -
- description); ?> -
- - form->getFieldset($name) as $field) : ?> - type === 'Spacer' ? ' field-spacer' : ''; - ?> - showon) : ?> - - 'auto', 'relative' => true)); ?> - showon, $field->formControl, $field->group)) . '\''; ?> - - hidden) : ?> - input; ?> - -
> - -
- label; ?> -
- -
- input; ?> -
-
- - -
- -
- -
- - -
- - - - - - -
-
diff --git a/administrator/components/com_config/view/component/tmpl/default.xml b/administrator/components/com_config/view/component/tmpl/default.xml deleted file mode 100755 index 803c832f4e0ac..0000000000000 --- a/administrator/components/com_config/view/component/tmpl/default.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - -
- -
-
-
diff --git a/administrator/components/com_config/view/component/tmpl/default_navigation.php b/administrator/components/com_config/view/component/tmpl/default_navigation.php deleted file mode 100644 index c26bbee57fa96..0000000000000 --- a/administrator/components/com_config/view/component/tmpl/default_navigation.php +++ /dev/null @@ -1,31 +0,0 @@ - - diff --git a/administrator/components/com_contact/Controller/ContactController.php b/administrator/components/com_contact/Controller/ContactController.php new file mode 100644 index 0000000000000..19f31b3fcad77 --- /dev/null +++ b/administrator/components/com_contact/Controller/ContactController.php @@ -0,0 +1,117 @@ +input->getInt('filter_category_id'), 'int'); + $allow = null; + + if ($categoryId) + { + // If the category has been passed in the URL check it. + $allow = Factory::getUser()->authorise('core.create', $this->option . '.category.' . $categoryId); + } + + if ($allow === null) + { + // In the absense of better information, revert to the component permissions. + return parent::allowAdd($data); + } + + return $allow; + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + + // Since there is no asset tracking, fallback to the component permissions. + if (!$recordId) + { + return parent::allowEdit($data, $key); + } + + // Get the item. + $item = $this->getModel()->getItem($recordId); + + // Since there is no item, return false. + if (empty($item)) + { + return false; + } + + $user = Factory::getUser(); + + // Check if can edit own core.edit.own. + $canEditOwn = $user->authorise('core.edit.own', $this->option . '.category.' . (int) $item->catid) && $item->created_by == $user->id; + + // Check the category core.edit permissions. + return $canEditOwn || $user->authorise('core.edit', $this->option . '.category.' . (int) $item->catid); + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 2.5 + */ + public function batch($model = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Set the model + /** @var \Joomla\Component\Contact\Administrator\Model\ContactModel $model */ + $model = $this->getModel('Contact', 'Administrator', array()); + + // Preset the redirect + $this->setRedirect(Route::_('index.php?option=com_contact&view=contacts' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } +} diff --git a/administrator/components/com_contact/Controller/ContactsController.php b/administrator/components/com_contact/Controller/ContactsController.php new file mode 100644 index 0000000000000..4f807bffc9bf1 --- /dev/null +++ b/administrator/components/com_contact/Controller/ContactsController.php @@ -0,0 +1,121 @@ +registerTask('unfeatured', 'featured'); + } + + /** + * Method to toggle the featured setting of a list of contacts. + * + * @return void + * + * @since 1.6 + */ + public function featured() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + $values = array('featured' => 1, 'unfeatured' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($values, $task, 0, 'int'); + + // Get the model. + /** @var \Joomla\Component\Contact\Administrator\Model\ContactModel $model */ + $model = $this->getModel(); + + // Access checks. + foreach ($ids as $i => $id) + { + $item = $model->getItem($id); + + if (!Factory::getUser()->authorise('core.edit.state', 'com_contact.category.' . (int) $item->catid)) + { + // Prune items that you can't change. + unset($ids[$i]); + $this->app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'notice'); + } + } + + if (empty($ids)) + { + $this->app->enqueueMessage(Text::_('COM_CONTACT_NO_ITEM_SELECTED'), 'warning'); + } + else + { + // Publish the items. + if (!$model->featured($ids, $value)) + { + $this->app->enqueueMessage($model->getError(), 'warning'); + } + + if ($value == 1) + { + $message = Text::plural('COM_CONTACT_N_ITEMS_FEATURED', count($ids)); + } + else + { + $message = Text::plural('COM_CONTACT_N_ITEMS_UNFEATURED', count($ids)); + } + } + + $this->setRedirect('index.php?option=com_contact&view=contacts', $message); + } + + /** + * Proxy for getModel. + * + * @param string $name The name of the model. + * @param string $prefix The prefix for the PHP class name. + * @param array $config Array of configuration parameters. + * + * @return \Joomla\CMS\MVC\Model\BaseDatabaseModel + * + * @since 1.6 + */ + public function getModel($name = 'Contact', $prefix = 'Administrator', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_contact/Controller/DisplayController.php b/administrator/components/com_contact/Controller/DisplayController.php new file mode 100644 index 0000000000000..8f25a49168a08 --- /dev/null +++ b/administrator/components/com_contact/Controller/DisplayController.php @@ -0,0 +1,61 @@ +input->get('view', $this->default_view); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($view == 'contact' && $layout == 'edit' && !$this->checkEditId('com_contact.edit.contact', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_contact&view=contacts', false)); + + return false; + } + + return parent::display(); + } +} diff --git a/administrator/components/com_contact/Field/Modal/ContactField.php b/administrator/components/com_contact/Field/Modal/ContactField.php new file mode 100644 index 0000000000000..90ad983cac2cd --- /dev/null +++ b/administrator/components/com_contact/Field/Modal/ContactField.php @@ -0,0 +1,297 @@ +element['new'] == 'true'); + $allowEdit = ((string) $this->element['edit'] == 'true'); + $allowClear = ((string) $this->element['clear'] != 'false'); + $allowSelect = ((string) $this->element['select'] != 'false'); + + // Load language + Factory::getLanguage()->load('com_contact', JPATH_ADMINISTRATOR); + + // The active contact id field. + $value = (int) $this->value > 0 ? (int) $this->value : ''; + + // Create the modal id. + $modalId = 'Contact_' . $this->id; + + // Add the modal field script to the document head. + HTMLHelper::_('jquery.framework'); + HTMLHelper::_('script', 'system/fields/modal-fields.min.js', array('version' => 'auto', 'relative' => true)); + + // Script to proxy the select modal function to the modal-fields.js file. + if ($allowSelect) + { + static $scriptSelect = null; + + if (is_null($scriptSelect)) + { + $scriptSelect = array(); + } + + if (!isset($scriptSelect[$this->id])) + { + Factory::getDocument()->addScriptDeclaration(" + function jSelectContact_" . $this->id . "(id, title, object) { + window.processModalSelect('Contact', '" . $this->id . "', id, title, '', object); + } + "); + + $scriptSelect[$this->id] = true; + } + } + + // Setup variables for display. + $linkContacts = 'index.php?option=com_contact&view=contacts&layout=modal&tmpl=component&' . Session::getFormToken() . '=1'; + $linkContact = 'index.php?option=com_contact&view=contact&layout=modal&tmpl=component&' . Session::getFormToken() . '=1'; + $modalTitle = Text::_('COM_CONTACT_CHANGE_CONTACT'); + + if (isset($this->element['language'])) + { + $linkContacts .= '&forcedLanguage=' . $this->element['language']; + $linkContact .= '&forcedLanguage=' . $this->element['language']; + $modalTitle .= ' — ' . $this->element['label']; + } + + $urlSelect = $linkContacts . '&function=jSelectContact_' . $this->id; + $urlEdit = $linkContact . '&task=contact.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \''; + $urlNew = $linkContact . '&task=contact.add'; + + if ($value) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('name')) + ->from($db->quoteName('#__contact_details')) + ->where($db->quoteName('id') . ' = ' . (int) $value); + $db->setQuery($query); + + try + { + $title = $db->loadResult(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + } + + $title = empty($title) ? Text::_('COM_CONTACT_SELECT_A_CONTACT') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); + + // The current contact display field. + $html = ''; + if ($allowSelect || $allowNew || $allowEdit || $allowClear) + { + $html .= ''; + } + + $html .= ''; + + if ($allowSelect || $allowNew || $allowEdit || $allowClear) + { + $html .= ''; + } + + // Select contact button + if ($allowSelect) + { + $html .= '' + . ' ' . Text::_('JSELECT') + . ''; + } + + // New contact button + if ($allowNew) + { + $html .= '' + . ' ' . Text::_('JACTION_CREATE') + . ''; + } + + // Edit contact button + if ($allowEdit) + { + $html .= '' + . ' ' . Text::_('JACTION_EDIT') + . ''; + } + + // Clear contact button + if ($allowClear) + { + $html .= '' + . '' . Text::_('JCLEAR') + . ''; + } + + if ($allowSelect || $allowNew || $allowEdit || $allowClear) + { + $html .= ''; + } + + // Select contact modal + if ($allowSelect) + { + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + 'ModalSelect' . $modalId, + array( + 'title' => $modalTitle, + 'url' => $urlSelect, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '', + ) + ); + } + + // New contact modal + if ($allowNew) + { + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + 'ModalNew' . $modalId, + array( + 'title' => Text::_('COM_CONTACT_NEW_CONTACT'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlNew, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '' + . '' + . '', + ) + ); + } + + // Edit contact modal. + if ($allowEdit) + { + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + 'ModalEdit' . $modalId, + array( + 'title' => Text::_('COM_CONTACT_EDIT_CONTACT'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlEdit, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '' + . '' + . '', + ) + ); + } + + // Note: class='required' for client side validation. + $class = $this->required ? ' class="required modal-value"' : ''; + + $html .= ''; + + return $html; + } + + /** + * Method to get the field label markup. + * + * @return string The field label markup. + * + * @since 3.4 + */ + protected function getLabel() + { + return str_replace($this->id, $this->id . '_id', parent::getLabel()); + } +} diff --git a/administrator/components/com_contact/Helper/ContactHelper.php b/administrator/components/com_contact/Helper/ContactHelper.php new file mode 100644 index 0000000000000..3c3d8c44e8fdf --- /dev/null +++ b/administrator/components/com_contact/Helper/ContactHelper.php @@ -0,0 +1,243 @@ +get('custom_fields_enable', '1')) + { + \JHtmlSidebar::addEntry( + Text::_('JGLOBAL_FIELDS'), + 'index.php?option=com_fields&context=com_contact.contact', + $vName == 'fields.fields' + ); + \JHtmlSidebar::addEntry( + Text::_('JGLOBAL_FIELD_GROUPS'), + 'index.php?option=com_fields&view=groups&context=com_contact.contact', + $vName == 'fields.groups' + ); + } + } + + /** + * Adds Count Items for Category Manager. + * + * @param \stdClass[] &$items The contact category objects + * + * @return \stdClass[] + * + * @since 3.5 + */ + public static function countItems(&$items) + { + $db = Factory::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->quoteName('#__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; + } + } + } + + 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 = Factory::getDbo(); + $parts = explode('.', $extension); + $section = null; + + if (count($parts) > 1) + { + $section = $parts[1]; + } + + $join = $db->quoteName('#__contact_details') . ' AS c ON ct.content_item_id=c.id'; + + if ($section === 'category') + { + $join = $db->quoteName('#__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->quoteName('#__contentitem_tag_map') . 'AS ct ') + ->where('ct.tag_id = ' . (int) $item->id) + ->where('ct.type_alias =' . $db->quote($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; + } + } + } + + return $items; + } + + /** + * Returns a valid section for contacts. If it is not valid then null + * is returned. + * + * @param string $section The section to get the mapping for + * @param object $item optional item object + * + * @return string|null The new section + * + * @since 3.7.0 + */ + public static function validateSection($section, $item) + { + if (Factory::getApplication()->isClient('site') && $section == 'contact' && $item instanceof \JForm) + { + // The contact form needs to be the mail section + $section = 'mail'; + } + + if (Factory::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 + return null; + } + + return $section; + } + + /** + * Returns valid contexts + * + * @return array + * + * @since 3.7.0 + */ + public static function getContexts() + { + Factory::getLanguage()->load('com_contact', JPATH_ADMINISTRATOR); + + $contexts = array( + 'com_contact.contact' => Text::_('COM_CONTACT_FIELDS_CONTEXT_CONTACT'), + 'com_contact.mail' => Text::_('COM_CONTACT_FIELDS_CONTEXT_MAIL'), + 'com_contact.categories' => Text::_('JCATEGORY') + ); + + return $contexts; + } +} diff --git a/administrator/components/com_contact/Model/ContactModel.php b/administrator/components/com_contact/Model/ContactModel.php new file mode 100644 index 0000000000000..848e06032f196 --- /dev/null +++ b/administrator/components/com_contact/Model/ContactModel.php @@ -0,0 +1,650 @@ + 'batchAccess', + 'language_id' => 'batchLanguage', + 'tag' => 'batchTag', + '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(Text::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; + } + + // 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. + * + * @param integer $value The new value matching a User ID. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 2.5 + */ + protected function batchUser($value, $pks, $contexts) + { + foreach ($pks as $pk) + { + if ($this->user->authorise('core.edit', $contexts[$pk])) + { + $this->table->reset(); + $this->table->load($pk); + $this->table->user_id = (int) $value; + + if (!$this->table->store()) + { + $this->setError($this->table->getError()); + + return false; + } + } + else + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canDelete($record) + { + if (!empty($record->id)) + { + if ($record->published != -2) + { + return false; + } + + return Factory::getUser()->authorise('core.delete', 'com_contact.category.' . (int) $record->catid); + } + } + + /** + * 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) + { + // Check against the category. + if (!empty($record->catid)) + { + return Factory::getUser()->authorise('core.edit.state', 'com_contact.category.' . (int) $record->catid); + } + + // Default to component settings if category not known. + return parent::canEditState($record); + } + + /** + * Method to get the row form. + * + * @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 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + \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)); + + if (empty($form)) + { + return false; + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('featured', 'disabled', 'true'); + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('featured', 'filter', 'unset'); + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) + { + // Convert the metadata field to an array. + $registry = new Registry($item->metadata); + $item->metadata = $registry->toArray(); + } + + // Load associated contact items + $assoc = Associations::isEnabled(); + + if ($assoc) + { + $item->associations = array(); + + if ($item->id != null) + { + $associations = Associations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', $item->id); + + foreach ($associations as $tag => $association) + { + $item->associations[$tag] = $association->id; + } + } + } + + // Load item tags + if (!empty($item->id)) + { + $item->tags = new TagsHelper; + $item->tags->getTagIds($item->id, 'com_contact.contact'); + } + + return $item; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + $app = Factory::getApplication(); + + // Check the session for previously entered form data. + $data = $app->getUserState('com_contact.edit.contact.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + + // Prime some default values. + if ($this->getState('contact.id') == 0) + { + $data->set('catid', $app->input->get('catid', $app->getUserState('com_contact.contacts.filter.category_id'), 'int')); + } + } + + $this->preprocessData('com_contact.contact', $data); + + return $data; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 3.0 + */ + public function save($data) + { + $input = Factory::getApplication()->input; + + \JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); + + // Cast catid to integer for comparison + $catid = (int) $data['catid']; + + // Check if New Category exists + if ($catid > 0) + { + $catid = \CategoriesHelper::validateCategoryId($data['catid'], 'com_contact'); + } + + // Save New Category + if ($catid == 0 && $this->canCreateCategory()) + { + $table = array(); + $table['title'] = $data['catid']; + $table['parent_id'] = 1; + $table['extension'] = 'com_contact'; + $table['language'] = $data['language']; + $table['published'] = 1; + + // Create new category and get catid back + $data['catid'] = \CategoriesHelper::createCategory($table); + } + + // Alter the name for save as copy + if ($input->get('task') == 'save2copy') + { + $origTable = clone $this->getTable(); + $origTable->load($input->getInt('id')); + + if ($data['name'] == $origTable->name) + { + list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']); + $data['name'] = $name; + $data['alias'] = $alias; + } + else + { + if ($data['alias'] == $origTable->alias) + { + $data['alias'] = ''; + } + } + + $data['published'] = 0; + } + + $links = array('linka', 'linkb', 'linkc', 'linkd', 'linke'); + + foreach ($links as $link) + { + if ($data['params'][$link]) + { + $data['params'][$link] = PunycodeHelper::urlToPunycode($data['params'][$link]); + } + } + + return parent::save($data); + } + + /** + * Prepare and sanitise the table prior to saving. + * + * @param \Joomla\CMS\Table\Table $table The Table object + * + * @return void + * + * @since 1.6 + */ + protected function prepareTable($table) + { + $date = Factory::getDate()->toSql(); + + $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); + + $table->generateAlias(); + + if (empty($table->id)) + { + // Set the values + $table->created = $date; + + // Set ordering to the last item if not set + if (empty($table->ordering)) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('MAX(ordering)') + ->from($db->quoteName('#__contact_details')); + $db->setQuery($query); + $max = $db->loadResult(); + + $table->ordering = $max + 1; + } + } + else + { + // Set the values + $table->modified = $date; + $table->modified_by = Factory::getUser()->id; + } + + // Increment the content version number. + $table->version++; + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param \Joomla\CMS\Table\Table $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 + */ + protected function getReorderConditions($table) + { + return array('catid = ' . (int) $table->catid); + } + + /** + * Preprocess the form. + * + * @param \JForm $form Form object. + * @param object $data Data object. + * @param string $group Group name. + * + * @return void + * + * @since 3.0.3 + */ + protected function preprocessForm(\JForm $form, $data, $group = 'content') + { + // Determine correct permissions to check. + if ($this->getState('contact.id')) + { + // Existing record. Can only edit in selected categories. + $form->setFieldAttribute('catid', 'action', 'core.edit'); + } + else + { + // New record. Can only create in selected categories. + $form->setFieldAttribute('catid', 'action', 'core.create'); + } + + if ($this->canCreateCategory()) + { + $form->setFieldAttribute('catid', 'allowAdd', 'true'); + } + + // Association contact items + if (Associations::isEnabled()) + { + $languages = LanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc'); + + if (count($languages) > 1) + { + $addform = new \SimpleXMLElement('
'); + $fields = $addform->addChild('fields'); + $fields->addAttribute('name', 'associations'); + $fieldset = $fields->addChild('fieldset'); + $fieldset->addAttribute('name', 'item_associations'); + + foreach ($languages as $language) + { + $field = $fieldset->addChild('field'); + $field->addAttribute('name', $language->lang_code); + $field->addAttribute('type', 'modal_contact'); + $field->addAttribute('language', $language->lang_code); + $field->addAttribute('label', $language->title); + $field->addAttribute('translate_label', 'false'); + $field->addAttribute('select', 'true'); + $field->addAttribute('new', 'true'); + $field->addAttribute('edit', 'true'); + $field->addAttribute('clear', 'true'); + } + + $form->load($addform, false); + } + } + + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to toggle the featured setting of contacts. + * + * @param array $pks The ids of the items to toggle. + * @param integer $value The value to toggle to. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function featured($pks, $value = 0) + { + // Sanitize the ids. + $pks = ArrayHelper::toInteger((array) $pks); + + if (empty($pks)) + { + $this->setError(Text::_('COM_CONTACT_NO_ITEM_SELECTED')); + + return false; + } + + $table = $this->getTable(); + + try + { + $db = $this->getDbo(); + + $query = $db->getQuery(true); + $query->update('#__contact_details'); + $query->set('featured = ' . (int) $value); + $query->where('id IN (' . implode(',', $pks) . ')'); + $db->setQuery($query); + + $db->execute(); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + $table->reorder(); + + // Clean component's cache + $this->cleanCache(); + + return true; + } + + /** + * 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. + * + * @return array Contains the modified title and alias. + * + * @since 3.1 + */ + protected function generateNewTitle($category_id, $alias, $name) + { + // 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); + } + + /** + * Is the user allowed to create an on the fly category? + * + * @return boolean + * + * @since 3.6.1 + */ + private function canCreateCategory() + { + return Factory::getUser()->authorise('core.create', 'com_contact'); + } +} diff --git a/administrator/components/com_contact/Model/ContactsModel.php b/administrator/components/com_contact/Model/ContactsModel.php new file mode 100644 index 0000000000000..77cfe036f150c --- /dev/null +++ b/administrator/components/com_contact/Model/ContactsModel.php @@ -0,0 +1,348 @@ +input->get('forcedLanguage', '', 'cmd'); + + // Adjust the context to support modal layouts. + if ($layout = $app->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + // Adjust the context to support forced languages. + if ($forcedLanguage) + { + $this->context .= '.' . $forcedLanguage; + } + + // List state information. + parent::populateState($ordering, $direction); + + // Force a language. + if (!empty($forcedLanguage)) + { + $this->setState('filter.language', $forcedLanguage); + } + } + + /** + * 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 A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . serialize($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'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = Factory::getUser(); + + // Select the required fields from the table. + $query->select( + $db->quoteName( + explode(', ', $this->getState( + 'list.select', + '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' + ) + ) + ) + ); + $query->from($db->quoteName('#__contact_details', 'a')); + + // Join over the users for the linked user. + $query->select( + array( + $db->quoteName('ul.name', 'linked_user'), + $db->quoteName('ul.email') + ) + ) + ->join( + 'LEFT', + $db->quoteName('#__users', 'ul') . ' ON ' . $db->quoteName('ul.id') . ' = ' . $db->quoteName('a.user_id') + ); + + // Join over the language + $query->select($db->quoteName('l.title', 'language_title')) + ->select($db->quoteName('l.image', 'language_image')) + ->join( + 'LEFT', + $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.language') + ); + + // Join over the users for the checked out user. + $query->select($db->quoteName('uc.name', 'editor')) + ->join( + 'LEFT', + $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out') + ); + + // Join over the asset groups. + $query->select($db->quoteName('ag.title', 'access_level')) + ->join( + 'LEFT', + $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access') + ); + + // Join over the categories. + $query->select($db->quoteName('c.title', 'category_title')) + ->join( + 'LEFT', + $db->quoteName('#__categories', 'c') . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid') + ); + + // Join over the associations. + $assoc = Associations::isEnabled(); + + 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' + ) + ) + ); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where($db->quoteName('a.access') . ' = ' . (int) $access); + } + + // Implement View Level Access + if (!$user->authorise('core.admin')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where($db->quoteName('a.access') . ' IN (' . $groups . ')'); + } + + // Filter by published state + $published = (string) $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where($db->quoteName('a.published') . ' = ' . (int) $published); + } + elseif ($published === '') + { + $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'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where( + '(' . $db->quoteName('a.name') . ' LIKE ' . $search . ' OR ' . $db->quoteName('a.alias') . ' LIKE ' . $search . ')' + ); + } + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + $query->where($db->quoteName('a.language') . ' = ' . $db->quote($language)); + } + + // Filter by a single tag. + $tagId = $this->getState('filter.tag'); + + if (is_numeric($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_contact.contact') + ); + } + + // Filter on the level. + if ($level = $this->getState('filter.level')) + { + $query->where('c.level <= ' . (int) $level); + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering', 'a.name'); + $orderDirn = $this->state->get('list.direction', 'asc'); + + if ($orderCol == 'a.ordering' || $orderCol == 'category_title') + { + $orderCol = $db->quoteName('c.title') . ' ' . $orderDirn . ', ' . $db->quoteName('a.ordering'); + } + + $query->order($db->escape($orderCol . ' ' . $orderDirn)); + + return $query; + } +} diff --git a/administrator/components/com_contact/Table/ContactTable.php b/administrator/components/com_contact/Table/ContactTable.php new file mode 100644 index 0000000000000..a6af9f21aed2e --- /dev/null +++ b/administrator/components/com_contact/Table/ContactTable.php @@ -0,0 +1,280 @@ +typeAlias = 'com_contact.contact'; + + parent::__construct('#__contact_details', 'id', $db); + } + + /** + * Stores a contact. + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return boolean True on success, false on failure. + * + * @since 1.6 + */ + public function store($updateNulls = false) + { + // Transform the params field + if (is_array($this->params)) + { + $registry = new Registry($this->params); + $this->params = (string) $registry; + } + + $date = Factory::getDate()->toSql(); + $userId = Factory::getUser()->id; + + if ($this->id) + { + // Existing item + $this->modified_by = $userId; + $this->modified = $date; + } + else + { + // New contact. A contact created and created_by field can be set by the user, + // so we don't touch either of these if they are set. + if (!(int) $this->created) + { + $this->created = $date; + } + + if (empty($this->created_by)) + { + $this->created_by = $userId; + } + } + + // Set publish_up to null date if not set + if (!$this->publish_up) + { + $this->publish_up = $this->_db->getNullDate(); + } + + // Set publish_down to null date if not set + if (!$this->publish_down) + { + $this->publish_down = $this->_db->getNullDate(); + } + + // Set xreference to empty string if not set + if (!$this->xreference) + { + $this->xreference = ''; + } + + // Store utf8 email as punycode + $this->email_to = PunycodeHelper::emailToPunycode($this->email_to); + + // Convert IDN urls to punycode + $this->webpage = PunycodeHelper::urlToPunycode($this->webpage); + + // Verify that the alias is unique + $table = Table::getInstance('ContactTable', __NAMESPACE__ . '\\', array('dbo' => $this->getDbo())); + + if ($table->load(array('alias' => $this->alias, 'catid' => $this->catid)) && ($table->id != $this->id || $this->id == 0)) + { + $this->setError(Text::_('COM_CONTACT_ERROR_UNIQUE_ALIAS')); + + return false; + } + + return parent::store($updateNulls); + } + + /** + * Overloaded check function + * + * @return boolean True on success, false on failure + * + * @see \JTable::check + * @since 1.5 + */ + public function check() + { + try + { + parent::check(); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + $this->default_con = (int) $this->default_con; + + if (\JFilterInput::checkAttribute(array('href', $this->webpage))) + { + $this->setError(Text::_('COM_CONTACT_WARNING_PROVIDE_VALID_URL')); + + return false; + } + + // Check for valid name + if (trim($this->name) == '') + { + $this->setError(Text::_('COM_CONTACT_WARNING_PROVIDE_VALID_NAME')); + + return false; + } + + // Generate a valid alias + $this->generateAlias(); + + // Check for valid category + if (trim($this->catid) == '') + { + $this->setError(Text::_('COM_CONTACT_WARNING_CATEGORY')); + + return false; + } + + // Sanity check for user_id + if (!$this->user_id) + { + $this->user_id = 0; + } + + // Check the publish down date is not earlier than publish up. + if ((int) $this->publish_down > 0 && $this->publish_down < $this->publish_up) + { + $this->setError(Text::_('JGLOBAL_START_PUBLISH_AFTER_FINISH')); + + return false; + } + + /* + * Clean up keywords -- eliminate extra spaces between phrases + * and cr (\r) and lf (\n) characters from string. + * Only process if not empty. + */ + if (!empty($this->metakey)) + { + // Array of characters to remove. + $badCharacters = array("\n", "\r", "\"", '<', '>'); + + // Remove bad characters. + $afterClean = StringHelper::str_ireplace($badCharacters, '', $this->metakey); + + // Create array using commas as delimiter. + $keys = explode(',', $afterClean); + $cleanKeys = array(); + + foreach ($keys as $key) + { + // Ignore blank keywords. + if (trim($key)) + { + $cleanKeys[] = trim($key); + } + } + + // Put array back together delimited by ", " + $this->metakey = implode(', ', $cleanKeys); + } + else + { + $this->metakey = ''; + } + + // Clean up description -- eliminate quotes and <> brackets + if (!empty($this->metadesc)) + { + // Only process if not empty + $badCharacters = array("\"", '<', '>'); + $this->metadesc = StringHelper::str_ireplace($badCharacters, '', $this->metadesc); + } + else + { + $this->metadesc = ''; + } + + if (empty($this->params)) + { + $this->params = '{}'; + } + + if (empty($this->metadata)) + { + $this->metadata = '{}'; + } + + if (empty($this->modified)) + { + $this->modified = $this->getDbo()->getNullDate(); + } + + return true; + } + + /** + * Generate a valid alias from title / date. + * Remains public to be able to check for duplicated alias before saving + * + * @return string + */ + public function generateAlias() + { + if (empty($this->alias)) + { + $this->alias = $this->name; + } + + $this->alias = ApplicationHelper::stringURLSafe($this->alias, $this->language); + + if (trim(str_replace('-', '', $this->alias)) == '') + { + $this->alias = Factory::getDate()->format('Y-m-d-H-i-s'); + } + + return $this->alias; + } +} diff --git a/administrator/components/com_contact/View/Contact/HtmlView.php b/administrator/components/com_contact/View/Contact/HtmlView.php new file mode 100644 index 0000000000000..b967574dea2e8 --- /dev/null +++ b/administrator/components/com_contact/View/Contact/HtmlView.php @@ -0,0 +1,169 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // If we are forcing a language in modal (used for associations). + if ($this->getLayout() === 'modal' && $forcedLanguage = Factory::getApplication()->input->get('forcedLanguage', '', 'cmd')) + { + // Set the language field to the forcedLanguage and disable changing it. + $this->form->setValue('language', null, $forcedLanguage); + $this->form->setFieldAttribute('language', 'readonly', 'true'); + + // Only allow to select categories with All language or with the forced language. + $this->form->setFieldAttribute('catid', 'language', '*,' . $forcedLanguage); + + // Only allow to select tags with All language or with the forced language. + $this->form->setFieldAttribute('tags', 'language', '*,' . $forcedLanguage); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $user = Factory::getUser(); + $userId = $user->id; + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); + + // Since we don't track these assets at the item level, use the category id. + $canDo = ContentHelper::getActions('com_contact', 'category', $this->item->catid); + + ToolbarHelper::title($isNew ? Text::_('COM_CONTACT_MANAGER_CONTACT_NEW') : Text::_('COM_CONTACT_MANAGER_CONTACT_EDIT'), 'address contact'); + + // Build the actions for new and existing records. + if ($isNew) + { + // For new records, check the create permission. + if ($isNew && (count($user->getAuthorisedCategories('com_contact', 'core.create')) > 0)) + { + ToolbarHelper::saveGroup( + [ + ['apply', 'contact.apply'], + ['save', 'contact.save'], + ['save2new', 'contact.save2new'] + ], + 'btn-success' + ); + } + + ToolbarHelper::cancel('contact.cancel'); + } + else + { + // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. + $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId); + + $toolbarButtons = []; + + // Can't save the record if it's checked out and editable + if (!$checkedOut && $itemEditable) + { + $toolbarButtons[] = ['apply', 'contact.apply']; + $toolbarButtons[] = ['save', 'contact.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')) + { + $toolbarButtons[] = ['save2new', 'contact.save2new']; + } + } + + // If checked out, we can still save + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'contact.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (ComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $itemEditable) + { + ToolbarHelper::versions('com_contact.contact', $this->item->id); + } + + ToolbarHelper::cancel('contact.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_COMPONENTS_CONTACTS_CONTACTS_EDIT'); + } +} diff --git a/administrator/components/com_contact/View/Contacts/HtmlView.php b/administrator/components/com_contact/View/Contacts/HtmlView.php new file mode 100644 index 0000000000000..ef3356e889906 --- /dev/null +++ b/administrator/components/com_contact/View/Contacts/HtmlView.php @@ -0,0 +1,224 @@ +getLayout() !== 'modal') + { + ContactHelper::addSubmenu('contacts'); + } + + $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 \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Preprocess the list of items to find ordering divisions. + // TODO: Complete the ordering stuff with nested sets + foreach ($this->items as &$item) + { + $item->order_up = true; + $item->order_dn = true; + } + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + // We do not need to filter by language when multilingual is disabled + if (!Multilanguage::isEnabled()) + { + unset($this->activeFilters['language']); + $this->filterForm->removeField('language', 'filter'); + } + } + 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 = Factory::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 a 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'); + } + } + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_contact', 'category', $this->state->get('filter.category_id')); + $user = Factory::getUser(); + + ToolbarHelper::title(Text::_('COM_CONTACT_MANAGER_CONTACTS'), 'address contact'); + + if ($canDo->get('core.create') || count($user->getAuthorisedCategories('com_contact', 'core.create')) > 0) + { + ToolbarHelper::addNew('contact.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publish('contacts.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('contacts.unpublish', 'JTOOLBAR_UNPUBLISH', true); + ToolbarHelper::custom('contacts.featured', 'featured.png', 'featured_f2.png', 'JFEATURE', true); + ToolbarHelper::custom('contacts.unfeatured', 'unfeatured.png', 'featured_f2.png', 'JUNFEATURE', true); + ToolbarHelper::archiveList('contacts.archive'); + ToolbarHelper::checkin('contacts.checkin'); + } + + // Add a batch button + if ($user->authorise('core.create', 'com_contact') + && $user->authorise('core.edit', 'com_contact') + && $user->authorise('core.edit.state', 'com_contact')) + { + $title = Text::_('JTOOLBAR_BATCH'); + + // Instantiate a new FileLayout instance and render the batch button + $layout = new FileLayout('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + Toolbar::getInstance('toolbar')->appendButton('Custom', $dhtml, 'batch'); + } + + if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'contacts.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('contacts.trash'); + } + + if ($user->authorise('core.admin', 'com_contact') || $user->authorise('core.options', 'com_contact')) + { + ToolbarHelper::preferences('com_contact'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_CONTACTS_CONTACTS'); + + \JHtmlSidebar::setAction('index.php?option=com_contact'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.ordering' => Text::_('JGRID_HEADING_ORDERING'), + 'a.published' => Text::_('JSTATUS'), + 'a.name' => Text::_('JGLOBAL_TITLE'), + 'category_title' => Text::_('JCATEGORY'), + 'ul.name' => Text::_('COM_CONTACT_FIELD_LINKED_USER_LABEL'), + 'a.featured' => Text::_('JFEATURED'), + 'a.access' => Text::_('JGRID_HEADING_ACCESS'), + 'a.language' => Text::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_contact/access.xml b/administrator/components/com_contact/access.xml index 14de10bac138d..c5b04e6c71c39 100644 --- a/administrator/components/com_contact/access.xml +++ b/administrator/components/com_contact/access.xml @@ -1,35 +1,35 @@
- - - - - - - - - + + + + + + + + +
- - - - - + + + + +
- - - - - - + + + + + +
- - - - + + + +
\ No newline at end of file diff --git a/administrator/components/com_contact/config.xml b/administrator/components/com_contact/config.xml index 15ee14fa5de99..1e5ac38e9468b 100644 --- a/administrator/components/com_contact/config.xml +++ b/administrator/components/com_contact/config.xml @@ -5,14 +5,13 @@ name="contact" label="COM_CONTACT_FIELD_CONFIG_INDIVIDUAL_CONTACT_DISPLAY" description="COM_CONTACT_FIELD_CONFIG_INDIVIDUAL_CONTACT_DESC" - addfieldpath="/administrator/components/com_fields/models/fields" > @@ -34,20 +31,18 @@ - + - + @@ -80,23 +73,21 @@ - + @@ -106,189 +97,174 @@ name="show_name" type="radio" label="COM_CONTACT_FIELD_PARAMS_NAME_LABEL" - description="COM_CONTACT_FIELD_PARAMS_NAME_DESC" default="1" - class="btn-group btn-group-yesno" + class="switcher" showon="show_info:1" > - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -296,44 +272,40 @@ - + - + - + @@ -357,22 +329,21 @@ - + @@ -380,20 +351,18 @@ - + @@ -463,7 +427,6 @@ name="icon_address" type="media" label="COM_CONTACT_FIELD_ICONS_ADDRESS_LABEL" - description="COM_CONTACT_FIELD_ICONS_ADDRESS_DESC" hide_none="1" default="" showon="contact_icons:0" @@ -473,7 +436,6 @@ name="icon_email" type="media" label="COM_CONTACT_FIELD_ICONS_EMAIL_LABEL" - description="COM_CONTACT_FIELD_ICONS_EMAIL_DESC" hide_none="1" default="" showon="contact_icons:0" @@ -483,7 +445,6 @@ name="icon_telephone" type="media" label="COM_CONTACT_FIELD_ICONS_TELEPHONE_LABEL" - description="COM_CONTACT_FIELD_ICONS_TELEPHONE_DESC" hide_none="1" default="" showon="contact_icons:0" @@ -493,7 +454,6 @@ name="icon_mobile" type="media" label="COM_CONTACT_FIELD_ICONS_MOBILE_LABEL" - description="COM_CONTACT_FIELD_ICONS_MOBILE_DESC" hide_none="1" default="" showon="contact_icons:0" @@ -503,7 +463,6 @@ name="icon_fax" type="media" label="COM_CONTACT_FIELD_ICONS_FAX_LABEL" - description="COM_CONTACT_FIELD_ICONS_FAX_DESC" hide_none="1" default="" showon="contact_icons:0" @@ -513,7 +472,6 @@ name="icon_misc" type="media" label="COM_CONTACT_FIELD_ICONS_MISC_LABEL" - description="COM_CONTACT_FIELD_ICONS_MISC_DESC" hide_none="1" default="" showon="contact_icons:0" @@ -530,7 +488,7 @@ name="category_layout" type="componentlayout" label="JGLOBAL_FIELD_LAYOUT_LABEL" - description="JGLOBAL_FIELD_LAYOUT_DESC" + class="custom-select" menuitems="true" extension="com_contact" view="category" @@ -539,44 +497,40 @@ - + - + - + @@ -591,51 +545,47 @@ - + - + - + - +
@@ -648,20 +598,18 @@ - + @@ -676,39 +624,36 @@ - + - + - + @@ -722,160 +667,147 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -886,21 +818,19 @@ - + @@ -921,7 +851,6 @@ name="captcha" type="plugins" label="COM_CONTACT_FIELD_CAPTCHA_LABEL" - description="COM_CONTACT_FIELD_CAPTCHA_DESC" folder="captcha" filter="cmd" useglobal="true" @@ -932,26 +861,24 @@ - + - + - + - + -
- - - - - - + - + label="JGLOBAL_SEF_NOIDS_LABEL" + filter="integer"> + diff --git a/administrator/components/com_contact/contact.php b/administrator/components/com_contact/contact.php deleted file mode 100644 index af2db364c682f..0000000000000 --- a/administrator/components/com_contact/contact.php +++ /dev/null @@ -1,20 +0,0 @@ -authorise('core.manage', 'com_contact')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('contact'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_contact/contact.xml b/administrator/components/com_contact/contact.xml index b285029f92aa3..4ac5e38eaee13 100644 --- a/administrator/components/com_contact/contact.xml +++ b/administrator/components/com_contact/contact.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 COM_CONTACT_XML_DESCRIPTION + Joomla\Component\Contact diff --git a/administrator/components/com_contact/controller.php b/administrator/components/com_contact/controller.php deleted file mode 100644 index 5169195180191..0000000000000 --- a/administrator/components/com_contact/controller.php +++ /dev/null @@ -1,58 +0,0 @@ -input->get('view', 'contacts'); - $layout = $this->input->get('layout', 'default'); - $id = $this->input->getInt('id'); - - // Check for edit form. - if ($view == 'contact' && $layout == 'edit' && !$this->checkEditId('com_contact.edit.contact', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_contact&view=contacts', false)); - - return false; - } - - return parent::display(); - } -} diff --git a/administrator/components/com_contact/controllers/contact.php b/administrator/components/com_contact/controllers/contact.php deleted file mode 100644 index 2f69d30bfd993..0000000000000 --- a/administrator/components/com_contact/controllers/contact.php +++ /dev/null @@ -1,110 +0,0 @@ -input->getInt('filter_category_id'), 'int'); - $allow = null; - - if ($categoryId) - { - // If the category has been passed in the URL check it. - $allow = JFactory::getUser()->authorise('core.create', $this->option . '.category.' . $categoryId); - } - - if ($allow === null) - { - // In the absense of better information, revert to the component permissions. - return parent::allowAdd($data); - } - - return $allow; - } - - /** - * Method override to check if you can edit an existing record. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. - * - * @return boolean - * - * @since 1.6 - */ - protected function allowEdit($data = array(), $key = 'id') - { - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; - - // Since there is no asset tracking, fallback to the component permissions. - if (!$recordId) - { - return parent::allowEdit($data, $key); - } - - // Get the item. - $item = $this->getModel()->getItem($recordId); - - // Since there is no item, return false. - if (empty($item)) - { - return false; - } - - $user = JFactory::getUser(); - - // Check if can edit own core.edit.own. - $canEditOwn = $user->authorise('core.edit.own', $this->option . '.category.' . (int) $item->catid) && $item->created_by == $user->id; - - // Check the category core.edit permissions. - return $canEditOwn || $user->authorise('core.edit', $this->option . '.category.' . (int) $item->catid); - } - - /** - * Method to run batch operations. - * - * @param object $model The model. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 2.5 - */ - public function batch($model = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Set the model - /** @var ContactModelContact $model */ - $model = $this->getModel('Contact', '', array()); - - // Preset the redirect - $this->setRedirect(JRoute::_('index.php?option=com_contact&view=contacts' . $this->getRedirectToListAppend(), false)); - - return parent::batch($model); - } -} diff --git a/administrator/components/com_contact/controllers/contacts.php b/administrator/components/com_contact/controllers/contacts.php deleted file mode 100644 index b800b51f7d54e..0000000000000 --- a/administrator/components/com_contact/controllers/contacts.php +++ /dev/null @@ -1,110 +0,0 @@ -registerTask('unfeatured', 'featured'); - } - - /** - * Method to toggle the featured setting of a list of contacts. - * - * @return void - * - * @since 1.6 - */ - public function featured() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = $this->input->get('cid', array(), 'array'); - $values = array('featured' => 1, 'unfeatured' => 0); - $task = $this->getTask(); - $value = ArrayHelper::getValue($values, $task, 0, 'int'); - - // Get the model. - /** @var ContactModelContact $model */ - $model = $this->getModel(); - - // Access checks. - foreach ($ids as $i => $id) - { - $item = $model->getItem($id); - - if (!JFactory::getUser()->authorise('core.edit.state', 'com_contact.category.' . (int) $item->catid)) - { - // Prune items that you can't change. - unset($ids[$i]); - JError::raiseNotice(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - } - } - - if (empty($ids)) - { - JError::raiseWarning(500, JText::_('COM_CONTACT_NO_ITEM_SELECTED')); - } - else - { - // Publish the items. - if (!$model->featured($ids, $value)) - { - JError::raiseWarning(500, $model->getError()); - } - - if ($value == 1) - { - $message = JText::plural('COM_CONTACT_N_ITEMS_FEATURED', count($ids)); - } - else - { - $message = JText::plural('COM_CONTACT_N_ITEMS_UNFEATURED', count($ids)); - } - } - - $this->setRedirect('index.php?option=com_contact&view=contacts', $message); - } - - /** - * Proxy for getModel. - * - * @param string $name The name of the model. - * @param string $prefix The prefix for the PHP class name. - * @param array $config Array of configuration parameters. - * - * @return JModelLegacy - * - * @since 1.6 - */ - public function getModel($name = 'Contact', $prefix = 'ContactModel', $config = array('ignore_request' => true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_contact/dispatcher.php b/administrator/components/com_contact/dispatcher.php new file mode 100644 index 0000000000000..91ce5b815030e --- /dev/null +++ b/administrator/components/com_contact/dispatcher.php @@ -0,0 +1,29 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ + + + + + + + + + +
+
+ + + + + diff --git a/administrator/components/com_contact/models/forms/fields/mail.xml b/administrator/components/com_contact/forms/fields/mail.xml similarity index 100% rename from administrator/components/com_contact/models/forms/fields/mail.xml rename to administrator/components/com_contact/forms/fields/mail.xml diff --git a/administrator/components/com_contact/forms/filter_contacts.xml b/administrator/components/com_contact/forms/filter_contacts.xml new file mode 100644 index 0000000000000..48bc197557738 --- /dev/null +++ b/administrator/components/com_contact/forms/filter_contacts.xml @@ -0,0 +1,119 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_contact/helpers/associations.php b/administrator/components/com_contact/helpers/associations.php index be5ebdbede39e..8e817b49559e8 100644 --- a/administrator/components/com_contact/helpers/associations.php +++ b/administrator/components/com_contact/helpers/associations.php @@ -10,8 +10,8 @@ defined('_JEXEC') or die; use Joomla\CMS\Association\AssociationExtensionHelper; - -JTable::addIncludePath(__DIR__ . '/../tables'); +use Joomla\CMS\Language\Associations; +use Joomla\CMS\Table\Table; /** * Content associations helper. @@ -47,6 +47,21 @@ class ContactAssociationsHelper extends AssociationExtensionHelper */ protected $associationsSupport = true; + /** + * Method to get the associations for a given item. + * + * @param integer $id Id of the item + * @param string $view Name of the view + * + * @return array Array of associations for the item + * + * @since 4.0.0 + */ + public function getAssociationsForItem($id = 0, $view = null) + { + return \ContactHelperAssociation::getAssociations($id, $view); + } + /** * Get the associated items for an item * @@ -71,7 +86,7 @@ public function getAssociations($typeName, $id) } // Get the associations. - $associations = JLanguageAssociations::getAssociations( + $associations = Associations::getAssociations( $this->extension, $type['tables']['a'], $context, @@ -90,7 +105,7 @@ public function getAssociations($typeName, $id) * @param string $typeName The item type * @param int $id The id of item for which we need the associated items * - * @return JTable|null + * @return Table|null * * @since 3.7.0 */ @@ -106,11 +121,11 @@ public function getItem($typeName, $id) switch ($typeName) { case 'contact': - $table = JTable::getInstance('Contact', 'ContactTable'); + $table = Table::getInstance('ContactTable', 'Joomla\\Component\\Contact\\Administrator\\Table\\'); break; case 'category': - $table = JTable::getInstance('Category'); + $table = Table::getInstance('Category'); break; } diff --git a/administrator/components/com_contact/helpers/contact.php b/administrator/components/com_contact/helpers/contact.php index fd345ef6dd42f..22a62db7780ad 100644 --- a/administrator/components/com_contact/helpers/contact.php +++ b/administrator/components/com_contact/helpers/contact.php @@ -14,223 +14,7 @@ * * @since 1.6 */ -class ContactHelper extends JHelperContent +class ContactHelper extends \Joomla\Component\Contact\Administrator\Helper\ContactHelper { - /** - * Configure the Linkbar. - * - * @param string $vName The name of the active view. - * - * @return void - * - * @since 1.6 - */ - public static function addSubmenu($vName) - { - JHtmlSidebar::addEntry( - JText::_('COM_CONTACT_SUBMENU_CONTACTS'), - 'index.php?option=com_contact&view=contacts', - $vName == 'contacts' - ); - JHtmlSidebar::addEntry( - JText::_('COM_CONTACT_SUBMENU_CATEGORIES'), - 'index.php?option=com_categories&extension=com_contact', - $vName == 'categories' - ); - - if (JComponentHelper::isEnabled('com_fields') && JComponentHelper::getParams('com_contact')->get('custom_fields_enable', '1')) - { - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_FIELDS'), - 'index.php?option=com_fields&context=com_contact.contact', - $vName == 'fields.fields' - ); - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_FIELD_GROUPS'), - 'index.php?option=com_fields&view=groups&context=com_contact.contact', - $vName == 'fields.groups' - ); - } - } - - /** - * Adds Count Items for Category Manager. - * - * @param stdClass[] &$items The contact category objects - * - * @return stdClass[] - * - * @since 3.5 - */ - 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; - } - } - } - - 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(); - $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; - } - } - } - - return $items; - } - - /** - * Returns a valid section for contacts. If it is not valid then null - * is returned. - * - * @param string $section The section to get the mapping for - * @param object $item optional item object - * - * @return string|null The new section - * - * @since 3.7.0 - */ - public static function validateSection($section, $item) - { - if (JFactory::getApplication()->isClient('site') && $section == 'contact' && $item instanceof JForm) - { - // The contact form needs to be the mail section - $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 - return null; - } - - return $section; - } - - /** - * Returns valid contexts - * - * @return array - * - * @since 3.7.0 - */ - public static function getContexts() - { - JFactory::getLanguage()->load('com_contact', JPATH_ADMINISTRATOR); - - $contexts = array( - 'com_contact.contact' => JText::_('COM_CONTACT_FIELDS_CONTEXT_CONTACT'), - 'com_contact.mail' => JText::_('COM_CONTACT_FIELDS_CONTEXT_MAIL'), - 'com_contact.categories' => JText::_('JCATEGORY') - ); - - return $contexts; - } } diff --git a/administrator/components/com_contact/helpers/html/contact.php b/administrator/components/com_contact/helpers/html/contact.php index 4e0915975a595..a3aeaa698d627 100644 --- a/administrator/components/com_contact/helpers/html/contact.php +++ b/administrator/components/com_contact/helpers/html/contact.php @@ -10,6 +10,12 @@ defined('_JEXEC') or die; use Joomla\Utilities\ArrayHelper; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; +use Joomla\CMS\Layout\LayoutHelper; +use Joomla\CMS\Language\Associations; +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; JLoader::register('ContactHelper', JPATH_ADMINISTRATOR . '/components/com_contact/helpers/contact.php'); @@ -35,7 +41,7 @@ public static function association($contactid) $html = ''; // Get the associations - if ($associations = JLanguageAssociations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', $contactid)) + if ($associations = Associations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', $contactid)) { foreach ($associations as $tag => $associated) { @@ -43,7 +49,7 @@ public static function association($contactid) } // Get the associated contact items - $db = JFactory::getDbo(); + $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('c.id, c.name as title') ->select('l.sef as lang_sef, lang_code') @@ -71,10 +77,9 @@ public static function association($contactid) foreach ($items as &$item) { $text = strtoupper($item->lang_sef); - $url = JRoute::_('index.php?option=com_contact&task=contact.edit&id=' . (int) $item->id); - - $tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '
' . JText::sprintf('JCATEGORY_SPRINTF', $item->category_title); - $classes = 'hasPopover label label-association label-' . $item->lang_sef; + $url = Route::_('index.php?option=com_contact&task=contact.edit&id=' . (int) $item->id); + $tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '
' . Text::sprintf('JCATEGORY_SPRINTF', $item->category_title); + $classes = 'hasPopover badge badge-secondary'; $item->link = '' @@ -82,9 +87,9 @@ public static function association($contactid) } } - JHtml::_('bootstrap.popover'); + HTMLHelper::_('bootstrap.popover'); - $html = JLayoutHelper::render('joomla.content.associations', $items); + $html = LayoutHelper::render('joomla.content.associations', $items); } return $html; @@ -114,14 +119,14 @@ public static function featured($value = 0, $i, $canChange = true) if ($canChange) { - $html = ''; } else { - $html = ''; + $html = ''; } return $html; diff --git a/administrator/components/com_contact/models/contact.php b/administrator/components/com_contact/models/contact.php deleted file mode 100644 index d279e57dd548e..0000000000000 --- a/administrator/components/com_contact/models/contact.php +++ /dev/null @@ -1,663 +0,0 @@ - 'batchAccess', - 'language_id' => 'batchLanguage', - 'tag' => 'batchTag', - '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. - * - * @param integer $value The new value matching a User ID. - * @param array $pks An array of row IDs. - * @param array $contexts An array of item contexts. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 2.5 - */ - protected function batchUser($value, $pks, $contexts) - { - foreach ($pks as $pk) - { - if ($this->user->authorise('core.edit', $contexts[$pk])) - { - $this->table->reset(); - $this->table->load($pk); - $this->table->user_id = (int) $value; - - $this->createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table); - - if (!$this->table->store()) - { - $this->setError($this->table->getError()); - - return false; - } - } - else - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); - - return false; - } - } - - // Clean the cache - $this->cleanCache(); - - return true; - } - - /** - * Method to test whether a record can be deleted. - * - * @param object $record A record object. - * - * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. - * - * @since 1.6 - */ - protected function canDelete($record) - { - if (!empty($record->id)) - { - if ($record->published != -2) - { - return false; - } - - return JFactory::getUser()->authorise('core.delete', 'com_contact.category.' . (int) $record->catid); - } - } - - /** - * 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) - { - // Check against the category. - if (!empty($record->catid)) - { - return JFactory::getUser()->authorise('core.edit.state', 'com_contact.category.' . (int) $record->catid); - } - - // Default to component settings if category not known. - return parent::canEditState($record); - } - - /** - * Returns a Table object, always creating it - * - * @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 - * - * @since 1.6 - */ - public function getTable($type = 'Contact', $prefix = 'ContactTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Method to get the row form. - * - * @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 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - 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)); - - if (empty($form)) - { - return false; - } - - // Modify the form based on access controls. - if (!$this->canEditState((object) $data)) - { - // Disable fields for display. - $form->setFieldAttribute('featured', 'disabled', 'true'); - $form->setFieldAttribute('ordering', 'disabled', 'true'); - $form->setFieldAttribute('published', 'disabled', 'true'); - - // Disable fields while saving. - // The controller has already verified this is a record you can edit. - $form->setFieldAttribute('featured', 'filter', 'unset'); - $form->setFieldAttribute('ordering', 'filter', 'unset'); - $form->setFieldAttribute('published', 'filter', 'unset'); - } - - return $form; - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - * - * @since 1.6 - */ - public function getItem($pk = null) - { - if ($item = parent::getItem($pk)) - { - // Convert the metadata field to an array. - $registry = new Registry($item->metadata); - $item->metadata = $registry->toArray(); - } - - // Load associated contact items - $assoc = JLanguageAssociations::isEnabled(); - - if ($assoc) - { - $item->associations = array(); - - if ($item->id != null) - { - $associations = JLanguageAssociations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', $item->id); - - foreach ($associations as $tag => $association) - { - $item->associations[$tag] = $association->id; - } - } - } - - // Load item tags - if (!empty($item->id)) - { - $item->tags = new JHelperTags; - $item->tags->getTagIds($item->id, 'com_contact.contact'); - } - - return $item; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - $app = JFactory::getApplication(); - - // Check the session for previously entered form data. - $data = $app->getUserState('com_contact.edit.contact.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - - // Prime some default values. - if ($this->getState('contact.id') == 0) - { - $data->set('catid', $app->input->get('catid', $app->getUserState('com_contact.contacts.filter.category_id'), 'int')); - } - } - - $this->preprocessData('com_contact.contact', $data); - - return $data; - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 3.0 - */ - public function save($data) - { - $input = JFactory::getApplication()->input; - - JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - - // Cast catid to integer for comparison - $catid = (int) $data['catid']; - - // Check if New Category exists - if ($catid > 0) - { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_contact'); - } - - // Save New Category - if ($catid == 0 && $this->canCreateCategory()) - { - $table = array(); - $table['title'] = $data['catid']; - $table['parent_id'] = 1; - $table['extension'] = 'com_contact'; - $table['language'] = $data['language']; - $table['published'] = 1; - - // Create new category and get catid back - $data['catid'] = CategoriesHelper::createCategory($table); - } - - // Alter the name for save as copy - if ($input->get('task') == 'save2copy') - { - $origTable = clone $this->getTable(); - $origTable->load($input->getInt('id')); - - if ($data['name'] == $origTable->name) - { - list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']); - $data['name'] = $name; - $data['alias'] = $alias; - } - else - { - if ($data['alias'] == $origTable->alias) - { - $data['alias'] = ''; - } - } - - $data['published'] = 0; - } - - $links = array('linka', 'linkb', 'linkc', 'linkd', 'linke'); - - foreach ($links as $link) - { - if ($data['params'][$link]) - { - $data['params'][$link] = JStringPunycode::urlToPunycode($data['params'][$link]); - } - } - - return parent::save($data); - } - - /** - * Prepare and sanitise the table prior to saving. - * - * @param JTable $table The JTable object - * - * @return void - * - * @since 1.6 - */ - protected function prepareTable($table) - { - $date = JFactory::getDate()->toSql(); - - $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); - - $table->generateAlias(); - - if (empty($table->id)) - { - // Set the values - $table->created = $date; - - // Set ordering to the last item if not set - if (empty($table->ordering)) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('MAX(ordering)') - ->from($db->quoteName('#__contact_details')); - $db->setQuery($query); - $max = $db->loadResult(); - - $table->ordering = $max + 1; - } - } - else - { - // Set the values - $table->modified = $date; - $table->modified_by = JFactory::getUser()->id; - } - - // Increment the content version number. - $table->version++; - } - - /** - * A protected method to get a set of ordering conditions. - * - * @param JTable $table A record object. - * - * @return array An array of conditions to add to add to ordering queries. - * - * @since 1.6 - */ - protected function getReorderConditions($table) - { - return array('catid = ' . (int) $table->catid); - } - - /** - * Preprocess the form. - * - * @param JForm $form Form object. - * @param object $data Data object. - * @param string $group Group name. - * - * @return void - * - * @since 3.0.3 - */ - protected function preprocessForm(JForm $form, $data, $group = 'content') - { - // Determine correct permissions to check. - if ($this->getState('contact.id')) - { - // Existing record. Can only edit in selected categories. - $form->setFieldAttribute('catid', 'action', 'core.edit'); - } - else - { - // New record. Can only create in selected categories. - $form->setFieldAttribute('catid', 'action', 'core.create'); - } - - if ($this->canCreateCategory()) - { - $form->setFieldAttribute('catid', 'allowAdd', 'true'); - } - - // Association contact items - if (JLanguageAssociations::isEnabled()) - { - $languages = JLanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc'); - - if (count($languages) > 1) - { - $addform = new SimpleXMLElement('
'); - $fields = $addform->addChild('fields'); - $fields->addAttribute('name', 'associations'); - $fieldset = $fields->addChild('fieldset'); - $fieldset->addAttribute('name', 'item_associations'); - - foreach ($languages as $language) - { - $field = $fieldset->addChild('field'); - $field->addAttribute('name', $language->lang_code); - $field->addAttribute('type', 'modal_contact'); - $field->addAttribute('language', $language->lang_code); - $field->addAttribute('label', $language->title); - $field->addAttribute('translate_label', 'false'); - $field->addAttribute('select', 'true'); - $field->addAttribute('new', 'true'); - $field->addAttribute('edit', 'true'); - $field->addAttribute('clear', 'true'); - } - - $form->load($addform, false); - } - } - - parent::preprocessForm($form, $data, $group); - } - - /** - * Method to toggle the featured setting of contacts. - * - * @param array $pks The ids of the items to toggle. - * @param integer $value The value to toggle to. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function featured($pks, $value = 0) - { - // Sanitize the ids. - $pks = ArrayHelper::toInteger((array) $pks); - - if (empty($pks)) - { - $this->setError(JText::_('COM_CONTACT_NO_ITEM_SELECTED')); - - return false; - } - - $table = $this->getTable(); - - try - { - $db = $this->getDbo(); - - $query = $db->getQuery(true); - $query->update('#__contact_details'); - $query->set('featured = ' . (int) $value); - $query->where('id IN (' . implode(',', $pks) . ')'); - $db->setQuery($query); - - $db->execute(); - } - catch (Exception $e) - { - $this->setError($e->getMessage()); - - return false; - } - - $table->reorder(); - - // Clean component's cache - $this->cleanCache(); - - return true; - } - - /** - * 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. - * - * @return array Contains the modified title and alias. - * - * @since 3.1 - */ - protected function generateNewTitle($category_id, $alias, $name) - { - // 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); - } - - /** - * Is the user allowed to create an on the fly category? - * - * @return boolean - * - * @since 3.6.1 - */ - private function canCreateCategory() - { - return JFactory::getUser()->authorise('core.create', 'com_contact'); - } -} diff --git a/administrator/components/com_contact/models/contacts.php b/administrator/components/com_contact/models/contacts.php deleted file mode 100644 index 287f732c55110..0000000000000 --- a/administrator/components/com_contact/models/contacts.php +++ /dev/null @@ -1,353 +0,0 @@ -input->get('forcedLanguage', '', 'cmd'); - - // Adjust the context to support modal layouts. - if ($layout = $app->input->get('layout')) - { - $this->context .= '.' . $layout; - } - - // Adjust the context to support forced languages. - if ($forcedLanguage) - { - $this->context .= '.' . $forcedLanguage; - } - - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.published', $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string')); - $this->setState('filter.category_id', - $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', '', 'string') - ); - $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'cmd')); - $this->setState('filter.language', $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', '', 'string')); - $this->setState('filter.tag', $this->getUserStateFromRequest($this->context . '.filter.tag', 'filter_tag', '', 'string')); - $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', null, 'int')); - - // List state information. - parent::populateState($ordering, $direction); - - // Force a language. - if (!empty($forcedLanguage)) - { - $this->setState('filter.language', $forcedLanguage); - } - } - - /** - * 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 A store id. - * - * @since 1.6 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.published'); - $id .= ':' . serialize($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'); - - return parent::getStoreId($id); - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - * - * @since 1.6 - */ - protected function getListQuery() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - $user = JFactory::getUser(); - - // Select the required fields from the table. - $query->select( - $db->quoteName( - explode(', ', $this->getState( - 'list.select', - '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' - ) - ) - ) - ); - $query->from($db->quoteName('#__contact_details', 'a')); - - // Join over the users for the linked user. - $query->select( - array( - $db->quoteName('ul.name', 'linked_user'), - $db->quoteName('ul.email') - ) - ) - ->join( - 'LEFT', - $db->quoteName('#__users', 'ul') . ' ON ' . $db->quoteName('ul.id') . ' = ' . $db->quoteName('a.user_id') - ); - - // Join over the language - $query->select($db->quoteName('l.title', 'language_title')) - ->select($db->quoteName('l.image', 'language_image')) - ->join( - 'LEFT', - $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.language') - ); - - // Join over the users for the checked out user. - $query->select($db->quoteName('uc.name', 'editor')) - ->join( - 'LEFT', - $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out') - ); - - // Join over the asset groups. - $query->select($db->quoteName('ag.title', 'access_level')) - ->join( - 'LEFT', - $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access') - ); - - // Join over the categories. - $query->select($db->quoteName('c.title', 'category_title')) - ->join( - 'LEFT', - $db->quoteName('#__categories', 'c') . ' ON ' . $db->quoteName('c.id') . ' = ' . $db->quoteName('a.catid') - ); - - // Join over the associations. - $assoc = JLanguageAssociations::isEnabled(); - - 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' - ) - ) - ); - } - - // Filter by access level. - if ($access = $this->getState('filter.access')) - { - $query->where($db->quoteName('a.access') . ' = ' . (int) $access); - } - - // Implement View Level Access - if (!$user->authorise('core.admin')) - { - $groups = implode(',', $user->getAuthorisedViewLevels()); - $query->where($db->quoteName('a.access') . ' IN (' . $groups . ')'); - } - - // Filter by published state - $published = $this->getState('filter.published'); - - if (is_numeric($published)) - { - $query->where($db->quoteName('a.published') . ' = ' . (int) $published); - } - elseif ($published === '') - { - $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'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where( - '(' . $db->quoteName('a.name') . ' LIKE ' . $search . ' OR ' . $db->quoteName('a.alias') . ' LIKE ' . $search . ')' - ); - } - } - - // Filter on the language. - if ($language = $this->getState('filter.language')) - { - $query->where($db->quoteName('a.language') . ' = ' . $db->quote($language)); - } - - // Filter by a single tag. - $tagId = $this->getState('filter.tag'); - - if (is_numeric($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_contact.contact') - ); - } - - // Filter on the level. - if ($level = $this->getState('filter.level')) - { - $query->where('c.level <= ' . (int) $level); - } - - // Add the list ordering clause. - $orderCol = $this->state->get('list.ordering', 'a.name'); - $orderDirn = $this->state->get('list.direction', 'asc'); - - if ($orderCol == 'a.ordering' || $orderCol == 'category_title') - { - $orderCol = $db->quoteName('c.title') . ' ' . $orderDirn . ', ' . $db->quoteName('a.ordering'); - } - - $query->order($db->escape($orderCol . ' ' . $orderDirn)); - - return $query; - } -} diff --git a/administrator/components/com_contact/models/fields/modal/contact.php b/administrator/components/com_contact/models/fields/modal/contact.php deleted file mode 100644 index e03511d6855c3..0000000000000 --- a/administrator/components/com_contact/models/fields/modal/contact.php +++ /dev/null @@ -1,275 +0,0 @@ -element['new'] == 'true'); - $allowEdit = ((string) $this->element['edit'] == 'true'); - $allowClear = ((string) $this->element['clear'] != 'false'); - $allowSelect = ((string) $this->element['select'] != 'false'); - - // Load language - JFactory::getLanguage()->load('com_contact', JPATH_ADMINISTRATOR); - - // The active contact id field. - $value = (int) $this->value > 0 ? (int) $this->value : ''; - - // Create the modal id. - $modalId = 'Contact_' . $this->id; - - // Add the modal field script to the document head. - JHtml::_('jquery.framework'); - JHtml::_('script', 'system/modal-fields.js', array('version' => 'auto', 'relative' => true)); - - // Script to proxy the select modal function to the modal-fields.js file. - if ($allowSelect) - { - static $scriptSelect = null; - - if (is_null($scriptSelect)) - { - $scriptSelect = array(); - } - - if (!isset($scriptSelect[$this->id])) - { - JFactory::getDocument()->addScriptDeclaration(" - function jSelectContact_" . $this->id . "(id, title, object) { - window.processModalSelect('Contact', '" . $this->id . "', id, title, '', object); - } - "); - - $scriptSelect[$this->id] = true; - } - } - - // Setup variables for display. - $linkContacts = 'index.php?option=com_contact&view=contacts&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; - $linkContact = 'index.php?option=com_contact&view=contact&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; - $modalTitle = JText::_('COM_CONTACT_CHANGE_CONTACT'); - - if (isset($this->element['language'])) - { - $linkContacts .= '&forcedLanguage=' . $this->element['language']; - $linkContact .= '&forcedLanguage=' . $this->element['language']; - $modalTitle .= ' — ' . $this->element['label']; - } - - $urlSelect = $linkContacts . '&function=jSelectContact_' . $this->id; - $urlEdit = $linkContact . '&task=contact.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \''; - $urlNew = $linkContact . '&task=contact.add'; - - if ($value) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('name')) - ->from($db->quoteName('#__contact_details')) - ->where($db->quoteName('id') . ' = ' . (int) $value); - $db->setQuery($query); - - try - { - $title = $db->loadResult(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - } - - $title = empty($title) ? JText::_('COM_CONTACT_SELECT_A_CONTACT') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); - - // The current contact display field. - $html = ''; - $html .= ''; - - // 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') - . ''; - } - - $html .= ''; - - // Select contact modal - if ($allowSelect) - { - $html .= JHtml::_( - 'bootstrap.renderModal', - 'ModalSelect' . $modalId, - array( - 'title' => $modalTitle, - 'url' => $urlSelect, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '', - ) - ); - } - - // New contact modal - if ($allowNew) - { - $html .= JHtml::_( - 'bootstrap.renderModal', - 'ModalNew' . $modalId, - array( - 'title' => JText::_('COM_CONTACT_NEW_CONTACT'), - 'backdrop' => 'static', - 'keyboard' => false, - 'closeButton' => false, - 'url' => $urlNew, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '' - . '' - . '', - ) - ); - } - - // Edit contact modal. - if ($allowEdit) - { - $html .= JHtml::_( - 'bootstrap.renderModal', - 'ModalEdit' . $modalId, - array( - 'title' => JText::_('COM_CONTACT_EDIT_CONTACT'), - 'backdrop' => 'static', - 'keyboard' => false, - 'closeButton' => false, - 'url' => $urlEdit, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '' - . '' - . '', - ) - ); - } - - // Note: class='required' for client side validation. - $class = $this->required ? ' class="required modal-value"' : ''; - - $html .= ''; - - return $html; - } - - /** - * Method to get the field label markup. - * - * @return string The field label markup. - * - * @since 3.4 - */ - protected function getLabel() - { - return str_replace($this->id, $this->id . '_id', parent::getLabel()); - } -} diff --git a/administrator/components/com_contact/models/forms/contact.xml b/administrator/components/com_contact/models/forms/contact.xml deleted file mode 100644 index 3146bfcc9df4b..0000000000000 --- a/administrator/components/com_contact/models/forms/contact.xml +++ /dev/null @@ -1,1005 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - -
- - - - - - - - - - -
-
- - - - - diff --git a/administrator/components/com_contact/models/forms/filter_contacts.xml b/administrator/components/com_contact/models/forms/filter_contacts.xml deleted file mode 100644 index 60c8ad7d62d73..0000000000000 --- a/administrator/components/com_contact/models/forms/filter_contacts.xml +++ /dev/null @@ -1,136 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/administrator/components/com_contact/tables/contact.php b/administrator/components/com_contact/tables/contact.php deleted file mode 100644 index 6b837e791f510..0000000000000 --- a/administrator/components/com_contact/tables/contact.php +++ /dev/null @@ -1,240 +0,0 @@ - 'com_contact.contact')); - JTableObserverContenthistory::createObserver($this, array('typeAlias' => 'com_contact.contact')); - } - - /** - * Stores a contact. - * - * @param boolean $updateNulls True to update fields even if they are null. - * - * @return boolean True on success, false on failure. - * - * @since 1.6 - */ - public function store($updateNulls = false) - { - // Transform the params field - if (is_array($this->params)) - { - $registry = new Registry($this->params); - $this->params = (string) $registry; - } - - $date = JFactory::getDate()->toSql(); - $userId = JFactory::getUser()->id; - - $this->modified = $date; - - if ($this->id) - { - // Existing item - $this->modified_by = $userId; - } - else - { - // New contact. A contact created and created_by field can be set by the user, - // so we don't touch either of these if they are set. - if (!(int) $this->created) - { - $this->created = $date; - } - - if (empty($this->created_by)) - { - $this->created_by = $userId; - } - } - - // Set publish_up to null date if not set - if (!$this->publish_up) - { - $this->publish_up = $this->_db->getNullDate(); - } - - // Set publish_down to null date if not set - if (!$this->publish_down) - { - $this->publish_down = $this->_db->getNullDate(); - } - - // Set xreference to empty string if not set - if (!$this->xreference) - { - $this->xreference = ''; - } - - // Store utf8 email as punycode - $this->email_to = JStringPunycode::emailToPunycode($this->email_to); - - // Convert IDN urls to punycode - $this->webpage = JStringPunycode::urlToPunycode($this->webpage); - - // Verify that the alias is unique - $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)) - { - $this->setError(JText::_('COM_CONTACT_ERROR_UNIQUE_ALIAS')); - - return false; - } - - return parent::store($updateNulls); - } - - /** - * Overloaded check function - * - * @return boolean True on success, false on failure - * - * @see JTable::check - * @since 1.5 - */ - public function check() - { - $this->default_con = (int) $this->default_con; - - if (JFilterInput::checkAttribute(array('href', $this->webpage))) - { - $this->setError(JText::_('COM_CONTACT_WARNING_PROVIDE_VALID_URL')); - - return false; - } - - // Check for valid name - if (trim($this->name) == '') - { - $this->setError(JText::_('COM_CONTACT_WARNING_PROVIDE_VALID_NAME')); - - return false; - } - - // Generate a valid alias - $this->generateAlias(); - - // Check for valid category - if (trim($this->catid) == '') - { - $this->setError(JText::_('COM_CONTACT_WARNING_CATEGORY')); - - return false; - } - - // Sanity check for user_id - if (!$this->user_id) - { - $this->user_id = 0; - } - - // Check the publish down date is not earlier than publish up. - if ((int) $this->publish_down > 0 && $this->publish_down < $this->publish_up) - { - $this->setError(JText::_('JGLOBAL_START_PUBLISH_AFTER_FINISH')); - - return false; - } - - /* - * Clean up keywords -- eliminate extra spaces between phrases - * and cr (\r) and lf (\n) characters from string. - * Only process if not empty. - */ - if (!empty($this->metakey)) - { - // Array of characters to remove. - $badCharacters = array("\n", "\r", "\"", '<', '>'); - - // Remove bad characters. - $afterClean = StringHelper::str_ireplace($badCharacters, '', $this->metakey); - - // Create array using commas as delimiter. - $keys = explode(',', $afterClean); - $cleanKeys = array(); - - foreach ($keys as $key) - { - // Ignore blank keywords. - if (trim($key)) - { - $cleanKeys[] = trim($key); - } - } - - // Put array back together delimited by ", " - $this->metakey = implode(', ', $cleanKeys); - } - - // Clean up description -- eliminate quotes and <> brackets - if (!empty($this->metadesc)) - { - // Only process if not empty - $badCharacters = array("\"", '<', '>'); - $this->metadesc = StringHelper::str_ireplace($badCharacters, '', $this->metadesc); - } - - return true; - } - - /** - * Generate a valid alias from title / date. - * Remains public to be able to check for duplicated alias before saving - * - * @return string - */ - public function generateAlias() - { - if (empty($this->alias)) - { - $this->alias = $this->name; - } - - $this->alias = JApplicationHelper::stringURLSafe($this->alias, $this->language); - - if (trim(str_replace('-', '', $this->alias)) == '') - { - $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); - } - - return $this->alias; - } -} diff --git a/administrator/components/com_contact/tmpl/contact/edit.php b/administrator/components/com_contact/tmpl/contact/edit.php new file mode 100644 index 0000000000000..084a772d22d60 --- /dev/null +++ b/administrator/components/com_contact/tmpl/contact/edit.php @@ -0,0 +1,118 @@ + 0 )); + +$app = Factory::getApplication(); +$input = $app->input; + +$assoc = Associations::isEnabled(); + +// Fieldsets to not automatically render by /layouts/joomla/edit/params.php +$this->ignore_fieldsets = array('details', 'item_associations', 'jmetadata'); +$this->useCoreUI = true; + +// In case of modal +$isModal = $input->get('layout') == 'modal' ? true : false; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; +?> + +
+ + + +
+ 'details')); ?> + + item->id) ? Text::_('COM_CONTACT_NEW_CONTACT') : Text::_('COM_CONTACT_EDIT_CONTACT')); ?> +
+
+
+
+ form->renderField('user_id'); ?> + form->renderField('image'); ?> + form->renderField('con_position'); ?> + form->renderField('email_to'); ?> + form->renderField('address'); ?> + form->renderField('suburb'); ?> + form->renderField('state'); ?> + form->renderField('postcode'); ?> + form->renderField('country'); ?> +
+
+ form->renderField('telephone'); ?> + form->renderField('mobile'); ?> + form->renderField('fax'); ?> + form->renderField('webpage'); ?> + form->renderField('sortname1'); ?> + form->renderField('sortname2'); ?> + form->renderField('sortname3'); ?> +
+
+
+
+
+
+ +
+
+
+
+ + + +
+
+ form->renderField('misc'); ?> +
+
+ + + + + +
+
+ +
+
+ +
+
+ + + + + loadTemplate('associations'); ?> + + + + + + +
+ + + +
diff --git a/administrator/components/com_contact/tmpl/contact/edit_associations.php b/administrator/components/com_contact/tmpl/contact/edit_associations.php new file mode 100644 index 0000000000000..6bbc7421ec05b --- /dev/null +++ b/administrator/components/com_contact/tmpl/contact/edit_associations.php @@ -0,0 +1,14 @@ +form->getFieldsets('params'); +foreach ($fieldSets as $name => $fieldSet) : + $paramstabs = 'params-' . $name; + echo HTMLHelper::_('bootstrap.addTab', 'myTab', $paramstabs, Text::_($fieldSet->label)); + + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '' . $this->escape(Text::_($fieldSet->description)) . ''; + endif; + ?> + form->getFieldset($name) as $field) : ?> +
+
label; ?>
+
input; ?>
+
+ + + diff --git a/administrator/components/com_contact/tmpl/contact/modal.php b/administrator/components/com_contact/tmpl/contact/modal.php new file mode 100644 index 0000000000000..a310090bd13af --- /dev/null +++ b/administrator/components/com_contact/tmpl/contact/modal.php @@ -0,0 +1,15 @@ + +
+ setLayout('edit'); ?> + loadTemplate(); ?> +
diff --git a/administrator/components/com_contact/tmpl/contact/modal_associations.php b/administrator/components/com_contact/tmpl/contact/modal_associations.php new file mode 100644 index 0000000000000..6bbc7421ec05b --- /dev/null +++ b/administrator/components/com_contact/tmpl/contact/modal_associations.php @@ -0,0 +1,14 @@ +form->getFieldsets('params'); +foreach ($fieldSets as $name => $fieldSet) : + $paramstabs = 'params-' . $name; + echo HTMLHelper::_('bootstrap.addTab', 'myTab', $paramstabs, Text::_($fieldSet->label)); + + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '' . $this->escape(Text::_($fieldSet->description)) . ''; + endif; + ?> + form->getFieldset($name) as $field) : ?> +
+
label; ?>
+
input; ?>
+
+ + + diff --git a/administrator/components/com_contact/tmpl/contacts/default.php b/administrator/components/com_contact/tmpl/contacts/default.php new file mode 100644 index 0000000000000..32219d6ff04e3 --- /dev/null +++ b/administrator/components/com_contact/tmpl/contacts/default.php @@ -0,0 +1,201 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; +$assoc = Associations::isEnabled(); + +if ($saveOrder && !empty($this->items)) +{ + $saveOrderingUrl = 'index.php?option=com_contact&task=contacts.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + + + + + + class="js-draggable" data-url="" data-direction="" data-nested="true"> + items); + foreach ($this->items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_contact.category.' . $item->catid); + $canEdit = $user->authorise('core.edit', 'com_contact.category.' . $item->catid); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canEditOwn = $user->authorise('core.edit.own', 'com_contact.category.' . $item->catid) && $item->created_by == $userId; + $canChange = $user->authorise('core.edit.state', 'com_contact.category.' . $item->catid) && $canCheckin; + + $item->cat_link = Route::_('index.php?option=com_categories&extension=com_contact&task=edit&type=other&id=' . $item->catid); + ?> + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + id); ?> + +
+ published, $i, 'contacts.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> + featured, $i, $canChange); ?> +
+
+
+ checked_out) : ?> + editor, $item->checked_out_time, 'contacts.', $canCheckin); ?> + + + checked_out ? '' : ''; ?> + + escape($item->name); ?> + + escape($item->name); ?> + + + escape($item->alias)); ?> + +
+ escape($item->category_title); ?> +
+
+
+ linked_user)) : ?> + linked_user; ?> +
email; ?>
+ +
+ access_level; ?> + + association) : ?> + id); ?> + + + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + authorise('core.create', 'com_contact') + && $user->authorise('core.edit', 'com_contact') + && $user->authorise('core.edit.state', 'com_contact')) : ?> + Text::_('COM_CONTACT_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_contact/tmpl/contacts/default_batch.php b/administrator/components/com_contact/tmpl/contacts/default_batch.php new file mode 100644 index 0000000000000..c8c4ef594f1ec --- /dev/null +++ b/administrator/components/com_contact/tmpl/contacts/default_batch.php @@ -0,0 +1,65 @@ +state->get('filter.published'); +?> +
-
@@ -385,7 +361,6 @@ name="captcha" type="plugins" label="COM_CONTENT_FIELD_CAPTCHA_LABEL" - description="COM_CONTENT_FIELD_CAPTCHA_DESC" folder="captcha" filter="cmd" useglobal="true" @@ -397,43 +372,39 @@ name="show_publishing_options" type="radio" label="COM_CONTENT_SHOW_PUBLISHING_OPTIONS_LABEL" - description="COM_CONTENT_SHOW_PUBLISHING_OPTIONS_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" > - + - + - + - + - + @@ -538,7 +503,6 @@ name="float_fulltext" type="list" label="COM_CONTENT_FLOAT_FULLTEXT_LABEL" - description="COM_CONTENT_FLOAT_DESC" showon="show_urls_images_backend:1[OR]show_urls_images_frontend:1" > @@ -555,10 +519,10 @@ > - + - - + - - + - - + - @@ -628,90 +587,83 @@ - - + - - + - - + - - + - - +
-
- - + - @@ -723,89 +675,81 @@ - - + - - + - - +
-
- - - - - @@ -813,17 +757,16 @@ - - @@ -836,30 +779,28 @@
-
- - + - @@ -869,23 +810,21 @@ - - + - @@ -894,61 +833,56 @@ - - - + - - + - - + - - +
@@ -958,12 +892,11 @@ label="COM_CONTENT_SHARED_LABEL" description="COM_CONTENT_SHARED_DESC" > - - @@ -972,11 +905,10 @@ - @@ -995,11 +927,10 @@ - @@ -1008,11 +939,10 @@ - @@ -1020,24 +950,22 @@ - - + - @@ -1047,29 +975,26 @@ -
- - + @@ -1082,50 +1007,46 @@ type="radio" label="JGLOBAL_FEED_SHOW_READMORE_LABEL" description="JGLOBAL_FEED_SHOW_READMORE_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="0" showon="show_feed_link:1[AND]feed_summary:0" > - + - - + + - + label="JGLOBAL_CUSTOM_FIELDS_ENABLE_LABEL" + class="switcher" + default="1" + > + - +
@@ -1135,7 +1056,6 @@ label="JCONFIG_PERMISSIONS_LABEL" description="JCONFIG_PERMISSIONS_DESC" > - authorise('core.manage', 'com_content')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -JLoader::register('ContentHelper', __DIR__ . '/helpers/content.php'); - -$controller = JControllerLegacy::getInstance('Content'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_content/content.xml b/administrator/components/com_content/content.xml index 2e07450a236cc..41d77f42fa2cb 100644 --- a/administrator/components/com_content/content.xml +++ b/administrator/components/com_content/content.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 COM_CONTENT_XML_DESCRIPTION + Joomla\Component\Content content.php controller.php diff --git a/administrator/components/com_content/controller.php b/administrator/components/com_content/controller.php deleted file mode 100644 index cead07fb6cd95..0000000000000 --- a/administrator/components/com_content/controller.php +++ /dev/null @@ -1,56 +0,0 @@ -input->get('view', 'articles'); - $layout = $this->input->get('layout', 'articles'); - $id = $this->input->getInt('id'); - - // Check for edit form. - if ($view == 'article' && $layout == 'edit' && !$this->checkEditId('com_content.edit.article', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_content&view=articles', false)); - - return false; - } - - return parent::display(); - } -} diff --git a/administrator/components/com_content/controllers/article.php b/administrator/components/com_content/controllers/article.php deleted file mode 100644 index 1a504d40d1896..0000000000000 --- a/administrator/components/com_content/controllers/article.php +++ /dev/null @@ -1,137 +0,0 @@ -input->get('return') == 'featured') - { - $this->view_list = 'featured'; - $this->view_item = 'article&return=featured'; - } - } - - /** - * Method override to check if you can add a new record. - * - * @param array $data An array of input data. - * - * @return boolean - * - * @since 1.6 - */ - protected function allowAdd($data = array()) - { - $categoryId = ArrayHelper::getValue($data, 'catid', $this->input->getInt('filter_category_id'), 'int'); - $allow = null; - - if ($categoryId) - { - // If the category has been passed in the data or URL check it. - $allow = JFactory::getUser()->authorise('core.create', 'com_content.category.' . $categoryId); - } - - if ($allow === null) - { - // In the absense of better information, revert to the component permissions. - return parent::allowAdd(); - } - - return $allow; - } - - /** - * Method override to check if you can edit an existing record. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. - * - * @return boolean - * - * @since 1.6 - */ - protected function allowEdit($data = array(), $key = 'id') - { - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; - $user = JFactory::getUser(); - - // 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_content.article.' . $recordId)) - { - return true; - } - - // Check edit own on the record asset (explicit or inherited) - if ($user->authorise('core.edit.own', 'com_content.article.' . $recordId)) - { - // Existing record already has an owner, get it - $record = $this->getModel()->getItem($recordId); - - if (empty($record)) - { - return false; - } - - // Grant if current user is owner of the record - return $user->id == $record->created_by; - } - - return false; - } - - /** - * Method to run batch operations. - * - * @param object $model The model. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 1.6 - */ - public function batch($model = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Set the model - /** @var ContentModelArticle $model */ - $model = $this->getModel('Article', '', array()); - - // Preset the redirect - $this->setRedirect(JRoute::_('index.php?option=com_content&view=articles' . $this->getRedirectToListAppend(), false)); - - return parent::batch($model); - } -} diff --git a/administrator/components/com_content/controllers/articles.php b/administrator/components/com_content/controllers/articles.php deleted file mode 100644 index 85948486d7f20..0000000000000 --- a/administrator/components/com_content/controllers/articles.php +++ /dev/null @@ -1,125 +0,0 @@ -input->get('view') == 'featured') - { - $this->view_list = 'featured'; - } - - $this->registerTask('unfeatured', 'featured'); - } - - /** - * Method to toggle the featured setting of a list of articles. - * - * @return void - * - * @since 1.6 - */ - public function featured() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $user = JFactory::getUser(); - $ids = $this->input->get('cid', array(), 'array'); - $values = array('featured' => 1, 'unfeatured' => 0); - $task = $this->getTask(); - $value = ArrayHelper::getValue($values, $task, 0, 'int'); - - // Access checks. - foreach ($ids as $i => $id) - { - if (!$user->authorise('core.edit.state', 'com_content.article.' . (int) $id)) - { - // Prune items that you can't change. - unset($ids[$i]); - JError::raiseNotice(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - } - } - - if (empty($ids)) - { - JError::raiseWarning(500, JText::_('JERROR_NO_ITEMS_SELECTED')); - } - else - { - // Get the model. - /** @var ContentModelArticle $model */ - $model = $this->getModel(); - - // Publish the items. - if (!$model->featured($ids, $value)) - { - JError::raiseWarning(500, $model->getError()); - } - - if ($value == 1) - { - $message = JText::plural('COM_CONTENT_N_ITEMS_FEATURED', count($ids)); - } - else - { - $message = JText::plural('COM_CONTENT_N_ITEMS_UNFEATURED', count($ids)); - } - } - - $view = $this->input->get('view', ''); - - if ($view == 'featured') - { - $this->setRedirect(JRoute::_('index.php?option=com_content&view=featured', false), $message); - } - else - { - $this->setRedirect(JRoute::_('index.php?option=com_content&view=articles', false), $message); - } - } - - /** - * Proxy for getModel. - * - * @param string $name The model name. Optional. - * @param string $prefix The class prefix. Optional. - * @param array $config The array of possible config values. Optional. - * - * @return JModelLegacy - * - * @since 1.6 - */ - public function getModel($name = 'Article', $prefix = 'ContentModel', $config = array('ignore_request' => true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_content/controllers/featured.php b/administrator/components/com_content/controllers/featured.php deleted file mode 100644 index f5ffbbc144d21..0000000000000 --- a/administrator/components/com_content/controllers/featured.php +++ /dev/null @@ -1,96 +0,0 @@ -input->get('cid', array(), 'array'); - - // Access checks. - foreach ($ids as $i => $id) - { - if (!$user->authorise('core.delete', 'com_content.article.' . (int) $id)) - { - // Prune items that you can't delete. - unset($ids[$i]); - JError::raiseNotice(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); - } - } - - if (empty($ids)) - { - JError::raiseWarning(500, JText::_('JERROR_NO_ITEMS_SELECTED')); - } - else - { - // Get the model. - /** @var ContentModelFeature $model */ - $model = $this->getModel(); - - // Remove the items. - if (!$model->featured($ids, 0)) - { - JError::raiseWarning(500, $model->getError()); - } - } - - $this->setRedirect('index.php?option=com_content&view=featured'); - } - - /** - * Method to publish a list of articles. - * - * @return void - * - * @since 1.0 - */ - public function publish() - { - parent::publish(); - - $this->setRedirect('index.php?option=com_content&view=featured'); - } - - /** - * 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 The model. - * - * @since 1.6 - */ - public function getModel($name = 'Feature', $prefix = 'ContentModel', $config = array('ignore_request' => true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_content/forms/article.xml b/administrator/components/com_content/forms/article.xml new file mode 100644 index 0000000000000..5d3b4fee583c4 --- /dev/null +++ b/administrator/components/com_content/forms/article.xml @@ -0,0 +1,944 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + diff --git a/administrator/components/com_content/forms/category.xml b/administrator/components/com_content/forms/category.xml new file mode 100644 index 0000000000000..5bb6298bd221d --- /dev/null +++ b/administrator/components/com_content/forms/category.xml @@ -0,0 +1,23 @@ + +
+ +
+ +
+
+ +
diff --git a/administrator/components/com_content/forms/filter_articles.xml b/administrator/components/com_content/forms/filter_articles.xml new file mode 100644 index 0000000000000..464c95f1afc84 --- /dev/null +++ b/administrator/components/com_content/forms/filter_articles.xml @@ -0,0 +1,143 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_content/models/forms/filter_featured.xml b/administrator/components/com_content/forms/filter_featured.xml similarity index 76% rename from administrator/components/com_content/models/forms/filter_featured.xml rename to administrator/components/com_content/forms/filter_featured.xml index 79bbe00fa71c3..fcbf9c0ea0827 100644 --- a/administrator/components/com_content/models/forms/filter_featured.xml +++ b/administrator/components/com_content/forms/filter_featured.xml @@ -10,45 +10,37 @@ /> - + name="state" + type="workflowstage" + label="COM_CONTENT_STATES" + onchange="this.form.submit();" + activeonly="true" + > + + + + + - - - - @@ -80,21 +68,29 @@ + + + + @@ -115,8 +111,8 @@ - - + + @@ -132,8 +128,6 @@ getType($typeName); - - $context = $this->extension . '.item'; - $catidField = 'catid'; - - if ($typeName === 'category') - { - $context = 'com_categories.item'; - $catidField = ''; - } - - // Get the associations. - $associations = JLanguageAssociations::getAssociations( - $this->extension, - $type['tables']['a'], - $context, - $id, - 'id', - 'alias', - $catidField - ); - - return $associations; - } - - /** - * Get item information - * - * @param string $typeName The item type - * @param int $id The id of item for which we need the associated items - * - * @return JTable|null - * - * @since 3.7.0 - */ - public function getItem($typeName, $id) - { - if (empty($id)) - { - return null; - } - - $table = null; - - switch ($typeName) - { - case 'article': - $table = JTable::getInstance('Content'); - break; - - case 'category': - $table = JTable::getInstance('Category'); - break; - } - - if (is_null($table)) - { - return null; - } - - $table->load($id); - - return $table; - } - - /** - * Get information about the type - * - * @param string $typeName The item type - * - * @return array Array of item types - * - * @since 3.7.0 - */ - public function getType($typeName = '') - { - $fields = $this->getFieldsTemplate(); - $tables = array(); - $joins = array(); - $support = $this->getSupportTemplate(); - $title = ''; - - if (in_array($typeName, $this->itemTypes)) - { - switch ($typeName) - { - case 'article': - - $support['state'] = true; - $support['acl'] = true; - $support['checkout'] = true; - $support['category'] = true; - $support['save2copy'] = true; - - $tables = array( - 'a' => '#__content' - ); - - $title = 'article'; - break; - - case 'category': - $fields['created_user_id'] = 'a.created_user_id'; - $fields['ordering'] = 'a.lft'; - $fields['level'] = 'a.level'; - $fields['catid'] = ''; - $fields['state'] = 'a.published'; - - $support['state'] = true; - $support['acl'] = true; - $support['checkout'] = true; - $support['level'] = true; - - $tables = array( - 'a' => '#__categories' - ); - - $title = 'category'; - break; - } - } - - return array( - 'fields' => $fields, - 'support' => $support, - 'tables' => $tables, - 'joins' => $joins, - 'title' => $title - ); - } -} diff --git a/administrator/components/com_content/helpers/content.php b/administrator/components/com_content/helpers/content.php index 42b73b5b9ed7a..a4d4e43cdddb0 100644 --- a/administrator/components/com_content/helpers/content.php +++ b/administrator/components/com_content/helpers/content.php @@ -12,261 +12,10 @@ /** * Content component helper. * - * @since 1.6 + * @since 1.6 + * + * @deprecated 5.0 Use \Joomla\Component\Content\Administrator\Helper\ContentHelper instead */ -class ContentHelper extends JHelperContent +class ContentHelper extends \Joomla\Component\Content\Administrator\Helper\ContentHelper { - public static $extension = 'com_content'; - - /** - * Configure the Linkbar. - * - * @param string $vName The name of the active view. - * - * @return void - * - * @since 1.6 - */ - public static function addSubmenu($vName) - { - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_ARTICLES'), - 'index.php?option=com_content&view=articles', - $vName == 'articles' - ); - JHtmlSidebar::addEntry( - JText::_('COM_CONTENT_SUBMENU_CATEGORIES'), - 'index.php?option=com_categories&extension=com_content', - $vName == 'categories' - ); - - JHtmlSidebar::addEntry( - JText::_('COM_CONTENT_SUBMENU_FEATURED'), - 'index.php?option=com_content&view=featured', - $vName == 'featured' - ); - - if (JComponentHelper::isEnabled('com_fields') && JComponentHelper::getParams('com_content')->get('custom_fields_enable', '1')) - { - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_FIELDS'), - 'index.php?option=com_fields&context=com_content.article', - $vName == 'fields.fields' - ); - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_FIELD_GROUPS'), - 'index.php?option=com_fields&view=groups&context=com_content.article', - $vName == 'fields.groups' - ); - } - } - - /** - * Applies the content tag filters to arbitrary text as per settings for current user group - * - * @param text $text The string to filter - * - * @return string The filtered string - * - * @deprecated 4.0 Use JComponentHelper::filterText() instead. - */ - public static function filterText($text) - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use JComponentHelper::filterText() instead', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - return JComponentHelper::filterText($text); - } - - /** - * Adds Count Items for Category Manager. - * - * @param stdClass[] &$items The banner category objects - * - * @return stdClass[] - * - * @since 3.5 - */ - 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; - } - } - } - - return $items; - } - - /** - * Adds Count Items for Tag Manager. - * - * @param stdClass[] &$items The content objects - * @param string $extension The name of the active view. - * - * @return stdClass[] - * - * @since 3.6 - */ - 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; - } - } - } - - return $items; - } - - /** - * Returns a valid section for articles. If it is not valid then null - * is returned. - * - * @param string $section The section to get the mapping for - * - * @return string|null The new section - * - * @since 3.7.0 - */ - public static function validateSection($section) - { - if (JFactory::getApplication()->isClient('site')) - { - // On the front end we need to map some sections - switch ($section) - { - // Editing an article - case 'form': - - // Category list view - case 'featured': - case 'category': - $section = 'article'; - } - } - - if ($section != 'article') - { - // We don't know other sections - return null; - } - - return $section; - } - - /** - * Returns valid contexts - * - * @return array - * - * @since 3.7.0 - */ - public static function getContexts() - { - JFactory::getLanguage()->load('com_content', JPATH_ADMINISTRATOR); - - $contexts = array( - 'com_content.article' => JText::_('COM_CONTENT'), - 'com_content.categories' => JText::_('JCATEGORY') - ); - - return $contexts; - } } diff --git a/administrator/components/com_content/helpers/html/contentadministrator.php b/administrator/components/com_content/helpers/html/contentadministrator.php deleted file mode 100644 index 821c9d2d01da7..0000000000000 --- a/administrator/components/com_content/helpers/html/contentadministrator.php +++ /dev/null @@ -1,129 +0,0 @@ - $associated) - { - $associations[$tag] = (int) $associated->id; - } - - // Get the associated menu items - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('c.*') - ->select('l.sef as lang_sef') - ->select('l.lang_code') - ->from('#__content as c') - ->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'); - $db->setQuery($query); - - try - { - $items = $db->loadObjectList('id'); - } - catch (RuntimeException $e) - { - throw new Exception($e->getMessage(), 500, $e); - } - - if ($items) - { - foreach ($items as &$item) - { - $text = $item->lang_sef ? strtoupper($item->lang_sef) : 'XX'; - $url = JRoute::_('index.php?option=com_content&task=article.edit&id=' . (int) $item->id); - - $tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '
' . JText::sprintf('JCATEGORY_SPRINTF', $item->category_title); - $classes = 'hasPopover label label-association label-' . $item->lang_sef; - - $item->link = '' - . $text . ''; - } - } - - JHtml::_('bootstrap.popover'); - - $html = JLayoutHelper::render('joomla.content.associations', $items); - } - - return $html; - } - - /** - * Show the feature/unfeature links - * - * @param integer $value The state value - * @param integer $i Row number - * @param boolean $canChange Is user allowed to change? - * - * @return string HTML code - */ - public static function featured($value = 0, $i, $canChange = true) - { - JHtml::_('bootstrap.tooltip'); - - // Array of image, task, title, action - $states = array( - 0 => array('unfeatured', 'articles.featured', 'COM_CONTENT_UNFEATURED', 'JGLOBAL_TOGGLE_FEATURED'), - 1 => array('featured', 'articles.unfeatured', 'COM_CONTENT_FEATURED', 'JGLOBAL_TOGGLE_FEATURED'), - ); - $state = ArrayHelper::getValue($states, (int) $value, $states[1]); - $icon = $state[0]; - - if ($canChange) - { - $html = ''; - } - else - { - $html = ''; - } - - return $html; - } -} diff --git a/administrator/components/com_content/models/article.php b/administrator/components/com_content/models/article.php deleted file mode 100644 index 6d64bf25c1b63..0000000000000 --- a/administrator/components/com_content/models/article.php +++ /dev/null @@ -1,996 +0,0 @@ -checkCategoryId($categoryId)) - { - return false; - } - - JPluginHelper::importPlugin('system'); - $dispatcher = JEventDispatcher::getInstance(); - - // Register FieldsHelper - JLoader::register('FieldsHelper', JPATH_ADMINISTRATOR . '/components/com_fields/helpers/fields.php'); - - // 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; - } - } - - $fields = FieldsHelper::getFields('com_content.article', $this->table, true); - $fieldsData = array(); - - if (!empty($fields)) - { - $fieldsData['com_fields'] = array(); - - foreach ($fields as $field) - { - $fieldsData['com_fields'][$field->name] = $field->rawvalue; - } - } - - // 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; - - // Reset hits because we are making a copy - $this->table->hits = 0; - - // Unpublish because we are making a copy - $this->table->state = 0; - - // 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()) - { - $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; - - // 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 copied article - $dispatcher->trigger('onContentAfterSave', array('com_content.article', &$this->table, true, $fieldsData)); - } - - // Clean the cache - $this->cleanCache(); - - return $newIds; - } - - /** - * 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 boolean True on success. - * - * @since 3.8.6 - */ - protected function batchMove($value, $pks, $contexts) - { - 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); - } - - $categoryId = (int) $value; - - if (!$this->checkCategoryId($categoryId)) - { - return false; - } - - 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) - { - if (!$this->user->authorise('core.edit', $contexts[$pk])) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); - - return false; - } - - // 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; - } - } - - $fields = FieldsHelper::getFields('com_content.article', $this->table, true); - $fieldsData = array(); - - if (!empty($fields)) - { - $fieldsData['com_fields'] = array(); - - foreach ($fields as $field) - { - $fieldsData['com_fields'][$field->name] = $field->rawvalue; - } - } - - // Set the new category ID - $this->table->catid = $categoryId; - - // Check the row. - if (!$this->table->check()) - { - $this->setError($this->table->getError()); - - return false; - } - - if (!empty($this->type)) - { - $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; - } - - // Run event for moved article - $dispatcher->trigger('onContentAfterSave', array('com_content.article', &$this->table, false, $fieldsData)); - } - - // Clean the cache - $this->cleanCache(); - - return true; - } - - /** - * Method to test whether a record can be deleted. - * - * @param object $record A record object. - * - * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. - * - * @since 1.6 - */ - protected function canDelete($record) - { - if (!empty($record->id)) - { - if ($record->state != -2) - { - return false; - } - - return JFactory::getUser()->authorise('core.delete', 'com_content.article.' . (int) $record->id); - } - - return false; - } - - /** - * 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 for existing article. - if (!empty($record->id)) - { - return $user->authorise('core.edit.state', 'com_content.article.' . (int) $record->id); - } - - // New article, so check against the category. - if (!empty($record->catid)) - { - return $user->authorise('core.edit.state', 'com_content.category.' . (int) $record->catid); - } - - // Default to component settings if neither article nor category known. - return parent::canEditState($record); - } - - /** - * Prepare and sanitise the table data prior to saving. - * - * @param JTable $table A JTable object. - * - * @return void - * - * @since 1.6 - */ - protected function prepareTable($table) - { - // Set the publish date to now - if ($table->state == 1 && (int) $table->publish_up == 0) - { - $table->publish_up = JFactory::getDate()->toSql(); - } - - if ($table->state == 1 && intval($table->publish_down) == 0) - { - $table->publish_down = $this->getDbo()->getNullDate(); - } - - // Increment the content version number. - $table->version++; - - // Reorder the articles within the category so the new article is first - if (empty($table->id)) - { - $table->reorder('catid = ' . (int) $table->catid . ' AND state >= 0'); - } - } - - /** - * Returns a Table object, always creating it. - * - * @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 - */ - public function getTable($type = 'Content', $prefix = 'JTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - */ - public function getItem($pk = null) - { - if ($item = parent::getItem($pk)) - { - // Convert the params field to an array. - $registry = new Registry($item->attribs); - $item->attribs = $registry->toArray(); - - // Convert the metadata field to an array. - $registry = new Registry($item->metadata); - $item->metadata = $registry->toArray(); - - // Convert the images field to an array. - $registry = new Registry($item->images); - $item->images = $registry->toArray(); - - // Convert the urls field to an array. - $registry = new Registry($item->urls); - $item->urls = $registry->toArray(); - - $item->articletext = trim($item->fulltext) != '' ? $item->introtext . "
" . $item->fulltext : $item->introtext; - - if (!empty($item->id)) - { - $item->tags = new JHelperTags; - $item->tags->getTagIds($item->id, 'com_content.article'); - } - } - - // Load associated content items - $assoc = JLanguageAssociations::isEnabled(); - - if ($assoc) - { - $item->associations = array(); - - if ($item->id != null) - { - $associations = JLanguageAssociations::getAssociations('com_content', '#__content', 'com_content.item', $item->id); - - foreach ($associations as $tag => $association) - { - $item->associations[$tag] = $association->id; - } - } - } - - return $item; - } - - /** - * Method to get the record form. - * - * @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 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - // Get the form. - $form = $this->loadForm('com_content.article', 'article', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - $jinput = JFactory::getApplication()->input; - - /* - * 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)); - - // Determine correct permissions to check. - if ($this->getState('article.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'); - } - else - { - // New record. Can only create in selected categories. - $form->setFieldAttribute('catid', 'action', 'core.create'); - } - - $user = JFactory::getUser(); - - // 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'))) - { - // Disable fields for display. - $form->setFieldAttribute('featured', 'disabled', 'true'); - $form->setFieldAttribute('ordering', 'disabled', 'true'); - $form->setFieldAttribute('publish_up', 'disabled', 'true'); - $form->setFieldAttribute('publish_down', 'disabled', 'true'); - $form->setFieldAttribute('state', 'disabled', 'true'); - - // Disable fields while saving. - // The controller has already verified this is an article you can edit. - $form->setFieldAttribute('featured', 'filter', 'unset'); - $form->setFieldAttribute('ordering', 'filter', 'unset'); - $form->setFieldAttribute('publish_up', 'filter', 'unset'); - $form->setFieldAttribute('publish_down', 'filter', 'unset'); - $form->setFieldAttribute('state', 'filter', 'unset'); - } - - // Prevent messing with article language and category when editing existing article with associations - $app = JFactory::getApplication(); - $assoc = JLanguageAssociations::isEnabled(); - - // Check if article is associated - if ($this->getState('article.id') && $app->isClient('site') && $assoc) - { - $associations = JLanguageAssociations::getAssociations('com_content', '#__content', 'com_content.item', $id); - - // Make fields read only - if (!empty($associations)) - { - $form->setFieldAttribute('language', 'readonly', 'true'); - $form->setFieldAttribute('catid', 'readonly', 'true'); - $form->setFieldAttribute('language', 'filter', 'unset'); - $form->setFieldAttribute('catid', 'filter', 'unset'); - } - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $app = JFactory::getApplication(); - $data = $app->getUserState('com_content.edit.article.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - - // Pre-select some filters (Status, Category, Language, Access) in edit form if those have been selected in Article Manager: Articles - if ($this->getState('article.id') == 0) - { - $filters = (array) $app->getUserState('com_content.articles.filter'); - $data->set( - 'state', - $app->input->getInt( - 'state', - ((isset($filters['published']) && $filters['published'] !== '') ? $filters['published'] : null) - ) - ); - $data->set('catid', $app->input->getInt('catid', (!empty($filters['category_id']) ? $filters['category_id'] : null))); - $data->set('language', $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null))); - $data->set('access', - $app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access'))) - ); - } - } - - // If there are params fieldsets in the form it will fail with a registry object - if (isset($data->params) && $data->params instanceof Registry) - { - $data->params = $data->params->toArray(); - } - - $this->preprocessData('com_content.article', $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.7.0 - */ - 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 (isset($data['created_by'])) - { - unset($data['created_by']); - } - - if (isset($data['modified_by'])) - { - unset($data['modified_by']); - } - } - - return parent::validate($form, $data, $group); - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function save($data) - { - $input = JFactory::getApplication()->input; - $filter = JFilterInput::getInstance(); - - if (isset($data['metadata']) && isset($data['metadata']['author'])) - { - $data['metadata']['author'] = $filter->clean($data['metadata']['author'], 'TRIM'); - } - - if (isset($data['created_by_alias'])) - { - $data['created_by_alias'] = $filter->clean($data['created_by_alias'], 'TRIM'); - } - - if (isset($data['images']) && is_array($data['images'])) - { - $registry = new Registry($data['images']); - - $data['images'] = (string) $registry; - } - - JLoader::register('CategoriesHelper', JPATH_ADMINISTRATOR . '/components/com_categories/helpers/categories.php'); - - // Cast catid to integer for comparison - $catid = (int) $data['catid']; - - // Check if New Category exists - if ($catid > 0) - { - $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_content'); - } - - // Save New Category - if ($catid == 0 && $this->canCreateCategory()) - { - $table = array(); - $table['title'] = $data['catid']; - $table['parent_id'] = 1; - $table['extension'] = 'com_content'; - $table['language'] = $data['language']; - $table['published'] = 1; - - // Create new category and get catid back - $data['catid'] = CategoriesHelper::createCategory($table); - } - - if (isset($data['urls']) && is_array($data['urls'])) - { - $check = $input->post->get('jform', array(), 'array'); - - foreach ($data['urls'] as $i => $url) - { - if ($url != false && ($i == 'urla' || $i == 'urlb' || $i == 'urlc')) - { - if (preg_match('~^#[a-zA-Z]{1}[a-zA-Z0-9-_:.]*$~', $check['urls'][$i]) == 1) - { - $data['urls'][$i] = $check['urls'][$i]; - } - else - { - $data['urls'][$i] = JStringPunycode::urlToPunycode($url); - } - } - } - - unset($check); - - $registry = new Registry($data['urls']); - - $data['urls'] = (string) $registry; - } - - // Alter the title for save as copy - if ($input->get('task') == 'save2copy') - { - $origTable = clone $this->getTable(); - $origTable->load($input->getInt('id')); - - if ($data['title'] == $origTable->title) - { - list($title, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['title']); - $data['title'] = $title; - $data['alias'] = $alias; - } - else - { - if ($data['alias'] == $origTable->alias) - { - $data['alias'] = ''; - } - } - - $data['state'] = 0; - } - - // Automatic handling of alias for empty fields - if (in_array($input->get('task'), array('apply', 'save', 'save2new')) && (!isset($data['id']) || (int) $data['id'] == 0)) - { - if ($data['alias'] == null) - { - if (JFactory::getConfig()->get('unicodeslugs') == 1) - { - $data['alias'] = JFilterOutput::stringURLUnicodeSlug($data['title']); - } - else - { - $data['alias'] = JFilterOutput::stringURLSafe($data['title']); - } - - $table = JTable::getInstance('Content', 'JTable'); - - if ($table->load(array('alias' => $data['alias'], 'catid' => $data['catid']))) - { - $msg = JText::_('COM_CONTENT_SAVE_WARNING'); - } - - list($title, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['title']); - $data['alias'] = $alias; - - if (isset($msg)) - { - JFactory::getApplication()->enqueueMessage($msg, 'warning'); - } - } - } - - if (parent::save($data)) - { - if (isset($data['featured'])) - { - $this->featured($this->getState($this->getName() . '.id'), $data['featured']); - } - - return true; - } - - return false; - } - - /** - * Method to toggle the featured setting of articles. - * - * @param array $pks The ids of the items to toggle. - * @param integer $value The value to toggle to. - * - * @return boolean True on success. - */ - public function featured($pks, $value = 0) - { - // Sanitize the ids. - $pks = (array) $pks; - $pks = ArrayHelper::toInteger($pks); - - if (empty($pks)) - { - $this->setError(JText::_('COM_CONTENT_NO_ITEM_SELECTED')); - - return false; - } - - $table = $this->getTable('Featured', 'ContentTable'); - - try - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->update($db->quoteName('#__content')) - ->set('featured = ' . (int) $value) - ->where('id IN (' . implode(',', $pks) . ')'); - $db->setQuery($query); - $db->execute(); - - if ((int) $value == 0) - { - // Adjust the mapping table. - // Clear the existing features settings. - $query = $db->getQuery(true) - ->delete($db->quoteName('#__content_frontpage')) - ->where('content_id IN (' . implode(',', $pks) . ')'); - $db->setQuery($query); - $db->execute(); - } - else - { - // First, we find out which of our new featured articles are already featured. - $query = $db->getQuery(true) - ->select('f.content_id') - ->from('#__content_frontpage AS f') - ->where('content_id IN (' . implode(',', $pks) . ')'); - $db->setQuery($query); - - $oldFeatured = $db->loadColumn(); - - // We diff the arrays to get a list of the articles that are newly featured - $newFeatured = array_diff($pks, $oldFeatured); - - // Featuring. - $tuples = array(); - - foreach ($newFeatured as $pk) - { - $tuples[] = $pk . ', 0'; - } - - if (count($tuples)) - { - $columns = array('content_id', 'ordering'); - $query = $db->getQuery(true) - ->insert($db->quoteName('#__content_frontpage')) - ->columns($db->quoteName($columns)) - ->values($tuples); - $db->setQuery($query); - $db->execute(); - } - } - } - catch (Exception $e) - { - $this->setError($e->getMessage()); - - return false; - } - - $table->reorder(); - - $this->cleanCache(); - - return true; - } - - /** - * A protected method to get a set of ordering conditions. - * - * @param object $table A record object. - * - * @return array An array of conditions to add to add to ordering queries. - * - * @since 1.6 - */ - protected function getReorderConditions($table) - { - return array('catid = ' . (int) $table->catid); - } - - /** - * Allows preprocessing of the JForm object. - * - * @param JForm $form The form object - * @param array $data The data to be merged into the form object - * @param string $group The plugin group to be executed - * - * @return void - * - * @since 3.0 - */ - protected function preprocessForm(JForm $form, $data, $group = 'content') - { - if ($this->canCreateCategory()) - { - $form->setFieldAttribute('catid', 'allowAdd', 'true'); - } - - // Association content items - if (JLanguageAssociations::isEnabled()) - { - $languages = JLanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc'); - - if (count($languages) > 1) - { - $addform = new SimpleXMLElement('
'); - $fields = $addform->addChild('fields'); - $fields->addAttribute('name', 'associations'); - $fieldset = $fields->addChild('fieldset'); - $fieldset->addAttribute('name', 'item_associations'); - - foreach ($languages as $language) - { - $field = $fieldset->addChild('field'); - $field->addAttribute('name', $language->lang_code); - $field->addAttribute('type', 'modal_article'); - $field->addAttribute('language', $language->lang_code); - $field->addAttribute('label', $language->title); - $field->addAttribute('translate_label', 'false'); - $field->addAttribute('select', 'true'); - $field->addAttribute('new', 'true'); - $field->addAttribute('edit', 'true'); - $field->addAttribute('clear', 'true'); - } - - $form->load($addform, false); - } - } - - parent::preprocessForm($form, $data, $group); - } - - /** - * 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 - * - * @return void - * - * @since 1.6 - */ - protected function cleanCache($group = null, $client_id = 0) - { - parent::cleanCache('com_content'); - parent::cleanCache('mod_articles_archive'); - parent::cleanCache('mod_articles_categories'); - parent::cleanCache('mod_articles_category'); - parent::cleanCache('mod_articles_latest'); - parent::cleanCache('mod_articles_news'); - parent::cleanCache('mod_articles_popular'); - } - - /** - * Void hit function for pagebreak when editing content from frontend - * - * @return void - * - * @since 3.6.0 - */ - public function hit() - { - return; - } - - /** - * Is the user allowed to create an on the fly category? - * - * @return boolean - * - * @since 3.6.1 - */ - private function canCreateCategory() - { - return JFactory::getUser()->authorise('core.create', 'com_content'); - } - - /** - * Delete #__content_frontpage items if the deleted articles was featured - * - * @param object &$pks The primary key related to the contents that was deleted. - * - * @return boolean - * - * @since 3.7.0 - */ - public function delete(&$pks) - { - $return = parent::delete($pks); - - if ($return) - { - // Now check to see if this articles was featured if so delete it from the #__content_frontpage table - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->delete($db->quoteName('#__content_frontpage')) - ->where('content_id IN (' . implode(',', $pks) . ')'); - $db->setQuery($query); - $db->execute(); - } - - return $return; - } -} diff --git a/administrator/components/com_content/models/articles.php b/administrator/components/com_content/models/articles.php deleted file mode 100644 index c38c16b5d5293..0000000000000 --- a/administrator/components/com_content/models/articles.php +++ /dev/null @@ -1,441 +0,0 @@ -input->get('forcedLanguage', '', 'cmd'); - - // Adjust the context to support modal layouts. - if ($layout = $app->input->get('layout')) - { - $this->context .= '.' . $layout; - } - - // Adjust the context to support forced languages. - if ($forcedLanguage) - { - $this->context .= '.' . $forcedLanguage; - } - - $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); - $this->setState('filter.search', $search); - - $published = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', ''); - $this->setState('filter.published', $published); - - $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); - - $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); - - // Force a language - if (!empty($forcedLanguage)) - { - $this->setState('filter.language', $forcedLanguage); - $this->setState('filter.forcedLanguage', $forcedLanguage); - } - } - - /** - * 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 A store id. - * - * @since 1.6 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . serialize($this->getState('filter.access')); - $id .= ':' . $this->getState('filter.published'); - $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); - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - * - * @since 1.6 - */ - protected function getListQuery() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - $user = JFactory::getUser(); - - // Select the required fields from the table. - $query->select( - $this->getState( - 'list.select', - 'DISTINCT 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' - ) - ); - $query->from('#__content AS a'); - - // Join over the language - $query->select('l.title AS language_title, l.image AS language_image') - ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); - - // Join over the users for the checked out user. - $query->select('uc.name AS editor') - ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); - - // Join over the asset groups. - $query->select('ag.title AS access_level') - ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); - - // Join over the categories. - $query->select('c.title AS category_title') - ->join('LEFT', '#__categories AS c ON c.id = a.catid'); - - // 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, - COALESCE(NULLIF(v.rating_count, 0), 0) as rating_count') - ->join('LEFT', '#__content_rating AS v ON a.id = v.content_id'); - } - - // 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); - } - - // Filter by access level. - $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 . ')'); - } - - // Filter by published state - $published = $this->getState('filter.published'); - - if (is_numeric($published)) - { - $query->where('a.state = ' . (int) $published); - } - elseif ($published === '') - { - $query->where('(a.state = 0 OR a.state = 1)'); - } - - // 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); - } - - // Filter by author - $authorId = $this->getState('filter.author_id'); - - if (is_numeric($authorId)) - { - $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'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - elseif (stripos($search, 'author:') === 0) - { - $search = $db->quote('%' . $db->escape(substr($search, 7), true) . '%'); - $query->where('(ua.name LIKE ' . $search . ' OR ua.username LIKE ' . $search . ')'); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ')'); - } - } - - // Filter on the language. - if ($language = $this->getState('filter.language')) - { - $query->where('a.language = ' . $db->quote($language)); - } - - // Filter by a single or group of tags. - $hasTag = false; - $tagId = $this->getState('filter.tag'); - - if (is_numeric($tagId)) - { - $hasTag = true; - - $query->where($db->quoteName('tagmap.tag_id') . ' = ' . (int) $tagId); - } - elseif (is_array($tagId)) - { - $tagId = ArrayHelper::toInteger($tagId); - $tagId = implode(',', $tagId); - - if (!empty($tagId)) - { - $hasTag = true; - - $query->where($db->quoteName('tagmap.tag_id') . ' IN (' . $tagId . ')'); - } - } - - if ($hasTag) - { - $query->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') - ); - } - - // Add the list ordering clause. - $orderCol = $this->state->get('list.ordering', 'a.id'); - $orderDirn = $this->state->get('list.direction', 'DESC'); - - $query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn)); - - return $query; - } - - /** - * Build a list of authors - * - * @return stdClass - * - * @since 1.6 - */ - public function getAuthors() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - - // Construct the query - $query->select('u.id AS value, u.name AS text') - ->from('#__users AS u') - ->join('INNER', '#__content AS c ON c.created_by = u.id') - ->group('u.id, u.name') - ->order('u.name'); - - // Setup the query - $db->setQuery($query); - - // 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(); - - foreach (array_keys($items) as $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 deleted file mode 100644 index 34f0c2ed6cdef..0000000000000 --- a/administrator/components/com_content/models/feature.php +++ /dev/null @@ -1,50 +0,0 @@ -getDbo(); - $query = $db->getQuery(true); - $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.hits,' . - 'a.created_by, a.featured, a.language, a.created_by_alias, a.publish_up, a.publish_down' - ) - ); - $query->from('#__content AS a'); - - // Join over the language - $query->select('l.title AS language_title, l.image AS language_image') - ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); - - // Join over the content table. - $query->select('fp.ordering') - ->join('INNER', '#__content_frontpage AS fp ON fp.content_id = a.id'); - - // Join over the users for the checked out user. - $query->select('uc.name AS editor') - ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); - - // Join over the asset groups. - $query->select('ag.title AS access_level') - ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); - - // Join over the categories. - $query->select('c.title AS category_title') - ->join('LEFT', '#__categories AS c ON c.id = a.catid'); - - // 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 - if (JPluginHelper::isEnabled('content', 'vote')) - { - $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')) - { - $query->where('a.access = ' . (int) $access); - } - - // Filter by access level on categories. - if (!$user->authorise('core.admin')) - { - $groups = implode(',', $user->getAuthorisedViewLevels()); - $query->where('c.access IN (' . $groups . ')'); - } - - // Filter by published state - $published = $this->getState('filter.published'); - - if (is_numeric($published)) - { - $query->where('a.state = ' . (int) $published); - } - elseif ($published === '') - { - $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'); - - if (is_numeric($categoryId)) - { - $cat_tbl = JTable::getInstance('Category', 'JTable'); - $cat_tbl->load($categoryId); - $rgt = $cat_tbl->rgt; - $lft = $cat_tbl->lft; - $baselevel = (int) $cat_tbl->level; - $query->where('c.lft >= ' . (int) $lft) - ->where('c.rgt <= ' . (int) $rgt); - } - elseif (is_array($categoryId)) - { - $categoryId = implode(',', ArrayHelper::toInteger($categoryId)); - $query->where('a.catid IN (' . $categoryId . ')'); - } - - // Filter on the level. - if ($level = $this->getState('filter.level')) - { - $query->where('c.level <= ' . ((int) $level + (int) $baselevel - 1)); - } - - // Filter by author - $authorId = $this->getState('filter.author_id'); - - if (is_numeric($authorId)) - { - $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'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - elseif (stripos($search, 'author:') === 0) - { - $search = $db->quote('%' . $db->escape(substr($search, 7), true) . '%'); - $query->where('(ua.name LIKE ' . $search . ' OR ua.username LIKE ' . $search . ')'); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search); - } - } - - // Filter on the language. - if ($language = $this->getState('filter.language')) - { - $query->where('a.language = ' . $db->quote($language)); - } - - // Filter by a single tag. - $tagId = $this->getState('filter.tag'); - - if (is_numeric($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') - ); - } - - // Add the list ordering clause. - $orderCol = $this->state->get('list.ordering', 'a.title'); - $orderDirn = $this->state->get('list.direction', 'ASC'); - - $query->order($db->escape($orderCol) . ' ' . $db->escape($orderDirn)); - - return $query; - } - - /** - * 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.5 - */ - protected function populateState($ordering = 'a.title', $direction = 'asc') - { - parent::populateState($ordering, $direction); - } -} diff --git a/administrator/components/com_content/models/fields/modal/article.php b/administrator/components/com_content/models/fields/modal/article.php deleted file mode 100644 index 28934a3cc7131..0000000000000 --- a/administrator/components/com_content/models/fields/modal/article.php +++ /dev/null @@ -1,272 +0,0 @@ -element['new'] == 'true'); - $allowEdit = ((string) $this->element['edit'] == 'true'); - $allowClear = ((string) $this->element['clear'] != 'false'); - $allowSelect = ((string) $this->element['select'] != 'false'); - - // Load language - JFactory::getLanguage()->load('com_content', JPATH_ADMINISTRATOR); - - // The active article id field. - $value = (int) $this->value > 0 ? (int) $this->value : ''; - - // Create the modal id. - $modalId = 'Article_' . $this->id; - - // Add the modal field script to the document head. - JHtml::_('jquery.framework'); - JHtml::_('script', 'system/modal-fields.js', array('version' => 'auto', 'relative' => true)); - - // Script to proxy the select modal function to the modal-fields.js file. - if ($allowSelect) - { - static $scriptSelect = null; - - if (is_null($scriptSelect)) - { - $scriptSelect = array(); - } - - if (!isset($scriptSelect[$this->id])) - { - JFactory::getDocument()->addScriptDeclaration(" - function jSelectArticle_" . $this->id . "(id, title, catid, object, url, language) { - window.processModalSelect('Article', '" . $this->id . "', id, title, catid, object, url, language); - } - "); - - $scriptSelect[$this->id] = true; - } - } - - // Setup variables for display. - $linkArticles = 'index.php?option=com_content&view=articles&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; - $linkArticle = 'index.php?option=com_content&view=article&layout=modal&tmpl=component&' . JSession::getFormToken() . '=1'; - - if (isset($this->element['language'])) - { - $linkArticles .= '&forcedLanguage=' . $this->element['language']; - $linkArticle .= '&forcedLanguage=' . $this->element['language']; - $modalTitle = JText::_('COM_CONTENT_CHANGE_ARTICLE') . ' — ' . $this->element['label']; - } - else - { - $modalTitle = JText::_('COM_CONTENT_CHANGE_ARTICLE'); - } - - $urlSelect = $linkArticles . '&function=jSelectArticle_' . $this->id; - $urlEdit = $linkArticle . '&task=article.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \''; - $urlNew = $linkArticle . '&task=article.add'; - - if ($value) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('title')) - ->from($db->quoteName('#__content')) - ->where($db->quoteName('id') . ' = ' . (int) $value); - $db->setQuery($query); - - try - { - $title = $db->loadResult(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - } - - $title = empty($title) ? JText::_('COM_CONTENT_SELECT_AN_ARTICLE') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); - - // The current article display field. - $html = ''; - $html .= ''; - - // 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') - . ''; - } - - $html .= ''; - - // Select article modal - if ($allowSelect) - { - $html .= JHtml::_( - 'bootstrap.renderModal', - 'ModalSelect' . $modalId, - array( - 'title' => $modalTitle, - 'url' => $urlSelect, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '', - ) - ); - } - - // New article modal - if ($allowNew) - { - $html .= JHtml::_( - 'bootstrap.renderModal', - 'ModalNew' . $modalId, - array( - 'title' => JText::_('COM_CONTENT_NEW_ARTICLE'), - 'backdrop' => 'static', - 'keyboard' => false, - 'closeButton' => false, - 'url' => $urlNew, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '' - . '' - . '', - ) - ); - } - - // Edit article modal - if ($allowEdit) - { - $html .= JHtml::_( - 'bootstrap.renderModal', - 'ModalEdit' . $modalId, - array( - 'title' => JText::_('COM_CONTENT_EDIT_ARTICLE'), - 'backdrop' => 'static', - 'keyboard' => false, - 'closeButton' => false, - 'url' => $urlEdit, - 'height' => '400px', - 'width' => '800px', - 'bodyHeight' => '70', - 'modalWidth' => '80', - 'footer' => '' - . '' - . '', - ) - ); - } - - // Note: class='required' for client side validation. - $class = $this->required ? ' class="required modal-value"' : ''; - - $html .= ''; - - return $html; - } - - /** - * Method to get the field label markup. - * - * @return string The field label markup. - * - * @since 3.4 - */ - protected function getLabel() - { - return str_replace($this->id, $this->id . '_id', parent::getLabel()); - } -} diff --git a/administrator/components/com_content/models/fields/voteradio.php b/administrator/components/com_content/models/fields/voteradio.php deleted file mode 100644 index 2a2d2a63bd16c..0000000000000 --- a/administrator/components/com_content/models/fields/voteradio.php +++ /dev/null @@ -1,58 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - -
-
- - - - - - - - diff --git a/administrator/components/com_content/models/forms/filter_articles.xml b/administrator/components/com_content/models/forms/filter_articles.xml deleted file mode 100644 index 2e1995ca81e10..0000000000000 --- a/administrator/components/com_content/models/forms/filter_articles.xml +++ /dev/null @@ -1,150 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/administrator/components/com_content/services/provider.php b/administrator/components/com_content/services/provider.php new file mode 100644 index 0000000000000..54ec867702858 --- /dev/null +++ b/administrator/components/com_content/services/provider.php @@ -0,0 +1,65 @@ +set(Categories::class, ['' => new Category]); + $container->set(AssociationExtensionInterface::class, new AssociationsHelper); + + $container->registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Content')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Content')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new ContentComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setRegistry($container->get(Registry::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + $component->setCategories($container->get(Categories::class)); + $component->setAssociationExtension($container->get(AssociationExtensionInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_content/tables/featured.php b/administrator/components/com_content/tables/featured.php deleted file mode 100644 index 2fd7614778fb7..0000000000000 --- a/administrator/components/com_content/tables/featured.php +++ /dev/null @@ -1,30 +0,0 @@ - 0 )); + +$this->configFieldsets = array('editorConfig'); +$this->hiddenFieldsets = array('basic-limited'); +$this->ignore_fieldsets = array('jmetadata', 'item_associations'); +$this->useCoreUI = true; + +// Create shortcut to parameters. +$params = clone $this->state->get('params'); +$params->merge(new Registry($this->item->attribs)); + +$app = Factory::getApplication(); +$input = $app->input; + +$assoc = Associations::isEnabled(); + +// In case of modal +$isModal = $input->get('layout') == 'modal' ? true : false; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; +?> + +
+ + + +
+ 'general')); ?> + + +
+
+
+ form->getInput('articletext'); ?> +
+
+
+
+
+ +
+
+
+
+ + + + + get('show_urls_images_backend') == 1) : ?> + +
+
+ form->renderField('images'); ?> + form->getGroup('images') as $field) : ?> + renderField(); ?> + +
+
+ form->getGroup('urls') as $field) : ?> + renderField(); ?> + +
+
+ + + + + show_options = $params->get('show_article_options', 1); ?> + + + + get('show_publishing_options', 1) == 1) : ?> + +
+
+ +
+
+ +
+
+ + + + + + loadTemplate('associations'); ?> + + + + + + canDo->get('core.admin')) : ?> + + form->renderFieldset('editorConfig'); ?> + + + + canDo->get('core.admin')) : ?> + + form->getInput('rules'); ?> + + + + + + + + + +
+
diff --git a/administrator/components/com_content/views/article/tmpl/edit.xml b/administrator/components/com_content/tmpl/article/edit.xml similarity index 100% rename from administrator/components/com_content/views/article/tmpl/edit.xml rename to administrator/components/com_content/tmpl/article/edit.xml diff --git a/administrator/components/com_content/tmpl/article/edit_associations.php b/administrator/components/com_content/tmpl/article/edit_associations.php new file mode 100644 index 0000000000000..965f41d498972 --- /dev/null +++ b/administrator/components/com_content/tmpl/article/edit_associations.php @@ -0,0 +1,14 @@ + +
+ setLayout('edit'); ?> + loadTemplate(); ?> +
diff --git a/administrator/components/com_content/tmpl/article/modal_associations.php b/administrator/components/com_content/tmpl/article/modal_associations.php new file mode 100644 index 0000000000000..965f41d498972 --- /dev/null +++ b/administrator/components/com_content/tmpl/article/modal_associations.php @@ -0,0 +1,14 @@ + 'auto', 'relative' => true)); + +$document = Factory::getDocument(); +$this->eName = Factory::getApplication()->input->getCmd('e_name', ''); +$this->eName = preg_replace('#[^A-Z0-9\-\_\[\]]#i', '', $this->eName); + +$document->setTitle(Text::_('COM_CONTENT_PAGEBREAK_DOC_TITLE')); +?> +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ + + +
+
diff --git a/administrator/components/com_content/tmpl/articles/default.php b/administrator/components/com_content/tmpl/articles/default.php new file mode 100644 index 0000000000000..ff17ffac39c0e --- /dev/null +++ b/administrator/components/com_content/tmpl/articles/default.php @@ -0,0 +1,376 @@ + Text::_('JOPTION_SELECT_TAG'))); +HTMLHelper::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_CATEGORY'))); +HTMLHelper::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_ACCESS'))); +HTMLHelper::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_AUTHOR'))); + +$app = Factory::getApplication(); +$user = Factory::getUser(); +$userId = $user->get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; + +if (strpos($listOrder, 'publish_up') !== false) +{ + $orderingColumn = 'publish_up'; +} +elseif (strpos($listOrder, 'publish_down') !== false) +{ + $orderingColumn = 'publish_down'; +} +elseif (strpos($listOrder, 'modified') !== false) +{ + $orderingColumn = 'modified'; +} +else +{ + $orderingColumn = 'created'; +} + +if ($saveOrder && !empty($this->items)) +{ + $saveOrderingUrl = 'index.php?option=com_content&task=articles.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} + +$js = <<addScriptDeclaration($js); + +$assoc = Associations::isEnabled(); + +// Configure featured button renderer. +$featuredButton = (new ActionButton(['tip_title' => 'JGLOBAL_TOGGLE_FEATURED'])) + ->addState(0, 'articles.featured', 'unfeatured', 'COM_CONTENT_UNFEATURED') + ->addState(1, 'articles.unfeatured', 'featured', 'COM_CONTENT_FEATURED'); +?> + +
+
+ sidebar)) : ?> +
+ sidebar; ?> +
+ +
+
+ $this)); + ?> + items)) : ?> + + + + + + + + + + + + + + + + + + + + + vote) : ?> + + + + + + + class="js-draggable" data-url="" data-direction="" data-nested="true"> + items as $i => $item) : + $item->max_ordering = 0; + $ordering = ($listOrder == 'a.ordering'); + $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; + $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; + + $transitions = ContentHelper::filterTransitions($this->transitions, $item->stage_id, $item->workflow_id); + + $hasTransitions = count($transitions) > 0; + + $default = [ + JHtml::_('select.option', '', $this->escape(Text::_($item->stage_title))), + JHtml::_('select.option', '-1', '--------', ['disable' => true]) + ]; + + $transitions = array_merge($default, $transitions); + + ?> + + + + + + + + + + + + + + + + vote) : ?> + + + + + + + +
+ , + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + id, false, 'cid', 'cb', $item->title); ?> + +
+
+ render($item->featured, $i, ['disabled' => !$canChange]); ?> + stage_condition) : + case ContentComponent::CONDITION_TRASHED: + $icon = 'trash'; + break; + case ContentComponent::CONDITION_UNPUBLISHED: + $icon = 'unpublish'; + break; + case ContentComponent::CONDITION_ARCHIVED: + $icon = 'archive'; + break; + default: + $icon = 'publish'; + endswitch; + ?> + + + + + + + +
+
escape(Text::_($item->stage_title)); ?>
+ +
+ 'transition-select_' . (int) $item->id, + 'list.attr' => [ + 'class' => 'custom-select custom-select-sm form-control form-control-sm', + 'onchange' => "Joomla.listItemTask('cb" . (int) $i . "', 'articles.runTransition')"] + ]; + echo JHtml::_('select.genericlist', $transitions, 'transition_' . (int) $item->id, $attribs); + ?> +
+ +
+
+
+ checked_out) : ?> + editor, $item->checked_out_time, 'articles.', $canCheckin); ?> + + + checked_out ? '' : ''; ?> + + escape($item->title); ?> + + escape($item->title); ?> + + + escape($item->alias)); ?> + +
+ escape($item->category_title); ?> +
+
+
+ escape($item->access_level); ?> + + association) : ?> + id); ?> + + + created_by != 0) : ?> + created_by_alias) : ?> + + escape($item->author_name); ?> +
escape($item->created_by_alias)); ?>
+ + + escape($item->author_name); ?> + + + created_by_alias) : ?> + +
escape($item->created_by_alias)); ?>
+ + + + +
+ + + {$orderingColumn}; + echo $date > 0 ? HTMLHelper::_('date', $date, Text::_('DATE_FORMAT_LC4')) : '-'; + ?> + + + hits; ?> + + + + rating_count; ?> + + + + rating; ?> + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + authorise('core.create', 'com_content') + && $user->authorise('core.edit', 'com_content') + && $user->authorise('core.edit.state', 'com_content')) : ?> + Text::_('COM_CONTENT_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + +
+
+
+
diff --git a/administrator/components/com_content/views/articles/tmpl/default.xml b/administrator/components/com_content/tmpl/articles/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_content/views/articles/tmpl/default.xml rename to administrator/components/com_content/tmpl/articles/default.xml diff --git a/administrator/components/com_content/tmpl/articles/default_batch_body.php b/administrator/components/com_content/tmpl/articles/default_batch_body.php new file mode 100644 index 0000000000000..acfb07cc1f359 --- /dev/null +++ b/administrator/components/com_content/tmpl/articles/default_batch_body.php @@ -0,0 +1,55 @@ +state->get('filter.published'); + +$user = \Joomla\CMS\Factory::getUser(); +?> + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ = 0) : ?> +
+
+ +
+
+ +
+
+ +
+
+ authorise('core.admin', 'com_content')) : ?> +
+
+ 'com_content']; + echo LayoutHelper::render('joomla.html.batch.workflowstage', $displayData); ?> +
+
+ +
+
diff --git a/administrator/components/com_content/tmpl/articles/default_batch_footer.php b/administrator/components/com_content/tmpl/articles/default_batch_footer.php new file mode 100644 index 0000000000000..02d45617d1a89 --- /dev/null +++ b/administrator/components/com_content/tmpl/articles/default_batch_footer.php @@ -0,0 +1,22 @@ + true, 'version' => 'auto']); +?> + + + + diff --git a/administrator/components/com_content/tmpl/articles/modal.php b/administrator/components/com_content/tmpl/articles/modal.php new file mode 100644 index 0000000000000..5122c20b01161 --- /dev/null +++ b/administrator/components/com_content/tmpl/articles/modal.php @@ -0,0 +1,159 @@ +isClient('site')) +{ + Session::checkToken('get') or die(Text::_('JINVALID_TOKEN')); +} + +JLoader::register('ContentHelperRoute', JPATH_ROOT . '/components/com_content/helpers/route.php'); + +HTMLHelper::_('behavior.core'); +HTMLHelper::_('script', 'com_content/admin-articles-modal.min.js', array('version' => 'auto', 'relative' => true)); +HTMLHelper::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); +HTMLHelper::_('behavior.multiselect'); +HTMLHelper::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_TAG'))); +HTMLHelper::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_CATEGORY'))); +HTMLHelper::_('formbehavior.chosen', '.multipleAccessLevels', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_ACCESS'))); +HTMLHelper::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_AUTHOR'))); + +$function = $app->input->getCmd('function', 'jSelectArticle'); +$editor = $app->input->getCmd('editor', ''); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$onclick = $this->escape($function); + +if (!empty($editor)) +{ + // This view is used also in com_menus. Load the xtd script only if the editor is set! + Factory::getDocument()->addScriptOptions('xtd-articles', array('editor' => $editor)); + $onclick = "jSelectArticle"; +} +?> +
+ +
+ + $this)); ?> + + items)) : ?> + + + + + + + + + + + + + + + 'icon-trash', + 0 => 'icon-unpublish', + 1 => 'icon-publish', + ); + ?> + items as $i => $item) : ?> + language && Multilanguage::isEnabled()) + { + $tag = strlen($item->language); + if ($tag == 5) + { + $lang = substr($item->language, 0, 2); + } + elseif ($tag == 6) + { + $lang = substr($item->language, 0, 3); + } + else { + $lang = ''; + } + } + elseif (!Multilanguage::isEnabled()) + { + $lang = ''; + } + ?> + + + + + + + + + + +
+ + + + + + + + + + + +
+ + + escape($onclick) . '"' + . ' data-id="' . $item->id . '"' + . ' 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->category_title); ?> +
+
+ escape($item->access_level); ?> + + + + created, Text::_('DATE_FORMAT_LC4')); ?> + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + + + + +
+
diff --git a/administrator/components/com_content/tmpl/featured/default.php b/administrator/components/com_content/tmpl/featured/default.php new file mode 100644 index 0000000000000..1f29707c343e9 --- /dev/null +++ b/administrator/components/com_content/tmpl/featured/default.php @@ -0,0 +1,314 @@ + Text::_('JOPTION_SELECT_ACCESS'))); +HTMLHelper::_('formbehavior.chosen', '.multipleAuthors', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_AUTHOR'))); +HTMLHelper::_('formbehavior.chosen', '.multipleCategories', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_CATEGORY'))); +HTMLHelper::_('formbehavior.chosen', '.multipleTags', null, array('placeholder_text_multiple' => Text::_('JOPTION_SELECT_TAG'))); + +$user = Factory::getUser(); +$userId = $user->get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'fp.ordering'; + +if (strpos($listOrder, 'publish_up') !== false) +{ + $orderingColumn = 'publish_up'; +} +elseif (strpos($listOrder, 'publish_down') !== false) +{ + $orderingColumn = 'publish_down'; +} +else +{ + $orderingColumn = 'created'; +} + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_content&task=featured.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('sortablelist.sortable', 'articleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); +} + +$js = <<addScriptDeclaration($js); + +?> + +
+
+ sidebar)) : ?> +
+ sidebar; ?> +
+ +
+
+ $this)); + ?> + items)) : ?> + + + + + + + + + + + + + + + + + vote) : ?> + + + + + + + + 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; + + $transitions = ContentHelper::filterTransitions($this->transitions, $item->stage_id, $item->workflow_id); + + $hasTransitions = count($transitions) > 0; + + $default = [ + JHtml::_('select.option', '', $this->escape($item->stage_title)), + JHtml::_('select.option', '-1', '--------', ['disable' => true]) + ]; + + $transitions = array_merge($default, $transitions); + + ?> + + + + + + + + + + + + + vote) : ?> + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + id); ?> + +
+
+ featured, $i, $canChange); ?> + stage_condition) : + case ContentComponent::CONDITION_TRASHED : + $icon = 'trash'; + break; + case ContentComponent::CONDITION_UNPUBLISHED : + $icon = 'unpublish'; + break; + case ContentComponent::CONDITION_ARCHIVED : + $icon = 'archive'; + break; + default : + $icon = 'publish'; + endswitch; + ?> + + + + + + + +
+
escape($item->stage_title); ?>
+ +
+ 'transition-select_' . (int) $item->id, + 'list.attr' => [ + 'class' => 'custom-select custom-select-sm form-control form-control-sm', + 'onchange' => "Joomla.listItemTask('cb" . (int) $i . "', 'articles.runTransition')"] + ]; + echo HTMLHelper::_('select.genericlist', $transitions, 'transition_' . (int) $item->id, $attribs); + ?> +
+ +
+
+
+ checked_out) : ?> + editor, $item->checked_out_time, 'articles.', $canCheckin); ?> + + + checked_out ? '' : ''; ?> + + escape($item->title); ?> + + escape($item->title); ?> + + + escape($item->alias)); ?> + +
+ escape($item->category_title); ?> +
+
+
+ escape($item->access_level); ?> + + created_by != 0) : ?> + created_by_alias) : ?> + + escape($item->author_name); ?> +
escape($item->created_by_alias)); ?>
+ + + escape($item->author_name); ?> + + + created_by_alias) : ?> + +
escape($item->created_by_alias)); ?>
+ + + + +
+ + + {$orderingColumn}; + echo $date > 0 ? HTMLHelper::_('date', $date, Text::_('DATE_FORMAT_LC4')) : '-'; + ?> + + + hits; ?> + + + + rating_count; ?> + + + + rating; ?> + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + + + +
+
+
+
diff --git a/administrator/components/com_content/views/featured/tmpl/default.xml b/administrator/components/com_content/tmpl/featured/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_content/views/featured/tmpl/default.xml rename to administrator/components/com_content/tmpl/featured/default.xml diff --git a/administrator/components/com_content/views/article/tmpl/edit.php b/administrator/components/com_content/views/article/tmpl/edit.php deleted file mode 100644 index 4e0a15cab02a2..0000000000000 --- a/administrator/components/com_content/views/article/tmpl/edit.php +++ /dev/null @@ -1,143 +0,0 @@ - 0 )); -JHtml::_('formbehavior.chosen', 'select'); - -$this->configFieldsets = array('editorConfig'); -$this->hiddenFieldsets = array('basic-limited'); -$this->ignore_fieldsets = array('jmetadata', 'item_associations'); - -// Create shortcut to parameters. -$params = clone $this->state->get('params'); -$params->merge(new Registry($this->item->attribs)); - -$app = JFactory::getApplication(); -$input = $app->input; - -$assoc = JLanguageAssociations::isEnabled(); - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(task) - { - if (task == "article.cancel" || document.formvalidator.isValid(document.getElementById("item-form"))) - { - jQuery("#permissions-sliders select").attr("disabled", "disabled"); - ' . $this->form->getField('articletext')->save() . ' - Joomla.submitform(task, document.getElementById("item-form")); - - // @deprecated 4.0 The following js is not needed since 3.7.0. - if (task !== "article.apply") - { - window.parent.jQuery("#articleEdit' . (int) $this->item->id . 'Modal").modal("hide"); - } - } - }; -'); - -// In case of modal -$isModal = $input->get('layout') == 'modal' ? true : false; -$layout = $isModal ? 'modal' : 'edit'; -$tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; -?> - -
- - - -
- 'general')); ?> - - -
-
-
- form->getInput('articletext'); ?> -
-
-
- -
-
- - - - get('show_urls_images_backend') == 1) : ?> - -
-
- form->renderField('images'); ?> - form->getGroup('images') as $field) : ?> - renderField(); ?> - -
-
- form->getGroup('urls') as $field) : ?> - renderField(); ?> - -
-
- - - - show_options = $params->get('show_article_options', 1); ?> - - - - get('show_publishing_options', 1) == 1) : ?> - -
-
- -
-
- -
-
- - - - - - - loadTemplate('associations'); ?> - - - - - - canDo->get('core.admin')) : ?> - - form->renderFieldset('editorConfig'); ?> - - - - canDo->get('core.admin')) : ?> - - form->getInput('rules'); ?> - - - - - - - - - -
-
diff --git a/administrator/components/com_content/views/article/tmpl/edit_associations.php b/administrator/components/com_content/views/article/tmpl/edit_associations.php deleted file mode 100644 index 9638336872009..0000000000000 --- a/administrator/components/com_content/views/article/tmpl/edit_associations.php +++ /dev/null @@ -1,12 +0,0 @@ - 'bottom')); - -// @deprecated 4.0 the function parameter, the inline js and the buttons are not needed since 3.7.0. -$function = JFactory::getApplication()->input->getCmd('function', 'jEditArticle_' . (int) $this->item->id); - -// Function to update input title when changed -JFactory::getDocument()->addScriptDeclaration(' - function jEditArticleModal() { - if (window.parent && document.formvalidator.isValid(document.getElementById("item-form"))) { - return window.parent.' . $this->escape($function) . '(document.getElementById("jform_title").value); - } - } -'); -?> - - - - -
- setLayout('edit'); ?> - loadTemplate(); ?> -
diff --git a/administrator/components/com_content/views/article/tmpl/modal_associations.php b/administrator/components/com_content/views/article/tmpl/modal_associations.php deleted file mode 100644 index 9638336872009..0000000000000 --- a/administrator/components/com_content/views/article/tmpl/modal_associations.php +++ /dev/null @@ -1,12 +0,0 @@ - 'auto', 'relative' => true)); - -$document = JFactory::getDocument(); -$this->eName = JFactory::getApplication()->input->getCmd('e_name', ''); -$this->eName = preg_replace('#[^A-Z0-9\-\_\[\]]#i', '', $this->eName); - -$document->setTitle(JText::_('COM_CONTENT_PAGEBREAK_DOC_TITLE')); -?> -
-
- -
- -
-
- -
- -
-
- - - -
-
diff --git a/administrator/components/com_content/views/article/view.html.php b/administrator/components/com_content/views/article/view.html.php deleted file mode 100644 index f0bfabc687c40..0000000000000 --- a/administrator/components/com_content/views/article/view.html.php +++ /dev/null @@ -1,159 +0,0 @@ -getLayout() == 'pagebreak') - { - return parent::display($tpl); - } - - $this->form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - $this->canDo = JHelperContent::getActions('com_content', 'article', $this->item->id); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - // If we are forcing a language in modal (used for associations). - if ($this->getLayout() === 'modal' && $forcedLanguage = JFactory::getApplication()->input->get('forcedLanguage', '', 'cmd')) - { - // Set the language field to the forcedLanguage and disable changing it. - $this->form->setValue('language', null, $forcedLanguage); - $this->form->setFieldAttribute('language', 'readonly', 'true'); - - // Only allow to select categories with All language or with the forced language. - $this->form->setFieldAttribute('catid', 'language', '*,' . $forcedLanguage); - - // Only allow to select tags with All language or with the forced language. - $this->form->setFieldAttribute('tags', 'language', '*,' . $forcedLanguage); - } - - $this->addToolbar(); - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - $user = JFactory::getUser(); - $userId = $user->id; - $isNew = ($this->item->id == 0); - $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); - - // Built the actions for new and existing records. - $canDo = $this->canDo; - - JToolbarHelper::title( - JText::_('COM_CONTENT_PAGE_' . ($checkedOut ? 'VIEW_ARTICLE' : ($isNew ? 'ADD_ARTICLE' : 'EDIT_ARTICLE'))), - 'pencil-2 article-add' - ); - - // For new records, check the create permission. - if ($isNew && (count($user->getAuthorisedCategories('com_content', 'core.create')) > 0)) - { - JToolbarHelper::apply('article.apply'); - JToolbarHelper::save('article.save'); - JToolbarHelper::save2new('article.save2new'); - JToolbarHelper::cancel('article.cancel'); - } - else - { - // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. - $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId); - - // Can't save the record if it's checked out and editable - if (!$checkedOut && $itemEditable) - { - JToolbarHelper::apply('article.apply'); - JToolbarHelper::save('article.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('article.save2new'); - } - } - - // If checked out, we can still save - if ($canDo->get('core.create')) - { - JToolbarHelper::save2copy('article.save2copy'); - } - - if (JComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $itemEditable) - { - JToolbarHelper::versions('com_content.article', $this->item->id); - } - - JToolbarHelper::cancel('article.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_CONTENT_ARTICLE_MANAGER_EDIT'); - } -} diff --git a/administrator/components/com_content/views/articles/tmpl/default.php b/administrator/components/com_content/views/articles/tmpl/default.php deleted file mode 100644 index 14d5f48f0c6b9..0000000000000 --- a/administrator/components/com_content/views/articles/tmpl/default.php +++ /dev/null @@ -1,281 +0,0 @@ - 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(); -$user = JFactory::getUser(); -$userId = $user->get('id'); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$saveOrder = $listOrder == 'a.ordering'; -$columns = 10; - -if (strpos($listOrder, 'publish_up') !== false) -{ - $orderingColumn = 'publish_up'; -} -elseif (strpos($listOrder, 'publish_down') !== false) -{ - $orderingColumn = 'publish_down'; -} -elseif (strpos($listOrder, 'modified') !== false) -{ - $orderingColumn = 'modified'; -} -else -{ - $orderingColumn = 'created'; -} - -if ($saveOrder) -{ - $saveOrderingUrl = 'index.php?option=com_content&task=articles.saveOrderAjax&tmpl=component'; - JHtml::_('sortablelist.sortable', 'articleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); -} - -$assoc = JLanguageAssociations::isEnabled(); -?> - -
-sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); - ?> - items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - vote) : ?> - - - - - - - - - - - - - - - items as $i => $item) : - $item->max_ordering = 0; - $ordering = ($listOrder == 'a.ordering'); - $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; - $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; - ?> - - - - - - - - - - - - - - vote) : ?> - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - - id); ?> - -
- state, $i, 'articles.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> - featured, $i, $canChange); ?> - state === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'articles'); - JHtml::_('actionsdropdown.' . ((int) $item->state === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'articles'); - echo JHtml::_('actionsdropdown.render', $this->escape($item->title)); - } - ?> -
-
-
- checked_out) : ?> - editor, $item->checked_out_time, 'articles.', $canCheckin); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - - escape($item->alias)); ?> - -
- escape($item->category_title); ?> -
-
-
- escape($item->access_level); ?> - - association) : ?> - id); ?> - - - created_by != 0) : ?> - created_by_alias) : ?> - - escape($item->author_name); ?> -
escape($item->created_by_alias)); ?>
- - - escape($item->author_name); ?> - - - created_by_alias) : ?> - -
escape($item->created_by_alias)); ?>
- - - - -
- - - {$orderingColumn}; - echo $date > 0 ? JHtml::_('date', $date, JText::_('DATE_FORMAT_LC4')) : '-'; - ?> - - - hits; ?> - - - - rating_count; ?> - - - - rating; ?> - - - id; ?> -
- - authorise('core.create', 'com_content') - && $user->authorise('core.edit', 'com_content') - && $user->authorise('core.edit.state', 'com_content')) : ?> - JText::_('COM_CONTENT_BATCH_OPTIONS'), - 'footer' => $this->loadTemplate('batch_footer'), - ), - $this->loadTemplate('batch_body') - ); ?> - - - - pagination->getListFooter(); ?> - - - - -
- 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 deleted file mode 100644 index 73afe728bfa56..0000000000000 --- a/administrator/components/com_content/views/articles/tmpl/default_batch_body.php +++ /dev/null @@ -1,40 +0,0 @@ -state->get('filter.published'); -?> - -
-
-
-
- -
-
-
-
- -
-
-
-
- = 0) : ?> -
-
- -
-
- -
-
- -
-
-
-
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 deleted file mode 100644 index 5be5d8c979435..0000000000000 --- a/administrator/components/com_content/views/articles/tmpl/default_batch_footer.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ 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 deleted file mode 100644 index 1ccce20f6e1f0..0000000000000 --- a/administrator/components/com_content/views/articles/tmpl/modal.php +++ /dev/null @@ -1,169 +0,0 @@ -isClient('site')) -{ - JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); -} - -JLoader::register('ContentHelperRoute', JPATH_ROOT . '/components/com_content/helpers/route.php'); - -// Include the component HTML helpers. -JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - -JHtml::_('behavior.core'); -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. -$searchFilterDesc = $this->filterForm->getFieldAttribute('search', 'description', null, 'filter'); -JHtml::_('bootstrap.tooltip', '#filter_search', array('title' => JText::_($searchFilterDesc), 'placement' => 'bottom')); - -$function = $app->input->getCmd('function', 'jSelectArticle'); -$editor = $app->input->getCmd('editor', ''); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$onclick = $this->escape($function); - -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-articles', array('editor' => $editor)); - $onclick = "jSelectArticle"; -} -?> -
- -
- - $this)); ?> - -
- - items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - 'icon-trash', - 0 => 'icon-unpublish', - 1 => 'icon-publish', - 2 => 'icon-archive', - ); - ?> - items as $i => $item) : ?> - language && JLanguageMultilang::isEnabled()) - { - $tag = strlen($item->language); - if ($tag == 5) - { - $lang = substr($item->language, 0, 2); - } - elseif ($tag == 6) - { - $lang = substr($item->language, 0, 3); - } - else { - $lang = ''; - } - } - elseif (!JLanguageMultilang::isEnabled()) - { - $lang = ''; - } - ?> - - - - - - - - - - -
- - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - escape($onclick) . '"' - . ' data-id="' . $item->id . '"' - . ' 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->category_title); ?> -
-
- escape($item->access_level); ?> - - - - created, JText::_('DATE_FORMAT_LC4')); ?> - - id; ?> -
- - - - - - - -
-
diff --git a/administrator/components/com_content/views/articles/view.html.php b/administrator/components/com_content/views/articles/view.html.php deleted file mode 100644 index 3ce0edcb5fe10..0000000000000 --- a/administrator/components/com_content/views/articles/view.html.php +++ /dev/null @@ -1,228 +0,0 @@ -getLayout() !== 'modal') - { - ContentHelper::addSubmenu('articles'); - } - - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->authors = $this->get('Authors'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - $this->vote = JPluginHelper::isEnabled('content', 'vote'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - // 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')), - JHtml::_('select.option', '3', JText::_('J3')), - JHtml::_('select.option', '4', JText::_('J4')), - JHtml::_('select.option', '5', JText::_('J5')), - JHtml::_('select.option', '6', JText::_('J6')), - JHtml::_('select.option', '7', JText::_('J7')), - JHtml::_('select.option', '8', JText::_('J8')), - JHtml::_('select.option', '9', JText::_('J9')), - JHtml::_('select.option', '10', JText::_('J10')), - ); - - // We don't need toolbar in the modal window. - if ($this->getLayout() !== 'modal') - { - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - } - 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 a 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'); - } - } - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_content', 'category', $this->state->get('filter.category_id')); - $user = JFactory::getUser(); - - // Get the toolbar object instance - $bar = JToolbar::getInstance('toolbar'); - - JToolbarHelper::title(JText::_('COM_CONTENT_ARTICLES_TITLE'), 'stack article'); - - 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')) - { - JToolbarHelper::editList('article.edit'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publish('articles.publish', 'JTOOLBAR_PUBLISH', true); - JToolbarHelper::unpublish('articles.unpublish', 'JTOOLBAR_UNPUBLISH', true); - JToolbarHelper::custom('articles.featured', 'featured.png', 'featured_f2.png', 'JFEATURE', true); - JToolbarHelper::custom('articles.unfeatured', 'unfeatured.png', 'featured_f2.png', 'JUNFEATURE', true); - JToolbarHelper::archiveList('articles.archive'); - JToolbarHelper::checkin('articles.checkin'); - } - - // Add a batch button - if ($user->authorise('core.create', 'com_content') - && $user->authorise('core.edit', 'com_content') - && $user->authorise('core.edit.state', 'com_content')) - { - $title = JText::_('JTOOLBAR_BATCH'); - - // Instantiate a new JLayoutFile instance and render the batch button - $layout = new JLayoutFile('joomla.toolbar.batch'); - - $dhtml = $layout->render(array('title' => $title)); - $bar->appendButton('Custom', $dhtml, 'batch'); - } - - if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'articles.delete', 'JTOOLBAR_EMPTY_TRASH'); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('articles.trash'); - } - - if ($user->authorise('core.admin', 'com_content') || $user->authorise('core.options', 'com_content')) - { - JToolbarHelper::preferences('com_content'); - } - - JToolbarHelper::help('JHELP_CONTENT_ARTICLE_MANAGER'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), - 'a.state' => JText::_('JSTATUS'), - 'a.title' => JText::_('JGLOBAL_TITLE'), - 'category_title' => JText::_('JCATEGORY'), - 'access_level' => JText::_('JGRID_HEADING_ACCESS'), - 'a.created_by' => JText::_('JAUTHOR'), - 'language' => JText::_('JGRID_HEADING_LANGUAGE'), - 'a.created' => JText::_('JDATE'), - 'a.id' => JText::_('JGRID_HEADING_ID'), - 'a.featured' => JText::_('JFEATURED') - ); - } -} diff --git a/administrator/components/com_content/views/featured/tmpl/default.php b/administrator/components/com_content/views/featured/tmpl/default.php deleted file mode 100644 index b6124c6e38a45..0000000000000 --- a/administrator/components/com_content/views/featured/tmpl/default.php +++ /dev/null @@ -1,249 +0,0 @@ - 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(); -$userId = $user->get('id'); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$saveOrder = $listOrder == 'fp.ordering'; -$columns = 10; - -if (strpos($listOrder, 'publish_up') !== false) -{ - $orderingColumn = 'publish_up'; -} -elseif (strpos($listOrder, 'publish_down') !== false) -{ - $orderingColumn = 'publish_down'; -} -else -{ - $orderingColumn = 'created'; -} - -if ($saveOrder) -{ - $saveOrderingUrl = 'index.php?option=com_content&task=featured.saveOrderAjax&tmpl=component'; - JHtml::_('sortablelist.sortable', 'articleList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); -} -?> - -
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); - ?> - items)) : ?> -
- -
- - - - - - - - - - - - - - vote) : ?> - - - - - - - - - - - - - - - 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; - ?> - - - - - - - - - - - vote) : ?> - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - - - - - - - id); ?> - -
- state, $i, 'articles.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> - featured, $i, $canChange); ?> - state === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'articles'); - JHtml::_('actionsdropdown.' . ((int) $item->state === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'articles'); - echo JHtml::_('actionsdropdown.render', $this->escape($item->title)); - } - ?> -
-
-
- checked_out) : ?> - editor, $item->checked_out_time, 'articles.', $canCheckin); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - - escape($item->alias)); ?> - -
- escape($item->category_title); ?> -
-
-
- escape($item->access_level); ?> - - created_by != 0) : ?> - created_by_alias) : ?> - - escape($item->author_name); ?> -
escape($item->created_by_alias)); ?>
- - - escape($item->author_name); ?> - - - created_by_alias) : ?> - -
escape($item->created_by_alias)); ?>
- - - - -
- - - {$orderingColumn}; - echo $date > 0 ? JHtml::_('date', $date, JText::_('DATE_FORMAT_LC4')) : '-'; - ?> - - - hits; ?> - - - - rating_count; ?> - - - - rating; ?> - - - id; ?> -
- - - - - - -
- diff --git a/administrator/components/com_content/views/featured/view.html.php b/administrator/components/com_content/views/featured/view.html.php deleted file mode 100644 index 3a213b011cf35..0000000000000 --- a/administrator/components/com_content/views/featured/view.html.php +++ /dev/null @@ -1,185 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->authors = $this->get('Authors'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - $this->vote = JPluginHelper::isEnabled('content', 'vote'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - // 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')), - JHtml::_('select.option', '3', JText::_('J3')), - JHtml::_('select.option', '4', JText::_('J4')), - JHtml::_('select.option', '5', JText::_('J5')), - JHtml::_('select.option', '6', JText::_('J6')), - JHtml::_('select.option', '7', JText::_('J7')), - JHtml::_('select.option', '8', JText::_('J8')), - JHtml::_('select.option', '9', JText::_('J9')), - JHtml::_('select.option', '10', JText::_('J10')), - ); - - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $state = $this->get('State'); - $canDo = JHelperContent::getActions('com_content', 'category', $this->state->get('filter.category_id')); - - JToolbarHelper::title(JText::_('COM_CONTENT_FEATURED_TITLE'), 'star featured'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('article.add'); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('article.edit'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publish('articles.publish', 'JTOOLBAR_PUBLISH', true); - JToolbarHelper::unpublish('articles.unpublish', 'JTOOLBAR_UNPUBLISH', true); - JToolbarHelper::custom('articles.unfeatured', 'unfeatured.png', 'featured_f2.png', 'JUNFEATURE', true); - JToolbarHelper::archiveList('articles.archive'); - JToolbarHelper::checkin('articles.checkin'); - } - - if ($state->get('filter.published') == -2 && $canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'articles.delete', 'JTOOLBAR_EMPTY_TRASH'); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('articles.trash'); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_content'); - } - - JToolbarHelper::help('JHELP_CONTENT_FEATURED_ARTICLES'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'fp.ordering' => JText::_('JGRID_HEADING_ORDERING'), - 'a.state' => JText::_('JSTATUS'), - 'a.title' => JText::_('JGLOBAL_TITLE'), - 'category_title' => JText::_('JCATEGORY'), - 'access_level' => JText::_('JGRID_HEADING_ACCESS'), - 'a.created_by' => JText::_('JAUTHOR'), - 'language' => JText::_('JGRID_HEADING_LANGUAGE'), - 'a.created' => JText::_('JDATE'), - 'a.id' => JText::_('JGRID_HEADING_ID'), - ); - } -} diff --git a/administrator/components/com_contenthistory/Controller/DisplayController.php b/administrator/components/com_contenthistory/Controller/DisplayController.php new file mode 100644 index 0000000000000..032fc48d51183 --- /dev/null +++ b/administrator/components/com_contenthistory/Controller/DisplayController.php @@ -0,0 +1,24 @@ +input->get('cid', array(), 'array'); + + if (!is_array($cid) || count($cid) < 1) + { + $this->app->enqueueMessage(Text::_('COM_CONTENTHISTORY_NO_ITEM_SELECTED'), 'warning'); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Remove the items. + if ($model->delete($cid)) + { + $this->setMessage(Text::plural('COM_CONTENTHISTORY_N_ITEMS_DELETED', count($cid))); + } + else + { + $this->setMessage($model->getError(), 'error'); + } + } + + $this->setRedirect( + Route::_( + 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' + . $this->input->getInt('item_id') . '&type_id=' . $this->input->getInt('type_id') + . '&type_alias=' . $this->input->getCmd('type_alias') . '&' . Session::getFormToken() . '=1', false + ) + ); + } + + /** + * Proxy for getModel. + * + * @param string $name The name of the model + * @param string $prefix The prefix for the model + * @param array $config An additional array of parameters + * + * @return \Joomla\CMS\MVC\Model\BaseDatabaseModel The model + * + * @since 3.2 + */ + public function getModel($name = 'History', $prefix = 'Administrator', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Toggles the keep forever value for one or more history rows. If it was Yes, changes to No. If No, changes to Yes. + * + * @return void + * + * @since 3.2 + */ + public function keep() + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Get items to remove from the request. + $cid = $this->input->get('cid', array(), 'array'); + + if (!is_array($cid) || count($cid) < 1) + { + $this->app->enqueueMessage(Text::_('COM_CONTENTHISTORY_NO_ITEM_SELECTED'), 'warning'); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Remove the items. + if ($model->keep($cid)) + { + $this->setMessage(Text::plural('COM_CONTENTHISTORY_N_ITEMS_KEEP_TOGGLE', count($cid))); + } + else + { + $this->setMessage($model->getError(), 'error'); + } + } + + $this->setRedirect( + Route::_( + 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' + . $this->input->getInt('item_id') . '&type_id=' . $this->input->getInt('type_id') + . '&type_alias=' . $this->input->getCmd('type_alias') . '&' . Session::getFormToken() . '=1', false + ) + ); + } +} diff --git a/administrator/components/com_contenthistory/Controller/PreviewController.php b/administrator/components/com_contenthistory/Controller/PreviewController.php new file mode 100644 index 0000000000000..c4cf8e5da3968 --- /dev/null +++ b/administrator/components/com_contenthistory/Controller/PreviewController.php @@ -0,0 +1,38 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_contenthistory/Dispatcher/Dispatcher.php b/administrator/components/com_contenthistory/Dispatcher/Dispatcher.php new file mode 100644 index 0000000000000..2d35f34c153e6 --- /dev/null +++ b/administrator/components/com_contenthistory/Dispatcher/Dispatcher.php @@ -0,0 +1,41 @@ +app->getIdentity()->guest) + { + throw new Notallowed($this->app->getLanguage()->_('JERROR_ALERTNOAUTHOR'), 403); + } + } +} diff --git a/administrator/components/com_contenthistory/Helper/ContenthistoryHelper.php b/administrator/components/com_contenthistory/Helper/ContenthistoryHelper.php new file mode 100644 index 0000000000000..f1a31e577d5a0 --- /dev/null +++ b/administrator/components/com_contenthistory/Helper/ContenthistoryHelper.php @@ -0,0 +1,393 @@ + $value) + { + $result[$name] = $value; + + if (is_object($value)) + { + foreach ($value as $subName => $subValue) + { + $result[$subName] = $subValue; + } + } + } + + return $result; + } + + /** + * Method to decode JSON-encoded fields in a standard object. Used to unpack JSON strings in the content history data column. + * + * @param \stdClass $jsonString Standard class object that may contain one or more JSON-encoded fields. + * + * @return \stdClass Object with any JSON-encoded fields unpacked. + * + * @since 3.2 + */ + public static function decodeFields($jsonString) + { + $object = json_decode($jsonString); + + if (is_object($object)) + { + foreach ($object as $name => $value) + { + if ($subObject = json_decode($value)) + { + $object->$name = $subObject; + } + } + } + + return $object; + } + + /** + * Method to get field labels for the fields in the JSON-encoded object. + * First we see if we can find translatable labels for the fields in the object. + * We translate any we can find and return an array in the format object->name => label. + * + * @param \stdClass $object Standard class object in the format name->value. + * @param ContentType $typesTable Table object with content history options. + * + * @return \stdClass Contains two associative arrays. + * $formValues->labels in the format name => label (for example, 'id' => 'Article ID'). + * $formValues->values in the format name => value (for example, 'state' => 'Published'. + * This translates the text from the selected option in the form. + * + * @since 3.2 + */ + public static function getFormValues($object, ContentType $typesTable) + { + $labels = array(); + $values = array(); + $expandedObjectArray = static::createObjectArray($object); + static::loadLanguageFiles($typesTable->type_alias); + + if ($formFile = static::getFormFile($typesTable)) + { + if ($xml = simplexml_load_file($formFile)) + { + // Now we need to get all of the labels from the form + $fieldArray = $xml->xpath('//field'); + $fieldArray = array_merge($fieldArray, $xml->xpath('//fields')); + + foreach ($fieldArray as $field) + { + if ($label = (string) $field->attributes()->label) + { + $labels[(string) $field->attributes()->name] = Text::_($label); + } + } + + // Get values for any list type fields + $listFieldArray = $xml->xpath('//field[@type="list" or @type="radio"]'); + + foreach ($listFieldArray as $field) + { + $name = (string) $field->attributes()->name; + + if (isset($expandedObjectArray[$name])) + { + $optionFieldArray = $field->xpath('option[@value="' . $expandedObjectArray[$name] . '"]'); + + $valueText = null; + + if (is_array($optionFieldArray) && count($optionFieldArray)) + { + $valueText = trim((string) $optionFieldArray[0]); + } + + $values[(string) $field->attributes()->name] = Text::_($valueText); + } + } + } + } + + $result = new \stdClass; + $result->labels = $labels; + $result->values = $values; + + return $result; + } + + /** + * Method to get the XML form file for this component. Used to get translated field names for history preview. + * + * @param ContentType $typesTable Table object with content history options. + * + * @return mixed \JModel object if successful, false if no model found. + * + * @since 3.2 + */ + public static function getFormFile(ContentType $typesTable) + { + $result = false; + + // First, see if we have a file name in the $typesTable + $options = json_decode($typesTable->content_history_options); + + if (is_object($options) && isset($options->formFile) && File::exists(JPATH_ROOT . '/' . $options->formFile)) + { + $result = JPATH_ROOT . '/' . $options->formFile; + } + else + { + $aliasArray = explode('.', $typesTable->type_alias); + + if (count($aliasArray) == 2) + { + $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0]; + $path = Folder::makeSafe(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/'); + $file = File::makeSafe($aliasArray[1] . '.xml'); + $result = File::exists($path . $file) ? $path . $file : false; + } + } + + return $result; + } + + /** + * Method to query the database using values from lookup objects. + * + * @param \stdClass $lookup The std object with the values needed to do the query. + * @param mixed $value The value used to find the matching title or name. Typically the id. + * + * @return mixed Value from database (for example, name or title) on success, false on failure. + * + * @since 3.2 + */ + public static function getLookupValue($lookup, $value) + { + $result = false; + + if (isset($lookup->sourceColumn) && isset($lookup->targetTable) && isset($lookup->targetColumn)&& isset($lookup->displayColumn)) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query->select($db->quoteName($lookup->displayColumn)) + ->from($db->quoteName($lookup->targetTable)) + ->where($db->quoteName($lookup->targetColumn) . ' = ' . $db->quote($value)); + $db->setQuery($query); + + try + { + $result = $db->loadResult(); + } + catch (\Exception $e) + { + // Ignore any errors and just return false + return false; + } + } + + return $result; + } + + /** + * Method to remove fields from the object based on values entered in the #__content_types table. + * + * @param \stdClass $object Object to be passed to view layout file. + * @param ContentType $typeTable Table object with content history options. + * + * @return \stdClass object with hidden fields removed. + * + * @since 3.2 + */ + public static function hideFields($object, ContentType $typeTable) + { + if ($options = json_decode($typeTable->content_history_options)) + { + if (isset($options->hideFields) && is_array($options->hideFields)) + { + foreach ($options->hideFields as $field) + { + unset($object->$field); + } + } + } + + return $object; + } + + /** + * Method to load the language files for the component whose history is being viewed. + * + * @param string $typeAlias The type alias, for example 'com_content.article'. + * + * @return void + * + * @since 3.2 + */ + public static function loadLanguageFiles($typeAlias) + { + $aliasArray = explode('.', $typeAlias); + + if (is_array($aliasArray) && count($aliasArray) == 2) + { + $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0]; + $lang = Factory::getLanguage(); + + /** + * Loading language file from the administrator/language directory then + * loading language file from the administrator/components/extension/language directory + */ + $lang->load($component, JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); + + // Force loading of backend global language file + $lang->load('joomla', Path::clean(JPATH_ADMINISTRATOR), null, false, true); + } + } + + /** + * Method to create object to pass to the layout. Format is as follows: + * field is std object with name, value. + * + * Value can be a std object with name, value pairs. + * + * @param \stdClass $object The std object from the JSON string. Can be nested 1 level deep. + * @param \stdClass $formValues Standard class of label and value in an associative array. + * + * @return \stdClass Object with translated labels where available + * + * @since 3.2 + */ + public static function mergeLabels($object, $formValues) + { + $result = new \stdClass; + + if ($object === null) + { + return $result; + } + + $labelsArray = $formValues->labels; + $valuesArray = $formValues->values; + + foreach ($object as $name => $value) + { + $result->$name = new \stdClass; + $result->$name->name = $name; + $result->$name->value = $valuesArray[$name] ?? $value; + $result->$name->label = $labelsArray[$name] ?? $name; + + if (is_object($value)) + { + $subObject = new \stdClass; + + foreach ($value as $subName => $subValue) + { + $subObject->$subName = new \stdClass; + $subObject->$subName->name = $subName; + $subObject->$subName->value = $valuesArray[$subName] ?? $subValue; + $subObject->$subName->label = $labelsArray[$subName] ?? $subName; + $result->$name->value = $subObject; + } + } + } + + return $result; + } + + /** + * Method to prepare the object for the preview and compare views. + * + * @param ContentHistory $table Table object loaded with data. + * + * @return \stdClass Object ready for the views. + * + * @since 3.2 + */ + public static function prepareData(ContentHistory $table) + { + $object = static::decodeFields($table->version_data); + $typesTable = Table::getInstance('Contenttype', 'Joomla\\CMS\\Table\\'); + $typesTable->load(array('type_id' => $table->ucm_type_id)); + $formValues = static::getFormValues($object, $typesTable); + $object = static::mergeLabels($object, $formValues); + $object = static::hideFields($object, $typesTable); + $object = static::processLookupFields($object, $typesTable); + + return $object; + } + + /** + * Method to process any lookup values found in the content_history_options column for this table. + * This allows category title and user name to be displayed instead of the id column. + * + * @param \stdClass $object The std object from the JSON string. Can be nested 1 level deep. + * @param ContentType $typesTable Table object loaded with data. + * + * @return \stdClass Object with lookup values inserted. + * + * @since 3.2 + */ + public static function processLookupFields($object, ContentType $typesTable) + { + if ($options = json_decode($typesTable->content_history_options)) + { + if (isset($options->displayLookup) && is_array($options->displayLookup)) + { + foreach ($options->displayLookup as $lookup) + { + $sourceColumn = $lookup->sourceColumn ?? false; + $sourceValue = $object->$sourceColumn->value ?? false; + + if ($sourceColumn && $sourceValue && ($lookupValue = static::getLookupValue($lookup, $sourceValue))) + { + $object->$sourceColumn->value = $lookupValue; + } + } + } + } + + return $object; + } +} diff --git a/administrator/components/com_contenthistory/Model/CompareModel.php b/administrator/components/com_contenthistory/Model/CompareModel.php new file mode 100644 index 0000000000000..d5a296003d879 --- /dev/null +++ b/administrator/components/com_contenthistory/Model/CompareModel.php @@ -0,0 +1,178 @@ +input; + + /** @var ContentHistory $table1 */ + $table1 = $this->getTable('ContentHistory'); + + /** @var ContentHistory $table2 */ + $table2 = $this->getTable('ContentHistory'); + + $id1 = $input->getInt('id1'); + $id2 = $input->getInt('id2'); + $result = array(); + + if ($table1->load($id1) && $table2->load($id2)) + { + // Get the first history record's content type record so we can check ACL + /** @var ContentType $contentTypeTable */ + $contentTypeTable = $this->getTable('ContentType'); + $ucmTypeId = $table1->ucm_type_id; + + if (!$contentTypeTable->load($ucmTypeId)) + { + // Assume a failure to load the content type means broken data, abort mission + return false; + } + + $user = Factory::getUser(); + + // Access check + if ($user->authorise('core.edit', $contentTypeTable->type_alias . '.' . (int) $table1->ucm_item_id) || $this->canEdit($table1)) + { + $return = true; + } + else + { + $this->setError(Text::_('JERROR_ALERTNOAUTHOR')); + + return false; + } + + // All's well, process the records + if ($return == true) + { + $nullDate = $this->getDbo()->getNullDate(); + + foreach (array($table1, $table2) as $table) + { + $object = new \stdClass; + $object->data = ContenthistoryHelper::prepareData($table); + $object->version_note = $table->version_note; + + // Let's use custom calendars when present + $object->save_date = HTMLHelper::_('date', $table->save_date, Text::_('DATE_FORMAT_LC6')); + + $dateProperties = array ( + 'modified_time', + 'created_time', + 'modified', + 'created', + 'checked_out_time', + 'publish_up', + 'publish_down', + ); + + foreach ($dateProperties as $dateProperty) + { + if (array_key_exists($dateProperty, $object->data) && $object->data->$dateProperty->value != $nullDate) + { + $object->data->$dateProperty->value = HTMLHelper::_('date', $object->data->$dateProperty->value, Text::_('DATE_FORMAT_LC6')); + } + } + + $result[] = $object; + } + + return $result; + } + } + + return false; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return Table A Table object + * + * @since 3.2 + */ + public function getTable($type = 'Contenthistory', $prefix = 'Joomla\\CMS\\Table\\', $config = array()) + { + return Table::getInstance($type, $prefix, $config); + } + + /** + * Method to test whether a record is editable + * + * @param ContentHistory $record A \JTable object. + * + * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. + * + * @since 3.6 + */ + protected function canEdit($record) + { + $result = false; + + if (!empty($record->ucm_type_id)) + { + // Check that the type id matches the type alias + $typeAlias = Factory::getApplication()->input->get('type_alias'); + + /** @var ContentType $contentTypeTable */ + $contentTypeTable = $this->getTable('ContentType'); + + if ($contentTypeTable->getTypeId($typeAlias) == $record->ucm_type_id) + { + /** + * Make sure user has edit privileges for this content item. Note that we use edit permissions + * for the content item, not delete permissions for the content history row. + */ + $user = Factory::getUser(); + $result = $user->authorise('core.edit', $typeAlias . '.' . (int) $record->ucm_item_id); + } + + // Finally try session (this catches edit.own case too) + if (!$result) + { + $contentTypeTable->load($record->ucm_type_id); + $typeEditables = (array) Factory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); + $result = in_array((int) $record->ucm_item_id, $typeEditables); + } + } + + return $result; + } +} diff --git a/administrator/components/com_contenthistory/Model/HistoryModel.php b/administrator/components/com_contenthistory/Model/HistoryModel.php new file mode 100644 index 0000000000000..aea972cf0892d --- /dev/null +++ b/administrator/components/com_contenthistory/Model/HistoryModel.php @@ -0,0 +1,431 @@ +ucm_type_id)) + { + // Check that the type id matches the type alias + $typeAlias = Factory::getApplication()->input->get('type_alias'); + + /** @var ContentType $contentTypeTable */ + $contentTypeTable = $this->getTable('ContentType'); + + if ($contentTypeTable->getTypeId($typeAlias) == $record->ucm_type_id) + { + /** + * Make sure user has edit privileges for this content item. Note that we use edit permissions + * for the content item, not delete permissions for the content history row. + */ + $user = Factory::getUser(); + $result = $user->authorise('core.edit', $typeAlias . '.' . (int) $record->ucm_item_id); + } + + // Finally try session (this catches edit.own case too) + if (!$result) + { + $contentTypeTable->load($record->ucm_type_id); + $typeEditables = (array) Factory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); + $result = in_array((int) $record->ucm_item_id, $typeEditables); + } + } + + return $result; + } + + /** + * Method to test whether a history record can be deleted. Note that we check whether we have edit permissions + * for the content item row. + * + * @param ContentHistory $record A Table object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 3.6 + */ + protected function canDelete($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. + * + * @return boolean True if successful, false if an error occurs. + * + * @since 3.2 + */ + public function delete(&$pks) + { + $pks = (array) $pks; + $table = $this->getTable(); + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if ($this->canEdit($table)) + { + if (!$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + $error = $this->getError(); + + if ($error) + { + try + { + Log::add($error, Log::WARNING, 'jerror'); + } + catch (\RuntimeException $exception) + { + Factory::getApplication()->enqueueMessage($error, 'warning'); + } + + return false; + } + else + { + try + { + Log::add(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), Log::WARNING, 'jerror'); + } + catch (\RuntimeException $exception) + { + Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'warning'); + } + + return false; + } + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 3.4.5 + */ + public function getItems() + { + $items = parent::getItems(); + $user = Factory::getUser(); + + if ($items === false) + { + return false; + } + + // This should be an array with at least one element + if (!is_array($items) || !isset($items[0])) + { + return $items; + } + + // Get the content type's record so we can check ACL + /** @var ContentType $contentTypeTable */ + $contentTypeTable = $this->getTable('ContentType'); + $ucmTypeId = $items[0]->ucm_type_id; + + if (!$contentTypeTable->load($ucmTypeId)) + { + // Assume a failure to load the content type means broken data, abort mission + return false; + } + + // Access check + if ($user->authorise('core.edit', $contentTypeTable->type_alias . '.' . (int) $items[0]->ucm_item_id) || $this->canEdit($items[0])) + { + return $items; + } + else + { + $this->setError(Text::_('JERROR_ALERTNOAUTHOR')); + + return false; + } + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return Table A Table object + * + * @since 3.2 + */ + public function getTable($type = 'ContentHistory', $prefix = 'Joomla\\CMS\\Table\\', $config = array()) + { + return Table::getInstance($type, $prefix, $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. + * + * @return boolean True if successful, false if an error occurs. + * + * @since 3.2 + */ + public function keep(&$pks) + { + $pks = (array) $pks; + $table = $this->getTable(); + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if ($this->canEdit($table)) + { + $table->keep_forever = $table->keep_forever ? 0 : 1; + + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + $error = $this->getError(); + + if ($error) + { + try + { + Log::add($error, Log::WARNING, 'jerror'); + } + catch (\RuntimeException $exception) + { + Factory::getApplication()->enqueueMessage($error, 'warning'); + } + + return false; + } + else + { + try + { + Log::add(Text::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), Log::WARNING, 'jerror'); + } + catch (\RuntimeException $exception) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), 'warning'); + } + + return false; + } + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } + + /** + * 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.2 + */ + protected function populateState($ordering = 'h.save_date', $direction = 'DESC') + { + $input = Factory::getApplication()->input; + $itemId = $input->get('item_id', 0, 'integer'); + $typeId = $input->get('type_id', 0, 'integer'); + $typeAlias = $input->get('type_alias', '', 'string'); + + $this->setState('item_id', $itemId); + $this->setState('type_id', $typeId); + $this->setState('type_alias', $typeAlias); + $this->setState('sha1_hash', $this->getSha1Hash()); + + // Load the parameters. + $params = ComponentHelper::getParams('com_contenthistory'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery + * + * @since 3.2 + */ + 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', + 'h.version_id, h.ucm_item_id, h.ucm_type_id, h.version_note, h.save_date, h.editor_user_id,' . + 'h.character_count, h.sha1_hash, h.version_data, h.keep_forever' + ) + ) + ->from($db->quoteName('#__ucm_history') . ' AS h') + ->where($db->quoteName('h.ucm_item_id') . ' = ' . (int) $this->getState('item_id')) + ->where($db->quoteName('h.ucm_type_id') . ' = ' . (int) $this->getState('type_id')) + + // Join over the users for the editor + ->select('uc.name AS editor') + ->join('LEFT', '#__users AS uc ON uc.id = h.editor_user_id'); + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering'); + $orderDirn = $this->state->get('list.direction'); + $query->order($db->quoteName($orderCol) . $orderDirn); + + return $query; + } + + /** + * Get the sha1 hash value for the current item being edited. + * + * @return string sha1 hash of row data + * + * @since 3.2 + */ + protected function getSha1Hash() + { + $result = false; + $typeTable = $this->getTable('ContentType'); + $typeId = Factory::getApplication()->input->getInteger('type_id', 0); + $typeTable->load($typeId); + $typeAliasArray = explode('.', $typeTable->type_alias); + Table::addIncludePath(JPATH_ADMINISTRATOR . '/components/' . $typeAliasArray[0] . '/tables'); + $contentTable = $typeTable->getContentTable(); + $keyValue = Factory::getApplication()->input->getInteger('item_id', 0); + + if ($contentTable && $contentTable->load($keyValue)) + { + $helper = new CMSHelper; + + $dataObject = $helper->getDataObject($contentTable); + $result = $this->getTable('ContentHistory')->getSha1(json_encode($dataObject), $typeTable); + } + + return $result; + } +} diff --git a/administrator/components/com_contenthistory/Model/PreviewModel.php b/administrator/components/com_contenthistory/Model/PreviewModel.php new file mode 100644 index 0000000000000..82d5b8fb7dac6 --- /dev/null +++ b/administrator/components/com_contenthistory/Model/PreviewModel.php @@ -0,0 +1,162 @@ +getTable('ContentHistory'); + $versionId = Factory::getApplication()->input->getInt('version_id'); + + if (!$table->load($versionId)) + { + return false; + } + + // Get the content type's record so we can check ACL + /** @var \Joomla\CMS\Table\ContentType $contentTypeTable */ + $contentTypeTable = $this->getTable('ContentType'); + + if (!$contentTypeTable->load($table->ucm_type_id)) + { + // Assume a failure to load the content type means broken data, abort mission + return false; + } + + $user = Factory::getUser(); + + // Access check + if ($user->authorise('core.edit', $contentTypeTable->type_alias . '.' . (int) $table->ucm_item_id) || $this->canEdit($table)) + { + $return = true; + } + else + { + $this->setError(Text::_('JERROR_ALERTNOAUTHOR')); + + return false; + } + + // Good to go, finish processing the data + if ($return == true) + { + $result = new \stdClass; + $result->version_note = $table->version_note; + $result->data = ContenthistoryHelper::prepareData($table); + + // Let's use custom calendars when present + $result->save_date = HTMLHelper::_('date', $table->save_date, Text::_('DATE_FORMAT_LC6')); + + $dateProperties = array ( + 'modified_time', + 'created_time', + 'modified', + 'created', + 'checked_out_time', + 'publish_up', + 'publish_down', + ); + + $nullDate = $this->getDbo()->getNullDate(); + + foreach ($dateProperties as $dateProperty) + { + if (array_key_exists($dateProperty, $result->data) && $result->data->$dateProperty->value != $nullDate) + { + $result->data->$dateProperty->value = HTMLHelper::_('date', $result->data->$dateProperty->value, Text::_('DATE_FORMAT_LC6')); + } + } + + return $result; + } + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return Table A Table object + * + * @since 3.2 + */ + public function getTable($type = 'ContentHistory', $prefix = 'Joomla\\CMS\\Table\\', $config = array()) + { + return Table::getInstance($type, $prefix, $config); + } + + /** + * Method to test whether a record is editable + * + * @param \Joomla\CMS\Table\ContentHistory $record A Table object. + * + * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. + * + * @since 3.6 + */ + protected function canEdit($record) + { + $result = false; + + if (!empty($record->ucm_type_id)) + { + // Check that the type id matches the type alias + $typeAlias = Factory::getApplication()->input->get('type_alias'); + + /** @var \Joomla\CMS\Table\ContentType $contentTypeTable */ + $contentTypeTable = $this->getTable('ContentType'); + + if ($contentTypeTable->getTypeId($typeAlias) == $record->ucm_type_id) + { + /** + * Make sure user has edit privileges for this content item. Note that we use edit permissions + * for the content item, not delete permissions for the content history row. + */ + $user = Factory::getUser(); + $result = $user->authorise('core.edit', $typeAlias . '.' . (int) $record->ucm_item_id); + } + + // Finally try session (this catches edit.own case too) + if (!$result) + { + $contentTypeTable->load($record->ucm_type_id); + $typeEditables = (array) Factory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); + $result = in_array((int) $record->ucm_item_id, $typeEditables); + } + } + + return $result; + } +} diff --git a/administrator/components/com_contenthistory/View/Compare/HtmlView.php b/administrator/components/com_contenthistory/View/Compare/HtmlView.php new file mode 100644 index 0000000000000..dcdf6bbc6d548 --- /dev/null +++ b/administrator/components/com_contenthistory/View/Compare/HtmlView.php @@ -0,0 +1,59 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + return parent::display($tpl); + } +} diff --git a/administrator/components/com_contenthistory/View/History/HtmlView.php b/administrator/components/com_contenthistory/View/History/HtmlView.php new file mode 100644 index 0000000000000..8c7e9286ddece --- /dev/null +++ b/administrator/components/com_contenthistory/View/History/HtmlView.php @@ -0,0 +1,67 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + return parent::display($tpl); + } +} diff --git a/administrator/components/com_contenthistory/View/Preview/HtmlView.php b/administrator/components/com_contenthistory/View/Preview/HtmlView.php new file mode 100644 index 0000000000000..8d1f14c72becb --- /dev/null +++ b/administrator/components/com_contenthistory/View/Preview/HtmlView.php @@ -0,0 +1,70 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + + if (false === $this->item) + { + Factory::getLanguage()->load('com_content', JPATH_SITE, null, true); + + throw new \Exception(Text::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND'), 404); + + return false; + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + return parent::display($tpl); + } +} diff --git a/administrator/components/com_contenthistory/contenthistory.php b/administrator/components/com_contenthistory/contenthistory.php deleted file mode 100644 index e7308dd000ed4..0000000000000 --- a/administrator/components/com_contenthistory/contenthistory.php +++ /dev/null @@ -1,20 +0,0 @@ -guest) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('Contenthistory', array('base_path' => JPATH_COMPONENT_ADMINISTRATOR)); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_contenthistory/contenthistory.xml b/administrator/components/com_contenthistory/contenthistory.xml index 1e878284c7d14..76f20251957cc 100644 --- a/administrator/components/com_contenthistory/contenthistory.xml +++ b/administrator/components/com_contenthistory/contenthistory.xml @@ -9,18 +9,20 @@ www.joomla.org 3.2.0 COM_CONTENTHISTORY_XML_DESCRIPTION + Joomla\Component\Contenthistory contenthistory.php index.html - controller.php - contenthistory.php - controllers + dispatcher.php + Controller + Helper helpers - media + Model models + View views diff --git a/administrator/components/com_contenthistory/controller.php b/administrator/components/com_contenthistory/controller.php deleted file mode 100644 index fb828a28bb64a..0000000000000 --- a/administrator/components/com_contenthistory/controller.php +++ /dev/null @@ -1,19 +0,0 @@ -input->get('cid', array(), 'array'); - - if (!is_array($cid) || count($cid) < 1) - { - JError::raiseWarning(500, JText::_('COM_CONTENTHISTORY_NO_ITEM_SELECTED')); - } - else - { - // Get the model. - $model = $this->getModel(); - - // Make sure the item ids are integers - $cid = ArrayHelper::toInteger($cid); - - // Remove the items. - if ($model->delete($cid)) - { - $this->setMessage(JText::plural('COM_CONTENTHISTORY_N_ITEMS_DELETED', count($cid))); - } - else - { - $this->setMessage($model->getError()); - } - } - - $this->setRedirect( - JRoute::_( - 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' - . $this->input->getInt('item_id') . '&type_id=' . $this->input->getInt('type_id') - . '&type_alias=' . $this->input->getCmd('type_alias') . '&' . JSession::getFormToken() . '=1', false - ) - ); - } - - /** - * Proxy for getModel. - * - * @param string $name The name of the model - * @param string $prefix The prefix for the model - * @param array $config An additional array of parameters - * - * @return JModelLegacy The model - * - * @since 3.2 - */ - public function getModel($name = 'History', $prefix = 'ContenthistoryModel', $config = array('ignore_request' => true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Toggles the keep forever value for one or more history rows. If it was Yes, changes to No. If No, changes to Yes. - * - * @return void - * - * @since 3.2 - */ - public function keep() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Get items to remove from the request. - $cid = $this->input->get('cid', array(), 'array'); - - if (!is_array($cid) || count($cid) < 1) - { - JError::raiseWarning(500, JText::_('COM_CONTENTHISTORY_NO_ITEM_SELECTED')); - } - else - { - // Get the model. - $model = $this->getModel(); - - // Make sure the item ids are integers - $cid = ArrayHelper::toInteger($cid); - - // Remove the items. - if ($model->keep($cid)) - { - $this->setMessage(JText::plural('COM_CONTENTHISTORY_N_ITEMS_KEEP_TOGGLE', count($cid))); - } - else - { - $this->setMessage($model->getError()); - } - } - - $this->setRedirect( - JRoute::_( - 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' - . $this->input->getInt('item_id') . '&type_id=' . $this->input->getInt('type_id') - . '&type_alias=' . $this->input->getCmd('type_alias') . '&' . JSession::getFormToken() . '=1', false - ) - ); - } -} diff --git a/administrator/components/com_contenthistory/controllers/preview.php b/administrator/components/com_contenthistory/controllers/preview.php deleted file mode 100644 index 1f926454130f3..0000000000000 --- a/administrator/components/com_contenthistory/controllers/preview.php +++ /dev/null @@ -1,34 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_contenthistory/helpers/contenthistory.php b/administrator/components/com_contenthistory/helpers/contenthistory.php index 9077ef75b88a2..c738d556824ea 100644 --- a/administrator/components/com_contenthistory/helpers/contenthistory.php +++ b/administrator/components/com_contenthistory/helpers/contenthistory.php @@ -12,373 +12,10 @@ /** * Categories helper. * - * @since 3.2 + * @since 3.2 + * + * @deprecated 5.0 Use \Joomla\Component\Contenthistory\Administrator\Helper\ContenthistoryHelper instead */ -class ContenthistoryHelper +class ContenthistoryHelper extends \Joomla\Component\Contenthistory\Administrator\Helper\ContenthistoryHelper { - /** - * Method to put all field names, including nested ones, in a single array for easy lookup. - * - * @param stdClass $object Standard class object that may contain one level of nested objects. - * - * @return array Associative array of all field names, including ones in a nested object. - * - * @since 3.2 - */ - public static function createObjectArray($object) - { - $result = array(); - - if ($object === null) - { - return $result; - } - - foreach ($object as $name => $value) - { - $result[$name] = $value; - - if (is_object($value)) - { - foreach ($value as $subName => $subValue) - { - $result[$subName] = $subValue; - } - } - } - - return $result; - } - - /** - * Method to decode JSON-encoded fields in a standard object. Used to unpack JSON strings in the content history data column. - * - * @param stdClass $jsonString Standard class object that may contain one or more JSON-encoded fields. - * - * @return stdClass Object with any JSON-encoded fields unpacked. - * - * @since 3.2 - */ - public static function decodeFields($jsonString) - { - $object = json_decode($jsonString); - - if (is_object($object)) - { - foreach ($object as $name => $value) - { - if ($subObject = json_decode($value)) - { - $object->$name = $subObject; - } - } - } - - return $object; - } - - /** - * Method to get field labels for the fields in the JSON-encoded object. - * First we see if we can find translatable labels for the fields in the object. - * We translate any we can find and return an array in the format object->name => label. - * - * @param stdClass $object Standard class object in the format name->value. - * @param JTableContenttype $typesTable Table object with content history options. - * - * @return stdClass Contains two associative arrays. - * $formValues->labels in the format name => label (for example, 'id' => 'Article ID'). - * $formValues->values in the format name => value (for example, 'state' => 'Published'. - * This translates the text from the selected option in the form. - * - * @since 3.2 - */ - public static function getFormValues($object, JTableContenttype $typesTable) - { - $labels = array(); - $values = array(); - $expandedObjectArray = static::createObjectArray($object); - static::loadLanguageFiles($typesTable->type_alias); - - if ($formFile = static::getFormFile($typesTable)) - { - if ($xml = simplexml_load_file($formFile)) - { - // Now we need to get all of the labels from the form - $fieldArray = $xml->xpath('//field'); - $fieldArray = array_merge($fieldArray, $xml->xpath('//fields')); - - foreach ($fieldArray as $field) - { - if ($label = (string) $field->attributes()->label) - { - $labels[(string) $field->attributes()->name] = JText::_($label); - } - } - - // Get values for any list type fields - $listFieldArray = $xml->xpath('//field[@type="list" or @type="radio"]'); - - foreach ($listFieldArray as $field) - { - $name = (string) $field->attributes()->name; - - if (isset($expandedObjectArray[$name])) - { - $optionFieldArray = $field->xpath('option[@value="' . $expandedObjectArray[$name] . '"]'); - - $valueText = null; - - if (is_array($optionFieldArray) && count($optionFieldArray)) - { - $valueText = trim((string) $optionFieldArray[0]); - } - - $values[(string) $field->attributes()->name] = JText::_($valueText); - } - } - } - } - - $result = new stdClass; - $result->labels = $labels; - $result->values = $values; - - return $result; - } - - /** - * Method to get the XML form file for this component. Used to get translated field names for history preview. - * - * @param JTableContenttype $typesTable Table object with content history options. - * - * @return mixed JModel object if successful, false if no model found. - * - * @since 3.2 - */ - public static function getFormFile(JTableContenttype $typesTable) - { - $result = false; - jimport('joomla.filesystem.file'); - jimport('joomla.filesystem.folder'); - - // First, see if we have a file name in the $typesTable - $options = json_decode($typesTable->content_history_options); - - if (is_object($options) && isset($options->formFile) && JFile::exists(JPATH_ROOT . '/' . $options->formFile)) - { - $result = JPATH_ROOT . '/' . $options->formFile; - } - else - { - $aliasArray = explode('.', $typesTable->type_alias); - - if (count($aliasArray) == 2) - { - $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0]; - $path = JFolder::makeSafe(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/'); - $file = JFile::makeSafe($aliasArray[1] . '.xml'); - $result = JFile::exists($path . $file) ? $path . $file : false; - } - } - - return $result; - } - - /** - * Method to query the database using values from lookup objects. - * - * @param stdClass $lookup The std object with the values needed to do the query. - * @param mixed $value The value used to find the matching title or name. Typically the id. - * - * @return mixed Value from database (for example, name or title) on success, false on failure. - * - * @since 3.2 - */ - public static function getLookupValue($lookup, $value) - { - $result = false; - - if (isset($lookup->sourceColumn) && isset($lookup->targetTable) && isset($lookup->targetColumn)&& isset($lookup->displayColumn)) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - $query->select($db->quoteName($lookup->displayColumn)) - ->from($db->quoteName($lookup->targetTable)) - ->where($db->quoteName($lookup->targetColumn) . ' = ' . $db->quote($value)); - $db->setQuery($query); - - try - { - $result = $db->loadResult(); - } - catch (Exception $e) - { - // Ignore any errors and just return false - return false; - } - } - - return $result; - } - - /** - * Method to remove fields from the object based on values entered in the #__content_types table. - * - * @param stdClass $object Object to be passed to view layout file. - * @param JTableContenttype $typeTable Table object with content history options. - * - * @return stdClass object with hidden fields removed. - * - * @since 3.2 - */ - public static function hideFields($object, JTableContenttype $typeTable) - { - if ($options = json_decode($typeTable->content_history_options)) - { - if (isset($options->hideFields) && is_array($options->hideFields)) - { - foreach ($options->hideFields as $field) - { - unset($object->$field); - } - } - } - - return $object; - } - - /** - * Method to load the language files for the component whose history is being viewed. - * - * @param string $typeAlias The type alias, for example 'com_content.article'. - * - * @return void - * - * @since 3.2 - */ - public static function loadLanguageFiles($typeAlias) - { - $aliasArray = explode('.', $typeAlias); - - if (is_array($aliasArray) && count($aliasArray) == 2) - { - $component = ($aliasArray[1] == 'category') ? 'com_categories' : $aliasArray[0]; - $lang = JFactory::getLanguage(); - - /** - * Loading language file from the administrator/language directory then - * loading language file from the administrator/components/extension/language directory - */ - $lang->load($component, JPATH_ADMINISTRATOR, null, false, true) - || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); - - // Force loading of backend global language file - $lang->load('joomla', JPath::clean(JPATH_ADMINISTRATOR), null, false, true); - } - } - - /** - * Method to create object to pass to the layout. Format is as follows: - * field is std object with name, value. - * - * Value can be a std object with name, value pairs. - * - * @param stdClass $object The std object from the JSON string. Can be nested 1 level deep. - * @param stdClass $formValues Standard class of label and value in an associative array. - * - * @return stdClass Object with translated labels where available - * - * @since 3.2 - */ - public static function mergeLabels($object, $formValues) - { - $result = new stdClass; - - if ($object === null) - { - return $result; - } - - $labelsArray = $formValues->labels; - $valuesArray = $formValues->values; - - foreach ($object as $name => $value) - { - $result->$name = new stdClass; - $result->$name->name = $name; - $result->$name->value = isset($valuesArray[$name]) ? $valuesArray[$name] : $value; - $result->$name->label = isset($labelsArray[$name]) ? $labelsArray[$name] : $name; - - if (is_object($value)) - { - $subObject = new stdClass; - - foreach ($value as $subName => $subValue) - { - $subObject->$subName = new stdClass; - $subObject->$subName->name = $subName; - $subObject->$subName->value = isset($valuesArray[$subName]) ? $valuesArray[$subName] : $subValue; - $subObject->$subName->label = isset($labelsArray[$subName]) ? $labelsArray[$subName] : $subName; - $result->$name->value = $subObject; - } - } - } - - return $result; - } - - /** - * Method to prepare the object for the preview and compare views. - * - * @param JTableContenthistory $table Table object loaded with data. - * - * @return stdClass Object ready for the views. - * - * @since 3.2 - */ - public static function prepareData(JTableContenthistory $table) - { - $object = static::decodeFields($table->version_data); - $typesTable = JTable::getInstance('Contenttype'); - $typesTable->load(array('type_id' => $table->ucm_type_id)); - $formValues = static::getFormValues($object, $typesTable); - $object = static::mergeLabels($object, $formValues); - $object = static::hideFields($object, $typesTable); - $object = static::processLookupFields($object, $typesTable); - - return $object; - } - - /** - * Method to process any lookup values found in the content_history_options column for this table. - * This allows category title and user name to be displayed instead of the id column. - * - * @param stdClass $object The std object from the JSON string. Can be nested 1 level deep. - * @param JTableContenttype $typesTable Table object loaded with data. - * - * @return stdClass Object with lookup values inserted. - * - * @since 3.2 - */ - public static function processLookupFields($object, JTableContenttype $typesTable) - { - if ($options = json_decode($typesTable->content_history_options)) - { - if (isset($options->displayLookup) && is_array($options->displayLookup)) - { - foreach ($options->displayLookup as $lookup) - { - $sourceColumn = isset($lookup->sourceColumn) ? $lookup->sourceColumn : false; - $sourceValue = isset($object->$sourceColumn->value) ? $object->$sourceColumn->value : false; - - if ($sourceColumn && $sourceValue && ($lookupValue = static::getLookupValue($lookup, $sourceValue))) - { - $object->$sourceColumn->value = $lookupValue; - } - } - } - } - - return $object; - } } diff --git a/administrator/components/com_contenthistory/helpers/html/textdiff.php b/administrator/components/com_contenthistory/helpers/html/textdiff.php deleted file mode 100644 index c81a9c3e7d87b..0000000000000 --- a/administrator/components/com_contenthistory/helpers/html/textdiff.php +++ /dev/null @@ -1,65 +0,0 @@ - 'auto', 'relative' => true)); - JHtml::_('script', 'com_contenthistory/jquery.pretty-text-diff.min.js', array('version' => 'auto', 'relative' => true)); - JHtml::_('stylesheet', 'com_contenthistory/jquery.pretty-text-diff.css', array('version' => 'auto', 'relative' => true)); - - // Attach diff to document - JFactory::getDocument()->addScriptDeclaration(" - (function ($){ - $(document).ready(function (){ - $('#" . $containerId . " tr').prettyTextDiff(); - }); - })(jQuery); - " - ); - - // Set static array - static::$loaded[__METHOD__] = true; - - return; - } -} diff --git a/administrator/components/com_contenthistory/models/compare.php b/administrator/components/com_contenthistory/models/compare.php deleted file mode 100644 index 8221ec7e861f4..0000000000000 --- a/administrator/components/com_contenthistory/models/compare.php +++ /dev/null @@ -1,151 +0,0 @@ -input; - - /** @var JTableContenthistory $table1 */ - $table1 = JTable::getInstance('Contenthistory'); - - /** @var JTableContenthistory $table2 */ - $table2 = JTable::getInstance('Contenthistory'); - - $id1 = $input->getInt('id1'); - $id2 = $input->getInt('id2'); - $result = array(); - - if ($table1->load($id1) && $table2->load($id2)) - { - // Get the first history record's content type record so we can check ACL - /** @var JTableContenttype $contentTypeTable */ - $contentTypeTable = JTable::getInstance('Contenttype'); - $ucmTypeId = $table1->ucm_type_id; - - if (!$contentTypeTable->load($ucmTypeId)) - { - // Assume a failure to load the content type means broken data, abort mission - return false; - } - - $user = JFactory::getUser(); - - // Access check - if ($user->authorise('core.edit', $contentTypeTable->type_alias . '.' . (int) $table1->ucm_item_id) || $this->canEdit($table1)) - { - $return = true; - } - else - { - $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); - - return false; - } - - // All's well, process the records - if ($return == true) - { - foreach (array($table1, $table2) as $table) - { - $object = new stdClass; - $object->data = ContenthistoryHelper::prepareData($table); - $object->version_note = $table->version_note; - - // Let's use custom calendars when present - $object->save_date = JHtml::_('date', $table->save_date, JText::_('DATE_FORMAT_LC6')); - - $dateProperties = array ( - 'modified_time', - 'created_time', - 'modified', - 'created', - 'checked_out_time', - 'publish_up', - 'publish_down', - ); - - foreach ($dateProperties as $dateProperty) - { - if (array_key_exists($dateProperty, $object->data) && $object->data->$dateProperty->value != '0000-00-00 00:00:00') - { - $object->data->$dateProperty->value = JHtml::_('date', $object->data->$dateProperty->value, JText::_('DATE_FORMAT_LC6')); - } - } - - $result[] = $object; - } - - return $result; - } - } - - return false; - } - - /** - * Method to test whether a record is editable - * - * @param JTableContenthistory $record A JTable object. - * - * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. - * - * @since 3.6 - */ - protected function canEdit($record) - { - $result = false; - - if (!empty($record->ucm_type_id)) - { - // Check that the type id matches the type alias - $typeAlias = JFactory::getApplication()->input->get('type_alias'); - - /** @var JTableContenttype $contentTypeTable */ - $contentTypeTable = JTable::getInstance('Contenttype', 'JTable'); - - if ($contentTypeTable->getTypeId($typeAlias) == $record->ucm_type_id) - { - /** - * Make sure user has edit privileges for this content item. Note that we use edit permissions - * for the content item, not delete permissions for the content history row. - */ - $user = JFactory::getUser(); - $result = $user->authorise('core.edit', $typeAlias . '.' . (int) $record->ucm_item_id); - } - - // Finally try session (this catches edit.own case too) - if (!$result) - { - $contentTypeTable->load($record->ucm_type_id); - $typeEditables = (array) JFactory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); - $result = in_array((int) $record->ucm_item_id, $typeEditables); - } - } - - return $result; - } -} diff --git a/administrator/components/com_contenthistory/models/history.php b/administrator/components/com_contenthistory/models/history.php deleted file mode 100644 index 41d032eb7ba5b..0000000000000 --- a/administrator/components/com_contenthistory/models/history.php +++ /dev/null @@ -1,418 +0,0 @@ -ucm_type_id)) - { - // Check that the type id matches the type alias - $typeAlias = JFactory::getApplication()->input->get('type_alias'); - - /** @var JTableContenttype $contentTypeTable */ - $contentTypeTable = JTable::getInstance('Contenttype', 'JTable'); - - if ($contentTypeTable->getTypeId($typeAlias) == $record->ucm_type_id) - { - /** - * Make sure user has edit privileges for this content item. Note that we use edit permissions - * for the content item, not delete permissions for the content history row. - */ - $user = JFactory::getUser(); - $result = $user->authorise('core.edit', $typeAlias . '.' . (int) $record->ucm_item_id); - } - - // Finally try session (this catches edit.own case too) - if (!$result) - { - $contentTypeTable->load($record->ucm_type_id); - $typeEditables = (array) JFactory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); - $result = in_array((int) $record->ucm_item_id, $typeEditables); - } - } - - return $result; - } - - /** - * Method to test whether a history record can be deleted. Note that we check whether we have edit permissions - * for the content item row. - * - * @param JTableContenthistory $record A JTable object. - * - * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. - * - * @since 3.6 - */ - protected function canDelete($record) - { - return canEdit($record); - } - - /** - * Method to delete one or more records from content history table. - * - * @param array &$pks An array of record primary keys. - * - * @return boolean True if successful, false if an error occurs. - * - * @since 3.2 - */ - public function delete(&$pks) - { - $pks = (array) $pks; - $table = $this->getTable(); - - // Iterate the items to delete each one. - foreach ($pks as $i => $pk) - { - if ($table->load($pk)) - { - if ($this->canEdit($table)) - { - if (!$table->delete($pk)) - { - $this->setError($table->getError()); - - return false; - } - } - else - { - // Prune items that you can't change. - unset($pks[$i]); - $error = $this->getError(); - - if ($error) - { - try - { - JLog::add($error, JLog::WARNING, 'jerror'); - } - catch (RuntimeException $exception) - { - JFactory::getApplication()->enqueueMessage($error, 'warning'); - } - - return false; - } - else - { - try - { - JLog::add(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), JLog::WARNING, 'jerror'); - } - catch (RuntimeException $exception) - { - JFactory::getApplication()->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'warning'); - } - - return false; - } - } - } - else - { - $this->setError($table->getError()); - - return false; - } - } - - // Clear the component's cache - $this->cleanCache(); - - return true; - } - - /** - * Method to get an array of data items. - * - * @return mixed An array of data items on success, false on failure. - * - * @since 3.4.5 - */ - public function getItems() - { - $items = parent::getItems(); - $user = JFactory::getUser(); - - if ($items === false) - { - return false; - } - - // This should be an array with at least one element - if (!is_array($items) || !isset($items[0])) - { - return $items; - } - - // Get the content type's record so we can check ACL - /** @var JTableContenttype $contentTypeTable */ - $contentTypeTable = JTable::getInstance('Contenttype'); - $ucmTypeId = $items[0]->ucm_type_id; - - if (!$contentTypeTable->load($ucmTypeId)) - { - // Assume a failure to load the content type means broken data, abort mission - return false; - } - - // Access check - if ($user->authorise('core.edit', $contentTypeTable->type_alias . '.' . (int) $items[0]->ucm_item_id) || $this->canEdit($items[0])) - { - return $items; - } - else - { - $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); - - return false; - } - } - - /** - * Method to get a table object, load it if necessary. - * - * @param string $type The table name. Optional. - * @param string $prefix The class prefix. Optional. - * @param array $config Configuration array for model. Optional. - * - * @return JTable A JTable object - * - * @since 3.2 - */ - public function getTable($type = 'Contenthistory', $prefix = 'JTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $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. - * - * @return boolean True if successful, false if an error occurs. - * - * @since 3.2 - */ - public function keep(&$pks) - { - $pks = (array) $pks; - $table = $this->getTable(); - - // Iterate the items to delete each one. - foreach ($pks as $i => $pk) - { - if ($table->load($pk)) - { - if ($this->canEdit($table)) - { - $table->keep_forever = $table->keep_forever ? 0 : 1; - - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - } - else - { - // Prune items that you can't change. - unset($pks[$i]); - $error = $this->getError(); - - if ($error) - { - try - { - JLog::add($error, JLog::WARNING, 'jerror'); - } - catch (RuntimeException $exception) - { - JFactory::getApplication()->enqueueMessage($error, 'warning'); - } - - return false; - } - else - { - try - { - JLog::add(JText::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), JLog::WARNING, 'jerror'); - } - catch (RuntimeException $exception) - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED'), 'warning'); - } - - return false; - } - } - } - else - { - $this->setError($table->getError()); - - return false; - } - } - - // Clear the component's cache - $this->cleanCache(); - - return true; - } - - /** - * 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.2 - */ - protected function populateState($ordering = 'h.save_date', $direction = 'DESC') - { - $input = JFactory::getApplication()->input; - $itemId = $input->get('item_id', 0, 'integer'); - $typeId = $input->get('type_id', 0, 'integer'); - $typeAlias = $input->get('type_alias', '', 'string'); - - $this->setState('item_id', $itemId); - $this->setState('type_id', $typeId); - $this->setState('type_alias', $typeAlias); - $this->setState('sha1_hash', $this->getSha1Hash()); - - // Load the parameters. - $params = JComponentHelper::getParams('com_contenthistory'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - * - * @since 3.2 - */ - 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', - 'h.version_id, h.ucm_item_id, h.ucm_type_id, h.version_note, h.save_date, h.editor_user_id,' . - 'h.character_count, h.sha1_hash, h.version_data, h.keep_forever' - ) - ) - ->from($db->quoteName('#__ucm_history') . ' AS h') - ->where($db->quoteName('h.ucm_item_id') . ' = ' . (int) $this->getState('item_id')) - ->where($db->quoteName('h.ucm_type_id') . ' = ' . (int) $this->getState('type_id')) - - // Join over the users for the editor - ->select('uc.name AS editor') - ->join('LEFT', '#__users AS uc ON uc.id = h.editor_user_id'); - - // Add the list ordering clause. - $orderCol = $this->state->get('list.ordering'); - $orderDirn = $this->state->get('list.direction'); - $query->order($db->quoteName($orderCol) . $orderDirn); - - return $query; - } - - /** - * Get the sha1 hash value for the current item being edited. - * - * @return string sha1 hash of row data - * - * @since 3.2 - */ - protected function getSha1Hash() - { - $result = false; - $typeTable = JTable::getInstance('Contenttype', 'JTable'); - $typeId = JFactory::getApplication()->input->getInteger('type_id', 0); - $typeTable->load($typeId); - $typeAliasArray = explode('.', $typeTable->type_alias); - JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/' . $typeAliasArray[0] . '/tables'); - $contentTable = $typeTable->getContentTable(); - $keyValue = JFactory::getApplication()->input->getInteger('item_id', 0); - - if ($contentTable && $contentTable->load($keyValue)) - { - $helper = new JHelper; - - $dataObject = $helper->getDataObject($contentTable); - $result = $this->getTable('Contenthistory', 'JTable')->getSha1(json_encode($dataObject), $typeTable); - } - - return $result; - } -} diff --git a/administrator/components/com_contenthistory/models/preview.php b/administrator/components/com_contenthistory/models/preview.php deleted file mode 100644 index 267aafa53a459..0000000000000 --- a/administrator/components/com_contenthistory/models/preview.php +++ /dev/null @@ -1,137 +0,0 @@ -input->getInt('version_id'); - - if (!$table->load($versionId)) - { - return false; - } - - // Get the content type's record so we can check ACL - /** @var JTableContenttype $contentTypeTable */ - $contentTypeTable = JTable::getInstance('Contenttype'); - - if (!$contentTypeTable->load($table->ucm_type_id)) - { - // Assume a failure to load the content type means broken data, abort mission - return false; - } - - $user = JFactory::getUser(); - - // Access check - if ($user->authorise('core.edit', $contentTypeTable->type_alias . '.' . (int) $table->ucm_item_id) || $this->canEdit($table)) - { - $return = true; - } - else - { - $this->setError(JText::_('JERROR_ALERTNOAUTHOR')); - - return false; - } - - // Good to go, finish processing the data - if ($return == true) - { - $result = new stdClass; - $result->version_note = $table->version_note; - $result->data = ContenthistoryHelper::prepareData($table); - - // Let's use custom calendars when present - $result->save_date = JHtml::_('date', $table->save_date, JText::_('DATE_FORMAT_LC6')); - - $dateProperties = array ( - 'modified_time', - 'created_time', - 'modified', - 'created', - 'checked_out_time', - 'publish_up', - 'publish_down', - ); - - foreach ($dateProperties as $dateProperty) - { - if (array_key_exists($dateProperty, $result->data) && $result->data->$dateProperty->value != '0000-00-00 00:00:00') - { - $result->data->$dateProperty->value = JHtml::_('date', $result->data->$dateProperty->value, JText::_('DATE_FORMAT_LC6')); - } - } - - return $result; - } - } - - /** - * Method to test whether a record is editable - * - * @param JTableContenthistory $record A JTable object. - * - * @return boolean True if allowed to edit the record. Defaults to the permission set in the component. - * - * @since 3.6 - */ - protected function canEdit($record) - { - $result = false; - - if (!empty($record->ucm_type_id)) - { - // Check that the type id matches the type alias - $typeAlias = JFactory::getApplication()->input->get('type_alias'); - - /** @var JTableContenttype $contentTypeTable */ - $contentTypeTable = JTable::getInstance('Contenttype', 'JTable'); - - if ($contentTypeTable->getTypeId($typeAlias) == $record->ucm_type_id) - { - /** - * Make sure user has edit privileges for this content item. Note that we use edit permissions - * for the content item, not delete permissions for the content history row. - */ - $user = JFactory::getUser(); - $result = $user->authorise('core.edit', $typeAlias . '.' . (int) $record->ucm_item_id); - } - - // Finally try session (this catches edit.own case too) - if (!$result) - { - $contentTypeTable->load($record->ucm_type_id); - $typeEditables = (array) JFactory::getApplication()->getUserState(str_replace('.', '.edit.', $contentTypeTable->type_alias) . '.id'); - $result = in_array((int) $record->ucm_item_id, $typeEditables); - } - } - - return $result; - } -} diff --git a/administrator/components/com_contenthistory/services/provider.php b/administrator/components/com_contenthistory/services/provider.php new file mode 100644 index 0000000000000..12202354091e9 --- /dev/null +++ b/administrator/components/com_contenthistory/services/provider.php @@ -0,0 +1,54 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Contenthistory')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Contenthistory')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_contenthistory/tmpl/compare/compare.php b/administrator/components/com_contenthistory/tmpl/compare/compare.php new file mode 100644 index 0000000000000..3b87ef92d198d --- /dev/null +++ b/administrator/components/com_contenthistory/tmpl/compare/compare.php @@ -0,0 +1,78 @@ +items[0]; +$version1 = $this->items[1]; +$object1 = $version1->data; +$object2 = $version2->data; + +HTMLHelper::_('script', 'vendor/diff/diff.min.js', array('version' => 'auto', 'relative' => true)); +HTMLHelper::_('script', 'com_contenthistory/admin-compare-compare.min.js', array('version' => 'auto', 'relative' => true)); +?> +
+ +

+ + + + + + + + + + + + $value) : ?> + value != $object2->$name->value) : ?> + + value)) : ?> + + + + + value as $subName => $subValue) : ?> + $name->value->$subName->value ?? ''; ?> + value || $newSubValue) : ?> + value != $newSubValue) : ?> + + + + + + + + + + + + + $name->value = is_object($object2->$name->value) ? json_encode($object2->$name->value) : $object2->$name->value; ?> + + + + + + + +
+ label; ?> +    
  label; ?>value, ENT_COMPAT, 'UTF-8'); ?> 
+ label; ?> + value); ?>$name->value, ENT_COMPAT, 'UTF-8'); ?> 
+ +
diff --git a/administrator/components/com_contenthistory/tmpl/history/modal.php b/administrator/components/com_contenthistory/tmpl/history/modal.php new file mode 100644 index 0000000000000..bb0215affb4cc --- /dev/null +++ b/administrator/components/com_contenthistory/tmpl/history/modal.php @@ -0,0 +1,148 @@ +input; +$field = $input->getCmd('field'); +$function = 'jSelectContenthistory_' . $field; +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$deleteMessage = "alert(Joomla.Text._('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'));"; +$aliasArray = explode('.', $this->state->type_alias); +$option = (end($aliasArray) == 'category') ? 'com_categories&extension=' . implode('.', array_slice($aliasArray, 0, count($aliasArray) - 1)) : $aliasArray[0]; +$filter = JFilterInput::getInstance(); +$task = $filter->clean(end($aliasArray)) . '.loadhistory'; +$loadUrl = Route::_('index.php?option=' . $filter->clean($option) . '&task=' . $task); +$deleteUrl = Route::_('index.php?option=com_contenthistory&task=history.delete'); +$hash = $this->state->get('sha1_hash'); +$formUrl = 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' . $this->state->get('item_id') . '&type_id=' + . $this->state->get('type_id') . '&type_alias=' . $this->state->get('type_alias') . '&' . Session::getFormToken() . '=1'; + +Text::script('COM_CONTENTHISTORY_BUTTON_SELECT_ONE', true); +Text::script('COM_CONTENTHISTORY_BUTTON_SELECT_TWO', true); +Text::script('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'); + +HTMLHelper::_('script', 'com_contenthistory/admin-history-modal.min.js', array('version' => 'auto', 'relative' => true)); +?> +
+ +
+ + + + + +
+ +
+ + + + + + + + + + + + + + items as $item) : ?> + + + + + + + + + + + +
+ + + + + + + + + + + +
+ version_id); ?> + + + save_date, Text::_('DATE_FORMAT_LC6')); ?> + + sha1_hash == $hash) : ?> +   + + + version_note); ?> + + keep_forever) : ?> + +   + + + + + + + + editor); ?> + + character_count, 0, Text::_('DECIMALS_SEPARATOR'), Text::_('THOUSANDS_SEPARATOR')); ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
diff --git a/administrator/components/com_contenthistory/tmpl/preview/preview.php b/administrator/components/com_contenthistory/tmpl/preview/preview.php new file mode 100644 index 0000000000000..10c2ead439f20 --- /dev/null +++ b/administrator/components/com_contenthistory/tmpl/preview/preview.php @@ -0,0 +1,52 @@ + +

+item->save_date); ?> +item->version_note) : ?> +   item->version_note); ?> + +

+ + + + + + + + + item->data as $name => $value) : ?> + + value)) : ?> + + + value as $subName => $subValue) : ?> + + + + + + + + + + + + + + +
label; ?> 
  label; ?>value; ?>
label; ?>value; ?>
diff --git a/administrator/components/com_contenthistory/views/compare/tmpl/compare.php b/administrator/components/com_contenthistory/views/compare/tmpl/compare.php deleted file mode 100644 index 2b7db450efb34..0000000000000 --- a/administrator/components/com_contenthistory/views/compare/tmpl/compare.php +++ /dev/null @@ -1,97 +0,0 @@ -items[0]; -$version1 = $this->items[1]; -$object1 = $version1->data; -$object2 = $version2->data; -JHtml::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR . '/helpers/html'); -JHtml::_('textdiff.textdiff', 'diff'); - -JFactory::getDocument()->addScriptDeclaration(" - (function ($){ - $(document).ready(function (){ - jQuery('.diffhtml, .diffhtml-header').hide(); - }); - })(jQuery); -" -); - -?> -
- - -
- - - - - - -
-
- - - - - - - - - - $value) : ?> - value == $object2->$name->value) ? 'items-equal' : 'items-not-equal'; ?> - - value)) : ?> - - - - - - - - - - - - - - $name->value = is_object($object2->$name->value) ? json_encode($object2->$name->value) : $object2->$name->value; ?> - - - - - - -
- - save_date, $version1->version_note); ?>save_date, $version2->version_note); ?>
label; ?> - value as $subName => $subValue) : ?> - $name->value->$subName->value) ? $object2->$name->value->$subName->value : ''; ?> - value || $newSubValue) : ?> - value == $newSubValue) ? 'items-equal' : 'items-not-equal'; ?> -
  label; ?>value; ?> - -
label; ?>value; ?>$name->value; ?> - - -
-
diff --git a/administrator/components/com_contenthistory/views/compare/view.html.php b/administrator/components/com_contenthistory/views/compare/view.html.php deleted file mode 100644 index 59d2718c1d65e..0000000000000 --- a/administrator/components/com_contenthistory/views/compare/view.html.php +++ /dev/null @@ -1,45 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Items'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - return parent::display($tpl); - } -} diff --git a/administrator/components/com_contenthistory/views/history/tmpl/modal.php b/administrator/components/com_contenthistory/views/history/tmpl/modal.php deleted file mode 100644 index 4dc45a3c1fec2..0000000000000 --- a/administrator/components/com_contenthistory/views/history/tmpl/modal.php +++ /dev/null @@ -1,191 +0,0 @@ - 'bottom')); -JHtml::_('behavior.multiselect'); -JHtml::_('jquery.framework'); - -$input = JFactory::getApplication()->input; -$field = $input->getCmd('field'); -$function = 'jSelectContenthistory_' . $field; -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$message = JText::_('COM_CONTENTHISTORY_BUTTON_SELECT_ONE', true); -$compareMessage = JText::_('COM_CONTENTHISTORY_BUTTON_SELECT_TWO', true); -JText::script('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'); -$deleteMessage = "alert(Joomla.JText._('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST'));"; -$aliasArray = explode('.', $this->state->type_alias); -$option = (end($aliasArray) == 'category') ? 'com_categories&extension=' . implode('.', array_slice($aliasArray, 0, count($aliasArray) - 1)) : $aliasArray[0]; -$filter = JFilterInput::getInstance(); -$task = $filter->clean(end($aliasArray)) . '.loadhistory'; -$loadUrl = JRoute::_('index.php?option=' . $filter->clean($option) . '&task=' . $task); -$deleteUrl = JRoute::_('index.php?option=com_contenthistory&task=history.delete'); -$hash = $this->state->get('sha1_hash'); -$formUrl = 'index.php?option=com_contenthistory&view=history&layout=modal&tmpl=component&item_id=' . $this->state->get('item_id') . '&type_id=' - . $this->state->get('type_id') . '&type_alias=' . $this->state->get('type_alias') . '&' . JSession::getFormToken() . '=1'; - -JFactory::getDocument()->addScriptDeclaration(" - (function ($){ - $(document).ready(function (){ - $('#toolbar-load').click(function() { - var ids = $('input[id*=\'cb\']:checked'); - if (ids.length == 1) { - // Add version item id to URL - var url = $('#toolbar-load').attr('data-url') + '&version_id=' + ids[0].value; - $('#content-url').attr('data-url', url); - if (window.parent) { - window.parent.location = url; - } - } else { - alert('" . $message . "'); - } - }); - - $('#toolbar-preview').click(function() { - var windowSizeArray = ['width=800, height=600, resizable=yes, scrollbars=yes']; - var ids = $('input[id*=\'cb\']:checked'); - if (ids.length == 1) { - // Add version item id to URL - var url = $('#toolbar-preview').attr('data-url') + '&version_id=' + ids[0].value; - $('#content-url').attr('data-url', url); - if (window.parent) { - window.open(url, '', windowSizeArray); - return false; - } - } else { - alert('" . $message . "'); - } - }); - - $('#toolbar-compare').click(function() { - var windowSizeArray = ['width=1000, height=600, resizable=yes, scrollbars=yes']; - var ids = $('input[id*=\'cb\']:checked'); - if (ids.length == 2) { - // Add version item ids to URL - var url = $('#toolbar-compare').attr('data-url') + '&id1=' + ids[0].value + '&id2=' + ids[1].value; - $('#content-url').attr('data-url', url); - if (window.parent) { - window.open(url, '', windowSizeArray); - return false; - } - } else { - alert('" . $compareMessage . "'); - } - }); - }); - })(jQuery); - " -); - -?> -
- -
- - - - - -
- -
-
- -
- - - - - - - - - - - - - - - - - - - items as $item) : ?> - - - - - - - - - - - -
- - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- version_id); ?> - - - save_date, JText::_('DATE_FORMAT_LC6')); ?> - - sha1_hash == $hash) : ?> -   - - - version_note); ?> - - keep_forever) : ?> - -   - - - - - - - - editor); ?> - - character_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); ?> -
- - - - - -
-
diff --git a/administrator/components/com_contenthistory/views/history/view.html.php b/administrator/components/com_contenthistory/views/history/view.html.php deleted file mode 100644 index 0cb7e07870595..0000000000000 --- a/administrator/components/com_contenthistory/views/history/view.html.php +++ /dev/null @@ -1,48 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - return parent::display($tpl); - } -} diff --git a/administrator/components/com_contenthistory/views/preview/tmpl/preview.php b/administrator/components/com_contenthistory/views/preview/tmpl/preview.php deleted file mode 100644 index 540a635b4d317..0000000000000 --- a/administrator/components/com_contenthistory/views/preview/tmpl/preview.php +++ /dev/null @@ -1,46 +0,0 @@ - -

-item->save_date); ?> -item->version_note) : ?> -   item->version_note); ?> - -

- - - - - - -item->data as $name => $value) : ?> - - value)) : ?> - - - value as $subName => $subValue) : ?> - - - - - - - - - - - - - - -
label; ?>
  label; ?>value; ?>
label; ?>value; ?>
diff --git a/administrator/components/com_contenthistory/views/preview/view.html.php b/administrator/components/com_contenthistory/views/preview/view.html.php deleted file mode 100644 index 8b3a00b16e438..0000000000000 --- a/administrator/components/com_contenthistory/views/preview/view.html.php +++ /dev/null @@ -1,54 +0,0 @@ -state = $this->get('State'); - $this->item = $this->get('Item'); - - if (false === $this->item) - { - JFactory::getLanguage()->load('com_content', JPATH_SITE, null, true); - - JError::raiseError(404, JText::_('COM_CONTENT_ERROR_ARTICLE_NOT_FOUND')); - - return false; - } - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - return parent::display($tpl); - } -} diff --git a/administrator/components/com_cpanel/Controller/DisplayController.php b/administrator/components/com_cpanel/Controller/DisplayController.php new file mode 100644 index 0000000000000..4eaa886c92657 --- /dev/null +++ b/administrator/components/com_cpanel/Controller/DisplayController.php @@ -0,0 +1,54 @@ +input->set('tmpl', 'cpanel'); + + return parent::display($cachable, $urlparams); + } +} diff --git a/administrator/components/com_cpanel/Dispatcher/Dispatcher.php b/administrator/components/com_cpanel/Dispatcher/Dispatcher.php new file mode 100644 index 0000000000000..8ef4dc5003e41 --- /dev/null +++ b/administrator/components/com_cpanel/Dispatcher/Dispatcher.php @@ -0,0 +1,36 @@ +modules = ModuleHelper::getModules('cpanel'); + + parent::display($tpl); + } +} diff --git a/administrator/components/com_cpanel/View/Help/HtmlView.php b/administrator/components/com_cpanel/View/Help/HtmlView.php new file mode 100644 index 0000000000000..a0c0d40029230 --- /dev/null +++ b/administrator/components/com_cpanel/View/Help/HtmlView.php @@ -0,0 +1,166 @@ + [ + 'link' => 'index.php?option=com_admin&view=help', + 'title' => 'MOD_MENU_HELP_JOOMLA', + 'label' => 'MOD_MENU_HELP_JOOMLA', + 'desc' => 'MOD_MENU_HELP_JOOMLA', + 'icon' => 'info' + ], + 'help_official_forum' => [ + 'link' => 'https://forum.joomla.org', + 'title' => 'MOD_MENU_HELP_SUPPORT_OFFICIAL_FORUM', + 'label' => 'MOD_MENU_HELP_SUPPORT_OFFICIAL_FORUM', + 'desc' => 'MOD_MENU_HELP_SUPPORT_OFFICIAL_FORUM', + 'icon' => 'info' + ], + 'help_forum' => [ + 'link' => '#', + 'title' => 'MOD_MENU_HELP_SUPPORT_CUSTOM_FORUM', + 'label' => 'MOD_MENU_HELP_SUPPORT_CUSTOM_FORUM', + 'desc' => 'MOD_MENU_HELP_SUPPORT_CUSTOM_FORUM', + 'icon' => 'info' + ], + 'help_official_language' => [ + 'link' => '#', + 'title' => 'MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM', + 'label' => 'MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM', + 'desc' => 'MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM', + 'icon' => 'info' + ], + 'help_official_documentation' => [ + 'link' => 'https://docs.joomla.org', + 'title' => 'MOD_MENU_HELP_DOCUMENTATION', + 'label' => 'MOD_MENU_HELP_DOCUMENTATION', + 'desc' => 'MOD_MENU_HELP_DOCUMENTATION', + 'icon' => 'info' + ], + 'help_official_extensions' => [ + 'link' => 'https://extensions.joomla.org', + 'title' => 'MOD_MENU_HELP_EXTENSIONS', + 'label' => 'MOD_MENU_HELP_EXTENSIONS', + 'desc' => 'MOD_MENU_HELP_EXTENSIONS', + 'icon' => 'info' + ], + 'help_official_translations' => [ + 'link' => 'https://community.joomla.org/translations.html', + 'title' => 'MOD_MENU_HELP_TRANSLATIONS', + 'label' => 'MOD_MENU_HELP_TRANSLATIONS', + 'desc' => 'MOD_MENU_HELP_TRANSLATIONS', + 'icon' => 'info' + ], + 'help_resources' => [ + 'link' => 'https://resources.joomla.org', + 'title' => 'MOD_MENU_HELP_RESOURCES', + 'label' => 'MOD_MENU_HELP_RESOURCES', + 'desc' => 'MOD_MENU_HELP_RESOURCES', + 'icon' => 'info' + ], + 'help_community' => [ + 'link' => 'https://community.joomla.org', + 'title' => 'MOD_MENU_HELP_COMMUNITY', + 'label' => 'MOD_MENU_HELP_COMMUNITY', + 'desc' => 'MOD_MENU_HELP_COMMUNITY', + 'icon' => 'info' + ], + 'help_security' => [ + 'link' => 'https://developer.joomla.org/security-centre.html', + 'title' => 'MOD_MENU_HELP_SECURITY', + 'label' => 'MOD_MENU_HELP_SECURITY', + 'desc' => 'MOD_MENU_HELP_SECURITY', + 'icon' => 'info' + ], + 'help_developer' => [ + 'link' => 'https://developer.joomla.org', + 'title' => 'MOD_MENU_HELP_DEVELOPER', + 'label' => 'MOD_MENU_HELP_DEVELOPER', + 'desc' => 'MOD_MENU_HELP_DEVELOPER', + 'icon' => 'info' + ], + 'help_exchange' => [ + 'link' => 'https://joomla.stackexchange.com', + 'title' => 'MOD_MENU_HELP_XCHANGE', + 'label' => 'MOD_MENU_HELP_XCHANGE', + 'desc' => 'MOD_MENU_HELP_XCHANGE', + 'icon' => 'info' + ], + 'help_shop' => [ + 'link' => 'https://community.joomla.org/the-joomla-shop.html', + 'title' => 'MOD_MENU_HELP_SHOP', + 'label' => 'MOD_MENU_HELP_SHOP', + 'desc' => 'MOD_MENU_HELP_SHOP', + 'icon' => 'info' + ], + ]; + + if ($user->authorise('core.manage', 'com_admin')) + { + static::$notEmpty = true; + } + + if (static::$notEmpty) + { + $this->links = $links; + } + else + { + throw new NotAllowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + Factory::getLanguage()->load( + 'mod_menu', + JPATH_ADMINISTRATOR, + Factory::getLanguage()->getTag(), + true + ); + + return parent::display($tpl); + } +} diff --git a/administrator/components/com_cpanel/View/System/HtmlView.php b/administrator/components/com_cpanel/View/System/HtmlView.php new file mode 100644 index 0000000000000..7f8aa7bf64b91 --- /dev/null +++ b/administrator/components/com_cpanel/View/System/HtmlView.php @@ -0,0 +1,526 @@ +authorise('core.admin')) + { + $links['MOD_MENU_SYSTEM'] = [ + // System configuration + 'com_config' => static::arrayBuilder( + 'MOD_MENU_CONFIGURATION', + 'index.php?option=com_config', + 'cog' + ), + ]; + + $headerIcons['MOD_MENU_SYSTEM'] = 'cog'; + + static::$notEmpty = true; + } + + // Install + if ($user->authorise('core.manage', 'com_installer')) + { + // Install + $links['MOD_MENU_INSTALL'] = [ + 'com_installer_install' => static::arrayBuilder( + 'MOD_MENU_INSTALL_EXTENSIONS', + 'index.php?option=com_installer&view=install', + 'cog' + ), + 'com_installer_discover' => static::arrayBuilder( + 'MOD_MENU_INSTALL_DISCOVER', + 'index.php?option=com_installer&view=discover', + 'cog' + ), + 'com_languages_install' => static::arrayBuilder( + 'MOD_MENU_INSTALL_LANGUAGES', + 'index.php?option=com_installer&view=languages', + 'cog' + ), + ]; + + $headerIcons['MOD_MENU_INSTALL'] = 'download'; + + static::$notEmpty = true; + } + + // Templates + if ($user->authorise('core.manage', 'com_templates')) + { + // Site + $links['MOD_MENU_TEMPLATES'] = [ + 'com_templates' => static::arrayBuilder( + 'MOD_MENU_TEMPLATE_SITE_TEMPLATES', + 'index.php?option=com_templates&view=templates&client_id=0', + 'edit' + ), + 'com_templates_site_styles' => static::arrayBuilder( + 'MOD_MENU_TEMPLATE_SITE_STYLES', + 'index.php?option=com_templates&view=styles&client_id=0', + 'image' + ), + // Admin + 'com_templates_edit' => static::arrayBuilder( + 'MOD_MENU_TEMPLATE_ADMIN_TEMPLATES', + 'index.php?option=com_templates&view=templates&client_id=1', + 'edit' + ), + 'com_templates_admin_styles' => static::arrayBuilder( + 'MOD_MENU_TEMPLATE_ADMIN_STYLES', + 'index.php?option=com_templates&view=styles&client_id=1', + 'image' + ), + ]; + + $headerIcons['MOD_MENU_TEMPLATES'] = 'image'; + + static::$notEmpty = true; + } + + // Access + if ($user->authorise('core.manage', 'com_users')) + { + // Site + $links['MOD_MENU_ACCESS'] = [ + 'com_users_groups' => static::arrayBuilder( + 'MOD_MENU_ACCESS_GROUPS', + 'index.php?option=com_users&view=groups', + 'image' + ), + 'com_users_levels' => static::arrayBuilder( + 'MOD_MENU_ACCESS_LEVELS', + 'index.php?option=com_users&view=levels', + 'image' + ), + ]; + + $headerIcons['MOD_MENU_ACCESS'] = 'lock'; + + static::$notEmpty = true; + } + + // Global Configuration - Permissions and Filters + if ($user->authorise('core.admin')) + { + $new = [ + 'com_config_permissions' => static::arrayBuilder( + 'MOD_MENU_ACCESS_SETTINGS', + 'index.php?option=com_config#page-permissions', + 'refresh' + ), + 'com_config_filters' => static::arrayBuilder( + 'MOD_MENU_ACCESS_TEXT_FILTERS', + 'index.php?option=com_config#page-filters', + 'refresh' + ), + ]; + + if (!empty($links['MOD_MENU_ACCESS'])) + { + $links['MOD_MENU_ACCESS'] = array_merge($links['MOD_MENU_ACCESS'], $new); + } + else + { + $links['MOD_MENU_ACCESS'] = $new; + + $headerIcons['MOD_MENU_ACCESS'] = 'lock'; + } + + static::$notEmpty = true; + } + + // Maintain + if ($user->authorise('core.manage', 'com_cache')) + { + $links['MOD_MENU_MAINTAIN'] = [ + 'com_cache' => static::arrayBuilder( + 'MOD_MENU_CLEAR_CACHE', + 'index.php?option=com_cache', + 'trash' + ), + 'com_cache_purge' => static::arrayBuilder( + 'MOD_MENU_PURGE_EXPIRED_CACHE', + 'index.php?option=com_cache&view=purge', + 'trash' + ), + ]; + + $headerIcons['MOD_MENU_MAINTAIN'] = 'refresh'; + + static::$notEmpty = true; + } + + if ($user->authorise('core.manage', 'com_checkin')) + { + $new = [ + 'com_checkin' => static::arrayBuilder( + 'MOD_MENU_GLOBAL_CHECKIN', + 'index.php?option=com_checkin', + 'refresh' + ), + ]; + + if (!empty($links['MOD_MENU_MAINTAIN'])) + { + $links['MOD_MENU_MAINTAIN'] = array_merge($links['MOD_MENU_MAINTAIN'], $new); + } + else + { + $links['MOD_MENU_MAINTAIN'] = $new; + + $headerIcons['MOD_MENU_MAINTAIN'] = 'refresh'; + } + + static::$notEmpty = true; + } + + // Manage + if ($user->authorise('core.manage', 'com_installer')) + { + $links['MOD_MENU_MANAGE'] = [ + 'com_installer_manage' => static::arrayBuilder( + 'MOD_MENU_MANAGE_EXTENSIONS', + 'index.php?option=com_installer&view=manage', + 'cog' + ), + ]; + + $headerIcons['MOD_MENU_MANAGE'] = 'refresh'; + + static::$notEmpty = true; + } + + if ($user->authorise('core.manage', 'com_languages')) + { + $new = [ + 'com_languages_installed' => static::arrayBuilder( + 'MOD_MENU_MANAGE_LANGUAGES', + 'index.php?option=com_languages&view=installed', + 'cog' + ), + 'com_languages_content' => static::arrayBuilder( + 'MOD_MENU_MANAGE_LANGUAGES_CONTENT', + 'index.php?option=com_languages&view=languages', + 'cog' + ), + 'com_languages_overrides' => static::arrayBuilder( + 'MOD_MENU_MANAGE_LANGUAGES_OVERRIDES', + 'index.php?option=com_languages&view=overrides', + 'cog' + ), + ]; + + if (!empty($links['MOD_MENU_MANAGE'])) + { + $links['MOD_MENU_MANAGE'] = array_merge($links['MOD_MENU_MANAGE'], $new); + } + else + { + $links['MOD_MENU_MANAGE'] = $new; + + $headerIcons['MOD_MENU_MANAGE'] = 'refresh'; + } + + static::$notEmpty = true; + } + + if ($user->authorise('core.manage', 'com_csp')) + { + $new = [ + 'com_csp_main' => static::arrayBuilder( + 'MOD_MENU_MANAGE_CSP', + 'index.php?option=com_csp', + 'cog' + ), + ]; + + if (!empty($links['MOD_MENU_MANAGE'])) + { + $links['MOD_MENU_MANAGE'] = array_merge($links['MOD_MENU_MANAGE'], $new); + } + else + { + $links['MOD_MENU_MANAGE'] = $new; + + $headerIcons['MOD_MENU_MANAGE'] = 'refresh'; + } + + static::$notEmpty = true; + } + + if ($user->authorise('core.manage', 'com_plugins')) + { + $new = [ + 'com_plugins' => static::arrayBuilder( + 'MOD_MENU_MANAGE_PLUGINS', + 'index.php?option=com_plugins', + 'cog' + ), + ]; + + if (!empty($links['MOD_MENU_MANAGE'])) + { + $links['MOD_MENU_MANAGE'] = array_merge($links['MOD_MENU_MANAGE'], $new); + } + else + { + $links['MOD_MENU_MANAGE'] = $new; + + $headerIcons['MOD_MENU_MANAGE'] = 'refresh'; + } + + static::$notEmpty = true; + } + + if ($user->authorise('core.manage', 'com_redirect')) + { + $new = [ + 'com_redirect' => static::arrayBuilder( + 'MOD_MENU_MANAGE_REDIRECTS', + 'index.php?option=com_redirect', + 'cog' + ), + ]; + + if (!empty($links['MOD_MENU_MANAGE'])) + { + $links['MOD_MENU_MANAGE'] = array_merge($links['MOD_MENU_MANAGE'], $new); + } + else + { + $links['MOD_MENU_MANAGE'] = $new; + + $headerIcons['MOD_MENU_MANAGE'] = 'refresh'; + } + + static::$notEmpty = true; + } + + // Information + if ($user->authorise('core.manage', 'com_installer')) + { + $links['MOD_MENU_INFORMATION'] = [ + 'com_installer_warnings' => static::arrayBuilder( + 'MOD_MENU_INFORMATION_WARNINGS', + 'index.php?option=com_installer&view=warnings', + 'refresh' + ), + ]; + + $headerIcons['MOD_MENU_INFORMATION'] = 'refresh'; + + static::$notEmpty = true; + } + + if ($user->authorise('core.manage', 'com_postinstall')) + { + $new = [ + 'com_postinstall' => static::arrayBuilder( + 'MOD_MENU_INFORMATION_POST_INSTALL_MESSAGES', + 'index.php?option=com_postinstall', + 'info-circle' + ), + ]; + + if (!empty($links['MOD_MENU_INFORMATION'])) + { + $links['MOD_MENU_INFORMATION'] = array_merge($links['MOD_MENU_INFORMATION'], $new); + } + else + { + $links['MOD_MENU_INFORMATION'] = $new; + + $headerIcons['MOD_MENU_INFORMATION'] = 'refresh'; + } + + static::$notEmpty = true; + } + + if ($user->authorise('core.admin')) + { + $new = [ + 'com_admin_sysinfo' => static::arrayBuilder( + 'MOD_MENU_SYSTEM_INFORMATION_SYSINFO', + 'index.php?option=com_admin&view=sysinfo', + 'info' + ), + ]; + + if (!empty($links['MOD_MENU_INFORMATION'])) + { + $links['MOD_MENU_INFORMATION'] = array_merge($links['MOD_MENU_INFORMATION'], $new); + } + else + { + $links['MOD_MENU_INFORMATION'] = $new; + + $headerIcons['MOD_MENU_INFORMATION'] = 'refresh'; + } + + static::$notEmpty = true; + } + + if ($user->authorise('core.manage', 'com_installer')) + { + $new = [ + 'com_installer_database' => static::arrayBuilder( + 'MOD_MENU_SYSTEM_INFORMATION_DATABASE', + 'index.php?option=com_installer&view=database', + 'refresh' + ), + ]; + + if (!empty($links['MOD_MENU_INFORMATION'])) + { + $links['MOD_MENU_INFORMATION'] = array_merge($links['MOD_MENU_INFORMATION'], $new); + } + else + { + $links['MOD_MENU_INFORMATION'] = $new; + + $headerIcons['MOD_MENU_INFORMATION'] = 'refresh'; + } + + static::$notEmpty = true; + } + + // Update + if ($user->authorise('core.manage', 'com_joomlaupdate')) + { + $links['MOD_MENU_UPDATE'] = [ + 'com_joomlaupdate' => static::arrayBuilder( + 'MOD_MENU_UPDATE_JOOMLA', + 'index.php?option=com_joomlaupdate', + 'upload' + ), + ]; + + $headerIcons['MOD_MENU_UPDATE'] = 'upload'; + + static::$notEmpty = true; + } + + if ($user->authorise('core.manage', 'com_installer')) + { + $new = [ + 'com_installer_extensions_update' => static::arrayBuilder( + 'MOD_MENU_UPDATE_EXTENSIONS', + 'index.php?option=com_installer&view=update', + 'upload' + ), + 'com_installer_update_sites' => static::arrayBuilder( + 'MOD_MENU_UPDATE_SOURCES', + 'index.php?option=com_installer&view=updatesites', + 'edit' + ), + ]; + + if (!empty($links['MOD_MENU_UPDATE'])) + { + $links['MOD_MENU_UPDATE'] = array_merge($links['MOD_MENU_UPDATE'], $new); + } + else + { + $links['MOD_MENU_UPDATE'] = $new; + + $headerIcons['MOD_MENU_UPDATE'] = 'upload'; + } + + static::$notEmpty = true; + } + + if (static::$notEmpty) + { + $this->links = $links; + $this->headerIcons = $headerIcons; + } + else + { + throw new NotAllowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + Factory::getLanguage()->load( + 'mod_menu', + JPATH_ADMINISTRATOR, + Factory::getLanguage()->getTag(), + true + ); + + return parent::display($tpl); + } + + /** + * Helper function to build an array for each link + * + * @param string $name the name of the link + * @param string $link the url of the link + * @param string $icon the name of the icon + * + * @return array + * + * @since 4.0.0 + */ + private static function arrayBuilder($name, $link, $icon): array + { + return [ + 'link' => $link, + 'title' => $name, + 'label' => $name . '_LBL', + 'desc' => $name . '_DESC', + 'icon' => $icon + ]; + } +} diff --git a/administrator/components/com_cpanel/controller.php b/administrator/components/com_cpanel/controller.php deleted file mode 100644 index 88971f64bc608..0000000000000 --- a/administrator/components/com_cpanel/controller.php +++ /dev/null @@ -1,19 +0,0 @@ -execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_cpanel/cpanel.xml b/administrator/components/com_cpanel/cpanel.xml index ee09c6ee56243..85fe14ec1ffaf 100644 --- a/administrator/components/com_cpanel/cpanel.xml +++ b/administrator/components/com_cpanel/cpanel.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 COM_CPANEL_XML_DESCRIPTION + Joomla\Component\Cpanel controller.php diff --git a/administrator/components/com_cpanel/services/provider.php b/administrator/components/com_cpanel/services/provider.php new file mode 100644 index 0000000000000..c45e2160dc7ee --- /dev/null +++ b/administrator/components/com_cpanel/services/provider.php @@ -0,0 +1,54 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Cpanel')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Cpanel')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_cpanel/tmpl/cpanel/default.php b/administrator/components/com_cpanel/tmpl/cpanel/default.php new file mode 100644 index 0000000000000..218c786594ced --- /dev/null +++ b/administrator/components/com_cpanel/tmpl/cpanel/default.php @@ -0,0 +1,41 @@ + + +
+ +
+ +
+ +
+
+ modules as $module) + { + echo ModuleHelper::renderModule($module, array('style' => 'well')); + } + ?> +
diff --git a/administrator/components/com_cpanel/views/cpanel/tmpl/default.xml b/administrator/components/com_cpanel/tmpl/cpanel/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_cpanel/views/cpanel/tmpl/default.xml rename to administrator/components/com_cpanel/tmpl/cpanel/default.xml diff --git a/administrator/components/com_cpanel/tmpl/help/default.php b/administrator/components/com_cpanel/tmpl/help/default.php new file mode 100644 index 0000000000000..b1b05b04fc694 --- /dev/null +++ b/administrator/components/com_cpanel/tmpl/help/default.php @@ -0,0 +1,27 @@ + + +
+

+ + +

+
    + links as $link) : ?> +
  • + +
  • + +
+
\ No newline at end of file diff --git a/administrator/components/com_cpanel/tmpl/system/default.php b/administrator/components/com_cpanel/tmpl/system/default.php new file mode 100644 index 0000000000000..e31bc9830aed4 --- /dev/null +++ b/administrator/components/com_cpanel/tmpl/system/default.php @@ -0,0 +1,35 @@ + + +
+ links as $name => $links) : ?> +
+

+ headerIcons[$name]) : ?> + + + +

+
    + $link) : ?> +
  • + +
  • + +
+
+ +
+ + diff --git a/administrator/components/com_cpanel/views/cpanel/tmpl/default.php b/administrator/components/com_cpanel/views/cpanel/tmpl/default.php deleted file mode 100644 index 7523a689d5f1d..0000000000000 --- a/administrator/components/com_cpanel/views/cpanel/tmpl/default.php +++ /dev/null @@ -1,76 +0,0 @@ - -
- -
- -
- -
- authorise('core.manage', 'com_postinstall') && $this->postinstall_message_count) : ?> -
-
-

- -

-

- -

-

- -

-

- - - -

-
-
- -
- modules as $module) - { - // Get module parameters - $params = new Registry($module->params); - $bootstrapSize = $params->get('bootstrap_size'); - if (!$bootstrapSize) - { - $bootstrapSize = 12; - } - $spans += $bootstrapSize; - if ($spans > 12) - { - echo '
'; - $spans = $bootstrapSize; - } - echo JModuleHelper::renderModule($module, array('style' => 'well')); - } - ?> -
-
-
diff --git a/administrator/components/com_cpanel/views/cpanel/view.html.php b/administrator/components/com_cpanel/views/cpanel/view.html.php deleted file mode 100644 index 18e215b91326b..0000000000000 --- a/administrator/components/com_cpanel/views/cpanel/view.html.php +++ /dev/null @@ -1,67 +0,0 @@ -input; - - /* - * Set the template - this will display cpanel.php - * from the selected admin template. - */ - $input->set('tmpl', 'cpanel'); - - // Display the cpanel modules - $this->modules = JModuleHelper::getModules('cpanel'); - - try - { - $messages_model = FOFModel::getTmpInstance('Messages', 'PostinstallModel')->eid(700); - $messages = $messages_model->getItemList(); - } - catch (RuntimeException $e) - { - $messages = array(); - - // Still render the error message from the Exception object - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); - } - - $this->postinstall_message_count = count($messages); - - parent::display($tpl); - } -} diff --git a/administrator/components/com_csp/Controller/DisplayController.php b/administrator/components/com_csp/Controller/DisplayController.php new file mode 100644 index 0000000000000..d62bfac7915ec --- /dev/null +++ b/administrator/components/com_csp/Controller/DisplayController.php @@ -0,0 +1,63 @@ +app->enqueueMessage(Text::sprintf('COM_CSP_PLUGIN_MODAL_DISABLED', $link), 'error'); + } + + parent::display(); + } +} diff --git a/administrator/components/com_csp/Controller/ReportsController.php b/administrator/components/com_csp/Controller/ReportsController.php new file mode 100644 index 0000000000000..3ccb320a1a1fa --- /dev/null +++ b/administrator/components/com_csp/Controller/ReportsController.php @@ -0,0 +1,38 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_csp/Helper/ReporterHelper.php b/administrator/components/com_csp/Helper/ReporterHelper.php new file mode 100644 index 0000000000000..e11b924cfa89e --- /dev/null +++ b/administrator/components/com_csp/Helper/ReporterHelper.php @@ -0,0 +1,51 @@ +getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) + ->where($db->quoteName('element') . ' = ' . $db->quote('httpheaders')); + $db->setQuery($query); + + try + { + $result = (int) $db->loadResult(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + return $result; + } +} diff --git a/administrator/components/com_csp/Model/ReportModel.php b/administrator/components/com_csp/Model/ReportModel.php new file mode 100644 index 0000000000000..6c88f63018bcb --- /dev/null +++ b/administrator/components/com_csp/Model/ReportModel.php @@ -0,0 +1,45 @@ +getState('filter.search'); + $id .= ':' . $this->getState('filter.published'); + + return parent::getStoreId($id); + } + + /** + * Method to create a query for a list of items. + * + * @return string + * + * @since 4.0.0 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query + ->select('*') + ->from('#__csp AS a'); + + // Filter by published state + $published = (string) $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.published IN (0, 1))'); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(a.document_uri LIKE ' . $search . ' OR a.blocked_uri LIKE ' . $search . ' OR a.directive LIKE ' . $search . ')'); + } + } + + // Add the list ordering clause + $listOrdering = $this->getState('list.ordering', 'a.id'); + $listDirn = $db->escape($this->getState('list.direction', 'ASC')); + + $query->order($db->escape($listOrdering) . ' ' . $listDirn); + + return $query; + } +} diff --git a/administrator/components/com_csp/Table/ReportTable.php b/administrator/components/com_csp/Table/ReportTable.php new file mode 100644 index 0000000000000..ef84ea19d5bc9 --- /dev/null +++ b/administrator/components/com_csp/Table/ReportTable.php @@ -0,0 +1,34 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->filterForm = $this->get('FilterForm'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + if (!(PluginHelper::isEnabled('system', 'httpheaders'))) + { + $this->httpHeadersId = ReporterHelper::getHttpHeadersPluginId(); + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 4.0.0 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_csp'); + + ToolbarHelper::title(Text::_('COM_CSP_REPORTS'), 'generic'); + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publish('reports.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('reports.unpublish', 'JTOOLBAR_UNPUBLISH', true); + } + + if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'reports.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('reports.trash'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_csp'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_CSP_REPORTS'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 4.0.0 + */ + protected function getSortFields() + { + return [ + 'a.state' => Text::_('JSTATUS'), + 'a.blocked_uri' => Text::_('COM_CSP_HEADING_BLOCKED_URI'), + 'a.document_uri' => Text::_('COM_CSP_HEADING_DOCUMENT_URI'), + 'a.directive' => Text::_('COM_CSP_HEADING_DIRECTIVE'), + 'a.client' => Text::_('JCLIENT'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ]; + } +} diff --git a/administrator/components/com_csp/access.xml b/administrator/components/com_csp/access.xml new file mode 100644 index 0000000000000..5582ccc729ee1 --- /dev/null +++ b/administrator/components/com_csp/access.xml @@ -0,0 +1,12 @@ + + +
+ + + + + + + +
+
diff --git a/administrator/components/com_csp/config.xml b/administrator/components/com_csp/config.xml new file mode 100644 index 0000000000000..99c33b5ccd58e --- /dev/null +++ b/administrator/components/com_csp/config.xml @@ -0,0 +1,14 @@ + + +
+ +
+
diff --git a/administrator/components/com_csp/csp.xml b/administrator/components/com_csp/csp.xml new file mode 100644 index 0000000000000..e9a2ef3c0293e --- /dev/null +++ b/administrator/components/com_csp/csp.xml @@ -0,0 +1,41 @@ + + + com_csp + Joomla! Project + May 2018 + (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 4.0.0 + COM_CSP_XML_DESCRIPTION + Joomla\Component\Csp + + dispatcher.php + router.php + Controller + Helper + helpers + Model + + + com_csp + + access.xml + csp.php + dispatcher.php + Controller + Helper + helpers + Model + models + Table + View + views + + + language/en-GB.com_csp.ini + language/en-GB.com_csp.sys.ini + + + diff --git a/administrator/components/com_csp/forms/filter_reports.xml b/administrator/components/com_csp/forms/filter_reports.xml new file mode 100644 index 0000000000000..c084086112f3a --- /dev/null +++ b/administrator/components/com_csp/forms/filter_reports.xml @@ -0,0 +1,53 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_csp/services/provider.php b/administrator/components/com_csp/services/provider.php new file mode 100644 index 0000000000000..6f7179907a5d5 --- /dev/null +++ b/administrator/components/com_csp/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Csp')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Csp')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_csp/tmpl/reports/default.php b/administrator/components/com_csp/tmpl/reports/default.php new file mode 100644 index 0000000000000..f231923a20d97 --- /dev/null +++ b/administrator/components/com_csp/tmpl/reports/default.php @@ -0,0 +1,135 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.id'; + +?> +
+
+
+
+ $this)); ?> + httpHeadersId) : ?> + httpHeadersId . '&tmpl=component&layout=modal'); ?> + httpHeadersId . 'Modal', + array( + 'url' => $link, + 'title' => Text::_('COM_CSP_EDIT_PLUGIN_SETTINGS'), + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => '70', + 'modalWidth' => '80', + 'closeButton' => false, + 'backdrop' => 'static', + 'keyboard' => false, + 'footer' => '' + . '' + . '' + ) + ); ?> + + items)) : ?> + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + authorise('core.edit.state', 'com_csp'); ?> + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ id); ?> + +
+ published, $i, 'reports.', $canChange, 'cb'); ?> +
+
+ document_uri; ?> + + blocked_uri; ?> + + directive; ?> + + client)); ?> + + created > 0 ? HTMLHelper::_('date', $item->created, JText::_('DATE_FORMAT_LC4')) : '-'; ?> + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_fields/Controller/DisplayController.php b/administrator/components/com_fields/Controller/DisplayController.php new file mode 100644 index 0000000000000..0ac67aea0e1bc --- /dev/null +++ b/administrator/components/com_fields/Controller/DisplayController.php @@ -0,0 +1,64 @@ +input->get('view', 'fields'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($vName == 'field' && !$this->checkEditId('com_fields.edit.field', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_fields&view=fields&context=' . $this->input->get('context'), false)); + + return false; + } + + return parent::display($cachable, $urlparams); + } +} diff --git a/administrator/components/com_fields/Controller/FieldController.php b/administrator/components/com_fields/Controller/FieldController.php new file mode 100644 index 0000000000000..28d1c4ff30cf1 --- /dev/null +++ b/administrator/components/com_fields/Controller/FieldController.php @@ -0,0 +1,196 @@ +internalContext = Factory::getApplication()->getUserStateFromRequest('com_fields.fields.context', 'context', 'com_content.article', 'CMD'); + $parts = FieldsHelper::extract($this->internalContext); + $this->component = $parts ? $parts[0] : null; + } + + /** + * Method override to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since 3.7.0 + */ + protected function allowAdd($data = array()) + { + return Factory::getUser()->authorise('core.create', $this->component); + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 3.7.0 + */ + protected function allowEdit($data = array(), $key = 'id') + { + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = Factory::getUser(); + + // 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', $this->component . '.field.' . $recordId)) + { + return true; + } + + // Check edit own on the record asset (explicit or inherited) + if ($user->authorise('core.edit.own', $this->component . '.field.' . $recordId)) + { + // Existing record already has an owner, get it + $record = $this->getModel()->getItem($recordId); + + if (empty($record)) + { + return false; + } + + // Grant if current user is owner of the record + return $user->id == $record->created_by; + } + + return false; + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 3.7.0 + */ + public function batch($model = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Field'); + + // Preset the redirect + $this->setRedirect('index.php?option=com_fields&view=fields&context=' . $this->internalContext); + + return parent::batch($model); + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since 3.7.0 + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') + { + return parent::getRedirectToItemAppend($recordId) . '&context=' . $this->internalContext; + } + + /** + * Gets the URL arguments to append to a list redirect. + * + * @return string The arguments to append to the redirect URL. + * + * @since 3.7.0 + */ + protected function getRedirectToListAppend() + { + return parent::getRedirectToListAppend() . '&context=' . $this->internalContext; + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param BaseDatabaseModel $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 3.7.0 + */ + protected function postSaveHook(BaseDatabaseModel $model, $validData = array()) + { + $item = $model->getItem(); + + if (isset($item->params) && is_array($item->params)) + { + $registry = new Registry; + $registry->loadArray($item->params); + $item->params = (string) $registry; + } + + return; + } +} diff --git a/administrator/components/com_fields/Controller/FieldsController.php b/administrator/components/com_fields/Controller/FieldsController.php new file mode 100644 index 0000000000000..484d5cf58cc6b --- /dev/null +++ b/administrator/components/com_fields/Controller/FieldsController.php @@ -0,0 +1,47 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_fields/Controller/GroupController.php b/administrator/components/com_fields/Controller/GroupController.php new file mode 100644 index 0000000000000..c63c0c4565695 --- /dev/null +++ b/administrator/components/com_fields/Controller/GroupController.php @@ -0,0 +1,175 @@ +input->getCmd('context')); + + if ($parts) + { + $this->component = $parts[0]; + } + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 3.7.0 + */ + public function batch($model = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('Group'); + + // Preset the redirect + $this->setRedirect('index.php?option=com_fields&view=groups'); + + return parent::batch($model); + } + + /** + * Method override to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since 3.7.0 + */ + protected function allowAdd($data = array()) + { + return Factory::getUser()->authorise('core.create', $this->component); + } + + /** + * Method override to check if you can edit an existing record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 3.7.0 + */ + protected function allowEdit($data = array(), $key = 'parent_id') + { + $recordId = (int) isset($data[$key]) ? $data[$key] : 0; + $user = Factory::getUser(); + + // Zero record (parent_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', $this->component . '.fieldgroup.' . $recordId)) + { + return true; + } + + // Check edit own on the record asset (explicit or inherited) + if ($user->authorise('core.edit.own', $this->component . '.fieldgroup.' . $recordId) || $user->authorise('core.edit.own', $this->component)) + { + // Existing record already has an owner, get it + $record = $this->getModel()->getItem($recordId); + + if (empty($record)) + { + return false; + } + + // Grant if current user is owner of the record + return $user->id == $record->created_by; + } + + return false; + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param BaseDatabaseModel $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 3.7.0 + */ + protected function postSaveHook(BaseDatabaseModel $model, $validData = array()) + { + $item = $model->getItem(); + + if (isset($item->params) && is_array($item->params)) + { + $registry = new Registry; + $registry->loadArray($item->params); + $item->params = (string) $registry; + } + + return; + } +} diff --git a/administrator/components/com_fields/Controller/GroupsController.php b/administrator/components/com_fields/Controller/GroupsController.php new file mode 100644 index 0000000000000..bc07f2fbc32cb --- /dev/null +++ b/administrator/components/com_fields/Controller/GroupsController.php @@ -0,0 +1,47 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_fields/Dispatcher/Dispatcher.php b/administrator/components/com_fields/Dispatcher/Dispatcher.php new file mode 100644 index 0000000000000..e3c6399ef1351 --- /dev/null +++ b/administrator/components/com_fields/Dispatcher/Dispatcher.php @@ -0,0 +1,48 @@ +app->getUserStateFromRequest( + 'com_fields.groups.context', + 'context', + $this->app->getUserStateFromRequest('com_fields.fields.context', 'context', 'com_content.article', 'CMD'), + 'CMD' + ); + + $parts = FieldsHelper::extract($context); + + if (!$parts || !$this->app->getIdentity()->authorise('core.manage', $parts[0])) + { + throw new Notallowed($this->app->getLanguage()->_('JERROR_ALERTNOAUTHOR'), 403); + } + } +} diff --git a/administrator/components/com_fields/Field/FieldcontextsField.php b/administrator/components/com_fields/Field/FieldcontextsField.php new file mode 100644 index 0000000000000..23e1c9b58d29b --- /dev/null +++ b/administrator/components/com_fields/Field/FieldcontextsField.php @@ -0,0 +1,62 @@ +getOptions() ? parent::getInput() : ''; + } + + /** + * Method to get the field options. + * + * @return array The field option objects. + * + * @since 3.7.0 + */ + protected function getOptions() + { + $parts = explode('.', $this->value); + + $component = Factory::getApplication()->bootComponent($parts[0]); + + if ($component instanceof FieldsServiceInterface) + { + return $component->getContexts(); + } + + return []; + } +} diff --git a/administrator/components/com_fields/Field/FieldgroupsField.php b/administrator/components/com_fields/Field/FieldgroupsField.php new file mode 100644 index 0000000000000..a7c26547416af --- /dev/null +++ b/administrator/components/com_fields/Field/FieldgroupsField.php @@ -0,0 +1,72 @@ +element['context']; + $states = $this->element['state'] ?: '0,1'; + $states = ArrayHelper::toInteger(explode(',', $states)); + + $user = Factory::getUser(); + $viewlevels = ArrayHelper::toInteger($user->getAuthorisedViewLevels()); + + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query->select('title AS text, id AS value, state'); + $query->from('#__fields_groups'); + $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(); + + foreach ($options AS $option) + { + if ($option->state == 0) + { + $option->text = '[' . $option->text . ']'; + } + + if ($option->state == 2) + { + $option->text = '{' . $option->text . '}'; + } + } + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_fields/Field/Modal/FieldField.php b/administrator/components/com_fields/Field/Modal/FieldField.php new file mode 100644 index 0000000000000..6bf5e8272bba4 --- /dev/null +++ b/administrator/components/com_fields/Field/Modal/FieldField.php @@ -0,0 +1,201 @@ +element['context']) + { + $context = (string) $this->element['context']; + } + else + { + $context = (string) Factory::getApplication()->input->get('context', 'com_content'); + } + + $allowEdit = ((string) $this->element['edit'] == 'true') ? true : false; + $allowClear = ((string) $this->element['clear'] != 'false') ? true : false; + + // Load language + Factory::getLanguage()->load('com_fields', JPATH_ADMINISTRATOR); + + $jsId = $this->id; + + // Build the script. + // Select button script + $script = <<addScriptDeclaration($script); + + // Setup variables for display. + $html = array(); + $link = 'index.php?option=com_fields&view=fields&layout=modal&tmpl=component&context=' . $context . + '&function=jSelectCategory_' . $this->id; + + if (isset($this->element['language'])) + { + $link .= '&forcedLanguage=' . $this->element['language']; + } + + if ((int) $this->value > 0) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__fields')) + ->where($db->quoteName('id') . ' = ' . (int) $this->value); + $db->setQuery($query); + + try + { + $title = $db->loadResult(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + } + + if (empty($title)) + { + $title = Text::_('COM_FIELDS_SELECT_A_FIELD'); + } + + $title = htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); + + // The active field id field. + if (0 == (int) $this->value) + { + $value = ''; + } + else + { + $value = (int) $this->value; + } + + // The current field display field. + $html[] = ''; + $html[] = ''; + $html[] = '' . ' ' . Text::_('JSELECT') . ''; + + // Edit field button + if ($allowEdit) + { + $html[] = '' . '' . Text::_('JACTION_EDIT') . + ''; + + $html[] = HTMLHelper::_( + 'bootstrap.renderModal', 'modalCategory-' . $this->id, + array( + 'url' => $link . '&' . Session::getFormToken() . '=1"', + 'title' => Text::_('COM_FIELDS_SELECT_A_FIELD'), + 'width' => '800px', + 'height' => '300px', + 'footer' => '' + ) + ); + } + + // Clear field button + if ($allowClear) + { + $html[] = '' . '' . Text::_('JCLEAR') . + ''; + } + + $html[] = ''; + + // Note: class='required' for client side validation + $class = ''; + + if ($this->required) + { + $class = ' class="required modal-value"'; + } + + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/administrator/components/com_fields/Field/SectionField.php b/administrator/components/com_fields/Field/SectionField.php new file mode 100644 index 0000000000000..1338aafcfbb87 --- /dev/null +++ b/administrator/components/com_fields/Field/SectionField.php @@ -0,0 +1,74 @@ +` 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. + * + * @since 3.7.0 + */ + public function setup(\SimpleXMLElement $element, $value, $group = null) + { + $return = parent::setup($element, $value, $group); + + // Onchange must always be the change context function + $this->onchange = 'fieldsChangeContext(jQuery(this).val());'; + + return $return; + } + + /** + * Method to get the field input markup for a generic list. + * Use the multiple attribute to enable multiselect. + * + * @return string The field input markup. + * + * @since 3.7.0 + */ + protected function getInput() + { + // Add the change context function to the document + Factory::getDocument()->addScriptDeclaration( + "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/Field/TypeField.php b/administrator/components/com_fields/Field/TypeField.php new file mode 100644 index 0000000000000..4ae2fe91e0215 --- /dev/null +++ b/administrator/components/com_fields/Field/TypeField.php @@ -0,0 +1,99 @@ +` 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. + * + * @since 3.7.0 + */ + public function setup(\SimpleXMLElement $element, $value, $group = null) + { + $return = parent::setup($element, $value, $group); + + $this->onchange = 'typeHasChanged(this);'; + + return $return; + } + + /** + * Method to get the field options. + * + * @return array The field option objects. + * + * @since 3.7.0 + */ + protected function getOptions() + { + $options = parent::getOptions(); + + $fieldTypes = FieldsHelper::getFieldTypes(); + + foreach ($fieldTypes as $fieldType) + { + $options[] = HTMLHelper::_('select.option', $fieldType['type'], $fieldType['label']); + } + + // Sorting the fields based on the text which is displayed + usort( + $options, + function ($a, $b) + { + return strcmp($a->text, $b->text); + } + ); + + $js = <<addScriptDeclaration($js); + + return $options; + } +} diff --git a/administrator/components/com_fields/Helper/FieldsHelper.php b/administrator/components/com_fields/Helper/FieldsHelper.php new file mode 100644 index 0000000000000..8866382b9dbcb --- /dev/null +++ b/administrator/components/com_fields/Helper/FieldsHelper.php @@ -0,0 +1,715 @@ +bootComponent($parts[0]); + + if ($component instanceof FieldsServiceInterface) + { + $newSection = $component->validateSection($parts[1], $item); + } + + if ($newSection) + { + $parts[1] = $newSection; + } + + return $parts; + } + + /** + * Returns the fields for the given context. + * If the item is an object the returned fields do have an additional field + * "value" which represents the value for the given item. If the item has an + * assigned_cat_ids field, then additionally fields which belong to that + * category will be returned. + * Should the value being prepared to be shown in an HTML context then + * prepareValue must be set to true. No further escaping needs to be done. + * The values of the fields can be overridden by an associative array where the keys + * have to be a name and its corresponding value. + * + * @param string $context The context of the content passed to the helper + * @param \stdClass $item item + * @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 + * + * @since 3.7.0 + */ + public static function getFields($context, $item = null, $prepareValue = false, array $valuesToOverride = null) + { + if (self::$fieldsCache === null) + { + // Load the model + self::$fieldsCache = Factory::getApplication()->bootComponent('com_fields') + ->createMVCFactory(Factory::getApplication()) + ->createModel('Fields', 'Administrator', ['ignore_request' => true]); + + self::$fieldsCache->setState('filter.state', 1); + self::$fieldsCache->setState('list.limit', 0); + } + + if (is_array($item)) + { + $item = (object) $item; + } + + if (Multilanguage::isEnabled() && isset($item->language) && $item->language != '*') + { + self::$fieldsCache->setState('filter.language', array('*', $item->language)); + } + + self::$fieldsCache->setState('filter.context', $context); + + /* + * If item has assigned_cat_ids parameter display only fields which + * belong to the category + */ + if ($item && (isset($item->catid) || isset($item->fieldscatid))) + { + $assignedCatIds = $item->catid ?? $item->fieldscatid; + + if (!is_array($assignedCatIds)) + { + $assignedCatIds = explode(',', $assignedCatIds); + } + + // Fields without any category assigned should show as well + $assignedCatIds[] = 0; + + self::$fieldsCache->setState('filter.assigned_cat_ids', $assignedCatIds); + } + + $fields = self::$fieldsCache->getItems(); + + if ($fields === false) + { + return array(); + } + + if ($item && isset($item->id)) + { + if (self::$fieldCache === null) + { + self::$fieldCache = Factory::getApplication()->bootComponent('com_fields') + ->createMVCFactory(Factory::getApplication()) + ->createModel('Field', 'Administrator', ['ignore_request' => true]); + } + + $fieldIds = array_map( + function ($f) + { + return $f->id; + }, + $fields + ); + + $fieldValues = self::$fieldCache->getFieldValues($fieldIds, $item->id); + + $new = array(); + + foreach ($fields as $key => $original) + { + /* + * Doing a clone, otherwise fields for different items will + * always reference to the same object + */ + $field = clone $original; + + if ($valuesToOverride && array_key_exists($field->name, $valuesToOverride)) + { + $field->value = $valuesToOverride[$field->name]; + } + elseif ($valuesToOverride && array_key_exists($field->id, $valuesToOverride)) + { + $field->value = $valuesToOverride[$field->id]; + } + elseif (array_key_exists($field->id, $fieldValues)) + { + $field->value = $fieldValues[$field->id]; + } + + if (!isset($field->value) || $field->value === '') + { + $field->value = $field->default_value; + } + + $field->rawvalue = $field->value; + + // 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'))) + { + PluginHelper::importPlugin('fields'); + + /* + * On before field prepare + * Event allow plugins to modfify the output of the field before it is prepared + */ + Factory::getApplication()->triggerEvent('onCustomFieldsBeforePrepareField', array($context, $item, &$field)); + + // Gathering the value for the field + $value = Factory::getApplication()->triggerEvent('onCustomFieldsPrepareField', array($context, $item, &$field)); + + if (is_array($value)) + { + $value = implode(' ', $value); + } + + /* + * On after field render + * Event allows plugins to modify the output of the prepared field + */ + Factory::getApplication()->triggerEvent('onCustomFieldsAfterPrepareField', array($context, $item, $field, &$value)); + + // Assign the value + $field->value = $value; + } + + $new[$key] = $field; + } + + $fields = $new; + } + + return $fields; + } + + /** + * Renders the layout file and data on the context and does a fall back to + * Fields afterwards. + * + * @param string $context The context of the content passed to the helper + * @param string $layoutFile layoutFile + * @param array $displayData displayData + * + * @return NULL|string + * + * @since 3.7.0 + */ + public static function render($context, $layoutFile, $displayData) + { + $value = ''; + + /* + * Because the layout refreshes the paths before the render function is + * called, so there is no way to load the layout overrides in the order + * template -> context -> fields. + * If there is no override in the context then we need to call the + * layout from Fields. + */ + if ($parts = self::extract($context)) + { + // Trying to render the layout on the component from the context + $value = LayoutHelper::render($layoutFile, $displayData, null, array('component' => $parts[0], 'client' => 0)); + } + + if ($value == '') + { + // Trying to render the layout on Fields itself + $value = LayoutHelper::render($layoutFile, $displayData, null, array('component' => 'com_fields','client' => 0)); + } + + return $value; + } + + /** + * PrepareForm + * + * @param string $context The context of the content passed to the helper + * @param Form $form form + * @param object $data data. + * + * @return boolean + * + * @since 3.7.0 + */ + public static function prepareForm($context, Form $form, $data) + { + // Extracting the component and section + $parts = self::extract($context); + + if (! $parts) + { + return true; + } + + $context = $parts[0] . '.' . $parts[1]; + + // When no fields available return here + $fields = self::getFields($parts[0] . '.' . $parts[1], new CMSObject); + + if (! $fields) + { + return true; + } + + $component = $parts[0]; + $section = $parts[1]; + + $assignedCatids = $data->catid ?? $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); + + // Choose the first category available + $xml = new \DOMDocument; + $xml->loadHTML($formField->__get('input')); + $options = $xml->getElementsByTagName('option'); + + if (!$assignedCatids && $firstChoice = $options->item(0)) + { + $assignedCatids = $firstChoice->getAttribute('value'); + } + + $data->fieldscatid = $assignedCatids; + } + + /* + * If there is a catid field we need to reload the page when the catid + * is changed + */ + if ($form->getField('catid') && $parts[0] != 'com_fields') + { + /* + * Setting the onchange event to reload the page when the category + * has changed + */ + $form->setFieldAttribute('catid', 'onchange', 'categoryHasChanged(this);'); + + // Preload spindle-wheel when we need to submit form due to category selector changed + Factory::getDocument()->addScriptDeclaration(" + function categoryHasChanged(element) { + var cat = jQuery(element); + if (cat.val() == '" . $assignedCatids . "')return; + Joomla.loadingLayer('show'); + jQuery('input[name=task]').val('" . $section . ".reload'); + element.form.submit(); + } + jQuery( document ).ready(function() { + Joomla.loadingLayer('load'); + var formControl = '#" . $form->getFormControl() . "_catid'; + if (!jQuery(formControl).val() != '" . $assignedCatids . "'){jQuery(formControl).val('" . $assignedCatids . "');} + });" + ); + } + + // Getting the fields + $fields = self::getFields($parts[0] . '.' . $parts[1], $data); + + if (!$fields) + { + return true; + } + + $fieldTypes = self::getFieldTypes(); + + // Creating the dom + $xml = new \DOMDocument('1.0', 'UTF-8'); + $fieldsNode = $xml->appendChild(new \DOMElement('form'))->appendChild(new \DOMElement('fields')); + $fieldsNode->setAttribute('name', 'com_fields'); + + // Organizing the fields according to their group + $fieldsPerGroup = array(0 => array()); + + foreach ($fields as $field) + { + if (!array_key_exists($field->type, $fieldTypes)) + { + // Field type is not available + continue; + } + + if (!array_key_exists($field->group_id, $fieldsPerGroup)) + { + $fieldsPerGroup[$field->group_id] = array(); + } + + if ($path = $fieldTypes[$field->type]['path']) + { + // Add the lookup path for the field + FormHelper::addFieldPath($path); + } + + if ($path = $fieldTypes[$field->type]['rules']) + { + // Add the lookup path for the rule + FormHelper::addRulePath($path); + } + + $fieldsPerGroup[$field->group_id][] = $field; + } + + $model = Factory::getApplication()->bootComponent('com_fields') + ->createMVCFactory(Factory::getApplication()) + ->createModel('Groups', 'Administrator', ['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 ($iterateGroups as $group) + { + if (empty($fieldsPerGroup[$group->id])) + { + continue; + } + + // Defining the field set + /** @var DOMElement $fieldset */ + $fieldset = $fieldsNode->appendChild(new \DOMElement('fieldset')); + $fieldset->setAttribute('name', 'fields-' . $group->id); + $fieldset->setAttribute('addfieldpath', '/administrator/components/' . $component . '/models/fields'); + $fieldset->setAttribute('addrulepath', '/administrator/components/' . $component . '/models/rules'); + + $label = $group->title; + $description = $group->description; + + if (!$label) + { + $key = strtoupper($component . '_FIELDS_' . $section . '_LABEL'); + + if (!Factory::getLanguage()->hasKey($key)) + { + $key = 'JGLOBAL_FIELDS'; + } + + $label = $key; + } + + if (!$description) + { + $key = strtoupper($component . '_FIELDS_' . $section . '_DESC'); + + if (Factory::getLanguage()->hasKey($key)) + { + $description = $key; + } + } + + $fieldset->setAttribute('label', $label); + $fieldset->setAttribute('description', strip_tags($description)); + + // Looping through the fields for that context + foreach ($fieldsPerGroup[$group->id] as $field) + { + try + { + Factory::getApplication()->triggerEvent('onCustomFieldsPrepareDom', array($field, $fieldset, $form)); + + /* + * If the field belongs to an assigned_cat_id but the assigned_cat_ids in the data + * is not known, set the required flag to false on any circumstance. + */ + if (!$assignedCatids && !empty($field->assigned_cat_ids) && $form->getField($field->name)) + { + $form->setFieldAttribute($field->name, 'required', 'false'); + } + } + catch (\Exception $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + } + + // When the field set is empty, then remove it + if (!$fieldset->hasChildNodes()) + { + $fieldsNode->removeChild($fieldset); + } + } + + // Loading the XML fields string into the form + $form->load($xml->saveXML()); + + $model = Factory::getApplication()->bootComponent('com_fields') + ->createMVCFactory(Factory::getApplication()) + ->createModel('Field', 'Administrator', ['ignore_request' => true]); + + if ((!isset($data->id) || !$data->id) && Factory::getApplication()->input->getCmd('controller') == 'modules' + && Factory::getApplication()->isClient('site')) + { + // Modules on front end editing don't have data and an id set + $data->id = Factory::getApplication()->input->getInt('id'); + } + + // Looping through the fields again to set the value + if (!isset($data->id) || !$data->id) + { + return true; + } + + foreach ($fields as $field) + { + $value = $model->getFieldValue($field->id, $data->id); + + if ($value === null) + { + continue; + } + + if (!is_array($value) && $value !== '') + { + // Function getField doesn't cache the fields, so we try to do it only when necessary + $formField = $form->getField($field->name, 'com_fields'); + + if ($formField && $formField->forceMultiple) + { + $value = (array) $value; + } + } + + // Setting the value on the field + $form->setValue($field->name, 'com_fields', $value); + } + + return true; + } + + /** + * Return a boolean if the actual logged in user can edit the given field value. + * + * @param \stdClass $field The field + * + * @return boolean + * + * @since 3.7.0 + */ + public static function canEditFieldValue($field) + { + $parts = self::extract($field->context); + + return Factory::getUser()->authorise('core.edit.value', $parts[0] . '.field.' . (int) $field->id); + } + + /** + * Gets assigned categories titles for a field + * + * @param \stdClass[] $fieldId The field ID + * + * @return array Array with the assigned categories + * + * @since 3.7.0 + */ + public static function getAssignedCategoriesTitles($fieldId) + { + $fieldId = (int) $fieldId; + + if (!$fieldId) + { + return array(); + } + + $db = Factory::getDbo(); + $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); + + $db->setQuery($query); + + return $db->loadColumn(); + } + + /** + * Gets the fields system plugin extension id. + * + * @return integer The fields system plugin extension id. + * + * @since 3.7.0 + */ + public static function getFieldsPluginId() + { + $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('fields')); + $db->setQuery($query); + + try + { + $result = (int) $db->loadResult(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + $result = 0; + } + + return $result; + } + + /** + * Configure the Linkbar. + * + * @param string $context The context the fields are used for + * @param string $vName The view currently active + * + * @return void + * + * @since 3.7.0 + */ + public static function addSubmenu($context, $vName) + { + $parts = self::extract($context); + + if (!$parts) + { + return; + } + + $component = $parts[0]; + + // Avoid nonsense situation. + if ($component == 'com_fields') + { + return; + } + + // 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)) + { + return; + } + + require_once $file; + + $cName = ucfirst($eName) . 'Helper'; + + if (class_exists($cName) && is_callable(array($cName, 'addSubmenu'))) + { + $lang = Factory::getLanguage(); + $lang->load($component, JPATH_ADMINISTRATOR) + || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component); + + $cName::addSubmenu('fields.' . $vName); + } + } + + /** + * Loads the fields plugins and returns an array of field types from the plugins. + * + * The returned array contains arrays with the following keys: + * - label: The label of the field + * - type: The type of the field + * - path: The path of the folder where the field can be found + * + * @return array + * + * @since 3.7.0 + */ + public static function getFieldTypes() + { + PluginHelper::importPlugin('fields'); + $eventData = Factory::getApplication()->triggerEvent('onCustomFieldsGetTypes'); + + $data = array(); + + foreach ($eventData as $fields) + { + foreach ($fields as $fieldDescription) + { + if (!array_key_exists('path', $fieldDescription)) + { + $fieldDescription['path'] = null; + } + + if (!array_key_exists('rules', $fieldDescription)) + { + $fieldDescription['rules'] = null; + } + + $data[$fieldDescription['type']] = $fieldDescription; + } + } + + 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/Model/FieldModel.php b/administrator/components/com_fields/Model/FieldModel.php new file mode 100644 index 0000000000000..845cf2dd8c5d3 --- /dev/null +++ b/administrator/components/com_fields/Model/FieldModel.php @@ -0,0 +1,1173 @@ + 'batchAccess', + 'language_id' => 'batchLanguage' + ); + + /** + * @var array + * + * @since 3.7.0 + */ + private $valueCache = array(); + + /** + * Constructor + * + * @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request). + * @param MVCFactoryInterface $factory The factory. + * + * @since 3.7.0 + * @throws \Exception + */ + public function __construct($config = array(), MVCFactoryInterface $factory = null) + { + parent::__construct($config, $factory); + + $this->typeAlias = Factory::getApplication()->input->getCmd('context', 'com_content.article') . '.field'; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success, False on error. + * + * @since 3.7.0 + */ + public function save($data) + { + $field = null; + + if (isset($data['id']) && $data['id']) + { + $field = $this->getItem($data['id']); + } + + if (!isset($data['label']) && isset($data['params']['label'])) + { + $data['label'] = $data['params']['label']; + + unset($data['params']['label']); + } + + // Alter the title for save as copy + $input = Factory::getApplication()->input; + + if ($input->get('task') == 'save2copy') + { + $origTable = clone $this->getTable(); + $origTable->load($input->getInt('id')); + + if ($data['title'] == $origTable->title) + { + list($title, $name) = $this->generateNewTitle($data['group_id'], $data['name'], $data['title']); + $data['title'] = $title; + $data['label'] = $title; + $data['name'] = $name; + } + else + { + if ($data['name'] == $origTable->name) + { + $data['name'] = ''; + } + } + + $data['state'] = 0; + } + + // Load the fields plugins, perhaps they want to do something + PluginHelper::importPlugin('fields'); + + $message = $this->checkDefaultValue($data); + + if ($message !== true) + { + $this->setError($message); + + return false; + } + + if (!parent::save($data)) + { + return false; + } + + // Save the assigned categories into #__fields_categories + $db = $this->getDbo(); + $id = (int) $this->getState('field.id'); + $cats = isset($data['assigned_cat_ids']) ? (array) $data['assigned_cat_ids'] : array(); + $cats = ArrayHelper::toInteger($cats); + + $assignedCatIds = array(); + + foreach ($cats as $cat) + { + if ($cat) + { + $assignedCatIds[] = $cat; + } + } + + // First delete all assigned categories + $query = $db->getQuery(true); + $query->delete('#__fields_categories') + ->where('field_id = ' . $id); + $db->setQuery($query); + $db->execute(); + + // Inset new assigned categories + $tupel = new \stdClass; + $tupel->field_id = $id; + + foreach ($assignedCatIds as $catId) + { + $tupel->category_id = $catId; + $db->insertObject('#__fields_categories', $tupel); + } + + // If the options have changed delete the values + if ($field && isset($data['fieldparams']['options']) && isset($field->fieldparams['options'])) + { + $oldParams = $this->getParams($field->fieldparams['options']); + $newParams = $this->getParams($data['fieldparams']['options']); + + if (is_object($oldParams) && is_object($newParams) && $oldParams != $newParams) + { + $names = array(); + + foreach ($newParams as $param) + { + $names[] = $db->quote($param['value']); + } + + $query = $db->getQuery(true); + $query->delete('#__fields_values')->where('field_id = ' . (int) $field->id) + ->where('value NOT IN (' . implode(',', $names) . ')'); + $db->setQuery($query); + $db->execute(); + } + } + + FieldsHelper::clearFieldsCache(); + + return true; + } + + + /** + * Checks if the default value is valid for the given data. If a string is returned then + * it can be assumed that the default value is invalid. + * + * @param array $data The data. + * + * @return true|string true if valid, a string containing the exception message when not. + * + * @since 3.7.0 + */ + private function checkDefaultValue($data) + { + // Empty default values are correct + if (empty($data['default_value'])) + { + return true; + } + + $types = FieldsHelper::getFieldTypes(); + + // Check if type exists + if (!array_key_exists($data['type'], $types)) + { + return true; + } + + $path = $types[$data['type']]['rules']; + + // Add the path for the rules of the plugin when available + if ($path) + { + // Add the lookup path for the rule + \JFormHelper::addRulePath($path); + } + + // Create the fields object + $obj = (object) $data; + $obj->params = new Registry($obj->params); + $obj->fieldparams = new Registry(!empty($obj->fieldparams) ? $obj->fieldparams : array()); + + // Prepare the dom + $dom = new \DOMDocument; + $node = $dom->appendChild(new \DOMElement('form')); + + // Trigger the event to create the field dom node + Factory::getApplication()->triggerEvent('onCustomFieldsPrepareDom', array($obj, $node, new \JForm($data['context']))); + + // Check if a node is created + if (!$node->firstChild) + { + return true; + } + + // Define the type either from the field or from the data + $type = $node->firstChild->getAttribute('validate') ? : $data['type']; + + // Load the rule + $rule = \JFormHelper::loadRuleType($type); + + // When no rule exists, we allow the default value + if (!$rule) + { + return true; + } + + try + { + // Perform the check + $result = $rule->test(simplexml_import_dom($node->firstChild), $data['default_value']); + + // Check if the test succeeded + return $result === true ? : Text::_('COM_FIELDS_FIELD_INVALID_DEFAULT_VALUE'); + } + catch (\UnexpectedValueException $e) + { + return $e->getMessage(); + } + } + + /** + * Converts the unknown params into an object. + * + * @param mixed $params The params. + * + * @return \stdClass Object on success, false on failure. + * + * @since 3.7.0 + */ + private function getParams($params) + { + if (is_string($params)) + { + $params = json_decode($params); + } + + if (is_array($params)) + { + $params = (object) $params; + } + + return $params; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 3.7.0 + */ + public function getItem($pk = null) + { + $result = parent::getItem($pk); + + if ($result) + { + // Prime required properties. + if (empty($result->id)) + { + $result->context = Factory::getApplication()->input->getCmd('context', $this->getState('field.context')); + } + + if (property_exists($result, 'fieldparams')) + { + $registry = new Registry; + + if ($result->fieldparams) + { + $registry->loadString($result->fieldparams); + } + + $result->fieldparams = $registry->toArray(); + } + + $db = $this->getDbo(); + $query = $db->getQuery(true); + $query->select('category_id') + ->from('#__fields_categories') + ->where('field_id = ' . (int) $result->id); + + $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(Factory::getApplication()->get('offset')); + + if ((int) $result->created_time) + { + $date = new Date($result->created_time); + $date->setTimezone($tz); + + $result->created_time = $date->toSql(true); + } + else + { + $result->created_time = null; + } + + if ((int) $result->modified_time) + { + $date = new Date($result->modified_time); + $date->setTimezone($tz); + + $result->modified_time = $date->toSql(true); + } + else + { + $result->modified_time = null; + } + } + + return $result; + } + + /** + * 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 Table A JTable object + * + * @since 3.7.0 + * @throws \Exception + */ + public function getTable($name = 'Field', $prefix = 'Administrator', $options = array()) + { + // Default to text type + $table = parent::getTable($name, $prefix, $options); + $table->type = 'text'; + + return $table; + } + + /** + * 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. + * + * @return array Contains the modified title and name. + * + * @since 3.7.0 + */ + protected function generateNewTitle($category_id, $name, $title) + { + // Alter the title & name + $table = $this->getTable(); + + while ($table->load(array('name' => $name))) + { + $title = StringHelper::increment($title); + $name = StringHelper::increment($name, 'dash'); + } + + return array( + $title, + $name, + ); + } + + /** + * Method to delete one or more records. + * + * @param array &$pks An array of record primary keys. + * + * @return boolean True if successful, false if an error occurs. + * + * @since 3.7.0 + */ + public function delete(&$pks) + { + $success = parent::delete($pks); + + if ($success) + { + $pks = (array) $pks; + $pks = ArrayHelper::toInteger($pks); + $pks = array_filter($pks); + + if (!empty($pks)) + { + // Delete Values + $query = $this->getDbo()->getQuery(true); + + $query->delete($query->quoteName('#__fields_values')) + ->where($query->quoteName('field_id') . ' IN(' . implode(',', $pks) . ')'); + + $this->getDbo()->setQuery($query)->execute(); + + // Delete Assigned Categories + $query = $this->getDbo()->getQuery(true); + + $query->delete($query->quoteName('#__fields_categories')) + ->where($query->quoteName('field_id') . ' IN(' . implode(',', $pks) . ')'); + + $this->getDbo()->setQuery($query)->execute(); + } + } + + return $success; + } + + /** + * Abstract 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 mixed A \JForm object on success, false on failure + * + * @since 3.7.0 + */ + public function getForm($data = array(), $loadData = true) + { + $context = $this->getState('field.context'); + $jinput = Factory::getApplication()->input; + + // A workaround to get the context into the model for save requests. + if (empty($context) && isset($data['context'])) + { + $context = $data['context']; + $parts = FieldsHelper::extract($context); + + $this->setState('field.context', $context); + + if ($parts) + { + $this->setState('field.component', $parts[0]); + $this->setState('field.section', $parts[1]); + } + } + + if (isset($data['type'])) + { + // This is needed that the plugins can determine the type + $this->setState('field.type', $data['type']); + } + + // Load the fields plugin that they can add additional parameters to the form + PluginHelper::importPlugin('fields'); + + // Get the form. + $form = $this->loadForm( + 'com_fields.field' . $context, 'field', + array( + 'control' => 'jform', + 'load_data' => true, + ) + ); + + if (empty($form)) + { + return false; + } + + // Modify the form based on Edit State access controls. + if (empty($data['context'])) + { + $data['context'] = $context; + } + + $fieldId = $jinput->get('id'); + $assetKey = $this->state->get('field.component') . '.field.' . $fieldId; + + if (!Factory::getUser()->authorise('core.edit.state', $assetKey)) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('state', 'disabled', 'true'); + + // Disable fields while saving. The controller has already verified this is a record you can edit. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('state', 'filter', 'unset'); + } + + return $form; + } + + /** + * 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. + * @param string $value The value. + * + * @return boolean + * + * @since 3.7.0 + */ + public function setFieldValue($fieldId, $itemId, $value) + { + $field = $this->getItem($fieldId); + $params = $field->params; + + if (is_array($params)) + { + $params = new Registry($params); + } + + // Don't save the value when the user is not authorized to change it + if (!$field || !FieldsHelper::canEditFieldValue($field)) + { + return false; + } + + $needsDelete = false; + $needsInsert = false; + $needsUpdate = false; + + $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 when not empty + $needsUpdate = is_array($value[0]) ? count($value[0]) : strlen($value[0]); + $needsDelete = !$needsUpdate; + } + else + { + // Multiple values, we need to purge the data and do a new + // insert + $needsDelete = true; + $needsInsert = true; + } + + if ($needsDelete) + { + // Deleting the existing record as it is a reset + $query = $this->getDbo()->getQuery(true); + + $query->delete($query->quoteName('#__fields_values')) + ->where($query->quoteName('field_id') . ' = ' . (int) $fieldId) + ->where($query->quoteName('item_id') . ' = ' . $query->quote($itemId)); + + $this->getDbo()->setQuery($query)->execute(); + } + + if ($needsInsert) + { + $newObj = new \stdClass; + + $newObj->field_id = (int) $fieldId; + $newObj->item_id = $itemId; + + foreach ($value as $v) + { + $newObj->value = $v; + + $this->getDbo()->insertObject('#__fields_values', $newObj); + } + } + + if ($needsUpdate) + { + $updateObj = new \stdClass; + + $updateObj->field_id = (int) $fieldId; + $updateObj->item_id = $itemId; + $updateObj->value = reset($value); + + $this->getDbo()->updateObject('#__fields_values', $updateObj, array('field_id', 'item_id')); + } + + $this->valueCache = array(); + FieldsHelper::clearFieldsCache(); + + return true; + } + + /** + * Returning 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. + * + * @return NULL|string + * + * @since 3.7.0 + */ + public function getFieldValue($fieldId, $itemId) + { + $values = $this->getFieldValues(array($fieldId), $itemId); + + if (array_key_exists($fieldId, $values)) + { + return $values[$fieldId]; + } + + return null; + } + + /** + * Returning the values for the given field ids, context and item id. + * + * @param array $fieldIds The field Ids. + * @param string $itemId The ID of the item. + * + * @return NULL|array + * + * @since 3.7.0 + */ + public function getFieldValues(array $fieldIds, $itemId) + { + if (!$fieldIds) + { + return array(); + } + + // Create a unique key for the cache + $key = md5(serialize($fieldIds) . $itemId); + + // Fill the cache when it doesn't exist + if (!array_key_exists($key, $this->valueCache)) + { + // Create the query + $query = $this->getDbo()->getQuery(true); + + $query->select(array($query->quoteName('field_id'), $query->quoteName('value'))) + ->from($query->quoteName('#__fields_values')) + ->where($query->quoteName('field_id') . ' IN (' . implode(',', ArrayHelper::toInteger($fieldIds)) . ')') + ->where($query->quoteName('item_id') . ' = ' . $query->quote($itemId)); + + // Fetch the row from the database + $rows = $this->getDbo()->setQuery($query)->loadObjectList(); + + $data = array(); + + // Fill the data container from the database rows + foreach ($rows as $row) + { + // If there are multiple values for a field, create an array + if (array_key_exists($row->field_id, $data)) + { + // Transform it to an array + if (!is_array($data[$row->field_id])) + { + $data[$row->field_id] = array($data[$row->field_id]); + } + + // Set the value in the array + $data[$row->field_id][] = $row->value; + + // Go to the next row, otherwise the value gets overwritten in the data container + continue; + } + + // Set the value + $data[$row->field_id] = $row->value; + } + + // Assign it to the internal cache + $this->valueCache[$key] = $data; + } + + // Return the value from the cache + return $this->valueCache[$key]; + } + + /** + * Cleaning up the values for the given item on the context. + * + * @param string $context The context. + * @param string $itemId The Item ID. + * + * @return void + * + * @since 3.7.0 + */ + public function cleanupValues($context, $itemId) + { + // Delete with inner join is not possible so we need to do a subquery + $fieldsQuery = $this->getDbo()->getQuery(true); + $fieldsQuery->select($fieldsQuery->quoteName('id')) + ->from($fieldsQuery->quoteName('#__fields')) + ->where($fieldsQuery->quoteName('context') . ' = ' . $fieldsQuery->quote($context)); + + $query = $this->getDbo()->getQuery(true); + + $query->delete($query->quoteName('#__fields_values')) + ->where($query->quoteName('field_id') . ' IN (' . $fieldsQuery . ')') + ->where($query->quoteName('item_id') . ' = ' . $query->quote($itemId)); + + $this->getDbo()->setQuery($query)->execute(); + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission for the component. + * + * @since 3.7.0 + */ + protected function canDelete($record) + { + if (!empty($record->id)) + { + if ($record->state != -2) + { + return false; + } + + $parts = FieldsHelper::extract($record->context); + + return Factory::getUser()->authorise('core.delete', $parts[0] . '.field.' . (int) $record->id); + } + + 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 for the + * component. + * + * @since 3.7.0 + */ + protected function canEditState($record) + { + $user = Factory::getUser(); + $parts = FieldsHelper::extract($record->context); + + // Check for existing field. + if (!empty($record->id)) + { + return $user->authorise('core.edit.state', $parts[0] . '.field.' . (int) $record->id); + } + + return $user->authorise('core.edit.state', $parts[0]); + } + + /** + * Stock method to auto-populate the model state. + * + * @return void + * + * @since 3.7.0 + */ + protected function populateState() + { + $app = Factory::getApplication(); + + // Load the User state. + $pk = $app->input->getInt('id'); + $this->setState($this->getName() . '.id', $pk); + + $context = $app->input->get('context', 'com_content.article'); + $this->setState('field.context', $context); + $parts = FieldsHelper::extract($context); + + // Extract the component name + $this->setState('field.component', $parts[0]); + + // Extract the optional section name + $this->setState('field.section', (count($parts) > 1) ? $parts[1] : null); + + // Load the parameters. + $params = ComponentHelper::getParams('com_fields'); + $this->setState('params', $params); + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param JTable $table A JTable object. + * + * @return array An array of conditions to add to ordering queries. + * + * @since 3.7.0 + */ + protected function getReorderConditions($table) + { + return 'context = ' . $this->_db->quote($table->context); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return array The default data is an empty array. + * + * @since 3.7.0 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $app = Factory::getApplication(); + $data = $app->getUserState('com_fields.edit.field.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + + // Pre-select some filters (Status, Language, Access) in edit form + // if those have been selected in Category Manager + if (!$data->id) + { + // Check for which context the Category Manager is used and + // get selected fields + $filters = (array) $app->getUserState('com_fields.fields.filter'); + + $data->set('state', $app->input->getInt('state', ((isset($filters['state']) && $filters['state'] !== '') ? $filters['state'] : null))); + $data->set('language', $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null))); + $data->set('group_id', $app->input->getString('group_id', (!empty($filters['group_id']) ? $filters['group_id'] : null))); + $data->set( + 'access', + $app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : Factory::getConfig()->get('access'))) + ); + + // Set the type if available from the request + $data->set('type', $app->input->getWord('type', $this->state->get('field.type', $data->get('type')))); + } + + if ($data->label && !isset($data->params['label'])) + { + $data->params['label'] = $data->label; + } + } + + $this->preprocessData('com_fields.field', $data); + + return $data; + } + + /** + * Method to allow derived classes to preprocess the form. + * + * @param \JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @see \JFormField + * @since 3.7.0 + * @throws \Exception if there is an error in the form event. + */ + protected function preprocessForm(\JForm $form, $data, $group = 'content') + { + $component = $this->state->get('field.component'); + $section = $this->state->get('field.section'); + $dataObject = $data; + + if (is_array($dataObject)) + { + $dataObject = (object) $dataObject; + } + + if (isset($dataObject->type)) + { + $form->setFieldAttribute('type', 'component', $component); + + // Not allowed to change the type of an existing record + if ($dataObject->id) + { + $form->setFieldAttribute('type', 'readonly', 'true'); + } + + // Allow to override the default value label and description through the plugin + $key = 'PLG_FIELDS_' . strtoupper($dataObject->type) . '_DEFAULT_VALUE_LABEL'; + + if (Factory::getLanguage()->hasKey($key)) + { + $form->setFieldAttribute('default_value', 'label', $key); + } + + $key = 'PLG_FIELDS_' . strtoupper($dataObject->type) . '_DEFAULT_VALUE_DESC'; + + if (Factory::getLanguage()->hasKey($key)) + { + $form->setFieldAttribute('default_value', 'description', $key); + } + + // Remove placeholder field on list fields + if ($dataObject->type == 'list') + { + $form->removeField('hint', 'params'); + } + } + + try + { + // Setting the context for the category field + $componentObject = $this->bootComponent($component); + + if (!$componentObject instanceof CategoriesServiceInterface) + { + throw new SectionNotFoundException; + } + + $cat = $componentObject->getCategories(); + + if ($cat->get('root')->hasChildren()) + { + $form->setFieldAttribute('assigned_cat_ids', 'extension', $component); + } + else + { + $form->removeField('assigned_cat_ids'); + } + } + catch (SectionNotFoundException $e) + { + $form->removeField('assigned_cat_ids'); + } + + $form->setFieldAttribute('type', 'component', $component); + $form->setFieldAttribute('group_id', 'context', $this->state->get('field.context')); + $form->setFieldAttribute('rules', 'component', $component); + + // Looking in the component forms folder for a specific section forms file + $path = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/forms/fields/' . $section . '.xml'); + + if (!file_exists($path)) + { + // Looking in the component models/forms folder for a specific section forms file + $path = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/fields/' . $section . '.xml'); + } + + if (file_exists($path)) + { + $lang = Factory::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(Text::_('JERROR_LOADFILE_FAILED')); + } + } + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * Clean the cache + * + * @param string $group The cache group + * @param integer $client_id The ID of the client + * + * @return void + * + * @since 3.7.0 + */ + protected function cleanCache($group = null, $client_id = 0) + { + $context = Factory::getApplication()->input->get('context'); + + switch ($context) + { + case 'com_content': + parent::cleanCache('com_content'); + parent::cleanCache('mod_articles_archive'); + parent::cleanCache('mod_articles_categories'); + parent::cleanCache('mod_articles_category'); + parent::cleanCache('mod_articles_latest'); + parent::cleanCache('mod_articles_news'); + parent::cleanCache('mod_articles_popular'); + break; + default: + parent::cleanCache($context); + break; + } + } + + /** + * Batch copy fields to a new group. + * + * @param integer $value The new value matching a fields group. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return array|boolean new IDs if successful, false otherwise and internal error is set. + * + * @since 3.7.0 + */ + protected function batchCopy($value, $pks, $contexts) + { + // Set the variables + $user = Factory::getUser(); + $table = $this->getTable(); + $newIds = array(); + $component = $this->state->get('filter.component'); + $value = (int) $value; + + foreach ($pks as $pk) + { + if ($user->authorise('core.create', $component . '.fieldgroup.' . $value)) + { + $table->reset(); + $table->load($pk); + + $table->group_id = $value; + + // Reset the ID because we are making a copy + $table->id = 0; + + // Unpublish the new field + $table->state = 0; + + 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; + } + else + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + + /** + * Batch move fields to a new group. + * + * @param integer $value The new value matching a fields group. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 3.7.0 + */ + protected function batchMove($value, $pks, $contexts) + { + // Set the variables + $user = Factory::getUser(); + $table = $this->getTable(); + $context = explode('.', Factory::getApplication()->getUserState('com_fields.fields.context')); + $value = (int) $value; + + foreach ($pks as $pk) + { + if ($user->authorise('core.edit', $context[0] . '.fieldgroup.' . $value)) + { + $table->reset(); + $table->load($pk); + + $table->group_id = $value; + + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + else + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } +} diff --git a/administrator/components/com_fields/Model/FieldsModel.php b/administrator/components/com_fields/Model/FieldsModel.php new file mode 100644 index 0000000000000..a164d1e938b32 --- /dev/null +++ b/administrator/components/com_fields/Model/FieldsModel.php @@ -0,0 +1,398 @@ +getUserStateFromRequest($this->context . '.context', 'context', 'com_content.article', 'CMD'); + $this->setState('filter.context', $context); + + // Split context into component and optional section + $parts = FieldsHelper::extract($context); + + if ($parts) + { + $this->setState('filter.component', $parts[0]); + $this->setState('filter.section', $parts[1]); + } + } + + /** + * Method to get a store id based on the 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 An identifier string to generate the store id. + * + * @return string A store id. + * + * @since 3.7.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.context'); + $id .= ':' . serialize($this->getState('filter.assigned_cat_ids')); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.group_id'); + $id .= ':' . serialize($this->getState('filter.language')); + + return parent::getStoreId($id); + } + + /** + * Method to get a JDatabaseQuery object for retrieving the data set from a database. + * + * @return \JDatabaseQuery A JDatabaseQuery object to retrieve the data set. + * + * @since 3.7.0 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = Factory::getUser(); + $app = Factory::getApplication(); + + // Select the required fields from the table. + $query->select( + $this->getState( + 'list.select', + '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' + ) + ); + $query->from('#__fields AS a'); + + // Join over the language + $query->select('l.title AS language_title, l.image AS language_image') + ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor')->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); + + // Join over the asset groups. + $query->select('ag.title AS access_level')->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + + // Join over the users for the author. + $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->join('LEFT', '#__fields_groups AS g ON g.id = a.group_id'); + + // Filter by context + if ($context = $this->getState('filter.context')) + { + $query->where('a.context = ' . $db->quote($context)); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + if (is_array($access)) + { + $access = ArrayHelper::toInteger($access); + $query->where('a.access in (' . implode(',', $access) . ')'); + } + else + { + $query->where('a.access = ' . (int) $access); + } + } + + if (($categories = $this->getState('filter.assigned_cat_ids')) && $context) + { + $categories = (array) $categories; + $categories = ArrayHelper::toInteger($categories); + $parts = FieldsHelper::extract($context); + + if ($parts) + { + // Get the category + $cat = Categories::getInstance(str_replace('com_', '', $parts[0])); + + if ($cat) + { + foreach ($categories as $assignedCatIds) + { + // Check if we have the actual category + $parent = $cat->get($assignedCatIds); + + if ($parent) + { + $categories[] = (int) $parent->id; + + // Traverse the tree up to get all the fields which are attached to a parent + while ($parent->getParent() && $parent->getParent()->id != 'root') + { + $parent = $parent->getParent(); + $categories[] = (int) $parent->id; + } + } + } + } + } + + $categories = array_unique($categories); + + // Join over the assigned categories + $query->join('LEFT', $db->quoteName('#__fields_categories') . ' AS fc ON fc.field_id = a.id'); + + if (in_array('0', $categories)) + { + $query->where('(fc.category_id IS NULL OR fc.category_id IN (' . implode(',', $categories) . '))'); + } + else + { + $query->where('fc.category_id IN (' . implode(',', $categories) . ')'); + } + } + + // Implement View Level Access + if (!$app->isClient('administrator') || !$user->authorise('core.admin')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ') AND (a.group_id = 0 OR g.access IN (' . $groups . '))'); + } + + // Filter by state + $state = $this->getState('filter.state'); + + // Include group state only when not on on back end list + $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); + + if ($includeGroupState) + { + $query->where('(a.group_id = 0 OR g.state = ' . (int) $state . ')'); + } + } + elseif (!$state) + { + $query->where('a.state IN (0, 1)'); + + if ($includeGroupState) + { + $query->where('(a.group_id = 0 OR g.state IN (0, 1))'); + } + } + + $groupId = $this->getState('filter.group_id'); + + if (is_numeric($groupId)) + { + $query->where('a.group_id = ' . (int) $groupId); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (! empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'author:') === 0) + { + $search = $db->quote('%' . $db->escape(substr($search, 7), true) . '%'); + $query->where('(ua.name LIKE ' . $search . ' OR ua.username LIKE ' . $search . ')'); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(a.title LIKE ' . $search . ' OR a.name LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); + } + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + $language = (array) $language; + + foreach ($language as $key => $l) + { + $language[$key] = $db->quote($l); + } + + $query->where('a.language in (' . implode(',', $language) . ')'); + } + + // Add the list ordering clause + $listOrdering = $this->state->get('list.ordering', 'a.ordering'); + $orderDirn = $this->state->get('list.direction', 'ASC'); + + $query->order($db->escape($listOrdering) . ' ' . $db->escape($orderDirn)); + + 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.7.0 + * @throws \RuntimeException + */ + protected function _getList($query, $limitstart = 0, $limit = 0) + { + $result = parent::_getList($query, $limitstart, $limit); + + if (is_array($result)) + { + foreach ($result as $field) + { + $field->fieldparams = new Registry($field->fieldparams); + $field->params = new Registry($field->params); + } + } + + return $result; + } + + /** + * Get the filter form + * + * @param array $data data + * @param boolean $loadData load current data + * + * @return \JForm|false the JForm object or false + * + * @since 3.7.0 + */ + public function getFilterForm($data = array(), $loadData = true) + { + $form = parent::getFilterForm($data, $loadData); + + if ($form) + { + $form->setValue('context', null, $this->getState('filter.context')); + $form->setFieldAttribute('group_id', 'context', $this->getState('filter.context'), 'filter'); + $form->setFieldAttribute('assigned_cat_ids', 'extension', $this->state->get('filter.component'), 'filter'); + } + + return $form; + } + + /** + * Get the groups for the batch method + * + * @return array An array of groups + * + * @since 3.7.0 + */ + public function getGroups() + { + $user = Factory::getUser(); + $viewlevels = ArrayHelper::toInteger($user->getAuthorisedViewLevels()); + + $db = $this->getDbo(); + $query = $db->getQuery(true); + $query->select('title AS text, id AS value, state'); + $query->from('#__fields_groups'); + $query->where('state IN (0,1)'); + $query->where('context = ' . $db->quote($this->state->get('filter.context'))); + $query->where('access IN (' . implode(',', $viewlevels) . ')'); + + $db->setQuery($query); + + return $db->loadObjectList(); + } +} diff --git a/administrator/components/com_fields/Model/GroupModel.php b/administrator/components/com_fields/Model/GroupModel.php new file mode 100644 index 0000000000000..d694160c01ae0 --- /dev/null +++ b/administrator/components/com_fields/Model/GroupModel.php @@ -0,0 +1,356 @@ + 'batchAccess', + 'language_id' => 'batchLanguage' + ); + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success, False on error. + * + * @since 3.7.0 + */ + public function save($data) + { + // Alter the title for save as copy + $input = Factory::getApplication()->input; + + // Save new group as unpublished + if ($input->get('task') == 'save2copy') + { + $data['state'] = 0; + } + + return parent::save($data); + } + + /** + * Abstract 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 mixed A JForm object on success, false on failure + * + * @since 3.7.0 + */ + public function getForm($data = array(), $loadData = true) + { + $context = $this->getState('filter.context'); + $jinput = Factory::getApplication()->input; + + if (empty($context) && isset($data['context'])) + { + $context = $data['context']; + $this->setState('filter.context', $context); + } + + // Get the form. + $form = $this->loadForm( + 'com_fields.group.' . $context, 'group', + array( + 'control' => 'jform', + 'load_data' => $loadData, + ) + ); + + if (empty($form)) + { + return false; + } + + // Modify the form based on Edit State access controls. + if (empty($data['context'])) + { + $data['context'] = $context; + } + + if (!Factory::getUser()->authorise('core.edit.state', $context . '.fieldgroup.' . $jinput->get('id'))) + { + // Disable fields for display. + $form->setFieldAttribute('ordering', 'disabled', 'true'); + $form->setFieldAttribute('state', 'disabled', 'true'); + + // Disable fields while saving. The controller has already verified this is a record you can edit. + $form->setFieldAttribute('ordering', 'filter', 'unset'); + $form->setFieldAttribute('state', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission for the component. + * + * @since 3.7.0 + */ + protected function canDelete($record) + { + if (empty($record->id) || $record->state != -2) + { + return false; + } + + return Factory::getUser()->authorise('core.delete', $record->context . '.fieldgroup.' . (int) $record->id); + } + + /** + * 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 for the + * component. + * + * @since 3.7.0 + */ + protected function canEditState($record) + { + $user = Factory::getUser(); + + // Check for existing fieldgroup. + if (!empty($record->id)) + { + return $user->authorise('core.edit.state', $record->context . '.fieldgroup.' . (int) $record->id); + } + + // Default to component settings. + return $user->authorise('core.edit.state', $record->context); + } + + /** + * Auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 3.7.0 + */ + protected function populateState() + { + parent::populateState(); + + $context = Factory::getApplication()->getUserStateFromRequest('com_fields.groups.context', 'context', 'com_fields', 'CMD'); + $this->setState('filter.context', $context); + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param Table $table A Table object. + * + * @return array An array of conditions to add to ordering queries. + * + * @since 3.7.0 + */ + protected function getReorderConditions($table) + { + return 'context = ' . $this->_db->quote($table->context); + } + + /** + * Method to preprocess the form. + * + * @param \JForm $form A JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @see \JFormField + * @since 3.7.0 + * @throws \Exception if there is an error in the form event. + */ + protected function preprocessForm(\JForm $form, $data, $group = 'content') + { + parent::preprocessForm($form, $data, $group); + + $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', $component); + } + + if ($section !== null) + { + // Looking first in the component models/forms folder + $path = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/fieldgroup/' . $section . '.xml'); + + if (file_exists($path)) + { + $lang = Factory::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(Text::_('JERROR_LOADFILE_FAILED')); + } + } + } + } + + /** + * Method to get the data that should be injected in the form. + * + * @return array The default data is an empty array. + * + * @since 3.7.0 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $app = Factory::getApplication(); + $data = $app->getUserState('com_fields.edit.group.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + + // Pre-select some filters (Status, Language, Access) in edit form if those have been selected in Field Group Manager + if (!$data->id) + { + // Check for which context the Field Group Manager is used and get selected fields + $context = substr($app->getUserState('com_fields.groups.filter.context'), 4); + $filters = (array) $app->getUserState('com_fields.groups.' . $context . '.filter'); + + $data->set( + 'state', + $app->input->getInt('state', (!empty($filters['state']) ? $filters['state'] : null)) + ); + $data->set( + 'language', + $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null)) + ); + $data->set( + 'access', + $app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : Factory::getConfig()->get('access'))) + ); + } + } + + $this->preprocessData('com_fields.group', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 3.7.0 + */ + public function getItem($pk = null) + { + if ($item = parent::getItem($pk)) + { + // Prime required properties. + if (empty($item->id)) + { + $item->context = $this->getState('filter.context'); + } + + // Convert the created and modified dates to local user time for display in the form. + $tz = new \DateTimeZone(Factory::getApplication()->get('offset')); + + if ((int) $item->created) + { + $date = new Date($item->created); + $date->setTimezone($tz); + $item->created = $date->toSql(true); + } + else + { + $item->created = null; + } + + if ((int) $item->modified) + { + $date = new Date($item->modified); + $date->setTimezone($tz); + $item->modified = $date->toSql(true); + } + else + { + $item->modified = null; + } + } + + return $item; + } + + /** + * Clean the cache + * + * @param string $group The cache group + * @param integer $client_id The ID of the client + * + * @return void + * + * @since 3.7.0 + */ + protected function cleanCache($group = null, $client_id = 0) + { + $context = Factory::getApplication()->input->get('context'); + + parent::cleanCache($context); + } +} diff --git a/administrator/components/com_fields/Model/GroupsModel.php b/administrator/components/com_fields/Model/GroupsModel.php new file mode 100644 index 0000000000000..44eb54a9fc422 --- /dev/null +++ b/administrator/components/com_fields/Model/GroupsModel.php @@ -0,0 +1,223 @@ +getUserStateFromRequest($this->context . '.context', 'context', 'com_content', 'CMD'); + $this->setState('filter.context', $context); + } + + /** + * Method to get a store id based on the 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 An identifier string to generate the store id. + * + * @return string A store id. + * + * @since 3.7.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.context'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . print_r($this->getState('filter.language'), true); + + return parent::getStoreId($id); + } + + /** + * Method to get a JDatabaseQuery object for retrieving the data set from a database. + * + * @return \JDatabaseQuery A JDatabaseQuery object to retrieve the data set. + * + * @since 3.7.0 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = Factory::getUser(); + + // Select the required fields from the table. + $query->select($this->getState('list.select', 'a.*')); + $query->from('#__fields_groups AS a'); + + // Join over the language + $query->select('l.title AS language_title, l.image AS language_image') + ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor')->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); + + // Join over the asset groups. + $query->select('ag.title AS access_level')->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + + // 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'); + + // Filter by context + if ($context = $this->getState('filter.context', 'com_fields')) + { + $query->where('a.context = ' . $db->quote($context)); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + if (is_array($access)) + { + $access = ArrayHelper::toInteger($access); + $query->where('a.access in (' . implode(',', $access) . ')'); + } + else + { + $query->where('a.access = ' . (int) $access); + } + } + + // Implement View Level Access + if (!$user->authorise('core.admin')) + { + $groups = implode(',', $user->getAuthorisedViewLevels()); + $query->where('a.access IN (' . $groups . ')'); + } + + // Filter by published state + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where('a.state = ' . (int) $state); + } + elseif (!$state) + { + $query->where('a.state IN (0, 1)'); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.title LIKE ' . $search); + } + } + + // Filter on the language. + if ($language = $this->getState('filter.language')) + { + $language = (array) $language; + + foreach ($language as $key => $l) + { + $language[$key] = $db->quote($l); + } + + $query->where('a.language in (' . implode(',', $language) . ')'); + } + + // Add the list ordering clause + $listOrdering = $this->getState('list.ordering', 'a.ordering'); + $listDirn = $db->escape($this->getState('list.direction', 'ASC')); + + $query->order($db->escape($listOrdering) . ' ' . $listDirn); + + return $query; + } +} diff --git a/administrator/components/com_fields/Plugin/FieldsListPlugin.php b/administrator/components/com_fields/Plugin/FieldsListPlugin.php new file mode 100644 index 0000000000000..ee007e14cca32 --- /dev/null +++ b/administrator/components/com_fields/Plugin/FieldsListPlugin.php @@ -0,0 +1,82 @@ +setAttribute('validate', 'options'); + + foreach ($this->getOptionsFromField($field) as $value => $name) + { + $option = new \DOMElement('option', htmlspecialchars($value, ENT_COMPAT, 'UTF-8')); + $option->textContent = htmlspecialchars(Text::_($name), ENT_COMPAT, 'UTF-8'); + + $element = $fieldNode->appendChild($option); + $element->setAttribute('value', $value); + } + + return $fieldNode; + } + + /** + * Returns an array of key values to put in a list from the given field. + * + * @param \stdClass $field The field. + * + * @return array + * + * @since 3.7.0 + */ + public function getOptionsFromField($field) + { + $data = array(); + + // Fetch the options from the plugin + $params = clone $this->params; + $params->merge($field->fieldparams); + + foreach ($params->get('options', array()) as $option) + { + $op = (object) $option; + $data[$op->value] = $op->name; + } + + return $data; + } +} diff --git a/administrator/components/com_fields/Plugin/FieldsPlugin.php b/administrator/components/com_fields/Plugin/FieldsPlugin.php new file mode 100644 index 0000000000000..36f80d1a7d318 --- /dev/null +++ b/administrator/components/com_fields/Plugin/FieldsPlugin.php @@ -0,0 +1,295 @@ +_type . $this->_name])) + { + return $types_cache[$this->_type . $this->_name]; + } + + $types = array(); + + // The root of the plugin + $root = JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name; + + foreach (Folder::files($root . '/tmpl', '.php') as $layout) + { + // Strip the extension + $layout = str_replace('.php', '', $layout); + + // The data array + $data = array(); + + // The language key + $key = strtoupper($layout); + + if ($key != strtoupper($this->_name)) + { + $key = strtoupper($this->_name) . '_' . $layout; + } + + // Needed attributes + $data['type'] = $layout; + + if (Factory::getLanguage()->hasKey('PLG_FIELDS_' . $key . '_LABEL')) + { + $data['label'] = Text::sprintf('PLG_FIELDS_' . $key . '_LABEL', strtolower($key)); + + // Fix wrongly set parentheses in RTL languages + if (Factory::getLanguage()->isRTL()) + { + $data['label'] = $data['label'] . '‎'; + } + } + else + { + $data['label'] = $key; + } + + $path = $root . '/fields'; + + // Add the path when it exists + if (file_exists($path)) + { + $data['path'] = $path; + } + + $path = $root . '/rules'; + + // Add the path when it exists + if (file_exists($path)) + { + $data['rules'] = $path; + } + + $types[] = $data; + } + + // Add to cache and return the data + $types_cache[$this->_type . $this->_name] = $types; + + return $types; + } + + /** + * Prepares the field value. + * + * @param string $context The context. + * @param \stdclass $item The item. + * @param \stdclass $field The field. + * + * @return string + * + * @since 3.7.0 + */ + public function onCustomFieldsPrepareField($context, $item, $field) + { + // Check if the field should be processed by us + if (!$this->isTypeSupported($field->type)) + { + return; + } + + // Merge the params from the plugin and field which has precedence + $fieldParams = clone $this->params; + $fieldParams->merge($field->fieldparams); + + // Get the path for the layout file + $path = PluginHelper::getLayoutPath('fields', $field->type, $field->type); + + // Render the layout + ob_start(); + include $path; + $output = ob_get_clean(); + + // Return the output + return $output; + } + + /** + * Transforms the field into a DOM XML element and appends it as a child on the given parent. + * + * @param \stdClass $field The field. + * @param \DOMElement $parent The field node parent. + * @param \JForm $form The form. + * + * @return \DOMElement + * + * @since 3.7.0 + */ + public function onCustomFieldsPrepareDom($field, \DOMElement $parent, \JForm $form) + { + // Check if the field should be processed by us + if (!$this->isTypeSupported($field->type)) + { + return null; + } + + $app = Factory::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')) + { + return null; + } + + // Create the node + $node = $parent->appendChild(new \DOMElement('field')); + + // Set the attributes + $node->setAttribute('name', $field->name); + $node->setAttribute('type', $field->type); + $node->setAttribute('label', $field->label); + $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); + + // Set the specific field parameters + foreach ($params->toArray() as $key => $param) + { + if (is_array($param)) + { + // Multidimensional arrays (eg. list options) can't be transformed properly + $param = count($param) == count($param, COUNT_RECURSIVE) ? implode(',', $param) : ''; + } + + if ($param === '' || (!is_string($param) && !is_numeric($param))) + { + continue; + } + + $node->setAttribute($key, $param); + } + + // Check if it is allowed to edit the field + if (!FieldsHelper::canEditFieldValue($field)) + { + $node->setAttribute('disabled', 'true'); + } + + // Return the node + return $node; + } + + /** + * The form event. Load additional parameters when available into the field form. + * Only when the type of the form is of interest. + * + * @param \JForm $form The form + * @param \stdClass $data The data + * + * @return void + * + * @since 3.7.0 + */ + public function onContentPrepareForm(\JForm $form, $data) + { + // Check if the field form is calling us + if (strpos($form->getName(), 'com_fields.field') !== 0) + { + return; + } + + // Ensure it is an object + $formData = (object) $data; + + // Gather the type + $type = $form->getValue('type'); + + if (!empty($formData->type)) + { + $type = $formData->type; + } + + // Not us + if (!$this->isTypeSupported($type)) + { + return; + } + + $path = JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/params/' . $type . '.xml'; + + // Check if params file exists + if (!file_exists($path)) + { + return; + } + + // Load the specific plugin parameters + $form->load(file_get_contents($path), true, '/form/*'); + } + + /** + * Returns true if the given type is supported by the plugin. + * + * @param string $type The type + * + * @return boolean + * + * @since 3.7.0 + */ + protected function isTypeSupported($type) + { + foreach ($this->onCustomFieldsGetTypes() as $typeSpecification) + { + if ($type == $typeSpecification['type']) + { + return true; + } + } + + return false; + } +} diff --git a/administrator/components/com_fields/Table/FieldTable.php b/administrator/components/com_fields/Table/FieldTable.php new file mode 100644 index 0000000000000..d14fd798cd397 --- /dev/null +++ b/administrator/components/com_fields/Table/FieldTable.php @@ -0,0 +1,273 @@ +setColumnAlias('published', 'state'); + } + + /** + * Method to bind an associative array or object to the JTable instance.This + * method only binds properties that are publicly accessible and optionally + * takes an array of properties to ignore when binding. + * + * @param mixed $src An associative array or object to bind to the JTable instance. + * @param mixed $ignore An optional array or space separated list of properties to ignore while binding. + * + * @return boolean True on success. + * + * @since 3.7.0 + * @throws \InvalidArgumentException + */ + public function bind($src, $ignore = '') + { + if (isset($src['params']) && is_array($src['params'])) + { + $registry = new Registry; + $registry->loadArray($src['params']); + $src['params'] = (string) $registry; + } + + if (isset($src['fieldparams']) && is_array($src['fieldparams'])) + { + $registry = new Registry; + $registry->loadArray($src['fieldparams']); + $src['fieldparams'] = (string) $registry; + } + + // Bind the rules. + if (isset($src['rules']) && is_array($src['rules'])) + { + $rules = new Rules($src['rules']); + $this->setRules($rules); + } + + return parent::bind($src, $ignore); + } + + /** + * Method to perform sanity checks on the JTable instance properties to ensure + * they are safe to store in the database. Child classes should override this + * method to make sure the data they are storing in the database is safe and + * as expected before storage. + * + * @return boolean True if the instance is sane and able to be stored in the database. + * + * @link https://docs.joomla.org/Special:MyLanguage/JTable/check + * @since 3.7.0 + */ + public function check() + { + // Check for valid name + if (trim($this->title) == '') + { + $this->setError(Text::_('COM_FIELDS_MUSTCONTAIN_A_TITLE_FIELD')); + + return false; + } + + if (empty($this->name)) + { + $this->name = $this->title; + } + + $this->name = ApplicationHelper::stringURLSafe($this->name, $this->language); + + if (trim(str_replace('-', '', $this->name)) == '') + { + $this->name = StringHelper::increment($this->name, 'dash'); + } + + $this->name = str_replace(',', '-', $this->name); + + // Verify that the name is unique + $table = new static($this->_db); + + if ($table->load(array('name' => $this->name)) && ($table->id != $this->id || $this->id == 0)) + { + $this->setError(Text::_('COM_FIELDS_ERROR_UNIQUE_NAME')); + + return false; + } + + $this->name = str_replace(',', '-', $this->name); + + if (empty($this->type)) + { + $this->type = 'text'; + } + + $date = Factory::getDate(); + $user = Factory::getUser(); + + if ($this->id) + { + // Existing item + $this->modified_time = $date->toSql(); + $this->modified_by = $user->get('id'); + } + else + { + if (!(int) $this->created_time) + { + $this->created_time = $date->toSql(); + } + + if (empty($this->created_user_id)) + { + $this->created_user_id = $user->get('id'); + } + } + + if (empty($this->group_id)) + { + $this->group_id = 0; + } + + return true; + } + + /** + * Method to compute the default name of the asset. + * The default name is in the form table_name.id + * where id is the value of the primary key of the table. + * + * @return string + * + * @since 3.7.0 + */ + protected function _getAssetName() + { + $contextArray = explode('.', $this->context); + + return $contextArray[0] . '.field.' . (int) $this->id; + } + + /** + * Method to return the title to use for the asset table. In + * tracking the assets a title is kept for each asset so that there is some + * context available in a unified access manager. Usually this would just + * return $this->title or $this->name or whatever is being used for the + * primary name of the row. If this method is not overridden, the asset name is used. + * + * @return string The string to use as the title in the asset table. + * + * @link https://docs.joomla.org/Special:MyLanguage/JTable/getAssetTitle + * @since 3.7.0 + */ + protected function _getAssetTitle() + { + return $this->title; + } + + /** + * Method to get the parent asset under which to register this one. + * By default, all assets are registered to the ROOT node with ID, + * which will default to 1 if none exists. + * The extended class can define a table and id to lookup. If the + * asset does not exist it will be created. + * + * @param Table $table A JTable object for the asset parent. + * @param integer $id Id to look up + * + * @return integer + * + * @since 3.7.0 + */ + protected function _getAssetParentId(Table $table = null, $id = null) + { + $contextArray = explode('.', $this->context); + $component = $contextArray[0]; + + if ($this->group_id) + { + $assetId = $this->getAssetId($component . '.fieldgroup.' . (int) $this->group_id); + + if ($assetId) + { + return $assetId; + } + } + else + { + $assetId = $this->getAssetId($component); + + if ($assetId) + { + return $assetId; + } + } + + return parent::_getAssetParentId($table, $id); + } + + /** + * Returns an asset id for the given name or false. + * + * @param string $name The asset name + * + * @return number|boolean + * + * @since 3.7.0 + */ + private function getAssetId($name) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__assets')) + ->where($db->quoteName('name') . ' = ' . $db->quote($name)); + + // Get the asset id from the database. + $db->setQuery($query); + + $assetId = null; + + if ($result = $db->loadResult()) + { + $assetId = (int) $result; + + if ($assetId) + { + return $assetId; + } + } + + return false; + } +} diff --git a/administrator/components/com_fields/Table/GroupTable.php b/administrator/components/com_fields/Table/GroupTable.php new file mode 100644 index 0000000000000..992ec385613ac --- /dev/null +++ b/administrator/components/com_fields/Table/GroupTable.php @@ -0,0 +1,188 @@ +setColumnAlias('published', 'state'); + } + + /** + * Method to bind an associative array or object to the JTable instance.This + * method only binds properties that are publicly accessible and optionally + * takes an array of properties to ignore when binding. + * + * @param mixed $src An associative array or object to bind to the JTable instance. + * @param mixed $ignore An optional array or space separated list of properties to ignore while binding. + * + * @return boolean True on success. + * + * @since 3.7.0 + * @throws \InvalidArgumentException + */ + public function bind($src, $ignore = '') + { + if (isset($src['params']) && is_array($src['params'])) + { + $registry = new Registry; + $registry->loadArray($src['params']); + $src['params'] = (string) $registry; + } + + // Bind the rules. + if (isset($src['rules']) && is_array($src['rules'])) + { + $rules = new Rules($src['rules']); + $this->setRules($rules); + } + + return parent::bind($src, $ignore); + } + + /** + * Method to perform sanity checks on the JTable instance properties to ensure + * they are safe to store in the database. Child classes should override this + * method to make sure the data they are storing in the database is safe and + * as expected before storage. + * + * @return boolean True if the instance is sane and able to be stored in the database. + * + * @link https://docs.joomla.org/Special:MyLanguage/JTable/check + * @since 3.7.0 + */ + public function check() + { + // Check for a title. + if (trim($this->title) == '') + { + $this->setError(Text::_('COM_FIELDS_MUSTCONTAIN_A_TITLE_GROUP')); + + return false; + } + + $date = Factory::getDate(); + $user = Factory::getUser(); + + if ($this->id) + { + $this->modified = $date->toSql(); + $this->modified_by = $user->get('id'); + } + else + { + if (!(int) $this->created) + { + $this->created = $date->toSql(); + } + + if (empty($this->created_by)) + { + $this->created_by = $user->get('id'); + } + } + + if ($this->params === null) + { + $this->params = '{}'; + } + + return true; + } + + /** + * Method to compute the default name of the asset. + * The default name is in the form table_name.id + * where id is the value of the primary key of the table. + * + * @return string + * + * @since 3.7.0 + */ + protected function _getAssetName() + { + $component = explode('.', $this->context); + + return $component[0] . '.fieldgroup.' . (int) $this->id; + } + + /** + * Method to return the title to use for the asset table. In + * tracking the assets a title is kept for each asset so that there is some + * context available in a unified access manager. Usually this would just + * return $this->title or $this->name or whatever is being used for the + * primary name of the row. If this method is not overridden, the asset name is used. + * + * @return string The string to use as the title in the asset table. + * + * @link https://docs.joomla.org/Special:MyLanguage/JTable/getAssetTitle + * @since 3.7.0 + */ + protected function _getAssetTitle() + { + return $this->title; + } + + /** + * Method to get the parent asset under which to register this one. + * By default, all assets are registered to the ROOT node with ID, + * which will default to 1 if none exists. + * The extended class can define a table and id to lookup. If the + * asset does not exist it will be created. + * + * @param Table $table A JTable object for the asset parent. + * @param integer $id Id to look up + * + * @return integer + * + * @since 3.7.0 + */ + protected function _getAssetParentId(Table $table = null, $id = null) + { + $component = explode('.', $this->context); + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__assets')) + ->where($db->quoteName('name') . ' = ' . $db->quote($component[0])); + $db->setQuery($query); + + if ($assetId = (int) $db->loadResult()) + { + return $assetId; + } + + return parent::_getAssetParentId($table, $id); + } +} diff --git a/administrator/components/com_fields/View/Field/HtmlView.php b/administrator/components/com_fields/View/Field/HtmlView.php new file mode 100644 index 0000000000000..873327e9b4cc3 --- /dev/null +++ b/administrator/components/com_fields/View/Field/HtmlView.php @@ -0,0 +1,167 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + $this->canDo = ContentHelper::getActions($this->state->get('field.component'), 'field', $this->item->id); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + Factory::getApplication()->input->set('hidemainmenu', true); + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Adds the toolbar. + * + * @return void + * + * @since 3.7.0 + */ + protected function addToolbar() + { + $component = $this->state->get('field.component'); + $section = $this->state->get('field.section'); + $userId = Factory::getUser()->get('id'); + $canDo = $this->canDo; + + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); + + // Avoid nonsense situation. + if ($component == 'com_fields') + { + return; + } + + // Load component language file + $lang = Factory::getLanguage(); + $lang->load($component, JPATH_ADMINISTRATOR) + || $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component)); + + $title = Text::sprintf('COM_FIELDS_VIEW_FIELD_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE', Text::_(strtoupper($component))); + + // Prepare the toolbar. + ToolbarHelper::title( + $title, + 'puzzle field-' . ($isNew ? 'add' : 'edit') . ' ' . substr($component, 4) . ($section ? "-$section" : '') . '-field-' . + ($isNew ? 'add' : 'edit') + ); + + // For new records, check the create permission. + if ($isNew) + { + ToolbarHelper::saveGroup( + [ + ['apply', 'field.apply'], + ['save', 'field.save'], + ['save2new', 'field.save2new'] + ], + 'btn-success' + ); + + ToolbarHelper::cancel('field.cancel'); + } + else + { + // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. + $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId); + + $toolbarButtons = []; + + // Can't save the record if it's checked out and editable + if (!$checkedOut && $itemEditable) + { + $toolbarButtons[] = ['apply', 'field.apply']; + $toolbarButtons[] = ['save', 'field.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')) + { + $toolbarButtons[] = ['save2new', 'field.save2new']; + } + } + + // If an existing item, can save to a copy. + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'field.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + ToolbarHelper::cancel('field.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELDS_EDIT'); + } +} diff --git a/administrator/components/com_fields/View/Fields/HtmlView.php b/administrator/components/com_fields/View/Fields/HtmlView.php new file mode 100644 index 0000000000000..b18dd46570b78 --- /dev/null +++ b/administrator/components/com_fields/View/Fields/HtmlView.php @@ -0,0 +1,229 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Display a warning if the fields system plugin is disabled + if (!PluginHelper::isEnabled('system', 'fields')) + { + $link = Route::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . FieldsHelper::getFieldsPluginId()); + Factory::getApplication()->enqueueMessage(Text::sprintf('COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED', $link), 'warning'); + } + + // Only add toolbar when not in modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + + // We do not need to filter by language when multilingual is disabled + if (!Multilanguage::isEnabled()) + { + unset($this->activeFilters['language']); + $this->filterForm->removeField('language', 'filter'); + } + } + + FieldsHelper::addSubmenu($this->state->get('filter.context'), 'fields'); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Adds the toolbar. + * + * @return void + * + * @since 3.7.0 + */ + protected function addToolbar() + { + $fieldId = $this->state->get('filter.field_id'); + $component = $this->state->get('filter.component'); + $section = $this->state->get('filter.section'); + $canDo = ContentHelper::getActions($component, 'field', $fieldId); + + // Get the toolbar object instance + $bar = Toolbar::getInstance('toolbar'); + + // Avoid nonsense situation. + if ($component == 'com_fields') + { + return; + } + + // Load extension language file + $lang = Factory::getLanguage(); + $lang->load($component, JPATH_ADMINISTRATOR) + || $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component)); + + $title = Text::sprintf('COM_FIELDS_VIEW_FIELDS_TITLE', Text::_(strtoupper($component))); + + // Prepare the toolbar. + ToolbarHelper::title($title, 'puzzle fields ' . substr($component, 4) . ($section ? "-$section" : '') . '-fields'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('field.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publish('fields.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('fields.unpublish', 'JTOOLBAR_UNPUBLISH', true); + ToolbarHelper::archiveList('fields.archive'); + } + + if (Factory::getUser()->authorise('core.admin')) + { + ToolbarHelper::checkin('fields.checkin'); + } + + // Add a batch button + if ($canDo->get('core.create') && $canDo->get('core.edit') && $canDo->get('core.edit.state')) + { + $title = Text::_('JTOOLBAR_BATCH'); + + // Instantiate a new FileLayout instance and render the batch button + $layout = new FileLayout('joomla.toolbar.batch'); + + $dhtml = $layout->render( + array( + 'title' => $title, + ) + ); + + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete', $component)) + { + ToolbarHelper::deleteList('', 'fields.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('fields.trash'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences($component); + } + + ToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELDS'); + } + + /** + * Returns the sort fields. + * + * @return array + * + * @since 3.7.0 + */ + protected function getSortFields() + { + return array( + 'a.ordering' => Text::_('JGRID_HEADING_ORDERING'), + 'a.state' => Text::_('JSTATUS'), + 'a.title' => Text::_('JGLOBAL_TITLE'), + 'a.type' => Text::_('COM_FIELDS_FIELD_TYPE_LABEL'), + 'a.access' => Text::_('JGRID_HEADING_ACCESS'), + 'language' => Text::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_fields/View/Group/HtmlView.php b/administrator/components/com_fields/View/Group/HtmlView.php new file mode 100644 index 0000000000000..cbc1d223b29c2 --- /dev/null +++ b/administrator/components/com_fields/View/Group/HtmlView.php @@ -0,0 +1,194 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + $component = ''; + $parts = FieldsHelper::extract($this->state->get('filter.context')); + + if ($parts) + { + $component = $parts[0]; + } + + $this->canDo = ContentHelper::getActions($component, 'fieldgroup', $this->item->id); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + Factory::getApplication()->input->set('hidemainmenu', true); + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Adds the toolbar. + * + * @return void + * + * @since 3.7.0 + */ + protected function addToolbar() + { + $component = ''; + $parts = FieldsHelper::extract($this->state->get('filter.context')); + + if ($parts) + { + $component = $parts[0]; + } + + $userId = Factory::getUser()->get('id'); + $canDo = $this->canDo; + + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); + + // Avoid nonsense situation. + if ($component == 'com_fields') + { + return; + } + + // Load component language file + $lang = Factory::getLanguage(); + $lang->load($component, JPATH_ADMINISTRATOR) + || $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component)); + + $title = Text::sprintf('COM_FIELDS_VIEW_GROUP_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE', Text::_(strtoupper($component))); + + // Prepare the toolbar. + ToolbarHelper::title( + $title, + 'puzzle field-' . ($isNew ? 'add' : 'edit') . ' ' . substr($component, 4) . '-group-' . + ($isNew ? 'add' : 'edit') + ); + + $toolbarButtons = []; + + // For new records, check the create permission. + if ($isNew) + { + ToolbarHelper::saveGroup( + [ + ['apply', 'group.apply'], + ['save', 'group.save'], + ['save2new', 'group.save2new'] + ], + 'btn-success' + ); + + ToolbarHelper::cancel('group.cancel'); + } + else + { + // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. + $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId); + + $toolbarButtons = []; + + // Can't save the record if it's checked out and editable + if (!$checkedOut && $itemEditable) + { + $toolbarButtons[] = ['apply', 'group.apply']; + $toolbarButtons[] = ['save', 'group.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')) + { + $toolbarButtons[] = ['save2new', 'group.save2new']; + } + } + + // If an existing item, can save to a copy. + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'group.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + ToolbarHelper::cancel('group.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELD_GROUPS_EDIT'); + } +} diff --git a/administrator/components/com_fields/View/Groups/HtmlView.php b/administrator/components/com_fields/View/Groups/HtmlView.php new file mode 100644 index 0000000000000..d236a93892f98 --- /dev/null +++ b/administrator/components/com_fields/View/Groups/HtmlView.php @@ -0,0 +1,231 @@ +state = $this->get('State'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Display a warning if the fields system plugin is disabled + if (!PluginHelper::isEnabled('system', 'fields')) + { + $link = Route::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . FieldsHelper::getFieldsPluginId()); + Factory::getApplication()->enqueueMessage(Text::sprintf('COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED', $link), 'warning'); + } + + $this->addToolbar(); + + // We do not need to filter by language when multilingual is disabled + if (!Multilanguage::isEnabled()) + { + unset($this->activeFilters['language']); + $this->filterForm->removeField('language', 'filter'); + } + + FieldsHelper::addSubmenu($this->state->get('filter.context'), 'groups'); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Adds the toolbar. + * + * @return void + * + * @since 3.7.0 + */ + protected function addToolbar() + { + $groupId = $this->state->get('filter.group_id'); + $component = ''; + $parts = FieldsHelper::extract($this->state->get('filter.context')); + + if ($parts) + { + $component = $parts[0]; + } + + $canDo = ContentHelper::getActions($component, 'fieldgroup', $groupId); + + // Get the toolbar object instance + $bar = Toolbar::getInstance('toolbar'); + + // Avoid nonsense situation. + if ($component == 'com_fields') + { + return; + } + + // Load component language file + $lang = Factory::getLanguage(); + $lang->load($component, JPATH_ADMINISTRATOR) + || $lang->load($component, Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component)); + + $title = Text::sprintf('COM_FIELDS_VIEW_GROUPS_TITLE', Text::_(strtoupper($component))); + + // Prepare the toolbar. + ToolbarHelper::title($title, 'puzzle fields ' . substr($component, 4) . '-groups'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('group.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publish('groups.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('groups.unpublish', 'JTOOLBAR_UNPUBLISH', true); + ToolbarHelper::archiveList('groups.archive'); + } + + if (Factory::getUser()->authorise('core.admin')) + { + ToolbarHelper::checkin('groups.checkin'); + } + + // Add a batch button + if ($canDo->get('core.create') && $canDo->get('core.edit') && $canDo->get('core.edit.state')) + { + $title = Text::_('JTOOLBAR_BATCH'); + + // Instantiate a new FileLayout instance and render the batch button + $layout = new FileLayout('joomla.toolbar.batch'); + + $dhtml = $layout->render( + array( + 'title' => $title, + ) + ); + + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete', $component)) + { + ToolbarHelper::deleteList('', 'groups.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('groups.trash'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences($component); + } + + ToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELD_GROUPS'); + } + + /** + * Returns the sort fields. + * + * @return array + * + * @since 3.7.0 + */ + protected function getSortFields() + { + return array( + 'a.ordering' => Text::_('JGRID_HEADING_ORDERING'), + 'a.state' => Text::_('JSTATUS'), + 'a.title' => Text::_('JGLOBAL_TITLE'), + 'a.access' => Text::_('JGRID_HEADING_ACCESS'), + 'language' => Text::_('JGRID_HEADING_LANGUAGE'), + 'a.context' => Text::_('JGRID_HEADING_CONTEXT'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_fields/controller.php b/administrator/components/com_fields/controller.php deleted file mode 100644 index 6acbf0a96c251..0000000000000 --- a/administrator/components/com_fields/controller.php +++ /dev/null @@ -1,59 +0,0 @@ -input->get('view', 'fields'); - $id = $this->input->getInt('id'); - - // Check for edit form. - if ($vName == 'field' && !$this->checkEditId('com_fields.edit.field', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_fields&view=fields&context=' . $this->input->get('context'), false)); - - return false; - } - - return parent::display($cachable, $urlparams); - } -} diff --git a/administrator/components/com_fields/controllers/field.php b/administrator/components/com_fields/controllers/field.php deleted file mode 100644 index 3b6d8f90c4be7..0000000000000 --- a/administrator/components/com_fields/controllers/field.php +++ /dev/null @@ -1,180 +0,0 @@ -internalContext = JFactory::getApplication()->getUserStateFromRequest('com_fields.fields.context', 'context', 'com_content.article', 'CMD'); - $parts = FieldsHelper::extract($this->internalContext); - $this->component = $parts ? $parts[0] : null; - } - - /** - * Method override to check if you can add a new record. - * - * @param array $data An array of input data. - * - * @return boolean - * - * @since 3.7.0 - */ - protected function allowAdd($data = array()) - { - return JFactory::getUser()->authorise('core.create', $this->component); - } - - /** - * Method override to check if you can edit an existing record. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. - * - * @return boolean - * - * @since 1.6 - */ - protected function allowEdit($data = array(), $key = 'id') - { - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; - $user = JFactory::getUser(); - - // 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', $this->component . '.field.' . $recordId)) - { - return true; - } - - // Check edit own on the record asset (explicit or inherited) - if ($user->authorise('core.edit.own', $this->component . '.field.' . $recordId)) - { - // Existing record already has an owner, get it - $record = $this->getModel()->getItem($recordId); - - if (empty($record)) - { - return false; - } - - // Grant if current user is owner of the record - return $user->id == $record->created_by; - } - - return false; - } - - /** - * Method to run batch operations. - * - * @param object $model The model. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 3.7.0 - */ - public function batch($model = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Set the model - $model = $this->getModel('Field'); - - // Preset the redirect - $this->setRedirect('index.php?option=com_fields&view=fields&context=' . $this->internalContext); - - return parent::batch($model); - } - - /** - * Gets the URL arguments to append to an item redirect. - * - * @param integer $recordId The primary key id for the item. - * @param string $urlVar The name of the URL variable for the id. - * - * @return string The arguments to append to the redirect URL. - * - * @since 3.7.0 - */ - protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') - { - return parent::getRedirectToItemAppend($recordId) . '&context=' . $this->internalContext; - } - - /** - * Gets the URL arguments to append to a list redirect. - * - * @return string The arguments to append to the redirect URL. - * - * @since 3.7.0 - */ - protected function getRedirectToListAppend() - { - return parent::getRedirectToListAppend() . '&context=' . $this->internalContext; - } - - /** - * 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.7.0 - */ - protected function postSaveHook(JModelLegacy $model, $validData = array()) - { - $item = $model->getItem(); - - if (isset($item->params) && is_array($item->params)) - { - $registry = new Registry; - $registry->loadArray($item->params); - $item->params = (string) $registry; - } - - return; - } -} diff --git a/administrator/components/com_fields/controllers/fields.php b/administrator/components/com_fields/controllers/fields.php deleted file mode 100644 index d6429e2756bac..0000000000000 --- a/administrator/components/com_fields/controllers/fields.php +++ /dev/null @@ -1,42 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_fields/controllers/group.php b/administrator/components/com_fields/controllers/group.php deleted file mode 100644 index d2e9a21bce9db..0000000000000 --- a/administrator/components/com_fields/controllers/group.php +++ /dev/null @@ -1,160 +0,0 @@ -input->getCmd('context')); - - if ($parts) - { - $this->component = $parts[0]; - } - } - - /** - * Method to run batch operations. - * - * @param object $model The model. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 3.7.0 - */ - public function batch($model = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Set the model - $model = $this->getModel('Group'); - - // Preset the redirect - $this->setRedirect('index.php?option=com_fields&view=groups'); - - return parent::batch($model); - } - - /** - * Method override to check if you can add a new record. - * - * @param array $data An array of input data. - * - * @return boolean - * - * @since 3.7.0 - */ - protected function allowAdd($data = array()) - { - return JFactory::getUser()->authorise('core.create', $this->component); - } - - /** - * Method override to check if you can edit an existing record. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. - * - * @return boolean - * - * @since 3.7.0 - */ - protected function allowEdit($data = array(), $key = 'parent_id') - { - $recordId = (int) isset($data[$key]) ? $data[$key] : 0; - $user = JFactory::getUser(); - - // Zero record (parent_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', $this->component . '.fieldgroup.' . $recordId)) - { - return true; - } - - // Check edit own on the record asset (explicit or inherited) - if ($user->authorise('core.edit.own', $this->component . '.fieldgroup.' . $recordId) || $user->authorise('core.edit.own', $this->component)) - { - // Existing record already has an owner, get it - $record = $this->getModel()->getItem($recordId); - - if (empty($record)) - { - return false; - } - - // Grant if current user is owner of the record - return $user->id == $record->created_by; - } - - return false; - } - - /** - * 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.7.0 - */ - protected function postSaveHook(JModelLegacy $model, $validData = array()) - { - $item = $model->getItem(); - - if (isset($item->params) && is_array($item->params)) - { - $registry = new Registry; - $registry->loadArray($item->params); - $item->params = (string) $registry; - } - - return; - } -} diff --git a/administrator/components/com_fields/controllers/groups.php b/administrator/components/com_fields/controllers/groups.php deleted file mode 100644 index b2fb9a30c1ff9..0000000000000 --- a/administrator/components/com_fields/controllers/groups.php +++ /dev/null @@ -1,42 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_fields/fields.php b/administrator/components/com_fields/fields.php deleted file mode 100644 index 7e0d4eafb7f31..0000000000000 --- a/administrator/components/com_fields/fields.php +++ /dev/null @@ -1,30 +0,0 @@ -getUserStateFromRequest( - 'com_fields.groups.context', - 'context', - $app->getUserStateFromRequest('com_fields.fields.context', 'context', 'com_content.article', 'CMD'), - 'CMD' -); - -$parts = FieldsHelper::extract($context); - -if (!$parts || !JFactory::getUser()->authorise('core.manage', $parts[0])) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('Fields'); -$controller->execute($app->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_fields/fields.xml b/administrator/components/com_fields/fields.xml index 9920c0a5ad6c6..e0b1d1608bcf0 100644 --- a/administrator/components/com_fields/fields.xml +++ b/administrator/components/com_fields/fields.xml @@ -9,6 +9,7 @@ www.joomla.org 3.7.0 COM_FIELDS_XML_DESCRIPTION + Joomla\Component\Fields controller.php fields.php diff --git a/administrator/components/com_fields/models/forms/field.xml b/administrator/components/com_fields/forms/field.xml similarity index 80% rename from administrator/components/com_fields/models/forms/field.xml rename to administrator/components/com_fields/forms/field.xml index 17de81827a690..296c20c165cc1 100644 --- a/administrator/components/com_fields/models/forms/field.xml +++ b/administrator/components/com_fields/forms/field.xml @@ -1,11 +1,10 @@ -
-
+ +
@@ -35,9 +33,9 @@ name="assigned_cat_ids" type="category" label="JCATEGORY" - description="JFIELD_FIELDS_CATEGORY_DESC" extension="com_content" multiple="true" + addfieldprefix="Joomla\Component\Categories\Administrator\Field" > @@ -46,8 +44,7 @@ name="title" type="text" label="JGLOBAL_TITLE" - description="JFIELD_TITLE_DESC" - class="input-xxlarge input-large-text" + class="input-xxlarge" size="40" required="true" /> @@ -56,7 +53,6 @@ name="name" type="text" label="JFIELD_NAME_LABEL" - description="JFIELD_NAME_DESC" hint="JFIELD_NAME_PLACEHOLDER" size="45" /> @@ -65,7 +61,6 @@ name="type" type="type" label="COM_FIELDS_FIELD_TYPE_LABEL" - description="COM_FIELDS_FIELD_TYPE_DESC" default="text" required="true" /> @@ -74,19 +69,17 @@ name="required" type="radio" label="COM_FIELDS_FIELD_REQUIRED_LABEL" - description="COM_FIELDS_FIELD_REQUIRED_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="0" > - + @@ -94,7 +87,6 @@ name="state" type="list" label="JSTATUS" - description="JFIELD_PUBLISHED_DESC" class="chzn-color-state" default="1" size="1" @@ -109,7 +101,6 @@ name="buttonspacer" type="spacer" label="JGLOBAL_ACTION_PERMISSIONS_LABEL" - description="JGLOBAL_ACTION_PERMISSIONS_DESCRIPTION" /> @@ -171,8 +160,7 @@ name="note" type="text" label="COM_FIELDS_FIELD_NOTE_LABEL" - description="COM_FIELDS_FIELD_NOTE_DESC" - class="span12" + class="col-md-12" size="40" /> @@ -180,7 +168,6 @@ name="label" type="text" label="COM_FIELDS_FIELD_LABEL_LABEL" - description="COM_FIELDS_FIELD_LABEL_DESC" size="40" hint="JFIELD_ALIAS_PLACEHOLDER" /> @@ -189,7 +176,6 @@ name="description" type="textarea" label="JGLOBAL_DESCRIPTION" - description="COM_FIELDS_FIELD_DESCRIPTION_DESC" size="40" filter="HTML" /> @@ -198,7 +184,6 @@ name="access" type="accesslevel" label="JFIELD_ACCESS_LABEL" - description="JFIELD_ACCESS_DESC" />
@@ -254,20 +238,17 @@ name="showlabel" type="radio" label="COM_FIELDS_FIELD_SHOWLABEL_LABEL" - description="COM_FIELDS_FIELD_SHOWLABEL_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" > - + @@ -279,7 +260,6 @@ name="display" type="list" label="COM_FIELDS_FIELD_DISPLAY_LABEL" - description="COM_FIELDS_FIELD_DISPLAY_DESC" default="2" > diff --git a/administrator/components/com_fields/forms/filter_fields.xml b/administrator/components/com_fields/forms/filter_fields.xml new file mode 100644 index 0000000000000..b3d134fcc518b --- /dev/null +++ b/administrator/components/com_fields/forms/filter_fields.xml @@ -0,0 +1,97 @@ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_fields/forms/filter_groups.xml b/administrator/components/com_fields/forms/filter_groups.xml new file mode 100644 index 0000000000000..6a88752d21eff --- /dev/null +++ b/administrator/components/com_fields/forms/filter_groups.xml @@ -0,0 +1,73 @@ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_fields/forms/group.xml b/administrator/components/com_fields/forms/group.xml new file mode 100644 index 0000000000000..d1c96adc7e6bf --- /dev/null +++ b/administrator/components/com_fields/forms/group.xml @@ -0,0 +1,142 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/administrator/components/com_fields/helpers/fields.php b/administrator/components/com_fields/helpers/fields.php index 52c9c46c19136..13d8d76526870 100644 --- a/administrator/components/com_fields/helpers/fields.php +++ b/administrator/components/com_fields/helpers/fields.php @@ -8,747 +8,13 @@ */ defined('_JEXEC') or die; -JLoader::register('JFolder', JPATH_LIBRARIES . '/joomla/filesystem/folder.php'); - /** * FieldsHelper * - * @since 3.7.0 + * @since 3.7.0 + * + * @deprecated 5.0 Use \Joomla\Component\Fields\Administrator\Helper\FieldsHelper instead */ -class FieldsHelper +class FieldsHelper extends \Joomla\Component\Fields\Administrator\Helper\FieldsHelper { - private static $fieldsCache = null; - - private static $fieldCache = null; - - /** - * Extracts the component and section from the context string which has to - * be in the format component.context. - * - * @param string $contextString contextString - * @param object $item optional item object - * - * @return array|null - * - * @since 3.7.0 - */ - public static function extract($contextString, $item = null) - { - $parts = explode('.', $contextString, 2); - - if (count($parts) < 2) - { - return null; - } - - $component = $parts[0]; - $eName = str_replace('com_', '', $component); - - $path = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php'); - - if (file_exists($path)) - { - $cName = ucfirst($eName) . 'Helper'; - - JLoader::register($cName, $path); - - if (class_exists($cName) && is_callable(array($cName, 'validateSection'))) - { - $section = call_user_func_array(array($cName, 'validateSection'), array($parts[1], $item)); - - if ($section) - { - $parts[1] = $section; - } - } - } - - return $parts; - } - - /** - * Returns the fields for the given context. - * If the item is an object the returned fields do have an additional field - * "value" which represents the value for the given item. If the item has an - * assigned_cat_ids field, then additionally fields which belong to that - * category will be returned. - * Should the value being prepared to be shown in an HTML context then - * prepareValue must be set to true. No further escaping needs to be done. - * The values of the fields can be overridden by an associative array where the keys - * have to be a name and its corresponding value. - * - * @param string $context The context of the content passed to the helper - * @param stdClass $item item - * @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 - * - * @since 3.7.0 - */ - public static function getFields($context, $item = null, $prepareValue = false, array $valuesToOverride = null) - { - if (self::$fieldsCache === null) - { - // Load the model - JLoader::import('joomla.application.component.model'); - JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_fields/models', 'FieldsModel'); - - self::$fieldsCache = JModelLegacy::getInstance('Fields', 'FieldsModel', array( - 'ignore_request' => true) - ); - - self::$fieldsCache->setState('filter.state', 1); - self::$fieldsCache->setState('list.limit', 0); - } - - if (is_array($item)) - { - $item = (object) $item; - } - - if (JLanguageMultilang::isEnabled() && isset($item->language) && $item->language != '*') - { - self::$fieldsCache->setState('filter.language', array('*', $item->language)); - } - - self::$fieldsCache->setState('filter.context', $context); - - /* - * If item has assigned_cat_ids parameter display only fields which - * belong to the category - */ - if ($item && (isset($item->catid) || isset($item->fieldscatid))) - { - $assignedCatIds = isset($item->catid) ? $item->catid : $item->fieldscatid; - - if (!is_array($assignedCatIds)) - { - $assignedCatIds = explode(',', $assignedCatIds); - } - - // Fields without any category assigned should show as well - $assignedCatIds[] = 0; - - self::$fieldsCache->setState('filter.assigned_cat_ids', $assignedCatIds); - } - - $fields = self::$fieldsCache->getItems(); - - if ($fields === false) - { - return array(); - } - - if ($item && isset($item->id)) - { - if (self::$fieldCache === null) - { - self::$fieldCache = JModelLegacy::getInstance('Field', 'FieldsModel', array('ignore_request' => true)); - } - - $fieldIds = array_map( - function ($f) - { - return $f->id; - }, - $fields - ); - - $fieldValues = self::$fieldCache->getFieldValues($fieldIds, $item->id); - - $new = array(); - - foreach ($fields as $key => $original) - { - /* - * Doing a clone, otherwise fields for different items will - * always reference to the same object - */ - $field = clone $original; - - if ($valuesToOverride && key_exists($field->name, $valuesToOverride)) - { - $field->value = $valuesToOverride[$field->name]; - } - elseif ($valuesToOverride && key_exists($field->id, $valuesToOverride)) - { - $field->value = $valuesToOverride[$field->id]; - } - elseif (key_exists($field->id, $fieldValues)) - { - $field->value = $fieldValues[$field->id]; - } - - if (!isset($field->value) || $field->value === '') - { - $field->value = $field->default_value; - } - - $field->rawvalue = $field->value; - - // 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 - $dispatcher->trigger('onCustomFieldsBeforePrepareField', array($context, $item, &$field)); - - // Gathering the value for the field - $value = $dispatcher->trigger('onCustomFieldsPrepareField', array($context, $item, &$field)); - - if (is_array($value)) - { - $value = implode(' ', $value); - } - - // Event allow plugins to modfify the output of the prepared field - $dispatcher->trigger('onCustomFieldsAfterPrepareField', array($context, $item, $field, &$value)); - - // Assign the value - $field->value = $value; - } - - $new[$key] = $field; - } - - $fields = $new; - } - - return $fields; - } - - /** - * Renders the layout file and data on the context and does a fall back to - * Fields afterwards. - * - * @param string $context The context of the content passed to the helper - * @param string $layoutFile layoutFile - * @param array $displayData displayData - * - * @return NULL|string - * - * @since 3.7.0 - */ - public static function render($context, $layoutFile, $displayData) - { - $value = ''; - - /* - * Because the layout refreshes the paths before the render function is - * called, so there is no way to load the layout overrides in the order - * template -> context -> fields. - * If there is no override in the context then we need to call the - * layout from Fields. - */ - if ($parts = self::extract($context)) - { - // Trying to render the layout on the component from the context - $value = JLayoutHelper::render($layoutFile, $displayData, null, array('component' => $parts[0], 'client' => 0)); - } - - if ($value == '') - { - // Trying to render the layout on Fields itself - $value = JLayoutHelper::render($layoutFile, $displayData, null, array('component' => 'com_fields','client' => 0)); - } - - return $value; - } - - /** - * PrepareForm - * - * @param string $context The context of the content passed to the helper - * @param JForm $form form - * @param object $data data. - * - * @return boolean - * - * @since 3.7.0 - */ - public static function prepareForm($context, JForm $form, $data) - { - // Extracting the component and section - $parts = self::extract($context); - - if (! $parts) - { - return true; - } - - $context = $parts[0] . '.' . $parts[1]; - - // When no fields available return here - $fields = self::getFields($parts[0] . '.' . $parts[1], new JObject); - - if (! $fields) - { - return true; - } - - $component = $parts[0]; - $section = $parts[1]; - - $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); - - // Choose the first category available - $xml = new DOMDocument; - $xml->loadHTML($formField->__get('input')); - $options = $xml->getElementsByTagName('option'); - - if (!$assignedCatids && $firstChoice = $options->item(0)) - { - $assignedCatids = $firstChoice->getAttribute('value'); - } - - $data->fieldscatid = $assignedCatids; - } - - /* - * If there is a catid field we need to reload the page when the catid - * is changed - */ - if ($form->getField('catid') && $parts[0] != 'com_fields') - { - /* - * Setting the onchange event to reload the page when the category - * has changed - */ - $form->setFieldAttribute('catid', 'onchange', 'categoryHasChanged(this);'); - - // Preload spindle-wheel when we need to submit form due to category selector changed - JFactory::getDocument()->addScriptDeclaration(" - function categoryHasChanged(element) { - var cat = jQuery(element); - if (cat.val() == '" . $assignedCatids . "')return; - Joomla.loadingLayer('show'); - jQuery('input[name=task]').val('" . $section . ".reload'); - element.form.submit(); - } - jQuery( document ).ready(function() { - Joomla.loadingLayer('load'); - var formControl = '#" . $form->getFormControl() . "_catid'; - if (!jQuery(formControl).val() != '" . $assignedCatids . "'){jQuery(formControl).val('" . $assignedCatids . "');} - });" - ); - } - - // Getting the fields - $fields = self::getFields($parts[0] . '.' . $parts[1], $data); - - if (!$fields) - { - return true; - } - - $fieldTypes = self::getFieldTypes(); - - // Creating the dom - $xml = new DOMDocument('1.0', 'UTF-8'); - $fieldsNode = $xml->appendChild(new DOMElement('form'))->appendChild(new DOMElement('fields')); - $fieldsNode->setAttribute('name', 'com_fields'); - - // Organizing the fields according to their group - $fieldsPerGroup = array(0 => array()); - - foreach ($fields as $field) - { - if (!array_key_exists($field->type, $fieldTypes)) - { - // Field type is not available - continue; - } - - if (!array_key_exists($field->group_id, $fieldsPerGroup)) - { - $fieldsPerGroup[$field->group_id] = array(); - } - - if ($path = $fieldTypes[$field->type]['path']) - { - // Add the lookup path for the field - JFormHelper::addFieldPath($path); - } - - if ($path = $fieldTypes[$field->type]['rules']) - { - // Add the lookup path for the rule - JFormHelper::addRulePath($path); - } - - $fieldsPerGroup[$field->group_id][] = $field; - } - - // 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 ($iterateGroups as $group) - { - if (empty($fieldsPerGroup[$group->id])) - { - continue; - } - - // Defining the field set - /** @var DOMElement $fieldset */ - $fieldset = $fieldsNode->appendChild(new DOMElement('fieldset')); - $fieldset->setAttribute('name', 'fields-' . $group->id); - $fieldset->setAttribute('addfieldpath', '/administrator/components/' . $component . '/models/fields'); - $fieldset->setAttribute('addrulepath', '/administrator/components/' . $component . '/models/rules'); - - $label = $group->title; - $description = $group->description; - - if (!$label) - { - $key = strtoupper($component . '_FIELDS_' . $section . '_LABEL'); - - if (!JFactory::getLanguage()->hasKey($key)) - { - $key = 'JGLOBAL_FIELDS'; - } - - $label = $key; - } - - if (!$description) - { - $key = strtoupper($component . '_FIELDS_' . $section . '_DESC'); - - if (JFactory::getLanguage()->hasKey($key)) - { - $description = $key; - } - } - - $fieldset->setAttribute('label', $label); - $fieldset->setAttribute('description', strip_tags($description)); - - // Looping through the fields for that context - foreach ($fieldsPerGroup[$group->id] as $field) - { - try - { - 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 - * is not known, set the required flag to false on any circumstance. - */ - if (!$assignedCatids && !empty($field->assigned_cat_ids) && $form->getField($field->name)) - { - $form->setFieldAttribute($field->name, 'required', 'false'); - } - } - catch (Exception $e) - { - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); - } - } - - // When the field set is empty, then remove it - if (!$fieldset->hasChildNodes()) - { - $fieldsNode->removeChild($fieldset); - } - } - - // Loading the XML fields string into the form - $form->load($xml->saveXML()); - - $model = JModelLegacy::getInstance('Field', 'FieldsModel', array('ignore_request' => true)); - - if ((!isset($data->id) || !$data->id) && JFactory::getApplication()->input->getCmd('controller') == 'config.display.modules' - && JFactory::getApplication()->isClient('site')) - { - // Modules on front end editing don't have data and an id set - $data->id = JFactory::getApplication()->input->getInt('id'); - } - - // Looping through the fields again to set the value - if (!isset($data->id) || !$data->id) - { - return true; - } - - foreach ($fields as $field) - { - $value = $model->getFieldValue($field->id, $data->id); - - if ($value === null) - { - continue; - } - - if (!is_array($value) && $value !== '') - { - // Function getField doesn't cache the fields, so we try to do it only when necessary - $formField = $form->getField($field->name, 'com_fields'); - - if ($formField && $formField->forceMultiple) - { - $value = (array) $value; - } - } - - // Setting the value on the field - $form->setValue($field->name, 'com_fields', $value); - } - - return true; - } - - /** - * Return a boolean if the actual logged in user can edit the given field value. - * - * @param stdClass $field The field - * - * @return boolean - * - * @since 3.7.0 - */ - public static function canEditFieldValue($field) - { - $parts = self::extract($field->context); - - return JFactory::getUser()->authorise('core.edit.value', $parts[0] . '.field.' . (int) $field->id); - } - - /** - * Adds Count Items for Category Manager. - * - * @param stdClass[] &$items The field category objects - * - * @return stdClass[] - * - * @since 3.7.0 - */ - 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(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', - ); - - foreach ($fields as $field) - { - $property = $states[$field->state]; - $item->$property = $field->count; - } - } - - return $items; - } - - /** - * Gets assigned categories titles for a field - * - * @param stdClass[] $fieldId The field ID - * - * @return array Array with the assigned categories - * - * @since 3.7.0 - */ - public static function getAssignedCategoriesTitles($fieldId) - { - $fieldId = (int) $fieldId; - - if (!$fieldId) - { - return array(); - } - - $db = JFactory::getDbo(); - $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); - - $db->setQuery($query); - - return $db->loadColumn(); - } - - /** - * Gets the fields system plugin extension id. - * - * @return integer The fields system plugin extension id. - * - * @since 3.7.0 - */ - 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')); - $db->setQuery($query); - - try - { - $result = (int) $db->loadResult(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - $result = 0; - } - - return $result; - } - - /** - * Configure the Linkbar. - * - * @param string $context The context the fields are used for - * @param string $vName The view currently active - * - * @return void - * - * @since 3.7.0 - */ - public static function addSubmenu($context, $vName) - { - $parts = self::extract($context); - - if (!$parts) - { - return; - } - - $component = $parts[0]; - - // Avoid nonsense situation. - if ($component == 'com_fields') - { - return; - } - - // Try to find the component helper. - $eName = str_replace('com_', '', $component); - $file = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php'); - - if (!file_exists($file)) - { - return; - } - - require_once $file; - - $cName = ucfirst($eName) . 'Helper'; - - if (class_exists($cName) && is_callable(array($cName, 'addSubmenu'))) - { - $lang = JFactory::getLanguage(); - $lang->load($component, JPATH_ADMINISTRATOR) - || $lang->load($component, JPATH_ADMINISTRATOR . '/components/' . $component); - - $cName::addSubmenu('fields.' . $vName); - } - } - - /** - * Loads the fields plugins and returns an array of field types from the plugins. - * - * The returned array contains arrays with the following keys: - * - label: The label of the field - * - type: The type of the field - * - path: The path of the folder where the field can be found - * - * @return array - * - * @since 3.7.0 - */ - public static function getFieldTypes() - { - JPluginHelper::importPlugin('fields'); - $eventData = JEventDispatcher::getInstance()->trigger('onCustomFieldsGetTypes'); - - $data = array(); - - foreach ($eventData as $fields) - { - foreach ($fields as $fieldDescription) - { - if (!array_key_exists('path', $fieldDescription)) - { - $fieldDescription['path'] = null; - } - - if (!array_key_exists('rules', $fieldDescription)) - { - $fieldDescription['rules'] = null; - } - - $data[$fieldDescription['type']] = $fieldDescription; - } - } - - 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 deleted file mode 100644 index 2a17117a5ddff..0000000000000 --- a/administrator/components/com_fields/libraries/fieldslistplugin.php +++ /dev/null @@ -1,79 +0,0 @@ -setAttribute('validate', 'options'); - - foreach ($this->getOptionsFromField($field) as $value => $name) - { - $option = new DOMElement('option', htmlspecialchars($value, ENT_COMPAT, 'UTF-8')); - $option->textContent = htmlspecialchars(JText::_($name), ENT_COMPAT, 'UTF-8'); - - $element = $fieldNode->appendChild($option); - $element->setAttribute('value', $value); - } - - return $fieldNode; - } - - /** - * Returns an array of key values to put in a list from the given field. - * - * @param stdClass $field The field. - * - * @return array - * - * @since 3.7.0 - */ - public function getOptionsFromField($field) - { - $data = array(); - - // Fetch the options from the plugin - $params = clone $this->params; - $params->merge($field->fieldparams); - - foreach ($params->get('options', array()) as $option) - { - $op = (object) $option; - $data[$op->value] = $op->name; - } - - return $data; - } -} diff --git a/administrator/components/com_fields/libraries/fieldsplugin.php b/administrator/components/com_fields/libraries/fieldsplugin.php deleted file mode 100644 index 9cf4eb6bb3e36..0000000000000 --- a/administrator/components/com_fields/libraries/fieldsplugin.php +++ /dev/null @@ -1,285 +0,0 @@ -_type . $this->_name])) - { - return $types_cache[$this->_type . $this->_name]; - } - - $types = array(); - - // The root of the plugin - $root = JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name; - - foreach (JFolder::files($root . '/tmpl', '.php') as $layout) - { - // Strip the extension - $layout = str_replace('.php', '', $layout); - - // The data array - $data = array(); - - // The language key - $key = strtoupper($layout); - - if ($key != strtoupper($this->_name)) - { - $key = strtoupper($this->_name) . '_' . $layout; - } - - // Needed attributes - $data['type'] = $layout; - - if (JFactory::getLanguage()->hasKey('PLG_FIELDS_' . $key . '_LABEL')) - { - $data['label'] = JText::sprintf('PLG_FIELDS_' . $key . '_LABEL', strtolower($key)); - - // Fix wrongly set parentheses in RTL languages - if (JFactory::getLanguage()->isRTL()) - { - $data['label'] = $data['label'] . '‎'; - } - } - else - { - $data['label'] = $key; - } - - $path = $root . '/fields'; - - // Add the path when it exists - if (file_exists($path)) - { - $data['path'] = $path; - } - - $path = $root . '/rules'; - - // Add the path when it exists - if (file_exists($path)) - { - $data['rules'] = $path; - } - - $types[] = $data; - } - - // Add to cache and return the data - $types_cache[$this->_type . $this->_name] = $types; - - return $types; - } - - /** - * Prepares the field value. - * - * @param string $context The context. - * @param stdclass $item The item. - * @param stdclass $field The field. - * - * @return string - * - * @since 3.7.0 - */ - public function onCustomFieldsPrepareField($context, $item, $field) - { - // Check if the field should be processed by us - if (!$this->isTypeSupported($field->type)) - { - return; - } - - // Merge the params from the plugin and field which has precedence - $fieldParams = clone $this->params; - $fieldParams->merge($field->fieldparams); - - // Get the path for the layout file - $path = JPluginHelper::getLayoutPath('fields', $field->type, $field->type); - - // Render the layout - ob_start(); - include $path; - $output = ob_get_clean(); - - // Return the output - return $output; - } - - /** - * Transforms the field into a DOM XML element and appends it as a child on the given parent. - * - * @param stdClass $field The field. - * @param DOMElement $parent The field node parent. - * @param JForm $form The form. - * - * @return DOMElement - * - * @since 3.7.0 - */ - public function onCustomFieldsPrepareDom($field, DOMElement $parent, JForm $form) - { - // Check if the field should be processed by us - if (!$this->isTypeSupported($field->type)) - { - 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')) - { - return null; - } - - // Create the node - $node = $parent->appendChild(new DOMElement('field')); - - // Set the attributes - $node->setAttribute('name', $field->name); - $node->setAttribute('type', $field->type); - $node->setAttribute('label', $field->label); - $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); - - // Set the specific field parameters - foreach ($params->toArray() as $key => $param) - { - if (is_array($param)) - { - // Multidimensional arrays (eg. list options) can't be transformed properly - $param = count($param) == count($param, COUNT_RECURSIVE) ? implode(',', $param) : ''; - } - - if ($param === '' || (!is_string($param) && !is_numeric($param))) - { - continue; - } - - $node->setAttribute($key, $param); - } - - // Check if it is allowed to edit the field - if (!FieldsHelper::canEditFieldValue($field)) - { - $node->setAttribute('disabled', 'true'); - } - - // Return the node - return $node; - } - - /** - * The form event. Load additional parameters when available into the field form. - * Only when the type of the form is of interest. - * - * @param JForm $form The form - * @param stdClass $data The data - * - * @return void - * - * @since 3.7.0 - */ - public function onContentPrepareForm(JForm $form, $data) - { - // Check if the field form is calling us - if (strpos($form->getName(), 'com_fields.field') !== 0) - { - return; - } - - // Ensure it is an object - $formData = (object) $data; - - // Gather the type - $type = $form->getValue('type'); - - if (!empty($formData->type)) - { - $type = $formData->type; - } - - // Not us - if (!$this->isTypeSupported($type)) - { - return; - } - - $path = JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/params/' . $type . '.xml'; - - // Check if params file exists - if (!file_exists($path)) - { - return; - } - - // Load the specific plugin parameters - $form->load(file_get_contents($path), true, '/form/*'); - } - - /** - * Returns true if the given type is supported by the plugin. - * - * @param string $type The type - * - * @return boolean - * - * @since 3.7.0 - */ - protected function isTypeSupported($type) - { - foreach ($this->onCustomFieldsGetTypes() as $typeSpecification) - { - if ($type == $typeSpecification['type']) - { - return true; - } - } - - return false; - } -} diff --git a/administrator/components/com_fields/models/field.php b/administrator/components/com_fields/models/field.php deleted file mode 100644 index 6cf51090da0f1..0000000000000 --- a/administrator/components/com_fields/models/field.php +++ /dev/null @@ -1,1138 +0,0 @@ - 'batchAccess', - 'language_id' => 'batchLanguage' - ); - - /** - * @var array - * - * @since 3.7.0 - */ - private $valueCache = array(); - - /** - * Constructor. - * - * @param array $config An optional associative array of configuration settings. - * - * @see JModelLegacy - * @since 3.7.0 - */ - public function __construct($config = array()) - { - parent::__construct($config); - - $this->typeAlias = JFactory::getApplication()->input->getCmd('context', 'com_content.article') . '.field'; - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success, False on error. - * - * @since 3.7.0 - */ - public function save($data) - { - $field = null; - - if (isset($data['id']) && $data['id']) - { - $field = $this->getItem($data['id']); - } - - if (!isset($data['label']) && isset($data['params']['label'])) - { - $data['label'] = $data['params']['label']; - - unset($data['params']['label']); - } - - // Alter the title for save as copy - $input = JFactory::getApplication()->input; - - if ($input->get('task') == 'save2copy') - { - $origTable = clone $this->getTable(); - $origTable->load($input->getInt('id')); - - if ($data['title'] == $origTable->title) - { - list($title, $name) = $this->generateNewTitle($data['group_id'], $data['name'], $data['title']); - $data['title'] = $title; - $data['label'] = $title; - $data['name'] = $name; - } - else - { - if ($data['name'] == $origTable->name) - { - $data['name'] = ''; - } - } - - $data['state'] = 0; - } - - // Load the fields plugins, perhaps they want to do something - JPluginHelper::importPlugin('fields'); - - $message = $this->checkDefaultValue($data); - - if ($message !== true) - { - $this->setError($message); - - return false; - } - - if (!parent::save($data)) - { - return false; - } - - // Save the assigned categories into #__fields_categories - $db = $this->getDbo(); - $id = (int) $this->getState('field.id'); - $cats = isset($data['assigned_cat_ids']) ? (array) $data['assigned_cat_ids'] : array(); - $cats = ArrayHelper::toInteger($cats); - - $assignedCatIds = array(); - - foreach ($cats as $cat) - { - if ($cat) - { - $assignedCatIds[] = $cat; - } - } - - // First delete all assigned categories - $query = $db->getQuery(true); - $query->delete('#__fields_categories') - ->where('field_id = ' . $id); - $db->setQuery($query); - $db->execute(); - - // Inset new assigned categories - $tupel = new stdClass; - $tupel->field_id = $id; - - foreach ($assignedCatIds as $catId) - { - $tupel->category_id = $catId; - $db->insertObject('#__fields_categories', $tupel); - } - - // If the options have changed delete the values - if ($field && isset($data['fieldparams']['options']) && isset($field->fieldparams['options'])) - { - $oldParams = $this->getParams($field->fieldparams['options']); - $newParams = $this->getParams($data['fieldparams']['options']); - - 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) . ')'); - $db->setQuery($query); - $db->execute(); - } - } - - FieldsHelper::clearFieldsCache(); - - return true; - } - - - /** - * Checks if the default value is valid for the given data. If a string is returned then - * it can be assumed that the default value is invalid. - * - * @param array $data The data. - * - * @return true|string true if valid, a string containing the exception message when not. - * - * @since 3.7.0 - */ - private function checkDefaultValue($data) - { - // Empty default values are correct - if (empty($data['default_value'])) - { - return true; - } - - $types = FieldsHelper::getFieldTypes(); - - // Check if type exists - if (!key_exists($data['type'], $types)) - { - return true; - } - - $path = $types[$data['type']]['rules']; - - // Add the path for the rules of the plugin when available - if ($path) - { - // Add the lookup path for the rule - JFormHelper::addRulePath($path); - } - - // Create the fields object - $obj = (object) $data; - $obj->params = new Registry($obj->params); - $obj->fieldparams = new Registry(!empty($obj->fieldparams) ? $obj->fieldparams : array()); - - // Prepare the dom - $dom = new DOMDocument; - $node = $dom->appendChild(new DOMElement('form')); - - // Trigger the event to create the field dom node - JEventDispatcher::getInstance()->trigger('onCustomFieldsPrepareDom', array($obj, $node, new JForm($data['context']))); - - // Check if a node is created - if (!$node->firstChild) - { - return true; - } - - // Define the type either from the field or from the data - $type = $node->firstChild->getAttribute('validate') ? : $data['type']; - - // Load the rule - $rule = JFormHelper::loadRuleType($type); - - // When no rule exists, we allow the default value - if (!$rule) - { - return true; - } - - try - { - // Perform the check - $result = $rule->test(simplexml_import_dom($node->firstChild), $data['default_value']); - - // Check if the test succeeded - return $result === true ? : JText::_('COM_FIELDS_FIELD_INVALID_DEFAULT_VALUE'); - } - catch (UnexpectedValueException $e) - { - return $e->getMessage(); - } - } - - /** - * Converts the unknown params into an object. - * - * @param mixed $params The params. - * - * @return stdClass Object on success, false on failure. - * - * @since 3.7.0 - */ - private function getParams($params) - { - if (is_string($params)) - { - $params = json_decode($params); - } - - if (is_array($params)) - { - $params = (object) $params; - } - - return $params; - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - * - * @since 3.7.0 - */ - public function getItem($pk = null) - { - $result = parent::getItem($pk); - - if ($result) - { - // Prime required properties. - if (empty($result->id)) - { - $result->context = JFactory::getApplication()->input->getCmd('context', $this->getState('field.context')); - } - - if (property_exists($result, 'fieldparams')) - { - $registry = new Registry; - $registry->loadString($result->fieldparams); - $result->fieldparams = $registry->toArray(); - } - - $db = $this->getDbo(); - $query = $db->getQuery(true); - $query->select('category_id') - ->from('#__fields_categories') - ->where('field_id = ' . (int) $result->id); - - $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; - } - - /** - * 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.7.0 - * @throws Exception - */ - public function getTable($name = 'Field', $prefix = 'FieldsTable', $options = array()) - { - if (strpos(JPATH_COMPONENT, 'com_fields') === false) - { - $this->addTablePath(JPATH_ADMINISTRATOR . '/components/com_fields/tables'); - } - - // Default to text type - $table = JTable::getInstance($name, $prefix, $options); - $table->type = 'text'; - - return $table; - } - - /** - * 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. - * - * @return array Contains the modified title and name. - * - * @since 3.7.0 - */ - protected function generateNewTitle($category_id, $name, $title) - { - // Alter the title & name - $table = $this->getTable(); - - while ($table->load(array('name' => $name))) - { - $title = StringHelper::increment($title); - $name = StringHelper::increment($name, 'dash'); - } - - return array( - $title, - $name, - ); - } - - /** - * Method to delete one or more records. - * - * @param array &$pks An array of record primary keys. - * - * @return boolean True if successful, false if an error occurs. - * - * @since 3.7.0 - */ - public function delete(&$pks) - { - $success = parent::delete($pks); - - if ($success) - { - $pks = (array) $pks; - $pks = ArrayHelper::toInteger($pks); - $pks = array_filter($pks); - - if (!empty($pks)) - { - // Delete Values - $query = $this->getDbo()->getQuery(true); - - $query->delete($query->qn('#__fields_values')) - ->where($query->qn('field_id') . ' IN(' . implode(',', $pks) . ')'); - - $this->getDbo()->setQuery($query)->execute(); - - // Delete Assigned Categories - $query = $this->getDbo()->getQuery(true); - - $query->delete($query->qn('#__fields_categories')) - ->where($query->qn('field_id') . ' IN(' . implode(',', $pks) . ')'); - - $this->getDbo()->setQuery($query)->execute(); - } - } - - return $success; - } - - /** - * Abstract 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 mixed A JForm object on success, false on failure - * - * @since 3.7.0 - */ - public function getForm($data = array(), $loadData = true) - { - $context = $this->getState('field.context'); - $jinput = JFactory::getApplication()->input; - - // A workaround to get the context into the model for save requests. - if (empty($context) && isset($data['context'])) - { - $context = $data['context']; - $parts = FieldsHelper::extract($context); - - $this->setState('field.context', $context); - - if ($parts) - { - $this->setState('field.component', $parts[0]); - $this->setState('field.section', $parts[1]); - } - } - - if (isset($data['type'])) - { - // This is needed that the plugins can determine the type - $this->setState('field.type', $data['type']); - } - - // Load the fields plugin that they can add additional parameters to the form - JPluginHelper::importPlugin('fields'); - - // Get the form. - $form = $this->loadForm( - 'com_fields.field' . $context, 'field', - array( - 'control' => 'jform', - 'load_data' => true, - ) - ); - - if (empty($form)) - { - return false; - } - - // Modify the form based on Edit State access controls. - if (empty($data['context'])) - { - $data['context'] = $context; - } - - $fieldId = $jinput->get('id'); - $assetKey = $this->state->get('field.component') . '.field.' . $fieldId; - - if (!JFactory::getUser()->authorise('core.edit.state', $assetKey)) - { - // Disable fields for display. - $form->setFieldAttribute('ordering', 'disabled', 'true'); - $form->setFieldAttribute('state', 'disabled', 'true'); - - // Disable fields while saving. The controller has already verified this is a record you can edit. - $form->setFieldAttribute('ordering', 'filter', 'unset'); - $form->setFieldAttribute('state', 'filter', 'unset'); - } - - return $form; - } - - /** - * 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. - * @param string $value The value. - * - * @return boolean - * - * @since 3.7.0 - */ - public function setFieldValue($fieldId, $itemId, $value) - { - $field = $this->getItem($fieldId); - $params = $field->params; - - if (is_array($params)) - { - $params = new Registry($params); - } - - // Don't save the value when the user is not authorized to change it - if (!$field || !FieldsHelper::canEditFieldValue($field)) - { - return false; - } - - $needsDelete = false; - $needsInsert = false; - $needsUpdate = false; - - $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 when not empty - $needsUpdate = is_array($value[0]) ? count($value[0]) : strlen($value[0]); - $needsDelete = !$needsUpdate; - } - else - { - // Multiple values, we need to purge the data and do a new - // insert - $needsDelete = true; - $needsInsert = true; - } - - if ($needsDelete) - { - // Deleting the existing record as it is a reset - $query = $this->getDbo()->getQuery(true); - - $query->delete($query->qn('#__fields_values')) - ->where($query->qn('field_id') . ' = ' . (int) $fieldId) - ->where($query->qn('item_id') . ' = ' . $query->q($itemId)); - - $this->getDbo()->setQuery($query)->execute(); - } - - if ($needsInsert) - { - $newObj = new stdClass; - - $newObj->field_id = (int) $fieldId; - $newObj->item_id = $itemId; - - foreach ($value as $v) - { - $newObj->value = $v; - - $this->getDbo()->insertObject('#__fields_values', $newObj); - } - } - - if ($needsUpdate) - { - $updateObj = new stdClass; - - $updateObj->field_id = (int) $fieldId; - $updateObj->item_id = $itemId; - $updateObj->value = reset($value); - - $this->getDbo()->updateObject('#__fields_values', $updateObj, array('field_id', 'item_id')); - } - - $this->valueCache = array(); - FieldsHelper::clearFieldsCache(); - - return true; - } - - /** - * Returning 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. - * - * @return NULL|string - * - * @since 3.7.0 - */ - public function getFieldValue($fieldId, $itemId) - { - $values = $this->getFieldValues(array($fieldId), $itemId); - - if (key_exists($fieldId, $values)) - { - return $values[$fieldId]; - } - - return null; - } - - /** - * Returning the values for the given field ids, context and item id. - * - * @param array $fieldIds The field Ids. - * @param string $itemId The ID of the item. - * - * @return NULL|array - * - * @since 3.7.0 - */ - public function getFieldValues(array $fieldIds, $itemId) - { - if (!$fieldIds) - { - return array(); - } - - // Create a unique key for the cache - $key = md5(serialize($fieldIds) . $itemId); - - // Fill the cache when it doesn't exist - if (!key_exists($key, $this->valueCache)) - { - // Create the query - $query = $this->getDbo()->getQuery(true); - - $query->select(array($query->qn('field_id'), $query->qn('value'))) - ->from($query->qn('#__fields_values')) - ->where($query->qn('field_id') . ' IN (' . implode(',', ArrayHelper::toInteger($fieldIds)) . ')') - ->where($query->qn('item_id') . ' = ' . $query->q($itemId)); - - // Fetch the row from the database - $rows = $this->getDbo()->setQuery($query)->loadObjectList(); - - $data = array(); - - // Fill the data container from the database rows - foreach ($rows as $row) - { - // If there are multiple values for a field, create an array - if (key_exists($row->field_id, $data)) - { - // Transform it to an array - if (!is_array($data[$row->field_id])) - { - $data[$row->field_id] = array($data[$row->field_id]); - } - - // Set the value in the array - $data[$row->field_id][] = $row->value; - - // Go to the next row, otherwise the value gets overwritten in the data container - continue; - } - - // Set the value - $data[$row->field_id] = $row->value; - } - - // Assign it to the internal cache - $this->valueCache[$key] = $data; - } - - // Return the value from the cache - return $this->valueCache[$key]; - } - - /** - * Cleaning up the values for the given item on the context. - * - * @param string $context The context. - * @param string $itemId The Item ID. - * - * @return void - * - * @since 3.7.0 - */ - public function cleanupValues($context, $itemId) - { - // Delete with inner join is not possible so we need to do a subquery - $fieldsQuery = $this->getDbo()->getQuery(true); - $fieldsQuery->select($fieldsQuery->qn('id')) - ->from($fieldsQuery->qn('#__fields')) - ->where($fieldsQuery->qn('context') . ' = ' . $fieldsQuery->q($context)); - - $query = $this->getDbo()->getQuery(true); - - $query->delete($query->qn('#__fields_values')) - ->where($query->qn('field_id') . ' IN (' . $fieldsQuery . ')') - ->where($query->qn('item_id') . ' = ' . $query->q($itemId)); - - $this->getDbo()->setQuery($query)->execute(); - } - - /** - * Method to test whether a record can be deleted. - * - * @param object $record A record object. - * - * @return boolean True if allowed to delete the record. Defaults to the permission for the component. - * - * @since 3.7.0 - */ - protected function canDelete($record) - { - if (!empty($record->id)) - { - 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; - } - - /** - * 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 for the - * component. - * - * @since 3.7.0 - */ - protected function canEditState($record) - { - $user = JFactory::getUser(); - $parts = FieldsHelper::extract($record->context); - - // Check for existing field. - if (!empty($record->id)) - { - return $user->authorise('core.edit.state', $parts[0] . '.field.' . (int) $record->id); - } - - return $user->authorise('core.edit.state', $parts[0]); - } - - /** - * Stock method to auto-populate the model state. - * - * @return void - * - * @since 3.7.0 - */ - protected function populateState() - { - $app = JFactory::getApplication('administrator'); - - // Load the User state. - $pk = $app->input->getInt('id'); - $this->setState($this->getName() . '.id', $pk); - - $context = $app->input->get('context', 'com_content.article'); - $this->setState('field.context', $context); - $parts = FieldsHelper::extract($context); - - // Extract the component name - $this->setState('field.component', $parts[0]); - - // Extract the optional section name - $this->setState('field.section', (count($parts) > 1) ? $parts[1] : null); - - // Load the parameters. - $params = JComponentHelper::getParams('com_fields'); - $this->setState('params', $params); - } - - /** - * A protected method to get a set of ordering conditions. - * - * @param JTable $table A JTable object. - * - * @return array An array of conditions to add to ordering queries. - * - * @since 3.7.0 - */ - protected function getReorderConditions($table) - { - return 'context = ' . $this->_db->quote($table->context); - } - - /** - * Method to get the data that should be injected in the form. - * - * @return array The default data is an empty array. - * - * @since 3.7.0 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $app = JFactory::getApplication(); - $data = $app->getUserState('com_fields.edit.field.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - - // Pre-select some filters (Status, Language, Access) in edit form - // if those have been selected in Category Manager - if (!$data->id) - { - // Check for which context the Category Manager is used and - // get selected fields - $filters = (array) $app->getUserState('com_fields.fields.filter'); - - $data->set('state', $app->input->getInt('state', ((isset($filters['state']) && $filters['state'] !== '') ? $filters['state'] : null))); - $data->set('language', $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null))); - $data->set('group_id', $app->input->getString('group_id', (!empty($filters['group_id']) ? $filters['group_id'] : null))); - $data->set( - 'access', - $app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access'))) - ); - - // Set the type if available from the request - $data->set('type', $app->input->getWord('type', $this->state->get('field.type', $data->get('type')))); - } - - if ($data->label && !isset($data->params['label'])) - { - $data->params['label'] = $data->label; - } - } - - $this->preprocessData('com_fields.field', $data); - - return $data; - } - - /** - * Method to allow derived classes to preprocess the form. - * - * @param JForm $form A JForm object. - * @param mixed $data The data expected for the form. - * @param string $group The name of the plugin group to import (defaults to "content"). - * - * @return void - * - * @see JFormField - * @since 3.7.0 - * @throws Exception if there is an error in the form event. - */ - protected function preprocessForm(JForm $form, $data, $group = 'content') - { - $component = $this->state->get('field.component'); - $section = $this->state->get('field.section'); - $dataObject = $data; - - if (is_array($dataObject)) - { - $dataObject = (object) $dataObject; - } - - if (isset($dataObject->type)) - { - $form->setFieldAttribute('type', 'component', $component); - - // Not allowed to change the type of an existing record - if ($dataObject->id) - { - $form->setFieldAttribute('type', 'readonly', 'true'); - } - - // 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)); - - if ($cat && $cat->get('root')->hasChildren()) - { - $form->setFieldAttribute('assigned_cat_ids', 'extension', $component); - } - else - { - $form->removeField('assigned_cat_ids'); - } - - $form->setFieldAttribute('type', 'component', $component); - $form->setFieldAttribute('group_id', 'context', $this->state->get('field.context')); - $form->setFieldAttribute('rules', 'component', $component); - - // Looking first in the component models/forms folder - $path = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/models/forms/fields/' . $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')); - } - } - - // Trigger the default form events. - parent::preprocessForm($form, $data, $group); - } - - /** - * Clean the cache - * - * @param string $group The cache group - * @param integer $client_id The ID of the client - * - * @return void - * - * @since 3.7.0 - */ - protected function cleanCache($group = null, $client_id = 0) - { - $context = JFactory::getApplication()->input->get('context'); - - switch ($context) - { - case 'com_content': - parent::cleanCache('com_content'); - parent::cleanCache('mod_articles_archive'); - parent::cleanCache('mod_articles_categories'); - parent::cleanCache('mod_articles_category'); - parent::cleanCache('mod_articles_latest'); - parent::cleanCache('mod_articles_news'); - parent::cleanCache('mod_articles_popular'); - break; - default: - parent::cleanCache($context); - break; - } - } - - /** - * Batch copy fields to a new group. - * - * @param integer $value The new value matching a fields group. - * @param array $pks An array of row IDs. - * @param array $contexts An array of item contexts. - * - * @return array|boolean new IDs if successful, false otherwise and internal error is set. - * - * @since 3.7.0 - */ - protected function batchCopy($value, $pks, $contexts) - { - // Set the variables - $user = JFactory::getUser(); - $table = $this->getTable(); - $newIds = array(); - $component = $this->state->get('filter.component'); - $value = (int) $value; - - foreach ($pks as $pk) - { - if ($user->authorise('core.create', $component . '.fieldgroup.' . $value)) - { - $table->reset(); - $table->load($pk); - - $table->group_id = $value; - - // Reset the ID because we are making a copy - $table->id = 0; - - // Unpublish the new field - $table->state = 0; - - 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; - } - else - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); - - return false; - } - } - - // Clean the cache - $this->cleanCache(); - - return $newIds; - } - - /** - * Batch move fields to a new group. - * - * @param integer $value The new value matching a fields group. - * @param array $pks An array of row IDs. - * @param array $contexts An array of item contexts. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 3.7.0 - */ - protected function batchMove($value, $pks, $contexts) - { - // Set the variables - $user = JFactory::getUser(); - $table = $this->getTable(); - $context = explode('.', JFactory::getApplication()->getUserState('com_fields.fields.context')); - $value = (int) $value; - - foreach ($pks as $pk) - { - if ($user->authorise('core.edit', $context[0] . '.fieldgroup.' . $value)) - { - $table->reset(); - $table->load($pk); - - $table->group_id = $value; - - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - } - else - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); - - return false; - } - } - - // Clean the cache - $this->cleanCache(); - - return true; - } -} diff --git a/administrator/components/com_fields/models/fields.php b/administrator/components/com_fields/models/fields.php deleted file mode 100644 index 271191d1c8e33..0000000000000 --- a/administrator/components/com_fields/models/fields.php +++ /dev/null @@ -1,389 +0,0 @@ -getUserStateFromRequest($this->context . '.context', 'context', 'com_content.article', 'CMD'); - $this->setState('filter.context', $context); - - // Split context into component and optional section - $parts = FieldsHelper::extract($context); - - if ($parts) - { - $this->setState('filter.component', $parts[0]); - $this->setState('filter.section', $parts[1]); - } - } - - /** - * Method to get a store id based on the 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 An identifier string to generate the store id. - * - * @return string A store id. - * - * @since 3.7.0 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.context'); - $id .= ':' . serialize($this->getState('filter.assigned_cat_ids')); - $id .= ':' . $this->getState('filter.state'); - $id .= ':' . $this->getState('filter.group_id'); - $id .= ':' . serialize($this->getState('filter.language')); - - return parent::getStoreId($id); - } - - /** - * Method to get a JDatabaseQuery object for retrieving the data set from a database. - * - * @return JDatabaseQuery A JDatabaseQuery object to retrieve the data set. - * - * @since 3.7.0 - */ - protected function getListQuery() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - $user = JFactory::getUser(); - $app = JFactory::getApplication(); - - // Select the required fields from the table. - $query->select( - $this->getState( - 'list.select', - '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' - ) - ); - $query->from('#__fields AS a'); - - // Join over the language - $query->select('l.title AS language_title, l.image AS language_image') - ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); - - // Join over the users for the checked out user. - $query->select('uc.name AS editor')->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); - - // Join over the asset groups. - $query->select('ag.title AS access_level')->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); - - // Join over the users for the author. - $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->join('LEFT', '#__fields_groups AS g ON g.id = a.group_id'); - - // Filter by context - if ($context = $this->getState('filter.context')) - { - $query->where('a.context = ' . $db->quote($context)); - } - - // Filter by access level. - if ($access = $this->getState('filter.access')) - { - if (is_array($access)) - { - $access = ArrayHelper::toInteger($access); - $query->where('a.access in (' . implode(',', $access) . ')'); - } - else - { - $query->where('a.access = ' . (int) $access); - } - } - - if (($categories = $this->getState('filter.assigned_cat_ids')) && $context) - { - $categories = (array) $categories; - $categories = ArrayHelper::toInteger($categories); - $parts = FieldsHelper::extract($context); - - if ($parts) - { - // Get the category - $cat = JCategories::getInstance(str_replace('com_', '', $parts[0])); - - if ($cat) - { - foreach ($categories as $assignedCatIds) - { - // Check if we have the actual category - $parent = $cat->get($assignedCatIds); - - if ($parent) - { - $categories[] = (int) $parent->id; - - // Traverse the tree up to get all the fields which are attached to a parent - while ($parent->getParent() && $parent->getParent()->id != 'root') - { - $parent = $parent->getParent(); - $categories[] = (int) $parent->id; - } - } - } - } - } - - $categories = array_unique($categories); - - // Join over the assigned categories - $query->join('LEFT', $db->quoteName('#__fields_categories') . ' AS fc ON fc.field_id = a.id'); - - if (in_array('0', $categories)) - { - $query->where('(fc.category_id IS NULL OR fc.category_id IN (' . implode(',', $categories) . '))'); - } - else - { - $query->where('fc.category_id IN (' . implode(',', $categories) . ')'); - } - } - - // Implement View Level Access - if (!$app->isClient('administrator') || !$user->authorise('core.admin')) - { - $groups = implode(',', $user->getAuthorisedViewLevels()); - $query->where('a.access IN (' . $groups . ') AND (a.group_id = 0 OR g.access IN (' . $groups . '))'); - } - - // Filter by state - $state = $this->getState('filter.state'); - - // Include group state only when not on on back end list - $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); - - if ($includeGroupState) - { - $query->where('(a.group_id = 0 OR g.state = ' . (int) $state . ')'); - } - } - elseif (!$state) - { - $query->where('a.state IN (0, 1)'); - - if ($includeGroupState) - { - $query->where('(a.group_id = 0 OR g.state IN (0, 1))'); - } - } - - $groupId = $this->getState('filter.group_id'); - - if (is_numeric($groupId)) - { - $query->where('a.group_id = ' . (int) $groupId); - } - - // Filter by search in title - $search = $this->getState('filter.search'); - - if (! empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - elseif (stripos($search, 'author:') === 0) - { - $search = $db->quote('%' . $db->escape(substr($search, 7), true) . '%'); - $query->where('(ua.name LIKE ' . $search . ' OR ua.username LIKE ' . $search . ')'); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('(a.title LIKE ' . $search . ' OR a.name LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); - } - } - - // Filter on the language. - if ($language = $this->getState('filter.language')) - { - $language = (array) $language; - - foreach ($language as $key => $l) - { - $language[$key] = $db->quote($l); - } - - $query->where('a.language in (' . implode(',', $language) . ')'); - } - - // Add the list ordering clause - $listOrdering = $this->state->get('list.ordering', 'a.ordering'); - $orderDirn = $this->state->get('list.direction', 'ASC'); - - $query->order($db->escape($listOrdering) . ' ' . $db->escape($orderDirn)); - - 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.7.0 - * @throws RuntimeException - */ - protected function _getList($query, $limitstart = 0, $limit = 0) - { - $result = parent::_getList($query, $limitstart, $limit); - - if (is_array($result)) - { - foreach ($result as $field) - { - $field->fieldparams = new Registry($field->fieldparams); - $field->params = new Registry($field->params); - } - } - - return $result; - } - - /** - * Get the filter form - * - * @param array $data data - * @param boolean $loadData load current data - * - * @return JForm|false the JForm object or false - * - * @since 3.7.0 - */ - public function getFilterForm($data = array(), $loadData = true) - { - $form = parent::getFilterForm($data, $loadData); - - if ($form) - { - $form->setValue('context', null, $this->getState('filter.context')); - $form->setFieldAttribute('group_id', 'context', $this->getState('filter.context'), 'filter'); - $form->setFieldAttribute('assigned_cat_ids', 'extension', $this->state->get('filter.component'), 'filter'); - } - - return $form; - } - - /** - * Get the groups for the batch method - * - * @return array An array of groups - * - * @since 3.7.0 - */ - public function getGroups() - { - $user = JFactory::getUser(); - $viewlevels = ArrayHelper::toInteger($user->getAuthorisedViewLevels()); - - $db = $this->getDbo(); - $query = $db->getQuery(true); - $query->select('title AS text, id AS value, state'); - $query->from('#__fields_groups'); - $query->where('state IN (0,1)'); - $query->where('context = ' . $db->quote($this->state->get('filter.context'))); - $query->where('access IN (' . implode(',', $viewlevels) . ')'); - - $db->setQuery($query); - - return $db->loadObjectList(); - } -} diff --git a/administrator/components/com_fields/models/fields/fieldcontexts.php b/administrator/components/com_fields/models/fields/fieldcontexts.php deleted file mode 100644 index 262c4f1447302..0000000000000 --- a/administrator/components/com_fields/models/fields/fieldcontexts.php +++ /dev/null @@ -1,71 +0,0 @@ -getOptions() ? parent::getInput() : ''; - } - - /** - * Method to get the field options. - * - * @return array The field option objects. - * - * @since 3.7.0 - */ - protected function getOptions() - { - $parts = explode('.', $this->value); - $eName = str_replace('com_', '', $parts[0]); - $file = JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $parts[0] . '/helpers/' . $eName . '.php'); - $contexts = array(); - - if (!file_exists($file)) - { - return array(); - } - - $prefix = ucfirst($eName); - $cName = $prefix . 'Helper'; - - JLoader::register($cName, $file); - - if (class_exists($cName) && is_callable(array($cName, 'getContexts'))) - { - $contexts = $cName::getContexts(); - } - - if (!$contexts || !is_array($contexts) || count($contexts) == 1) - { - return array(); - } - - return $contexts; - } -} diff --git a/administrator/components/com_fields/models/fields/fieldgroups.php b/administrator/components/com_fields/models/fields/fieldgroups.php deleted file mode 100644 index 7932d50186a0f..0000000000000 --- a/administrator/components/com_fields/models/fields/fieldgroups.php +++ /dev/null @@ -1,67 +0,0 @@ -element['context']; - $states = $this->element['state'] ?: '0,1'; - $states = ArrayHelper::toInteger(explode(',', $states)); - - $user = JFactory::getUser(); - $viewlevels = ArrayHelper::toInteger($user->getAuthorisedViewLevels()); - - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - $query->select('title AS text, id AS value, state'); - $query->from('#__fields_groups'); - $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(); - - foreach ($options AS $option) - { - if ($option->state == 0) - { - $option->text = '[' . $option->text . ']'; - } - - if ($option->state == 2) - { - $option->text = '{' . $option->text . '}'; - } - } - - return array_merge(parent::getOptions(), $options); - } -} diff --git a/administrator/components/com_fields/models/fields/section.php b/administrator/components/com_fields/models/fields/section.php deleted file mode 100644 index 75b99bd70ce7b..0000000000000 --- a/administrator/components/com_fields/models/fields/section.php +++ /dev/null @@ -1,68 +0,0 @@ -` 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. - * - * @since 3.7.0 - */ - public function setup(SimpleXMLElement $element, $value, $group = null) - { - $return = parent::setup($element, $value, $group); - - // Onchange must always be the change context function - $this->onchange = 'fieldsChangeContext(jQuery(this).val());'; - - return $return; - } - - /** - * Method to get the field input markup for a generic list. - * Use the multiple attribute to enable multiselect. - * - * @return string The field input markup. - * - * @since 3.7.0 - */ - protected function getInput() - { - // Add the change context function to the document - JFactory::getDocument()->addScriptDeclaration( - "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 deleted file mode 100644 index 05b3270ba72d3..0000000000000 --- a/administrator/components/com_fields/models/fields/type.php +++ /dev/null @@ -1,86 +0,0 @@ -` 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. - * - * @since 3.7.0 - */ - public function setup(SimpleXMLElement $element, $value, $group = null) - { - $return = parent::setup($element, $value, $group); - - $this->onchange = 'typeHasChanged(this);'; - - return $return; - } - - /** - * Method to get the field options. - * - * @return array The field option objects. - * - * @since 3.7.0 - */ - protected function getOptions() - { - $options = parent::getOptions(); - - $fieldTypes = FieldsHelper::getFieldTypes(); - - foreach ($fieldTypes as $fieldType) - { - $options[] = JHtml::_('select.option', $fieldType['type'], $fieldType['label']); - } - - // Sorting the fields based on the text which is displayed - usort( - $options, - function ($a, $b) - { - return strcmp($a->text, $b->text); - } - ); - - JFactory::getDocument()->addScriptDeclaration(" - jQuery( document ).ready(function() { - Joomla.loadingLayer('load'); - }); - function typeHasChanged(element){ - Joomla.loadingLayer('show'); - var cat = jQuery(element); - jQuery('input[name=task]').val('field.reload'); - element.form.submit(); - } - " - ); - - return $options; - } -} diff --git a/administrator/components/com_fields/models/forms/filter_fields.xml b/administrator/components/com_fields/models/forms/filter_fields.xml deleted file mode 100644 index aca47a63e508b..0000000000000 --- a/administrator/components/com_fields/models/forms/filter_fields.xml +++ /dev/null @@ -1,100 +0,0 @@ - -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/administrator/components/com_fields/models/forms/filter_groups.xml b/administrator/components/com_fields/models/forms/filter_groups.xml deleted file mode 100644 index 6e18a7daf0b23..0000000000000 --- a/administrator/components/com_fields/models/forms/filter_groups.xml +++ /dev/null @@ -1,74 +0,0 @@ - -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/administrator/components/com_fields/models/forms/group.xml b/administrator/components/com_fields/models/forms/group.xml deleted file mode 100644 index 03a6619019378..0000000000000 --- a/administrator/components/com_fields/models/forms/group.xml +++ /dev/null @@ -1,153 +0,0 @@ - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
diff --git a/administrator/components/com_fields/models/group.php b/administrator/components/com_fields/models/group.php deleted file mode 100644 index d8f8c087ed470..0000000000000 --- a/administrator/components/com_fields/models/group.php +++ /dev/null @@ -1,362 +0,0 @@ - 'batchAccess', - 'language_id' => 'batchLanguage' - ); - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success, False on error. - * - * @since 3.7.0 - */ - public function save($data) - { - // Alter the title for save as copy - $input = JFactory::getApplication()->input; - - // Save new group as unpublished - if ($input->get('task') == 'save2copy') - { - $data['state'] = 0; - } - - return parent::save($data); - } - - /** - * 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.7.0 - * @throws Exception - */ - public function getTable($name = 'Group', $prefix = 'FieldsTable', $options = array()) - { - return JTable::getInstance($name, $prefix, $options); - } - - /** - * Abstract 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 mixed A JForm object on success, false on failure - * - * @since 3.7.0 - */ - public function getForm($data = array(), $loadData = true) - { - $context = $this->getState('filter.context'); - $jinput = JFactory::getApplication()->input; - - if (empty($context) && isset($data['context'])) - { - $context = $data['context']; - $this->setState('filter.context', $context); - } - - // Get the form. - $form = $this->loadForm( - 'com_fields.group.' . $context, 'group', - array( - 'control' => 'jform', - 'load_data' => $loadData, - ) - ); - - if (empty($form)) - { - return false; - } - - // Modify the form based on Edit State access controls. - if (empty($data['context'])) - { - $data['context'] = $context; - } - - if (!JFactory::getUser()->authorise('core.edit.state', $context . '.fieldgroup.' . $jinput->get('id'))) - { - // Disable fields for display. - $form->setFieldAttribute('ordering', 'disabled', 'true'); - $form->setFieldAttribute('state', 'disabled', 'true'); - - // Disable fields while saving. The controller has already verified this is a record you can edit. - $form->setFieldAttribute('ordering', 'filter', 'unset'); - $form->setFieldAttribute('state', 'filter', 'unset'); - } - - return $form; - } - - /** - * Method to test whether a record can be deleted. - * - * @param object $record A record object. - * - * @return boolean True if allowed to delete the record. Defaults to the permission for the component. - * - * @since 3.7.0 - */ - protected function canDelete($record) - { - if (empty($record->id) || $record->state != -2) - { - return false; - } - - return JFactory::getUser()->authorise('core.delete', $record->context . '.fieldgroup.' . (int) $record->id); - } - - /** - * 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 for the - * component. - * - * @since 3.7.0 - */ - protected function canEditState($record) - { - $user = JFactory::getUser(); - - // Check for existing fieldgroup. - if (!empty($record->id)) - { - return $user->authorise('core.edit.state', $record->context . '.fieldgroup.' . (int) $record->id); - } - - // Default to component settings. - return $user->authorise('core.edit.state', $record->context); - } - - /** - * Auto-populate the model state. - * - * Note. Calling getState in this method will result in recursion. - * - * @return void - * - * @since 3.7.0 - */ - protected function populateState() - { - parent::populateState(); - - $context = JFactory::getApplication()->getUserStateFromRequest('com_fields.groups.context', 'context', 'com_fields', 'CMD'); - $this->setState('filter.context', $context); - } - - /** - * A protected method to get a set of ordering conditions. - * - * @param JTable $table A JTable object. - * - * @return array An array of conditions to add to ordering queries. - * - * @since 3.7.0 - */ - protected function getReorderConditions($table) - { - return 'context = ' . $this->_db->quote($table->context); - } - - /** - * Method to preprocess the form. - * - * @param JForm $form A JForm object. - * @param mixed $data The data expected for the form. - * @param string $group The name of the plugin group to import (defaults to "content"). - * - * @return void - * - * @see JFormField - * @since 3.7.0 - * @throws Exception if there is an error in the form event. - */ - protected function preprocessForm(JForm $form, $data, $group = 'content') - { - parent::preprocessForm($form, $data, $group); - - $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', $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 get the data that should be injected in the form. - * - * @return array The default data is an empty array. - * - * @since 3.7.0 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $app = JFactory::getApplication(); - $data = $app->getUserState('com_fields.edit.group.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - - // Pre-select some filters (Status, Language, Access) in edit form if those have been selected in Field Group Manager - if (!$data->id) - { - // Check for which context the Field Group Manager is used and get selected fields - $context = substr($app->getUserState('com_fields.groups.filter.context'), 4); - $filters = (array) $app->getUserState('com_fields.groups.' . $context . '.filter'); - - $data->set( - 'state', - $app->input->getInt('state', (!empty($filters['state']) ? $filters['state'] : null)) - ); - $data->set( - 'language', - $app->input->getString('language', (!empty($filters['language']) ? $filters['language'] : null)) - ); - $data->set( - 'access', - $app->input->getInt('access', (!empty($filters['access']) ? $filters['access'] : JFactory::getConfig()->get('access'))) - ); - } - } - - $this->preprocessData('com_fields.group', $data); - - return $data; - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - * - * @since 3.7.0 - */ - public function getItem($pk = null) - { - if ($item = parent::getItem($pk)) - { - // Prime required properties. - if (empty($item->id)) - { - $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 - { - $item->modified = null; - } - } - - return $item; - } - - /** - * Clean the cache - * - * @param string $group The cache group - * @param integer $client_id The ID of the client - * - * @return void - * - * @since 3.7.0 - */ - protected function cleanCache($group = null, $client_id = 0) - { - $context = JFactory::getApplication()->input->get('context'); - - parent::cleanCache($context); - } -} diff --git a/administrator/components/com_fields/models/groups.php b/administrator/components/com_fields/models/groups.php deleted file mode 100644 index 93ddb6632d00c..0000000000000 --- a/administrator/components/com_fields/models/groups.php +++ /dev/null @@ -1,216 +0,0 @@ -getUserStateFromRequest($this->context . '.context', 'context', 'com_content', 'CMD'); - $this->setState('filter.context', $context); - } - - /** - * Method to get a store id based on the 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 An identifier string to generate the store id. - * - * @return string A store id. - * - * @since 3.7.0 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.context'); - $id .= ':' . $this->getState('filter.state'); - $id .= ':' . print_r($this->getState('filter.language'), true); - - return parent::getStoreId($id); - } - - /** - * Method to get a JDatabaseQuery object for retrieving the data set from a database. - * - * @return JDatabaseQuery A JDatabaseQuery object to retrieve the data set. - * - * @since 3.7.0 - */ - protected function getListQuery() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - $user = JFactory::getUser(); - - // Select the required fields from the table. - $query->select($this->getState('list.select', 'a.*')); - $query->from('#__fields_groups AS a'); - - // Join over the language - $query->select('l.title AS language_title, l.image AS language_image') - ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); - - // Join over the users for the checked out user. - $query->select('uc.name AS editor')->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); - - // Join over the asset groups. - $query->select('ag.title AS access_level')->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); - - // 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'); - - // Filter by context - if ($context = $this->getState('filter.context', 'com_fields')) - { - $query->where('a.context = ' . $db->quote($context)); - } - - // Filter by access level. - if ($access = $this->getState('filter.access')) - { - if (is_array($access)) - { - $access = ArrayHelper::toInteger($access); - $query->where('a.access in (' . implode(',', $access) . ')'); - } - else - { - $query->where('a.access = ' . (int) $access); - } - } - - // Implement View Level Access - if (!$user->authorise('core.admin')) - { - $groups = implode(',', $user->getAuthorisedViewLevels()); - $query->where('a.access IN (' . $groups . ')'); - } - - // Filter by published state - $state = $this->getState('filter.state'); - - if (is_numeric($state)) - { - $query->where('a.state = ' . (int) $state); - } - elseif (!$state) - { - $query->where('a.state IN (0, 1)'); - } - - // Filter by search in title - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('a.title LIKE ' . $search); - } - } - - // Filter on the language. - if ($language = $this->getState('filter.language')) - { - $language = (array) $language; - - foreach ($language as $key => $l) - { - $language[$key] = $db->quote($l); - } - - $query->where('a.language in (' . implode(',', $language) . ')'); - } - - // Add the list ordering clause - $listOrdering = $this->getState('list.ordering', 'a.ordering'); - $listDirn = $db->escape($this->getState('list.direction', 'ASC')); - - $query->order($db->escape($listOrdering) . ' ' . $listDirn); - - return $query; - } -} diff --git a/administrator/components/com_fields/services/provider.php b/administrator/components/com_fields/services/provider.php new file mode 100644 index 0000000000000..f5bac66933c18 --- /dev/null +++ b/administrator/components/com_fields/services/provider.php @@ -0,0 +1,54 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Fields')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Fields')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_fields/tables/field.php b/administrator/components/com_fields/tables/field.php deleted file mode 100644 index daf46e6874b5a..0000000000000 --- a/administrator/components/com_fields/tables/field.php +++ /dev/null @@ -1,263 +0,0 @@ -setColumnAlias('published', 'state'); - } - - /** - * Method to bind an associative array or object to the JTable instance.This - * method only binds properties that are publicly accessible and optionally - * takes an array of properties to ignore when binding. - * - * @param mixed $src An associative array or object to bind to the JTable instance. - * @param mixed $ignore An optional array or space separated list of properties to ignore while binding. - * - * @return boolean True on success. - * - * @since 3.7.0 - * @throws InvalidArgumentException - */ - public function bind($src, $ignore = '') - { - if (isset($src['params']) && is_array($src['params'])) - { - $registry = new Registry; - $registry->loadArray($src['params']); - $src['params'] = (string) $registry; - } - - if (isset($src['fieldparams']) && is_array($src['fieldparams'])) - { - $registry = new Registry; - $registry->loadArray($src['fieldparams']); - $src['fieldparams'] = (string) $registry; - } - - // Bind the rules. - if (isset($src['rules']) && is_array($src['rules'])) - { - $rules = new JAccessRules($src['rules']); - $this->setRules($rules); - } - - return parent::bind($src, $ignore); - } - - /** - * Method to perform sanity checks on the JTable instance properties to ensure - * they are safe to store in the database. Child classes should override this - * method to make sure the data they are storing in the database is safe and - * as expected before storage. - * - * @return boolean True if the instance is sane and able to be stored in the database. - * - * @link https://docs.joomla.org/Special:MyLanguage/JTable/check - * @since 3.7.0 - */ - public function check() - { - // Check for valid name - if (trim($this->title) == '') - { - $this->setError(JText::_('COM_FIELDS_MUSTCONTAIN_A_TITLE_FIELD')); - - return false; - } - - if (empty($this->name)) - { - $this->name = $this->title; - } - - $this->name = JApplicationHelper::stringURLSafe($this->name, $this->language); - - if (trim(str_replace('-', '', $this->name)) == '') - { - $this->name = Joomla\String\StringHelper::increment($this->name, 'dash'); - } - - $this->name = str_replace(',', '-', $this->name); - - // Verify that the name is unique - $table = JTable::getInstance('Field', 'FieldsTable', array('dbo' => $this->_db)); - - if ($table->load(array('name' => $this->name)) && ($table->id != $this->id || $this->id == 0)) - { - $this->setError(JText::_('COM_FIELDS_ERROR_UNIQUE_NAME')); - - return false; - } - - $this->name = str_replace(',', '-', $this->name); - - if (empty($this->type)) - { - $this->type = 'text'; - } - - $date = JFactory::getDate(); - $user = JFactory::getUser(); - - if ($this->id) - { - // Existing item - $this->modified_time = $date->toSql(); - $this->modified_by = $user->get('id'); - } - else - { - if (!(int) $this->created_time) - { - $this->created_time = $date->toSql(); - } - - if (empty($this->created_user_id)) - { - $this->created_user_id = $user->get('id'); - } - } - - if (empty($this->group_id)) - { - $this->group_id = 0; - } - - return true; - } - - /** - * Method to compute the default name of the asset. - * The default name is in the form table_name.id - * where id is the value of the primary key of the table. - * - * @return string - * - * @since 3.7.0 - */ - protected function _getAssetName() - { - $contextArray = explode('.', $this->context); - - return $contextArray[0] . '.field.' . (int) $this->id; - } - - /** - * Method to return the title to use for the asset table. In - * tracking the assets a title is kept for each asset so that there is some - * context available in a unified access manager. Usually this would just - * return $this->title or $this->name or whatever is being used for the - * primary name of the row. If this method is not overridden, the asset name is used. - * - * @return string The string to use as the title in the asset table. - * - * @link https://docs.joomla.org/Special:MyLanguage/JTable/getAssetTitle - * @since 3.7.0 - */ - protected function _getAssetTitle() - { - return $this->title; - } - - /** - * Method to get the parent asset under which to register this one. - * By default, all assets are registered to the ROOT node with ID, - * which will default to 1 if none exists. - * The extended class can define a table and id to lookup. If the - * asset does not exist it will be created. - * - * @param JTable $table A JTable object for the asset parent. - * @param integer $id Id to look up - * - * @return integer - * - * @since 3.7.0 - */ - protected function _getAssetParentId(JTable $table = null, $id = null) - { - $contextArray = explode('.', $this->context); - $component = $contextArray[0]; - - if ($this->group_id) - { - $assetId = $this->getAssetId($component . '.fieldgroup.' . (int) $this->group_id); - - if ($assetId) - { - return $assetId; - } - } - else - { - $assetId = $this->getAssetId($component); - - if ($assetId) - { - return $assetId; - } - } - - return parent::_getAssetParentId($table, $id); - } - - /** - * Returns an asset id for the given name or false. - * - * @param string $name The asset name - * - * @return number|boolean - * - * @since 3.7.0 - */ - private function getAssetId($name) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from($db->quoteName('#__assets')) - ->where($db->quoteName('name') . ' = ' . $db->quote($name)); - - // Get the asset id from the database. - $db->setQuery($query); - - $assetId = null; - - if ($result = $db->loadResult()) - { - $assetId = (int) $result; - - if ($assetId) - { - return $assetId; - } - } - - return false; - } -} diff --git a/administrator/components/com_fields/tables/group.php b/administrator/components/com_fields/tables/group.php deleted file mode 100644 index cec38c262417d..0000000000000 --- a/administrator/components/com_fields/tables/group.php +++ /dev/null @@ -1,175 +0,0 @@ -setColumnAlias('published', 'state'); - } - - /** - * Method to bind an associative array or object to the JTable instance.This - * method only binds properties that are publicly accessible and optionally - * takes an array of properties to ignore when binding. - * - * @param mixed $src An associative array or object to bind to the JTable instance. - * @param mixed $ignore An optional array or space separated list of properties to ignore while binding. - * - * @return boolean True on success. - * - * @since 3.7.0 - * @throws InvalidArgumentException - */ - public function bind($src, $ignore = '') - { - if (isset($src['params']) && is_array($src['params'])) - { - $registry = new Registry; - $registry->loadArray($src['params']); - $src['params'] = (string) $registry; - } - - // Bind the rules. - if (isset($src['rules']) && is_array($src['rules'])) - { - $rules = new JAccessRules($src['rules']); - $this->setRules($rules); - } - - return parent::bind($src, $ignore); - } - - /** - * Method to perform sanity checks on the JTable instance properties to ensure - * they are safe to store in the database. Child classes should override this - * method to make sure the data they are storing in the database is safe and - * as expected before storage. - * - * @return boolean True if the instance is sane and able to be stored in the database. - * - * @link https://docs.joomla.org/Special:MyLanguage/JTable/check - * @since 3.7.0 - */ - public function check() - { - // Check for a title. - if (trim($this->title) == '') - { - $this->setError(JText::_('COM_FIELDS_MUSTCONTAIN_A_TITLE_GROUP')); - - return false; - } - - $date = JFactory::getDate(); - $user = JFactory::getUser(); - - if ($this->id) - { - $this->modified = $date->toSql(); - $this->modified_by = $user->get('id'); - } - else - { - if (!(int) $this->created) - { - $this->created = $date->toSql(); - } - - if (empty($this->created_by)) - { - $this->created_by = $user->get('id'); - } - } - - return true; - } - - /** - * Method to compute the default name of the asset. - * The default name is in the form table_name.id - * where id is the value of the primary key of the table. - * - * @return string - * - * @since 3.7.0 - */ - protected function _getAssetName() - { - $component = explode('.', $this->context); - - return $component[0] . '.fieldgroup.' . (int) $this->id; - } - - /** - * Method to return the title to use for the asset table. In - * tracking the assets a title is kept for each asset so that there is some - * context available in a unified access manager. Usually this would just - * return $this->title or $this->name or whatever is being used for the - * primary name of the row. If this method is not overridden, the asset name is used. - * - * @return string The string to use as the title in the asset table. - * - * @link https://docs.joomla.org/Special:MyLanguage/JTable/getAssetTitle - * @since 3.7.0 - */ - protected function _getAssetTitle() - { - return $this->title; - } - - /** - * Method to get the parent asset under which to register this one. - * By default, all assets are registered to the ROOT node with ID, - * which will default to 1 if none exists. - * The extended class can define a table and id to lookup. If the - * asset does not exist it will be created. - * - * @param JTable $table A JTable object for the asset parent. - * @param integer $id Id to look up - * - * @return integer - * - * @since 3.7.0 - */ - protected function _getAssetParentId(JTable $table = null, $id = null) - { - $component = explode('.', $this->context); - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from($db->quoteName('#__assets')) - ->where($db->quoteName('name') . ' = ' . $db->quote($component[0])); - $db->setQuery($query); - - if ($assetId = (int) $db->loadResult()) - { - return $assetId; - } - - return parent::_getAssetParentId($table, $id); - } -} diff --git a/administrator/components/com_fields/tmpl/field/edit.php b/administrator/components/com_fields/tmpl/field/edit.php new file mode 100644 index 0000000000000..4e9598aa6c4a5 --- /dev/null +++ b/administrator/components/com_fields/tmpl/field/edit.php @@ -0,0 +1,99 @@ + 0 )); + +$app = Factory::getApplication(); +$input = $app->input; + +$this->useCoreUI = true; + +HTMLHelper::_('script', 'com_fields/admin-field-edit.js', ['relative' => true, 'version' => 'auto']); +?> + +
+ + + + 'general')); ?> + +
+
+ form->renderField('type'); ?> + form->renderField('name'); ?> + form->renderField('label'); ?> + form->renderField('description'); ?> + form->renderField('required'); ?> + form->renderField('default_value'); ?> + + form->getFieldsets('fieldparams') as $name => $fieldSet) : ?> + form->getFieldset($name) as $field) : ?> + renderField(); ?> + + + +
+
+
+
+ set('fields', + array( + array( + 'published', + 'state', + 'enabled', + ), + 'group_id', + 'assigned_cat_ids', + 'access', + 'language', + 'note', + ) + ); ?> + + set('fields', null); ?> +
+
+
+
+ + set('ignore_fieldsets', array('fieldparams')); ?> + + +
+
+ +
+
+
+
+ + canDo->get('core.admin')) : ?> + + form->getInput('rules'); ?> + + + + form->getInput('context'); ?> + + +
diff --git a/administrator/components/com_fields/tmpl/field/modal.php b/administrator/components/com_fields/tmpl/field/modal.php new file mode 100644 index 0000000000000..9912088618f52 --- /dev/null +++ b/administrator/components/com_fields/tmpl/field/modal.php @@ -0,0 +1,98 @@ +input; + +$this->useCoreUI = true; + +Factory::getDocument()->addScriptDeclaration(" + Joomla.submitbutton = function(task) + { + if (task == 'field.cancel' || document.formvalidator.isValid(document.getElementById('item-form'))) + { + if (window.opener && (task == 'field.save' || task == 'field.cancel')) + { + window.opener.document.closeEditWindow = self; + window.opener.setTimeout('window.document.closeEditWindow.close()', 1000); + } + + Joomla.submitform(task, document.getElementById('item-form')); + } + }; +"); +?> +
+ +
+ + + +
+ +
+ +
+ + +
+ 'general')); ?> + + +
+
+ form->getLabel('description'); ?> + form->getInput('description'); ?> +
+
+ +
+
+ + + +
+
+ +
+
+
+
+ + + canDo->get('core.admin')) : ?> + + form->getInput('rules'); ?> + + + + + + + + form->getInput('context'); ?> + + +
+
+
diff --git a/administrator/components/com_fields/tmpl/field/modal_options.php b/administrator/components/com_fields/tmpl/field/modal_options.php new file mode 100644 index 0000000000000..3761ae09f6e43 --- /dev/null +++ b/administrator/components/com_fields/tmpl/field/modal_options.php @@ -0,0 +1,48 @@ + 'collapse0')); + +$fieldSets = $this->form->getFieldsets('params'); +$i = 0; +?> + $fieldSet) : ?> + label) ? $fieldSet->label : 'COM_FIELDS_' . $name . '_FIELDSET_LABEL'; ?> + + description) && trim($fieldSet->description)) : ?> + ' . $this->escape(Text::_($fieldSet->description)) . '

'; ?> + + form->getFieldset($name) as $field) : ?> +
+
+ label; ?> +
+
+ input; ?> +
+
+ + + +
+
+ form->getLabel('note'); ?> +
+
+ form->getInput('note'); ?> +
+
+ + + + diff --git a/administrator/components/com_fields/tmpl/fields/default.php b/administrator/components/com_fields/tmpl/fields/default.php new file mode 100644 index 0000000000000..f1ca5fda70ce9 --- /dev/null +++ b/administrator/components/com_fields/tmpl/fields/default.php @@ -0,0 +1,201 @@ +get('id'); +$context = $this->escape($this->state->get('filter.context')); +$component = $this->state->get('filter.component'); +$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 = Categories::getInstance(str_replace('com_', '', $component)); + +if ($saveOrder && !empty($this->items)) +{ + $saveOrderingUrl = 'index.php?option=com_fields&task=fields.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} +?> + +
+
+ sidebar)) { ?> +
+ sidebar; ?> +
+ +
+
+ $this, 'options' => array('selectorFieldName' => 'context'))); ?> + items)) : ?> + + + + + + + + + + + + + + + + + + + class="js-draggable" data-url="" data-direction="" data-nested="true"> + items as $i => $item) : ?> + + authorise('core.edit', $component . '.field.' . $item->id); ?> + authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; ?> + authorise('core.edit.own', $component . '.field.' . $item->id) && $item->created_user_id == $userId; ?> + authorise('core.edit.state', $component . '.field.' . $item->id) && $canCheckin; ?> + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + id); ?> + +
+ state, $i, 'fields.', $canChange, 'cb'); ?> +
+
+
+ checked_out) : ?> + editor, $item->checked_out_time, 'fields.', $canCheckin); ?> + + + checked_out ? '' : ''; ?> + + escape($item->title); ?> + + escape($item->title); ?> + + + note)) : ?> + escape($item->name)); ?> + + escape($item->name), $this->escape($item->note)); ?> + + + +
+ + id); ?> + + + + + +
+ +
+
+ escape($item->type); ?> + + escape($item->group_title); ?> + + escape($item->access_level); ?> + + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + authorise('core.create', $component) + && $user->authorise('core.edit', $component) + && $user->authorise('core.edit.state', $component)) : ?> + Text::_('COM_FIELDS_VIEW_FIELDS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer') + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_fields/tmpl/fields/default_batch_body.php b/administrator/components/com_fields/tmpl/fields/default_batch_body.php new file mode 100644 index 0000000000000..2eeef1da845ea --- /dev/null +++ b/administrator/components/com_fields/tmpl/fields/default_batch_body.php @@ -0,0 +1,58 @@ + true, 'version' => 'auto']); + +$context = $this->escape($this->state->get('filter.context')); +?> + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + +
+ +
+
+ + +
+
+
+
+
diff --git a/administrator/components/com_fields/tmpl/fields/default_batch_footer.php b/administrator/components/com_fields/tmpl/fields/default_batch_footer.php new file mode 100644 index 0000000000000..c758c6437e0f6 --- /dev/null +++ b/administrator/components/com_fields/tmpl/fields/default_batch_footer.php @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_fields/tmpl/fields/modal.php b/administrator/components/com_fields/tmpl/fields/modal.php new file mode 100644 index 0000000000000..a9b69143c491d --- /dev/null +++ b/administrator/components/com_fields/tmpl/fields/modal.php @@ -0,0 +1,113 @@ +isClient('site')) +{ + Session::checkToken('get') or die(Text::_('JINVALID_TOKEN')); +} + +HTMLHelper::_('behavior.core'); +HTMLHelper::_('formbehavior.chosen', '.advancedSelect'); +HTMLHelper::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); +HTMLHelper::_('script', 'com_fields/admin-fields-modal.js', array('version' => 'auto', 'relative' => true)); + +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$editor = Factory::getApplication()->input->get('editor', '', 'cmd'); +?> +
+ +
+ + $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + 'icon-trash', + 0 => 'icon-unpublish', + 1 => 'icon-publish', + 2 => 'icon-archive', + ); + foreach ($this->items as $i => $item) : + ?> + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + escape($item->title); ?> + + group_id ? $this->escape($item->group_title) : Text::_('JNONE'); ?> + + type; ?> + + escape($item->access_level); ?> + + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + + + +
+
diff --git a/administrator/components/com_fields/tmpl/group/edit.php b/administrator/components/com_fields/tmpl/group/edit.php new file mode 100644 index 0000000000000..f52f7384cce61 --- /dev/null +++ b/administrator/components/com_fields/tmpl/group/edit.php @@ -0,0 +1,78 @@ +input; +?> + +
+ +
+ 'general')); ?> + +
+
+ form->renderField('label'); ?> + form->renderField('description'); ?> +
+
+ set('fields', + array( + array( + 'published', + 'state', + 'enabled', + ), + 'access', + 'language', + 'note', + ) + ); ?> + + set('fields', null); ?> +
+
+ + +
+
+ +
+
+
+
+ + set('ignore_fieldsets', array('fieldparams')); ?> + + canDo->get('core.admin')) : ?> + + form->getInput('rules'); ?> + + + + form->getInput('context'); ?> + + +
+
diff --git a/administrator/components/com_fields/tmpl/groups/default.php b/administrator/components/com_fields/tmpl/groups/default.php new file mode 100644 index 0000000000000..720ee0db00149 --- /dev/null +++ b/administrator/components/com_fields/tmpl/groups/default.php @@ -0,0 +1,180 @@ +get('id'); + +$component = ''; +$parts = FieldsHelper::extract($this->state->get('filter.context')); + +if ($parts) +{ + $component = $this->escape($parts[0]); +} + +$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'); + +if ($saveOrder && !empty($this->items)) +{ + $saveOrderingUrl = 'index.php?option=com_fields&task=groups.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} +?> + +
+
+ sidebar)) { ?> +
+ sidebar; ?> +
+ +
+
+ $this, 'options' => array('selectorFieldName' => 'context'))); ?> + items)) : ?> + + + + + + + + + + + + + + + + + class="js-draggable" data-url="" data-direction="" data-nested="true"> + items as $i => $item) : ?> + + authorise('core.edit', $component . '.fieldgroup.' . $item->id); ?> + authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; ?> + authorise('core.edit.own', $component . '.fieldgroup.' . $item->id) && $item->created_by == $userId; ?> + authorise('core.edit.state', $component . '.fieldgroup.' . $item->id) && $canCheckin; ?> + + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + id); ?> + +
+ state, $i, 'groups.', $canChange, 'cb'); ?> +
+
+
+ checked_out) : ?> + editor, $item->checked_out_time, 'groups.', $canCheckin); ?> + + + checked_out ? '' : ''; ?> + + escape($item->title); ?> + + escape($item->title); ?> + + + note) : ?> + escape($item->note)); ?> + + +
+
+ escape($item->access_level); ?> + + + + id; ?> +
+ + + pagination->getListFooter(); ?> + + + authorise('core.create', $component) + && $user->authorise('core.edit', $component) + && $user->authorise('core.edit.state', $component)) : ?> + Text::_('COM_FIELDS_VIEW_GROUPS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer') + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_fields/tmpl/groups/default_batch_body.php b/administrator/components/com_fields/tmpl/groups/default_batch_body.php new file mode 100644 index 0000000000000..c9149bdb5542b --- /dev/null +++ b/administrator/components/com_fields/tmpl/groups/default_batch_body.php @@ -0,0 +1,30 @@ + + +
+
+
+
+ +
+
+
+
+ +
+
+
+
diff --git a/administrator/components/com_fields/tmpl/groups/default_batch_footer.php b/administrator/components/com_fields/tmpl/groups/default_batch_footer.php new file mode 100644 index 0000000000000..90e776c34cad5 --- /dev/null +++ b/administrator/components/com_fields/tmpl/groups/default_batch_footer.php @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_fields/views/field/tmpl/edit.php b/administrator/components/com_fields/views/field/tmpl/edit.php deleted file mode 100644 index 991273c74cbdf..0000000000000 --- a/administrator/components/com_fields/views/field/tmpl/edit.php +++ /dev/null @@ -1,107 +0,0 @@ - 0 )); -JHtml::_('formbehavior.chosen', 'select'); - -$app = JFactory::getApplication(); -$input = $app->input; - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(task) - { - if (task == "field.cancel" || document.formvalidator.isValid(document.getElementById("item-form"))) - { - Joomla.submitform(task, document.getElementById("item-form")); - } - }; - jQuery(document).ready(function() { - jQuery("#jform_title").data("dp-old-value", jQuery("#jform_title").val()); - jQuery("#jform_title").change(function(data, handler) { - if(jQuery("#jform_title").data("dp-old-value") == jQuery("#jform_label").val()) { - jQuery("#jform_label").val(jQuery("#jform_title").val()); - } - - jQuery("#jform_title").data("dp-old-value", jQuery("#jform_title").val()); - }); - }); -'); - -?> - -
- -
- 'general')); ?> - -
-
- form->renderField('type'); ?> - form->renderField('name'); ?> - form->renderField('label'); ?> - form->renderField('description'); ?> - form->renderField('required'); ?> - form->renderField('default_value'); ?> - - form->getFieldsets('fieldparams') as $name => $fieldSet) : ?> - form->getFieldset($name) as $field) : ?> - renderField(); ?> - - - -
-
- set('fields', - array( - array( - 'published', - 'state', - 'enabled', - ), - 'group_id', - 'assigned_cat_ids', - 'access', - 'language', - 'note', - ) - ); ?> - - set('fields', null); ?> -
-
- - set('ignore_fieldsets', array('fieldparams')); ?> - - -
-
- -
-
-
-
- - canDo->get('core.admin')) : ?> - - form->getInput('rules'); ?> - - - - form->getInput('context'); ?> - - -
-
diff --git a/administrator/components/com_fields/views/field/view.html.php b/administrator/components/com_fields/views/field/view.html.php deleted file mode 100644 index 2c665643a2285..0000000000000 --- a/administrator/components/com_fields/views/field/view.html.php +++ /dev/null @@ -1,144 +0,0 @@ -form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - - $this->canDo = JHelperContent::getActions($this->state->get('field.component'), 'field', $this->item->id); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - JFactory::getApplication()->input->set('hidemainmenu', true); - - $this->addToolbar(); - - return parent::display($tpl); - } - - /** - * Adds the toolbar. - * - * @return void - * - * @since 3.7.0 - */ - protected function addToolbar() - { - $component = $this->state->get('field.component'); - $section = $this->state->get('field.section'); - $userId = JFactory::getUser()->get('id'); - $canDo = $this->canDo; - - $isNew = ($this->item->id == 0); - $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); - - // Avoid nonsense situation. - if ($component == 'com_fields') - { - return; - } - - // Load component language file - $lang = JFactory::getLanguage(); - $lang->load($component, JPATH_ADMINISTRATOR) - || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component)); - - $title = JText::sprintf('COM_FIELDS_VIEW_FIELD_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE', JText::_(strtoupper($component))); - - // Prepare the toolbar. - JToolbarHelper::title( - $title, - 'puzzle field-' . ($isNew ? 'add' : 'edit') . ' ' . substr($component, 4) . ($section ? "-$section" : '') . '-field-' . - ($isNew ? 'add' : 'edit') - ); - - // For new records, check the create permission. - if ($isNew) - { - JToolbarHelper::apply('field.apply'); - JToolbarHelper::save('field.save'); - JToolbarHelper::save2new('field.save2new'); - } - - // If not checked out, can save the item. - elseif (!$checkedOut && ($canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_user_id == $userId))) - { - JToolbarHelper::apply('field.apply'); - JToolbarHelper::save('field.save'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::save2new('field.save2new'); - } - } - - // If an existing item, can save to a copy. - if (!$isNew && $canDo->get('core.create')) - { - JToolbarHelper::save2copy('field.save2copy'); - } - - if (empty($this->item->id)) - { - JToolbarHelper::cancel('field.cancel'); - } - else - { - JToolbarHelper::cancel('field.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELDS_EDIT'); - } -} diff --git a/administrator/components/com_fields/views/fields/tmpl/default.php b/administrator/components/com_fields/views/fields/tmpl/default.php deleted file mode 100644 index 34fda9402c41c..0000000000000 --- a/administrator/components/com_fields/views/fields/tmpl/default.php +++ /dev/null @@ -1,198 +0,0 @@ -get('id'); -$context = $this->escape($this->state->get('filter.context')); -$component = $this->state->get('filter.component'); -$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)); - -if ($saveOrder) -{ - $saveOrderingUrl = 'index.php?option=com_fields&task=fields.saveOrderAjax&tmpl=component'; - JHtml::_('sortablelist.sortable', 'fieldList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); -} -?> - -
-
- sidebar; ?> -
-
-
-
- filterForm->getField('context')->input; ?> -
  -
- $this)); ?> - items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - - - items as $i => $item) : ?> - - authorise('core.edit', $component . '.field.' . $item->id); ?> - authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; ?> - authorise('core.edit.own', $component . '.field.' . $item->id) && $item->created_user_id == $userId; ?> - authorise('core.edit.state', $component . '.field.' . $item->id) && $canCheckin; ?> - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - - - - - - - - - - - - id); ?> - -
- state, $i, 'fields.', $canChange, 'cb'); ?> - - - state === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'fields'); ?> - state === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'fields'); ?> - escape($item->title)); ?> - -
-
-
- checked_out) : ?> - editor, $item->checked_out_time, 'fields.', $canCheckin); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - - note)) : ?> - escape($item->name)); ?> - - escape($item->name), $this->escape($item->note)); ?> - - -
- - - id); ?> - - - - - - -
-
-
- escape($item->type); ?> - - escape($item->group_title); ?> - - escape($item->access_level); ?> - - - - id; ?> -
- - authorise('core.create', $component) - && $user->authorise('core.edit', $component) - && $user->authorise('core.edit.state', $component)) : ?> - JText::_('COM_FIELDS_VIEW_FIELDS_BATCH_OPTIONS'), - 'footer' => $this->loadTemplate('batch_footer') - ), - $this->loadTemplate('batch_body') - ); ?> - - - - - -
-
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 deleted file mode 100644 index fabf1e1e61562..0000000000000 --- a/administrator/components/com_fields/views/fields/tmpl/default_batch_body.php +++ /dev/null @@ -1,69 +0,0 @@ -addScriptDeclaration( - ' - jQuery(document).ready(function($){ - if ($("#batch-group-id").length){var batchSelector = $("#batch-group-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(); - } - }); - } - }); - ' -); - -$context = $this->escape($this->state->get('filter.context')); -?> - -
-
-
-
- -
-
-
-
- -
-
-
-
-
-
- - -
- -
-
- - -
-
-
-
-
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 deleted file mode 100644 index 10ca5b037e684..0000000000000 --- a/administrator/components/com_fields/views/fields/tmpl/default_batch_footer.php +++ /dev/null @@ -1,17 +0,0 @@ - - - \ 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 deleted file mode 100644 index 2c5cb5890f0a3..0000000000000 --- a/administrator/components/com_fields/views/fields/tmpl/modal.php +++ /dev/null @@ -1,117 +0,0 @@ -isClient('site')) -{ - JSession::checkToken('get') or die(JText::_('JINVALID_TOKEN')); -} - -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)); - -// Special case for the search field tooltip. -$searchFilterDesc = $this->filterForm->getFieldAttribute('search', 'description', null, 'filter'); -JHtml::_('bootstrap.tooltip', '#filter_search', array('title' => JText::_($searchFilterDesc), 'placement' => 'bottom')); - -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$editor = JFactory::getApplication()->input->get('editor', '', 'cmd'); -?> -
- -
- - $this)); ?> - items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - 'icon-trash', - 0 => 'icon-unpublish', - 1 => 'icon-publish', - 2 => 'icon-archive', - ); - foreach ($this->items as $i => $item) : - ?> - - - - - - - - - - - -
- - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - escape($item->title); ?> - - group_id ? $this->escape($item->group_title) : JText::_('JNONE'); ?> - - type; ?> - - escape($item->access_level); ?> - - - - id; ?> -
- - - - - - -
-
diff --git a/administrator/components/com_fields/views/fields/view.html.php b/administrator/components/com_fields/views/fields/view.html.php deleted file mode 100644 index d2e72347a7722..0000000000000 --- a/administrator/components/com_fields/views/fields/view.html.php +++ /dev/null @@ -1,211 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $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); - } - - // Display a warning if the fields system plugin is disabled - if (!JPluginHelper::isEnabled('system', 'fields')) - { - $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . FieldsHelper::getFieldsPluginId()); - JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED', $link), 'warning'); - } - - // Only add toolbar when not in modal window. - if ($this->getLayout() !== 'modal') - { - $this->addToolbar(); - } - - FieldsHelper::addSubmenu($this->state->get('filter.context'), 'fields'); - $this->sidebar = JHtmlSidebar::render(); - - return parent::display($tpl); - } - - /** - * Adds the toolbar. - * - * @return void - * - * @since 3.7.0 - */ - protected function addToolbar() - { - $fieldId = $this->state->get('filter.field_id'); - $component = $this->state->get('filter.component'); - $section = $this->state->get('filter.section'); - $canDo = JHelperContent::getActions($component, 'field', $fieldId); - - // Get the toolbar object instance - $bar = JToolBar::getInstance('toolbar'); - - // Avoid nonsense situation. - if ($component == 'com_fields') - { - return; - } - - // Load extension language file - $lang = JFactory::getLanguage(); - $lang->load($component, JPATH_ADMINISTRATOR) - || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component)); - - $title = JText::sprintf('COM_FIELDS_VIEW_FIELDS_TITLE', JText::_(strtoupper($component))); - - // Prepare the toolbar. - JToolbarHelper::title($title, 'puzzle fields ' . substr($component, 4) . ($section ? "-$section" : '') . '-fields'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('field.add'); - } - - if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) - { - JToolbarHelper::editList('field.edit'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publish('fields.publish', 'JTOOLBAR_PUBLISH', true); - JToolbarHelper::unpublish('fields.unpublish', 'JTOOLBAR_UNPUBLISH', true); - JToolbarHelper::archiveList('fields.archive'); - } - - if (JFactory::getUser()->authorise('core.admin')) - { - JToolbarHelper::checkin('fields.checkin'); - } - - // Add a batch button - if ($canDo->get('core.create') && $canDo->get('core.edit') && $canDo->get('core.edit.state')) - { - $title = JText::_('JTOOLBAR_BATCH'); - - // Instantiate a new JLayoutFile instance and render the batch button - $layout = new JLayoutFile('joomla.toolbar.batch'); - - $dhtml = $layout->render( - array( - 'title' => $title, - ) - ); - - $bar->appendButton('Custom', $dhtml, 'batch'); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences($component); - } - - if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete', $component)) - { - JToolbarHelper::deleteList('', 'fields.delete', 'JTOOLBAR_EMPTY_TRASH'); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('fields.trash'); - } - - JToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELDS'); - } - - /** - * Returns the sort fields. - * - * @return array - * - * @since 3.7.0 - */ - protected function getSortFields() - { - return array( - 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), - 'a.state' => JText::_('JSTATUS'), - '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.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 deleted file mode 100644 index e00f223e871c5..0000000000000 --- a/administrator/components/com_fields/views/group/tmpl/edit.php +++ /dev/null @@ -1,82 +0,0 @@ -input; - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(task) - { - if (task == "group.cancel" || document.formvalidator.isValid(document.getElementById("item-form"))) - { - Joomla.submitform(task, document.getElementById("item-form")); - } - }; -'); -?> - -
- -
- 'general')); ?> - -
-
- form->renderField('label'); ?> - form->renderField('description'); ?> -
-
- set('fields', - array( - array( - 'published', - 'state', - 'enabled', - ), - 'access', - 'language', - 'note', - ) - ); ?> - - set('fields', null); ?> -
-
- - -
-
- -
-
-
-
- - set('ignore_fieldsets', array('fieldparams')); ?> - - canDo->get('core.admin')) : ?> - - form->getInput('rules'); ?> - - - - form->getInput('context'); ?> - - -
-
diff --git a/administrator/components/com_fields/views/group/view.html.php b/administrator/components/com_fields/views/group/view.html.php deleted file mode 100644 index c017989773556..0000000000000 --- a/administrator/components/com_fields/views/group/view.html.php +++ /dev/null @@ -1,168 +0,0 @@ -form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - - $component = ''; - $parts = FieldsHelper::extract($this->state->get('filter.context')); - - if ($parts) - { - $component = $parts[0]; - } - - $this->canDo = JHelperContent::getActions($component, 'fieldgroup', $this->item->id); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - JFactory::getApplication()->input->set('hidemainmenu', true); - - $this->addToolbar(); - - return parent::display($tpl); - } - - /** - * Adds the toolbar. - * - * @return void - * - * @since 3.7.0 - */ - protected function addToolbar() - { - $component = ''; - $parts = FieldsHelper::extract($this->state->get('filter.context')); - - if ($parts) - { - $component = $parts[0]; - } - - $userId = JFactory::getUser()->get('id'); - $canDo = $this->canDo; - - $isNew = ($this->item->id == 0); - $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); - - // Avoid nonsense situation. - if ($component == 'com_fields') - { - return; - } - - // Load component language file - $lang = JFactory::getLanguage(); - $lang->load($component, JPATH_ADMINISTRATOR) - || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component)); - - $title = JText::sprintf('COM_FIELDS_VIEW_GROUP_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE', JText::_(strtoupper($component))); - - // Prepare the toolbar. - JToolbarHelper::title( - $title, - 'puzzle field-' . ($isNew ? 'add' : 'edit') . ' ' . substr($component, 4) . '-group-' . - ($isNew ? 'add' : 'edit') - ); - - // For new records, check the create permission. - if ($isNew) - { - JToolbarHelper::apply('group.apply'); - JToolbarHelper::save('group.save'); - JToolbarHelper::save2new('group.save2new'); - } - - // If not checked out, can save the item. - elseif (!$checkedOut && ($canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId))) - { - JToolbarHelper::apply('group.apply'); - JToolbarHelper::save('group.save'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::save2new('group.save2new'); - } - } - - // If an existing item, can save to a copy. - if (!$isNew && $canDo->get('core.create')) - { - JToolbarHelper::save2copy('group.save2copy'); - } - - if (empty($this->item->id)) - { - JToolbarHelper::cancel('group.cancel'); - } - else - { - JToolbarHelper::cancel('group.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELD_GROUPS_EDIT'); - } -} diff --git a/administrator/components/com_fields/views/groups/tmpl/default.php b/administrator/components/com_fields/views/groups/tmpl/default.php deleted file mode 100644 index 65da48e8832c9..0000000000000 --- a/administrator/components/com_fields/views/groups/tmpl/default.php +++ /dev/null @@ -1,177 +0,0 @@ -get('id'); - -$component = ''; -$parts = FieldsHelper::extract($this->state->get('filter.context')); - -if ($parts) -{ - $component = $this->escape($parts[0]); -} - -$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'); - -if ($saveOrder) -{ - $saveOrderingUrl = 'index.php?option=com_fields&task=groups.saveOrderAjax&tmpl=component'; - JHtml::_('sortablelist.sortable', 'groupList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); -} -?> - -
-
- sidebar; ?> -
-
-
-
- filterForm->getField('context')->input; ?> -
  -
- $this)); ?> - items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - items as $i => $item) : ?> - - authorise('core.edit', $component . '.fieldgroup.' . $item->id); ?> - authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; ?> - authorise('core.edit.own', $component . '.fieldgroup.' . $item->id) && $item->created_by == $userId; ?> - authorise('core.edit.state', $component . '.fieldgroup.' . $item->id) && $canCheckin; ?> - - - - - - - - - - - -
- - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - - - - - - - - - - - - id); ?> - -
- state, $i, 'groups.', $canChange, 'cb'); ?> - - - state === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'groups'); ?> - state === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'groups'); ?> - escape($item->title)); ?> - -
-
-
- checked_out) : ?> - editor, $item->checked_out_time, 'groups.', $canCheckin); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - - note) : ?> - escape($item->note)); ?> - - -
-
- escape($item->access_level); ?> - - - - id; ?> -
- - authorise('core.create', $component) - && $user->authorise('core.edit', $component) - && $user->authorise('core.edit.state', $component)) : ?> - JText::_('COM_FIELDS_VIEW_GROUPS_BATCH_OPTIONS'), - 'footer' => $this->loadTemplate('batch_footer') - ), - $this->loadTemplate('batch_body') - ); ?> - - - - - -
-
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 deleted file mode 100644 index e9e7a76e9c286..0000000000000 --- a/administrator/components/com_fields/views/groups/tmpl/default_batch_body.php +++ /dev/null @@ -1,27 +0,0 @@ - - -
-
-
-
- -
-
-
-
- -
-
-
-
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 deleted file mode 100644 index 4fcb5c8f3596b..0000000000000 --- a/administrator/components/com_fields/views/groups/tmpl/default_batch_footer.php +++ /dev/null @@ -1,17 +0,0 @@ - - - \ 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 deleted file mode 100644 index f08cc0d666dbd..0000000000000 --- a/administrator/components/com_fields/views/groups/view.html.php +++ /dev/null @@ -1,213 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $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); - } - - // Display a warning if the fields system plugin is disabled - if (!JPluginHelper::isEnabled('system', 'fields')) - { - $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . FieldsHelper::getFieldsPluginId()); - JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED', $link), 'warning'); - } - - $this->addToolbar(); - - FieldsHelper::addSubmenu($this->state->get('filter.context'), 'groups'); - $this->sidebar = JHtmlSidebar::render(); - - return parent::display($tpl); - } - - /** - * Adds the toolbar. - * - * @return void - * - * @since 3.7.0 - */ - protected function addToolbar() - { - $groupId = $this->state->get('filter.group_id'); - $component = ''; - $parts = FieldsHelper::extract($this->state->get('filter.context')); - - if ($parts) - { - $component = $parts[0]; - } - - $canDo = JHelperContent::getActions($component, 'fieldgroup', $groupId); - - // Get the toolbar object instance - $bar = JToolbar::getInstance('toolbar'); - - // Avoid nonsense situation. - if ($component == 'com_fields') - { - return; - } - - // Load component language file - $lang = JFactory::getLanguage(); - $lang->load($component, JPATH_ADMINISTRATOR) - || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component)); - - $title = JText::sprintf('COM_FIELDS_VIEW_GROUPS_TITLE', JText::_(strtoupper($component))); - - // Prepare the toolbar. - JToolbarHelper::title($title, 'puzzle fields ' . substr($component, 4) . '-groups'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('group.add'); - } - - if ($canDo->get('core.edit') || $canDo->get('core.edit.own')) - { - JToolbarHelper::editList('group.edit'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publish('groups.publish', 'JTOOLBAR_PUBLISH', true); - JToolbarHelper::unpublish('groups.unpublish', 'JTOOLBAR_UNPUBLISH', true); - JToolbarHelper::archiveList('groups.archive'); - } - - if (JFactory::getUser()->authorise('core.admin')) - { - JToolbarHelper::checkin('groups.checkin'); - } - - // Add a batch button - if ($canDo->get('core.create') && $canDo->get('core.edit') && $canDo->get('core.edit.state')) - { - $title = JText::_('JTOOLBAR_BATCH'); - - // Instantiate a new JLayoutFile instance and render the batch button - $layout = new JLayoutFile('joomla.toolbar.batch'); - - $dhtml = $layout->render( - array( - 'title' => $title, - ) - ); - - $bar->appendButton('Custom', $dhtml, 'batch'); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences($component); - } - - if ($this->state->get('filter.state') == -2 && $canDo->get('core.delete', $component)) - { - JToolbarHelper::deleteList('', 'groups.delete', 'JTOOLBAR_EMPTY_TRASH'); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('groups.trash'); - } - - JToolbarHelper::help('JHELP_COMPONENTS_FIELDS_FIELD_GROUPS'); - } - - /** - * Returns the sort fields. - * - * @return array - * - * @since 3.7.0 - */ - protected function getSortFields() - { - return array( - 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), - 'a.state' => JText::_('JSTATUS'), - 'a.title' => JText::_('JGLOBAL_TITLE'), - 'a.access' => JText::_('JGRID_HEADING_ACCESS'), - 'language' => JText::_('JGRID_HEADING_LANGUAGE'), - 'a.context' => JText::_('JGRID_HEADING_CONTEXT'), - 'a.id' => JText::_('JGRID_HEADING_ID'), - ); - } -} diff --git a/administrator/components/com_finder/Controller/DisplayController.php b/administrator/components/com_finder/Controller/DisplayController.php new file mode 100644 index 0000000000000..f530a39bdf3ea --- /dev/null +++ b/administrator/components/com_finder/Controller/DisplayController.php @@ -0,0 +1,59 @@ +input->get('view', 'index', 'word'); + $layout = $this->input->get('layout', 'index', 'word'); + $filterId = $this->input->get('filter_id', null, 'int'); + + // Check for edit form. + 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->setMessage(\JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $f_id), 'error'); + $this->setRedirect(\JRoute::_('index.php?option=com_finder&view=filters', false)); + + return false; + } + + return parent::display(); + } +} diff --git a/administrator/components/com_finder/Controller/FilterController.php b/administrator/components/com_finder/Controller/FilterController.php new file mode 100644 index 0000000000000..4f28b02ee3a49 --- /dev/null +++ b/administrator/components/com_finder/Controller/FilterController.php @@ -0,0 +1,240 @@ +input; + + /* @var \Joomla\Component\Finder\Administrator\Model\FilterModel $model */ + $model = $this->getModel(); + $table = $model->getTable(); + $data = $input->post->get('jform', array(), 'array'); + $checkin = $table->hasField('checked_out'); + $context = "$this->option.edit.$this->context"; + $task = $this->getTask(); + + // 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 = $input->get($urlVar, '', 'int'); + + if (!$this->checkEditId($context, $recordId)) + { + // Somehow the person just went to the form and tried to save it. We don't allow that. + $this->setMessage(\JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $recordId), 'error'); + $this->setRedirect(\JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + + return false; + } + + // Populate the row id from the session. + $data[$key] = $recordId; + + // The save2copy task needs to be handled slightly differently. + if ($task === 'save2copy') + { + // Check-in the original row. + if ($checkin && $model->checkin($data[$key]) === false) + { + // Check-in failed. Go back to the item and display a notice. + $this->setMessage(\JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'error'); + $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar)); + + return false; + } + + // Reset the ID and then treat the request as for Apply. + $data[$key] = 0; + $task = 'apply'; + } + + // Access check. + if (!$this->allowSave($data, $key)) + { + $this->setMessage(\JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + $this->setRedirect(\JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + + return false; + } + + // Validate the posted data. + // Sometimes the form needs some posted data, such as for plugins and modules. + $form = $model->getForm($data, false); + + if (!$form) + { + $app->enqueueMessage($model->getError(), 'error'); + + return false; + } + + // Test whether the data is valid. + $validData = $model->validate($form, $data); + + // Check for validation errors. + if ($validData === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // 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) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState($context . '.data', $data); + + // Redirect back to the edit screen. + $this->setRedirect( + \JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false) + ); + + return false; + } + + // Get and sanitize the filter data. + $validData['data'] = $input->post->get('t', array(), 'array'); + $validData['data'] = array_unique($validData['data']); + $validData['data'] = ArrayHelper::toInteger($validData['data']); + + // Remove any values of zero. + if (array_search(0, $validData['data'], true)) + { + unset($validData['data'][array_search(0, $validData['data'], true)]); + } + + // Attempt to save the data. + if (!$model->save($validData)) + { + // Save the data in the session. + $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=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false) + ); + + return false; + } + + // Save succeeded, so check-in the record. + if ($checkin && $model->checkin($validData[$key]) === false) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + // Check-in failed, so go back to the record and display a notice. + $this->setMessage(\JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'error'); + $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key)); + + return false; + } + + $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' + ) + ); + + // Redirect the user and adjust session state based on the chosen task. + switch ($task) + { + case 'apply': + // Set the record data in the session. + $recordId = $model->getState($this->context . '.id'); + $this->holdEditId($context, $recordId); + $app->setUserState($context . '.data', null); + $model->checkout($recordId); + + // Redirect back to the edit screen. + $this->setRedirect( + \JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false) + ); + + break; + + case 'save2new': + // Clear the record id and data from the session. + $this->releaseEditId($context, $recordId); + $app->setUserState($context . '.data', null); + + // Redirect back to the edit screen. + $this->setRedirect( + \JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(null, $key), false) + ); + + break; + + default: + // Clear the record id and data from the session. + $this->releaseEditId($context, $recordId); + $app->setUserState($context . '.data', null); + + // Redirect to the list screen. + $this->setRedirect( + \JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false) + ); + + break; + } + + // Invoke the postSave method to allow for the child class to access the model. + $this->postSaveHook($model, $validData); + + return true; + } +} diff --git a/administrator/components/com_finder/Controller/FiltersController.php b/administrator/components/com_finder/Controller/FiltersController.php new file mode 100644 index 0000000000000..80447b3a26376 --- /dev/null +++ b/administrator/components/com_finder/Controller/FiltersController.php @@ -0,0 +1,38 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_finder/Controller/IndexController.php b/administrator/components/com_finder/Controller/IndexController.php new file mode 100644 index 0000000000000..13c830676b19c --- /dev/null +++ b/administrator/components/com_finder/Controller/IndexController.php @@ -0,0 +1,74 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to purge all indexed links from the database. + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function purge() + { + \JSession::checkToken() or jexit(\JText::_('JINVALID_TOKEN')); + + // Remove the script time limit. + @set_time_limit(0); + + /* @var \Joomla\Component\Finder\Administrator\Model\IndexModel $model */ + $model = $this->getModel('Index', 'Administrator'); + + // Attempt to purge the index. + $return = $model->purge(); + + if (!$return) + { + $message = \JText::_('COM_FINDER_INDEX_PURGE_FAILED', $model->getError()); + $this->setRedirect('index.php?option=com_finder&view=index', $message); + + return false; + } + else + { + $message = \JText::_('COM_FINDER_INDEX_PURGE_SUCCESS'); + $this->setRedirect('index.php?option=com_finder&view=index', $message); + + return true; + } + } +} diff --git a/administrator/components/com_finder/Controller/IndexerController.php b/administrator/components/com_finder/Controller/IndexerController.php new file mode 100644 index 0000000000000..d63b731bfffaf --- /dev/null +++ b/administrator/components/com_finder/Controller/IndexerController.php @@ -0,0 +1,406 @@ +get('enable_logging', '0')) + { + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'indexer.php'; + Log::addLogger($options); + } + + // Log the start + try + { + Log::add('Starting the indexer', Log::INFO); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + // We don't want this form to be cached. + $this->app->allowCache(false); + + // Check for a valid token. If invalid, send a 403 with the error message. + Session::checkToken('request') or static::sendResponse(new \Exception(\JText::_('JINVALID_TOKEN'), 403)); + + // Put in a buffer to silence noise. + ob_start(); + + // Reset the indexer state. + \FinderIndexer::resetState(); + + // Import the finder plugins. + PluginHelper::importPlugin('finder'); + + // Add the indexer language to \JS + \JText::script('COM_FINDER_AN_ERROR_HAS_OCCURRED'); + \JText::script('COM_FINDER_NO_ERROR_RETURNED'); + + // Start the indexer. + try + { + // Trigger the onStartIndex event. + $this->app->triggerEvent('onStartIndex'); + + // Get the indexer state. + $state = \FinderIndexer::getState(); + $state->start = 1; + + // Send the response. + static::sendResponse($state); + } + + // Catch an exception and return the response. + catch (\Exception $e) + { + static::sendResponse($e); + } + } + + /** + * Method to run the next batch of content through the indexer. + * + * @return void + * + * @since 2.5 + */ + public function batch() + { + $params = ComponentHelper::getParams('com_finder'); + + if ($params->get('enable_logging', '0')) + { + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'indexer.php'; + Log::addLogger($options); + } + + // Log the start + try + { + Log::add('Starting the indexer batch process', Log::INFO); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + // We don't want this form to be cached. + $this->app->allowCache(false); + + // Check for a valid token. If invalid, send a 403 with the error message. + Session::checkToken('request') or static::sendResponse(new \Exception(\JText::_('JINVALID_TOKEN'), 403)); + + // Put in a buffer to silence noise. + ob_start(); + + // Remove the script time limit. + @set_time_limit(0); + + // Get the indexer state. + $state = \FinderIndexer::getState(); + + // Reset the batch offset. + $state->batchOffset = 0; + + // Update the indexer state. + \FinderIndexer::setState($state); + + // Import the finder plugins. + PluginHelper::importPlugin('finder'); + + /* + * We are going to swap out the raw document object with an HTML document + * in order to work around some plugins that don't do proper environment + * checks before trying to use HTML document functions. + */ + $raw = clone Factory::getDocument(); + $lang = Factory::getLanguage(); + + // Get the document properties. + $attributes = array ( + 'charset' => 'utf-8', + 'lineend' => 'unix', + 'tab' => ' ', + 'language' => $lang->getTag(), + 'direction' => $lang->isRtl() ? 'rtl' : 'ltr' + ); + + // Get the HTML document. + $html = Factory::getContainer()->get(FactoryInterface::class)->createDocument('html', $attributes); + + // TODO: Why is this document fetched and immediately overwritten? + $doc = Factory::getDocument(); + + // Swap the documents. + $doc = $html; + + // Get the admin application. + $admin = clone Factory::getApplication(); + + // Get the site app. + $site = Factory::getContainer()->get(SiteApplication::class); + + // Swap the app. + $app = Factory::getApplication(); + + // TODO: Why is the app fetched and immediately overwritten? + $app = $site; + + // Start the indexer. + try + { + // Trigger the onBeforeIndex event. + Factory::getApplication()->triggerEvent('onBeforeIndex'); + + // Trigger the onBuildIndex event. + Factory::getApplication()->triggerEvent('onBuildIndex'); + + // Get the indexer state. + $state = \FinderIndexer::getState(); + $state->start = 0; + $state->complete = 0; + + // Swap the documents back. + $doc = $raw; + + // Swap the applications back. + $app = $admin; + + // Log batch completion and memory high-water mark. + try + { + Log::add('Batch completed, peak memory usage: ' . number_format(memory_get_peak_usage(true)) . ' bytes', Log::INFO); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + // Send the response. + static::sendResponse($state); + } + + // Catch an exception and return the response. + catch (\Exception $e) + { + // Swap the documents back. + $doc = $raw; + + // Send the response. + static::sendResponse($e); + } + } + + /** + * Method to optimize the index and perform any necessary cleanup. + * + * @return void + * + * @since 2.5 + */ + public function optimize() + { + // We don't want this form to be cached. + $this->app->allowCache(false); + + // Check for a valid token. If invalid, send a 403 with the error message. + Session::checkToken('request') or static::sendResponse(new \Exception(\JText::_('JINVALID_TOKEN'), 403)); + + // Put in a buffer to silence noise. + ob_start(); + + // Import the finder plugins. + PluginHelper::importPlugin('finder'); + + try + { + // Optimize the index + \FinderIndexer::getInstance()->optimize(); + + // Get the indexer state. + $state = \FinderIndexer::getState(); + $state->start = 0; + $state->complete = 1; + + // Send the response. + static::sendResponse($state); + } + + // Catch an exception and return the response. + catch (\Exception $e) + { + static::sendResponse($e); + } + } + + /** + * Method to handle a send a \JSON response. The body parameter + * can be an \Exception object for when an error has occurred or + * a \JObject for a good response. + * + * @param mixed $data \JObject on success, \Exception on error. [optional] + * + * @return void + * + * @since 2.5 + */ + public static function sendResponse($data = null) + { + $app = Factory::getApplication(); + + $params = ComponentHelper::getParams('com_finder'); + + if ($params->get('enable_logging', '0')) + { + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'indexer.php'; + Log::addLogger($options); + } + + // Send the assigned error code if we are catching an exception. + if ($data instanceof \Exception) + { + try + { + Log::add($data->getMessage(), Log::ERROR); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + $app->setHeader('status', $data->getCode()); + } + + // Create the response object. + $response = new FinderIndexerResponse($data); + + // Add the buffer. + $response->buffer = \JDEBUG ? ob_get_contents() : ob_end_clean(); + + // Send the JSON response. + echo json_encode($response); + } +} + +/** + * Finder Indexer JSON Response Class + * + * @since 2.5 + */ +class FinderIndexerResponse +{ + /** + * Class Constructor + * + * @param mixed $state The processing state for the indexer + * + * @since 2.5 + */ + public function __construct($state) + { + $params = ComponentHelper::getParams('com_finder'); + + if ($params->get('enable_logging', '0')) + { + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'indexer.php'; + Log::addLogger($options); + } + + // The old token is invalid so send a new one. + $this->token = Factory::getSession()->getFormToken(); + + // Check if we are dealing with an error. + if ($state instanceof \Exception) + { + // Log the error + try + { + Log::add($state->getMessage(), Log::ERROR); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + // Prepare the error response. + $this->error = true; + $this->header = \JText::_('COM_FINDER_INDEXER_HEADER_ERROR'); + $this->message = $state->getMessage(); + } + else + { + // Prepare the response data. + $this->batchSize = (int) $state->batchSize; + $this->batchOffset = (int) $state->batchOffset; + $this->totalItems = (int) $state->totalItems; + + $this->startTime = $state->startTime; + $this->endTime = Factory::getDate()->toSql(); + + $this->start = !empty($state->start) ? (int) $state->start : 0; + $this->complete = !empty($state->complete) ? (int) $state->complete : 0; + + // Set the appropriate messages. + if ($this->totalItems <= 0 && $this->complete) + { + $this->header = \JText::_('COM_FINDER_INDEXER_HEADER_COMPLETE'); + $this->message = \JText::_('COM_FINDER_INDEXER_MESSAGE_COMPLETE'); + } + elseif ($this->totalItems <= 0) + { + $this->header = \JText::_('COM_FINDER_INDEXER_HEADER_OPTIMIZE'); + $this->message = \JText::_('COM_FINDER_INDEXER_MESSAGE_OPTIMIZE'); + } + else + { + $this->header = \JText::_('COM_FINDER_INDEXER_HEADER_RUNNING'); + $this->message = \JText::_('COM_FINDER_INDEXER_MESSAGE_RUNNING'); + } + } + } +} diff --git a/administrator/components/com_finder/Controller/MapsController.php b/administrator/components/com_finder/Controller/MapsController.php new file mode 100644 index 0000000000000..eb86d60f26de3 --- /dev/null +++ b/administrator/components/com_finder/Controller/MapsController.php @@ -0,0 +1,38 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_finder/Controller/SearchesController.php b/administrator/components/com_finder/Controller/SearchesController.php new file mode 100644 index 0000000000000..3e435d2690017 --- /dev/null +++ b/administrator/components/com_finder/Controller/SearchesController.php @@ -0,0 +1,42 @@ +getModel('Searches'); + + if (!$model->reset()) + { + $this->app->enqueueMessage($model->getError(), 'error'); + } + + $this->setRedirect('index.php?option=com_finder&view=searches'); + } +} diff --git a/administrator/components/com_finder/Field/BranchesField.php b/administrator/components/com_finder/Field/BranchesField.php new file mode 100644 index 0000000000000..813a7fd1c4a18 --- /dev/null +++ b/administrator/components/com_finder/Field/BranchesField.php @@ -0,0 +1,42 @@ +getQuery(true); + $levelQuery->select('title AS branch_title, 1 as level') + ->select($db->quoteName('id')) + ->from($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' = 1'); + $levelQuery2 = $db->getQuery(true); + $levelQuery2->select('b.title AS branch_title, 2 as level') + ->select($db->quoteName('a.id')) + ->from($db->quoteName('#__finder_taxonomy', 'a')) + ->join('LEFT', $db->quoteName('#__finder_taxonomy', 'b') . ' ON ' . $db->quoteName('a.parent_id') . ' = ' . $db->quoteName('b.id')) + ->where($db->quoteName('a.parent_id') . ' NOT IN (0, 1)'); + + $levelQuery->union($levelQuery2); + + // Main query. + $query = $db->getQuery(true) + ->select($db->quoteName('a.title', 'text')) + ->select($db->quoteName('a.id', 'value')) + ->select($db->quoteName('d.level')) + ->from($db->quoteName('#__finder_taxonomy', 'a')) + ->join('LEFT', '(' . $levelQuery . ') AS d ON ' . $db->quoteName('d.id') . ' = ' . $db->quoteName('a.id')) + ->where($db->quoteName('a.parent_id') . ' <> 0') + ->order('d.branch_title ASC, d.level ASC, a.title ASC'); + + $db->setQuery($query); + + try + { + $contentMap = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + return; + } + + // Build the grouped list array. + if ($contentMap) + { + $lang = Factory::getLanguage(); + + foreach ($contentMap as $branch) + { + if ((int) $branch->level === 1) + { + $name = $branch->text; + } + else + { + $levelPrefix = str_repeat('- ', max(0, $branch->level - 1)); + + if (trim($name, '**') === 'Language') + { + $text = FinderHelperLanguage::branchLanguageTitle($branch->text); + } + else + { + $key = FinderHelperLanguage::branchSingular($branch->text); + $text = $lang->hasKey($key) ? \JText::_($key) : $branch->text; + } + + // Initialize the group if necessary. + if (!isset($groups[$name])) + { + $groups[$name] = array(); + } + + $groups[$name][] = \JHtml::_('select.option', $branch->value, $levelPrefix . $text); + } + } + } + + // Merge any additional groups in the XML definition. + $groups = array_merge(parent::getGroups(), $groups); + + return $groups; + } +} diff --git a/administrator/components/com_finder/Field/ContenttypesField.php b/administrator/components/com_finder/Field/ContenttypesField.php new file mode 100644 index 0000000000000..6c9897060803a --- /dev/null +++ b/administrator/components/com_finder/Field/ContenttypesField.php @@ -0,0 +1,85 @@ +getQuery(true) + ->select($db->quoteName('id', 'value')) + ->select($db->quoteName('title', 'text')) + ->from($db->quoteName('#__finder_types')); + + // Get the options. + $db->setQuery($query); + + try + { + $contentTypes = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + \JFactory::getApplication()->enqueueMessage($db->getMessage(), 'error'); + } + + // Translate. + foreach ($contentTypes as $contentType) + { + $key = FinderHelperLanguage::branchSingular($contentType->text); + $contentType->translatedText = $lang->hasKey($key) ? \JText::_($key) : $contentType->text; + } + + // Order by title. + $contentTypes = ArrayHelper::sortObjects($contentTypes, 'translatedText', 1, true, true); + + // Convert the values to options. + foreach ($contentTypes as $contentType) + { + $options[] = \JHtml::_('select.option', $contentType->value, $contentType->translatedText); + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } +} diff --git a/administrator/components/com_finder/Field/SearchfilterField.php b/administrator/components/com_finder/Field/SearchfilterField.php new file mode 100644 index 0000000000000..9b24acbd2e9bc --- /dev/null +++ b/administrator/components/com_finder/Field/SearchfilterField.php @@ -0,0 +1,55 @@ +getQuery(true) + ->select('f.title AS text, f.filter_id AS value') + ->from($db->quoteName('#__finder_filters') . ' AS f') + ->where('f.state = 1') + ->order('f.title ASC'); + $db->setQuery($query); + $options = $db->loadObjectList(); + + array_unshift($options, \JHtml::_('select.option', '', \JText::_('COM_FINDER_SELECT_SEARCH_FILTER'), 'value', 'text')); + + return $options; + } +} diff --git a/administrator/components/com_finder/Helper/FinderHelper.php b/administrator/components/com_finder/Helper/FinderHelper.php new file mode 100644 index 0000000000000..090da9f372b86 --- /dev/null +++ b/administrator/components/com_finder/Helper/FinderHelper.php @@ -0,0 +1,120 @@ +getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('content')) + ->where($db->quoteName('element') . ' = ' . $db->quote('finder')); + $db->setQuery($query); + + try + { + $result = (int) $db->loadResult(); + } + catch (\RuntimeException $e) + { + \JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + return $result; + } + + /** + * Gets a list of the actions that can be performed. + * + * @return \JObject A JObject containing the allowed actions. + * + * @since 2.5 + * @deprecated 3.2 Use \JHelperContent::getActions() instead + */ + public static function getActions() + { + // Log usage of deprecated function + try + { + \JLog::add( + sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__), + \JLog::WARNING, + 'deprecated' + ); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + // Get list of actions + return ContentHelper::getActions('com_finder'); + } +} diff --git a/administrator/components/com_finder/Helper/FinderHelperLanguage.php b/administrator/components/com_finder/Helper/FinderHelperLanguage.php new file mode 100644 index 0000000000000..871ba7034defa --- /dev/null +++ b/administrator/components/com_finder/Helper/FinderHelperLanguage.php @@ -0,0 +1,148 @@ +title; + } + } + + return $title; + } + + /** + * Method to load Smart Search component language file. + * + * @return void + * + * @since 2.5 + */ + public static function loadComponentLanguage() + { + \JFactory::getLanguage()->load('com_finder', JPATH_SITE); + } + + /** + * Method to load Smart Search plugin language files. + * + * @return void + * + * @since 2.5 + */ + public static function loadPluginLanguage() + { + static $loaded = false; + + // If already loaded, don't load again. + if ($loaded) + { + return; + } + + $loaded = true; + + // Get array of all the enabled Smart Search plugin names. + $db = \JFactory::getDbo(); + $query = $db->getQuery(true) + ->select(array($db->quoteName('name'), $db->quoteName('element'))) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('finder')) + ->where($db->quoteName('enabled') . ' = 1'); + $db->setQuery($query); + $plugins = $db->loadObjectList(); + + if (empty($plugins)) + { + return; + } + + // Load generic language strings. + $lang = \JFactory::getLanguage(); + $lang->load('plg_content_finder', JPATH_ADMINISTRATOR); + + // Load language file for each plugin. + foreach ($plugins as $plugin) + { + $lang->load($plugin->name, JPATH_ADMINISTRATOR) + || $lang->load($plugin->name, JPATH_PLUGINS . '/finder/' . $plugin->element); + } + } +} diff --git a/administrator/components/com_finder/Model/FilterModel.php b/administrator/components/com_finder/Model/FilterModel.php new file mode 100644 index 0000000000000..c7d117c16f03e --- /dev/null +++ b/administrator/components/com_finder/Model/FilterModel.php @@ -0,0 +1,153 @@ +getState('filter.id'); + + // Get a FinderTableFilter instance. + $filter = $this->getTable(); + + // Attempt to load the row. + $return = $filter->load($filter_id); + + // Check for a database error. + if ($return === false && $filter->getError()) + { + $this->setError($filter->getError()); + + return false; + } + + // Process the filter data. + if (!empty($filter->data)) + { + $filter->data = explode(',', $filter->data); + } + elseif (empty($filter->data)) + { + $filter->data = array(); + } + + return $filter; + } + + /** + * Method to get the record form. + * + * @param array $data Data for the form. [optional] + * @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional] + * + * @return \JForm|boolean A \JForm object on success, false on failure + * + * @since 2.5 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_finder.filter', 'filter', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 2.5 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = \JFactory::getApplication()->getUserState('com_finder.edit.filter.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_finder.filter', $data); + + return $data; + } + + /** + * Method to get the total indexed items + * + * @return number the number of indexed items + * + * @since 3.5 + */ + public function getTotal() + { + $db = \JFactory::getDbo(); + $query = $db->getQuery(true) + ->select('MAX(link_id)') + ->from('#__finder_links'); + + return $db->setQuery($query)->loadResult(); + } +} diff --git a/administrator/components/com_finder/Model/FiltersModel.php b/administrator/components/com_finder/Model/FiltersModel.php new file mode 100644 index 0000000000000..0809c5aa48e81 --- /dev/null +++ b/administrator/components/com_finder/Model/FiltersModel.php @@ -0,0 +1,141 @@ +getDbo(); + $query = $db->getQuery(true); + + // Select all fields from the table. + $query->select('a.*') + ->from($db->quoteName('#__finder_filters', 'a')); + + // Join over the users for the checked out user. + $query->select($db->quoteName('uc.name', 'editor')) + ->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')); + + // Join over the users for the author. + $query->select($db->quoteName('ua.name', 'user_name')) + ->join('LEFT', $db->quoteName('#__users', 'ua') . ' ON ' . $db->quoteName('ua.id') . ' = ' . $db->quoteName('a.created_by')); + + // Check for a search filter. + if ($search = $this->getState('filter.search')) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where($db->quoteName('a.title') . ' LIKE ' . $search); + } + + // If the model is set to check item state, add to the query. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where($db->quoteName('a.state') . ' = ' . (int) $state); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.title') . ' ' . $db->escape($this->getState('list.direction', 'ASC')))); + + 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. [optional] + * + * @return string A store id. + * + * @since 2.5 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + + return parent::getStoreId($id); + } + + /** + * Method to auto-populate the model state. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. [optional] + * @param string $direction An optional direction. [optional] + * + * @return void + * + * @since 2.5 + */ + protected function populateState($ordering = 'a.title', $direction = 'asc') + { + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + + // Load the parameters. + $params = ComponentHelper::getParams('com_finder'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } +} diff --git a/administrator/components/com_finder/Model/IndexModel.php b/administrator/components/com_finder/Model/IndexModel.php new file mode 100644 index 0000000000000..2a2cd2ce6f852 --- /dev/null +++ b/administrator/components/com_finder/Model/IndexModel.php @@ -0,0 +1,453 @@ +authorise('core.delete', $this->option); + } + + /** + * 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 for the component. + * + * @since 2.5 + */ + protected function canEditState($record) + { + return \JFactory::getUser()->authorise('core.edit.state', $this->option); + } + + /** + * Method to delete one or more records. + * + * @param array &$pks An array of record primary keys. + * + * @return boolean True if successful, false if an error occurs. + * + * @since 2.5 + */ + public function delete(&$pks) + { + $pks = (array) $pks; + $table = $this->getTable(); + + // Include the content plugins for the on delete events. + PluginHelper::importPlugin('content'); + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if ($this->canDelete($table)) + { + $context = $this->option . '.' . $this->name; + + // Trigger the onContentBeforeDelete event. + $result = \JFactory::getApplication()->triggerEvent($this->event_before_delete, array($context, $table)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + if (!$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the onContentAfterDelete event. + \JFactory::getApplication()->triggerEvent($this->event_after_delete, array($context, $table)); + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + $error = $this->getError(); + + if ($error) + { + $this->setError($error); + } + else + { + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + } + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery A \JDatabaseQuery object + * + * @since 2.5 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('l.*') + ->select($db->quoteName('t.title', 't_title')) + ->from($db->quoteName('#__finder_links', 'l')) + ->join('INNER', $db->quoteName('#__finder_types', 't') . ' ON ' . $db->quoteName('t.id') . ' = ' . $db->quoteName('l.type_id')); + + // Check the type filter. + $type = $this->getState('filter.type'); + + if (is_numeric($type)) + { + $query->where($db->quoteName('l.type_id') . ' = ' . (int) $type); + } + + // Check the map filter. + $contentMapId = $this->getState('filter.content_map'); + + if (is_numeric($contentMapId)) + { + $query->join('INNER', $db->quoteName('#__finder_taxonomy_map', 'm') . ' ON ' . $db->quoteName('m.link_id') . ' = ' . $db->quoteName('l.link_id')) + ->where($db->quoteName('m.node_id') . ' = ' . (int) $contentMapId); + } + + // Check for state filter. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where($db->quoteName('l.published') . ' = ' . (int) $state); + } + + // Check the search phrase. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $orSearchSql = $db->quoteName('l.title') . ' LIKE ' . $search . ' OR ' . $db->quoteName('l.url') . ' LIKE ' . $search; + + // Filter by indexdate only if $search doesn't contains non-ascii characters + if (!preg_match('/[^\x00-\x7F]/', $search)) + { + $orSearchSql .= ' OR ' . $query->castAsChar($db->quoteName('l.indexdate')) . ' LIKE ' . $search; + } + + $query->where('(' . $orSearchSql . ')'); + } + + // Handle the list ordering. + $listOrder = $this->getState('list.ordering', 'l.title'); + $listDir = $this->getState('list.direction', 'ASC'); + + if ($listOrder === 't.title') + { + $ordering = $db->quoteName('t.title') . ' ' . $db->escape($listDir) . ', ' . $db->quoteName('l.title') . ' ' . $db->escape($listDir); + } + else + { + $ordering = $db->escape($listOrder) . ' ' . $db->escape($listDir); + } + + $query->order($ordering); + + return $query; + } + + /** + * Method to get the state of the Smart Search Plugins. + * + * @return array Array of relevant plugins and whether they are enabled or not. + * + * @since 2.5 + */ + public function getPluginState() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('name, enabled') + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('folder') . ' IN (' . $db->quote('system') . ',' . $db->quote('content') . ')') + ->where($db->quoteName('element') . ' = ' . $db->quote('finder')); + $db->setQuery($query); + + return $db->loadObjectList('name'); + } + + /** + * 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. [optional] + * + * @return string A store id. + * + * @since 2.5 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.type'); + $id .= ':' . $this->getState('filter.content_map'); + + return parent::getStoreId($id); + } + + /** + * Gets the total of indexed items. + * + * @return integer The total of indexed items. + * + * @since 3.6.0 + */ + public function getTotalIndexed() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(link_id)') + ->from($db->quoteName('#__finder_links')); + $db->setQuery($query); + + $db->execute(); + + return (int) $db->loadResult(); + } + + /** + * Returns a \JTable object, always creating it. + * + * @param string $type The table type to instantiate. [optional] + * @param string $prefix A prefix for the table class name. [optional] + * @param array $config Configuration array for model. [optional] + * + * @return \JTable A database object + * + * @since 2.5 + */ + public function getTable($type = 'Link', $prefix = 'Administrator', $config = array()) + { + return parent::getTable($type, $prefix, $config); + } + + /** + * Method to purge the index, deleting all links. + * + * @return boolean True on success, false on failure. + * + * @since 2.5 + * @throws \Exception on database error + */ + public function purge() + { + $db = $this->getDbo(); + + // Truncate the links table. + $db->truncateTable('#__finder_links'); + + // Truncate the links terms tables. + $db->truncateTable('#__finder_links_terms'); + + // Truncate the terms table. + $db->truncateTable('#__finder_terms'); + + // Truncate the taxonomy map table. + $db->truncateTable('#__finder_taxonomy_map'); + + // Truncate the taxonomy table and insert the root node. + $db->truncateTable('#__finder_taxonomy'); + $root = (object) array('id' => 1, 'parent_id' => 0, 'title' => 'ROOT', 'state' => 0, 'access' => 0, 'ordering' => 0); + $db->insertObject('#__finder_taxonomy', $root); + + // Truncate the tokens tables. + $db->truncateTable('#__finder_tokens'); + + // Truncate the tokens aggregate table. + $db->truncateTable('#__finder_tokens_aggregate'); + + return true; + } + + /** + * Method to auto-populate the model state. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. [optional] + * @param string $direction An optional direction. [optional] + * + * @return void + * + * @since 2.5 + */ + protected function populateState($ordering = 'l.title', $direction = 'asc') + { + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'cmd')); + $this->setState('filter.content_map', $this->getUserStateFromRequest($this->context . '.filter.content_map', 'filter_content_map', '', 'cmd')); + + // Load the parameters. + $params = ComponentHelper::getParams('com_finder'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to change the published state of one or more records. + * + * @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. + * + * @since 2.5 + */ + public function publish(&$pks, $value = 1) + { + $user = \JFactory::getUser(); + $table = $this->getTable(); + $pks = (array) $pks; + + // Include the content plugins for the change of state event. + PluginHelper::importPlugin('content'); + + // Access checks. + foreach ($pks as $i => $pk) + { + $table->reset(); + + if ($table->load($pk) && !$this->canEditState($table)) + { + // Prune items that you can't change. + unset($pks[$i]); + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + + return false; + } + } + + // Attempt to change the state of the records. + if (!$table->publish($pks, $value, $user->get('id'))) + { + $this->setError($table->getError()); + + return false; + } + + $context = $this->option . '.' . $this->name; + + // Trigger the onContentChangeState event. + $result = \JFactory::getApplication()->triggerEvent('onContentChangeState', array($context, $pks, $value)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } +} diff --git a/administrator/components/com_finder/Model/IndexerModel.php b/administrator/components/com_finder/Model/IndexerModel.php new file mode 100644 index 0000000000000..80b803f202240 --- /dev/null +++ b/administrator/components/com_finder/Model/IndexerModel.php @@ -0,0 +1,23 @@ +authorise('core.delete', $this->option); + } + + /** + * 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 for the component. + * + * @since 2.5 + */ + protected function canEditState($record) + { + return \JFactory::getUser()->authorise('core.edit.state', $this->option); + } + + /** + * Method to delete one or more records. + * + * @param array &$pks An array of record primary keys. + * + * @return boolean True if successful, false if an error occurs. + * + * @since 2.5 + */ + public function delete(&$pks) + { + $pks = (array) $pks; + $table = $this->getTable(); + + // Include the content plugins for the on delete events. + PluginHelper::importPlugin('content'); + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if ($this->canDelete($table)) + { + $context = $this->option . '.' . $this->name; + + // Trigger the onContentBeforeDelete event. + $result = \JFactory::getApplication()->triggerEvent('onContentBeforeDelete', array($context, $table)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + if (!$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the onContentAfterDelete event. + \JFactory::getApplication()->triggerEvent('onContentAfterDelete', array($context, $table)); + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + $error = $this->getError(); + + if ($error) + { + $this->setError($error); + } + else + { + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + } + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery A \JDatabaseQuery object + * + * @since 2.5 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + + // Select all fields from the table. + $query = $db->getQuery(true) + ->select('a.id, a.parent_id, a.title, a.state, a.access, a.ordering') + ->select('CASE WHEN a.parent_id = 1 THEN 1 ELSE 2 END AS level') + ->select('p.title AS parent_title') + ->from($db->quoteName('#__finder_taxonomy', 'a')) + ->leftJoin($db->quoteName('#__finder_taxonomy', 'p') . ' ON p.id = a.parent_id') + ->where('a.parent_id != 0'); + + $childQuery = $db->getQuery(true) + ->select('parent_id') + ->select('COUNT(*) AS num_children') + ->from($db->quoteName('#__finder_taxonomy')) + ->where('parent_id != 0') + ->group('parent_id'); + + // Join to get children. + $query->select('b.num_children'); + $query->select('CASE WHEN a.parent_id = 1 THEN a.title ELSE p.title END AS branch_title'); + $query->leftJoin('(' . $childQuery . ') AS b ON b.parent_id = a.id'); + + // Join to get the map links. + $stateQuery = $db->getQuery(true) + ->select('m.node_id') + ->select('COUNT(NULLIF(l.published, 0)) AS count_published') + ->select('COUNT(NULLIF(l.published, 1)) AS count_unpublished') + ->from($db->quoteName('#__finder_taxonomy_map', 'm')) + ->leftJoin($db->quoteName('#__finder_links', 'l') . ' ON l.link_id = m.link_id') + ->group('m.node_id'); + + $query->select('COALESCE(s.count_published, 0) AS count_published'); + $query->select('COALESCE(s.count_unpublished, 0) AS count_unpublished'); + $query->leftJoin('(' . $stateQuery . ') AS s ON s.node_id = a.id'); + + // If the model is set to check item state, add to the query. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where('a.state = ' . (int) $state); + } + + // Filter over level. + $level = $this->getState('filter.level'); + + if (is_numeric($level) && (int) $level === 1) + { + $query->where('a.parent_id = 1'); + } + + // Filter the maps over the branch if set. + $branchId = $this->getState('filter.branch'); + + if (is_numeric($branchId)) + { + $query->where('a.parent_id = ' . (int) $branchId); + } + + // Filter the maps over the search string if set. + if ($search = $this->getState('filter.search')) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.title LIKE ' . $search); + } + + // Handle the list ordering. + $listOrdering = $this->getState('list.ordering', 'd.branch_title'); + $listDirn = $this->getState('list.direction', 'ASC'); + + if ($listOrdering === 'd.branch_title') + { + $query->order("branch_title $listDirn, level ASC, a.title $listDirn"); + } + elseif ($listOrdering === 'a.state') + { + $query->order("a.state $listDirn, branch_title $listDirn, level ASC"); + } + + return $query; + } + + /** + * Returns a record count for the query. + * + * @param \JDatabaseQuery|string $query The query. + * + * @return integer Number of rows for query. + * + * @since 3.0 + */ + protected function _getListCount($query) + { + $query = clone $query; + $query->clear('select')->clear('join')->clear('order')->clear('limit')->clear('offset')->select('COUNT(*)'); + + return (int) $this->getDbo()->setQuery($query)->loadResult(); + } + + /** + * 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. [optional] + * + * @return string A store id. + * + * @since 2.5 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.branch'); + $id .= ':' . $this->getState('filter.level'); + + return parent::getStoreId($id); + } + + /** + * Returns a \JTable object, always creating it. + * + * @param string $type The table type to instantiate. [optional] + * @param string $prefix A prefix for the table class name. [optional] + * @param array $config Configuration array for model. [optional] + * + * @return \Joomla\CMS\Table\Table A database object + * + * @since 2.5 + */ + public function getTable($type = 'Map', $prefix = 'Administrator', $config = array()) + { + return parent::getTable($type, $prefix, $config); + } + + /** + * Method to auto-populate the model state. Calling getState in this method will result in recursion. + * + * @param string $ordering An optional ordering field. [optional] + * @param string $direction An optional direction. [optional] + * + * @return void + * + * @since 2.5 + */ + protected function populateState($ordering = 'd.branch_title', $direction = 'ASC') + { + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); + $this->setState('filter.branch', $this->getUserStateFromRequest($this->context . '.filter.branch', 'filter_branch', '', 'cmd')); + $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); + + // Load the parameters. + $params = ComponentHelper::getParams('com_finder'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Method to change the published state of one or more records. + * + * @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. + * + * @since 2.5 + */ + public function publish(&$pks, $value = 1) + { + $user = \JFactory::getUser(); + $table = $this->getTable(); + $pks = (array) $pks; + + // Include the content plugins for the change of state event. + PluginHelper::importPlugin('content'); + + // Access checks. + foreach ($pks as $i => $pk) + { + $table->reset(); + + if ($table->load($pk) && !$this->canEditState($table)) + { + // Prune items that you can't change. + unset($pks[$i]); + $this->setError(\JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + + return false; + } + } + + // Attempt to change the state of the records. + if (!$table->publish($pks, $value, $user->get('id'))) + { + $this->setError($table->getError()); + + return false; + } + + $context = $this->option . '.' . $this->name; + + // Trigger the onContentChangeState event. + $result = \JFactory::getApplication()->triggerEvent('onContentChangeState', array($context, $pks, $value)); + + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Clear the component's cache + $this->cleanCache(); + + return true; + } + + /** + * Method to purge all maps from the taxonomy. + * + * @return boolean Returns true on success, false on failure. + * + * @since 2.5 + */ + public function purge() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' > 1'); + $db->setQuery($query); + $db->execute(); + + $query->clear() + ->delete($db->quoteName('#__finder_taxonomy_map')) + ->where('1'); + $db->setQuery($query); + $db->execute(); + + return true; + } +} diff --git a/administrator/components/com_finder/Model/SearchesModel.php b/administrator/components/com_finder/Model/SearchesModel.php new file mode 100644 index 0000000000000..d288f8b741855 --- /dev/null +++ b/administrator/components/com_finder/Model/SearchesModel.php @@ -0,0 +1,176 @@ +setState('show_results', $this->getUserStateFromRequest($this->context . '.show_results', 'show_results', 1, 'int')); + + // Load the parameters. + $params = ComponentHelper::getParams('com_finder'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + * + * @since 4.0.0 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('show_results'); + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery + * + * @since 4.0.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('#__finder_logging', 'a')); + + // Filter by search in title + if ($search = $this->getState('filter.search')) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where($db->quoteName('a.searchterm') . ' LIKE ' . $search); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.hits')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Override the parent getItems to inject optional data. + * + * @return mixed An array of objects on success, false on failure. + * + * @since 4.0.0 + */ + public function getItems() + { + $items = parent::getItems(); + + \JLoader::register('FinderIndexerQuery', JPATH_COMPONENT_ADMINISTRATOR . '/helpers/indexer/query.php'); + \JLoader::register('FinderIndexerToken', JPATH_COMPONENT_ADMINISTRATOR . '/helpers/indexer/token.php'); + + foreach ($items as $item) + { + $item->query = unserialize($item->query); + } + + return $items; + } + + /** + * Method to reset the search log table. + * + * @return boolean + * + * @since 4.0.0 + */ + public function reset() + { + $db = $this->getDbo(); + + try + { + $db->truncateTable('#__finder_logging'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } +} diff --git a/administrator/components/com_finder/Model/StatisticsModel.php b/administrator/components/com_finder/Model/StatisticsModel.php new file mode 100644 index 0000000000000..f0c15f99a970c --- /dev/null +++ b/administrator/components/com_finder/Model/StatisticsModel.php @@ -0,0 +1,83 @@ +getDbo(); + $query = $db->getQuery(true); + $data = new \JObject; + + $query->select('COUNT(term_id)') + ->from($db->quoteName('#__finder_terms')); + $db->setQuery($query); + $data->term_count = $db->loadResult(); + + $query->clear() + ->select('COUNT(link_id)') + ->from($db->quoteName('#__finder_links')); + $db->setQuery($query); + $data->link_count = $db->loadResult(); + + $query->clear() + ->select('COUNT(id)') + ->from($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' = 1'); + $db->setQuery($query); + $data->taxonomy_branch_count = $db->loadResult(); + + $query->clear() + ->select('COUNT(id)') + ->from($db->quoteName('#__finder_taxonomy')) + ->where($db->quoteName('parent_id') . ' > 1'); + $db->setQuery($query); + $data->taxonomy_node_count = $db->loadResult(); + + $query->clear() + ->select('t.title AS type_title, COUNT(a.link_id) AS link_count') + ->from($db->quoteName('#__finder_links') . ' AS a') + ->join('INNER', $db->quoteName('#__finder_types') . ' AS t ON t.id = a.type_id') + ->group('a.type_id, t.title') + ->order($db->quoteName('type_title') . ' ASC'); + $db->setQuery($query); + $data->type_list = $db->loadObjectList(); + + $lang = \JFactory::getLanguage(); + $plugins = PluginHelper::getPlugin('finder'); + + foreach ($plugins as $plugin) + { + $lang->load('plg_finder_' . $plugin->name . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load('plg_finder_' . $plugin->name . '.sys', JPATH_PLUGINS . '/finder/' . $plugin->name, null, false, true); + } + + return $data; + } +} diff --git a/administrator/components/com_finder/Table/FilterTable.php b/administrator/components/com_finder/Table/FilterTable.php new file mode 100644 index 0000000000000..ed3a5ca00d11e --- /dev/null +++ b/administrator/components/com_finder/Table/FilterTable.php @@ -0,0 +1,273 @@ +setError($e->getMessage()); + + return false; + } + + if (trim($this->alias) === '') + { + $this->alias = $this->title; + } + + $this->alias = ApplicationHelper::stringURLSafe($this->alias); + + if (trim(str_replace('-', '', $this->alias)) === '') + { + $this->alias = \JFactory::getDate()->format('Y-m-d-H-i-s'); + } + + $params = new Registry($this->params); + + $nullDate = $this->_db->getNullDate(); + $d1 = $params->get('d1', $nullDate); + $d2 = $params->get('d2', $nullDate); + + // Check the end date is not earlier than the start date. + if ($d2 > $nullDate && $d2 < $d1) + { + // Swap the dates. + $params->set('d1', $d2); + $params->set('d2', $d1); + $this->params = (string) $params; + } + + if (empty($this->modified)) + { + $this->modified = $nullDate; + } + + return true; + } + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to checkin rows that it can after adjustments are made. + * + * @param mixed $pks An array of primary key values to update. If not + * set the instance property value is used. [optional] + * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] [optional] + * @param integer $userId The user id of the user performing the operation. [optional] + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + $k = $this->_tbl_key; + + // Sanitize input. + $pks = ArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(\JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k . '=' . implode(' OR ' . $k . '=', $pks); + + // Determine if there is checkin support for the table. + if (!$this->hasField('checked_out') || !$this->hasField('checked_out_time')) + { + $checkin = ''; + } + else + { + $checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')'; + } + + // Update the publishing state for rows with the given primary keys. + $query = $this->_db->getQuery(true) + ->update($this->_db->quoteName($this->_tbl)) + ->set($this->_db->quoteName('state') . ' = ' . (int) $state) + ->where($where); + $this->_db->setQuery($query . $checkin); + + try + { + $this->_db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && count($pks) === $this->_db->getAffectedRows()) + { + // Checkin the rows. + foreach ($pks as $pk) + { + $this->checkIn($pk); + } + } + + // If the \JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } + + /** + * Method to store a row in the database from the \JTable instance properties. + * If a primary key value is set the row with that primary key value will be + * updated with the instance property values. If no primary key value is set + * a new row will be inserted into the database with the properties from the + * \JTable instance. + * + * @param boolean $updateNulls True to update fields even if they are null. [optional] + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function store($updateNulls = false) + { + $date = \JFactory::getDate()->toSql(); + $userId = \JFactory::getUser()->id; + + if ($this->filter_id) + { + // Existing item + $this->modified_by = $userId; + $this->modified = $date; + } + else + { + // New item. A filter's created field can be set by the user, + // so we don't touch it if it is set. + if (!(int) $this->created) + { + $this->created = $date; + } + + if (empty($this->created_by)) + { + $this->created_by = $userId; + } + } + + if (is_array($this->data)) + { + $this->map_count = count($this->data); + $this->data = implode(',', $this->data); + } + else + { + $this->map_count = 0; + $this->data = implode(',', array()); + } + + // Verify that the alias is unique + $table = new static($this->getDbo()); + + if ($table->load(array('alias' => $this->alias)) && ($table->filter_id != $this->filter_id || $this->filter_id == 0)) + { + $this->setError(\JText::_('JLIB_DATABASE_ERROR_ARTICLE_UNIQUE_ALIAS')); + + return false; + } + + return parent::store($updateNulls); + } +} diff --git a/administrator/components/com_finder/Table/LinkTable.php b/administrator/components/com_finder/Table/LinkTable.php new file mode 100644 index 0000000000000..b081961f828e5 --- /dev/null +++ b/administrator/components/com_finder/Table/LinkTable.php @@ -0,0 +1,33 @@ +_tbl_key; + + // Sanitize input. + $pks = ArrayHelper::toInteger($pks); + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(\JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + // Build the WHERE clause for the primary keys. + $where = $k . '=' . implode(' OR ' . $k . '=', $pks); + + // Update the publishing state for rows with the given primary keys. + $query = $this->_db->getQuery(true) + ->update($this->_db->quoteName($this->_tbl)) + ->set($this->_db->quoteName('state') . ' = ' . (int) $state) + ->where($where); + $this->_db->setQuery($query); + + try + { + $this->_db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // If the \JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } +} diff --git a/administrator/components/com_finder/View/Filter/HtmlView.php b/administrator/components/com_finder/View/Filter/HtmlView.php new file mode 100644 index 0000000000000..e90a1862f054d --- /dev/null +++ b/administrator/components/com_finder/View/Filter/HtmlView.php @@ -0,0 +1,173 @@ +filter = $this->get('Filter'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + $this->state = $this->get('State'); + $this->total = $this->get('Total'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + \JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + \JHtml::addIncludePath(JPATH_SITE . '/components/com_finder/helpers/html'); + + // Configure the toolbar. + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Method to configure the toolbar for this view. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + \JFactory::getApplication()->input->set('hidemainmenu', true); + + $isNew = ($this->item->filter_id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == \JFactory::getUser()->id); + $canDo = ContentHelper::getActions('com_finder'); + + // Configure the toolbar. + ToolbarHelper::title( + $isNew ? \JText::_('COM_FINDER_FILTER_NEW_TOOLBAR_TITLE') : \JText::_('COM_FINDER_FILTER_EDIT_TOOLBAR_TITLE'), + 'zoom-in finder' + ); + + // Set the actions for new and existing records. + if ($isNew) + { + // For new records, check the create permission. + if ($canDo->get('core.create')) + { + ToolbarHelper::saveGroup( + [ + ['apply', 'filter.apply'], + ['save', 'filter.save'], + ['save2new', 'filter.save2new'] + ], + 'btn-success' + ); + } + + ToolbarHelper::cancel('filter.cancel'); + } + else + { + $toolbarButtons = []; + + // Can't save the record if it's checked out. + // Since it's an existing record, check the edit permission. + if (!$checkedOut && $canDo->get('core.edit')) + { + $toolbarButtons[] = ['apply', 'filter.apply']; + $toolbarButtons[] = ['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')) + { + $toolbarButtons[] = ['save2new', 'filter.save2new']; + } + } + + // If an existing item, can save as a copy + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'filter.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + ToolbarHelper::cancel('filter.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT'); + } +} diff --git a/administrator/components/com_finder/View/Filters/HtmlView.php b/administrator/components/com_finder/View/Filters/HtmlView.php new file mode 100644 index 0000000000000..64d93ccc0cb71 --- /dev/null +++ b/administrator/components/com_finder/View/Filters/HtmlView.php @@ -0,0 +1,169 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->total = $this->get('Total'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + FinderHelper::addSubmenu('filters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + \JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Configure the toolbar. + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Method to configure the toolbar for this view. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_finder'); + + ToolbarHelper::title(\JText::_('COM_FINDER_FILTERS_TOOLBAR_TITLE'), 'zoom-in finder'); + $toolbar = Toolbar::getInstance('toolbar'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('filter.add'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publishList('filters.publish'); + ToolbarHelper::unpublishList('filters.unpublish'); + ToolbarHelper::checkin('filters.checkin'); + ToolbarHelper::divider(); + } + + ToolbarHelper::divider(); + $toolbar->appendButton('Popup', 'bars', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 350); + ToolbarHelper::divider(); + + if ($canDo->get('core.delete')) + { + ToolbarHelper::deleteList('', 'filters.delete'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_finder'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS'); + } +} diff --git a/administrator/components/com_finder/View/Index/HtmlView.php b/administrator/components/com_finder/View/Index/HtmlView.php new file mode 100644 index 0000000000000..ab1b9358751fb --- /dev/null +++ b/administrator/components/com_finder/View/Index/HtmlView.php @@ -0,0 +1,191 @@ +items = $this->get('Items'); + $this->total = $this->get('Total'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->pluginState = $this->get('pluginState'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + FinderHelper::addSubmenu('index'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + if (!$this->pluginState['plg_content_finder']->enabled) + { + $link = \JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . FinderHelper::getFinderPluginId()); + \JFactory::getApplication()->enqueueMessage(\JText::sprintf('COM_FINDER_INDEX_PLUGIN_CONTENT_NOT_ENABLED', $link), 'warning'); + } + elseif ($this->get('TotalIndexed') === 0) + { + \JFactory::getApplication()->enqueueMessage(\JText::_('COM_FINDER_INDEX_NO_DATA') . ' ' . \JText::_('COM_FINDER_INDEX_TIP'), 'notice'); + } + + \JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Configure the toolbar. + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Method to configure the toolbar for this view. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_finder'); + + ToolbarHelper::title(\JText::_('COM_FINDER_INDEX_TOOLBAR_TITLE'), 'zoom-in finder'); + + $toolbar = Toolbar::getInstance('toolbar'); + $toolbar->appendButton( + 'Popup', 'archive', 'COM_FINDER_INDEX', 'index.php?option=com_finder&view=indexer&tmpl=component', 500, 210, 0, 0, + 'window.parent.location.reload()', 'COM_FINDER_HEADING_INDEXER' + ); + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publishList('index.publish'); + ToolbarHelper::unpublishList('index.unpublish'); + } + + $toolbar->appendButton('Popup', 'bars', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 350); + + if ($canDo->get('core.delete')) + { + ToolbarHelper::deleteList('', 'index.delete'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('index.purge', 'COM_FINDER_INDEX_TOOLBAR_PURGE', false); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_finder'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT'); + } +} diff --git a/administrator/components/com_finder/View/Indexer/HtmlView.php b/administrator/components/com_finder/View/Indexer/HtmlView.php new file mode 100644 index 0000000000000..43eca298f9680 --- /dev/null +++ b/administrator/components/com_finder/View/Indexer/HtmlView.php @@ -0,0 +1,24 @@ +items = $this->get('Items'); + $this->total = $this->get('Total'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + FinderHelper::addSubmenu('maps'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + \JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Prepare the view. + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Method to configure the toolbar for this view. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_finder'); + + ToolbarHelper::title(\JText::_('COM_FINDER_MAPS_TOOLBAR_TITLE'), 'zoom-in finder'); + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publishList('maps.publish'); + ToolbarHelper::unpublishList('maps.unpublish'); + ToolbarHelper::divider(); + } + + ToolbarHelper::divider(); + Toolbar::getInstance('toolbar')->appendButton( + 'Popup', + 'bars', + 'COM_FINDER_STATISTICS', + 'index.php?option=com_finder&view=statistics&tmpl=component', + 550, + 350 + ); + ToolbarHelper::divider(); + + if ($canDo->get('core.delete')) + { + ToolbarHelper::deleteList('', 'maps.delete'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_finder'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_CONTENT_MAPS'); + } +} diff --git a/administrator/components/com_finder/View/Searches/HtmlView.php b/administrator/components/com_finder/View/Searches/HtmlView.php new file mode 100644 index 0000000000000..7158c007fd093 --- /dev/null +++ b/administrator/components/com_finder/View/Searches/HtmlView.php @@ -0,0 +1,145 @@ +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->enabled = $this->state->params->get('logging_enabled'); + $this->canDo = ContentHelper::getActions('com_finder'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + FinderHelper::addSubmenu('searches'); + + // Check if plugin is enabled + if (!$this->enabled) + { + $app->enqueueMessage(\JText::_('COM_FINDER_LOGGING_DISABLED'), 'warning'); + } + + // Prepare the view. + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = $this->canDo; + + ToolbarHelper::title(\JText::_('COM_FINDER_MANAGER_SEARCHES'), 'search'); + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::custom('searches.reset', 'refresh.png', 'refresh_f2.png', 'JSEARCH_RESET', false); + } + + ToolbarHelper::divider(); + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_finder'); + } + + ToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCHES'); + } +} diff --git a/administrator/components/com_finder/View/Statistics/HtmlView.php b/administrator/components/com_finder/View/Statistics/HtmlView.php new file mode 100644 index 0000000000000..aaffb21992fa2 --- /dev/null +++ b/administrator/components/com_finder/View/Statistics/HtmlView.php @@ -0,0 +1,54 @@ +data = $this->get('Data'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + return parent::display($tpl); + } +} diff --git a/administrator/components/com_finder/access.xml b/administrator/components/com_finder/access.xml index 7d09d2cbf1294..f88fefbd61fb2 100644 --- a/administrator/components/com_finder/access.xml +++ b/administrator/components/com_finder/access.xml @@ -1,12 +1,12 @@
- - - - - - - + + + + + + +
diff --git a/administrator/components/com_finder/config.xml b/administrator/components/com_finder/config.xml index 869fba3f886ad..9bc869619cd2e 100644 --- a/administrator/components/com_finder/config.xml +++ b/administrator/components/com_finder/config.xml @@ -7,159 +7,166 @@ > - - + + - + - - - + + - + + + + + + + + + + + - + - + - + - + - + - - + + - + @@ -172,7 +179,6 @@ name="sort_direction" type="list" label="COM_FINDER_CONFIG_SORT_DIRECTION_LABEL" - description="COM_FINDER_CONFIG_SORT_DIRECTION_DESC" default="desc" validate="options" > @@ -184,30 +190,40 @@ name="highlight_terms" type="radio" label="COM_FINDER_CONFIG_HILIGHT_CONTENT_SEARCH_TERMS_LABEL" - description="COM_FINDER_CONFIG_HILIGHT_CONTENT_SEARCH_TERMS_DESCRIPTION" - class="btn-group btn-group-yesno" + class="switcher" default="1" > + + + + +
@@ -218,11 +234,21 @@ description="COM_FINDER_FIELDSET_INDEX_OPTIONS_DESCRIPTION" > + + + + + @@ -242,8 +268,6 @@ name="memory_table_limit" type="number" label="COM_FINDER_CONFIG_MEMORY_TABLE_LIMIT_LABEL" - description="COM_FINDER_CONFIG_MEMORY_TABLE_LIMIT_DESCRIPTION" - size="10" default="30000" filter="integer" /> @@ -252,8 +276,6 @@ name="title_multiplier" type="number" label="COM_FINDER_CONFIG_TITLE_MULTIPLIER_LABEL" - description="COM_FINDER_CONFIG_TITLE_MULTIPLIER_DESCRIPTION" - size="5" default="1.7" /> @@ -261,8 +283,6 @@ name="text_multiplier" type="number" label="COM_FINDER_CONFIG_TEXT_MULTIPLIER_LABEL" - description="COM_FINDER_CONFIG_TEXT_MULTIPLIER_DESCRIPTION" - size="5" default="0.7" /> @@ -270,8 +290,6 @@ name="meta_multiplier" type="number" label="COM_FINDER_CONFIG_META_MULTIPLIER_LABEL" - description="COM_FINDER_CONFIG_META_MULTIPLIER_DESCRIPTION" - size="5" default="1.2" /> @@ -279,8 +297,6 @@ name="path_multiplier" type="number" label="COM_FINDER_CONFIG_PATH_MULTIPLIER_LABEL" - description="COM_FINDER_CONFIG_PATH_MULTIPLIER_DESCRIPTION" - size="5" default="2.0" /> @@ -288,46 +304,28 @@ name="misc_multiplier" type="number" label="COM_FINDER_CONFIG_MISC_MULTIPLIER_LABEL" - description="COM_FINDER_CONFIG_MISC_MULTIPLIER_DESCRIPTION" - size="5" default="0.3" /> - + - - - - - - - - + + diff --git a/administrator/components/com_finder/controller.php b/administrator/components/com_finder/controller.php deleted file mode 100644 index 339dc9b4571f1..0000000000000 --- a/administrator/components/com_finder/controller.php +++ /dev/null @@ -1,58 +0,0 @@ -input->get('view', 'index', 'word'); - $layout = $this->input->get('layout', 'index', 'word'); - $filterId = $this->input->get('filter_id', null, 'int'); - - // Check for edit form. - 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)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_finder&view=filters', false)); - - return false; - } - - return parent::display(); - } -} diff --git a/administrator/components/com_finder/controllers/filter.php b/administrator/components/com_finder/controllers/filter.php deleted file mode 100644 index 2948b065235ea..0000000000000 --- a/administrator/components/com_finder/controllers/filter.php +++ /dev/null @@ -1,240 +0,0 @@ -input; - $model = $this->getModel(); - $table = $model->getTable(); - $data = $input->post->get('jform', array(), 'array'); - $checkin = property_exists($table, 'checked_out'); - $context = "$this->option.edit.$this->context"; - $task = $this->getTask(); - - // 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 = $input->get($urlVar, '', 'int'); - - if (!$this->checkEditId($context, $recordId)) - { - // Somehow the person just went to the form and tried to save it. We don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $recordId)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); - - return false; - } - - // Populate the row id from the session. - $data[$key] = $recordId; - - // The save2copy task needs to be handled slightly differently. - if ($task === 'save2copy') - { - // Check-in the original row. - if ($checkin && $model->checkin($data[$key]) === false) - { - // Check-in failed. Go back to the item and display a notice. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $urlVar)); - - return false; - } - - // Reset the ID and then treat the request as for Apply. - $data[$key] = 0; - $task = 'apply'; - } - - // 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=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); - - return false; - } - - // Validate the posted data. - // Sometimes the form needs some posted data, such as for plugins and modules. - $form = $model->getForm($data, false); - - if (!$form) - { - $app->enqueueMessage($model->getError(), 'error'); - - return false; - } - - // Test whether the data is valid. - $validData = $model->validate($form, $data); - - // Check for validation errors. - if ($validData === false) - { - // Get the validation messages. - $errors = $model->getErrors(); - - // 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) - { - $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); - } - else - { - $app->enqueueMessage($errors[$i], 'warning'); - } - } - - // Save the data in the session. - $app->setUserState($context . '.data', $data); - - // Redirect back to the edit screen. - $this->setRedirect( - JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false) - ); - - return false; - } - - // Get and sanitize the filter data. - $validData['data'] = $input->post->get('t', array(), 'array'); - $validData['data'] = array_unique($validData['data']); - $validData['data'] = ArrayHelper::toInteger($validData['data']); - - // Remove any values of zero. - if (array_search(0, $validData['data'], true)) - { - unset($validData['data'][array_search(0, $validData['data'], true)]); - } - - // Attempt to save the data. - if (!$model->save($validData)) - { - // Save the data in the session. - $app->setUserState($context . '.data', $validData); - - // 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=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false) - ); - - return false; - } - - // Save succeeded, so check-in the record. - if ($checkin && $model->checkin($validData[$key]) === false) - { - // Save the data in the session. - $app->setUserState($context . '.data', $validData); - - // Check-in failed, so go back to the record and display a notice. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError())); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key)); - - return false; - } - - $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' - ) - ); - - // Redirect the user and adjust session state based on the chosen task. - switch ($task) - { - case 'apply': - // Set the record data in the session. - $recordId = $model->getState($this->context . '.id'); - $this->holdEditId($context, $recordId); - $app->setUserState($context . '.data', null); - $model->checkout($recordId); - - // Redirect back to the edit screen. - $this->setRedirect( - JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, $key), false) - ); - - break; - - case 'save2new': - // Clear the record id and data from the session. - $this->releaseEditId($context, $recordId); - $app->setUserState($context . '.data', null); - - // Redirect back to the edit screen. - $this->setRedirect( - JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(null, $key), false) - ); - - break; - - default: - // Clear the record id and data from the session. - $this->releaseEditId($context, $recordId); - $app->setUserState($context . '.data', null); - - // Redirect to the list screen. - $this->setRedirect( - JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false) - ); - - break; - } - - // Invoke the postSave method to allow for the child class to access the model. - $this->postSaveHook($model, $validData); - - return true; - } -} diff --git a/administrator/components/com_finder/controllers/filters.php b/administrator/components/com_finder/controllers/filters.php deleted file mode 100644 index f9c045f20af53..0000000000000 --- a/administrator/components/com_finder/controllers/filters.php +++ /dev/null @@ -1,34 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_finder/controllers/index.php b/administrator/components/com_finder/controllers/index.php deleted file mode 100644 index 6c1de7509fbc1..0000000000000 --- a/administrator/components/com_finder/controllers/index.php +++ /dev/null @@ -1,69 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Method to purge all indexed links from the database. - * - * @return boolean True on success. - * - * @since 2.5 - */ - public function purge() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Remove the script time limit. - @set_time_limit(0); - - $model = $this->getModel('Index', 'FinderModel'); - - // Attempt to purge the index. - $return = $model->purge(); - - if (!$return) - { - $message = JText::_('COM_FINDER_INDEX_PURGE_FAILED', $model->getError()); - $this->setRedirect('index.php?option=com_finder&view=index', $message); - - return false; - } - else - { - $message = JText::_('COM_FINDER_INDEX_PURGE_SUCCESS'); - $this->setRedirect('index.php?option=com_finder&view=index', $message); - - return true; - } - } -} diff --git a/administrator/components/com_finder/controllers/indexer.json.php b/administrator/components/com_finder/controllers/indexer.json.php deleted file mode 100644 index b9c087b3e96a3..0000000000000 --- a/administrator/components/com_finder/controllers/indexer.json.php +++ /dev/null @@ -1,416 +0,0 @@ -get('enable_logging', '0')) - { - $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; - $options['text_file'] = 'indexer.php'; - JLog::addLogger($options); - } - - // Log the start - try - { - JLog::add('Starting the indexer', JLog::INFO); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // We don't want this form to be cached. - $app = JFactory::getApplication(); - $app->setHeader('Expires', 'Mon, 1 Jan 2001 00:00:00 GMT', true); - $app->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true); - $app->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false); - $app->setHeader('Pragma', 'no-cache'); - - // Check for a valid token. If invalid, send a 403 with the error message. - JSession::checkToken('request') or static::sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); - - // Put in a buffer to silence noise. - ob_start(); - - // Reset the indexer state. - FinderIndexer::resetState(); - - // Import the finder plugins. - JPluginHelper::importPlugin('finder'); - - // Add the indexer language to JS - JText::script('COM_FINDER_AN_ERROR_HAS_OCCURRED'); - JText::script('COM_FINDER_NO_ERROR_RETURNED'); - - // Start the indexer. - try - { - // Trigger the onStartIndex event. - JEventDispatcher::getInstance()->trigger('onStartIndex'); - - // Get the indexer state. - $state = FinderIndexer::getState(); - $state->start = 1; - - // Send the response. - static::sendResponse($state); - } - - // Catch an exception and return the response. - catch (Exception $e) - { - static::sendResponse($e); - } - } - - /** - * Method to run the next batch of content through the indexer. - * - * @return void - * - * @since 2.5 - */ - public function batch() - { - $params = JComponentHelper::getParams('com_finder'); - - if ($params->get('enable_logging', '0')) - { - $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; - $options['text_file'] = 'indexer.php'; - JLog::addLogger($options); - } - - // Log the start - try - { - JLog::add('Starting the indexer batch process', JLog::INFO); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // We don't want this form to be cached. - $app = JFactory::getApplication(); - $app->setHeader('Expires', 'Mon, 1 Jan 2001 00:00:00 GMT', true); - $app->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true); - $app->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false); - $app->setHeader('Pragma', 'no-cache'); - - // Check for a valid token. If invalid, send a 403 with the error message. - JSession::checkToken('request') or static::sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); - - // Put in a buffer to silence noise. - ob_start(); - - // Remove the script time limit. - @set_time_limit(0); - - // Get the indexer state. - $state = FinderIndexer::getState(); - - // Reset the batch offset. - $state->batchOffset = 0; - - // Update the indexer state. - FinderIndexer::setState($state); - - // Import the finder plugins. - JPluginHelper::importPlugin('finder'); - - /* - * We are going to swap out the raw document object with an HTML document - * in order to work around some plugins that don't do proper environment - * checks before trying to use HTML document functions. - */ - $raw = clone JFactory::getDocument(); - $lang = JFactory::getLanguage(); - - // Get the document properties. - $attributes = array ( - 'charset' => 'utf-8', - 'lineend' => 'unix', - 'tab' => ' ', - 'language' => $lang->getTag(), - 'direction' => $lang->isRtl() ? 'rtl' : 'ltr' - ); - - // Get the HTML document. - $html = JDocument::getInstance('html', $attributes); - - // Todo: Why is this document fetched and immediately overwritten? - $doc = JFactory::getDocument(); - - // Swap the documents. - $doc = $html; - - // Get the admin application. - $admin = clone JFactory::getApplication(); - - // Get the site app. - $site = JApplicationCms::getInstance('site'); - - // Swap the app. - $app = JFactory::getApplication(); - - // Todo: Why is the app fetched and immediately overwritten? - $app = $site; - - // Start the indexer. - try - { - // Trigger the onBeforeIndex event. - JEventDispatcher::getInstance()->trigger('onBeforeIndex'); - - // Trigger the onBuildIndex event. - JEventDispatcher::getInstance()->trigger('onBuildIndex'); - - // Get the indexer state. - $state = FinderIndexer::getState(); - $state->start = 0; - $state->complete = 0; - - // Swap the documents back. - $doc = $raw; - - // Swap the applications back. - $app = $admin; - - // Log batch completion and memory high-water mark. - try - { - JLog::add('Batch completed, peak memory usage: ' . number_format(memory_get_peak_usage(true)) . ' bytes', JLog::INFO); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Send the response. - static::sendResponse($state); - } - - // Catch an exception and return the response. - catch (Exception $e) - { - // Swap the documents back. - $doc = $raw; - - // Send the response. - static::sendResponse($e); - } - } - - /** - * Method to optimize the index and perform any necessary cleanup. - * - * @return void - * - * @since 2.5 - */ - public function optimize() - { - // We don't want this form to be cached. - $app = JFactory::getApplication(); - $app->setHeader('Expires', 'Mon, 1 Jan 2001 00:00:00 GMT', true); - $app->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true); - $app->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false); - $app->setHeader('Pragma', 'no-cache'); - - // Check for a valid token. If invalid, send a 403 with the error message. - JSession::checkToken('request') or static::sendResponse(new Exception(JText::_('JINVALID_TOKEN'), 403)); - - // Put in a buffer to silence noise. - ob_start(); - - // Import the finder plugins. - JPluginHelper::importPlugin('finder'); - - try - { - // Optimize the index - FinderIndexer::getInstance()->optimize(); - - // Get the indexer state. - $state = FinderIndexer::getState(); - $state->start = 0; - $state->complete = 1; - - // Send the response. - static::sendResponse($state); - } - - // Catch an exception and return the response. - catch (Exception $e) - { - static::sendResponse($e); - } - } - - /** - * Method to handle a send a JSON response. The body parameter - * can be an Exception object for when an error has occurred or - * a JObject for a good response. - * - * @param mixed $data JObject on success, Exception on error. [optional] - * - * @return void - * - * @since 2.5 - */ - public static function sendResponse($data = null) - { - // This method always sends a JSON response - $app = JFactory::getApplication(); - $app->mimeType = 'application/json'; - - $params = JComponentHelper::getParams('com_finder'); - - if ($params->get('enable_logging', '0')) - { - $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; - $options['text_file'] = 'indexer.php'; - JLog::addLogger($options); - } - - // Send the assigned error code if we are catching an exception. - if ($data instanceof Exception) - { - try - { - JLog::add($data->getMessage(), JLog::ERROR); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $app->setHeader('status', $data->getCode()); - } - - // Create the response object. - $response = new FinderIndexerResponse($data); - - // Add the buffer. - $response->buffer = JDEBUG ? ob_get_contents() : ob_end_clean(); - - // Send the JSON response. - $app->setHeader('Content-Type', $app->mimeType . '; charset=' . $app->charSet); - $app->sendHeaders(); - echo json_encode($response); - - // Close the application. - $app->close(); - } -} - -/** - * Finder Indexer JSON Response Class - * - * @since 2.5 - */ -class FinderIndexerResponse -{ - /** - * Class Constructor - * - * @param mixed $state The processing state for the indexer - * - * @since 2.5 - */ - public function __construct($state) - { - $params = JComponentHelper::getParams('com_finder'); - - if ($params->get('enable_logging', '0')) - { - $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; - $options['text_file'] = 'indexer.php'; - JLog::addLogger($options); - } - - // The old token is invalid so send a new one. - $this->token = JFactory::getSession()->getFormToken(); - - // Check if we are dealing with an error. - if ($state instanceof Exception) - { - // Log the error - try - { - JLog::add($state->getMessage(), JLog::ERROR); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Prepare the error response. - $this->error = true; - $this->header = JText::_('COM_FINDER_INDEXER_HEADER_ERROR'); - $this->message = $state->getMessage(); - } - else - { - // Prepare the response data. - $this->batchSize = (int) $state->batchSize; - $this->batchOffset = (int) $state->batchOffset; - $this->totalItems = (int) $state->totalItems; - - $this->startTime = $state->startTime; - $this->endTime = JFactory::getDate()->toSql(); - - $this->start = !empty($state->start) ? (int) $state->start : 0; - $this->complete = !empty($state->complete) ? (int) $state->complete : 0; - - // Set the appropriate messages. - if ($this->totalItems <= 0 && $this->complete) - { - $this->header = JText::_('COM_FINDER_INDEXER_HEADER_COMPLETE'); - $this->message = JText::_('COM_FINDER_INDEXER_MESSAGE_COMPLETE'); - } - elseif ($this->totalItems <= 0) - { - $this->header = JText::_('COM_FINDER_INDEXER_HEADER_OPTIMIZE'); - $this->message = JText::_('COM_FINDER_INDEXER_MESSAGE_OPTIMIZE'); - } - else - { - $this->header = JText::_('COM_FINDER_INDEXER_HEADER_RUNNING'); - $this->message = JText::_('COM_FINDER_INDEXER_MESSAGE_RUNNING'); - } - } - } -} - -// Register the error handler. -JError::setErrorHandling(E_ALL, 'callback', array('FinderControllerIndexer', 'sendResponse')); diff --git a/administrator/components/com_finder/controllers/maps.php b/administrator/components/com_finder/controllers/maps.php deleted file mode 100644 index 0a31778d128c9..0000000000000 --- a/administrator/components/com_finder/controllers/maps.php +++ /dev/null @@ -1,34 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_finder/finder.php b/administrator/components/com_finder/finder.php deleted file mode 100644 index 4318352a8b47e..0000000000000 --- a/administrator/components/com_finder/finder.php +++ /dev/null @@ -1,19 +0,0 @@ -authorise('core.manage', 'com_finder')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('Finder'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_finder/finder.xml b/administrator/components/com_finder/finder.xml index 4a232b08a11b2..ef5713a525a9c 100644 --- a/administrator/components/com_finder/finder.xml +++ b/administrator/components/com_finder/finder.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 COM_FINDER_XML_DESCRIPTION + Joomla\Component\Finder COM_FINDER controller.php diff --git a/administrator/components/com_finder/models/forms/filter.xml b/administrator/components/com_finder/forms/filter.xml similarity index 81% rename from administrator/components/com_finder/models/forms/filter.xml rename to administrator/components/com_finder/forms/filter.xml index f281aa884712c..ad6e20d8ce1bf 100644 --- a/administrator/components/com_finder/models/forms/filter.xml +++ b/administrator/components/com_finder/forms/filter.xml @@ -5,7 +5,6 @@ name="filter_id" type="text" label="JGLOBAL_FIELD_ID_LABEL" - description="JGLOBAL_FIELD_ID_DESC" class="readonly" size="10" default="0" @@ -16,7 +15,6 @@ name="title" type="text" label="JGLOBAL_TITLE" - description="COM_FINDER_FILTER_TITLE_DESCRIPTION" class="input-xxlarge input-large-text" size="40" id="title" @@ -27,7 +25,6 @@ name="alias" type="text" label="JFIELD_ALIAS_LABEL" - description="JFIELD_ALIAS_DESC" hint="JFIELD_ALIAS_PLACEHOLDER" size="45" /> @@ -36,7 +33,6 @@ name="created" type="calendar" label="JGLOBAL_FIELD_CREATED_LABEL" - description="JGLOBAL_FIELD_CREATED_DESC" translateformat="true" showtime="true" size="22" @@ -47,7 +43,6 @@ name="modified" type="calendar" label="JGLOBAL_FIELD_MODIFIED_LABEL" - description="COM_FINDER_FIELD_MODIFIED_DESCRIPTION" class="readonly" translateformat="true" showtime="true" @@ -60,14 +55,12 @@ name="created_by" type="user" label="COM_FINDER_FIELD_CREATED_BY_LABEL" - description="COM_FINDER_FIELD_CREATED_BY_DESC" /> @@ -96,8 +89,7 @@ name="state" type="list" label="JSTATUS" - description="JFIELD_PUBLISHED_DESC" - class="chzn-color-state" + class="custom-select-color-state" filter="intval" size="1" default="1" @@ -110,7 +102,6 @@ name="map_count" type="text" label="COM_FINDER_FILTER_MAP_COUNT" - description="COM_FINDER_FILTER_MAP_COUNT_DESCRIPTION" class="readonly" size="10" default="0" @@ -124,7 +115,6 @@ name="w1" type="list" label="COM_FINDER_FILTER_WHEN_START_DATE_LABEL" - description="COM_FINDER_FILTER_WHEN_START_DATE_DESCRIPTION" default="" filter="string" > @@ -138,7 +128,6 @@ name="d1" type="calendar" label="COM_FINDER_FILTER_START_DATE_LABEL" - description="COM_FINDER_FILTER_START_DATE_DESCRIPTION" translateformat="true" size="22" filter="user_utc" @@ -148,7 +137,6 @@ name="w2" type="list" label="COM_FINDER_FILTER_WHEN_END_DATE_LABEL" - description="COM_FINDER_FILTER_WHEN_END_DATE_DESCRIPTION" default="" filter="string" > @@ -162,7 +150,6 @@ name="d2" type="calendar" label="COM_FINDER_FILTER_END_DATE_LABEL" - description="COM_FINDER_FILTER_END_DATE_DESCRIPTION" translateformat="true" size="22" filter="user_utc" diff --git a/administrator/components/com_finder/models/forms/filter_filters.xml b/administrator/components/com_finder/forms/filter_filters.xml similarity index 93% rename from administrator/components/com_finder/models/forms/filter_filters.xml rename to administrator/components/com_finder/forms/filter_filters.xml index f5ea1528f992b..d454c7a301bc8 100644 --- a/administrator/components/com_finder/models/forms/filter_filters.xml +++ b/administrator/components/com_finder/forms/filter_filters.xml @@ -12,8 +12,6 @@ @@ -46,7 +44,6 @@ diff --git a/administrator/components/com_finder/models/forms/filter_index.xml b/administrator/components/com_finder/forms/filter_index.xml similarity index 83% rename from administrator/components/com_finder/models/forms/filter_index.xml rename to administrator/components/com_finder/forms/filter_index.xml index 0e38017706479..db720c45ca8b1 100644 --- a/administrator/components/com_finder/models/forms/filter_index.xml +++ b/administrator/components/com_finder/forms/filter_index.xml @@ -1,5 +1,5 @@ -
+ @@ -22,9 +20,7 @@ @@ -32,9 +28,7 @@ @@ -64,7 +58,6 @@ diff --git a/administrator/components/com_finder/models/forms/filter_maps.xml b/administrator/components/com_finder/forms/filter_maps.xml similarity index 86% rename from administrator/components/com_finder/models/forms/filter_maps.xml rename to administrator/components/com_finder/forms/filter_maps.xml index 312d66aa9a85e..28a6f5430441b 100644 --- a/administrator/components/com_finder/models/forms/filter_maps.xml +++ b/administrator/components/com_finder/forms/filter_maps.xml @@ -1,5 +1,5 @@ - + @@ -30,8 +28,6 @@ diff --git a/administrator/components/com_finder/forms/filter_searches.xml b/administrator/components/com_finder/forms/filter_searches.xml new file mode 100644 index 0000000000000..c3a4c1caf1418 --- /dev/null +++ b/administrator/components/com_finder/forms/filter_searches.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_finder/helpers/finder.php b/administrator/components/com_finder/helpers/finder.php deleted file mode 100644 index 07b6c82ed409c..0000000000000 --- a/administrator/components/com_finder/helpers/finder.php +++ /dev/null @@ -1,111 +0,0 @@ -getQuery(true) - ->select($db->quoteName('extension_id')) - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('folder') . ' = ' . $db->quote('content')) - ->where($db->quoteName('element') . ' = ' . $db->quote('finder')); - $db->setQuery($query); - - try - { - $result = (int) $db->loadResult(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - return $result; - } - - /** - * Gets a list of the actions that can be performed. - * - * @return JObject A JObject containing the allowed actions. - * - * @since 2.5 - * @deprecated 3.2 Use JHelperContent::getActions() instead - */ - public static function getActions() - { - // Log usage of deprecated function - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Get list of actions - return JHelperContent::getActions('com_finder'); - } -} diff --git a/administrator/components/com_finder/helpers/html/finder.php b/administrator/components/com_finder/helpers/html/finder.php index 6995cd42890e9..b04ba0b14ac95 100644 --- a/administrator/components/com_finder/helpers/html/finder.php +++ b/administrator/components/com_finder/helpers/html/finder.php @@ -9,7 +9,7 @@ defined('_JEXEC') or die; -JLoader::register('FinderHelperLanguage', JPATH_ADMINISTRATOR . '/components/com_finder/helpers/language.php'); +use Joomla\Component\Finder\Administrator\Helper\FinderHelperLanguage; use Joomla\Utilities\ArrayHelper; @@ -85,7 +85,7 @@ public static function mapslist() } catch (RuntimeException $e) { - JError::raiseWarning(500, $db->getMessage()); + JFactory::getApplication()->enqueueMessage($db->getMessage(), 'error'); } // Translate. diff --git a/administrator/components/com_finder/helpers/indexer/driver/mysql.php b/administrator/components/com_finder/helpers/indexer/driver/mysql.php index c91c1295e24a9..e970fe85b4ca3 100644 --- a/administrator/components/com_finder/helpers/indexer/driver/mysql.php +++ b/administrator/components/com_finder/helpers/indexer/driver/mysql.php @@ -9,8 +9,6 @@ defined('_JEXEC') or die; -jimport('joomla.filesystem.file'); - /** * Indexer class supporting MySQL(i) for the Finder indexer package. * @@ -78,15 +76,12 @@ public function index($item, $format = 'html') */ if (!$isNew) { - for ($i = 0; $i <= 15; $i++) - { - // Flush the maps for the link. - $query->clear() - ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) - ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); - $db->setQuery($query); - $db->execute(); - } + // Flush the maps for the link. + $query->clear() + ->delete($db->quoteName('#__finder_links_terms')) + ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); + $db->setQuery($query); + $db->execute(); // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); @@ -288,8 +283,7 @@ public function index($item, $format = 'html') */ $query = 'INSERT INTO ' . $db->quoteName('#__finder_tokens_aggregate') . ' (' . $db->quoteName('term_id') . - ', ' . $db->quoteName('map_suffix') . - ', ' . $db->quoteName('term') . + ', ' . $db->quoteName('term') . ', ' . $db->quoteName('stem') . ', ' . $db->quoteName('common') . ', ' . $db->quoteName('phrase') . @@ -299,7 +293,7 @@ public function index($item, $format = 'html') ', ' . $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,' . + ' 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' . @@ -377,50 +371,25 @@ public function index($item, $format = 'html') // Mark afterTerms in the profiler. static::$profiler ? static::$profiler->mark('afterTerms') : null; - /* - * Before we can insert all of the mapping rows, we have to figure out - * which mapping table the rows need to be inserted into. The mapping - * table for each term is based on the first character of the md5 of - * the first character of the term. In php, it would be expressed as - * substr(md5(substr($token, 0, 1)), 0, 1) - */ - $query->clear() - ->update($db->quoteName('#__finder_tokens_aggregate')) - ->set($db->quoteName('map_suffix') . ' = SUBSTR(MD5(SUBSTR(' . $db->quoteName('term') . ', 1, 1)), 1, 1)'); - $db->setQuery($query); - $db->execute(); - /* * At this point, the aggregate table contains a record for each * term in each context. So, we're going to pull down all of that * data while grouping the records by term and add all of the * sub-totals together to arrive at the final total for each token for - * this link. Then, we insert all of that data into the appropriate - * mapping table. + * this link. Then, we insert all of that data into the mapping table. */ - for ($i = 0; $i <= 15; $i++) - { - // Get the mapping table suffix. - $suffix = dechex($i); - - /* - * We have to run this query 16 times, one for each link => term - * mapping table. - */ - $db->setQuery( - 'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) . - ' (' . $db->quoteName('link_id') . - ', ' . $db->quoteName('term_id') . - ', ' . $db->quoteName('weight') . ')' . - ' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' . - ' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' . - ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . - ' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) . - ' GROUP BY ' . $db->quoteName('term') . ', ' . $db->quoteName('term_id') . - ' ORDER BY ' . $db->quoteName('term') . ' DESC' - ); - $db->execute(); - } + $db->setQuery( + 'INSERT INTO ' . $db->quoteName('#__finder_links_terms') . + ' (' . $db->quoteName('link_id') . + ', ' . $db->quoteName('term_id') . + ', ' . $db->quoteName('weight') . ')' . + ' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' . + ' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' . + ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . + ' GROUP BY ' . $db->quoteName('term') . ', ' . $db->quoteName('term_id') . + ' ORDER BY ' . $db->quoteName('term') . ' DESC' + ); + $db->execute(); // Mark afterMapping in the profiler. static::$profiler ? static::$profiler->mark('afterMapping') : null; @@ -476,12 +445,9 @@ public function optimize() $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links')); $db->execute(); - for ($i = 0; $i <= 15; $i++) - { - // Optimize the terms mapping table. - $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links_terms' . dechex($i))); - $db->execute(); - } + // Optimize the terms mapping table. + $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_links_terms')); + $db->execute(); // Optimize the filters table. $db->setQuery('OPTIMIZE TABLE ' . $db->quoteName('#__finder_filters')); diff --git a/administrator/components/com_finder/helpers/indexer/driver/postgresql.php b/administrator/components/com_finder/helpers/indexer/driver/postgresql.php index cc3a32055eba9..adcbe727c6daa 100644 --- a/administrator/components/com_finder/helpers/indexer/driver/postgresql.php +++ b/administrator/components/com_finder/helpers/indexer/driver/postgresql.php @@ -9,8 +9,6 @@ defined('_JEXEC') or die; -jimport('joomla.filesystem.file'); - /** * Indexer class supporting PostgreSQL for the Finder indexer package. * @@ -51,7 +49,7 @@ public function index($item, $format = 'html') // Get the signatures of the item. $curSig = static::getSignature($item); - $oldSig = isset($link->md5sum) ? $link->md5sum : null; + $oldSig = $link->md5sum ?? null; // Get the other item information. $linkId = empty($link->link_id) ? null : $link->link_id; @@ -70,15 +68,12 @@ public function index($item, $format = 'html') */ if (!$isNew) { - for ($i = 0; $i <= 15; $i++) - { - // Flush the maps for the link. - $query->clear() - ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) - ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); - $db->setQuery($query); - $db->execute(); - } + // Flush the maps for the link. + $query->clear() + ->delete($db->quoteName('#__finder_links_terms')) + ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); + $db->setQuery($query); + $db->execute(); // Remove the taxonomy maps. FinderIndexerTaxonomy::removeMaps($linkId); @@ -378,19 +373,6 @@ public function index($item, $format = 'html') // Mark afterTerms in the profiler. static::$profiler ? static::$profiler->mark('afterTerms') : null; - /* - * Before we can insert all of the mapping rows, we have to figure out - * which mapping table the rows need to be inserted into. The mapping - * table for each term is based on the first character of the md5 of - * the first character of the term. In php, it would be expressed as - * substr(md5(substr($token, 0, 1)), 0, 1) - */ - $query->clear() - ->update($db->quoteName('#__finder_tokens_aggregate')) - ->set($db->quoteName('map_suffix') . ' = SUBSTR(MD5(SUBSTR(' . $db->quoteName('term') . ', 1, 1)), 1, 1)'); - $db->setQuery($query); - $db->execute(); - /* * At this point, the aggregate table contains a record for each * term in each context. So, we're going to pull down all of that @@ -399,29 +381,18 @@ public function index($item, $format = 'html') * this link. Then, we insert all of that data into the appropriate * mapping table. */ - for ($i = 0; $i <= 15; $i++) - { - // Get the mapping table suffix. - $suffix = dechex($i); - - /* - * We have to run this query 16 times, one for each link => term - * mapping table. - */ - $db->setQuery( - 'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) . - ' (' . $db->quoteName('link_id') . - ', ' . $db->quoteName('term_id') . - ', ' . $db->quoteName('weight') . ')' . - ' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' . - ' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' . - ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . - ' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) . - ' GROUP BY ' . $db->quoteName('term') . ', ' . $db->quoteName('term_id') . - ' ORDER BY ' . $db->quoteName('term') . ' DESC' - ); - $db->execute(); - } + $db->setQuery( + 'INSERT INTO ' . $db->quoteName('#__finder_links_terms') . + ' (' . $db->quoteName('link_id') . + ', ' . $db->quoteName('term_id') . + ', ' . $db->quoteName('weight') . ')' . + ' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' . + ' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' . + ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . + ' GROUP BY ' . $db->quoteName('term') . ', ' . $db->quoteName('term_id') . + ' ORDER BY ' . $db->quoteName('term') . ' DESC' + ); + $db->execute(); // Mark afterMapping in the profiler. static::$profiler ? static::$profiler->mark('afterMapping') : null; @@ -479,14 +450,11 @@ public function optimize() $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_links')); $db->execute(); - for ($i = 0; $i <= 15; $i++) - { - // Optimize the terms mapping table. - $db->setQuery('VACUUM ' . $db->quoteName('#__finder_links_terms' . dechex($i))); - $db->execute(); - $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_links_terms' . dechex($i))); - $db->execute(); - } + // Optimize the terms mapping table. + $db->setQuery('VACUUM ' . $db->quoteName('#__finder_links_terms')); + $db->execute(); + $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_links_terms')); + $db->execute(); // Optimize the filters table. $db->setQuery('REINDEX TABLE ' . $db->quoteName('#__finder_filters')); diff --git a/administrator/components/com_finder/helpers/indexer/driver/sqlsrv.php b/administrator/components/com_finder/helpers/indexer/driver/sqlsrv.php deleted file mode 100644 index dd975dc1e9470..0000000000000 --- a/administrator/components/com_finder/helpers/indexer/driver/sqlsrv.php +++ /dev/null @@ -1,531 +0,0 @@ -mark('beforeIndexing') : null; - $db = $this->db; - $nd = $db->getNullDate(); - - // Check if the item is in the database. - $query = $db->getQuery(true) - ->select($db->quoteName('link_id') . ', ' . $db->quoteName('md5sum')) - ->from($db->quoteName('#__finder_links')) - ->where($db->quoteName('url') . ' = ' . $db->quote($item->url)); - - // Load the item from the database. - $db->setQuery($query); - $link = $db->loadObject(); - - // Get the indexer state. - $state = static::getState(); - - // Get the signatures of the item. - $curSig = static::getSignature($item); - $oldSig = isset($link->md5sum) ? $link->md5sum : null; - - // Get the other item information. - $linkId = empty($link->link_id) ? null : $link->link_id; - $isNew = empty($link->link_id) ? true : false; - - // Check the signatures. If they match, the item is up to date. - if (!$isNew && $curSig == $oldSig) - { - return $linkId; - } - - /* - * If the link already exists, flush all the term maps for the item. - * Maps are stored in 16 tables so we need to iterate through and flush - * each table one at a time. - */ - if (!$isNew) - { - for ($i = 0; $i <= 15; $i++) - { - // Flush the maps for the link. - $query->clear() - ->delete($db->quoteName('#__finder_links_terms' . dechex($i))) - ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); - $db->setQuery($query); - $db->execute(); - } - - // Remove the taxonomy maps. - FinderIndexerTaxonomy::removeMaps($linkId); - } - - // Mark afterUnmapping in the profiler. - static::$profiler ? static::$profiler->mark('afterUnmapping') : null; - - // Perform cleanup on the item data. - $item->publish_start_date = (int) $item->publish_start_date != 0 ? $item->publish_start_date : $nd; - $item->publish_end_date = (int) $item->publish_end_date != 0 ? $item->publish_end_date : $nd; - $item->start_date = (int) $item->start_date != 0 ? $item->start_date : $nd; - $item->end_date = (int) $item->end_date != 0 ? $item->end_date : $nd; - - // Prepare the item description. - $item->description = FinderIndexerHelper::parse($item->summary); - - /* - * Now, we need to enter the item into the links table. If the item - * already exists in the database, we need to use an UPDATE query. - * Otherwise, we need to use an INSERT to get the link id back. - */ - - 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 ?: 0) . ', ' - . (double) ($item->sale_price ?: 0) - ); - $db->setQuery($query); - $db->execute(); - - // Get the link id. - $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 ?: 0)) - ->set($db->quoteName('sale_price') . ' = ' . (double) ($item->sale_price ?: 0)) - ->where('link_id = ' . (int) $linkId); - $db->setQuery($query); - $db->execute(); - } - - // Set up the variables we will need during processing. - $count = 0; - - // Mark afterLinking in the profiler. - static::$profiler ? static::$profiler->mark('afterLinking') : null; - - // Truncate the tokens tables. - $db->truncateTable('#__finder_tokens'); - - // Truncate the tokens aggregate table. - $db->truncateTable('#__finder_tokens_aggregate'); - - /* - * Process the item's content. The items can customize their - * processing instructions to define extra properties to process - * or rearrange how properties are weighted. - */ - foreach ($item->getInstructions() as $group => $properties) - { - // Iterate through the properties of the group. - foreach ($properties as $property) - { - // Check if the property exists in the item. - if (empty($item->$property)) - { - continue; - } - - // Tokenize the property. - if (is_array($item->$property)) - { - // Tokenize an array of content and add it to the database. - foreach ($item->$property as $ip) - { - /* - * If the group is path, we need to a few extra processing - * steps to strip the extension and convert slashes and dashes - * to spaces. - */ - if ($group === static::PATH_CONTEXT) - { - $ip = JFile::stripExt($ip); - $ip = str_replace('/', ' ', $ip); - $ip = str_replace('-', ' ', $ip); - } - - // Tokenize a string of content and add it to the database. - $count += $this->tokenizeToDb($ip, $group, $item->language, $format); - - // Check if we're approaching the memory limit of the token table. - if ($count > static::$state->options->get('memory_table_limit', 30000)) - { - $this->toggleTables(false); - } - } - } - else - { - /* - * If the group is path, we need to a few extra processing - * steps to strip the extension and convert slashes and dashes - * to spaces. - */ - if ($group === static::PATH_CONTEXT) - { - $item->$property = JFile::stripExt($item->$property); - $item->$property = str_replace('/', ' ', $item->$property); - $item->$property = str_replace('-', ' ', $item->$property); - } - - // Tokenize a string of content and add it to the database. - $count += $this->tokenizeToDb($item->$property, $group, $item->language, $format); - - // Check if we're approaching the memory limit of the token table. - if ($count > static::$state->options->get('memory_table_limit', 30000)) - { - $this->toggleTables(false); - } - } - } - } - - /* - * Process the item's taxonomy. The items can customize their - * taxonomy mappings to define extra properties to map. - */ - foreach ($item->getTaxonomy() as $branch => $nodes) - { - // Iterate through the nodes and map them to the branch. - foreach ($nodes as $node) - { - // Add the node to the tree. - $nodeId = FinderIndexerTaxonomy::addNode($branch, $node->title, $node->state, $node->access); - - // 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); - } - } - - // Mark afterProcessing in the profiler. - static::$profiler ? static::$profiler->mark('afterProcessing') : null; - - /* - * At this point, all of the item's content has been parsed, tokenized - * and inserted into the #__finder_tokens table. Now, we need to - * aggregate all the data into that table into a more usable form. The - * aggregated data will be inserted into #__finder_tokens_aggregate - * 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' . - ' 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) - { - // Run the query to aggregate the tokens for this context.. - $db->setQuery(sprintf($query, $multiplier, $context, $context)); - $db->execute(); - } - - // Mark afterAggregating in the profiler. - static::$profiler ? static::$profiler->mark('afterAggregating') : null; - - /* - * When we pulled down all of the aggregate data, we did a LEFT JOIN - * over the terms table to try to find all the term ids that - * already exist for our tokens. If any of the rows in the aggregate - * table have a term of 0, then no term record exists for that - * term so we need to add it to the terms table. - */ - $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') . ')' . - ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term)' . - ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . ' AS ta' . - ' WHERE ta.term_id IS NULL' . - ' GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight' - ); - $db->execute(); - - /* - * Now, we just inserted a bunch of new records into the terms table - * so we need to go back and update the aggregate table with all the - * new term ids. - */ - $query = $db->getQuery(true) - ->update('ta') - ->set('ta.term_id = t.term_id from #__finder_tokens_aggregate AS ta INNER JOIN #__finder_terms AS t ON t.term = ta.term') - ->where('ta.term_id IS NULL'); - $db->setQuery($query); - $db->execute(); - - // Mark afterTerms in the profiler. - static::$profiler ? static::$profiler->mark('afterTerms') : null; - - /* - * After we've made sure that all of the terms are in the terms table - * and the aggregate table has the correct term ids, we need to update - * the links counter for each term by one. - */ - $query->clear() - ->update('t') - ->set('t.links = t.links + 1 FROM #__finder_terms AS t INNER JOIN #__finder_tokens_aggregate AS ta ON ta.term_id = t.term_id'); - $db->setQuery($query); - $db->execute(); - - // Mark afterTerms in the profiler. - static::$profiler ? static::$profiler->mark('afterTerms') : null; - - /* - * Before we can insert all of the mapping rows, we have to figure out - * which mapping table the rows need to be inserted into. The mapping - * table for each term is based on the first character of the md5 of - * the first character of the term. In php, it would be expressed as - * substr(md5(substr($token, 0, 1)), 0, 1) - */ - $query->clear() - ->update($db->quoteName('#__finder_tokens_aggregate')) - ->set($db->quoteName('map_suffix') . " = SUBSTRING(HASHBYTES('MD5', SUBSTRING(" . $db->quoteName('term') . ', 1, 1)), 1, 1)'); - $db->setQuery($query); - $db->execute(); - - /* - * At this point, the aggregate table contains a record for each - * term in each context. So, we're going to pull down all of that - * data while grouping the records by term and add all of the - * sub-totals together to arrive at the final total for each token for - * this link. Then, we insert all of that data into the appropriate - * mapping table. - */ - for ($i = 0; $i <= 15; $i++) - { - // Get the mapping table suffix. - $suffix = dechex($i); - - /* - * We have to run this query 16 times, one for each link => term - * mapping table. - */ - $db->setQuery( - 'INSERT INTO ' . $db->quoteName('#__finder_links_terms' . $suffix) . - ' (' . $db->quoteName('link_id') . - ', ' . $db->quoteName('term_id') . - ', ' . $db->quoteName('weight') . ')' . - ' SELECT ' . (int) $linkId . ', ' . $db->quoteName('term_id') . ',' . - ' ROUND(SUM(' . $db->quoteName('context_weight') . '), 8)' . - ' FROM ' . $db->quoteName('#__finder_tokens_aggregate') . - ' WHERE ' . $db->quoteName('map_suffix') . ' = ' . $db->quote($suffix) . - ' GROUP BY term, term_id' . - ' ORDER BY ' . $db->quoteName('term') . ' DESC' - ); - $db->execute(); - } - - // Mark afterMapping in the profiler. - static::$profiler ? static::$profiler->mark('afterMapping') : null; - - // Update the signature. - $query->clear() - ->update($db->quoteName('#__finder_links')) - ->set($db->quoteName('md5sum') . ' = ' . $db->quote($curSig)) - ->where($db->quoteName('link_id') . ' = ' . $db->quote($linkId)); - $db->setQuery($query); - $db->execute(); - - // Mark afterSigning in the profiler. - static::$profiler ? static::$profiler->mark('afterSigning') : null; - - // Truncate the tokens tables. - $db->truncateTable('#__finder_tokens'); - - // Truncate the tokens aggregate table. - $db->truncateTable('#__finder_tokens_aggregate'); - - // Toggle the token tables back to memory tables. - $this->toggleTables(true); - - // Mark afterTruncating in the profiler. - static::$profiler ? static::$profiler->mark('afterTruncating') : null; - - return $linkId; - } - - /** - * Method to remove a link from the index. - * - * @param integer $linkId The id of the link. - * - * @return boolean True on success. - * - * @since 3.1 - * @throws Exception on database error. - */ - 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->update('t') - ->set('t.links = t.links - 1 from #__finder_terms AS t INNER JOIN #__finder_links_terms' . dechex($i) . ' AS m ON m.term_id = t.term_id') - ->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. - * - * @return boolean True on success. - * - * @since 3.1 - * @throws Exception on database error. - */ - public function optimize() - { - // Get the database object. - $db = $this->db; - $query = $db->getQuery(true); - - // Delete all orphaned terms. - $query->delete($db->quoteName('#__finder_terms')) - ->where($db->quoteName('links') . ' <= 0'); - $db->setQuery($query); - $db->execute(); - - // Remove the orphaned taxonomy nodes. - FinderIndexerTaxonomy::removeOrphanNodes(); - - return true; - } -} diff --git a/administrator/components/com_finder/helpers/indexer/helper.php b/administrator/components/com_finder/helpers/indexer/helper.php index 759468052f40b..3460a10349066 100644 --- a/administrator/components/com_finder/helpers/indexer/helper.php +++ b/administrator/components/com_finder/helpers/indexer/helper.php @@ -9,11 +9,14 @@ defined('_JEXEC') or die; +use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Router\Router; +use Joomla\CMS\Language\Multilanguage; use Joomla\Registry\Registry; use Joomla\String\StringHelper; +JLoader::register('FinderIndexerLanguage', __DIR__ . '/language.php'); JLoader::register('FinderIndexerParser', __DIR__ . '/parser.php'); -JLoader::register('FinderIndexerStemmer', __DIR__ . '/stemmer.php'); JLoader::register('FinderIndexerToken', __DIR__ . '/token.php'); /** @@ -23,23 +26,6 @@ */ class FinderIndexerHelper { - /** - * The token stemmer object. The stemmer is set by whatever class - * wishes to use it but it must be an instance of FinderIndexerStemmer. - * - * @var FinderIndexerStemmer - * @since 2.5 - */ - public static $stemmer; - - /** - * A state flag, in order to not constantly check if the stemmer is an instance of FinderIndexerStemmer - * - * @var boolean - * @since 3.7.0 - */ - protected static $stemmerOK; - /** * Method to parse input into plain text. * @@ -70,83 +56,64 @@ public static function parse($input, $format = 'html') */ public static function tokenize($input, $lang, $phrase = false) { - static $cache; - $store = StringHelper::strlen($input) < 128 ? md5($input . '::' . $lang . '::' . $phrase) : null; + static $cache, $tuplecount; + static $multilingual; + static $defaultLanguage; + + $store = md5($input . '::' . $lang . '::' . $phrase); // Check if the string has been tokenized already. - if ($store && isset($cache[$store])) + if (isset($cache[$store])) { return $cache[$store]; } - $tokens = array(); - $quotes = html_entity_decode('‘’'', ENT_QUOTES, 'UTF-8'); - - // Get the simple language key. - $lang = static::getPrimaryLanguage($lang); - - /* - * Parsing the string input into terms is a multi-step process. - * - * Regexes: - * 1. Remove everything except letters, numbers, quotes, apostrophe, plus, dash, period, and comma. - * 2. Remove plus, dash, period, and comma characters located before letter characters. - * 3. Remove plus, dash, period, and comma characters located after other characters. - * 4. Remove plus, period, and comma characters enclosed in alphabetical characters. Ungreedy. - * 5. Remove orphaned apostrophe, plus, dash, period, and comma characters. - * 6. Remove orphaned quote characters. - * 7. Replace the assorted single quotation marks with the ASCII standard single quotation. - * 8. Remove multiple space characters and replaces with a single space. - */ - $input = StringHelper::strtolower($input); - $input = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,]+#mui', ' ', $input); - $input = preg_replace('#(^|\s)[+-.,]+([\pL\pM]+)#mui', ' $1', $input); - $input = preg_replace('#([\pL\pM\pN]+)[+-.,]+(\s|$)#mui', '$1 ', $input); - $input = preg_replace('#([\pL\pM]+)[+.,]+([\pL\pM]+)#muiU', '$1 $2', $input); - $input = preg_replace('#(^|\s)[\'+-.,]+(\s|$)#mui', ' ', $input); - $input = preg_replace('#(^|\s)[\p{Pi}\p{Pf}]+(\s|$)#mui', ' ', $input); - $input = preg_replace('#[' . $quotes . ']+#mui', '\'', $input); - $input = preg_replace('#\s+#mui', ' ', $input); - $input = trim($input); - - // Explode the normalized string to get the terms. - $terms = explode(' ', $input); - - /* - * If we have Unicode support and are dealing with Chinese text, Chinese - * has to be handled specially because there are not necessarily any spaces - * between the "words". So, we have to test if the words belong to the Chinese - * character set and if so, explode them into single glyphs or "words". - */ - if ($lang === 'zh') + if (!$tuplecount) { - // Iterate through the terms and test if they contain Chinese. - for ($i = 0, $n = count($terms); $i < $n; $i++) - { - $charMatches = array(); - $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); + $params = ComponentHelper::getParams('com_finder'); + $tuplecount = $params->get('tuplecount', 1); + } - if (!empty($tSplit)) - { - $terms[$i] = $tSplit; - } - else - { - unset($terms[$i]); - } + if (is_null($multilingual)) + { + $multilingual = Multilanguage::isEnabled(); + $config = ComponentHelper::getParams('com_finder'); - $terms[] = $charMatches[0][$j]; - } + if ($config->get('language_default', '') == '') + { + $defaultLang = '*'; + } + elseif ($config->get('language_default', '') == '-1') + { + $defaultLang = self::getDefaultLanguage(); + } + else + { + $defaultLang = $config->get('language_default'); } - // Reset array keys. - $terms = array_values($terms); + /* + * The default language always has the language code '*'. + * In order to not overwrite the language code of the language + * object that we are using, we are cloning it here. + */ + $obj = FinderIndexerLanguage::getInstance($defaultLang); + $defaultLanguage = clone $obj; + $defaultLanguage->language = '*'; + } + + if (!$multilingual || $lang == '*') + { + $language = $defaultLanguage; } + else + { + $language = FinderIndexerLanguage::getInstance($lang); + } + + $tokens = array(); + $terms = $language->tokenise($input); + $terms = array_filter($terms); /* * If we have to handle the input as a phrase, that means we don't @@ -156,63 +123,49 @@ public static function tokenize($input, $lang, $phrase = false) if ($phrase === true && count($terms) > 1) { // Create tokens from the phrase. - $tokens[] = new FinderIndexerToken($terms, $lang); + $tokens[] = new FinderIndexerToken($terms, $language->language, $language->spacer); } else { // Create tokens from the terms. for ($i = 0, $n = count($terms); $i < $n; $i++) { - $tokens[] = new FinderIndexerToken($terms[$i], $lang); + $tokens[] = new FinderIndexerToken($terms[$i], $language->language); } - // Create two and three word phrase tokens from the individual words. - for ($i = 0, $n = count($tokens); $i < $n; $i++) + // Create multi-word phrase tokens from the individual words. + if ($tuplecount > 1) { - // Setup the phrase positions. - $i2 = $i + 1; - $i3 = $i + 2; - - // Create the two word phrase. - if ($i2 < $n && isset($tokens[$i2])) + for ($i = 0, $n = count($tokens); $i < $n; $i++) { - // Tokenize the two word phrase. - $token = new FinderIndexerToken(array($tokens[$i]->term, $tokens[$i2]->term), $lang, $lang === 'zh' ? '' : ' '); - $token->derived = true; + $temp = array($tokens[$i]->term); - // Add the token to the stack. - $tokens[] = $token; - } + // Create tokens for 2 to $tuplecount length phrases + for ($j = 1; $j < $tuplecount; $j++) + { + if ($i + $j >= $n || !isset($tokens[$i + $j])) + { + break; + } - // Create the three word phrase. - 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->derived = true; + $temp[] = $tokens[$i + $j]->term; + $token = new FinderIndexerToken($temp, $language->language, $language->spacer); + $token->derived = true; - // Add the token to the stack. - $tokens[] = $token; + // Add the token to the stack. + $tokens[] = $token; + } } } } - if ($store) - { - $cache[$store] = count($tokens) > 1 ? $tokens : array_shift($tokens); + $cache[$store] = $tokens; - return $cache[$store]; - } - else - { - return count($tokens) > 1 ? $tokens : array_shift($tokens); - } + return $cache[$store]; } /** - * Method to get the base word of a token. This method uses the public - * {@link FinderIndexerHelper::$stemmer} object if it is set. If no stemmer is set, - * the original token is returned. + * Method to get the base word of a token. * * @param string $token The token to stem. * @param string $lang The language of the token. @@ -223,31 +176,38 @@ public static function tokenize($input, $lang, $phrase = false) */ public static function stem($token, $lang) { - // Trim apostrophes at either end of the token. - $token = trim($token, '\''); + static $multilingual; + static $defaultStemmer; - // Trim everything after any apostrophe in the token. - if ($res = explode('\'', $token)) + if (is_null($multilingual)) { - $token = $res[0]; + $multilingual = Multilanguage::isEnabled(); + $config = ComponentHelper::getParams('com_finder'); + + if ($config->get('language_default', '') == '') + { + $defaultStemmer = FinderIndexerLanguage::getInstance('*'); + } + elseif ($config->get('language_default', '') == '-1') + { + $defaultStemmer = FinderIndexerLanguage::getInstance(self::getDefaultLanguage()); + } + else + { + $defaultStemmer = FinderIndexerLanguage::getInstance($config->get('language_default')); + } } - if (static::$stemmerOK === true) + if (!$multilingual || $lang == '*') { - return static::$stemmer->stem($token, $lang); + $language = $defaultStemmer; } else { - // Stem the token if we have a valid stemmer to use. - if (static::$stemmer instanceof FinderIndexerStemmer) - { - static::$stemmerOK = true; - - return static::$stemmer->stem($token, $lang); - } + $language = FinderIndexerLanguage::getInstance($lang); } - return $token; + return $language->stem($token); } /** @@ -372,7 +332,7 @@ public static function getDefaultLanguage() // We need to go to com_languages to get the site default language, it's the best we can guess. if (empty($lang)) { - $lang = JComponentHelper::getParams('com_languages')->get('site', 'en-GB'); + $lang = ComponentHelper::getParams('com_languages')->get('site', 'en-GB'); } return $lang; @@ -409,36 +369,6 @@ public static function getPrimaryLanguage($lang) return $data[$lang]; } - /** - * Method to get the path (SEF route) for a content item. - * - * @param string $url The non-SEF route to the content item. - * - * @return string The path for the content item. - * - * @since 2.5 - */ - public static function getContentPath($url) - { - static $router; - - // Only get the router once. - if (!($router instanceof JRouter)) - { - // Get and configure the site router. - $config = JFactory::getConfig(); - $router = JRouter::getInstance('site'); - $router->setMode($config->get('sef', 1)); - } - - // Build the relative route. - $uri = $router->build($url); - $route = $uri->toString(array('path', 'query', 'fragment')); - $route = str_replace(JUri::base(true) . '/', '', $route); - - return $route; - } - /** * 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. @@ -452,21 +382,10 @@ public static function getContentPath($url) */ public static function getContentExtras(FinderIndexerResult &$item) { - // Get the event dispatcher. - $dispatcher = JEventDispatcher::getInstance(); - // Load the finder plugin group. JPluginHelper::importPlugin('finder'); - // Trigger the event. - $results = $dispatcher->trigger('onPrepareFinderContent', array(&$item)); - - // Check the returned results. This is for plugins that don't throw - // exceptions when they encounter serious errors. - if (in_array(false, $results)) - { - throw new Exception($dispatcher->getError(), 500); - } + JFactory::getApplication()->triggerEvent('onPrepareFinderContent', array(&$item)); return true; } @@ -486,9 +405,6 @@ public static function prepareContent($text, $params = null, FinderIndexerResult { static $loaded; - // Get the dispatcher. - $dispatcher = JEventDispatcher::getInstance(); - // Load the content plugins if necessary. if (empty($loaded)) { @@ -519,7 +435,7 @@ public static function prepareContent($text, $params = null, FinderIndexerResult } // Fire the onContentPrepare event. - $dispatcher->trigger('onContentPrepare', array('com_finder.indexer', &$content, &$params, 0)); + JFactory::getApplication()->triggerEvent('onContentPrepare', array('com_finder.indexer', &$content, &$params, 0)); return $content->text; } diff --git a/administrator/components/com_finder/helpers/indexer/indexer.php b/administrator/components/com_finder/helpers/indexer/indexer.php index d532d54cf9ae3..c1498b1b059ec 100644 --- a/administrator/components/com_finder/helpers/indexer/indexer.php +++ b/administrator/components/com_finder/helpers/indexer/indexer.php @@ -12,13 +12,11 @@ use Joomla\String\StringHelper; JLoader::register('FinderIndexerHelper', __DIR__ . '/helper.php'); +JLoader::register('FinderIndexerLanguage', __DIR__ . '/language.php'); JLoader::register('FinderIndexerParser', __DIR__ . '/parser.php'); -JLoader::register('FinderIndexerStemmer', __DIR__ . '/stemmer.php'); JLoader::register('FinderIndexerTaxonomy', __DIR__ . '/taxonomy.php'); JLoader::register('FinderIndexerToken', __DIR__ . '/token.php'); -jimport('joomla.filesystem.file'); - /** * Main indexer class for the Finder indexer package. * @@ -145,12 +143,6 @@ public static function getInstance() // Setup the adapter for the indexer. $serverType = JFactory::getDbo()->getServerType(); - // For `mssql` server types, convert the type to `sqlsrv` - if ($serverType === 'mssql') - { - $serverType = 'sqlsrv'; - } - $path = __DIR__ . '/driver/' . $serverType . '.php'; $class = 'FinderIndexerDriver' . ucfirst($serverType); @@ -219,12 +211,6 @@ public static function getState() static::$profiler = JProfiler::getInstance('FinderIndexer'); } - // Setup the stemmer. - if ($data->options->get('stem', 1) && $data->options->get('stemmer', 'porter_en')) - { - FinderIndexerHelper::$stemmer = FinderIndexerStemmer::getInstance($data->options->get('stemmer', 'porter_en')); - } - // Set the state. static::$state = $data; @@ -301,23 +287,19 @@ 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 m.term_id = t.term_id') - ->set('t.links = t.links - 1') - ->where($db->quoteName('m.link_id') . ' = ' . (int) $linkId); - $db->setQuery($query)->execute(); + // Update the link counts for the terms. + $query->clear() + ->update($db->quoteName('#__finder_terms', 't')) + ->join('INNER', $db->quoteName('#__finder_links_terms', 'm') . ' ON m.term_id = t.term_id') + ->set('t.links = t.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(); - } + // Remove all records from the mapping tables. + $query->clear() + ->delete($db->quoteName('#__finder_links_terms')) + ->where($db->quoteName('link_id') . ' = ' . (int) $linkId); + $db->setQuery($query)->execute(); // Delete all orphaned terms. $query->clear() @@ -481,6 +463,11 @@ private function tokenizeToDbShort($input, $context, $lang, $format, $count) // Tokenize the input. $tokens = FinderIndexerHelper::tokenize($input, $lang); + if (count($tokens) == 0) + { + return $count; + } + // Add the tokens to the database. $count += $this->addTokensToDb($tokens, $context); @@ -532,7 +519,7 @@ protected function addTokensToDb($tokens, $context = '') . $db->quote($token->stem) . ', ' . (int) $token->common . ', ' . (int) $token->phrase . ', ' - . (float) $token->weight . ', ' + . $db->quote($token->weight) . ', ' . (int) $context . ', ' . $db->quote($token->language) ); diff --git a/administrator/components/com_finder/helpers/indexer/language.php b/administrator/components/com_finder/helpers/indexer/language.php new file mode 100644 index 0000000000000..e36f10af4b927 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language.php @@ -0,0 +1,146 @@ +language = $locale; + } + + return $instances[$language]; + } + + /** + * Method to tokenise a text string. + * + * @param string $input The input to tokenise. + * + * @return array An array of term strings. + * + * @since 4.0.0 + */ + public function tokenise($input) + { + $quotes = html_entity_decode('‘’'', ENT_QUOTES, 'UTF-8'); + + /* + * Parsing the string input into terms is a multi-step process. + * + * Regexes: + * 1. Remove everything except letters, numbers, quotes, apostrophe, plus, dash, period, and comma. + * 2. Remove plus, dash, period, and comma characters located before letter characters. + * 3. Remove plus, dash, period, and comma characters located after other characters. + * 4. Remove plus, period, and comma characters enclosed in alphabetical characters. Ungreedy. + * 5. Remove orphaned apostrophe, plus, dash, period, and comma characters. + * 6. Remove orphaned quote characters. + * 7. Replace the assorted single quotation marks with the ASCII standard single quotation. + * 8. Remove multiple space characters and replaces with a single space. + */ + $input = StringHelper::strtolower($input); + $input = preg_replace('#[^\pL\pM\pN\p{Pi}\p{Pf}\'+-.,]+#mui', ' ', $input); + $input = preg_replace('#(^|\s)[+-.,]+([\pL\pM]+)#mui', ' $1', $input); + $input = preg_replace('#([\pL\pM\pN]+)[+-.,]+(\s|$)#mui', '$1 ', $input); + $input = preg_replace('#([\pL\pM]+)[+.,]+([\pL\pM]+)#muiU', '$1 $2', $input); + $input = preg_replace('#(^|\s)[\'+-.,]+(\s|$)#mui', ' ', $input); + $input = preg_replace('#(^|\s)[\p{Pi}\p{Pf}]+(\s|$)#mui', ' ', $input); + $input = preg_replace('#[' . $quotes . ']+#mui', '\'', $input); + $input = preg_replace('#\s+#mui', ' ', $input); + $input = trim($input); + + // Explode the normalized string to get the terms. + $terms = explode(' ', $input); + + return $terms; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $token; + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/da.php b/administrator/components/com_finder/helpers/indexer/language/da.php new file mode 100644 index 0000000000000..5fd74b10ce933 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/da.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\Danish; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/de.php b/administrator/components/com_finder/helpers/indexer/language/de.php new file mode 100644 index 0000000000000..7a8cbed62bbd9 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/de.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\German; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/el.php b/administrator/components/com_finder/helpers/indexer/language/el.php new file mode 100644 index 0000000000000..8fa4ce6b5caf6 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/el.php @@ -0,0 +1,1015 @@ +. This is + * derivative work, based on the Greek stemmer for Drupal, see + * https://github.com/magaras/greek_stemmer/blob/master/mod_stemmer.php + */ + +defined('_JEXEC') or die; + +/** + * Greek language support class for the Finder indexer package. + * + * @since 4.0.0 + */ +class FinderIndexerLanguageel extends FinderIndexerLanguage +{ + /** + * Language locale of the class + * + * @var string + * @since 4.0.0 + */ + public $language = 'el'; + + /** + * Method to tokenise a text string. It takes into account the odd punctuation commonly used in Greek text, mapping + * it to ASCII punctuation. + * + * Reference: http://www.teicrete.gr/users/kutrulis/Glosika/Stixi.htm + * + * @param string $input The input to tokenise. + * + * @return array An array of term strings. + * + * @since 4.0.0 + */ + public function tokenise($input) + { + // Replace Greek calligraphic double quotes (various styles) to dumb double quotes + $input = str_replace(['“', '”', '„', '«' ,'»'], '"', $input); + + // Replace Greek calligraphic single quotes (various styles) to dumb single quotes + $input = str_replace(['‘','’','‚'], "'", $input); + + // Replace the middle dot (ano teleia) with a comma, adequate for the purpose of stemming + $input = str_replace('·', ',', $input); + + // Dot and dash (τελεία και παύλα), used to denote the end of a context at the end of a paragraph. + $input = str_replace('.–', '.', $input); + + // Ellipsis, two styles (separate dots or single glyph) + $input = str_replace(['...', '…'], '.', $input); + + // Cross. Marks the death date of a person. Removed. + $input = str_replace('†', '', $input); + + // Star. Reference, supposition word (in philology), birth date of a person. + $input = str_replace('*', '', $input); + + // Paragraph. Indicates change of subject. + $input = str_replace('§', '.', $input); + + // Plus/minus. Shows approximation. Not relevant for the stemmer, hence its conversion to a space. + $input = str_replace('±', ' ', $input); + + return parent::tokenise($input); + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + $token = $this->toUpperCase($token, $w_CASE); + + // Stop-word removal + $stop_words = '/^(ΕΚΟ|ΑΒΑ|ΑΓΑ|ΑΓΗ|ΑΓΩ|ΑΔΗ|ΑΔΩ|ΑΕ|ΑΕΙ|ΑΘΩ|ΑΙ|ΑΙΚ|ΑΚΗ|ΑΚΟΜΑ|ΑΚΟΜΗ|ΑΚΡΙΒΩΣ|ΑΛΑ|ΑΛΗΘΕΙΑ|ΑΛΗΘΙΝΑ|ΑΛΛΑΧΟΥ|ΑΛΛΙΩΣ|ΑΛΛΙΩΤΙΚΑ|' + . 'ΑΛΛΟΙΩΣ|ΑΛΛΟΙΩΤΙΚΑ|ΑΛΛΟΤΕ|ΑΛΤ|ΑΛΩ|ΑΜΑ|ΑΜΕ|ΑΜΕΣΑ|ΑΜΕΣΩΣ|ΑΜΩ|ΑΝ|ΑΝΑ|ΑΝΑΜΕΣΑ|ΑΝΑΜΕΤΑΞΥ|ΑΝΕΥ|ΑΝΤΙ|ΑΝΤΙΠΕΡΑ|ΑΝΤΙΣ|ΑΝΩ|ΑΝΩΤΕΡΩ|ΑΞΑΦΝΑ|' + . 'ΑΠ|ΑΠΕΝΑΝΤΙ|ΑΠΟ|ΑΠΟΨΕ|ΑΠΩ|ΑΡΑ|ΑΡΑΓΕ|ΑΡΕ|ΑΡΚ|ΑΡΚΕΤΑ|ΑΡΛ|ΑΡΜ|ΑΡΤ|ΑΡΥ|ΑΡΩ|ΑΣ|ΑΣΑ|ΑΣΟ|ΑΤΑ|ΑΤΕ|ΑΤΗ|ΑΤΙ|ΑΤΜ|ΑΤΟ|ΑΥΡΙΟ|ΑΦΗ|ΑΦΟΤΟΥ|ΑΦΟΥ|' + . 'ΑΧ|ΑΧΕ|ΑΧΟ|ΑΨΑ|ΑΨΕ|ΑΨΗ|ΑΨΥ|ΑΩΕ|ΑΩΟ|ΒΑΝ|ΒΑΤ|ΒΑΧ|ΒΕΑ|ΒΕΒΑΙΟΤΑΤΑ|ΒΗΞ|ΒΙΑ|ΒΙΕ|ΒΙΗ|ΒΙΟ|ΒΟΗ|ΒΟΩ|ΒΡΕ|ΓΑ|ΓΑΒ|ΓΑΡ|ΓΕΝ|ΓΕΣ||ΓΗ|ΓΗΝ|ΓΙ|ΓΙΑ|' + . 'ΓΙΕ|ΓΙΝ|ΓΙΟ|ΓΚΙ|ΓΙΑΤΙ|ΓΚΥ|ΓΟΗ|ΓΟΟ|ΓΡΗΓΟΡΑ|ΓΡΙ|ΓΡΥ|ΓΥΗ|ΓΥΡΩ|ΔΑ|ΔΕ|ΔΕΗ|ΔΕΙ|ΔΕΝ|ΔΕΣ|ΔΗ|ΔΗΘΕΝ|ΔΗΛΑΔΗ|ΔΗΩ|ΔΙ|ΔΙΑ|ΔΙΑΡΚΩΣ|ΔΙΟΛΟΥ|ΔΙΣ|' + . 'ΔΙΧΩΣ|ΔΟΛ|ΔΟΝ|ΔΡΑ|ΔΡΥ|ΔΡΧ|ΔΥΕ|ΔΥΟ|ΔΩ|ΕΑΜ|ΕΑΝ|ΕΑΡ|ΕΘΗ|ΕΙ|ΕΙΔΕΜΗ|ΕΙΘΕ|ΕΙΜΑΙ|ΕΙΜΑΣΤΕ|ΕΙΝΑΙ|ΕΙΣ|ΕΙΣΑΙ|ΕΙΣΑΣΤΕ|ΕΙΣΤΕ|ΕΙΤΕ|ΕΙΧΑ|ΕΙΧΑΜΕ|' + . 'ΕΙΧΑΝ|ΕΙΧΑΤΕ|ΕΙΧΕ|ΕΙΧΕΣ|ΕΚ|ΕΚΕΙ|ΕΛΑ|ΕΛΙ|ΕΜΠ|ΕΝ|ΕΝΤΕΛΩΣ|ΕΝΤΟΣ|ΕΝΤΩΜΕΤΑΞΥ|ΕΝΩ|ΕΞ|ΕΞΑΦΝΑ|ΕΞΙ|ΕΞΙΣΟΥ|ΕΞΩ|ΕΟΚ|ΕΠΑΝΩ|ΕΠΕΙΔΗ|ΕΠΕΙΤΑ|ΕΠΗ|' + . 'ΕΠΙ|ΕΠΙΣΗΣ|ΕΠΟΜΕΝΩΣ|ΕΡΑ|ΕΣ|ΕΣΑΣ|ΕΣΕ|ΕΣΕΙΣ|ΕΣΕΝΑ|ΕΣΗ|ΕΣΤΩ|ΕΣΥ|ΕΣΩ|ΕΤΙ|ΕΤΣΙ|ΕΥ|ΕΥΑ|ΕΥΓΕ|ΕΥΘΥΣ|ΕΥΤΥΧΩΣ|ΕΦΕ|ΕΦΕΞΗΣ|ΕΦΤ|ΕΧΕ|ΕΧΕΙ|' + . 'ΕΧΕΙΣ|ΕΧΕΤΕ|ΕΧΘΕΣ|ΕΧΟΜΕ|ΕΧΟΥΜΕ|ΕΧΟΥΝ|ΕΧΤΕΣ|ΕΧΩ|ΕΩΣ|ΖΕΑ|ΖΕΗ|ΖΕΙ|ΖΕΝ|ΖΗΝ|ΖΩ|Η|ΗΔΗ|ΗΔΥ|ΗΘΗ|ΗΛΟ|ΗΜΙ|ΗΠΑ|ΗΣΑΣΤΕ|ΗΣΟΥΝ|ΗΤΑ|ΗΤΑΝ|ΗΤΑΝΕ|' + . 'ΗΤΟΙ|ΗΤΤΟΝ|ΗΩ|ΘΑ|ΘΥΕ|ΘΩΡ|Ι|ΙΑ|ΙΒΟ|ΙΔΗ|ΙΔΙΩΣ|ΙΕ|ΙΙ|ΙΙΙ|ΙΚΑ|ΙΛΟ|ΙΜΑ|ΙΝΑ|ΙΝΩ|ΙΞΕ|ΙΞΟ|ΙΟ|ΙΟΙ|ΙΣΑ|ΙΣΑΜΕ|ΙΣΕ|ΙΣΗ|ΙΣΙΑ|ΙΣΟ|ΙΣΩΣ|ΙΩΒ|ΙΩΝ|' + . 'ΙΩΣ|ΙΑΝ|ΚΑΘ|ΚΑΘΕ|ΚΑΘΕΤΙ|ΚΑΘΟΛΟΥ|ΚΑΘΩΣ|ΚΑΙ|ΚΑΝ|ΚΑΠΟΤΕ|ΚΑΠΟΥ|ΚΑΠΩΣ|ΚΑΤ|ΚΑΤΑ|ΚΑΤΙ|ΚΑΤΙΤΙ|ΚΑΤΟΠΙΝ|ΚΑΤΩ|ΚΑΩ|ΚΒΟ|ΚΕΑ|ΚΕΙ|ΚΕΝ|ΚΙ|ΚΙΜ|' + . 'ΚΙΟΛΑΣ|ΚΙΤ|ΚΙΧ|ΚΚΕ|ΚΛΙΣΕ|ΚΛΠ|ΚΟΚ|ΚΟΝΤΑ|ΚΟΧ|ΚΤΛ|ΚΥΡ|ΚΥΡΙΩΣ|ΚΩ|ΚΩΝ|ΛΑ|ΛΕΑ|ΛΕΝ|ΛΕΟ|ΛΙΑ|ΛΙΓΑΚΙ|ΛΙΓΟΥΛΑΚΙ|ΛΙΓΟ|ΛΙΓΩΤΕΡΟ|ΛΙΟ|ΛΙΡ|ΛΟΓΩ|' + . 'ΛΟΙΠΑ|ΛΟΙΠΟΝ|ΛΟΣ|ΛΣ|ΛΥΩ|ΜΑ|ΜΑΖΙ|ΜΑΚΑΡΙ|ΜΑΛΙΣΤΑ|ΜΑΛΛΟΝ|ΜΑΝ|ΜΑΞ|ΜΑΣ|ΜΑΤ|ΜΕ|ΜΕΘΑΥΡΙΟ|ΜΕΙ|ΜΕΙΟΝ|ΜΕΛ|ΜΕΛΕΙ|ΜΕΛΛΕΤΑΙ|ΜΕΜΙΑΣ|ΜΕΝ|ΜΕΣ|' + . 'ΜΕΣΑ|ΜΕΤ|ΜΕΤΑ|ΜΕΤΑΞΥ|ΜΕΧΡΙ|ΜΗ|ΜΗΔΕ|ΜΗΝ|ΜΗΠΩΣ|ΜΗΤΕ|ΜΙ|ΜΙΞ|ΜΙΣ|ΜΜΕ|ΜΝΑ|ΜΟΒ|ΜΟΛΙΣ|ΜΟΛΟΝΟΤΙ|ΜΟΝΑΧΑ|ΜΟΝΟΜΙΑΣ|ΜΙΑ|ΜΟΥ|ΜΠΑ|ΜΠΟΡΕΙ|' + . 'ΜΠΟΡΟΥΝ|ΜΠΡΑΒΟ|ΜΠΡΟΣ|ΜΠΩ|ΜΥ|ΜΥΑ|ΜΥΝ|ΝΑ|ΝΑΕ|ΝΑΙ|ΝΑΟ|ΝΔ|ΝΕΐ|ΝΕΑ|ΝΕΕ|ΝΕΟ|ΝΙ|ΝΙΑ|ΝΙΚ|ΝΙΛ|ΝΙΝ|ΝΙΟ|ΝΤΑ|ΝΤΕ|ΝΤΙ|ΝΤΟ|ΝΥΝ|ΝΩΕ|ΝΩΡΙΣ|ΞΑΝΑ|' + . 'ΞΑΦΝΙΚΑ|ΞΕΩ|ΞΙ|Ο|ΟΑ|ΟΑΠ|ΟΔΟ|ΟΕ|ΟΖΟ|ΟΗΕ|ΟΙ|ΟΙΑ|ΟΙΗ|ΟΚΑ|ΟΛΟΓΥΡΑ|ΟΛΟΝΕΝ|ΟΛΟΤΕΛΑ|ΟΛΩΣΔΙΟΛΟΥ|ΟΜΩΣ|ΟΝ|ΟΝΕ|ΟΝΟ|ΟΠΑ|ΟΠΕ|ΟΠΗ|ΟΠΟ|' + . 'ΟΠΟΙΑΔΗΠΟΤΕ|ΟΠΟΙΑΝΔΗΠΟΤΕ|ΟΠΟΙΑΣΔΗΠΟΤΕ|ΟΠΟΙΔΗΠΟΤΕ|ΟΠΟΙΕΣΔΗΠΟΤΕ|ΟΠΟΙΟΔΗΠΟΤΕ|ΟΠΟΙΟΝΔΗΠΟΤΕ|ΟΠΟΙΟΣΔΗΠΟΤΕ|ΟΠΟΙΟΥΔΗΠΟΤΕ|ΟΠΟΙΟΥΣΔΗΠΟΤΕ|' + . 'ΟΠΟΙΩΝΔΗΠΟΤΕ|ΟΠΟΤΕΔΗΠΟΤΕ|ΟΠΟΥ|ΟΠΟΥΔΗΠΟΤΕ|ΟΠΩΣ|ΟΡΑ|ΟΡΕ|ΟΡΗ|ΟΡΟ|ΟΡΦ|ΟΡΩ|ΟΣΑ|ΟΣΑΔΗΠΟΤΕ|ΟΣΕ|ΟΣΕΣΔΗΠΟΤΕ|ΟΣΗΔΗΠΟΤΕ|ΟΣΗΝΔΗΠΟΤΕ|' + . 'ΟΣΗΣΔΗΠΟΤΕ|ΟΣΟΔΗΠΟΤΕ|ΟΣΟΙΔΗΠΟΤΕ|ΟΣΟΝΔΗΠΟΤΕ|ΟΣΟΣΔΗΠΟΤΕ|ΟΣΟΥΔΗΠΟΤΕ|ΟΣΟΥΣΔΗΠΟΤΕ|ΟΣΩΝΔΗΠΟΤΕ|ΟΤΑΝ|ΟΤΕ|ΟΤΙ|ΟΤΙΔΗΠΟΤΕ|ΟΥ|ΟΥΔΕ|ΟΥΚ|ΟΥΣ|' + . 'ΟΥΤΕ|ΟΥΦ|ΟΧΙ|ΟΨΑ|ΟΨΕ|ΟΨΗ|ΟΨΙ|ΟΨΟ|ΠΑ|ΠΑΛΙ|ΠΑΝ|ΠΑΝΤΟΤΕ|ΠΑΝΤΟΥ|ΠΑΝΤΩΣ|ΠΑΠ|ΠΑΡ|ΠΑΡΑ|ΠΕΙ|ΠΕΡ|ΠΕΡΑ|ΠΕΡΙ|ΠΕΡΙΠΟΥ|ΠΕΡΣΙ|ΠΕΡΥΣΙ|ΠΕΣ|ΠΙ|' + . 'ΠΙΑ|ΠΙΘΑΝΟΝ|ΠΙΚ|ΠΙΟ|ΠΙΣΩ|ΠΙΤ|ΠΙΩ|ΠΛΑΙ|ΠΛΕΟΝ|ΠΛΗΝ|ΠΛΩ|ΠΜ|ΠΟΑ|ΠΟΕ|ΠΟΛ|ΠΟΛΥ|ΠΟΠ|ΠΟΤΕ|ΠΟΥ|ΠΟΥΘΕ|ΠΟΥΘΕΝΑ|ΠΡΕΠΕΙ|ΠΡΙ|ΠΡΙΝ|ΠΡΟ|' + . 'ΠΡΟΚΕΙΜΕΝΟΥ|ΠΡΟΚΕΙΤΑΙ|ΠΡΟΠΕΡΣΙ|ΠΡΟΣ|ΠΡΟΤΟΥ|ΠΡΟΧΘΕΣ|ΠΡΟΧΤΕΣ|ΠΡΩΤΥΤΕΡΑ|ΠΥΑ|ΠΥΞ|ΠΥΟ|ΠΥΡ|ΠΧ|ΠΩ|ΠΩΛ|ΠΩΣ|ΡΑ|ΡΑΙ|ΡΑΠ|ΡΑΣ|ΡΕ|ΡΕΑ|ΡΕΕ|ΡΕΙ|' + . 'ΡΗΣ|ΡΘΩ|ΡΙΟ|ΡΟ|ΡΟΐ|ΡΟΕ|ΡΟΖ|ΡΟΗ|ΡΟΘ|ΡΟΙ|ΡΟΚ|ΡΟΛ|ΡΟΝ|ΡΟΣ|ΡΟΥ|ΣΑΙ|ΣΑΝ|ΣΑΟ|ΣΑΣ|ΣΕ|ΣΕΙΣ|ΣΕΚ|ΣΕΞ|ΣΕΡ|ΣΕΤ|ΣΕΦ|ΣΗΜΕΡΑ|ΣΙ|ΣΙΑ|ΣΙΓΑ|ΣΙΚ|' + . 'ΣΙΧ|ΣΚΙ|ΣΟΙ|ΣΟΚ|ΣΟΛ|ΣΟΝ|ΣΟΣ|ΣΟΥ|ΣΡΙ|ΣΤΑ|ΣΤΗ|ΣΤΗΝ|ΣΤΗΣ|ΣΤΙΣ|ΣΤΟ|ΣΤΟΝ|ΣΤΟΥ|ΣΤΟΥΣ|ΣΤΩΝ|ΣΥ|ΣΥΓΧΡΟΝΩΣ|ΣΥΝ|ΣΥΝΑΜΑ|ΣΥΝΕΠΩΣ|ΣΥΝΗΘΩΣ|' + . 'ΣΧΕΔΟΝ|ΣΩΣΤΑ|ΤΑ|ΤΑΔΕ|ΤΑΚ|ΤΑΝ|ΤΑΟ|ΤΑΥ|ΤΑΧΑ|ΤΑΧΑΤΕ|ΤΕ|ΤΕΙ|ΤΕΛ|ΤΕΛΙΚΑ|ΤΕΛΙΚΩΣ|ΤΕΣ|ΤΕΤ|ΤΖΟ|ΤΗ|ΤΗΛ|ΤΗΝ|ΤΗΣ|ΤΙ|ΤΙΚ|ΤΙΜ|ΤΙΠΟΤΑ|ΤΙΠΟΤΕ|' + . 'ΤΙΣ|ΤΝΤ|ΤΟ|ΤΟΙ|ΤΟΚ|ΤΟΜ|ΤΟΝ|ΤΟΠ|ΤΟΣ|ΤΟΣ?Ν|ΤΟΣΑ|ΤΟΣΕΣ|ΤΟΣΗ|ΤΟΣΗΝ|ΤΟΣΗΣ|ΤΟΣΟ|ΤΟΣΟΙ|ΤΟΣΟΝ|ΤΟΣΟΣ|ΤΟΣΟΥ|ΤΟΣΟΥΣ|ΤΟΤΕ|ΤΟΥ|ΤΟΥΛΑΧΙΣΤΟ|' + . 'ΤΟΥΛΑΧΙΣΤΟΝ|ΤΟΥΣ|ΤΣ|ΤΣΑ|ΤΣΕ|ΤΥΧΟΝ|ΤΩ|ΤΩΝ|ΤΩΡΑ|ΥΑΣ|ΥΒΑ|ΥΒΟ|ΥΙΕ|ΥΙΟ|ΥΛΑ|ΥΛΗ|ΥΝΙ|ΥΠ|ΥΠΕΡ|ΥΠΟ|ΥΠΟΨΗ|ΥΠΟΨΙΝ|ΥΣΤΕΡΑ|ΥΦΗ|ΥΨΗ|ΦΑ|ΦΑΐ|ΦΑΕ|' + . 'ΦΑΝ|ΦΑΞ|ΦΑΣ|ΦΑΩ|ΦΕΖ|ΦΕΙ|ΦΕΤΟΣ|ΦΕΥ|ΦΙ|ΦΙΛ|ΦΙΣ|ΦΟΞ|ΦΠΑ|ΦΡΙ|ΧΑ|ΧΑΗ|ΧΑΛ|ΧΑΝ|ΧΑΦ|ΧΕ|ΧΕΙ|ΧΘΕΣ|ΧΙ|ΧΙΑ|ΧΙΛ|ΧΙΟ|ΧΛΜ|ΧΜ|ΧΟΗ|ΧΟΛ|ΧΡΩ|ΧΤΕΣ|' + . 'ΧΩΡΙΣ|ΧΩΡΙΣΤΑ|ΨΕΣ|ΨΗΛΑ|ΨΙ|ΨΙΤ|Ω|ΩΑ|ΩΑΣ|ΩΔΕ|ΩΕΣ|ΩΘΩ|ΩΜΑ|ΩΜΕ|ΩΝ|ΩΟ|ΩΟΝ|ΩΟΥ|ΩΣ|ΩΣΑΝ|ΩΣΗ|ΩΣΟΤΟΥ|ΩΣΠΟΥ|ΩΣΤΕ|ΩΣΤΟΣΟ|ΩΤΑ|ΩΧ|ΩΩΝ)$/'; + + if (preg_match($stop_words, $token)) + { + return $this->toLowerCase($token, $w_CASE); + } + + // Vowels + $v = '(Α|Ε|Η|Ι|Ο|Υ|Ω)'; + + // Vowels without Y + $v2 = '(Α|Ε|Η|Ι|Ο|Ω)'; + + $test1 = true; + + // Step S1. 14 stems + $re = '/^(.+?)(ΙΖΑ|ΙΖΕΣ|ΙΖΕ|ΙΖΑΜΕ|ΙΖΑΤΕ|ΙΖΑΝ|ΙΖΑΝΕ|ΙΖΩ|ΙΖΕΙΣ|ΙΖΕΙ|ΙΖΟΥΜΕ|ΙΖΕΤΕ|ΙΖΟΥΝ|ΙΖΟΥΝΕ)$/'; + $exceptS1 = '/^(ΑΝΑΜΠΑ|ΕΜΠΑ|ΕΠΑ|ΞΑΝΑΠΑ|ΠΑ|ΠΕΡΙΠΑ|ΑΘΡΟ|ΣΥΝΑΘΡΟ|ΔΑΝΕ)$/'; + $exceptS2 = '/^(ΜΑΡΚ|ΚΟΡΝ|ΑΜΠΑΡ|ΑΡΡ|ΒΑΘΥΡΙ|ΒΑΡΚ|Β|ΒΟΛΒΟΡ|ΓΚΡ|ΓΛΥΚΟΡ|ΓΛΥΚΥΡ|ΙΜΠ|Λ|ΛΟΥ|ΜΑΡ|Μ|ΠΡ|ΜΠΡ|ΠΟΛΥΡ|Π|Ρ|ΠΙΠΕΡΟΡ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = $token . 'I'; + } + + if (preg_match($exceptS2, $token)) + { + $token = $token . 'IΖ'; + } + + return $this->toLowerCase($token, $w_CASE); + } + + // Step S2. 7 stems + $re = '/^(.+?)(ΩΘΗΚΑ|ΩΘΗΚΕΣ|ΩΘΗΚΕ|ΩΘΗΚΑΜΕ|ΩΘΗΚΑΤΕ|ΩΘΗΚΑΝ|ΩΘΗΚΑΝΕ)$/'; + $exceptS1 = '/^(ΑΛ|ΒΙ|ΕΝ|ΥΨ|ΛΙ|ΖΩ|Σ|Χ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = $token . 'ΩΝ'; + } + + return $this->toLowerCase($token, $w_CASE); + } + + // Step S3. 7 stems + $re = '/^(.+?)(ΙΣΑ|ΙΣΕΣ|ΙΣΕ|ΙΣΑΜΕ|ΙΣΑΤΕ|ΙΣΑΝ|ΙΣΑΝΕ)$/'; + $exceptS1 = '/^(ΑΝΑΜΠΑ|ΑΘΡΟ|ΕΜΠΑ|ΕΣΕ|ΕΣΩΚΛΕ|ΕΠΑ|ΞΑΝΑΠΑ|ΕΠΕ|ΠΕΡΙΠΑ|ΑΘΡΟ|ΣΥΝΑΘΡΟ|ΔΑΝΕ|ΚΛΕ|ΧΑΡΤΟΠΑ|ΕΞΑΡΧΑ|ΜΕΤΕΠΕ|ΑΠΟΚΛΕ|ΑΠΕΚΛΕ|ΕΚΛΕ|ΠΕ|ΠΕΡΙΠΑ)$/'; + $exceptS2 = '/^(ΑΝ|ΑΦ|ΓΕ|ΓΙΓΑΝΤΟΑΦ|ΓΚΕ|ΔΗΜΟΚΡΑΤ|ΚΟΜ|ΓΚ|Μ|Π|ΠΟΥΚΑΜ|ΟΛΟ|ΛΑΡ)$/'; + + if ($token == "ΙΣΑ") + { + $token = "ΙΣ"; + + return $token; + } + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = $token . 'Ι'; + } + + if (preg_match($exceptS2, $token)) + { + $token = $token . 'ΙΣ'; + } + + return $this->toLowerCase($token, $w_CASE); + } + + + // Step S4. 7 stems + $re = '/^(.+?)(ΙΣΩ|ΙΣΕΙΣ|ΙΣΕΙ|ΙΣΟΥΜΕ|ΙΣΕΤΕ|ΙΣΟΥΝ|ΙΣΟΥΝΕ)$/'; + $exceptS1 = '/^(ΑΝΑΜΠΑ|ΕΜΠΑ|ΕΣΕ|ΕΣΩΚΛΕ|ΕΠΑ|ΞΑΝΑΠΑ|ΕΠΕ|ΠΕΡΙΠΑ|ΑΘΡΟ|ΣΥΝΑΘΡΟ|ΔΑΝΕ|ΚΛΕ|ΧΑΡΤΟΠΑ|ΕΞΑΡΧΑ|ΜΕΤΕΠΕ|ΑΠΟΚΛΕ|ΑΠΕΚΛΕ|ΕΚΛΕ|ΠΕ|ΠΕΡΙΠΑ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = $token . 'Ι'; + } + + return $this->toLowerCase($token, $w_CASE); + } + + // Step S5. 11 stems + $re = '/^(.+?)(ΙΣΤΟΣ|ΙΣΤΟΥ|ΙΣΤΟ|ΙΣΤΕ|ΙΣΤΟΙ|ΙΣΤΩΝ|ΙΣΤΟΥΣ|ΙΣΤΗ|ΙΣΤΗΣ|ΙΣΤΑ|ΙΣΤΕΣ)$/'; + $exceptS1 = '/^(Μ|Π|ΑΠ|ΑΡ|ΗΔ|ΚΤ|ΣΚ|ΣΧ|ΥΨ|ΦΑ|ΧΡ|ΧΤ|ΑΚΤ|ΑΟΡ|ΑΣΧ|ΑΤΑ|ΑΧΝ|ΑΧΤ|ΓΕΜ|ΓΥΡ|ΕΜΠ|ΕΥΠ|ΕΧΘ|ΗΦΑ|ΚΑΘ|ΚΑΚ|ΚΥΛ|ΛΥΓ|ΜΑΚ|ΜΕΓ|ΤΑΧ|ΦΙΛ|ΧΩΡ)$/'; + $exceptS2 = '/^(ΔΑΝΕ|ΣΥΝΑΘΡΟ|ΚΛΕ|ΣΕ|ΕΣΩΚΛΕ|ΑΣΕ|ΠΛΕ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = $token . 'ΙΣΤ'; + } + + if (preg_match($exceptS2, $token)) + { + $token = $token . 'Ι'; + } + + return $this->toLowerCase($token, $w_CASE); + } + + // Step S6. 6 stems + $re = '/^(.+?)(ΙΣΜΟ|ΙΣΜΟΙ|ΙΣΜΟΣ|ΙΣΜΟΥ|ΙΣΜΟΥΣ|ΙΣΜΩΝ)$/'; + $exceptS1 = '/^(ΑΓΝΩΣΤΙΚ|ΑΤΟΜΙΚ|ΓΝΩΣΤΙΚ|ΕΘΝΙΚ|ΕΚΛΕΚΤΙΚ|ΣΚΕΠΤΙΚ|ΤΟΠΙΚ)$/'; + $exceptS2 = '/^(ΣΕ|ΜΕΤΑΣΕ|ΜΙΚΡΟΣΕ|ΕΓΚΛΕ|ΑΠΟΚΛΕ)$/'; + $exceptS3 = '/^(ΔΑΝΕ|ΑΝΤΙΔΑΝΕ)$/'; + $exceptS4 = '/^(ΑΛΕΞΑΝΔΡΙΝ|ΒΥΖΑΝΤΙΝ|ΘΕΑΤΡΙΝ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = str_replace('ΙΚ', "", $token); + } + + if (preg_match($exceptS2, $token)) + { + $token = $token . "ΙΣΜ"; + } + + if (preg_match($exceptS3, $token)) + { + $token = $token . "Ι"; + } + + if (preg_match($exceptS4, $token)) + { + $token = str_replace('ΙΝ', "", $token); + } + + return $this->toLowerCase($token, $w_CASE); + } + + // Step S7. 4 stems + $re = '/^(.+?)(ΑΡΑΚΙ|ΑΡΑΚΙΑ|ΟΥΔΑΚΙ|ΟΥΔΑΚΙΑ)$/'; + $exceptS1 = '/^(Σ|Χ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = $token . "AΡΑΚ"; + } + + return $this->toLowerCase($token, $w_CASE); + } + + + // Step S8. 8 stems + $re = '/^(.+?)(ΑΚΙ|ΑΚΙΑ|ΙΤΣΑ|ΙΤΣΑΣ|ΙΤΣΕΣ|ΙΤΣΩΝ|ΑΡΑΚΙ|ΑΡΑΚΙΑ)$/'; + $exceptS1 = '/^(ΑΝΘΡ|ΒΑΜΒ|ΒΡ|ΚΑΙΜ|ΚΟΝ|ΚΟΡ|ΛΑΒΡ|ΛΟΥΛ|ΜΕΡ|ΜΟΥΣΤ|ΝΑΓΚΑΣ|ΠΛ|Ρ|ΡΥ|Σ|ΣΚ|ΣΟΚ|ΣΠΑΝ|ΤΖ|ΦΑΡΜ|Χ|' + . 'ΚΑΠΑΚ|ΑΛΙΣΦ|ΑΜΒΡ|ΑΝΘΡ|Κ|ΦΥΛ|ΚΑΤΡΑΠ|ΚΛΙΜ|ΜΑΛ|ΣΛΟΒ|Φ|ΣΦ|ΤΣΕΧΟΣΛΟΒ)$/'; + $exceptS2 = '/^(Β|ΒΑΛ|ΓΙΑΝ|ΓΛ|Ζ|ΗΓΟΥΜΕΝ|ΚΑΡΔ|ΚΟΝ|ΜΑΚΡΥΝ|ΝΥΦ|ΠΑΤΕΡ|Π|ΣΚ|ΤΟΣ|ΤΡΙΠΟΛ)$/'; + + // For words like ΠΛΟΥΣΙΟΚΟΡΙΤΣΑ, ΠΑΛΙΟΚΟΡΙΤΣΑ etc + $exceptS3 = '/(ΚΟΡ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = $token . "ΑΚ"; + } + + if (preg_match($exceptS2, $token)) + { + $token = $token . "ΙΤΣ"; + } + + if (preg_match($exceptS3, $token)) + { + $token = $token . "ΙΤΣ"; + } + + return $this->toLowerCase($token, $w_CASE); + } + + // Step S9. 3 stems + $re = '/^(.+?)(ΙΔΙΟ|ΙΔΙΑ|ΙΔΙΩΝ)$/'; + $exceptS1 = '/^(ΑΙΦΝ|ΙΡ|ΟΛΟ|ΨΑΛ)$/'; + $exceptS2 = '/(Ε|ΠΑΙΧΝ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = $token . "ΙΔ"; + } + + if (preg_match($exceptS2, $token)) + { + $token = $token . "ΙΔ"; + } + + return $this->toLowerCase($token, $w_CASE); + } + + // Step S10. 4 stems + $re = '/^(.+?)(ΙΣΚΟΣ|ΙΣΚΟΥ|ΙΣΚΟ|ΙΣΚΕ)$/'; + $exceptS1 = '/^(Δ|ΙΒ|ΜΗΝ|Ρ|ΦΡΑΓΚ|ΛΥΚ|ΟΒΕΛ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + + if (preg_match($exceptS1, $token)) + { + $token = $token . "ΙΣΚ"; + } + + return $this->toLowerCase($token, $w_CASE); + } + + // Step 1 + // step1list is used in Step 1. 41 stems + $step1list = Array(); + $step1list["ΦΑΓΙΑ"] = "ΦΑ"; + $step1list["ΦΑΓΙΟΥ"] = "ΦΑ"; + $step1list["ΦΑΓΙΩΝ"] = "ΦΑ"; + $step1list["ΣΚΑΓΙΑ"] = "ΣΚΑ"; + $step1list["ΣΚΑΓΙΟΥ"] = "ΣΚΑ"; + $step1list["ΣΚΑΓΙΩΝ"] = "ΣΚΑ"; + $step1list["ΟΛΟΓΙΟΥ"] = "ΟΛΟ"; + $step1list["ΟΛΟΓΙΑ"] = "ΟΛΟ"; + $step1list["ΟΛΟΓΙΩΝ"] = "ΟΛΟ"; + $step1list["ΣΟΓΙΟΥ"] = "ΣΟ"; + $step1list["ΣΟΓΙΑ"] = "ΣΟ"; + $step1list["ΣΟΓΙΩΝ"] = "ΣΟ"; + $step1list["ΤΑΤΟΓΙΑ"] = "ΤΑΤΟ"; + $step1list["ΤΑΤΟΓΙΟΥ"] = "ΤΑΤΟ"; + $step1list["ΤΑΤΟΓΙΩΝ"] = "ΤΑΤΟ"; + $step1list["ΚΡΕΑΣ"] = "ΚΡΕ"; + $step1list["ΚΡΕΑΤΟΣ"] = "ΚΡΕ"; + $step1list["ΚΡΕΑΤΑ"] = "ΚΡΕ"; + $step1list["ΚΡΕΑΤΩΝ"] = "ΚΡΕ"; + $step1list["ΠΕΡΑΣ"] = "ΠΕΡ"; + $step1list["ΠΕΡΑΤΟΣ"] = "ΠΕΡ"; + + // Added by Spyros. Also at $re in step1 + $step1list["ΠΕΡΑΤΗ"] = "ΠΕΡ"; + $step1list["ΠΕΡΑΤΑ"] = "ΠΕΡ"; + $step1list["ΠΕΡΑΤΩΝ"] = "ΠΕΡ"; + $step1list["ΤΕΡΑΣ"] = "ΤΕΡ"; + $step1list["ΤΕΡΑΤΟΣ"] = "ΤΕΡ"; + $step1list["ΤΕΡΑΤΑ"] = "ΤΕΡ"; + $step1list["ΤΕΡΑΤΩΝ"] = "ΤΕΡ"; + $step1list["ΦΩΣ"] = "ΦΩ"; + $step1list["ΦΩΤΟΣ"] = "ΦΩ"; + $step1list["ΦΩΤΑ"] = "ΦΩ"; + $step1list["ΦΩΤΩΝ"] = "ΦΩ"; + $step1list["ΚΑΘΕΣΤΩΣ"] = "ΚΑΘΕΣΤ"; + $step1list["ΚΑΘΕΣΤΩΤΟΣ"] = "ΚΑΘΕΣΤ"; + $step1list["ΚΑΘΕΣΤΩΤΑ"] = "ΚΑΘΕΣΤ"; + $step1list["ΚΑΘΕΣΤΩΤΩΝ"] = "ΚΑΘΕΣΤ"; + $step1list["ΓΕΓΟΝΟΣ"] = "ΓΕΓΟΝ"; + $step1list["ΓΕΓΟΝΟΤΟΣ"] = "ΓΕΓΟΝ"; + $step1list["ΓΕΓΟΝΟΤΑ"] = "ΓΕΓΟΝ"; + $step1list["ΓΕΓΟΝΟΤΩΝ"] = "ΓΕΓΟΝ"; + + $re = '/(.*)(ΦΑΓΙΑ|ΦΑΓΙΟΥ|ΦΑΓΙΩΝ|ΣΚΑΓΙΑ|ΣΚΑΓΙΟΥ|ΣΚΑΓΙΩΝ|ΟΛΟΓΙΟΥ|ΟΛΟΓΙΑ|ΟΛΟΓΙΩΝ|ΣΟΓΙΟΥ|ΣΟΓΙΑ|ΣΟΓΙΩΝ|ΤΑΤΟΓΙΑ|ΤΑΤΟΓΙΟΥ|ΤΑΤΟΓΙΩΝ|ΚΡΕΑΣ|ΚΡΕΑΤΟΣ|' + . 'ΚΡΕΑΤΑ|ΚΡΕΑΤΩΝ|ΠΕΡΑΣ|ΠΕΡΑΤΟΣ|ΠΕΡΑΤΗ|ΠΕΡΑΤΑ|ΠΕΡΑΤΩΝ|ΤΕΡΑΣ|ΤΕΡΑΤΟΣ|ΤΕΡΑΤΑ|ΤΕΡΑΤΩΝ|ΦΩΣ|ΦΩΤΟΣ|ΦΩΤΑ|ΦΩΤΩΝ|ΚΑΘΕΣΤΩΣ|ΚΑΘΕΣΤΩΤΟΣ|' + . 'ΚΑΘΕΣΤΩΤΑ|ΚΑΘΕΣΤΩΤΩΝ|ΓΕΓΟΝΟΣ|ΓΕΓΟΝΟΤΟΣ|ΓΕΓΟΝΟΤΑ|ΓΕΓΟΝΟΤΩΝ)$/'; + + if (preg_match($re, $token, $match)) + { + $stem = $match[1]; + $suffix = $match[2]; + $token = $stem . (array_key_exists($suffix, $step1list) ? $step1list[$suffix] : ''); + $test1 = false; + } + + // Step 2a. 2 stems + $re = '/^(.+?)(ΑΔΕΣ|ΑΔΩΝ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1]; + $re = '/(ΟΚ|ΜΑΜ|ΜΑΝ|ΜΠΑΜΠ|ΠΑΤΕΡ|ΓΙΑΓΙ|ΝΤΑΝΤ|ΚΥΡ|ΘΕΙ|ΠΕΘΕΡ)$/'; + + if (!preg_match($re, $token)) + { + $token = $token . "ΑΔ"; + } + } + + // Step 2b. 2 stems + $re = '/^(.+?)(ΕΔΕΣ|ΕΔΩΝ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $exept2 = '/(ΟΠ|ΙΠ|ΕΜΠ|ΥΠ|ΓΗΠ|ΔΑΠ|ΚΡΑΣΠ|ΜΙΛ)$/'; + + if (preg_match($exept2, $token)) + { + $token = $token . 'ΕΔ'; + } + } + + // Step 2c + $re = '/^(.+?)(ΟΥΔΕΣ|ΟΥΔΩΝ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + + $exept3 = '/(ΑΡΚ|ΚΑΛΙΑΚ|ΠΕΤΑΛ|ΛΙΧ|ΠΛΕΞ|ΣΚ|Σ|ΦΛ|ΦΡ|ΒΕΛ|ΛΟΥΛ|ΧΝ|ΣΠ|ΤΡΑΓ|ΦΕ)$/'; + + if (preg_match($exept3, $token)) + { + $token = $token . 'ΟΥΔ'; + } + } + + // Step 2d + $re = '/^(.+?)(ΕΩΣ|ΕΩΝ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept4 = '/^(Θ|Δ|ΕΛ|ΓΑΛ|Ν|Π|ΙΔ|ΠΑΡ)$/'; + + if (preg_match($exept4, $token)) + { + $token = $token . 'Ε'; + } + + } + + // Step 3 + $re = '/^(.+?)(ΙΑ|ΙΟΥ|ΙΩΝ)$/'; + + if (preg_match($re, $token, $fp)) + { + $stem = $fp[1]; + $token = $stem; + $re = '/' . $v . '$/'; + $test1 = false; + + if (preg_match($re, $token)) + { + $token = $stem . 'Ι'; + } + } + + // Step 4 + $re = '/^(.+?)(ΙΚΑ|ΙΚΟ|ΙΚΟΥ|ΙΚΩΝ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $re = '/' . $v . '$/'; + $exept5 = '/^(ΑΛ|ΑΔ|ΕΝΔ|ΑΜΑΝ|ΑΜΜΟΧΑΛ|ΗΘ|ΑΝΗΘ|ΑΝΤΙΔ|ΦΥΣ|ΒΡΩΜ|ΓΕΡ|ΕΞΩΔ|ΚΑΛΠ|ΚΑΛΛΙΝ|ΚΑΤΑΔ|ΜΟΥΛ|ΜΠΑΝ|ΜΠΑΓΙΑΤ|ΜΠΟΛ|ΜΠΟΣ|ΝΙΤ|ΞΙΚ|ΣΥΝΟΜΗΛ|ΠΕΤΣ|' + . 'ΠΙΤΣ|ΠΙΚΑΝΤ|ΠΛΙΑΤΣ|ΠΟΣΤΕΛΝ|ΠΡΩΤΟΔ|ΣΕΡΤ|ΣΥΝΑΔ|ΤΣΑΜ|ΥΠΟΔ|ΦΙΛΟΝ|ΦΥΛΟΔ|ΧΑΣ)$/'; + + if (preg_match($re, $token) || preg_match($exept5, $token)) + { + $token = $token . 'ΙΚ'; + } + } + + // Step 5a + $re = '/^(.+?)(ΑΜΕ)$/'; + $re2 = '/^(.+?)(ΑΓΑΜΕ|ΗΣΑΜΕ|ΟΥΣΑΜΕ|ΗΚΑΜΕ|ΗΘΗΚΑΜΕ)$/'; + + if ($token == "ΑΓΑΜΕ") + { + $token = "ΑΓΑΜ"; + + } + + if (preg_match($re2, $token)) + { + preg_match($re2, $token, $match); + $token = $match[1]; + $test1 = false; + } + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept6 = '/^(ΑΝΑΠ|ΑΠΟΘ|ΑΠΟΚ|ΑΠΟΣΤ|ΒΟΥΒ|ΞΕΘ|ΟΥΛ|ΠΕΘ|ΠΙΚΡ|ΠΟΤ|ΣΙΧ|Χ)$/'; + + if (preg_match($exept6, $token)) + { + $token = $token . "ΑΜ"; + } + } + + // Step 5b + $re2 = '/^(.+?)(ΑΝΕ)$/'; + $re3 = '/^(.+?)(ΑΓΑΝΕ|ΗΣΑΝΕ|ΟΥΣΑΝΕ|ΙΟΝΤΑΝΕ|ΙΟΤΑΝΕ|ΙΟΥΝΤΑΝΕ|ΟΝΤΑΝΕ|ΟΤΑΝΕ|ΟΥΝΤΑΝΕ|ΗΚΑΝΕ|ΗΘΗΚΑΝΕ)$/'; + + if (preg_match($re3, $token)) + { + preg_match($re3, $token, $match); + $token = $match[1]; + $test1 = false; + $re3 = '/^(ΤΡ|ΤΣ)$/'; + + if (preg_match($re3, $token)) + { + $token = $token . "ΑΓΑΝ"; + } + } + + if (preg_match($re2, $token)) + { + preg_match($re2, $token, $match); + $token = $match[1]; + $test1 = false; + $re2 = '/' . $v2 . '$/'; + $exept7 = '/^(ΒΕΤΕΡ|ΒΟΥΛΚ|ΒΡΑΧΜ|Γ|ΔΡΑΔΟΥΜ|Θ|ΚΑΛΠΟΥΖ|ΚΑΣΤΕΛ|ΚΟΡΜΟΡ|ΛΑΟΠΛ|ΜΩΑΜΕΘ|Μ|ΜΟΥΣΟΥΛΜ|Ν|ΟΥΛ|Π|ΠΕΛΕΚ|ΠΛ|ΠΟΛΙΣ|ΠΟΡΤΟΛ|ΣΑΡΑΚΑΤΣ|ΣΟΥΛΤ|' + . 'ΤΣΑΡΛΑΤ|ΟΡΦ|ΤΣΙΓΓ|ΤΣΟΠ|ΦΩΤΟΣΤΕΦ|Χ|ΨΥΧΟΠΛ|ΑΓ|ΟΡΦ|ΓΑΛ|ΓΕΡ|ΔΕΚ|ΔΙΠΛ|ΑΜΕΡΙΚΑΝ|ΟΥΡ|ΠΙΘ|ΠΟΥΡΙΤ|Σ|ΖΩΝΤ|ΙΚ|ΚΑΣΤ|ΚΟΠ|ΛΙΧ|ΛΟΥΘΗΡ|ΜΑΙΝΤ|' + . 'ΜΕΛ|ΣΙΓ|ΣΠ|ΣΤΕΓ|ΤΡΑΓ|ΤΣΑΓ|Φ|ΕΡ|ΑΔΑΠ|ΑΘΙΓΓ|ΑΜΗΧ|ΑΝΙΚ|ΑΝΟΡΓ|ΑΠΗΓ|ΑΠΙΘ|ΑΤΣΙΓΓ|ΒΑΣ|ΒΑΣΚ|ΒΑΘΥΓΑΛ|ΒΙΟΜΗΧ|ΒΡΑΧΥΚ|ΔΙΑΤ|ΔΙΑΦ|ΕΝΟΡΓ|' + . 'ΘΥΣ|ΚΑΠΝΟΒΙΟΜΗΧ|ΚΑΤΑΓΑΛ|ΚΛΙΒ|ΚΟΙΛΑΡΦ|ΛΙΒ|ΜΕΓΛΟΒΙΟΜΗΧ|ΜΙΚΡΟΒΙΟΜΗΧ|ΝΤΑΒ|ΞΗΡΟΚΛΙΒ|ΟΛΙΓΟΔΑΜ|ΟΛΟΓΑΛ|ΠΕΝΤΑΡΦ|ΠΕΡΗΦ|ΠΕΡΙΤΡ|ΠΛΑΤ|' + . 'ΠΟΛΥΔΑΠ|ΠΟΛΥΜΗΧ|ΣΤΕΦ|ΤΑΒ|ΤΕΤ|ΥΠΕΡΗΦ|ΥΠΟΚΟΠ|ΧΑΜΗΛΟΔΑΠ|ΨΗΛΟΤΑΒ)$/'; + + + if (preg_match($re2, $token) || preg_match($exept7, $token)) + { + $token = $token . "ΑΝ"; + } + } + + // Step 5c + $re3 = '/^(.+?)(ΕΤΕ)$/'; + $re4 = '/^(.+?)(ΗΣΕΤΕ)$/'; + + if (preg_match($re4, $token)) + { + preg_match($re4, $token, $match); + $token = $match[1]; + $test1 = false; + } + + if (preg_match($re3, $token)) + { + preg_match($re3, $token, $match); + $token = $match[1]; + $test1 = false; + $re3 = '/' . $v2 . '$/'; + $exept8 = '/(ΟΔ|ΑΙΡ|ΦΟΡ|ΤΑΘ|ΔΙΑΘ|ΣΧ|ΕΝΔ|ΕΥΡ|ΤΙΘ|ΥΠΕΡΘ|ΡΑΘ|ΕΝΘ|ΡΟΘ|ΣΘ|ΠΥΡ|ΑΙΝ|ΣΥΝΔ|ΣΥΝ|ΣΥΝΘ|ΧΩΡ|ΠΟΝ|ΒΡ|ΚΑΘ|ΕΥΘ|ΕΚΘ|ΝΕΤ|ΡΟΝ|ΑΡΚ|ΒΑΡ|ΒΟΛ|ΩΦΕΛ)$/'; + $exept9 = '/^(ΑΒΑΡ|ΒΕΝ|ΕΝΑΡ|ΑΒΡ|ΑΔ|ΑΘ|ΑΝ|ΑΠΛ|ΒΑΡΟΝ|ΝΤΡ|ΣΚ|ΚΟΠ|ΜΠΟΡ|ΝΙΦ|ΠΑΓ|ΠΑΡΑΚΑΛ|ΣΕΡΠ|ΣΚΕΛ|ΣΥΡΦ|ΤΟΚ|Υ|Δ|ΕΜ|ΘΑΡΡ|Θ)$/'; + + if (preg_match($re3, $token) || preg_match($exept8, $token) || preg_match($exept9, $token)) + { + $token = $token . "ΕΤ"; + } + } + + // Step 5d + $re = '/^(.+?)(ΟΝΤΑΣ|ΩΝΤΑΣ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept10 = '/^(ΑΡΧ)$/'; + $exept11 = '/(ΚΡΕ)$/'; + + if (preg_match($exept10, $token)) + { + $token = $token . "ΟΝΤ"; + } + + if (preg_match($exept11, $token)) + { + $token = $token . "ΩΝΤ"; + } + } + + // Step 5e + $re = '/^(.+?)(ΟΜΑΣΤΕ|ΙΟΜΑΣΤΕ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept11 = '/^(ΟΝ)$/'; + + if (preg_match($exept11, $token)) + { + $token = $token . "ΟΜΑΣΤ"; + } + } + + // Step 5f + $re = '/^(.+?)(ΕΣΤΕ)$/'; + $re2 = '/^(.+?)(ΙΕΣΤΕ)$/'; + + if (preg_match($re2, $token)) + { + preg_match($re2, $token, $match); + $token = $match[1]; + $test1 = false; + $re2 = '/^(Π|ΑΠ|ΣΥΜΠ|ΑΣΥΜΠ|ΑΚΑΤΑΠ|ΑΜΕΤΑΜΦ)$/'; + + if (preg_match($re2, $token)) + { + $token = $token . "ΙΕΣΤ"; + } + } + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept12 = '/^(ΑΛ|ΑΡ|ΕΚΤΕΛ|Ζ|Μ|Ξ|ΠΑΡΑΚΑΛ|ΑΡ|ΠΡΟ|ΝΙΣ)$/'; + + if (preg_match($exept12, $token)) + { + $token = $token . "ΕΣΤ"; + } + } + + // Step 5g + $re = '/^(.+?)(ΗΚΑ|ΗΚΕΣ|ΗΚΕ)$/'; + $re2 = '/^(.+?)(ΗΘΗΚΑ|ΗΘΗΚΕΣ|ΗΘΗΚΕ)$/'; + + if (preg_match($re2, $token)) + { + preg_match($re2, $token, $match); + $token = $match[1]; + $test1 = false; + } + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept13 = '/(ΣΚΩΛ|ΣΚΟΥΛ|ΝΑΡΘ|ΣΦ|ΟΘ|ΠΙΘ)$/'; + $exept14 = '/^(ΔΙΑΘ|Θ|ΠΑΡΑΚΑΤΑΘ|ΠΡΟΣΘ|ΣΥΝΘ|)$/'; + + if (preg_match($exept13, $token) || preg_match($exept14, $token)) + { + $token = $token . "ΗΚ"; + } + } + + // Step 5h + $re = '/^(.+?)(ΟΥΣΑ|ΟΥΣΕΣ|ΟΥΣΕ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept15 = '/^(ΦΑΡΜΑΚ|ΧΑΔ|ΑΓΚ|ΑΝΑΡΡ|ΒΡΟΜ|ΕΚΛΙΠ|ΛΑΜΠΙΔ|ΛΕΧ|Μ|ΠΑΤ|Ρ|Λ|ΜΕΔ|ΜΕΣΑΖ|ΥΠΟΤΕΙΝ|ΑΜ|ΑΙΘ|ΑΝΗΚ|ΔΕΣΠΟΖ|ΕΝΔΙΑΦΕΡ|ΔΕ|ΔΕΥΤΕΡΕΥ|ΚΑΘΑΡΕΥ|ΠΛΕ|ΤΣΑ)$/'; + $exept16 = '/(ΠΟΔΑΡ|ΒΛΕΠ|ΠΑΝΤΑΧ|ΦΡΥΔ|ΜΑΝΤΙΛ|ΜΑΛΛ|ΚΥΜΑΤ|ΛΑΧ|ΛΗΓ|ΦΑΓ|ΟΜ|ΠΡΩΤ)$/'; + + if (preg_match($exept15, $token) || preg_match($exept16, $token)) + { + $token = $token . "ΟΥΣ"; + } + } + + // Step 5i + $re = '/^(.+?)(ΑΓΑ|ΑΓΕΣ|ΑΓΕ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept17 = '/^(ΨΟΦ|ΝΑΥΛΟΧ)$/'; + $exept20 = '/(ΚΟΛΛ)$/'; + $exept18 = '/^(ΑΒΑΣΤ|ΠΟΛΥΦ|ΑΔΗΦ|ΠΑΜΦ|Ρ|ΑΣΠ|ΑΦ|ΑΜΑΛ|ΑΜΑΛΛΙ|ΑΝΥΣΤ|ΑΠΕΡ|ΑΣΠΑΡ|ΑΧΑΡ|ΔΕΡΒΕΝ|ΔΡΟΣΟΠ|ΞΕΦ|ΝΕΟΠ|ΝΟΜΟΤ|ΟΛΟΠ|ΟΜΟΤ|ΠΡΟΣΤ|ΠΡΟΣΩΠΟΠ|' + . 'ΣΥΜΠ|ΣΥΝΤ|Τ|ΥΠΟΤ|ΧΑΡ|ΑΕΙΠ|ΑΙΜΟΣΤ|ΑΝΥΠ|ΑΠΟΤ|ΑΡΤΙΠ|ΔΙΑΤ|ΕΝ|ΕΠΙΤ|ΚΡΟΚΑΛΟΠ|ΣΙΔΗΡΟΠ|Λ|ΝΑΥ|ΟΥΛΑΜ|ΟΥΡ|Π|ΤΡ|Μ)$/'; + $exept19 = '/(ΟΦ|ΠΕΛ|ΧΟΡΤ|ΛΛ|ΣΦ|ΡΠ|ΦΡ|ΠΡ|ΛΟΧ|ΣΜΗΝ)$/'; + + if ((preg_match($exept18, $token) || preg_match($exept19, $token)) + && !(preg_match($exept17, $token) || preg_match($exept20, $token))) + { + $token = $token . "ΑΓ"; + } + } + + + // Step 5j + $re = '/^(.+?)(ΗΣΕ|ΗΣΟΥ|ΗΣΑ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept21 = '/^(Ν|ΧΕΡΣΟΝ|ΔΩΔΕΚΑΝ|ΕΡΗΜΟΝ|ΜΕΓΑΛΟΝ|ΕΠΤΑΝ)$/'; + + if (preg_match($exept21, $token)) + { + $token = $token . "ΗΣ"; + } + } + + // Step 5k + $re = '/^(.+?)(ΗΣΤΕ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept22 = '/^(ΑΣΒ|ΣΒ|ΑΧΡ|ΧΡ|ΑΠΛ|ΑΕΙΜΝ|ΔΥΣΧΡ|ΕΥΧΡ|ΚΟΙΝΟΧΡ|ΠΑΛΙΜΨ)$/'; + + if (preg_match($exept22, $token)) + { + $token = $token . "ΗΣΤ"; + } + } + + // Step 5l + $re = '/^(.+?)(ΟΥΝΕ|ΗΣΟΥΝΕ|ΗΘΟΥΝΕ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept23 = '/^(Ν|Ρ|ΣΠΙ|ΣΤΡΑΒΟΜΟΥΤΣ|ΚΑΚΟΜΟΥΤΣ|ΕΞΩΝ)$/'; + + if (preg_match($exept23, $token)) + { + $token = $token . "ΟΥΝ"; + } + } + + // Step 5m + $re = '/^(.+?)(ΟΥΜΕ|ΗΣΟΥΜΕ|ΗΘΟΥΜΕ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + $test1 = false; + $exept24 = '/^(ΠΑΡΑΣΟΥΣ|Φ|Χ|ΩΡΙΟΠΛ|ΑΖ|ΑΛΛΟΣΟΥΣ|ΑΣΟΥΣ)$/'; + + if (preg_match($exept24, $token)) + { + $token = $token . "ΟΥΜ"; + } + } + + // Step 6 + $re = '/^(.+?)(ΜΑΤΑ|ΜΑΤΩΝ|ΜΑΤΟΣ)$/'; + $re2 = '/^(.+?)(Α|ΑΓΑΤΕ|ΑΓΑΝ|ΑΕΙ|ΑΜΑΙ|ΑΝ|ΑΣ|ΑΣΑΙ|ΑΤΑΙ|ΑΩ|Ε|ΕΙ|ΕΙΣ|ΕΙΤΕ|ΕΣΑΙ|ΕΣ|ΕΤΑΙ|Ι|ΙΕΜΑΙ|ΙΕΜΑΣΤΕ|ΙΕΤΑΙ|ΙΕΣΑΙ|ΙΕΣΑΣΤΕ|ΙΟΜΑΣΤΑΝ|ΙΟΜΟΥΝ|' + . 'ΙΟΜΟΥΝΑ|ΙΟΝΤΑΝ|ΙΟΝΤΟΥΣΑΝ|ΙΟΣΑΣΤΑΝ|ΙΟΣΑΣΤΕ|ΙΟΣΟΥΝ|ΙΟΣΟΥΝΑ|ΙΟΤΑΝ|ΙΟΥΜΑ|ΙΟΥΜΑΣΤΕ|ΙΟΥΝΤΑΙ|ΙΟΥΝΤΑΝ|Η|ΗΔΕΣ|ΗΔΩΝ|ΗΘΕΙ|ΗΘΕΙΣ|ΗΘΕΙΤΕ|' + . 'ΗΘΗΚΑΤΕ|ΗΘΗΚΑΝ|ΗΘΟΥΝ|ΗΘΩ|ΗΚΑΤΕ|ΗΚΑΝ|ΗΣ|ΗΣΑΝ|ΗΣΑΤΕ|ΗΣΕΙ|ΗΣΕΣ|ΗΣΟΥΝ|ΗΣΩ|Ο|ΟΙ|ΟΜΑΙ|ΟΜΑΣΤΑΝ|ΟΜΟΥΝ|ΟΜΟΥΝΑ|ΟΝΤΑΙ|ΟΝΤΑΝ|ΟΝΤΟΥΣΑΝ|ΟΣ|' + . 'ΟΣΑΣΤΑΝ|ΟΣΑΣΤΕ|ΟΣΟΥΝ|ΟΣΟΥΝΑ|ΟΤΑΝ|ΟΥ|ΟΥΜΑΙ|ΟΥΜΑΣΤΕ|ΟΥΝ|ΟΥΝΤΑΙ|ΟΥΝΤΑΝ|ΟΥΣ|ΟΥΣΑΝ|ΟΥΣΑΤΕ|Υ|ΥΣ|Ω|ΩΝ)$/'; + + if (preg_match($re, $token, $match)) + { + $token = $match[1] . "ΜΑ"; + } + + if (preg_match($re2, $token) && $test1) + { + preg_match($re2, $token, $match); + $token = $match[1]; + } + + // Step 7 (ΠΑΡΑΘΕΤΙΚΑ) + $re = '/^(.+?)(ΕΣΤΕΡ|ΕΣΤΑΤ|ΟΤΕΡ|ΟΤΑΤ|ΥΤΕΡ|ΥΤΑΤ|ΩΤΕΡ|ΩΤΑΤ)$/'; + + if (preg_match($re, $token)) + { + preg_match($re, $token, $match); + $token = $match[1]; + } + + return $this->toLowerCase($token, $w_CASE); + } + + /** + * Converts the token to uppercase, suppressing accents and diaeresis. The array $w_CASE contains a special map of + * the uppercase rule used to convert each character at each position. + * + * @param string $token Token to process + * @param array &$w_CASE Map of uppercase rules + * + * @return string + * + * @since 4.0.0 + */ + protected function toUpperCase($token, &$w_CASE) + { + $w_CASE = array_fill(0, mb_strlen($token, 'UTF-8'), 0); + $caseConvert = array( + "α" => 'Α', + "β" => 'Β', + "γ" => 'Γ', + "δ" => 'Δ', + "ε" => 'Ε', + "ζ" => 'Ζ', + "η" => 'Η', + "θ" => 'Θ', + "ι" => 'Ι', + "κ" => 'Κ', + "λ" => 'Λ', + "μ" => 'Μ', + "ν" => 'Ν', + "ξ" => 'Ξ', + "ο" => 'Ο', + "π" => 'Π', + "ρ" => 'Ρ', + "σ" => 'Σ', + "τ" => 'Τ', + "υ" => 'Υ', + "φ" => 'Φ', + "χ" => 'Χ', + "ψ" => 'Ψ', + "ω" => 'Ω', + "ά" => 'Α', + "έ" => 'Ε', + "ή" => 'Η', + "ί" => 'Ι', + "ό" => 'Ο', + "ύ" => 'Υ', + "ώ" => 'Ω', + "ς" => 'Σ', + "ϊ" => 'Ι', + "ϋ" => 'Ι', + "ΐ" => 'Ι', + "ΰ" => 'Υ', + ); + $newToken = ''; + + for ($i = 0; $i < mb_strlen($token); $i++) + { + $char = mb_substr($token, $i, 1); + $isLower = array_key_exists($char, $caseConvert); + + if (!$isLower) + { + $newToken .= $char; + + continue; + } + + $upperCase = $caseConvert[$char]; + $newToken .= $upperCase; + + $w_CASE[$i] = 1; + + if (in_array($char, ['ά', 'έ', 'ή', 'ί', 'ό', 'ύ', 'ώ', 'ς'])) + { + $w_CASE[$i] = 2; + } + + if (in_array($char, ['ϊ', 'ϋ'])) + { + $w_CASE[$i] = 3; + } + + if (in_array($char, ['ΐ', 'ΰ'])) + { + $w_CASE[$i] = 4; + } + } + + return $newToken; + } + + /** + * Converts the suppressed uppercase token back to lowercase, using the $w_CASE map to add back the accents, + * diaeresis and handle the special case of final sigma (different lowercase glyph than the regular sigma, only + * used at the end of words). + * + * @param string $token Token to process + * @param array $w_CASE Map of lowercase rules + * + * @return string + * + * @since 4.0.0 + */ + protected function toLowerCase($token, $w_CASE) + { + $newToken = ''; + + for ($i = 0; $i < mb_strlen($token); $i++) + { + $char = mb_substr($token, $i, 1); + + // Is $w_CASE not set at this position? We assume no case conversion ever took place. + if (!isset($w_CASE[$i])) + { + $newToken .= $char; + + continue; + } + + // The character was not case-converted + if ($w_CASE[$i] == 0) + { + $newToken .= $char; + + continue; + } + + // Case 1: Unaccented letter + if ($w_CASE[$i] == 1) + { + $newToken .= mb_strtolower($char); + + continue; + } + + // Case 2: Vowel with accent (tonos); or the special case of final sigma + if ($w_CASE[$i] == 2) + { + $charMap = [ + 'Α' => 'ά', + 'Ε' => 'έ', + 'Η' => 'ή', + 'Ι' => 'ί', + 'Ο' => 'ό', + 'Υ' => 'ύ', + 'Ω' => 'ώ', + 'Σ' => 'ς' + ]; + + $newToken .= $charMap[$char]; + + continue; + } + + // Case 3: vowels with diaeresis (dialytika) + if ($w_CASE[$i] == 3) + { + $charMap = [ + 'Ι' => 'ϊ', + 'Υ' => 'ϋ' + ]; + + $newToken .= $charMap[$char]; + + continue; + } + + // Case 4: vowels with both diaeresis (dialytika) and accent (tonos) + if ($w_CASE[$i] == 4) + { + $charMap = [ + 'Ι' => 'ΐ', + 'Υ' => 'ΰ' + ]; + + $newToken .= $charMap[$char]; + + continue; + } + + // This should never happen! + $newToken .= $char; + } + + return $newToken; + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/en.php b/administrator/components/com_finder/helpers/indexer/language/en.php new file mode 100644 index 0000000000000..11e58d5abf4ab --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/en.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\English; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/es.php b/administrator/components/com_finder/helpers/indexer/language/es.php new file mode 100644 index 0000000000000..5095c77852767 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/es.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\Spanish; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/fr.php b/administrator/components/com_finder/helpers/indexer/language/fr.php new file mode 100644 index 0000000000000..0436fb468a273 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/fr.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\French; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/it.php b/administrator/components/com_finder/helpers/indexer/language/it.php new file mode 100644 index 0000000000000..1b2649f6fafb0 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/it.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\Italian; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/nl.php b/administrator/components/com_finder/helpers/indexer/language/nl.php new file mode 100644 index 0000000000000..d01768dcbe9a6 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/nl.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\Dutch; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/nn.php b/administrator/components/com_finder/helpers/indexer/language/nn.php new file mode 100644 index 0000000000000..e7dd8307cff8c --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/nn.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\Norwegian; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/pt.php b/administrator/components/com_finder/helpers/indexer/language/pt.php new file mode 100644 index 0000000000000..ef8d678133b0c --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/pt.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\Portuguese; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/ro.php b/administrator/components/com_finder/helpers/indexer/language/ro.php new file mode 100644 index 0000000000000..96ba4bd7cbc75 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/ro.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\Romanian; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/ru.php b/administrator/components/com_finder/helpers/indexer/language/ru.php new file mode 100644 index 0000000000000..9a6074705fd3b --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/ru.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\Russian; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/sv.php b/administrator/components/com_finder/helpers/indexer/language/sv.php new file mode 100644 index 0000000000000..d1c186c984db7 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/sv.php @@ -0,0 +1,58 @@ +stemmer = new \Wamania\Snowball\Swedish; + } + + /** + * Method to stem a token. + * + * @param string $token The token to stem. + * + * @return string The stemmed token. + * + * @since 4.0.0 + */ + public function stem($token) + { + return $this->stemmer->stem($token); + } +} diff --git a/administrator/components/com_finder/helpers/indexer/language/zh.php b/administrator/components/com_finder/helpers/indexer/language/zh.php new file mode 100644 index 0000000000000..a989defc828d4 --- /dev/null +++ b/administrator/components/com_finder/helpers/indexer/language/zh.php @@ -0,0 +1,74 @@ +input = isset($options['input']) ? $options['input'] : null; + $this->input = $options['input'] ?? null; // Get the empty query setting. $this->empty = isset($options['empty']) ? (bool) $options['empty'] : false; // Get the input language. $this->language = !empty($options['language']) ? $options['language'] : FinderIndexerHelper::getDefaultLanguage(); - $this->language = FinderIndexerHelper::getPrimaryLanguage($this->language); // Get the matching mode. $this->mode = 'AND'; @@ -730,11 +739,12 @@ protected function processDates($date1, $date2, $when1, $when2) protected function processString($input, $lang, $mode) { // Clean up the input string. - $input = html_entity_decode($input, ENT_QUOTES, 'UTF-8'); - $input = StringHelper::strtolower($input); - $input = preg_replace('#\s+#mi', ' ', $input); - $input = trim($input); - $debug = JFactory::getConfig()->get('debug_lang'); + $input = html_entity_decode($input, ENT_QUOTES, 'UTF-8'); + $input = StringHelper::strtolower($input); + $input = preg_replace('#\s+#mi', ' ', $input); + $input = trim($input); + $debug = JFactory::getConfig()->get('debug_lang'); + $params = ComponentHelper::getParams('com_finder'); /* * First, we need to handle string based modifiers. String based @@ -786,7 +796,7 @@ protected function processString($input, $lang, $mode) if (preg_match('#' . $pattern . '\s*:\s*' . $suffix . '#mi', $input, $matches)) { // Get the value given to the modifier. - $value = isset($matches[3]) ? $matches[3] : $matches[1]; + $value = $matches[3] ?? $matches[1]; // Now we have to handle the filter string. switch ($modifier) @@ -892,51 +902,33 @@ protected function processString($input, $lang, $mode) // Get the number of words in the phrase. $parts = explode(' ', $match); + $tuplecount = $params->get('tuplecount', 1); - // Check if the phrase is longer than three words. - if (count($parts) > 3) + // Check if the phrase is longer than our $tuplecount. + if (count($parts) > $tuplecount && $tuplecount > 1) { + $chunk = array_slice($parts, 0, $tuplecount); + $parts = array_slice($parts, $tuplecount); + + // If the chunk is not empty, add it as a phrase. + if (count($chunk)) + { + $phrases[] = implode(' ', $chunk); + $terms[] = implode(' ', $chunk); + } + /* - * If the phrase is longer than three words, we need to + * If the phrase is longer than $tuplecount words, we need to * break it down into smaller chunks of phrases that - * are less than or equal to three words. We overlap + * are less than or equal to $tuplecount words. We overlap * the chunks so that we can ensure that a match is * found for the complete phrase and not just portions * of it. */ - for ($i = 0, $c = count($parts); $i < $c; $i += 2) + for ($i = 0, $c = count($parts); $i < $c; $i++) { - // Set up the chunk. - $chunk = array(); - - // The chunk has to be assembled based on how many - // pieces are available to use. - switch ($c - $i) - { - /* - * If only one word is left, we can break from - * the switch and loop because the last word - * was already used at the end of the last - * chunk. - */ - case 1: - break 2; - - // If there words are left, we use them both as - // the last chunk of the phrase and we're done. - case 2: - $chunk[] = $parts[$i]; - $chunk[] = $parts[$i + 1]; - break; - - // If there are three or more words left, we - // build a three word chunk and continue on. - default: - $chunk[] = $parts[$i]; - $chunk[] = $parts[$i + 1]; - $chunk[] = $parts[$i + 2]; - break; - } + array_shift($chunk); + $chunk[] = array_shift($parts); // If the chunk is not empty, add it as a phrase. if (count($chunk)) @@ -948,7 +940,7 @@ protected function processString($input, $lang, $mode) } else { - // The phrase is <= 3 words so we can use it as is. + // The phrase is <= $tuplecount words so we can use it as is. $phrases[] = $match; $terms[] = $match; } @@ -994,7 +986,7 @@ protected function processString($input, $lang, $mode) { // Tokenize the current term. $token = FinderIndexerHelper::tokenize($terms[$i], $lang, true); - $token = $this->getTokenData($token); + $token = $this->getTokenData(array_shift($token)); // Set the required flag. $token->required = true; @@ -1008,7 +1000,7 @@ protected function processString($input, $lang, $mode) // Tokenize the term after the next term (current plus two). $other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true); - $other = $this->getTokenData($other); + $other = $this->getTokenData(array_shift($other)); // Set the required flag. $other->required = true; @@ -1042,7 +1034,7 @@ protected function processString($input, $lang, $mode) { // Tokenize the current term. $token = FinderIndexerHelper::tokenize($terms[$i], $lang, true); - $token = $this->getTokenData($token); + $token = $this->getTokenData(array_shift($token)); // Set the required flag. $token->required = false; @@ -1063,7 +1055,7 @@ protected function processString($input, $lang, $mode) // Tokenize the term after the next term (current plus two). $other = FinderIndexerHelper::tokenize($terms[$i + 2], $lang, true); - $other = $this->getTokenData($other); + $other = $this->getTokenData(array_shift($other)); // Set the required flag. $other->required = false; @@ -1108,7 +1100,7 @@ protected function processString($input, $lang, $mode) // Tokenize the next term (current plus one). $other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true); - $other = $this->getTokenData($other); + $other = $this->getTokenData(array_shift($other)); // Set the required flag. $other->required = false; @@ -1146,7 +1138,7 @@ protected function processString($input, $lang, $mode) // Tokenize the next term (current plus one). $other = FinderIndexerHelper::tokenize($terms[$i + 1], $lang, true); - $other = $this->getTokenData($other); + $other = $this->getTokenData(array_shift($other)); // Set the required flag. $other->required = false; @@ -1186,7 +1178,7 @@ protected function processString($input, $lang, $mode) { // Tokenize the phrase. $token = FinderIndexerHelper::tokenize($phrases[$i], $lang, true); - $token = $this->getTokenData($token); + $token = $this->getTokenData(array_shift($token)); // Set the required flag. $token->required = true; @@ -1267,13 +1259,6 @@ protected function getTokenData($token) ->select('t.term, t.term_id') ->from('#__finder_terms AS t'); - /* - * If the token is a phrase, the lookup process is fairly simple. If - * the token is a word, it is a little more complicated. We have to - * create two queries to lookup the term and the stem respectively, - * then union the result sets together. This is MUCH faster than using - * an or condition in the database query. - */ if ($token->phrase) { // Add the phrase to the query. @@ -1283,17 +1268,8 @@ protected function getTokenData($token) else { // Add the term to the query. - $query->where('t.term = ' . $db->quote($token->term)) + $query->where('(t.term = ' . $db->quote($token->term) . ' OR t.stem = ' . $db->quote($token->stem) . ')') ->where('t.phrase = 0'); - - // Clone the query, replace the WHERE clause. - $sub = clone $query; - $sub->clear('where'); - $sub->where('t.stem = ' . $db->quote($token->stem)); - $sub->where('t.phrase = 0'); - - // Union the two queries. - $query->union($sub); } // Get the terms. diff --git a/administrator/components/com_finder/helpers/indexer/stemmer.php b/administrator/components/com_finder/helpers/indexer/stemmer.php deleted file mode 100644 index 15ecc7cbb55cd..0000000000000 --- a/administrator/components/com_finder/helpers/indexer/stemmer.php +++ /dev/null @@ -1,83 +0,0 @@ -clean($adapter, 'cmd'); - $path = __DIR__ . '/stemmer/' . $adapter . '.php'; - $class = 'FinderIndexerStemmer' . ucfirst($adapter); - - // Check if a stemmer exists for the adapter. - if (!file_exists($path)) - { - // Throw invalid adapter exception. - throw new Exception(JText::sprintf('COM_FINDER_INDEXER_INVALID_STEMMER', $adapter)); - } - - // Instantiate the stemmer. - JLoader::register($class, $path); - $instances[$adapter] = new $class; - - return $instances[$adapter]; - } - - /** - * Method to stem a token and return the root. - * - * @param string $token The token to stem. - * @param string $lang The language of the token. - * - * @return string The root token. - * - * @since 2.5 - */ - abstract public function stem($token, $lang); -} diff --git a/administrator/components/com_finder/helpers/indexer/stemmer/fr.php b/administrator/components/com_finder/helpers/indexer/stemmer/fr.php deleted file mode 100644 index 8aa080efc5fff..0000000000000 --- a/administrator/components/com_finder/helpers/indexer/stemmer/fr.php +++ /dev/null @@ -1,265 +0,0 @@ -cache[$lang][$token])) - { - // Stem the token. - $result = self::getStem($token); - - // Add the token to the cache. - $this->cache[$lang][$token] = $result; - } - - return $this->cache[$lang][$token]; - } - - /** - * French stemmer rules variables. - * - * @return array The rules - * - * @since 3.0 - */ - protected static function getStemRules() - { - if (self::$stemRules) - { - return self::$stemRules; - } - - $vars = array(); - - // French accented letters in ISO-8859-1 encoding - $vars['accents'] = chr(224) . chr(226) . chr(232) . chr(233) . chr(234) . chr(235) . chr(238) . chr(239) - . chr(244) . chr(251) . chr(249) . chr(231); - - // The rule patterns include all accented words for french language - $vars['rule_pattern'] = '/^([a-z' . $vars['accents'] . ']*)(\*){0,1}(\d)([a-z' . $vars['accents'] . ']*)([.|>])/'; - - // French vowels (including y) in ISO-8859-1 encoding - $vars['vowels'] = chr(97) . chr(224) . chr(226) . chr(101) . chr(232) . chr(233) . chr(234) . chr(235) - . chr(105) . chr(238) . chr(239) . chr(111) . chr(244) . chr(117) . chr(251) . chr(249) . chr(121); - - // The French rules in ISO-8859-1 encoding - $vars['rules'] = array( - 'esre1>', 'esio1>', 'siol1.', 'siof0.', 'sioe0.', 'sio3>', 'st1>', 'sf1>', 'sle1>', 'slo1>', 's' . chr(233) . '1>', chr(233) . 'tuae5.', - chr(233) . 'tuae2.', 'tnia0.', 'tniv1.', 'tni3>', 'suor1.', 'suo0.', 'sdrail5.', 'sdrai4.', 'er' . chr(232) . 'i1>', 'sesue3x>', - 'esuey5i.', 'esue2x>', 'se1>', 'er' . chr(232) . 'g3.', 'eca1>', 'esiah0.', 'esi1>', 'siss2.', 'sir2>', 'sit2>', 'egan' . chr(233) . '1.', - 'egalli6>', 'egass1.', 'egas0.', 'egat3.', 'ega3>', 'ette4>', 'ett2>', 'etio1.', 'tio' . chr(231) . '4c.', 'tio0.', 'et1>', 'eb1>', - 'snia1>', 'eniatnau8>', 'eniatn4.', 'enia1>', 'niatnio3.', 'niatg3.', 'e' . chr(233) . '1>', chr(233) . 'hcat1.', chr(233) . 'hca4.', - chr(233) . 'tila5>', chr(233) . 'tici5.', chr(233) . 'tir1.', chr(233) . 'ti3>', chr(233) . 'gan1.', chr(233) . 'ga3>', - chr(233) . 'tehc1.', chr(233) . 'te3>', chr(233) . 'it0.', chr(233) . '1>', 'eire4.', 'eirue5.', 'eio1.', 'eia1.', 'ei1>', 'eng1.', - 'xuaessi7.', 'xuae1>', 'uaes0.', 'uae3.', 'xuave2l.', 'xuav2li>', 'xua3la>', 'ela1>', 'lart2.', 'lani2>', 'la' . chr(233) . '2>', - 'siay4i.', 'siassia7.', 'siarv1*.', 'sia1>', 'tneiayo6i.', 'tneiay6i.', 'tneiassia9.', 'tneiareio7.', 'tneia5>', 'tneia4>', 'tiario4.', - 'tiarim3.', 'tiaria3.', 'tiaris3.', 'tiari5.', 'tiarve6>', 'tiare5>', 'iare4>', 'are3>', 'tiay4i.', 'tia3>', 'tnay4i.', - 'em' . chr(232) . 'iu5>', 'em' . chr(232) . 'i4>', 'tnaun3.', 'tnauqo3.', 'tnau4>', 'tnaf0.', 'tnat' . chr(233) . '2>', 'tna3>', 'tno3>', - 'zeiy4i.', 'zey3i.', 'zeire5>', 'zeird4.', 'zeirio4.', 'ze2>', 'ssiab0.', 'ssia4.', 'ssi3.', 'tnemma6>', 'tnemesuey9i.', 'tnemesue8>', - 'tnemevi7.', 'tnemessia5.', 'tnemessi8.', 'tneme5>', 'tnemia4.', 'tnem' . chr(233) . '5>', 'el2l>', 'lle3le>', 'let' . chr(244) . '0.', - 'lepp0.', 'le2>', 'srei1>', 'reit3.', 'reila2.', 'rei3>', 'ert' . chr(226) . 'e5.', 'ert' . chr(226) . chr(233) . '1.', - 'ert' . chr(226) . '4.', 'drai4.', 'erdro0.', 'erute5.', 'ruta0.', 'eruta1.', 'erutiov1.', 'erub3.', 'eruh3.', 'erul3.', 'er2r>', 'nn1>', - 'r' . chr(232) . 'i3.', 'srev0.', 'sr1>', 'rid2>', 're2>', 'xuei4.', 'esuei5.', 'lbati3.', 'lba3>', 'rueis0.', 'ruehcn4.', 'ecirta6.', - 'ruetai6.', 'rueta5.', 'rueir0.', 'rue3>', 'esseti6.', 'essere6>', 'esserd1.', 'esse4>', 'essiab1.', 'essia5.', 'essio1.', 'essi4.', - 'essal4.', 'essa1>', 'ssab1.', 'essurp1.', 'essu4.', 'essi1.', 'ssor1.', 'essor2.', 'esso1>', 'ess2>', 'tio3.', 'r' . chr(232) . 's2re.', - 'r' . chr(232) . '0e.', 'esn1.', 'eu1>', 'sua0.', 'su1>', 'utt1>', 'tu' . chr(231) . '3c.', 'u' . chr(231) . '2c.', 'ur1.', 'ehcn2>', - 'ehcu1>', 'snorr3.', 'snoru3.', 'snorua3.', 'snorv3.', 'snorio4.', 'snori5.', 'snore5>', 'snortt4>', 'snort' . chr(238) . 'a7.', 'snort3.', - 'snor4.', 'snossi6.', 'snoire6.', 'snoird5.', 'snoitai7.', 'snoita6.', 'snoits1>', 'noits0.', 'snoi4>', 'noitaci7>', 'noitai6.', 'noita5.', - 'noitu4.', 'noi3>', 'snoya0.', 'snoy4i.', 'sno' . chr(231) . 'a1.', 'sno' . chr(231) . 'r1.', 'snoe4.', 'snosiar1>', 'snola1.', 'sno3>', - 'sno1>', 'noll2.', 'tnennei4.', 'ennei2>', 'snei1>', 'sne' . chr(233) . '1>', 'enne' . chr(233) . '5e.', 'ne' . chr(233) . '3e.', 'neic0.', - 'neiv0.', 'nei3.', 'sc1.', 'sd1.', 'sg1.', 'sni1.', 'tiu0.', 'ti2.', 'sp1>', 'sna1>', 'sue1.', 'enn2>', 'nong2.', 'noss2.', 'rioe4.', - 'riot0.', 'riorc1.', 'riovec5.', 'rio3.', 'ric2.', 'ril2.', 'tnerim3.', 'tneris3>', 'tneri5.', 't' . chr(238) . 'a3.', 'riss2.', - 't' . chr(238) . '2.', 't' . chr(226) . '2>', 'ario2.', 'arim1.', 'ara1.', 'aris1.', 'ari3.', 'art1>', 'ardn2.', 'arr1.', 'arua1.', - 'aro1.', 'arv1.', 'aru1.', 'ar2.', 'rd1.', 'ud1.', 'ul1.', 'ini1.', 'rin2.', 'tnessiab3.', 'tnessia7.', 'tnessi6.', 'tnessni4.', 'sini2.', - 'sl1.', 'iard3.', 'iario3.', 'ia2>', 'io0.', 'iule2.', 'i1>', 'sid2.', 'sic2.', 'esoi4.', 'ed1.', 'ai2>', 'a1>', 'adr1.', - 'tner' . chr(232) . '5>', 'evir1.', 'evio4>', 'evi3.', 'fita4.', 'fi2>', 'enie1.', 'sare4>', 'sari4>', 'sard3.', 'sart2>', 'sa2.', - 'tnessa6>', 'tnessu6>', 'tnegna3.', 'tnegi3.', 'tneg0.', 'tneru5>', 'tnemg0.', 'tnerni4.', 'tneiv1.', 'tne3>', 'une1.', 'en1>', 'nitn2.', - 'ecnay5i.', 'ecnal1.', 'ecna4.', 'ec1>', 'nn1.', 'rit2>', 'rut2>', 'rud2.', 'ugn1>', 'eg1>', 'tuo0.', 'tul2>', 't' . chr(251) . '2>', - 'ev1>', 'v' . chr(232) . '2ve>', 'rtt1>', 'emissi6.', 'em1.', 'ehc1.', 'c' . chr(233) . 'i2c' . chr(232) . '.', 'libi2l.', 'llie1.', - 'liei4i.', 'xuev1.', 'xuey4i.', 'xueni5>', 'xuell4.', 'xuere5.', 'xue3>', 'rb' . chr(233) . '3rb' . chr(232) . '.', 'tur2.', - 'rir' . chr(233) . '4re.', 'rir2.', 'c' . chr(226) . '2ca.', 'snu1.', 'rt' . chr(238) . 'a4.', 'long2.', 'vec2.', chr(231) . '1c>', - 'ssilp3.', 'silp2.', 't' . chr(232) . 'hc2te.', 'n' . chr(232) . 'm2ne.', 'llepp1.', 'tan2.', 'rv' . chr(232) . '3rve.', - 'rv' . chr(233) . '3rve.', 'r' . chr(232) . '2re.', 'r' . chr(233) . '2re.', 't' . chr(232) . '2te.', 't' . chr(233) . '2te.', 'epp1.', - 'eya2i.', 'ya1i.', 'yo1i.', 'esu1.', 'ugi1.', 'tt1.', 'end0.' - ); - - self::$stemRules = $vars; - - return self::$stemRules; - } - - /** - * Returns the number of the first rule from the rule number - * 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 - * - * @return integer Number of the first rule - * - * @since 3.0 - */ - private static function getFirstRule($reversed_input, $rule_number) - { - $vars = static::getStemRules(); - - $nb_rules = count($vars['rules']); - - for ($i = $rule_number; $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) - { - return $i; - } - } - - return -1; - } - - /** - * Check the acceptability of a stem for French language - * - * @param string $reversed_stem The stem to check in reverse form - * - * @return boolean True if stem is acceptable - * - * @since 3.0 - */ - private static function check($reversed_stem) - { - $vars = static::getStemRules(); - - if (preg_match('/[' . $vars['vowels'] . ']$/', utf8_encode($reversed_stem))) - { - // 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); - } - else - { - // If the reversed stem starts with a consonant then at least two letters must remain after stemming - if (strlen($reversed_stem) <= 2) - { - return false; - } - - // And at least one of these must be a vowel or "y" - return preg_match('/[' . $vars['vowels'] . ']/', utf8_encode($reversed_stem)); - } - } - - /** - * Paice/Husk stemmer which returns a stem for the given $input - * - * @param string $input The word for which we want the stem in UTF-8 - * - * @return string The stem - * - * @since 3.0 - */ - private static function getStem($input) - { - $vars = static::getStemRules(); - - $intact = true; - $reversed_input = strrev(utf8_decode($input)); - $rule_number = 0; - - // This loop goes through the rules' array until it finds an ending one (ending by '.') or the last one ('end0.') - while (true) - { - $rule_number = self::getFirstRule($reversed_input, $rule_number); - - if ($rule_number == -1) - { - // No other rule can be applied => the stem has been found - break; - } - - $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]); - - if (self::check($reversed_stem)) - { - $reversed_input = $reversed_stem; - - if ($matches[5] == '.') - { - break; - } - } - else - { - // Go to another rule - $rule_number++; - } - } - else - { - // Go to another rule - $rule_number++; - } - } - - return utf8_encode(strrev($reversed_input)); - } -} diff --git a/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php b/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php deleted file mode 100644 index e1649958f2b21..0000000000000 --- a/administrator/components/com_finder/helpers/indexer/stemmer/porter_en.php +++ /dev/null @@ -1,446 +0,0 @@ -cache[$lang][$token])) - { - // Stem the token. - $result = $token; - $result = self::step1ab($result); - $result = self::step1c($result); - $result = self::step2($result); - $result = self::step3($result); - $result = self::step4($result); - $result = self::step5($result); - - // Add the token to the cache. - $this->cache[$lang][$token] = $result; - } - - return $this->cache[$lang][$token]; - } - - /** - * Step 1 - * - * @param string $word The token to stem. - * - * @return string - * - * @since 2.5 - */ - private static function step1ab($word) - { - // Part a - if (substr($word, -1) == 's') - { - self::replace($word, 'sses', 'ss') - || self::replace($word, 'ies', 'i') - || self::replace($word, 'ss', 'ss') - || self::replace($word, 's', ''); - } - - // Part b - if (substr($word, -2, 1) != 'e' || !self::replace($word, 'eed', 'ee', 0)) - { - // First rule - $v = self::$regex_vowel; - - // 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', '') - || preg_match("#$v+#", substr($word, 0, -2)) && self::replace($word, 'ed', '')) - { - // If one of above two test successful - if (!self::replace($word, 'at', 'ate') && !self::replace($word, 'bl', 'ble') && !self::replace($word, 'iz', 'ize')) - { - // Double consonant ending - if (self::doubleConsonant($word) && substr($word, -2) != 'll' && substr($word, -2) != 'ss' && substr($word, -2) != 'zz') - { - $word = substr($word, 0, -1); - } - elseif (self::m($word) == 1 && self::cvc($word)) - { - $word .= 'e'; - } - } - } - } - - return $word; - } - - /** - * Step 1c - * - * @param string $word The token to stem. - * - * @return string - * - * @since 2.5 - */ - private static function step1c($word) - { - $v = self::$regex_vowel; - - if (substr($word, -1) == 'y' && preg_match("#$v+#", substr($word, 0, -1))) - { - self::replace($word, 'y', 'i'); - } - - return $word; - } - - /** - * Step 2 - * - * @param string $word The token to stem. - * - * @return string - * - * @since 2.5 - */ - private static function step2($word) - { - switch (substr($word, -2, 1)) - { - case 'a': - self::replace($word, 'ational', 'ate', 0) - || self::replace($word, 'tional', 'tion', 0); - break; - case 'c': - self::replace($word, 'enci', 'ence', 0) - || self::replace($word, 'anci', 'ance', 0); - break; - case 'e': - self::replace($word, 'izer', 'ize', 0); - break; - case 'g': - self::replace($word, 'logi', 'log', 0); - break; - case 'l': - self::replace($word, 'entli', 'ent', 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) - || self::replace($word, 'ation', 'ate', 0) - || self::replace($word, 'ator', 'ate', 0); - break; - case 's': - self::replace($word, 'iveness', 'ive', 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) - || self::replace($word, 'aliti', 'al', 0) - || self::replace($word, 'iviti', 'ive', 0); - break; - } - - return $word; - } - - /** - * Step 3 - * - * @param string $word The token to stem. - * - * @return string - * - * @since 2.5 - */ - private static function step3($word) - { - switch (substr($word, -2, 1)) - { - case 'a': - self::replace($word, 'ical', 'ic', 0); - break; - case 's': - self::replace($word, 'ness', '', 0); - break; - case 't': - self::replace($word, 'icate', 'ic', 0) - || self::replace($word, 'iciti', 'ic', 0); - break; - case 'u': - self::replace($word, 'ful', '', 0); - break; - case 'v': - self::replace($word, 'ative', '', 0); - break; - case 'z': - self::replace($word, 'alize', 'al', 0); - break; - } - - return $word; - } - - /** - * Step 4 - * - * @param string $word The token to stem. - * - * @return string - * - * @since 2.5 - */ - private static function step4($word) - { - switch (substr($word, -2, 1)) - { - case 'a': - self::replace($word, 'al', '', 1); - break; - case 'c': - self::replace($word, 'ance', '', 1) - || self::replace($word, 'ence', '', 1); - break; - case 'e': - self::replace($word, 'er', '', 1); - break; - case 'i': - self::replace($word, 'ic', '', 1); - break; - case 'l': - self::replace($word, 'able', '', 1) - || self::replace($word, 'ible', '', 1); - break; - case 'n': - self::replace($word, 'ant', '', 1) - || self::replace($word, 'ement', '', 1) - || self::replace($word, 'ment', '', 1) - || self::replace($word, 'ent', '', 1); - break; - case 'o': - if (substr($word, -4) == 'tion' || substr($word, -4) == 'sion') - { - self::replace($word, 'ion', '', 1); - } - else - { - self::replace($word, 'ou', '', 1); - } - break; - case 's': - self::replace($word, 'ism', '', 1); - break; - case 't': - self::replace($word, 'ate', '', 1) - || self::replace($word, 'iti', '', 1); - break; - case 'u': - self::replace($word, 'ous', '', 1); - break; - case 'v': - self::replace($word, 'ive', '', 1); - break; - case 'z': - self::replace($word, 'ize', '', 1); - break; - } - - return $word; - } - - /** - * Step 5 - * - * @param string $word The token to stem. - * - * @return string - * - * @since 2.5 - */ - private static function step5($word) - { - // Part a - 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) - { - if (!self::cvc(substr($word, 0, -1))) - { - self::replace($word, 'e', ''); - } - } - } - - // Part b - if (self::m($word) > 1 && self::doubleConsonant($word) && substr($word, -1) == 'l') - { - $word = substr($word, 0, -1); - } - - return $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 $check Ending to check for - * @param string $repl Replacement string - * @param integer $m Optional minimum number of m() to meet - * - * @return boolean Whether the $check string was at the end - * of the $str string. True does not necessarily mean - * that it was replaced. - * - * @since 2.5 - */ - private static function replace(&$str, $check, $repl, $m = null) - { - $len = 0 - strlen($check); - - if (substr($str, $len) == $check) - { - $substr = substr($str, 0, $len); - - if (is_null($m) || self::m($substr) > $m) - { - $str = $substr . $repl; - } - - return true; - } - - return false; - } - - /** - * m() measures the number of consonant sequences in $str. if c is - * a consonant sequence and v a vowel sequence, and <..> indicates arbitrary - * presence, - * - * gives 0 - * vc gives 1 - * vcvc gives 2 - * vcvcvc gives 3 - * - * @param string $str The string to return the m count for - * - * @return integer The m count - * - * @since 2.5 - */ - private static function m($str) - { - $c = self::$regex_consonant; - $v = self::$regex_vowel; - - $str = preg_replace("#^$c+#", '', $str); - $str = preg_replace("#$v+$#", '', $str); - - preg_match_all("#($v+$c+)#", $str, $matches); - - return count($matches[1]); - } - - /** - * Returns true/false as to whether the given string contains two - * of the same consonant next to each other at the end of the string. - * - * @param string $str String to check - * - * @return boolean Result - * - * @since 2.5 - */ - private static function doubleConsonant($str) - { - $c = self::$regex_consonant; - - return preg_match("#$c{2}$#", $str, $matches) && $matches[0]{0} == $matches[0]{1}; - } - - /** - * Checks for ending CVC sequence where second C is not W, X or Y - * - * @param string $str String to check - * - * @return boolean Result - * - * @since 2.5 - */ - private static function cvc($str) - { - $c = self::$regex_consonant; - $v = self::$regex_vowel; - - 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 deleted file mode 100644 index 44a8899654a72..0000000000000 --- a/administrator/components/com_finder/helpers/indexer/stemmer/snowball.php +++ /dev/null @@ -1,133 +0,0 @@ -sef) ? $languages[0]->sef : '*'; - $lang = $defaultLang; - } - - // Stem the token if it is not in the cache. - if (!isset($this->cache[$lang][$token])) - { - // Get the stem function from the language string. - switch ($lang) - { - // Danish stemmer. - case 'da': - $function = 'stem_danish'; - break; - - // German stemmer. - case 'de': - $function = 'stem_german'; - break; - - // English stemmer. - default: - case 'en': - $function = 'stem_english'; - break; - - // Spanish stemmer. - case 'es': - $function = 'stem_spanish'; - break; - - // Finnish stemmer. - case 'fi': - $function = 'stem_finnish'; - break; - - // French stemmer. - case 'fr': - $function = 'stem_french'; - break; - - // Hungarian stemmer. - case 'hu': - $function = 'stem_hungarian'; - break; - - // Italian stemmer. - case 'it': - $function = 'stem_italian'; - break; - - // Norwegian stemmer. - case 'nb': - $function = 'stem_norwegian'; - break; - - // Dutch stemmer. - case 'nl': - $function = 'stem_dutch'; - break; - - // Portuguese stemmer. - case 'pt': - $function = 'stem_portuguese'; - break; - - // Romanian stemmer. - case 'ro': - $function = 'stem_romanian'; - break; - - // Russian stemmer. - case 'ru': - $function = 'stem_russian_unicode'; - break; - - // Swedish stemmer. - case 'sv': - $function = 'stem_swedish'; - break; - - // Turkish stemmer. - case 'tr': - $function = 'stem_turkish_unicode'; - break; - } - - // Stem the word if the stemmer method exists. - $this->cache[$lang][$token] = function_exists($function) ? $function($token) : $token; - } - - return $this->cache[$lang][$token]; - } -} diff --git a/administrator/components/com_finder/helpers/indexer/taxonomy.php b/administrator/components/com_finder/helpers/indexer/taxonomy.php index 92637310965b5..0b90dde30d38f 100644 --- a/administrator/components/com_finder/helpers/indexer/taxonomy.php +++ b/administrator/components/com_finder/helpers/indexer/taxonomy.php @@ -10,7 +10,7 @@ defined('_JEXEC') or die; /** - * Stemmer base class for the Finder indexer package. + * Taxonomy base class for the Finder indexer package. * * @since 2.5 */ diff --git a/administrator/components/com_finder/helpers/indexer/token.php b/administrator/components/com_finder/helpers/indexer/token.php index ec8040983605d..40ea5ec9ff406 100644 --- a/administrator/components/com_finder/helpers/indexer/token.php +++ b/administrator/components/com_finder/helpers/indexer/token.php @@ -98,7 +98,14 @@ class FinderIndexerToken */ public function __construct($term, $lang, $spacer = ' ') { - $this->language = $lang; + if (!$lang) + { + $this->language = '*'; + } + else + { + $this->language = $lang; + } // Tokens can be a single word or an array of words representing a phrase. if (is_array($term)) diff --git a/administrator/components/com_finder/helpers/language.php b/administrator/components/com_finder/helpers/language.php index dce9e644e5edb..a8a860452edaa 100644 --- a/administrator/components/com_finder/helpers/language.php +++ b/administrator/components/com_finder/helpers/language.php @@ -14,131 +14,7 @@ * * @since 2.5 */ -class FinderHelperLanguage +class FinderHelperLanguage extends \Joomla\Component\Finder\Administrator\Helper\FinderHelperLanguage { - /** - * Method to return a plural language code for a taxonomy branch. - * - * @param string $branchName Branch title. - * - * @return string Language key code. - * - * @since 2.5 - */ - public static function branchPlural($branchName) - { - $return = preg_replace('/[^a-zA-Z0-9]+/', '_', strtoupper($branchName)); - if ($return !== '_') - { - return 'PLG_FINDER_QUERY_FILTER_BRANCH_P_' . $return; - } - - return $branchName; - } - - /** - * Method to return a singular language code for a taxonomy branch. - * - * @param string $branchName Branch name. - * - * @return string Language key code. - * - * @since 2.5 - */ - public static function branchSingular($branchName) - { - $return = preg_replace('/[^a-zA-Z0-9]+/', '_', strtoupper($branchName)); - - return 'PLG_FINDER_QUERY_FILTER_BRANCH_S_' . $return; - } - - /** - * Method to return the language name for a language taxonomy branch. - * - * @param string $branchName Language branch name. - * - * @return string The language title. - * - * @since 3.6.0 - */ - public static function branchLanguageTitle($branchName) - { - $title = $branchName; - - if ($branchName === '*') - { - $title = JText::_('JALL_LANGUAGE'); - } - else - { - $languages = JLanguageHelper::getLanguages('lang_code'); - - if (isset($languages[$branchName])) - { - $title = $languages[$branchName]->title; - } - } - - return $title; - } - - /** - * Method to load Smart Search component language file. - * - * @return void - * - * @since 2.5 - */ - public static function loadComponentLanguage() - { - JFactory::getLanguage()->load('com_finder', JPATH_SITE); - } - - /** - * Method to load Smart Search plugin language files. - * - * @return void - * - * @since 2.5 - */ - public static function loadPluginLanguage() - { - static $loaded = false; - - // If already loaded, don't load again. - if ($loaded) - { - return; - } - - $loaded = true; - - // Get array of all the enabled Smart Search plugin names. - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select(array($db->qn('name'), $db->qn('element'))) - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) - ->where($db->quoteName('folder') . ' = ' . $db->quote('finder')) - ->where($db->quoteName('enabled') . ' = 1'); - $db->setQuery($query); - $plugins = $db->loadObjectList(); - - if (empty($plugins)) - { - return; - } - - // Load generic language strings. - $lang = JFactory::getLanguage(); - $lang->load('plg_content_finder', JPATH_ADMINISTRATOR); - - // Load language file for each plugin. - foreach ($plugins as $plugin) - { - $lang->load($plugin->name, JPATH_ADMINISTRATOR) - || $lang->load($plugin->name, JPATH_PLUGINS . '/finder/' . $plugin->element); - } - } } diff --git a/administrator/components/com_finder/models/fields/branches.php b/administrator/components/com_finder/models/fields/branches.php deleted file mode 100644 index 5e36f32971a76..0000000000000 --- a/administrator/components/com_finder/models/fields/branches.php +++ /dev/null @@ -1,40 +0,0 @@ -getQuery(true); - $levelQuery->select('title AS branch_title, 1 as level') - ->select($db->quoteName('id')) - ->from($db->quoteName('#__finder_taxonomy')) - ->where($db->quoteName('parent_id') . ' = 1'); - $levelQuery2 = $db->getQuery(true); - $levelQuery2->select('b.title AS branch_title, 2 as level') - ->select($db->quoteName('a.id')) - ->from($db->quoteName('#__finder_taxonomy', 'a')) - ->join('LEFT', $db->quoteName('#__finder_taxonomy', 'b') . ' ON ' . $db->qn('a.parent_id') . ' = ' . $db->qn('b.id')) - ->where($db->quoteName('a.parent_id') . ' NOT IN (0, 1)'); - - $levelQuery->union($levelQuery2); - - // Main query. - $query = $db->getQuery(true) - ->select($db->quoteName('a.title', 'text')) - ->select($db->quoteName('a.id', 'value')) - ->select($db->quoteName('d.level')) - ->from($db->quoteName('#__finder_taxonomy', 'a')) - ->join('LEFT', '(' . $levelQuery . ') AS d ON ' . $db->qn('d.id') . ' = ' . $db->qn('a.id')) - ->where($db->quoteName('a.parent_id') . ' <> 0') - ->order('d.branch_title ASC, d.level ASC, a.title ASC'); - - $db->setQuery($query); - - try - { - $contentMap = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - return; - } - - // Build the grouped list array. - if ($contentMap) - { - $lang = JFactory::getLanguage(); - - foreach ($contentMap as $branch) - { - if ((int) $branch->level === 1) - { - $name = $branch->text; - } - else - { - $levelPrefix = str_repeat('- ', max(0, $branch->level - 1)); - - if (trim($name, '**') === 'Language') - { - $text = FinderHelperLanguage::branchLanguageTitle($branch->text); - } - else - { - $key = FinderHelperLanguage::branchSingular($branch->text); - $text = $lang->hasKey($key) ? JText::_($key) : $branch->text; - } - - // Initialize the group if necessary. - if (!isset($groups[$name])) - { - $groups[$name] = array(); - } - - $groups[$name][] = JHtml::_('select.option', $branch->value, $levelPrefix . $text); - } - } - } - - // Merge any additional groups in the XML definition. - $groups = array_merge(parent::getGroups(), $groups); - - return $groups; - } -} diff --git a/administrator/components/com_finder/models/fields/contenttypes.php b/administrator/components/com_finder/models/fields/contenttypes.php deleted file mode 100644 index 013f833a16caa..0000000000000 --- a/administrator/components/com_finder/models/fields/contenttypes.php +++ /dev/null @@ -1,84 +0,0 @@ -getQuery(true) - ->select($db->quoteName('id', 'value')) - ->select($db->quoteName('title', 'text')) - ->from($db->quoteName('#__finder_types')); - - // Get the options. - $db->setQuery($query); - - try - { - $contentTypes = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $db->getMessage()); - } - - // Translate. - foreach ($contentTypes as $contentType) - { - $key = FinderHelperLanguage::branchSingular($contentType->text); - $contentType->translatedText = $lang->hasKey($key) ? JText::_($key) : $contentType->text; - } - - // Order by title. - $contentTypes = ArrayHelper::sortObjects($contentTypes, 'translatedText', 1, true, true); - - // Convert the values to options. - foreach ($contentTypes as $contentType) - { - $options[] = JHtml::_('select.option', $contentType->value, $contentType->translatedText); - } - - // Merge any additional options in the XML definition. - $options = array_merge(parent::getOptions(), $options); - - return $options; - } -} diff --git a/administrator/components/com_finder/models/fields/directories.php b/administrator/components/com_finder/models/fields/directories.php deleted file mode 100644 index 49dc6c995725f..0000000000000 --- a/administrator/components/com_finder/models/fields/directories.php +++ /dev/null @@ -1,93 +0,0 @@ -get('log_path'), - JFactory::getApplication()->get('tmp_path') - ); - - // Get the base directories. - jimport('joomla.filesystem.folder'); - $dirs = JFolder::folders(JPATH_SITE, '.', false, true); - - // Iterate through the base directories and find the subdirectories. - foreach ($dirs as $dir) - { - // Check if the directory should be excluded. - if (in_array($dir, $exclude)) - { - continue; - } - - // Get the child directories. - $return = JFolder::folders($dir, '.', true, true); - - // Merge the directories. - if (is_array($return)) - { - $values[] = $dir; - $values = array_merge($values, $return); - } - } - - // Convert the values to options. - foreach ($values as $value) - { - $options[] = JHtml::_('select.option', str_replace(JPATH_SITE . '/', '', $value), str_replace(JPATH_SITE . '/', '', $values)); - } - - // Add a null option. - array_unshift($options, JHtml::_('select.option', '', '- ' . JText::_('JNONE') . ' -')); - - return $options; - } -} diff --git a/administrator/components/com_finder/models/fields/searchfilter.php b/administrator/components/com_finder/models/fields/searchfilter.php deleted file mode 100644 index 07fa70aadb885..0000000000000 --- a/administrator/components/com_finder/models/fields/searchfilter.php +++ /dev/null @@ -1,52 +0,0 @@ -getQuery(true) - ->select('f.title AS text, f.filter_id AS value') - ->from($db->quoteName('#__finder_filters') . ' AS f') - ->where('f.state = 1') - ->order('f.title ASC'); - $db->setQuery($query); - $options = $db->loadObjectList(); - - array_unshift($options, JHtml::_('select.option', '', JText::_('COM_FINDER_SELECT_SEARCH_FILTER'), 'value', 'text')); - - return $options; - } -} diff --git a/administrator/components/com_finder/models/filter.php b/administrator/components/com_finder/models/filter.php deleted file mode 100644 index 3c9290271dc99..0000000000000 --- a/administrator/components/com_finder/models/filter.php +++ /dev/null @@ -1,173 +0,0 @@ -getState('filter.id'); - - // Get a FinderTableFilter instance. - $filter = $this->getTable(); - - // Attempt to load the row. - $return = $filter->load($filter_id); - - // Check for a database error. - if ($return === false && $filter->getError()) - { - $this->setError($filter->getError()); - - return false; - } - - // Process the filter data. - if (!empty($filter->data)) - { - $filter->data = explode(',', $filter->data); - } - elseif (empty($filter->data)) - { - $filter->data = array(); - } - - // Check for a database error. - if ($this->_db->getErrorNum()) - { - $this->setError($this->_db->getErrorMsg()); - - return false; - } - - return $filter; - } - - /** - * Method to get the record form. - * - * @param array $data Data for the form. [optional] - * @param boolean $loadData True if the form is to load its own data (default case), false if not. [optional] - * - * @return JForm|boolean A JForm object on success, false on failure - * - * @since 2.5 - */ - public function getForm($data = array(), $loadData = true) - { - // Get the form. - $form = $this->loadForm('com_finder.filter', 'filter', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Returns a JTable object, always creating it. - * - * @param string $type The table type to instantiate. [optional] - * @param string $prefix A prefix for the table class name. [optional] - * @param array $config Configuration array for model. [optional] - * - * @return JTable A database object - * - * @since 2.5 - */ - public function getTable($type = 'Filter', $prefix = 'FinderTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 2.5 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_finder.edit.filter.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - $this->preprocessData('com_finder.filter', $data); - - return $data; - } - - /** - * Method to get the total indexed items - * - * @return number the number of indexed items - * - * @since 3.5 - */ - public function getTotal() - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('MAX(link_id)') - ->from('#__finder_links'); - - return $db->setQuery($query)->loadResult(); - } -} diff --git a/administrator/components/com_finder/models/filters.php b/administrator/components/com_finder/models/filters.php deleted file mode 100644 index 48e8e0ca3c2cf..0000000000000 --- a/administrator/components/com_finder/models/filters.php +++ /dev/null @@ -1,134 +0,0 @@ -getDbo(); - $query = $db->getQuery(true); - - // Select all fields from the table. - $query->select('a.*') - ->from($db->quoteName('#__finder_filters', 'a')); - - // Join over the users for the checked out user. - $query->select($db->quoteName('uc.name', 'editor')) - ->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON ' . $db->quoteName('uc.id') . ' = ' . $db->quoteName('a.checked_out')); - - // Join over the users for the author. - $query->select($db->quoteName('ua.name', 'user_name')) - ->join('LEFT', $db->quoteName('#__users', 'ua') . ' ON ' . $db->quoteName('ua.id') . ' = ' . $db->quoteName('a.created_by')); - - // Check for a search filter. - if ($search = $this->getState('filter.search')) - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where($db->quoteName('a.title') . ' LIKE ' . $search); - } - - // If the model is set to check item state, add to the query. - $state = $this->getState('filter.state'); - - if (is_numeric($state)) - { - $query->where($db->quoteName('a.state') . ' = ' . (int) $state); - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.title') . ' ' . $db->escape($this->getState('list.direction', 'ASC')))); - - 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. [optional] - * - * @return string A store id. - * - * @since 2.5 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.state'); - - return parent::getStoreId($id); - } - - /** - * Method to auto-populate the model state. Calling getState in this method will result in recursion. - * - * @param string $ordering An optional ordering field. [optional] - * @param string $direction An optional direction. [optional] - * - * @return void - * - * @since 2.5 - */ - protected function populateState($ordering = 'a.title', $direction = 'asc') - { - // Load the filter state. - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); - - // Load the parameters. - $params = JComponentHelper::getParams('com_finder'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } -} diff --git a/administrator/components/com_finder/models/index.php b/administrator/components/com_finder/models/index.php deleted file mode 100644 index d1862184e6ba7..0000000000000 --- a/administrator/components/com_finder/models/index.php +++ /dev/null @@ -1,455 +0,0 @@ -authorise('core.delete', $this->option); - } - - /** - * 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 for the component. - * - * @since 2.5 - */ - protected function canEditState($record) - { - return JFactory::getUser()->authorise('core.edit.state', $this->option); - } - - /** - * Method to delete one or more records. - * - * @param array &$pks An array of record primary keys. - * - * @return boolean True if successful, false if an error occurs. - * - * @since 2.5 - */ - public function delete(&$pks) - { - $dispatcher = JEventDispatcher::getInstance(); - $pks = (array) $pks; - $table = $this->getTable(); - - // Include the content plugins for the on delete events. - JPluginHelper::importPlugin('content'); - - // Iterate the items to delete each one. - foreach ($pks as $i => $pk) - { - if ($table->load($pk)) - { - if ($this->canDelete($table)) - { - $context = $this->option . '.' . $this->name; - - // Trigger the onContentBeforeDelete event. - $result = $dispatcher->trigger($this->event_before_delete, array($context, $table)); - - if (in_array(false, $result, true)) - { - $this->setError($table->getError()); - - return false; - } - - if (!$table->delete($pk)) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the onContentAfterDelete event. - $dispatcher->trigger($this->event_after_delete, array($context, $table)); - } - else - { - // Prune items that you can't change. - unset($pks[$i]); - $error = $this->getError(); - - if ($error) - { - $this->setError($error); - } - else - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); - } - } - } - else - { - $this->setError($table->getError()); - - return false; - } - } - - // Clear the component's cache - $this->cleanCache(); - - return true; - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery A JDatabaseQuery object - * - * @since 2.5 - */ - protected function getListQuery() - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('l.*') - ->select($db->quoteName('t.title', 't_title')) - ->from($db->quoteName('#__finder_links', 'l')) - ->join('INNER', $db->quoteName('#__finder_types', 't') . ' ON ' . $db->quoteName('t.id') . ' = ' . $db->quoteName('l.type_id')); - - // Check the type filter. - $type = $this->getState('filter.type'); - - if (is_numeric($type)) - { - $query->where($db->quoteName('l.type_id') . ' = ' . (int) $type); - } - - // Check the map filter. - $contentMapId = $this->getState('filter.content_map'); - - if (is_numeric($contentMapId)) - { - $query->join('INNER', $db->quoteName('#__finder_taxonomy_map', 'm') . ' ON ' . $db->quoteName('m.link_id') . ' = ' . $db->quoteName('l.link_id')) - ->where($db->quoteName('m.node_id') . ' = ' . (int) $contentMapId); - } - - // Check for state filter. - $state = $this->getState('filter.state'); - - if (is_numeric($state)) - { - $query->where($db->quoteName('l.published') . ' = ' . (int) $state); - } - - // Check the search phrase. - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $orSearchSql = $db->quoteName('l.title') . ' LIKE ' . $search . ' OR ' . $db->quoteName('l.url') . ' LIKE ' . $search; - - // Filter by indexdate only if $search doesn't contains non-ascii characters - if (!preg_match('/[^\x00-\x7F]/', $search)) - { - $orSearchSql .= ' OR ' . $query->castAsChar($db->quoteName('l.indexdate')) . ' LIKE ' . $search; - } - - $query->where('(' . $orSearchSql . ')'); - } - - // Handle the list ordering. - $listOrder = $this->getState('list.ordering', 'l.title'); - $listDir = $this->getState('list.direction', 'ASC'); - - if ($listOrder === 't.title') - { - $ordering = $db->quoteName('t.title') . ' ' . $db->escape($listDir) . ', ' . $db->quoteName('l.title') . ' ' . $db->escape($listDir); - } - else - { - $ordering = $db->escape($listOrder) . ' ' . $db->escape($listDir); - } - - $query->order($ordering); - - return $query; - } - - /** - * Method to get the state of the Smart Search Plugins. - * - * @return array Array of relevant plugins and whether they are enabled or not. - * - * @since 2.5 - */ - public function getPluginState() - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('name, enabled') - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) - ->where($db->quoteName('folder') . ' IN (' . $db->quote('system') . ',' . $db->quote('content') . ')') - ->where($db->quoteName('element') . ' = ' . $db->quote('finder')); - $db->setQuery($query); - - return $db->loadObjectList('name'); - } - - /** - * 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. [optional] - * - * @return string A store id. - * - * @since 2.5 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.state'); - $id .= ':' . $this->getState('filter.type'); - $id .= ':' . $this->getState('filter.content_map'); - - return parent::getStoreId($id); - } - - /** - * Gets the total of indexed items. - * - * @return integer The total of indexed items. - * - * @since 3.6.0 - */ - public function getTotalIndexed() - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('COUNT(link_id)') - ->from($db->quoteName('#__finder_links')); - $db->setQuery($query); - - $db->execute(); - - return (int) $db->loadResult(); - } - - /** - * Returns a JTable object, always creating it. - * - * @param string $type The table type to instantiate. [optional] - * @param string $prefix A prefix for the table class name. [optional] - * @param array $config Configuration array for model. [optional] - * - * @return JTable A database object - * - * @since 2.5 - */ - public function getTable($type = 'Link', $prefix = 'FinderTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Method to purge the index, deleting all links. - * - * @return boolean True on success, false on failure. - * - * @since 2.5 - * @throws Exception on database error - */ - public function purge() - { - $db = $this->getDbo(); - - // Truncate the links table. - $db->truncateTable('#__finder_links'); - - // Truncate the links terms tables. - for ($i = 0; $i <= 15; $i++) - { - // Get the mapping table suffix. - $suffix = dechex($i); - - $db->truncateTable('#__finder_links_terms' . $suffix); - } - - // Truncate the terms table. - $db->truncateTable('#__finder_terms'); - - // Truncate the taxonomy map table. - $db->truncateTable('#__finder_taxonomy_map'); - - // Delete all the taxonomy nodes except the root. - $query = $db->getQuery(true) - ->delete($db->quoteName('#__finder_taxonomy')) - ->where($db->quoteName('id') . ' > 1'); - $db->setQuery($query); - $db->execute(); - - // Truncate the tokens tables. - $db->truncateTable('#__finder_tokens'); - - // Truncate the tokens aggregate table. - $db->truncateTable('#__finder_tokens_aggregate'); - - return true; - } - - /** - * Method to auto-populate the model state. Calling getState in this method will result in recursion. - * - * @param string $ordering An optional ordering field. [optional] - * @param string $direction An optional direction. [optional] - * - * @return void - * - * @since 2.5 - */ - protected function populateState($ordering = 'l.title', $direction = 'asc') - { - // Load the filter state. - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); - $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'cmd')); - $this->setState('filter.content_map', $this->getUserStateFromRequest($this->context . '.filter.content_map', 'filter_content_map', '', 'cmd')); - - // Load the parameters. - $params = JComponentHelper::getParams('com_finder'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * Method to change the published state of one or more records. - * - * @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. - * - * @since 2.5 - */ - public function publish(&$pks, $value = 1) - { - $dispatcher = JEventDispatcher::getInstance(); - $user = JFactory::getUser(); - $table = $this->getTable(); - $pks = (array) $pks; - - // Include the content plugins for the change of state event. - JPluginHelper::importPlugin('content'); - - // Access checks. - foreach ($pks as $i => $pk) - { - $table->reset(); - - if ($table->load($pk) && !$this->canEditState($table)) - { - // Prune items that you can't change. - unset($pks[$i]); - $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - - return false; - } - } - - // Attempt to change the state of the records. - if (!$table->publish($pks, $value, $user->get('id'))) - { - $this->setError($table->getError()); - - return false; - } - - $context = $this->option . '.' . $this->name; - - // Trigger the onContentChangeState event. - $result = $dispatcher->trigger('onContentChangeState', array($context, $pks, $value)); - - if (in_array(false, $result, true)) - { - $this->setError($table->getError()); - - return false; - } - - // Clear the component's cache - $this->cleanCache(); - - return true; - } -} diff --git a/administrator/components/com_finder/models/indexer.php b/administrator/components/com_finder/models/indexer.php deleted file mode 100644 index 0a4d03ed93ed7..0000000000000 --- a/administrator/components/com_finder/models/indexer.php +++ /dev/null @@ -1,19 +0,0 @@ -authorise('core.delete', $this->option); - } - - /** - * 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 for the component. - * - * @since 2.5 - */ - protected function canEditState($record) - { - return JFactory::getUser()->authorise('core.edit.state', $this->option); - } - - /** - * Method to delete one or more records. - * - * @param array &$pks An array of record primary keys. - * - * @return boolean True if successful, false if an error occurs. - * - * @since 2.5 - */ - public function delete(&$pks) - { - $dispatcher = JEventDispatcher::getInstance(); - $pks = (array) $pks; - $table = $this->getTable(); - - // Include the content plugins for the on delete events. - JPluginHelper::importPlugin('content'); - - // Iterate the items to delete each one. - foreach ($pks as $i => $pk) - { - if ($table->load($pk)) - { - if ($this->canDelete($table)) - { - $context = $this->option . '.' . $this->name; - - // Trigger the onContentBeforeDelete event. - $result = $dispatcher->trigger('onContentBeforeDelete', array($context, $table)); - - if (in_array(false, $result, true)) - { - $this->setError($table->getError()); - - return false; - } - - if (!$table->delete($pk)) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the onContentAfterDelete event. - $dispatcher->trigger('onContentAfterDelete', array($context, $table)); - } - else - { - // Prune items that you can't change. - unset($pks[$i]); - $error = $this->getError(); - - if ($error) - { - $this->setError($error); - } - else - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); - } - } - } - else - { - $this->setError($table->getError()); - - return false; - } - } - - // Clear the component's cache - $this->cleanCache(); - - return true; - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery A JDatabaseQuery object - * - * @since 2.5 - */ - protected function getListQuery() - { - $db = $this->getDbo(); - - // Select all fields from the table. - $query = $db->getQuery(true) - ->select('a.id, a.parent_id, a.title, a.state, a.access, a.ordering') - ->select('CASE WHEN a.parent_id = 1 THEN 1 ELSE 2 END AS level') - ->select('p.title AS parent_title') - ->from($db->quoteName('#__finder_taxonomy', 'a')) - ->leftJoin($db->quoteName('#__finder_taxonomy', 'p') . ' ON p.id = a.parent_id') - ->where('a.parent_id != 0'); - - $childQuery = $db->getQuery(true) - ->select('parent_id') - ->select('COUNT(*) AS num_children') - ->from($db->quoteName('#__finder_taxonomy')) - ->where('parent_id != 0') - ->group('parent_id'); - - // Join to get children. - $query->select('b.num_children'); - $query->select('CASE WHEN a.parent_id = 1 THEN a.title ELSE p.title END AS branch_title'); - $query->leftJoin('(' . $childQuery . ') AS b ON b.parent_id = a.id'); - - // Join to get the map links. - $stateQuery = $db->getQuery(true) - ->select('m.node_id') - ->select('COUNT(NULLIF(l.published, 0)) AS count_published') - ->select('COUNT(NULLIF(l.published, 1)) AS count_unpublished') - ->from($db->quoteName('#__finder_taxonomy_map', 'm')) - ->leftJoin($db->quoteName('#__finder_links', 'l') . ' ON l.link_id = m.link_id') - ->group('m.node_id'); - - $query->select('COALESCE(s.count_published, 0) AS count_published'); - $query->select('COALESCE(s.count_unpublished, 0) AS count_unpublished'); - $query->leftJoin('(' . $stateQuery . ') AS s ON s.node_id = a.id'); - - // If the model is set to check item state, add to the query. - $state = $this->getState('filter.state'); - - if (is_numeric($state)) - { - $query->where('a.state = ' . (int) $state); - } - - // Filter over level. - $level = $this->getState('filter.level'); - - if (is_numeric($level) && (int) $level === 1) - { - $query->where('a.parent_id = 1'); - } - - // Filter the maps over the branch if set. - $branchId = $this->getState('filter.branch'); - - if (is_numeric($branchId)) - { - $query->where('a.parent_id = ' . (int) $branchId); - } - - // Filter the maps over the search string if set. - if ($search = $this->getState('filter.search')) - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('a.title LIKE ' . $search); - } - - // Handle the list ordering. - $listOrdering = $this->getState('list.ordering', 'd.branch_title'); - $listDirn = $this->getState('list.direction', 'ASC'); - - if ($listOrdering === 'd.branch_title') - { - $query->order("branch_title $listDirn, level ASC, a.title $listDirn"); - } - elseif ($listOrdering === 'a.state') - { - $query->order("a.state $listDirn, branch_title $listDirn, level ASC"); - } - - return $query; - } - - /** - * Returns a record count for the query. - * - * @param JDatabaseQuery|string $query The query. - * - * @return integer Number of rows for query. - * - * @since 3.0 - */ - protected function _getListCount($query) - { - $query = clone $query; - $query->clear('select')->clear('join')->clear('order')->clear('limit')->clear('offset')->select('COUNT(*)'); - - return (int) $this->getDbo()->setQuery($query)->loadResult(); - } - - /** - * 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. [optional] - * - * @return string A store id. - * - * @since 2.5 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.state'); - $id .= ':' . $this->getState('filter.branch'); - $id .= ':' . $this->getState('filter.level'); - - return parent::getStoreId($id); - } - - /** - * Returns a JTable object, always creating it. - * - * @param string $type The table type to instantiate. [optional] - * @param string $prefix A prefix for the table class name. [optional] - * @param array $config Configuration array for model. [optional] - * - * @return JTable A database object - * - * @since 2.5 - */ - public function getTable($type = 'Map', $prefix = 'FinderTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Method to auto-populate the model state. Calling getState in this method will result in recursion. - * - * @param string $ordering An optional ordering field. [optional] - * @param string $direction An optional direction. [optional] - * - * @return void - * - * @since 2.5 - */ - protected function populateState($ordering = 'd.branch_title', $direction = 'ASC') - { - // Load the filter state. - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); - $this->setState('filter.branch', $this->getUserStateFromRequest($this->context . '.filter.branch', 'filter_branch', '', 'cmd')); - $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); - - // Load the parameters. - $params = JComponentHelper::getParams('com_finder'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * Method to change the published state of one or more records. - * - * @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. - * - * @since 2.5 - */ - public function publish(&$pks, $value = 1) - { - $dispatcher = JEventDispatcher::getInstance(); - $user = JFactory::getUser(); - $table = $this->getTable(); - $pks = (array) $pks; - - // Include the content plugins for the change of state event. - JPluginHelper::importPlugin('content'); - - // Access checks. - foreach ($pks as $i => $pk) - { - $table->reset(); - - if ($table->load($pk) && !$this->canEditState($table)) - { - // Prune items that you can't change. - unset($pks[$i]); - $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - - return false; - } - } - - // Attempt to change the state of the records. - if (!$table->publish($pks, $value, $user->get('id'))) - { - $this->setError($table->getError()); - - return false; - } - - $context = $this->option . '.' . $this->name; - - // Trigger the onContentChangeState event. - $result = $dispatcher->trigger('onContentChangeState', array($context, $pks, $value)); - - if (in_array(false, $result, true)) - { - $this->setError($table->getError()); - - return false; - } - - // Clear the component's cache - $this->cleanCache(); - - return true; - } - - /** - * Method to purge all maps from the taxonomy. - * - * @return boolean Returns true on success, false on failure. - * - * @since 2.5 - */ - public function purge() - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->delete($db->quoteName('#__finder_taxonomy')) - ->where($db->quoteName('parent_id') . ' > 1'); - $db->setQuery($query); - $db->execute(); - - $query->clear() - ->delete($db->quoteName('#__finder_taxonomy_map')) - ->where('1'); - $db->setQuery($query); - $db->execute(); - - return true; - } -} diff --git a/administrator/components/com_finder/models/statistics.php b/administrator/components/com_finder/models/statistics.php deleted file mode 100644 index a301d9b342f3f..0000000000000 --- a/administrator/components/com_finder/models/statistics.php +++ /dev/null @@ -1,78 +0,0 @@ -getDbo(); - $query = $db->getQuery(true); - $data = new JObject; - - $query->select('COUNT(term_id)') - ->from($db->quoteName('#__finder_terms')); - $db->setQuery($query); - $data->term_count = $db->loadResult(); - - $query->clear() - ->select('COUNT(link_id)') - ->from($db->quoteName('#__finder_links')); - $db->setQuery($query); - $data->link_count = $db->loadResult(); - - $query->clear() - ->select('COUNT(id)') - ->from($db->quoteName('#__finder_taxonomy')) - ->where($db->quoteName('parent_id') . ' = 1'); - $db->setQuery($query); - $data->taxonomy_branch_count = $db->loadResult(); - - $query->clear() - ->select('COUNT(id)') - ->from($db->quoteName('#__finder_taxonomy')) - ->where($db->quoteName('parent_id') . ' > 1'); - $db->setQuery($query); - $data->taxonomy_node_count = $db->loadResult(); - - $query->clear() - ->select('t.title AS type_title, COUNT(a.link_id) AS link_count') - ->from($db->quoteName('#__finder_links') . ' AS a') - ->join('INNER', $db->quoteName('#__finder_types') . ' AS t ON t.id = a.type_id') - ->group('a.type_id, t.title') - ->order($db->quoteName('type_title') . ' ASC'); - $db->setQuery($query); - $data->type_list = $db->loadObjectList(); - - $lang = JFactory::getLanguage(); - $plugins = JPluginHelper::getPlugin('finder'); - - foreach ($plugins as $plugin) - { - $lang->load('plg_finder_' . $plugin->name . '.sys', JPATH_ADMINISTRATOR, null, false, true) - || $lang->load('plg_finder_' . $plugin->name . '.sys', JPATH_PLUGINS . '/finder/' . $plugin->name, null, false, true); - } - - return $data; - } -} diff --git a/administrator/components/com_finder/services/provider.php b/administrator/components/com_finder/services/provider.php new file mode 100644 index 0000000000000..7011e9eb0d127 --- /dev/null +++ b/administrator/components/com_finder/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Finder')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Finder')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_finder/sql/install.mysql.sql b/administrator/components/com_finder/sql/install.mysql.sql index 4207fa2111075..792d43c162566 100644 --- a/administrator/components/com_finder/sql/install.mysql.sql +++ b/administrator/components/com_finder/sql/install.mysql.sql @@ -35,7 +35,7 @@ CREATE TABLE IF NOT EXISTS `#__finder_links` ( `published` tinyint(1) NOT NULL DEFAULT 1, `state` int(5) DEFAULT 1, `access` int(5) DEFAULT 0, - `language` varchar(8) NOT NULL, + `language` char(7) 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', `start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', @@ -54,10 +54,10 @@ CREATE TABLE IF NOT EXISTS `#__finder_links` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; -- --- Table structure for table `#__finder_links_terms0` +-- Table structure for table `#__finder_links_terms` -- -CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( +CREATE TABLE IF NOT EXISTS `#__finder_links_terms` ( `link_id` int(10) unsigned NOT NULL, `term_id` int(10) unsigned NOT NULL, `weight` float unsigned NOT NULL, @@ -67,198 +67,17 @@ CREATE TABLE IF NOT EXISTS `#__finder_links_terms0` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; -- --- Table structure for table `#__finder_links_terms1` +-- Table structure for table `#__finder_logging` -- -CREATE TABLE IF NOT EXISTS `#__finder_links_terms1` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_terms2` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms2` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_terms3` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms3` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_terms4` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms4` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_terms5` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms5` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_terms6` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms6` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_terms7` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms7` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_terms8` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms8` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_terms9` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_terms9` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_termsa` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsa` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_termsb` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsb` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_termsc` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsc` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_termsd` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsd` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_termse` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_termse` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; - --- --- Table structure for table `#__finder_links_termsf` --- - -CREATE TABLE IF NOT EXISTS `#__finder_links_termsf` ( - `link_id` int(10) unsigned NOT NULL, - `term_id` int(10) unsigned NOT NULL, - `weight` float unsigned NOT NULL, - PRIMARY KEY (`link_id`,`term_id`), - KEY `idx_term_weight` (`term_id`,`weight`), - KEY `idx_link_term_weight` (`link_id`,`term_id`,`weight`) +CREATE TABLE IF NOT EXISTS `#__finder_logging` ( + `searchterm` VARCHAR(255) NOT NULL DEFAULT '', + `md5sum` VARCHAR(32) NOT NULL DEFAULT '', + `query` BLOB NOT NULL, + `hits` INT(11) NOT NULL DEFAULT '1', + `results` INT(11) NOT NULL DEFAULT '0', + UNIQUE INDEX `md5sum` (`md5sum`), + INDEX `searchterm` (`searchterm`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; -- @@ -312,7 +131,7 @@ CREATE TABLE IF NOT EXISTS `#__finder_terms` ( `weight` float unsigned NOT NULL DEFAULT 0, `soundex` varchar(75) NOT NULL, `links` int(10) NOT NULL DEFAULT 0, - `language` char(3) NOT NULL DEFAULT '', + `language` char(7) NOT NULL DEFAULT '', PRIMARY KEY (`term_id`), UNIQUE KEY `idx_term` (`term`), KEY `idx_term_phrase` (`term`,`phrase`), @@ -326,7 +145,7 @@ CREATE TABLE IF NOT EXISTS `#__finder_terms` ( CREATE TABLE IF NOT EXISTS `#__finder_terms_common` ( `term` varchar(75) NOT NULL, - `language` varchar(3) NOT NULL, + `language` char(7) NOT NULL, KEY `idx_word_lang` (`term`,`language`), KEY `idx_lang` (`language`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; @@ -458,7 +277,7 @@ CREATE TABLE IF NOT EXISTS `#__finder_tokens` ( `phrase` tinyint(1) unsigned NOT NULL DEFAULT 0, `weight` float unsigned NOT NULL DEFAULT 1, `context` tinyint(1) unsigned NOT NULL DEFAULT 2, - `language` char(3) NOT NULL DEFAULT '', + `language` char(7) NOT NULL DEFAULT '', KEY `idx_word` (`term`), KEY `idx_context` (`context`) ) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; @@ -469,7 +288,6 @@ CREATE TABLE IF NOT EXISTS `#__finder_tokens` ( CREATE TABLE IF NOT EXISTS `#__finder_tokens_aggregate` ( `term_id` int(10) 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, @@ -478,7 +296,7 @@ CREATE TABLE IF NOT EXISTS `#__finder_tokens_aggregate` ( `context` tinyint(1) unsigned NOT NULL DEFAULT 2, `context_weight` float unsigned NOT NULL, `total_weight` float unsigned NOT NULL, - `language` char(3) NOT NULL DEFAULT '', + `language` char(7) NOT NULL DEFAULT '', KEY `token` (`term`), KEY `keyword_id` (`term_id`) ) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_general_ci; diff --git a/administrator/components/com_finder/sql/install.postgresql.sql b/administrator/components/com_finder/sql/install.postgresql.sql index 8097507ebece1..086964f903f0f 100644 --- a/administrator/components/com_finder/sql/install.postgresql.sql +++ b/administrator/components/com_finder/sql/install.postgresql.sql @@ -1,7 +1,7 @@ -- -- Table: #__finder_filters -- -CREATE TABLE "#__finder_filters" ( +CREATE TABLE IF NOT EXISTS "#__finder_filters" ( "filter_id" serial NOT NULL, "title" character varying(255) NOT NULL, "alias" character varying(255) NOT NULL, @@ -22,7 +22,7 @@ CREATE TABLE "#__finder_filters" ( -- -- Table: #__finder_links -- -CREATE TABLE "#__finder_links" ( +CREATE TABLE IF NOT EXISTS "#__finder_links" ( "link_id" serial NOT NULL, "url" character varying(255) NOT NULL, "route" character varying(255) NOT NULL, @@ -52,9 +52,9 @@ CREATE INDEX "#__finder_links_idx_published_list" on "#__finder_links" ("publish CREATE INDEX "#__finder_links_idx_published_sale" on "#__finder_links" ("published", "state", "access", "publish_start_date", "publish_end_date", "sale_price"); -- --- Table: #__finder_links_terms0 +-- Table: #__finder_links_terms -- -CREATE TABLE "#__finder_links_terms0" ( +CREATE TABLE IF NOT EXISTS "#__finder_links_terms" ( "link_id" integer NOT NULL, "term_id" integer NOT NULL, "weight" numeric(8,2) NOT NULL, @@ -64,189 +64,24 @@ CREATE INDEX "#__finder_links_terms0_idx_term_weight" on "#__finder_links_terms0 CREATE INDEX "#__finder_links_terms0_idx_link_term_weight" on "#__finder_links_terms0" ("link_id", "term_id", "weight"); -- --- Table: #__finder_links_terms1 +-- Table structure for table `#__finder_logging` -- -CREATE TABLE "#__finder_links_terms1" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_terms1_idx_term_weight" on "#__finder_links_terms1" ("term_id", "weight"); -CREATE INDEX "#__finder_links_terms1_idx_link_term_weight" on "#__finder_links_terms1" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_terms2 --- -CREATE TABLE "#__finder_links_terms2" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_terms2_idx_term_weight" on "#__finder_links_terms2" ("term_id", "weight"); -CREATE INDEX "#__finder_links_terms2_idx_link_term_weight" on "#__finder_links_terms2" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_terms3 --- -CREATE TABLE "#__finder_links_terms3" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_terms3_idx_term_weight" on "#__finder_links_terms3" ("term_id", "weight"); -CREATE INDEX "#__finder_links_terms3_idx_link_term_weight" on "#__finder_links_terms3" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_terms4 --- -CREATE TABLE "#__finder_links_terms4" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_terms4_idx_term_weight" on "#__finder_links_terms4" ("term_id", "weight"); -CREATE INDEX "#__finder_links_terms4_idx_link_term_weight" on "#__finder_links_terms4" ("link_id", "term_id", "weight"); --- --- Table: #__finder_links_terms5 --- -CREATE TABLE "#__finder_links_terms5" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_terms5_idx_term_weight" on "#__finder_links_terms5" ("term_id", "weight"); -CREATE INDEX "#__finder_links_terms5_idx_link_term_weight" on "#__finder_links_terms5" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_terms6 --- -CREATE TABLE "#__finder_links_terms6" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_terms6_idx_term_weight" on "#__finder_links_terms6" ("term_id", "weight"); -CREATE INDEX "#__finder_links_terms6_idx_link_term_weight" on "#__finder_links_terms6" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_terms7 --- -CREATE TABLE "#__finder_links_terms7" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_terms7_idx_term_weight" on "#__finder_links_terms7" ("term_id", "weight"); -CREATE INDEX "#__finder_links_terms7_idx_link_term_weight" on "#__finder_links_terms7" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_terms8 --- -CREATE TABLE "#__finder_links_terms8" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_terms8_idx_term_weight" on "#__finder_links_terms8" ("term_id", "weight"); -CREATE INDEX "#__finder_links_terms8_idx_link_term_weight" on "#__finder_links_terms8" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_terms9 --- -CREATE TABLE "#__finder_links_terms9" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_terms9_idx_term_weight" on "#__finder_links_terms9" ("term_id", "weight"); -CREATE INDEX "#__finder_links_terms9_idx_link_term_weight" on "#__finder_links_terms9" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_termsa --- -CREATE TABLE "#__finder_links_termsa" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_termsa_idx_term_weight" on "#__finder_links_termsa" ("term_id", "weight"); -CREATE INDEX "#__finder_links_termsa_idx_link_term_weight" on "#__finder_links_termsa" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_termsb --- -CREATE TABLE "#__finder_links_termsb" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_termsb_idx_term_weight" on "#__finder_links_termsb" ("term_id", "weight"); -CREATE INDEX "#__finder_links_termsb_idx_link_term_weight" on "#__finder_links_termsb" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_termsc --- -CREATE TABLE "#__finder_links_termsc" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_termsc_idx_term_weight" on "#__finder_links_termsc" ("term_id", "weight"); -CREATE INDEX "#__finder_links_termsc_idx_link_term_weight" on "#__finder_links_termsc" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_termsd --- -CREATE TABLE "#__finder_links_termsd" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_termsd_idx_term_weight" on "#__finder_links_termsd" ("term_id", "weight"); -CREATE INDEX "#__finder_links_termsd_idx_link_term_weight" on "#__finder_links_termsd" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_termse --- -CREATE TABLE "#__finder_links_termse" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") -); -CREATE INDEX "#__finder_links_termse_idx_term_weight" on "#__finder_links_termse" ("term_id", "weight"); -CREATE INDEX "#__finder_links_termse_idx_link_term_weight" on "#__finder_links_termse" ("link_id", "term_id", "weight"); - --- --- Table: #__finder_links_termsf --- -CREATE TABLE "#__finder_links_termsf" ( - "link_id" integer NOT NULL, - "term_id" integer NOT NULL, - "weight" numeric(8,2) NOT NULL, - PRIMARY KEY ("link_id", "term_id") +CREATE TABLE IF NOT EXISTS "#__finder_logging" ( + "searchterm" character varying(255) NOT NULL DEFAULT '', + "md5sum" character varying(32) NOT NULL DEFAULT '', + "query" bytes NOT NULL, + "hits" integer NOT NULL DEFAULT 1, + "results" integer NOT NULL DEFAULT 0, + CONSTRAINT "#__finder_logging_idx_md5sum" UNIQUE ("md5sum") ); -CREATE INDEX "#__finder_links_termsf_idx_term_weight" on "#__finder_links_termsf" ("term_id", "weight"); -CREATE INDEX "#__finder_links_termsf_idx_link_term_weight" on "#__finder_links_termsf" ("link_id", "term_id", "weight"); +CREATE INDEX "#__finder_logging_idx_md5sum" on "#__finder_logging" ("md5sum"); +CREATE INDEX "#__finder_logging_idx_searchterm" on "#__finder_logging" ("searchterm"); -- -- Table: #__finder_taxonomy -- -CREATE TABLE "#__finder_taxonomy" ( +CREATE TABLE IF NOT EXISTS "#__finder_taxonomy" ( "id" serial NOT NULL, "parent_id" integer DEFAULT 0 NOT NULL, "title" character varying(255) NOT NULL, @@ -276,7 +111,7 @@ SELECT 1, 0, 'ROOT', 0, 0, 0 WHERE 1 NOT IN -- -- Table: #__finder_taxonomy_map -- -CREATE TABLE "#__finder_taxonomy_map" ( +CREATE TABLE IF NOT EXISTS "#__finder_taxonomy_map" ( "link_id" integer NOT NULL, "node_id" integer NOT NULL, PRIMARY KEY ("link_id", "node_id") @@ -287,7 +122,7 @@ CREATE INDEX "#__finder_taxonomy_map_node_id" on "#__finder_taxonomy_map" ("node -- -- Table: #__finder_terms -- -CREATE TABLE "#__finder_terms" ( +CREATE TABLE IF NOT EXISTS "#__finder_terms" ( "term_id" serial NOT NULL, "term" character varying(75) NOT NULL, "stem" character varying(75) NOT NULL, @@ -306,7 +141,7 @@ CREATE INDEX "#__finder_terms_idx_soundex_phrase" on "#__finder_terms" ("soundex -- -- Table: #__finder_terms_common -- -CREATE TABLE "#__finder_terms_common" ( +CREATE TABLE IF NOT EXISTS "#__finder_terms_common" ( "term" character varying(75) NOT NULL, "language" character varying(3) NOT NULL ); @@ -983,7 +818,7 @@ SELECT 'yours', 'en' WHERE 1 NOT IN (SELECT 1 FROM "#__finder_terms_common" WHER -- -- Table: #__finder_tokens -- -CREATE TABLE "#__finder_tokens" ( +CREATE TABLE IF NOT EXISTS "#__finder_tokens" ( "term" character varying(75) NOT NULL, "stem" character varying(75) NOT NULL, "common" smallint DEFAULT 0 NOT NULL, @@ -997,9 +832,8 @@ CREATE INDEX "#__finder_tokens_idx_context" on "#__finder_tokens" ("context"); -- -- Table: #__finder_tokens_aggregate -- -CREATE TABLE "#__finder_tokens_aggregate" ( +CREATE TABLE IF NOT EXISTS "#__finder_tokens_aggregate" ( "term_id" integer NOT NULL, - "map_suffix" character(1) NOT NULL, "term" character varying(75) NOT NULL, "stem" character varying(75) NOT NULL, "common" smallint DEFAULT 0 NOT NULL, @@ -1015,7 +849,7 @@ CREATE INDEX "_#__finder_tokens_aggregate_keyword_id" on "#__finder_tokens_aggre -- -- Table: #__finder_types -- -CREATE TABLE "#__finder_types" ( +CREATE TABLE IF NOT EXISTS "#__finder_types" ( "id" serial NOT NULL, "title" character varying(100) NOT NULL, "mime" character varying(100) NOT NULL, diff --git a/administrator/components/com_finder/sql/uninstall.mysql.sql b/administrator/components/com_finder/sql/uninstall.mysql.sql index 89579b982d43f..5167421c75378 100644 --- a/administrator/components/com_finder/sql/uninstall.mysql.sql +++ b/administrator/components/com_finder/sql/uninstall.mysql.sql @@ -1,21 +1,7 @@ DROP TABLE IF EXISTS `#__finder_filters`; DROP TABLE IF EXISTS `#__finder_links`; -DROP TABLE IF EXISTS `#__finder_links_terms0`; -DROP TABLE IF EXISTS `#__finder_links_terms1`; -DROP TABLE IF EXISTS `#__finder_links_terms2`; -DROP TABLE IF EXISTS `#__finder_links_terms3`; -DROP TABLE IF EXISTS `#__finder_links_terms4`; -DROP TABLE IF EXISTS `#__finder_links_terms5`; -DROP TABLE IF EXISTS `#__finder_links_terms6`; -DROP TABLE IF EXISTS `#__finder_links_terms7`; -DROP TABLE IF EXISTS `#__finder_links_terms8`; -DROP TABLE IF EXISTS `#__finder_links_terms9`; -DROP TABLE IF EXISTS `#__finder_links_termsa`; -DROP TABLE IF EXISTS `#__finder_links_termsb`; -DROP TABLE IF EXISTS `#__finder_links_termsc`; -DROP TABLE IF EXISTS `#__finder_links_termsd`; -DROP TABLE IF EXISTS `#__finder_links_termse`; -DROP TABLE IF EXISTS `#__finder_links_termsf`; +DROP TABLE IF EXISTS `#__finder_links_terms`; +DROP TABLE IF EXISTS `#__finder_logging`; DROP TABLE IF EXISTS `#__finder_taxonomy`; DROP TABLE IF EXISTS `#__finder_taxonomy_map`; DROP TABLE IF EXISTS `#__finder_terms`; diff --git a/administrator/components/com_finder/sql/uninstall.postgresql.sql b/administrator/components/com_finder/sql/uninstall.postgresql.sql index 76d7981529149..06507dcd70af5 100644 --- a/administrator/components/com_finder/sql/uninstall.postgresql.sql +++ b/administrator/components/com_finder/sql/uninstall.postgresql.sql @@ -1,21 +1,7 @@ DROP TABLE IF EXISTS "#__finder_filters"; DROP TABLE IF EXISTS "#__finder_links"; -DROP TABLE IF EXISTS "#__finder_links_terms0"; -DROP TABLE IF EXISTS "#__finder_links_terms1"; -DROP TABLE IF EXISTS "#__finder_links_terms2"; -DROP TABLE IF EXISTS "#__finder_links_terms3"; -DROP TABLE IF EXISTS "#__finder_links_terms4"; -DROP TABLE IF EXISTS "#__finder_links_terms5"; -DROP TABLE IF EXISTS "#__finder_links_terms6"; -DROP TABLE IF EXISTS "#__finder_links_terms7"; -DROP TABLE IF EXISTS "#__finder_links_terms8"; -DROP TABLE IF EXISTS "#__finder_links_terms9"; -DROP TABLE IF EXISTS "#__finder_links_termsa"; -DROP TABLE IF EXISTS "#__finder_links_termsb"; -DROP TABLE IF EXISTS "#__finder_links_termsc"; -DROP TABLE IF EXISTS "#__finder_links_termsd"; -DROP TABLE IF EXISTS "#__finder_links_termse"; -DROP TABLE IF EXISTS "#__finder_links_termsf"; +DROP TABLE IF EXISTS "#__finder_links_terms"; +DROP TABLE IF EXISTS "#__finder_logging"; DROP TABLE IF EXISTS "#__finder_taxonomy"; DROP TABLE IF EXISTS "#__finder_taxonomy_map"; DROP TABLE IF EXISTS "#__finder_terms"; diff --git a/administrator/components/com_finder/tables/filter.php b/administrator/components/com_finder/tables/filter.php deleted file mode 100644 index c9bd00bbe63cc..0000000000000 --- a/administrator/components/com_finder/tables/filter.php +++ /dev/null @@ -1,254 +0,0 @@ -alias) === '') - { - $this->alias = $this->title; - } - - $this->alias = JApplicationHelper::stringURLSafe($this->alias); - - if (trim(str_replace('-', '', $this->alias)) === '') - { - $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); - } - - $params = new Registry($this->params); - - $nullDate = $this->_db->getNullDate(); - $d1 = $params->get('d1', $nullDate); - $d2 = $params->get('d2', $nullDate); - - // Check the end date is not earlier than the start date. - if ($d2 > $nullDate && $d2 < $d1) - { - // Swap the dates. - $params->set('d1', $d2); - $params->set('d2', $d1); - $this->params = (string) $params; - } - - return true; - } - - /** - * Method to set the publishing state for a row or list of rows in the database - * table. The method respects checked out rows by other users and will attempt - * to checkin rows that it can after adjustments are made. - * - * @param mixed $pks An array of primary key values to update. If not - * set the instance property value is used. [optional] - * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] [optional] - * @param integer $userId The user id of the user performing the operation. [optional] - * - * @return boolean True on success. - * - * @since 2.5 - */ - public function publish($pks = null, $state = 1, $userId = 0) - { - $k = $this->_tbl_key; - - // Sanitize input. - $pks = ArrayHelper::toInteger($pks); - $userId = (int) $userId; - $state = (int) $state; - - // If there are no primary keys set check to see if the instance key is set. - if (empty($pks)) - { - if ($this->$k) - { - $pks = array($this->$k); - } - // Nothing to set publishing state on, return false. - else - { - $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); - - return false; - } - } - - // Build the WHERE clause for the primary keys. - $where = $k . '=' . implode(' OR ' . $k . '=', $pks); - - // Determine if there is checkin support for the table. - if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) - { - $checkin = ''; - } - else - { - $checkin = ' AND (checked_out = 0 OR checked_out = ' . (int) $userId . ')'; - } - - // Update the publishing state for rows with the given primary keys. - $query = $this->_db->getQuery(true) - ->update($this->_db->quoteName($this->_tbl)) - ->set($this->_db->quoteName('state') . ' = ' . (int) $state) - ->where($where); - $this->_db->setQuery($query . $checkin); - - try - { - $this->_db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // If checkin is supported and all rows were adjusted, check them in. - if ($checkin && count($pks) === $this->_db->getAffectedRows()) - { - // Checkin the rows. - foreach ($pks as $pk) - { - $this->checkIn($pk); - } - } - - // If the JTable instance value is in the list of primary keys that were set, set the instance. - if (in_array($this->$k, $pks)) - { - $this->state = $state; - } - - $this->setError(''); - - return true; - } - - /** - * Method to store a row in the database from the JTable instance properties. - * If a primary key value is set the row with that primary key value will be - * updated with the instance property values. If no primary key value is set - * a new row will be inserted into the database with the properties from the - * JTable instance. - * - * @param boolean $updateNulls True to update fields even if they are null. [optional] - * - * @return boolean True on success. - * - * @since 2.5 - */ - public function store($updateNulls = false) - { - $date = JFactory::getDate()->toSql(); - $userId = JFactory::getUser()->id; - - $this->modified = $date; - - if ($this->filter_id) - { - // Existing item - $this->modified_by = $userId; - } - else - { - // New item. A filter's created field can be set by the user, - // so we don't touch it if it is set. - if (!(int) $this->created) - { - $this->created = $date; - } - - if (empty($this->created_by)) - { - $this->created_by = $userId; - } - } - - if (is_array($this->data)) - { - $this->map_count = count($this->data); - $this->data = implode(',', $this->data); - } - else - { - $this->map_count = 0; - $this->data = implode(',', array()); - } - - // Verify that the alias is unique - $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)) - { - $this->setError(JText::_('JLIB_DATABASE_ERROR_ARTICLE_UNIQUE_ALIAS')); - - return false; - } - - return parent::store($updateNulls); - } -} diff --git a/administrator/components/com_finder/tables/link.php b/administrator/components/com_finder/tables/link.php deleted file mode 100644 index 18c010eb06c46..0000000000000 --- a/administrator/components/com_finder/tables/link.php +++ /dev/null @@ -1,30 +0,0 @@ -_tbl_key; - - // Sanitize input. - $pks = ArrayHelper::toInteger($pks); - $state = (int) $state; - - // If there are no primary keys set check to see if the instance key is set. - if (empty($pks)) - { - if ($this->$k) - { - $pks = array($this->$k); - } - // Nothing to set publishing state on, return false. - else - { - $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); - - return false; - } - } - - // Build the WHERE clause for the primary keys. - $where = $k . '=' . implode(' OR ' . $k . '=', $pks); - - // Update the publishing state for rows with the given primary keys. - $query = $this->_db->getQuery(true) - ->update($this->_db->quoteName($this->_tbl)) - ->set($this->_db->quoteName('state') . ' = ' . (int) $state) - ->where($where); - $this->_db->setQuery($query); - - try - { - $this->_db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // If the JTable instance value is in the list of primary keys that were set, set the instance. - if (in_array($this->$k, $pks)) - { - $this->state = $state; - } - - $this->setError(''); - - return true; - } -} diff --git a/administrator/components/com_finder/tmpl/filter/edit.php b/administrator/components/com_finder/tmpl/filter/edit.php new file mode 100644 index 0000000000000..73125baf6c856 --- /dev/null +++ b/administrator/components/com_finder/tmpl/filter/edit.php @@ -0,0 +1,68 @@ +useCoreUI = true; + +JHtml::_('script', 'com_finder/finder-edit.min.js', array('version' => 'auto', 'relative' => true)); +?> + +
+ + + + 'details')); ?> + + +
+
+ total > 0) : ?> +
+ form->renderField('map_count'); ?> +
+ + + +
+ + + $this->filter->data)); ?> +
+
+
+
+ +
+
+
+
+ + + + + + + + + + + + + +
diff --git a/administrator/components/com_finder/tmpl/filters/default.php b/administrator/components/com_finder/tmpl/filters/default.php new file mode 100644 index 0000000000000..76d40f1c3d9ee --- /dev/null +++ b/administrator/components/com_finder/tmpl/filters/default.php @@ -0,0 +1,116 @@ +get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); +HTMLHelper::_('script', 'com_finder/filters.js', ['relative' => true, 'version' => 'auto']); +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + 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->id; + foreach ($this->items as $i => $item) : + $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; ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_finder/tmpl/index/default.php b/administrator/components/com_finder/tmpl/index/default.php new file mode 100644 index 0000000000000..f444135730f4c --- /dev/null +++ b/administrator/components/com_finder/tmpl/index/default.php @@ -0,0 +1,106 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$lang = JFactory::getLanguage(); + +JText::script('COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT'); +JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); +HTMLHelper::_('script', 'com_finder/index.js', ['relative' => true, 'version' => 'auto']); +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + + + + + + + + + + + + + + authorise('core.manage', 'com_finder'); ?> + items as $i => $item) : ?> + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ link_id); ?> + + published, $i, 'index.', $canChange, 'cb'); ?> + + + + t_title); + echo $lang->hasKey($key) ? JText::_($key) : $item->t_title; + ?> + + indexdate, JText::_('DATE_FORMAT_LC4')); ?> + + publish_start_date or (int) $item->publish_end_date or (int) $item->start_date or (int) $item->end_date) : ?> + + publish_start_date, $item->publish_end_date, $item->start_date, $item->end_date); ?> + + + url) > 80) ? substr($item->url, 0, 70) . '...' : $item->url; ?> +
+ + + pagination->getListFooter(); ?> + + + + +
+
+
+
diff --git a/administrator/components/com_finder/tmpl/indexer/default.php b/administrator/components/com_finder/tmpl/indexer/default.php new file mode 100644 index 0000000000000..ec5b329539c47 --- /dev/null +++ b/administrator/components/com_finder/tmpl/indexer/default.php @@ -0,0 +1,26 @@ + 'auto', 'relative' => true)); +JFactory::getDocument()->addScriptDeclaration('var msg = "' . JText::_('COM_FINDER_INDEXER_MESSAGE_COMPLETE') . '";'); +?> + +
+

+

+
+
+
+ +
diff --git a/administrator/components/com_finder/tmpl/maps/default.php b/administrator/components/com_finder/tmpl/maps/default.php new file mode 100644 index 0000000000000..68269f12fb503 --- /dev/null +++ b/administrator/components/com_finder/tmpl/maps/default.php @@ -0,0 +1,134 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$lang = JFactory::getLanguage(); +$branchFilter = $this->escape($this->state->get('filter.branch')); +JText::script('COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT'); +HTMLHelper::_('script', 'com_finder/maps.js', ['relative' => true, 'version' => 'auto']); +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + + authorise('core.manage', 'com_finder'); ?> + items as $i => $item) : ?> + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ id); ?> + + state, $i, 'maps.', $canChange, 'cb'); ?> + + parent_title, '**') === 'Language') + { + $title = FinderHelperLanguage::branchLanguageTitle($item->title); + } + else + { + $key = FinderHelperLanguage::branchSingular($item->title); + $title = $lang->hasKey($key) ? JText::_($key) : $item->title; + } + ?> + num_children === 0) : ?> + + + + escape(trim($title, '**')) === 'Language' && JLanguageMultilang::isEnabled()) : ?> + + + + num_children !== 0) : ?> + + num_children; ?> + + - + + + num_children === 0) : ?> + + count_published; ?> + + - + + + num_children === 0) : ?> + + count_unpublished; ?> + + - + +
+ + + pagination->getListFooter(); ?> + + +
+ + + + +
+
+
diff --git a/administrator/components/com_finder/tmpl/searches/default.php b/administrator/components/com_finder/tmpl/searches/default.php new file mode 100644 index 0000000000000..560becad619f0 --- /dev/null +++ b/administrator/components/com_finder/tmpl/searches/default.php @@ -0,0 +1,72 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+
+ sidebar; ?> +
+
+
+ $this, 'options' => array('filterButton' => false))); ?> + items)) : ?> + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + +
+ + + + + +
+ escape($item->searchterm); ?> + + hits; ?> + + results; ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_finder/tmpl/statistics/default.php b/administrator/components/com_finder/tmpl/statistics/default.php new file mode 100644 index 0000000000000..484d4fa079235 --- /dev/null +++ b/administrator/components/com_finder/tmpl/statistics/default.php @@ -0,0 +1,56 @@ + +

+ +

+ +
+
+

data->term_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->taxonomy_node_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->taxonomy_branch_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR'))); ?>

+ + + + + + + + + data->type_list as $type) : ?> + + + + + + + + + + +
+ + + +
+ type_title); + $lang_string = JText::_($lang_key); + echo $lang_string === $lang_key ? $type->type_title : $lang_string; + ?> + + link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); ?> +
+ + + data->link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); ?> +
+
+
diff --git a/administrator/components/com_finder/views/filter/tmpl/edit.php b/administrator/components/com_finder/views/filter/tmpl/edit.php deleted file mode 100644 index 822d0bd036d32..0000000000000 --- a/administrator/components/com_finder/views/filter/tmpl/edit.php +++ /dev/null @@ -1,103 +0,0 @@ -addScriptDeclaration(' - Joomla.submitbutton = function(task) - { - if (task == "filter.cancel" || document.formvalidator.isValid(document.getElementById("adminForm"))) - { - Joomla.submitform(task, document.getElementById("adminForm")); - } - }; - - jQuery(document).ready(function($) { - $("#rightbtn").on("click", function() { - if($(this).text() == "' . JText::_('COM_FINDER_FILTER_SHOW_ALL') . '") { - $(".collapse:not(.in)").each(function (index) { - $(this).collapse("toggle"); - }); - $(this).text("' . JText::_('COM_FINDER_FILTER_HIDE_ALL') . '"); - } else { - $(this).text("' . JText::_('COM_FINDER_FILTER_SHOW_ALL') . '"); - $(".collapse.in").each(function (index) { - $(this).collapse("toggle"); - }); - } - return false; - }); - - $(".filter-node").change(function() { - $(\'input[id="jform_map_count"]\').val(document.querySelectorAll(\'input[type="checkbox"]:checked\').length); - }); - - - }); -'); - -JFactory::getDocument()->addStyleDeclaration(' - .accordion-inner .control-group .controls { - margin-left: 10px; - } - .accordion-inner > .control-group { - margin-bottom: 0; - } - '); -?> - -
- - - -
- 'details')); ?> - - -
-
- total > 0) : ?> -
- form->renderField('map_count'); ?> -
- - - -
- - - $this->filter->data)); ?> -
-
- -
-
- - - -
- -
- - - - - -
- - - - -
diff --git a/administrator/components/com_finder/views/filter/view.html.php b/administrator/components/com_finder/views/filter/view.html.php deleted file mode 100644 index a34c3216705d0..0000000000000 --- a/administrator/components/com_finder/views/filter/view.html.php +++ /dev/null @@ -1,159 +0,0 @@ -filter = $this->get('Filter'); - $this->item = $this->get('Item'); - $this->form = $this->get('Form'); - $this->state = $this->get('State'); - $this->total = $this->get('Total'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - JHtml::addIncludePath(JPATH_SITE . '/components/com_finder/helpers/html'); - - // Configure the toolbar. - $this->addToolbar(); - - return parent::display($tpl); - } - - /** - * Method to configure the toolbar for this view. - * - * @return void - * - * @since 2.5 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - - $isNew = ($this->item->filter_id == 0); - $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == JFactory::getUser()->id); - $canDo = JHelperContent::getActions('com_finder'); - - // Configure the toolbar. - JToolbarHelper::title( - $isNew ? JText::_('COM_FINDER_FILTER_NEW_TOOLBAR_TITLE') : JText::_('COM_FINDER_FILTER_EDIT_TOOLBAR_TITLE'), - 'zoom-in finder' - ); - - // Set the actions for new and existing records. - if ($isNew) - { - // For new records, check the create permission. - if ($canDo->get('core.create')) - { - JToolbarHelper::apply('filter.apply'); - JToolbarHelper::save('filter.save'); - JToolbarHelper::save2new('filter.save2new'); - } - - JToolbarHelper::cancel('filter.cancel'); - } - else - { - // Can't save the record if it's checked out. - // Since it's an existing record, check the edit permission. - if (!$checkedOut && $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::save2new('filter.save2new'); - } - } - - // If an existing item, can save as a copy - if ($canDo->get('core.create')) - { - JToolbarHelper::save2copy('filter.save2copy'); - } - - JToolbarHelper::cancel('filter.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT'); - } -} diff --git a/administrator/components/com_finder/views/filters/tmpl/default.php b/administrator/components/com_finder/views/filters/tmpl/default.php deleted file mode 100644 index b8ccb6f458d03..0000000000000 --- a/administrator/components/com_finder/views/filters/tmpl/default.php +++ /dev/null @@ -1,140 +0,0 @@ -get('id'); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); - -JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(pressbutton) - { - if (pressbutton == "filters.delete") - { - if (confirm(Joomla.JText._("COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT"))) - { - Joomla.submitform(pressbutton); - } - else - { - return false; - } - } - Joomla.submitform(pressbutton); - }; -'); -?> -
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> -
- items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - 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) : - $canCheckIn = $userAuthoriseCoreManage || $item->checked_out == $userId || $item->checked_out == 0; - $canChange = $userAuthoriseCoreEditState && $canCheckIn; - $escapedTitle = $this->escape($item->title); - ?> - - - - - - - - - - - -
- - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- 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 deleted file mode 100644 index 1cf544b525cfe..0000000000000 --- a/administrator/components/com_finder/views/filters/view.html.php +++ /dev/null @@ -1,145 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->total = $this->get('Total'); - $this->state = $this->get('State'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - FinderHelper::addSubmenu('filters'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - - // Configure the toolbar. - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - - return parent::display($tpl); - } - - /** - * Method to configure the toolbar for this view. - * - * @return void - * - * @since 2.5 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_finder'); - - JToolbarHelper::title(JText::_('COM_FINDER_FILTERS_TOOLBAR_TITLE'), 'zoom-in finder'); - $toolbar = JToolbar::getInstance('toolbar'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('filter.add'); - JToolbarHelper::editList('filter.edit'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publishList('filters.publish'); - JToolbarHelper::unpublishList('filters.unpublish'); - JToolbarHelper::checkin('filters.checkin'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_finder'); - } - - JToolbarHelper::divider(); - $toolbar->appendButton('Popup', 'bars', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 350); - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS'); - - if ($canDo->get('core.delete')) - { - JToolbarHelper::deleteList('', 'filters.delete'); - JToolbarHelper::divider(); - } - } -} diff --git a/administrator/components/com_finder/views/index/tmpl/default.php b/administrator/components/com_finder/views/index/tmpl/default.php deleted file mode 100644 index 422e6ad71c6f1..0000000000000 --- a/administrator/components/com_finder/views/index/tmpl/default.php +++ /dev/null @@ -1,138 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$lang = JFactory::getLanguage(); - -JText::script('COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT'); -JText::script('COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT'); - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(pressbutton) - { - if (pressbutton == "index.purge") - { - if (confirm(Joomla.JText._("COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT"))) - { - Joomla.submitform(pressbutton); - } - else - { - return false; - } - } - if (pressbutton == "index.delete") - { - if (confirm(Joomla.JText._("COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT"))) - { - Joomla.submitform(pressbutton); - } - else - { - return false; - } - } - - Joomla.submitform(pressbutton); - }; -'); -?> -
-sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> - - - - - - - - - - - - - - - - - - - authorise('core.manage', 'com_finder'); ?> - items as $i => $item) : ?> - - - - - - - - - - - - -
- - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- link_id); ?> - - published, $i, 'index.', $canChange, 'cb'); ?> - - - - t_title); - echo $lang->hasKey($key) ? JText::_($key) : $item->t_title; - ?> - - indexdate, JText::_('DATE_FORMAT_LC4')); ?> - - 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); ?> - - - url) > 80) ? substr($item->url, 0, 70) . '...' : $item->url; ?> -
- - - -
- diff --git a/administrator/components/com_finder/views/index/view.html.php b/administrator/components/com_finder/views/index/view.html.php deleted file mode 100644 index a30d5c87bf2b2..0000000000000 --- a/administrator/components/com_finder/views/index/view.html.php +++ /dev/null @@ -1,170 +0,0 @@ -items = $this->get('Items'); - $this->total = $this->get('Total'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->pluginState = $this->get('pluginState'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - FinderHelper::addSubmenu('index'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - JError::raiseError(500, implode("\n", $errors)); - - return false; - } - - if (!$this->pluginState['plg_content_finder']->enabled) - { - $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . FinderHelper::getFinderPluginId()); - JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_FINDER_INDEX_PLUGIN_CONTENT_NOT_ENABLED', $link), 'warning'); - } - elseif ($this->get('TotalIndexed') === 0) - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_FINDER_INDEX_NO_DATA') . ' ' . JText::_('COM_FINDER_INDEX_TIP'), 'notice'); - } - - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - - // Configure the toolbar. - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - - return parent::display($tpl); - } - - /** - * Method to configure the toolbar for this view. - * - * @return void - * - * @since 2.5 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_finder'); - - JToolbarHelper::title(JText::_('COM_FINDER_INDEX_TOOLBAR_TITLE'), 'zoom-in finder'); - - $toolbar = JToolbar::getInstance('toolbar'); - $toolbar->appendButton( - 'Popup', 'archive', 'COM_FINDER_INDEX', 'index.php?option=com_finder&view=indexer&tmpl=component', 500, 210, 0, 0, - 'window.parent.location.reload()', 'COM_FINDER_HEADING_INDEXER' - ); - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publishList('index.publish'); - JToolbarHelper::unpublishList('index.unpublish'); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_finder'); - } - - $toolbar->appendButton('Popup', 'bars', 'COM_FINDER_STATISTICS', 'index.php?option=com_finder&view=statistics&tmpl=component', 550, 350); - - if ($canDo->get('core.delete')) - { - JToolbarHelper::deleteList('', 'index.delete'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('index.purge', 'COM_FINDER_INDEX_TOOLBAR_PURGE', false); - } - - JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT'); - } -} diff --git a/administrator/components/com_finder/views/indexer/tmpl/default.php b/administrator/components/com_finder/views/indexer/tmpl/default.php deleted file mode 100644 index 53c8098c1881f..0000000000000 --- a/administrator/components/com_finder/views/indexer/tmpl/default.php +++ /dev/null @@ -1,30 +0,0 @@ - 'auto', 'relative' => true)); -JFactory::getDocument()->addScriptDeclaration('var msg = "' . JText::_('COM_FINDER_INDEXER_MESSAGE_COMPLETE') . '";'); -?> - -
-

-

- -

- -
-
-
- - -
diff --git a/administrator/components/com_finder/views/indexer/view.html.php b/administrator/components/com_finder/views/indexer/view.html.php deleted file mode 100644 index 3f17744a1ba79..0000000000000 --- a/administrator/components/com_finder/views/indexer/view.html.php +++ /dev/null @@ -1,20 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$lang = JFactory::getLanguage(); -$branchFilter = $this->escape($this->state->get('filter.branch')); -$colSpan = $branchFilter ? 5 : 6; -JText::script('COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT'); - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(pressbutton) - { - if (pressbutton == "map.delete") - { - if (confirm(Joomla.JText._("COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT"))) - { - Joomla.submitform(pressbutton); - } - else - { - return false; - } - } - Joomla.submitform(pressbutton); - }; -'); -?> -
-sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> -
- items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - - authorise('core.manage', 'com_finder'); ?> - items as $i => $item) : ?> - - - - - - - - - - - - -
- - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- id); ?> - - state, $i, 'maps.', $canChange, 'cb'); ?> - - parent_title, '**') === 'Language') - { - $title = FinderHelperLanguage::branchLanguageTitle($item->title); - } - else - { - $key = FinderHelperLanguage::branchSingular($item->title); - $title = $lang->hasKey($key) ? JText::_($key) : $item->title; - } - ?> - num_children === 0) : ?> - - - - escape(trim($title, '**')) === 'Language' && JLanguageMultilang::isEnabled()) : ?> - - - - num_children !== 0) : ?> - - num_children; ?> - - - - - - num_children === 0) : ?> - - count_published; ?> - - - - - - num_children === 0) : ?> - - count_unpublished; ?> - - - - -
- -
- - - - - diff --git a/administrator/components/com_finder/views/maps/view.html.php b/administrator/components/com_finder/views/maps/view.html.php deleted file mode 100644 index 31a0d0f4da49a..0000000000000 --- a/administrator/components/com_finder/views/maps/view.html.php +++ /dev/null @@ -1,148 +0,0 @@ -items = $this->get('Items'); - $this->total = $this->get('Total'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - FinderHelper::addSubmenu('maps'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - - // Prepare the view. - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - - return parent::display($tpl); - } - - /** - * Method to configure the toolbar for this view. - * - * @return void - * - * @since 2.5 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_finder'); - - JToolbarHelper::title(JText::_('COM_FINDER_MAPS_TOOLBAR_TITLE'), 'zoom-in finder'); - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publishList('maps.publish'); - JToolbarHelper::unpublishList('maps.unpublish'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_finder'); - } - - JToolbarHelper::divider(); - JToolbar::getInstance('toolbar')->appendButton( - 'Popup', - 'bars', - 'COM_FINDER_STATISTICS', - 'index.php?option=com_finder&view=statistics&tmpl=component', - 550, - 350 - ); - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_COMPONENTS_FINDER_MANAGE_CONTENT_MAPS'); - - if ($canDo->get('core.delete')) - { - JToolbarHelper::deleteList('', 'maps.delete'); - JToolbarHelper::divider(); - } - } -} diff --git a/administrator/components/com_finder/views/statistics/tmpl/default.php b/administrator/components/com_finder/views/statistics/tmpl/default.php deleted file mode 100644 index 3ae82a5066255..0000000000000 --- a/administrator/components/com_finder/views/statistics/tmpl/default.php +++ /dev/null @@ -1,56 +0,0 @@ - -

- -

- -
-
-

data->term_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->taxonomy_node_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')), number_format($this->data->taxonomy_branch_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR'))); ?>

- - - - - - - - - data->type_list as $type) : ?> - - - - - - - - - - -
- - - -
- type_title); - $lang_string = JText::_($lang_key); - echo $lang_string === $lang_key ? $type->type_title : $lang_string; - ?> - - link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); ?> -
- - - data->link_count, 0, JText::_('DECIMALS_SEPARATOR'), JText::_('THOUSANDS_SEPARATOR')); ?> -
-
-
diff --git a/administrator/components/com_finder/views/statistics/view.html.php b/administrator/components/com_finder/views/statistics/view.html.php deleted file mode 100644 index ab45541e8a208..0000000000000 --- a/administrator/components/com_finder/views/statistics/view.html.php +++ /dev/null @@ -1,50 +0,0 @@ -data = $this->get('Data'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - return parent::display($tpl); - } -} diff --git a/administrator/components/com_installer/Controller/DatabaseController.php b/administrator/components/com_installer/Controller/DatabaseController.php new file mode 100644 index 0000000000000..dbe70a0e20d95 --- /dev/null +++ b/administrator/components/com_installer/Controller/DatabaseController.php @@ -0,0 +1,70 @@ +input->get('cid', array(), 'array'); + + if (!is_array($cid) || count($cid) < 1) + { + $this->app->getLogger()->warning( + Text::_( + 'COM_INSTALLER_ERROR_NO_EXTENSIONS_SELECTED' + ), array('category' => 'jerror') + ); + } + else + { + // Get the model + /** @var DatabaseModel $model */ + $model = $this->getModel('database'); + $model->fix($cid); + + $updateModel = new UpdateModel; + $updateModel->purge(); + + // Refresh versionable assets cache + $this->app->flushAssets(); + } + + $this->setRedirect(Route::_('index.php?option=com_installer&view=database', false)); + } +} diff --git a/administrator/components/com_installer/Controller/DiscoverController.php b/administrator/components/com_installer/Controller/DiscoverController.php new file mode 100644 index 0000000000000..a3ff9b0f6c5c4 --- /dev/null +++ b/administrator/components/com_installer/Controller/DiscoverController.php @@ -0,0 +1,68 @@ +getModel('discover'); + $model->discover(); + $this->setRedirect(Route::_('index.php?option=com_installer&view=discover', false)); + } + + /** + * Install a discovered extension. + * + * @return void + * + * @since 1.6 + */ + public function install() + { + /* @var \Joomla\Component\Installer\Administrator\Model\DiscoverModel $model */ + $model = $this->getModel('discover'); + $model->discover_install(); + $this->setRedirect(Route::_('index.php?option=com_installer&view=discover', false)); + } + + /** + * Clean out the discovered extension cache. + * + * @return void + * + * @since 1.6 + */ + public function purge() + { + /* @var \Joomla\Component\Installer\Administrator\Model\DiscoverModel $model */ + $model = $this->getModel('discover'); + $model->purge(); + $this->setRedirect(Route::_('index.php?option=com_installer&view=discover', false), $model->_message); + } +} diff --git a/administrator/components/com_installer/Controller/DisplayController.php b/administrator/components/com_installer/Controller/DisplayController.php new file mode 100644 index 0000000000000..74f9fae2604d2 --- /dev/null +++ b/administrator/components/com_installer/Controller/DisplayController.php @@ -0,0 +1,69 @@ +input->get('view', 'install'); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + $ftp = ClientHelper::setCredentialsFromRequest('ftp'); + $view->ftp = &$ftp; + + // Get the model for the view. + $model = $this->getModel($vName); + + // Push the model into the view (as default). + $view->setModel($model, true); + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + + // Load the submenu. + InstallerHelper::addSubmenu($vName); + $view->display(); + } + + return $this; + } +} diff --git a/administrator/components/com_installer/Controller/InstallController.php b/administrator/components/com_installer/Controller/InstallController.php new file mode 100644 index 0000000000000..b41cd99a2be64 --- /dev/null +++ b/administrator/components/com_installer/Controller/InstallController.php @@ -0,0 +1,105 @@ +getModel('install'); + + // TODO: Reset the users acl here as well to kill off any missing bits. + $result = $model->install(); + + $app = $this->app; + $redirect_url = $app->getUserState('com_installer.redirect_url'); + + if (!$redirect_url) + { + $redirect_url = base64_decode($this->input->get('return')); + } + + // Don't redirect to an external URL. + if (!Uri::isInternal($redirect_url)) + { + $redirect_url = ''; + } + + if (empty($redirect_url)) + { + $redirect_url = Route::_('index.php?option=com_installer&view=install', false); + } + else + { + // Wipe out the user state when we're going to redirect. + $app->setUserState('com_installer.redirect_url', ''); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + } + + $this->setRedirect($redirect_url); + + return $result; + } + + /** + * Install an extension from drag & drop ajax upload. + * + * @return void + * + * @since 3.7.0 + */ + public function ajax_upload() + { + $app = $this->app; + $message = $app->getUserState('com_installer.message'); + + // Do install + $result = $this->install(); + + // Get redirect URL + $redirect = $this->redirect; + + // Push message queue to session because we will redirect page by \Javascript, not $app->redirect(). + // The "application.queue" is only set in redirect() method, so we must manually store it. + $app->getSession()->set('application.queue', $app->getMessageQueue()); + + header('Content-Type: application/json'); + + echo new JsonResponse(array('redirect' => $redirect), $message, !$result); + + $app->close(); + } +} diff --git a/administrator/components/com_installer/Controller/ManageController.php b/administrator/components/com_installer/Controller/ManageController.php new file mode 100644 index 0000000000000..e40424aedc073 --- /dev/null +++ b/administrator/components/com_installer/Controller/ManageController.php @@ -0,0 +1,139 @@ +registerTask('unpublish', 'publish'); + $this->registerTask('publish', 'publish'); + } + + /** + * Enable/Disable an extension (if supported). + * + * @return void + * + * @since 1.6 + */ + public function publish() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + $values = array('publish' => 1, 'unpublish' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($values, $task, 0, 'int'); + + if (empty($ids)) + { + $this->setMessage(Text::_('COM_INSTALLER_ERROR_NO_EXTENSIONS_SELECTED'), 'warning'); + } + else + { + /* @var \Joomla\Component\Installer\Administrator\Model\ManageModel $model */ + $model = $this->getModel('manage'); + + // Change the state of the records. + if (!$model->publish($ids, $value)) + { + $this->setMessage(implode('
', $model->getErrors()), 'warning'); + } + else + { + if ($value == 1) + { + $ntext = 'COM_INSTALLER_N_EXTENSIONS_PUBLISHED'; + } + else + { + $ntext = 'COM_INSTALLER_N_EXTENSIONS_UNPUBLISHED'; + } + + $this->setMessage(Text::plural($ntext, count($ids))); + } + } + + $this->setRedirect(Route::_('index.php?option=com_installer&view=manage', false)); + } + + /** + * Remove an extension (Uninstall). + * + * @return void + * + * @since 1.5 + */ + public function remove() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Installer\Administrator\Model\ManageModel $model */ + $model = $this->getModel('manage'); + + $eid = $this->input->get('cid', array(), 'array'); + $eid = ArrayHelper::toInteger($eid, array()); + $model->remove($eid); + $this->setRedirect(Route::_('index.php?option=com_installer&view=manage', false)); + } + + /** + * Refreshes the cached metadata about an extension. + * + * Useful for debugging and testing purposes when the XML file might change. + * + * @return void + * + * @since 1.6 + */ + public function refresh() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Installer\Administrator\Model\ManageModel $model */ + $model = $this->getModel('manage'); + + $uid = $this->input->get('cid', array(), 'array'); + $uid = ArrayHelper::toInteger($uid, array()); + $model->refresh($uid); + $this->setRedirect(Route::_('index.php?option=com_installer&view=manage', false)); + } +} diff --git a/administrator/components/com_installer/Controller/UpdateController.php b/administrator/components/com_installer/Controller/UpdateController.php new file mode 100644 index 0000000000000..df47b8215c7d7 --- /dev/null +++ b/administrator/components/com_installer/Controller/UpdateController.php @@ -0,0 +1,207 @@ +getModel('update'); + + $uid = $this->input->get('cid', array(), 'array'); + $uid = ArrayHelper::toInteger($uid, array()); + + // Get the minimum stability. + $params = ComponentHelper::getComponent('com_installer')->getParams(); + $minimum_stability = $params->get('minimum_stability', Updater::STABILITY_STABLE, 'int'); + + $model->update($uid, $minimum_stability); + + $app = $this->app; + $redirect_url = $app->getUserState('com_installer.redirect_url'); + + // Don't redirect to an external URL. + if (!Uri::isInternal($redirect_url)) + { + $redirect_url = ''; + } + + if (empty($redirect_url)) + { + $redirect_url = Route::_('index.php?option=com_installer&view=update', false); + } + else + { + // Wipe out the user state when we're going to redirect. + $app->setUserState('com_installer.redirect_url', ''); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + } + + $this->setRedirect($redirect_url); + } + + /** + * Find new updates. + * + * @return void + * + * @since 1.6 + */ + public function find() + { + (Session::checkToken() or Session::checkToken('get')) or jexit(Text::_('JINVALID_TOKEN')); + + // Get the caching duration. + $params = ComponentHelper::getComponent('com_installer')->getParams(); + $cache_timeout = $params->get('cachetimeout', 6, 'int'); + $cache_timeout = 3600 * $cache_timeout; + + // Get the minimum stability. + $minimum_stability = $params->get('minimum_stability', Updater::STABILITY_STABLE, 'int'); + + // Find updates. + /* @var \Joomla\Component\Installer\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('update'); + + $disabledUpdateSites = $model->getDisabledUpdateSites(); + + if ($disabledUpdateSites) + { + $updateSitesUrl = Route::_('index.php?option=com_installer&view=updatesites'); + $this->setMessage(Text::sprintf('COM_INSTALLER_MSG_UPDATE_SITES_COUNT_CHECK', $updateSitesUrl), 'warning'); + } + + $model->findUpdates(0, $cache_timeout, $minimum_stability); + $this->setRedirect(Route::_('index.php?option=com_installer&view=update', false)); + } + + /** + * Purges updates. + * + * @return void + * + * @since 1.6 + */ + public function purge() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Installer\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('update'); + $model->purge(); + + /** + * We no longer need to enable update sites in Joomla! 3.4 as we now allow the users to manage update sites + * themselves. + * $model->enableSites(); + */ + + $this->setRedirect(Route::_('index.php?option=com_installer&view=update', false), $model->_message); + } + + /** + * Fetch and report updates in \JSON format, for A\JAX requests + * + * @return void + * + * @since 2.5 + */ + public function ajax() + { + $app = $this->app; + + if (!Session::checkToken('get')) + { + $app->setHeader('status', 403, true); + $app->sendHeaders(); + echo Text::_('JINVALID_TOKEN'); + $app->close(); + } + + $eid = $this->input->getInt('eid', 0); + $skip = $this->input->get('skip', array(), 'array'); + $cache_timeout = $this->input->getInt('cache_timeout', 0); + $minimum_stability = $this->input->getInt('minimum_stability', -1); + + $params = ComponentHelper::getComponent('com_installer')->getParams(); + + if ($cache_timeout == 0) + { + $cache_timeout = $params->get('cachetimeout', 6, 'int'); + $cache_timeout = 3600 * $cache_timeout; + } + + if ($minimum_stability < 0) + { + $minimum_stability = $params->get('minimum_stability', Updater::STABILITY_STABLE, 'int'); + } + + /* @var \Joomla\Component\Installer\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('update'); + $model->findUpdates($eid, $cache_timeout, $minimum_stability); + + $model->setState('list.start', 0); + $model->setState('list.limit', 0); + + if ($eid != 0) + { + $model->setState('filter.extension_id', $eid); + } + + $updates = $model->getItems(); + + if (!empty($skip)) + { + $unfiltered_updates = $updates; + $updates = array(); + + foreach ($unfiltered_updates as $update) + { + if (!in_array($update->extension_id, $skip)) + { + $updates[] = $update; + } + } + } + + echo json_encode($updates); + + $app->close(); + } +} diff --git a/administrator/components/com_installer/Controller/UpdatesitesController.php b/administrator/components/com_installer/Controller/UpdatesitesController.php new file mode 100644 index 0000000000000..68ad66d9d7e0f --- /dev/null +++ b/administrator/components/com_installer/Controller/UpdatesitesController.php @@ -0,0 +1,136 @@ +registerTask('unpublish', 'publish'); + $this->registerTask('publish', 'publish'); + $this->registerTask('delete', 'delete'); + $this->registerTask('rebuild', 'rebuild'); + } + + /** + * Enable/Disable an extension (if supported). + * + * @return void + * + * @since 3.4 + * + * @throws \Exception on error + */ + public function publish() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + $values = array('publish' => 1, 'unpublish' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($values, $task, 0, 'int'); + + if (empty($ids)) + { + throw new \Exception(Text::_('COM_INSTALLER_ERROR_NO_UPDATESITES_SELECTED'), 500); + } + + // Get the model. + /* @var \Joomla\Component\Installer\Administrator\Model\UpdatesitesModel $model */ + $model = $this->getModel('Updatesites'); + + // Change the state of the records. + if (!$model->publish($ids, $value)) + { + throw new \Exception(implode('
', $model->getErrors()), 500); + } + + $ntext = ($value == 0) ? 'COM_INSTALLER_N_UPDATESITES_UNPUBLISHED' : 'COM_INSTALLER_N_UPDATESITES_PUBLISHED'; + + $this->setMessage(Text::plural($ntext, count($ids))); + + $this->setRedirect(Route::_('index.php?option=com_installer&view=updatesites', false)); + } + + /** + * Deletes an update site (if supported). + * + * @return void + * + * @since 3.6 + * + * @throws \Exception on error + */ + public function delete() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + + if (empty($ids)) + { + throw new \Exception(Text::_('COM_INSTALLER_ERROR_NO_UPDATESITES_SELECTED'), 500); + } + + // Delete the records. + $this->getModel('Updatesites')->delete($ids); + + $this->setRedirect(Route::_('index.php?option=com_installer&view=updatesites', false)); + } + + /** + * Rebuild update sites tables. + * + * @return void + * + * @since 3.6 + */ + public function rebuild() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Rebuild the update sites. + $this->getModel('Updatesites')->rebuild(); + + $this->setRedirect(Route::_('index.php?option=com_installer&view=updatesites', false)); + } +} diff --git a/administrator/components/com_installer/Field/ExtensionstatusField.php b/administrator/components/com_installer/Field/ExtensionstatusField.php new file mode 100644 index 0000000000000..9bd1cf764452d --- /dev/null +++ b/administrator/components/com_installer/Field/ExtensionstatusField.php @@ -0,0 +1,47 @@ +getQuery(true) + ->select('DISTINCT type') + ->from('#__extensions'); + $db->setQuery($query); + $types = $db->loadColumn(); + + $options = array(); + + foreach ($types as $type) + { + $options[] = HTMLHelper::_('select.option', $type, Text::_('COM_INSTALLER_TYPE_' . strtoupper($type))); + } + + return $options; + } + + /** + * Get a list of filter options for the extension types. + * + * @return array An array of \stdClass objects. + * + * @since 3.0 + */ + public static function getExtensionGroupes() + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT ' . $db->quoteName('folder')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('folder') . ' != ' . $db->quote('')) + ->order($db->quoteName('folder')); + $db->setQuery($query); + $folders = $db->loadColumn(); + + $options = array(); + + foreach ($folders as $folder) + { + $options[] = HTMLHelper::_('select.option', $folder, $folder); + } + + return $options; + } + + /** + * Get a list of filter options for the application clients. + * + * @return array An array of \JHtmlOption elements. + * + * @since 3.5 + */ + public static function getClientOptions() + { + // Build the filter options. + $options = array(); + $options[] = HTMLHelper::_('select.option', '0', Text::_('JSITE')); + $options[] = HTMLHelper::_('select.option', '1', Text::_('JADMINISTRATOR')); + + return $options; + } + + /** + * Get a list of filter options for the application statuses. + * + * @return array An array of \JHtmlOption elements. + * + * @since 3.5 + */ + public static function getStateOptions() + { + // Build the filter options. + $options = array(); + $options[] = HTMLHelper::_('select.option', '0', Text::_('JDISABLED')); + $options[] = HTMLHelper::_('select.option', '1', Text::_('JENABLED')); + $options[] = HTMLHelper::_('select.option', '2', Text::_('JPROTECTED')); + $options[] = HTMLHelper::_('select.option', '3', Text::_('JUNPROTECTED')); + + return $options; + } + + /** + * Get a list of filter options for the application statuses. + * + * @param string $element element of an extension + * @param string $type type of an extension + * @param integer $client_id client_id of an extension + * @param string $folder folder of an extension + * + * @return \SimpleXMLElement + * + * @since 4.0.0 + */ + public static function getInstallationXML($element, $type, $client_id = 1, $folder = null) + { + $path = $client_id ? JPATH_ADMINISTRATOR : JPATH_ROOT; + + switch ($type) + { + case 'component': + $path .= '/components/' . $element . '/' . substr($element, 4) . '.xml'; + break; + case 'plugin': + $path .= '/plugins/' . $folder . '/' . $element . '/' . $element . '.xml'; + break; + case 'module': + $path .= '/modules/' . $element . '/' . $element->element . '.xml'; + break; + case 'template': + $path .= '/templates/' . $element . '/templateDetails.xml'; + break; + case 'library': + $path = JPATH_ADMINISTRATOR . '/manifests/libraries/' . $element . '.xml'; + break; + case 'file': + $path = JPATH_ADMINISTRATOR . '/manifests/files/' . $element . '.xml'; + break; + case 'package': + $path = JPATH_ADMINISTRATOR . '/manifests/packages/' . $element . '.xml'; + } + + return simplexml_load_file($path); + } +} diff --git a/administrator/components/com_installer/Model/DatabaseModel.php b/administrator/components/com_installer/Model/DatabaseModel.php new file mode 100644 index 0000000000000..feaf5de695a2a --- /dev/null +++ b/administrator/components/com_installer/Model/DatabaseModel.php @@ -0,0 +1,697 @@ +errorCount; + } + + /** + * Method to populate the schema cache. + * + * @param integer $cid The extension ID to get the schema for + * + * @return void + * + * @throws \Exception + * + * @since 4.0.0 + */ + private function fetchSchemaCache($cid = 0) + { + // We already have it + if (array_key_exists($cid, $this->changeSetList)) + { + return; + } + + // Add the ID to the state so it can be used for filtering + if ($cid) + { + $this->setState('filter.extension_id', $cid); + } + + // With the parent::save it can get the limit and we need to make sure it gets all extensions + $results = $this->_getList($this->getListQuery()); + + foreach ($results as $result) + { + $errorMessages = array(); + $errorCount = 0; + + if (strcmp($result->element, 'joomla') === 0) + { + $result->element = 'com_admin'; + + if (!$this->getDefaultTextFilters()) + { + $errorMessages[] = Text::_('COM_INSTALLER_MSG_DATABASE_FILTER_ERROR'); + $errorCount++; + } + } + + $db = $this->getDbo(); + $folderTmp = JPATH_ADMINISTRATOR . '/components/' . $result->element . '/sql/updates/'; + + // If the extension doesn't follow the standard location for the + // update sql files we don't support it + if (!file_exists($folderTmp)) + { + $installationXML = InstallerHelper::getInstallationXML($result->element, $result->type); + $folderTmp = (string) $installationXML->update->schemas->schemapath[0]; + + $a = explode('/', $folderTmp); + array_pop($a); + $folderTmp = JPATH_ADMINISTRATOR . '/components/' . $result->element . '/' . implode('/', $a); + } + + $changeSet = new ChangeSet($db, $folderTmp); + + // If the version in the #__schemas is different + // than the update files, add to problems message + $schema = $changeSet->getSchema(); + + if ($result->version_id !== $schema) + { + $errorMessages[] = Text::sprintf('COM_INSTALLER_MSG_DATABASE_SCHEMA_ERROR', $result->version_id, $schema); + $errorCount++; + } + + // If the version in the manifest_cache is different than the + // version in the installation xml, add to problems message + $compareUpdateMessage = $this->compareUpdateVersion($result); + + if ($compareUpdateMessage) + { + $errorMessages[] = $compareUpdateMessage; + $errorCount++; + } + + // If there are errors in the database, add to the problems message + $errors = $changeSet->check(); + + $errorsMessage = $this->getErrorsMessage($errors); + + if ($errorsMessage) + { + $errorMessages = array_merge($errorMessages, $errorsMessage); + $errorCount++; + } + + // Number of database tables Checked and Skipped + $errorMessages = array_merge($errorMessages, $this->getOtherInformationMessage($changeSet->getStatus())); + + // Set the total number of errors + $this->errorCount += $errorCount; + + // Collect the extension details + $this->changeSetList[$result->extension_id] = array( + 'folderTmp' => $folderTmp, + 'errorsMessage' => $errorMessages, + 'errorsCount' => $errorCount, + 'results' => $changeSet->getStatus(), + 'schema' => $schema, + 'extension' => $result + ); + } + } + + /** + * 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 1.6 + */ + protected function populateState($ordering = 'name', $direction = 'asc') + { + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); + $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); + + // Prepare the utf8mb4 conversion check table + $this->prepareUtf8mb4StatusTable(); + + parent::populateState($ordering, $direction); + } + + /** + * Fixes database problems. + * + * @param array $cids List of the selected extensions to fix + * + * @return void|boolean + * + * @throws \Exception + * + * @since 4.0.0 + */ + public function fix($cids = array()) + { + $db = $this->getDbo(); + + foreach ($cids as $i => $cid) + { + // Load the database issues + $this->fetchSchemaCache($cid); + + $changeSet = $this->changeSetList[$cid]; + $changeSet['changeset'] = new ChangeSet($db, $changeSet['folderTmp']); + $changeSet['changeset']->fix(); + + $this->fixSchemaVersion($changeSet['changeset'], $changeSet['extension']->extension_id); + $this->fixUpdateVersion($changeSet['extension']->extension_id); + + if ($i === 'com_admin') + { + $installer = new \JoomlaInstallerScript; + $installer->deleteUnexistingFiles(); + $this->fixDefaultTextFilters(); + + /* + * Finally, if the schema updates succeeded, make sure the database table is + * converted to utf8mb4 or, if not suported by the server, compatible to it. + */ + $statusArray = $changeSet['changeset']->getStatus(); + + if (count($statusArray['error']) == 0) + { + $installer->convertTablesToUtf8mb4(false); + } + } + } + } + + /** + * Gets the changeset array. + * + * @return array Array with the information of the versions problems, errors and the extensions itself + * + * @throws \Exception + * + * @since 4.0.0 + */ + public function getItems() + { + $this->fetchSchemaCache(); + + $results = parent::getItems(); + $results = $this->mergeSchemaCache($results); + + return $results; + } + + /** + * Method to get the database query + * + * @return \JDatabaseQuery The database query + * + * @since 4.0.0 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select( + $db->quoteName( + array( + 'extensions.client_id', + 'extensions.element', + 'extensions.extension_id', + 'extensions.folder', + 'extensions.manifest_cache', + 'extensions.name', + 'extensions.type', + 'schemas.version_id' + ) + ) + ) + ->from( + $db->quoteName( + '#__schemas', + 'schemas' + ) + )->join( + 'INNER', + $db->quoteName( + '#__extensions', 'extensions' + ) . ' ON (' . $db->quoteName( + 'schemas.extension_id' + ) . ' = ' . $db->quoteName( + 'extensions.extension_id' + ) . ')' + ); + + $type = $this->getState('filter.type'); + $clientId = $this->getState('filter.client_id'); + $extensionId = $this->getState('filter.extension_id'); + $folder = $this->getState('filter.folder'); + + if ($type) + { + $query->where($db->quoteName('extensions.type') . ' = ' . $db->quote($type)); + } + + if ($clientId != '') + { + $query->where($db->quoteName('extensions.client_id') . ' = ' . (int) $clientId); + } + + if ($extensionId != '') + { + $query->where($db->quoteName('extensions.extension_id') . ' = ' . (int) $extensionId); + } + + if ($folder != '' && in_array($type, array('plugin', 'library', ''))) + { + $query->where($db->quoteName('extensions.folder') . ' = ' . $db->quote($folder == '*' ? '' : $folder)); + } + + // Process search filter (update site id). + $search = $this->getState('filter.search'); + + if (!empty($search) && stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('schemas.extension_id') . ' = ' . (int) substr($search, 3)); + } + + return $query; + } + + /** + * Merge the items that will be visible with the changeSet information in cache + * + * @param array $results extensions returned from parent::getItems(). + * + * @return array the changeSetList of the merged items + * + * @since 4.0.0 + */ + protected function mergeSchemaCache($results) + { + $changeSetList = $this->changeSetList; + $finalResults = array(); + + foreach ($results as $result) + { + if (array_key_exists($result->extension_id, $changeSetList) && $changeSetList[$result->extension_id]) + { + $finalResults[] = $changeSetList[$result->extension_id]; + } + } + + return $finalResults; + } + + /** + * Get version from #__schemas table. + * + * @param integer $extensionId id of the extensions. + * + * @return mixed the return value from the query, or null if the query fails. + * + * @throws \Exception + * + * @since 4.0.0 + */ + public function getSchemaVersion($extensionId) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('version_id')) + ->from($db->quoteName('#__schemas')) + ->where($db->quoteName('extension_id') . ' = ' . (int) $extensionId); + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * Fix schema version if wrong. + * + * @param ChangeSet $changeSet Schema change set. + * @param integer $extensionId ID of the extensions. + * + * @return mixed string schema version if success, false if fail. + * + * @throws \Exception + * + * @since 4.0.0 + */ + public function fixSchemaVersion($changeSet, $extensionId) + { + // Get correct schema version -- last file in array. + $schema = $changeSet->getSchema(); + + // Check value. If ok, don't do update. + if ($schema == $this->getSchemaVersion($extensionId)) + { + return $schema; + } + + // Delete old row. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__schemas')) + ->where($db->quoteName('extension_id') . ' = ' . (int) $extensionId); + $db->setQuery($query)->execute(); + + // Add new row. + $query->clear() + ->insert($db->quoteName('#__schemas')) + ->columns($db->quoteName('extension_id') . ',' . $db->quoteName('version_id')) + ->values((int) $extensionId . ', ' . $db->quote($schema)); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (ExecutionFailureException $e) + { + return false; + } + + return $schema; + } + + /** + * Get current version from #__extensions table. + * + * @param object $extension data from #__extensions of a single extension. + * + * @return mixed string message with the errors with the update version or null if none + * + * @since 4.0.0 + */ + public function compareUpdateVersion($extension) + { + $updateVersion = json_decode($extension->manifest_cache)->version; + + if ($extension->element === 'com_admin') + { + $extensionVersion = JVERSION; + } + else + { + $installationXML = InstallerHelper::getInstallationXML($extension->element, $extension->type); + $extensionVersion = (string) $installationXML->version; + } + + if (version_compare($extensionVersion, $updateVersion) != 0) + { + return Text::sprintf('COM_INSTALLER_MSG_DATABASE_UPDATEVERSION_ERROR', $updateVersion, $extension->name, $extensionVersion); + } + + return null; + } + + /** + * Get a message of the tables skipped and checked + * + * @param array $status status of of the update files + * + * @return array Messages with the errors with the update version + * + * @since 4.0.0 + */ + private function getOtherInformationMessage($status) + { + $problemsMessage = array(); + $problemsMessage[] = Text::sprintf('COM_INSTALLER_MSG_DATABASE_CHECKED_OK', count($status['ok'])); + $problemsMessage[] = Text::sprintf('COM_INSTALLER_MSG_DATABASE_SKIPPED', count($status['skipped'])); + + return $problemsMessage; + } + + /** + * Get a message with all errors found in a given extension + * + * @param array $errors data from #__extensions of a single extension. + * + * @return array List of messages with the errors in the database + * + * @since 4.0.0 + */ + private function getErrorsMessage($errors) + { + $errorMessages = array(); + + foreach ($errors as $line => $error) + { + $key = 'COM_INSTALLER_MSG_DATABASE_' . $error->queryType; + $messages = $error->msgElements; + $file = basename($error->file); + $message0 = isset($messages[0]) ? $messages[0] : ' '; + $message1 = isset($messages[1]) ? $messages[1] : ' '; + $message2 = isset($messages[2]) ? $messages[2] : ' '; + $errorMessages[] = Text::sprintf($key, $file, $message0, $message1, $message2); + } + + return $errorMessages; + } + + /** + * Fix Joomla version in #__extensions table if wrong (doesn't equal \JVersion short version). + * + * @param integer $extensionId id of the extension + * + * @return mixed string update version if success, false if fail. + * + * @since 4.0.0 + */ + public function fixUpdateVersion($extensionId) + { + $table = new Extension($this->getDbo()); + $table->load($extensionId); + $cache = new Registry($table->manifest_cache); + $updateVersion = $cache->get('version'); + + if ($table->get('type') === 'file' && $table->get('element') === 'joomla') + { + $extensionVersion = new Version; + $extensionVersion = $extensionVersion->getShortVersion(); + } + else + { + $installationXML = InstallerHelper::getInstallationXML($table->get('element'), $table->get('type')); + $extensionVersion = (string) $installationXML->version; + } + + if ($updateVersion === $extensionVersion) + { + return $updateVersion; + } + + $cache->set('version', $extensionVersion); + $table->set('manifest_cache', $cache->toString()); + + if ($table->store()) + { + return $extensionVersion; + } + + return false; + } + + /** + * For version 2.5.x only + * Check if com_config parameters are blank. + * + * @return string default text filters (if any). + * + * @since 4.0.0 + */ + public function getDefaultTextFilters() + { + $table = new Extension($this->getDbo()); + $table->load($table->find(array('name' => 'com_config'))); + + return $table->params; + } + + /** + * For version 2.5.x only + * Check if com_config parameters are blank. If so, populate with com_content text filters. + * + * @return void + * + * @since 4.0.0 + */ + private function fixDefaultTextFilters() + { + $table = new Extension($this->getDbo()); + $table->load($table->find(array('name' => 'com_config'))); + + // Check for empty $config and non-empty content filters. + if (!$table->params) + { + // Get filters from com_content and store if you find them. + $contentParams = ComponentHelper::getComponent('com_content')->getParams(); + + if ($contentParams->get('filters')) + { + $newParams = new Registry; + $newParams->set('filters', $contentParams->get('filters')); + $table->params = (string) $newParams; + $table->store(); + } + } + } + + /** + * Prepare the table to save the status of utf8mb4 conversion + * Make sure it contains 1 initialized record if there is not + * already exactly 1 record. + * + * @return void + * + * @since 3.5 + */ + private function prepareUtf8mb4StatusTable() + { + $db = Factory::getDbo(); + + if (!$db instanceof UTF8MB4SupportInterface) + { + return; + } + + $creaTabSql = 'CREATE TABLE IF NOT EXISTS ' . $db->quoteName('#__utf8_conversion') + . ' (' . $db->quoteName('converted') . ' tinyint(4) NOT NULL DEFAULT 0' + . ') ENGINE=InnoDB'; + + if ($db->hasUTF8mb4Support()) + { + $creaTabSql = $creaTabSql + . ' DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;'; + } + else + { + $creaTabSql = $creaTabSql + . ' DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_unicode_ci;'; + } + + $db->setQuery($creaTabSql)->execute(); + + $db->setQuery('SELECT COUNT(*) FROM ' . $db->quoteName('#__utf8_conversion') . ';'); + + $count = $db->loadResult(); + + if ($count > 1) + { + // Table messed up somehow, clear it + $db->setQuery('DELETE FROM ' . $db->quoteName('#__utf8_conversion') + . ';')->execute(); + $db->setQuery('INSERT INTO ' . $db->quoteName('#__utf8_conversion') + . ' (' . $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(); + } + } +} diff --git a/administrator/components/com_installer/Model/DiscoverModel.php b/administrator/components/com_installer/Model/DiscoverModel.php new file mode 100644 index 0000000000000..56e14827930bb --- /dev/null +++ b/administrator/components/com_installer/Model/DiscoverModel.php @@ -0,0 +1,264 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); + $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); + + $this->setState('message', $app->getUserState('com_installer.message')); + $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); + + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + parent::populateState($ordering, $direction); + } + + /** + * Method to get the database query. + * + * @return \JDatabaseQuery the database query + * + * @since 3.1 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('state') . ' = -1'); + + // Process select filters. + $type = $this->getState('filter.type'); + $clientId = $this->getState('filter.client_id'); + $folder = $this->getState('filter.folder'); + + if ($type) + { + $query->where($db->quoteName('type') . ' = ' . $db->quote($type)); + } + + if ($clientId != '') + { + $query->where($db->quoteName('client_id') . ' = ' . (int) $clientId); + } + + if ($folder != '' && in_array($type, array('plugin', 'library', ''))) + { + $query->where($db->quoteName('folder') . ' = ' . $db->quote($folder == '*' ? '' : $folder)); + } + + // Process search filter. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('extension_id') . ' = ' . (int) substr($search, 3)); + } + } + + // Note: The search for name, ordering and pagination are processed by the parent InstallerModel class (in extension.php). + + return $query; + } + + /** + * Discover extensions. + * + * Finds uninstalled extensions + * + * @return void + * + * @since 1.6 + */ + public function discover() + { + // Purge the list of discovered extensions and fetch them again. + $this->purge(); + $results = Installer::getInstance()->discover(); + + // Get all templates, including discovered ones + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName(array('extension_id', 'element', 'folder', 'client_id', 'type'))) + ->from($db->quoteName('#__extensions')); + $db->setQuery($query); + $installedtmp = $db->loadObjectList(); + + $extensions = array(); + + foreach ($installedtmp as $install) + { + $key = implode(':', array($install->type, $install->element, $install->folder, $install->client_id)); + $extensions[$key] = $install; + } + + foreach ($results as $result) + { + // Check if we have a match on the element + $key = implode(':', array($result->type, $result->element, $result->folder, $result->client_id)); + + if (!array_key_exists($key, $extensions)) + { + // Put it into the table + $result->check(); + $result->store(); + } + } + } + + /** + * Installs a discovered extension. + * + * @return void + * + * @since 1.6 + */ + public function discover_install() + { + $app = Factory::getApplication(); + $input = $app->input; + $eid = $input->get('cid', 0, 'array'); + + if (is_array($eid) || $eid) + { + if (!is_array($eid)) + { + $eid = array($eid); + } + + $eid = ArrayHelper::toInteger($eid); + $failed = false; + + foreach ($eid as $id) + { + $installer = new Installer; + + $result = $installer->discover_install($id); + + if (!$result) + { + $failed = true; + $app->enqueueMessage(Text::_('COM_INSTALLER_MSG_DISCOVER_INSTALLFAILED') . ': ' . $id); + } + } + + // TODO - We are only receiving the message for the last Installer instance + $this->setState('action', 'remove'); + $this->setState('name', $installer->get('name')); + $app->setUserState('com_installer.message', $installer->message); + $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); + + if (!$failed) + { + $app->enqueueMessage(Text::_('COM_INSTALLER_MSG_DISCOVER_INSTALLSUCCESSFUL')); + } + } + else + { + $app->enqueueMessage(Text::_('COM_INSTALLER_MSG_DISCOVER_NOEXTENSIONSELECTED')); + } + } + + /** + * Cleans out the list of discovered extensions. + * + * @return boolean True on success + * + * @since 1.6 + */ + public function purge() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->delete($db->quoteName('#__extensions')) + ->where($db->quoteName('state') . ' = -1'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (ExecutionFailureException $e) + { + $this->_message = Text::_('COM_INSTALLER_MSG_DISCOVER_FAILEDTOPURGEEXTENSIONS'); + + return false; + } + + $this->_message = Text::_('COM_INSTALLER_MSG_DISCOVER_PURGEDDISCOVEREDEXTENSIONS'); + + return true; + } +} diff --git a/administrator/components/com_installer/Model/InstallModel.php b/administrator/components/com_installer/Model/InstallModel.php new file mode 100644 index 0000000000000..8b5b9364049e1 --- /dev/null +++ b/administrator/components/com_installer/Model/InstallModel.php @@ -0,0 +1,425 @@ +setState('message', $app->getUserState('com_installer.message')); + $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + parent::populateState(); + } + + /** + * Install an extension from either folder, URL or upload. + * + * @return boolean + * + * @since 1.5 + */ + public function install() + { + $this->setState('action', 'install'); + + // Set FTP credentials, if given. + ClientHelper::setCredentialsFromRequest('ftp'); + $app = Factory::getApplication(); + + // Load installer plugins for assistance if required: + PluginHelper::importPlugin('installer'); + + $package = null; + + // This event allows an input pre-treatment, a custom pre-packing or custom installation. + // (e.g. from a \JSON description). + $results = $app->triggerEvent('onInstallerBeforeInstallation', array($this, &$package)); + + if (in_array(true, $results, true)) + { + return true; + } + + if (in_array(false, $results, true)) + { + return false; + } + + $installType = $app->input->getWord('installtype'); + + if ($package === null) + { + switch ($installType) + { + case 'folder': + // Remember the 'Install from Directory' path. + $app->getUserStateFromRequest($this->_context . '.install_directory', 'install_directory'); + $package = $this->_getPackageFromFolder(); + break; + + case 'upload': + $package = $this->_getPackageFromUpload(); + break; + + case 'url': + $package = $this->_getPackageFromUrl(); + break; + + default: + $app->setUserState('com_installer.message', Text::_('COM_INSTALLER_NO_INSTALL_TYPE_FOUND')); + + return false; + break; + } + } + + // This event allows a custom installation of the package or a customization of the package: + $results = $app->triggerEvent('onInstallerBeforeInstaller', array($this, &$package)); + + if (in_array(true, $results, true)) + { + return true; + } + + if (in_array(false, $results, true)) + { + if (in_array($installType, array('upload', 'url'))) + { + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + } + + return false; + } + + // Get an installer instance. + $installer = Installer::getInstance(); + + /* + * Check for a Joomla core package. + * To do this we need to set the source path to find the manifest (the same first step as Installer::install()) + * + * This must be done before the unpacked check because InstallerHelper::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'])) + { + $installer->setPath('source', $package['dir']); + + if (!$installer->findManifest()) + { + // If a manifest isn't found at the source, this may be a Joomla package; check the package directory for the Joomla manifest + if (file_exists($package['dir'] . '/administrator/manifests/files/joomla.xml')) + { + // We have a Joomla package + if (in_array($installType, array('upload', 'url'))) + { + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + } + + $app->enqueueMessage( + Text::sprintf('COM_INSTALLER_UNABLE_TO_INSTALL_JOOMLA_PACKAGE', Route::_('index.php?option=com_joomlaupdate')), + 'warning' + ); + + return false; + } + } + } + + // Was the package unpacked? + if (!$package || !$package['type']) + { + if (in_array($installType, array('upload', 'url'))) + { + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + } + + $app->enqueueMessage(Text::_('COM_INSTALLER_UNABLE_TO_FIND_INSTALL_PACKAGE'), 'error'); + + return false; + } + + // Install the package. + if (!$installer->install($package['dir'])) + { + // There was an error installing the package. + $msg = Text::sprintf('COM_INSTALLER_INSTALL_ERROR', Text::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); + $result = false; + $msgType = 'error'; + } + else + { + // Package installed successfully. + $msg = Text::sprintf('COM_INSTALLER_INSTALL_SUCCESS', Text::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); + $result = true; + $msgType = 'message'; + } + + // This event allows a custom a post-flight: + $app->triggerEvent('onInstallerAfterInstaller', array($this, &$package, $installer, &$result, &$msg)); + + // Set some model state values. + $app->enqueueMessage($msg, $msgType); + $this->setState('name', $installer->get('name')); + $this->setState('result', $result); + $app->setUserState('com_installer.message', $installer->message); + $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); + $app->setUserState('com_installer.redirect_url', $installer->get('redirect_url')); + + // Cleanup the install files. + if (!is_file($package['packagefile'])) + { + $config = Factory::getConfig(); + $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; + } + + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + + // Clear the cached extension data and menu cache + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + $this->cleanCache('com_modules', 0); + $this->cleanCache('com_modules', 1); + $this->cleanCache('com_plugins', 0); + $this->cleanCache('com_plugins', 1); + $this->cleanCache('mod_menu', 0); + $this->cleanCache('mod_menu', 1); + + return $result; + } + + /** + * Works out an installation package from a HTTP upload. + * + * @return mixed Package definition or false on failure. + */ + protected function _getPackageFromUpload() + { + // Get the uploaded file information. + $input = Factory::getApplication()->input; + + // Do not change the filter type 'raw'. We need this to let files containing PHP code to upload. See \JInputFiles::get. + $userfile = $input->files->get('install_package', null, 'raw'); + + // Make sure that file uploads are enabled in php. + if (!(bool) ini_get('file_uploads')) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLFILE'), 'error'); + + return false; + } + + // Make sure that zlib is loaded so that the package can be unpacked. + if (!extension_loaded('zlib')) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB'), 'error'); + + return false; + } + + // If there is no uploaded file, we have a problem... + if (!is_array($userfile)) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_INSTALL_NO_FILE_SELECTED'), 'error'); + + return false; + } + + // Is the PHP tmp directory missing? + if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_NO_TMP_DIR)) + { + Factory::getApplication()->enqueueMessage( + Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), + 'error' + ); + + return false; + } + + // Is the max upload size too small in php.ini? + if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_INI_SIZE)) + { + Factory::getApplication()->enqueueMessage( + Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), + 'error' + ); + + return false; + } + + // Check if there was a different problem uploading the file. + if ($userfile['error'] || $userfile['size'] < 1) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR'), 'error'); + + return false; + } + + // Build the appropriate paths. + $config = Factory::getApplication()->getConfig(); + $tmp_dest = $config->get('tmp_path') . '/' . $userfile['name']; + $tmp_src = $userfile['tmp_name']; + + // Move uploaded file. + File::upload($tmp_src, $tmp_dest, false, true); + + // Unpack the downloaded package file. + $package = InstallerHelper::unpack($tmp_dest, true); + + return $package; + } + + /** + * Install an extension from a directory + * + * @return array Package details or false on failure + * + * @since 1.5 + */ + protected function _getPackageFromFolder() + { + $input = Factory::getApplication()->input; + + // Get the path to the package to install. + $p_dir = $input->getString('install_directory'); + $p_dir = Path::clean($p_dir); + + // Did you give us a valid directory? + if (!is_dir($p_dir)) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_INSTALL_PLEASE_ENTER_A_PACKAGE_DIRECTORY'), 'error'); + + return false; + } + + // Detect the package type + $type = InstallerHelper::detectType($p_dir); + + // Did you give us a valid package? + if (!$type) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_INSTALL_PATH_DOES_NOT_HAVE_A_VALID_PACKAGE'), 'error'); + } + + $package['packagefile'] = null; + $package['extractdir'] = null; + $package['dir'] = $p_dir; + $package['type'] = $type; + + return $package; + } + + /** + * Install an extension from a URL. + * + * @return Package details or false on failure. + * + * @since 1.5 + */ + protected function _getPackageFromUrl() + { + $input = Factory::getApplication()->input; + + // Get the URL of the package to install. + $url = $input->getString('install_url'); + + // Did you give us a URL? + if (!$url) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_INSTALL_ENTER_A_URL'), 'error'); + + return false; + } + + // Handle updater XML file case: + if (preg_match('/\.xml\s*$/', $url)) + { + $update = new Update; + $update->loadFromXml($url); + $package_url = trim($update->get('downloadurl', false)->_data); + + if ($package_url) + { + $url = $package_url; + } + + unset($update); + } + + // Download the package at the URL given. + $p_file = InstallerHelper::downloadPackage($url); + + // Was the package downloaded? + if (!$p_file) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_INSTALL_INVALID_URL'), 'error'); + + return false; + } + + $config = Factory::getConfig(); + $tmp_dest = $config->get('tmp_path'); + + // Unpack the downloaded package file. + $package = InstallerHelper::unpack($tmp_dest . '/' . $p_file, true); + + return $package; + } +} diff --git a/administrator/components/com_installer/Model/InstallerModel.php b/administrator/components/com_installer/Model/InstallerModel.php new file mode 100644 index 0000000000000..eeb9c1ab5e02d --- /dev/null +++ b/administrator/components/com_installer/Model/InstallerModel.php @@ -0,0 +1,231 @@ +getState('list.ordering', 'name'); + $listDirn = $this->getState('list.direction', 'asc'); + + // Replace slashes so preg_match will work + $search = $this->getState('filter.search'); + $search = str_replace('/', ' ', $search); + $db = $this->getDbo(); + + // Define which fields have to be processed in a custom way because of translation. + $customOrderFields = array('name', 'client_translated', 'type_translated', 'folder_translated'); + + // Process searching, ordering and pagination for fields that need to be translated. + if (in_array($listOrder, $customOrderFields) || (!empty($search) && stripos($search, 'id:') !== 0)) + { + // Get results from database and translate them. + $db->setQuery($query); + $result = $db->loadObjectList(); + $this->translate($result); + + // Process searching. + if (!empty($search) && stripos($search, 'id:') !== 0) + { + $escapedSearchString = $this->refineSearchStringToRegex($search, '/'); + + // By default search only the extension name field. + $searchFields = array('name'); + + // If in update sites view search also in the update site name field. + if ($this instanceof Updatesites) + { + $searchFields[] = 'update_site_name'; + } + + foreach ($result as $i => $item) + { + // 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})) + { + $found = 1; + } + } + + // If search string was not found in any of the fields searched remove it from results array. + if (!$found) + { + unset($result[$i]); + } + } + } + + // Process ordering. + // Sort array object by selected ordering and selected direction. Sort is case insensative 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) + { + $limitstart = 0; + $this->setState('list.start', 0); + } + + return array_slice($result, $limitstart, $limit ?: null); + } + + // Process searching, ordering and pagination for regular database fields. + $query->order($db->quoteName($listOrder) . ' ' . $db->escape($listDirn)); + $result = parent::_getList($query, $limitstart, $limit); + $this->translate($result); + + return $result; + } + + /** + * Translate a list of objects + * + * @param array &$items The array of objects + * + * @return array The array of translated objects + */ + protected function translate(&$items) + { + $lang = Factory::getLanguage(); + + foreach ($items as &$item) + { + if (strlen($item->manifest_cache) && $data = json_decode($item->manifest_cache)) + { + foreach ($data as $key => $value) + { + if ($key == 'type') + { + // Ignore the type field + continue; + } + + $item->$key = $value; + } + } + + $item->author_info = @$item->authorEmail . '
' . @$item->authorUrl; + $item->client = $item->client_id ? Text::_('JADMINISTRATOR') : Text::_('JSITE'); + $item->client_translated = $item->client; + $item->type_translated = Text::_('COM_INSTALLER_TYPE_' . strtoupper($item->type)); + $item->folder_translated = @$item->folder ? $item->folder : Text::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); + + $path = $item->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE; + + switch ($item->type) + { + case 'component': + $extension = $item->element; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + break; + case 'file': + $extension = 'files_' . $item->element; + $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); + break; + case 'module': + $extension = $item->element; + $source = $path . '/modules/' . $extension; + $lang->load("$extension.sys", $path, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + break; + case 'plugin': + $extension = 'plg_' . $item->folder . '_' . $item->element; + $source = JPATH_PLUGINS . '/' . $item->folder . '/' . $item->element; + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + break; + case 'template': + $extension = 'tpl_' . $item->element; + $source = $path . '/templates/' . $item->element; + $lang->load("$extension.sys", $path, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + break; + case 'package': + default: + $extension = $item->element; + $lang->load("$extension.sys", JPATH_SITE, null, false, true); + break; + } + + // Translate the extension name if possible + $item->name = Text::_($item->name); + + settype($item->description, 'string'); + + if (!in_array($item->type, array('language'))) + { + $item->description = Text::_($item->description); + } + } + } +} diff --git a/administrator/components/com_installer/Model/LanguagesModel.php b/administrator/components/com_installer/Model/LanguagesModel.php new file mode 100644 index 0000000000000..88af12e80bbd1 --- /dev/null +++ b/administrator/components/com_installer/Model/LanguagesModel.php @@ -0,0 +1,265 @@ +getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('us.location')) + ->from($db->quoteName('#__extensions', 'e')) + ->where($db->quoteName('e.type') . ' = ' . $db->quote('package')) + ->where($db->quoteName('e.element') . ' = ' . $db->quote('pkg_en-GB')) + ->where($db->quoteName('e.client_id') . ' = 0') + ->join( + 'LEFT', $db->quoteName('#__update_sites_extensions', 'use') + . ' ON ' . $db->quoteName('use.extension_id') . ' = ' . $db->quoteName('e.extension_id') + ) + ->join( + 'LEFT', $db->quoteName('#__update_sites', 'us') + . ' ON ' . $db->quoteName('us.update_site_id') . ' = ' . $db->quoteName('use.update_site_id') + ); + + return $db->setQuery($query)->loadResult(); + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 3.7.0 + */ + public function getItems() + { + // Get a storage key. + $store = $this->getStoreId(); + + // Try to load the data from internal storage. + if (isset($this->cache[$store])) + { + return $this->cache[$store]; + } + + try + { + // Load the list items and add the items to the internal cache. + $this->cache[$store] = $this->getLanguages(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $this->cache[$store]; + } + + /** + * Gets an array of objects from the updatesite. + * + * @return object[] An array of results. + * + * @since 3.0 + * @throws \RuntimeException + */ + protected function getLanguages() + { + $updateSite = $this->getUpdateSite(); + + try + { + $response = HttpFactory::getHttp()->get($updateSite); + } + catch (\RuntimeException $e) + { + $response = null; + } + + if ($response === null || $response->code !== 200) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_WARNING_NO_LANGUAGES_UPDATESERVER'), 'warning'); + + return; + } + + $updateSiteXML = simplexml_load_string($response->body); + $languages = array(); + $search = strtolower($this->getState('filter.search')); + + foreach ($updateSiteXML->extension as $extension) + { + $language = new \stdClass; + + foreach ($extension->attributes() as $key => $value) + { + $language->$key = (string) $value; + } + + if ($search) + { + if (strpos(strtolower($language->name), $search) === false + && strpos(strtolower($language->element), $search) === false) + { + continue; + } + } + + $languages[$language->name] = $language; + } + + // Workaround for php 5.3 + $that = $this; + + // Sort the array by value of subarray + usort( + $languages, + function($a, $b) use ($that) + { + $ordering = $that->getState('list.ordering'); + + if (strtolower($that->getState('list.direction')) === 'asc') + { + return StringHelper::strcmp($a->$ordering, $b->$ordering); + } + else + { + return StringHelper::strcmp($b->$ordering, $a->$ordering); + } + } + ); + + // Count the non-paginated list + $this->languageCount = count($languages); + $limit = ($this->getState('list.limit') > 0) ? $this->getState('list.limit') : $this->languageCount; + + return array_slice($languages, $this->getStart(), $limit); + } + + /** + * Returns a record count for the updatesite. + * + * @param \JDatabaseQuery|string $query The query. + * + * @return integer Number of rows for query. + * + * @since 3.7.0 + */ + protected function _getListCount($query) + { + return $this->languageCount; + } + + /** + * Method to get a store id based on model configuration state. + * + * @param string $id A prefix for the store id. + * + * @return string A store id. + * + * @since 2.5.7 + */ + 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 list order + * @param string $direction direction in the list + * + * @return void + * + * @since 2.5.7 + */ + protected function populateState($ordering = 'name', $direction = 'asc') + { + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + $this->setState('extension_message', Factory::getApplication()->getUserState('com_installer.extension_message')); + + parent::populateState($ordering, $direction); + } + + /** + * Method to compare two languages in order to sort them. + * + * @param object $lang1 The first language. + * @param object $lang2 The second language. + * + * @return integer + * + * @since 3.7.0 + */ + protected function compareLanguages($lang1, $lang2) + { + return strcmp($lang1->name, $lang2->name); + } +} diff --git a/administrator/components/com_installer/Model/ManageModel.php b/administrator/components/com_installer/Model/ManageModel.php new file mode 100644 index 0000000000000..740ec2a39ff26 --- /dev/null +++ b/administrator/components/com_installer/Model/ManageModel.php @@ -0,0 +1,379 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.status', $this->getUserStateFromRequest($this->context . '.filter.status', 'filter_status', '', 'string')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); + $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); + $this->setState('filter.core', $this->getUserStateFromRequest($this->context . '.filter.core', 'filter_core', '', 'string')); + + $this->setState('message', $app->getUserState('com_installer.message')); + $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + parent::populateState($ordering, $direction); + } + + /** + * Enable/Disable an extension. + * + * @param array &$eid Extension ids to un/publish + * @param int $value Publish value + * + * @return boolean True on success + * + * @since 1.5 + */ + public function publish(&$eid = array(), $value = 1) + { + if (!Factory::getUser()->authorise('core.edit.state', 'com_installer')) + { + Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'error'); + + return false; + } + + $result = true; + + /* + * Ensure eid is an array of extension ids + * TODO: If it isn't an array do we want to set an error and fail? + */ + if (!is_array($eid)) + { + $eid = array($eid); + } + + // Get a table object for the extension type + $table = new \Joomla\CMS\Table\Extension($this->getDbo()); + + // Enable the extension in the table and store it in the database + foreach ($eid as $i => $id) + { + $table->load($id); + + if ($table->type == 'template') + { + $style = new StyleTable($this->getDbo()); + + if ($style->load(array('template' => $table->element, 'client_id' => $table->client_id, 'home' => 1))) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_ERROR_DISABLE_DEFAULT_TEMPLATE_NOT_PERMITTED'), 'notice'); + unset($eid[$i]); + continue; + } + } + + if ($table->protected == 1) + { + $result = false; + Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'error'); + } + else + { + $table->enabled = $value; + } + + if (!$table->store()) + { + $this->setError($table->getError()); + $result = false; + } + } + + // Clear the cached extension data and menu cache + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + $this->cleanCache('com_modules', 0); + $this->cleanCache('com_modules', 1); + $this->cleanCache('mod_menu', 0); + $this->cleanCache('mod_menu', 1); + + return $result; + } + + /** + * Refreshes the cached manifest information for an extension. + * + * @param int $eid extension identifier (key in #__extensions) + * + * @return boolean result of refresh + * + * @since 1.6 + */ + public function refresh($eid) + { + if (!is_array($eid)) + { + $eid = array($eid => 0); + } + + // Get an installer object for the extension type + $installer = Installer::getInstance(); + $result = 0; + + // Uninstall the chosen extensions + foreach ($eid as $id) + { + $result |= $installer->refreshManifestCache($id); + } + + return $result; + } + + /** + * Remove (uninstall) an extension + * + * @param array $eid An array of identifiers + * + * @return boolean True on success + * + * @since 1.5 + */ + public function remove($eid = array()) + { + if (!Factory::getUser()->authorise('core.delete', 'com_installer')) + { + Factory::getApplication()->enqueueMessage(Text::_('JERROR_CORE_DELETE_NOT_PERMITTED'), 'error'); + + return false; + } + + /* + * Ensure eid is an array of extension ids in the form id => client_id + * TODO: If it isn't an array do we want to set an error and fail? + */ + if (!is_array($eid)) + { + $eid = array($eid => 0); + } + + // Get an installer object for the extension type + $installer = Installer::getInstance(); + $row = new \Joomla\CMS\Table\Extension($this->getDbo()); + + // Uninstall the chosen extensions + $msgs = array(); + $result = false; + + foreach ($eid as $id) + { + $id = trim($id); + $row->load($id); + $result = false; + + $langstring = 'COM_INSTALLER_TYPE_TYPE_' . strtoupper($row->type); + $rowtype = Text::_($langstring); + + if (strpos($rowtype, $langstring) !== false) + { + $rowtype = $row->type; + } + + if ($row->type) + { + $result = $installer->uninstall($row->type, $id); + + // Build an array of extensions that failed to uninstall + if ($result === false) + { + // There was an error in uninstalling the package + $msgs[] = Text::sprintf('COM_INSTALLER_UNINSTALL_ERROR', $rowtype); + + continue; + } + + // Package uninstalled successfully + $msgs[] = Text::sprintf('COM_INSTALLER_UNINSTALL_SUCCESS', $rowtype); + $result = true; + + continue; + } + + // There was an error in uninstalling the package + $msgs[] = Text::sprintf('COM_INSTALLER_UNINSTALL_ERROR', $rowtype); + } + + $msg = implode('
', $msgs); + $app = Factory::getApplication(); + $app->enqueueMessage($msg); + $this->setState('action', 'remove'); + $this->setState('name', $installer->get('name')); + $app->setUserState('com_installer.message', $installer->message); + $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); + + // Clear the cached extension data and menu cache + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + $this->cleanCache('com_modules', 0); + $this->cleanCache('com_modules', 1); + $this->cleanCache('com_plugins', 0); + $this->cleanCache('com_plugins', 1); + $this->cleanCache('mod_menu', 0); + $this->cleanCache('mod_menu', 1); + + return $result; + } + + /** + * Method to get the database query + * + * @return DatabaseQuery The database query + * + * @since 1.6 + */ + protected function getListQuery() + { + $query = $this->getDbo()->getQuery(true) + ->select('*') + ->select('2*protected+(1-protected)*enabled AS status') + ->from('#__extensions') + ->where('state = 0'); + + // Process select filters. + $status = $this->getState('filter.status'); + $type = $this->getState('filter.type'); + $clientId = $this->getState('filter.client_id'); + $folder = $this->getState('filter.folder'); + $core = $this->getState('filter.core'); + + if ($status !== '') + { + if ($status === '2') + { + $query->where('protected = 1'); + } + elseif ($status === '3') + { + $query->where('protected = 0'); + } + else + { + $query->where('protected = 0') + ->where('enabled = ' . (int) $status); + } + } + + if ($type) + { + $query->where('type = ' . $this->_db->quote($type)); + } + + if ($clientId !== '') + { + $query->where('client_id = ' . (int) $clientId); + } + + if ($folder !== '') + { + $query->where('folder = ' . $this->_db->quote($folder == '*' ? '' : $folder)); + } + + if ($core !== '') + { + $coreExtensions = ExtensionHelper::getCoreExtensions(); + $elements = array(); + + foreach ($coreExtensions as $extension) + { + $elements[] = $this->getDbo()->quote($extension[1]); + } + + if ($elements) + { + if ($core === '1') + { + $query->where($this->getDbo()->quoteName('element') . ' IN (' . implode(',', $elements) . ')'); + } + elseif ($core === '0') + { + $query->where($this->getDbo()->quoteName('element') . ' NOT IN (' . implode(',', $elements) . ')'); + } + } + } + + // Process search filter (extension id). + $search = $this->getState('filter.search'); + + if (!empty($search) && stripos($search, 'id:') === 0) + { + $query->where('extension_id = ' . (int) substr($search, 3)); + } + + // Note: The search for name, ordering and pagination are processed by the parent InstallerModel class (in extension.php). + + return $query; + } +} diff --git a/administrator/components/com_installer/Model/UpdateModel.php b/administrator/components/com_installer/Model/UpdateModel.php new file mode 100644 index 0000000000000..2f3f5c40ab91c --- /dev/null +++ b/administrator/components/com_installer/Model/UpdateModel.php @@ -0,0 +1,607 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); + $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); + + $app = Factory::getApplication(); + $this->setState('message', $app->getUserState('com_installer.message')); + $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + parent::populateState($ordering, $direction); + } + + /** + * Method to get the database query + * + * @return \JDatabaseQuery The database query + * + * @since 1.6 + */ + protected function getListQuery() + { + $db = $this->getDbo(); + + // Grab updates ignoring new installs + $query = $db->getQuery(true) + ->select('u.*') + ->select($db->quoteName('e.manifest_cache')) + ->from($db->quoteName('#__updates', 'u')) + ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON ' . $db->quoteName('e.extension_id') . ' = ' . $db->quoteName('u.extension_id')) + ->where($db->quoteName('u.extension_id') . ' != ' . $db->quote(0)); + + // Process select filters. + $clientId = $this->getState('filter.client_id'); + $type = $this->getState('filter.type'); + $folder = $this->getState('filter.folder'); + $extensionId = $this->getState('filter.extension_id'); + + if ($type) + { + $query->where($db->quoteName('u.type') . ' = ' . $db->quote($type)); + } + + if ($clientId != '') + { + $query->where($db->quoteName('u.client_id') . ' = ' . (int) $clientId); + } + + if ($folder != '' && in_array($type, array('plugin', 'library', ''))) + { + $query->where($db->quoteName('u.folder') . ' = ' . $db->quote($folder == '*' ? '' : $folder)); + } + + if ($extensionId) + { + $query->where($db->quoteName('u.extension_id') . ' = ' . $db->quote((int) $extensionId)); + } + else + { + $query->where($db->quoteName('u.extension_id') . ' != ' . $db->quote(0)) + ->where($db->quoteName('u.extension_id') . ' != ' . $db->quote(700)); + } + + // Process search filter. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'eid:') !== false) + { + $query->where($db->quoteName('u.extension_id') . ' = ' . (int) substr($search, 4)); + } + else + { + if (stripos($search, 'uid:') !== false) + { + $query->where($db->quoteName('u.update_site_id') . ' = ' . (int) substr($search, 4)); + } + elseif (stripos($search, 'id:') !== false) + { + $query->where($db->quoteName('u.update_id') . ' = ' . (int) substr($search, 3)); + } + else + { + $query->where($db->quoteName('u.name') . ' LIKE ' . $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true)) . '%')); + } + } + } + + return $query; + } + + /** + * Translate a list of objects + * + * @param array &$items The array of objects + * + * @return array The array of translated objects + * + * @since 3.5 + */ + protected function translate(&$items) + { + foreach ($items as &$item) + { + $item->client_translated = $item->client_id ? Text::_('JADMINISTRATOR') : Text::_('JSITE'); + $manifest = json_decode($item->manifest_cache); + $item->current_version = $manifest->version ?? Text::_('JLIB_UNKNOWN'); + $item->type_translated = Text::_('COM_INSTALLER_TYPE_' . strtoupper($item->type)); + $item->folder_translated = $item->folder ?: Text::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); + $item->install_type = $item->extension_id ? Text::_('COM_INSTALLER_MSG_UPDATE_UPDATE') : Text::_('COM_INSTALLER_NEW_INSTALL'); + } + + return $items; + } + + /** + * Returns an object list + * + * @param \JDatabaseQuery $query The query + * @param int $limitstart Offset + * @param int $limit The number of records + * + * @return array + * + * @since 3.5 + */ + protected function _getList($query, $limitstart = 0, $limit = 0) + { + $db = $this->getDbo(); + $listOrder = $this->getState('list.ordering', 'u.name'); + $listDirn = $this->getState('list.direction', 'asc'); + + // Process ordering. + if (in_array($listOrder, array('client_translated', 'folder_translated', 'type_translated'))) + { + $db->setQuery($query); + $result = $db->loadObjectList(); + $this->translate($result); + $result = ArrayHelper::sortObjects($result, $listOrder, strtolower($listDirn) === 'desc' ? -1 : 1, true, true); + $total = count($result); + + if ($total < $limitstart) + { + $limitstart = 0; + $this->setState('list.start', 0); + } + + return array_slice($result, $limitstart, $limit ?: null); + } + else + { + $query->order($db->quoteName($listOrder) . ' ' . $db->escape($listDirn)); + + $result = parent::_getList($query, $limitstart, $limit); + $this->translate($result); + + return $result; + } + } + + /** + * Get the count of disabled update sites + * + * @return integer + * + * @since 3.4 + */ + public function getDisabledUpdateSites() + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__update_sites')) + ->where($db->quoteName('enabled') . ' = 0'); + + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * 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 Updater} (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 = Updater::STABILITY_STABLE) + { + // Purge the updates list + $this->purge(); + + Updater::getInstance()->findUpdates($eid, $cache_timeout, $minimum_stability); + + return true; + } + + /** + * Removes all of the updates from the table. + * + * @return boolean result of operation + * + * @since 1.6 + */ + public function purge() + { + $db = $this->getDbo(); + + try + { + $db->truncateTable('#__updates'); + } + catch (ExecutionFailureException $e) + { + $this->_message = Text::_('JLIB_INSTALLER_FAILED_TO_PURGE_UPDATES'); + + return false; + } + + // Reset the last update check timestamp + $query = $db->getQuery(true) + ->update($db->quoteName('#__update_sites')) + ->set($db->quoteName('last_check_timestamp') . ' = ' . $db->quote(0)); + $db->setQuery($query); + $db->execute(); + $this->_message = Text::_('JLIB_INSTALLER_PURGED_UPDATES'); + + return true; + } + + /** + * Enables any disabled rows in #__update_sites table + * + * @return boolean result of operation + * + * @since 1.6 + */ + public function enableSites() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->update($db->quoteName('#__update_sites')) + ->set($db->quoteName('enabled') . ' = 1') + ->where($db->quoteName('enabled') . ' = 0'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (ExecutionFailureException $e) + { + $this->_message .= Text::_('COM_INSTALLER_FAILED_TO_ENABLE_UPDATES'); + + return false; + } + + if ($rows = $db->getAffectedRows()) + { + $this->_message .= Text::plural('COM_INSTALLER_ENABLED_UPDATES', $rows); + } + + return true; + } + + /** + * Update function. + * + * 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 Updater} + * + * @return void + * + * @since 1.6 + */ + public function update($uids, $minimum_stability = Updater::STABILITY_STABLE) + { + $result = true; + + foreach ($uids as $uid) + { + $update = new Update; + $instance = new \Joomla\CMS\Table\Update($this->getDbo()); + $instance->load($uid); + $update->loadFromXml($instance->detailsurl, $minimum_stability); + $update->set('extra_query', $instance->extra_query); + + $this->preparePreUpdate($update, $instance); + + // Install sets state and enqueues messages + $res = $this->install($update); + + if ($res) + { + $instance->delete($uid); + } + + $result = $res & $result; + } + + // Clear the cached extension data and menu cache + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + $this->cleanCache('com_modules', 0); + $this->cleanCache('com_modules', 1); + $this->cleanCache('com_plugins', 0); + $this->cleanCache('com_plugins', 1); + $this->cleanCache('mod_menu', 0); + $this->cleanCache('mod_menu', 1); + + // Set the final state + $this->setState('result', $result); + } + + /** + * Handles the actual update installation. + * + * @param Update $update An update definition + * + * @return boolean Result of install + * + * @since 1.6 + */ + private function install($update) + { + $app = Factory::getApplication(); + + if (!isset($update->get('downloadurl')->_data)) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_INVALID_EXTENSION_UPDATE'), 'error'); + + return false; + } + + $url = $update->downloadurl->_data; + $sources = $update->get('downloadSources', array()); + + if ($extra_query = $update->get('extra_query')) + { + $url .= (strpos($url, '?') === false) ? '?' : '&'; + $url .= $extra_query; + } + + $mirror = 0; + + while (!($p_file = InstallerHelper::downloadPackage($url)) && isset($sources[$mirror])) + { + $name = $sources[$mirror]; + $url = $name->url; + + if ($extra_query) + { + $url .= (strpos($url, '?') === false) ? '?' : '&'; + $url .= $extra_query; + } + + $mirror++; + } + + // Was the package downloaded? + if (!$p_file) + { + Factory::getApplication()->enqueueMessage(Text::sprintf('COM_INSTALLER_PACKAGE_DOWNLOAD_FAILED', $url), 'error'); + + return false; + } + + $config = $app->getConfig(); + $tmp_dest = $config->get('tmp_path'); + + // Unpack the downloaded package file + $package = InstallerHelper::unpack($tmp_dest . '/' . $p_file); + + // Get an installer instance + $installer = Installer::getInstance(); + $update->set('type', $package['type']); + + // Install the package + if (!$installer->update($package['dir'])) + { + // There was an error updating the package + $msg = Text::sprintf('COM_INSTALLER_MSG_UPDATE_ERROR', Text::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); + $result = false; + } + else + { + // Package updated successfully + $msg = Text::sprintf('COM_INSTALLER_MSG_UPDATE_SUCCESS', Text::_('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); + $app->setUserState('com_installer.message', $installer->message); + $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); + + // Cleanup the install files + if (!is_file($package['packagefile'])) + { + $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; + } + + InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); + + return $result; + } + + /** + * Method to get the row form. + * + * @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 mixed A \JForm object on success, false on failure + * + * @since 2.5.2 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + \JForm::addFormPath(JPATH_COMPONENT . '/models/forms'); + \JForm::addFieldPath(JPATH_COMPONENT . '/models/fields'); + $form = \JForm::getInstance('com_installer.update', 'update', array('load_data' => $loadData)); + + // Check for an error. + if ($form == false) + { + $this->setError($form->getMessage()); + + return false; + } + + // Check the session for previously entered form data. + $data = $this->loadFormData(); + + // Bind the form data if present. + if (!empty($data)) + { + $form->bind($data); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 2.5.2 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState($this->context, array()); + + return $data; + } + + /** + * Method to add parameters to the update + * + * @param Update $update An update definition + * @param \Joomla\CMS\Table\Update $table The update instance from the database + * + * @return void + * + * @since 3.7.0 + */ + protected function preparePreUpdate($update, $table) + { + switch ($table->type) + { + // Components could have a helper which adds additional data + case 'component': + $ename = str_replace('com_', '', $table->element); + $fname = $ename . '.php'; + $cname = ucfirst($ename) . 'Helper'; + + $path = JPATH_ADMINISTRATOR . '/components/' . $table->element . '/helpers/' . $fname; + + if (File::exists($path)) + { + require_once $path; + + if (class_exists($cname) && is_callable(array($cname, 'prepareUpdate'))) + { + call_user_func_array(array($cname, 'prepareUpdate'), array(&$update, &$table)); + } + } + + break; + + // Modules could have a helper which adds additional data + case 'module': + $cname = str_replace('_', '', $table->element) . 'Helper'; + $path = ($table->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/modules/' . $table->element . '/helper.php'; + + if (File::exists($path)) + { + require_once $path; + + if (class_exists($cname) && is_callable(array($cname, 'prepareUpdate'))) + { + call_user_func_array(array($cname, 'prepareUpdate'), array(&$update, &$table)); + } + } + + break; + + // If we have a plugin, we can use the plugin trigger "onInstallerBeforePackageDownload" + // But we should make sure, that our plugin is loaded, so we don't need a second "installer" plugin + case 'plugin': + $cname = str_replace('plg_', '', $table->element); + PluginHelper::importPlugin($table->folder, $cname); + break; + } + } +} diff --git a/administrator/components/com_installer/Model/UpdatesitesModel.php b/administrator/components/com_installer/Model/UpdatesitesModel.php new file mode 100644 index 0000000000000..c3a0b4adfe27a --- /dev/null +++ b/administrator/components/com_installer/Model/UpdatesitesModel.php @@ -0,0 +1,485 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); + $this->setState('filter.enabled', $this->getUserStateFromRequest($this->context . '.filter.enabled', 'filter_enabled', '', 'string')); + $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); + $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); + + parent::populateState($ordering, $direction); + } + + /** + * Enable/Disable an extension. + * + * @param array &$eid Extension ids to un/publish + * @param int $value Publish value + * + * @return boolean True on success + * + * @since 3.4 + * + * @throws \Exception on ACL error + */ + public function publish(&$eid = array(), $value = 1) + { + if (!Factory::getUser()->authorise('core.edit.state', 'com_installer')) + { + throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 403); + } + + $result = true; + + // Ensure eid is an array of extension ids + if (!is_array($eid)) + { + $eid = array($eid); + } + + // Get a table object for the extension type + $table = new \Joomla\CMS\Table\UpdateSite($this->getDbo()); + + // Enable the update site in the table and store it in the database + foreach ($eid as $i => $id) + { + $table->load($id); + $table->enabled = $value; + + if (!$table->store()) + { + $this->setError($table->getError()); + $result = false; + } + } + + return $result; + } + + /** + * Deletes an update site. + * + * @param array $ids Extension ids to delete. + * + * @return void + * + * @since 3.6 + * + * @throws \Exception on ACL error + */ + public function delete($ids = array()) + { + if (!Factory::getUser()->authorise('core.delete', 'com_installer')) + { + throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 403); + } + + // Ensure eid is an array of extension ids + if (!is_array($ids)) + { + $ids = array($ids); + } + + $db = $this->getDbo(); + $app = Factory::getApplication(); + + $count = 0; + + // Gets the update site names. + $query = $db->getQuery(true) + ->select($db->quoteName(array('update_site_id', 'name'))) + ->from($db->quoteName('#__update_sites')) + ->where($db->quoteName('update_site_id') . ' IN (' . implode(', ', $ids) . ')'); + $db->setQuery($query); + $updateSitesNames = $db->loadObjectList('update_site_id'); + + // Gets Joomla core update sites Ids. + $joomlaUpdateSitesIds = $this->getJoomlaUpdateSitesIds(0); + + // Enable the update site in the table and store it in the database + foreach ($ids as $i => $id) + { + // Don't allow to delete Joomla Core update sites. + if (in_array((int) $id, $joomlaUpdateSitesIds)) + { + $app->enqueueMessage(Text::sprintf('COM_INSTALLER_MSG_UPDATESITES_DELETE_CANNOT_DELETE', $updateSitesNames[$id]->name), 'error'); + continue; + } + + // Delete the update site from all tables. + try + { + $query = $db->getQuery(true) + ->delete($db->quoteName('#__update_sites')) + ->where($db->quoteName('update_site_id') . ' = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + $query = $db->getQuery(true) + ->delete($db->quoteName('#__update_sites_extensions')) + ->where($db->quoteName('update_site_id') . ' = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + $query = $db->getQuery(true) + ->delete($db->quoteName('#__updates')) + ->where($db->quoteName('update_site_id') . ' = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + $count++; + } + catch (\RuntimeException $e) + { + $app->enqueueMessage(Text::sprintf('COM_INSTALLER_MSG_UPDATESITES_DELETE_ERROR', $updateSitesNames[$id]->name, $e->getMessage()), 'error'); + } + } + + if ($count > 0) + { + $app->enqueueMessage(Text::plural('COM_INSTALLER_MSG_UPDATESITES_N_DELETE_UPDATESITES_DELETED', $count), 'message'); + } + } + + /** + * Rebuild update sites tables. + * + * @return void + * + * @since 3.6 + * + * @throws \Exception on ACL error + */ + public function rebuild() + { + if (!Factory::getUser()->authorise('core.admin', 'com_installer')) + { + throw new \Exception(Text::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_NOT_PERMITTED'), 403); + } + + $db = $this->getDbo(); + $app = Factory::getApplication(); + + // Check if Joomla Extension plugin is enabled. + if (!PluginHelper::isEnabled('extension', 'joomla')) + { + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) + ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')) + ->where($db->quoteName('folder') . ' = ' . $db->quote('extension')); + $db->setQuery($query); + + $pluginId = (int) $db->loadResult(); + + $link = Route::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . $pluginId); + $app->enqueueMessage(Text::sprintf('COM_INSTALLER_MSG_UPDATESITES_REBUILD_EXTENSION_PLUGIN_NOT_ENABLED', $link), 'error'); + + return; + } + + $clients = array(JPATH_SITE, JPATH_ADMINISTRATOR); + $extensionGroupFolders = array('components', 'modules', 'plugins', 'templates', 'language', 'manifests'); + + $pathsToSearch = array(); + + // Identifies which folders to search for manifest files. + foreach ($clients as $clientPath) + { + foreach ($extensionGroupFolders as $extensionGroupFolderName) + { + // Components, modules, plugins, templates, languages and manifest (files, libraries, etc) + if ($extensionGroupFolderName != 'plugins') + { + foreach (glob($clientPath . '/' . $extensionGroupFolderName . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $extensionFolderPath) + { + $pathsToSearch[] = $extensionFolderPath; + } + } + + // Plugins (another directory level is needed) + else + { + foreach (glob($clientPath . '/' . $extensionGroupFolderName . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $pluginGroupFolderPath) + { + foreach (glob($pluginGroupFolderPath . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $extensionFolderPath) + { + $pathsToSearch[] = $extensionFolderPath; + } + } + } + } + } + + // Gets Joomla core update sites Ids. + $joomlaUpdateSitesIds = implode(', ', $this->getJoomlaUpdateSitesIds(0)); + + // Delete from all tables (except joomla core update sites). + $query = $db->getQuery(true) + ->delete($db->quoteName('#__update_sites')) + ->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); + $db->setQuery($query); + $db->execute(); + + $query = $db->getQuery(true) + ->delete($db->quoteName('#__update_sites_extensions')) + ->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); + $db->setQuery($query); + $db->execute(); + + $query = $db->getQuery(true) + ->delete($db->quoteName('#__updates')) + ->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); + $db->setQuery($query); + $db->execute(); + + $count = 0; + + // Gets Joomla core extension Ids. + $joomlaCoreExtensionIds = implode(', ', $this->getJoomlaUpdateSitesIds(1)); + + // Search for updateservers in manifest files inside the folders to search. + foreach ($pathsToSearch as $extensionFolderPath) + { + $tmpInstaller = new Installer; + + $tmpInstaller->setPath('source', $extensionFolderPath); + + // Main folder manifests (higher priority) + $parentXmlfiles = Folder::files($tmpInstaller->getPath('source'), '.xml$', false, true); + + // Search for children manifests (lower priority) + $allXmlFiles = Folder::files($tmpInstaller->getPath('source'), '.xml$', 1, true); + + // Create an unique array of files ordered by priority + $xmlfiles = array_unique(array_merge($parentXmlfiles, $allXmlFiles)); + + if (!empty($xmlfiles)) + { + foreach ($xmlfiles as $file) + { + // Is it a valid Joomla installation manifest file? + $manifest = $tmpInstaller->isManifest($file); + + if (!is_null($manifest)) + { + // Search if the extension exists in the extensions table. Excluding joomla core extensions (id < 10000) and discovered 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('type') . ' = ' . $db->quote($manifest['type'])) + ->where($db->quoteName('extension_id') . ' NOT IN (' . $joomlaCoreExtensionIds . ')') + ->where($db->quoteName('state') . ' != -1'); + $db->setQuery($query); + + $eid = (int) $db->loadResult(); + + if ($eid && $manifest->updateservers) + { + // Set the manifest object and path + $tmpInstaller->manifest = $manifest; + $tmpInstaller->setPath('manifest', $file); + + // Load the extension plugin (if not loaded yet). + PluginHelper::importPlugin('extension', 'joomla'); + + // Fire the onExtensionAfterUpdate + $app->triggerEvent('onExtensionAfterUpdate', array('installer' => $tmpInstaller, 'eid' => $eid)); + + $count++; + } + } + } + } + } + + if ($count > 0) + { + $app->enqueueMessage(Text::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_SUCCESS'), 'message'); + } + else + { + $app->enqueueMessage(Text::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_MESSAGE'), 'message'); + } + } + + /** + * Fetch the Joomla update sites ids. + * + * @param integer $column Column to return. 0 for update site ids, 1 for extension ids. + * + * @return array Array with joomla core update site ids. + * + * @since 3.6.0 + */ + protected function getJoomlaUpdateSitesIds($column = 0) + { + $db = $this->getDbo(); + + // Fetch the Joomla core update sites ids and their extension ids. We search for all except the core joomla extension with update sites. + $query = $db->getQuery(true) + ->select($db->quoteName(array('use.update_site_id', 'e.extension_id'))) + ->from($db->quoteName('#__update_sites_extensions', 'use')) + ->join( + 'LEFT', $db->quoteName('#__update_sites', 'us') + . ' ON ' . $db->quoteName('us.update_site_id') . ' = ' . $db->quoteName('use.update_site_id') + ) + ->join( + 'LEFT', $db->quoteName('#__extensions', 'e') + . ' ON ' . $db->quoteName('e.extension_id') . ' = ' . $db->quoteName('use.extension_id') + ) + ->where('(' + . '(' . $db->quoteName('e.type') . ' = ' . $db->quote('file') . ' AND ' . $db->quoteName('e.element') . ' = ' . $db->quote('joomla') . ')' + . ' OR (' . $db->quoteName('e.type') . ' = ' . $db->quote('package') . ' AND ' . $db->quoteName('e.element') + . ' = ' . $db->quote('pkg_en-GB') . ')' . ' OR (' . $db->quoteName('e.type') . ' = ' . $db->quote('component') + . ' AND ' . $db->quoteName('e.element') . ' = ' . $db->quote('com_joomlaupdate') . ')' + . ')' + ); + + $db->setQuery($query); + + return $db->loadColumn($column); + } + + /** + * Method to get the database query + * + * @return \JDatabaseQuery The database query + * + * @since 3.4 + */ + protected function getListQuery() + { + $query = $this->getDbo()->getQuery(true) + ->select( + array( + 's.update_site_id', + 's.name AS update_site_name', + 's.type AS update_site_type', + 's.location', + 's.enabled', + 'e.extension_id', + 'e.name', + 'e.type', + 'e.element', + 'e.folder', + 'e.client_id', + 'e.state', + 'e.manifest_cache', + ) + ) + ->from('#__update_sites AS s') + ->innerJoin('#__update_sites_extensions AS se ON (se.update_site_id = s.update_site_id)') + ->innerJoin('#__extensions AS e ON (e.extension_id = se.extension_id)') + ->where('state = 0'); + + // Process select filters. + $enabled = $this->getState('filter.enabled'); + $type = $this->getState('filter.type'); + $clientId = $this->getState('filter.client_id'); + $folder = $this->getState('filter.folder'); + + if ($enabled != '') + { + $query->where('s.enabled = ' . (int) $enabled); + } + + if ($type) + { + $query->where('e.type = ' . $this->_db->quote($type)); + } + + if ($clientId != '') + { + $query->where('e.client_id = ' . (int) $clientId); + } + + if ($folder != '' && in_array($type, array('plugin', 'library', ''))) + { + $query->where('e.folder = ' . $this->_db->quote($folder == '*' ? '' : $folder)); + } + + // Process search filter (update site id). + $search = $this->getState('filter.search'); + + if (!empty($search) && stripos($search, 'id:') === 0) + { + $query->where('s.update_site_id = ' . (int) substr($search, 3)); + } + + // Note: The search for name, ordering and pagination are processed by the parent InstallerModel class (in extension.php). + + return $query; + } +} diff --git a/administrator/components/com_installer/Model/WarningsModel.php b/administrator/components/com_installer/Model/WarningsModel.php new file mode 100644 index 0000000000000..6c831bbe430c1 --- /dev/null +++ b/administrator/components/com_installer/Model/WarningsModel.php @@ -0,0 +1,175 @@ + Text::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADSDISABLED'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADISDISABLEDDESC')); + } + + $upload_dir = ini_get('upload_tmp_dir'); + + if (!$upload_dir) + { + $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSETDESC')); + } + else + { + if (!is_writable($upload_dir)) + { + $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLE'), + 'description' => Text::sprintf('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLEDESC', $upload_dir)); + } + } + + $config = Factory::getConfig(); + $tmp_path = $config->get('tmp_path'); + + if (!$tmp_path) + { + $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSET'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSETDESC')); + } + else + { + if (!is_writable($tmp_path)) + { + $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLE'), + 'description' => Text::sprintf('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLEDESC', $tmp_path)); + } + } + + $memory_limit = $this->return_bytes(ini_get('memory_limit')); + + if ($memory_limit < (8 * 1024 * 1024) && $memory_limit != -1) + { + // 8MB + $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYWARN'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYDESC')); + } + elseif ($memory_limit < (16 * 1024 * 1024) && $memory_limit != -1) + { + // 16MB + $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYWARN'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYDESC')); + } + + $post_max_size = $this->return_bytes(ini_get('post_max_size')); + $upload_max_filesize = $this->return_bytes(ini_get('upload_max_filesize')); + + if ($post_max_size < $upload_max_filesize) + { + $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOST'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOSTDESC')); + } + + if ($post_max_size < (8 * 1024 * 1024)) // 8MB + { + $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZE'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZEDESC')); + } + + if ($upload_max_filesize < (8 * 1024 * 1024)) // 8MB + { + $messages[] = array('message' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), + 'description' => Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZEDESC')); + } + + return $messages; + } +} diff --git a/administrator/components/com_installer/View/Database/HtmlView.php b/administrator/components/com_installer/View/Database/HtmlView.php new file mode 100644 index 0000000000000..4feb61e748dc4 --- /dev/null +++ b/administrator/components/com_installer/View/Database/HtmlView.php @@ -0,0 +1,130 @@ +getModel(); + + try + { + $this->changeSet = $model->getItems(); + } + catch (\Exception $exception) + { + $app->enqueueMessage($exception->getMessage(), 'error'); + } + + $this->errorCount = $model->getErrorCount(); + $this->pagination = $model->getPagination(); + $this->filterForm = $model->getFilterForm(); + $this->activeFilters = $model->getActiveFilters(); + + if ($this->changeSet) + { + ($this->errorCount === 0) + ? $app->enqueueMessage(Text::_('COM_INSTALLER_MSG_DATABASE_CORE_OK'), 'info') + : $app->enqueueMessage(Text::_('COM_INSTALLER_MSG_DATABASE_CORE_ERRORS'), 'warning'); + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + /* + * Set toolbar items for the page. + */ + ToolbarHelper::custom('database.fix', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_DATABASE_FIX', true); + ToolbarHelper::divider(); + parent::addToolbar(); + ToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_DATABASE'); + } +} diff --git a/administrator/components/com_installer/View/Discover/HtmlView.php b/administrator/components/com_installer/View/Discover/HtmlView.php new file mode 100644 index 0000000000000..2ce618f393d31 --- /dev/null +++ b/administrator/components/com_installer/View/Discover/HtmlView.php @@ -0,0 +1,101 @@ +checkExtensions()) + { + $this->getModel('discover')->discover(); + } + + // Get data from the model. + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.1 + */ + protected function addToolbar() + { + /* + * Set toolbar items for the page. + */ + ToolbarHelper::custom('discover.install', 'upload', 'upload', 'JTOOLBAR_INSTALL', true); + ToolbarHelper::custom('discover.refresh', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_DISCOVER', false); + ToolbarHelper::divider(); + + \JHtmlSidebar::setAction('index.php?option=com_installer&view=discover'); + + parent::addToolbar(); + + ToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_DISCOVER'); + } + + /** + * Check extensions. + * + * Checks uninstalled extensions in extensions table. + * + * @return boolean True if there are discovered extensions on the database. + * + * @since 3.5 + */ + public function checkExtensions() + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('state') . ' = -1'); + $db->setQuery($query); + $discoveredExtensions = $db->loadObjectList(); + + return (count($discoveredExtensions) === 0) ? false : true; + } +} diff --git a/administrator/components/com_installer/View/Install/HtmlView.php b/administrator/components/com_installer/View/Install/HtmlView.php new file mode 100644 index 0000000000000..6411d4acb8416 --- /dev/null +++ b/administrator/components/com_installer/View/Install/HtmlView.php @@ -0,0 +1,60 @@ +first = ''; + + $this->paths = &$paths; + + PluginHelper::importPlugin('installer'); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + parent::addToolbar(); + + ToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_INSTALL'); + } +} diff --git a/administrator/components/com_installer/View/Installer/HtmlView.php b/administrator/components/com_installer/View/Installer/HtmlView.php new file mode 100644 index 0000000000000..c6174c7d44ce3 --- /dev/null +++ b/administrator/components/com_installer/View/Installer/HtmlView.php @@ -0,0 +1,118 @@ +_addPath('template', $this->_basePath . '/tmpl/installer'); + $this->_addPath('template', JPATH_THEMES . '/' . Factory::getApplication()->getTemplate() . '/html/com_installer/installer'); + } + + /** + * Display the view. + * + * @param string $tpl Template + * + * @return void + * + * @since 1.5 + */ + public function display($tpl = null) + { + // Get data from the model. + $state = $this->get('State'); + + // Are there messages to display? + $showMessage = false; + + if (is_object($state)) + { + $message1 = $state->get('message'); + $message2 = $state->get('extension_message'); + $showMessage = ($message1 || $message2); + } + + $this->showMessage = $showMessage; + $this->state = &$state; + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_installer'); + ToolbarHelper::title(Text::_('COM_INSTALLER_HEADER_' . strtoupper($this->getName())), 'puzzle install'); + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_installer'); + ToolbarHelper::divider(); + } + + // Render side bar. + $this->sidebar = \JHtmlSidebar::render(); + } +} diff --git a/administrator/components/com_installer/View/Languages/HtmlView.php b/administrator/components/com_installer/View/Languages/HtmlView.php new file mode 100644 index 0000000000000..b25f7af1795e0 --- /dev/null +++ b/administrator/components/com_installer/View/Languages/HtmlView.php @@ -0,0 +1,80 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->installedLang = LanguageHelper::getInstalledLanguages(); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_installer'); + ToolbarHelper::title(Text::_('COM_INSTALLER_HEADER_' . $this->getName()), 'puzzle install'); + + if ($canDo->get('core.admin')) + { + parent::addToolbar(); + + // TODO: this help screen will need to be created. + ToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_LANGUAGES'); + } + } +} diff --git a/administrator/components/com_installer/View/Manage/HtmlView.php b/administrator/components/com_installer/View/Manage/HtmlView.php new file mode 100644 index 0000000000000..711e89544d8a4 --- /dev/null +++ b/administrator/components/com_installer/View/Manage/HtmlView.php @@ -0,0 +1,94 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Include the component HTML helpers. + HTMLHelper::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Display the view. + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_installer'); + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publish('manage.publish', 'JTOOLBAR_ENABLE', true); + ToolbarHelper::unpublish('manage.unpublish', 'JTOOLBAR_DISABLE', true); + ToolbarHelper::divider(); + } + + ToolbarHelper::custom('manage.refresh', 'refresh', 'refresh', 'JTOOLBAR_REFRESH_CACHE', true); + ToolbarHelper::divider(); + + if ($canDo->get('core.delete')) + { + ToolbarHelper::deleteList('COM_INSTALLER_CONFIRM_UNINSTALL', 'manage.remove', 'JTOOLBAR_UNINSTALL'); + ToolbarHelper::divider(); + } + + \JHtmlSidebar::setAction('index.php?option=com_installer&view=manage'); + + parent::addToolbar(); + ToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_MANAGE'); + } +} diff --git a/administrator/components/com_installer/View/Update/HtmlView.php b/administrator/components/com_installer/View/Update/HtmlView.php new file mode 100644 index 0000000000000..4b5e590be0266 --- /dev/null +++ b/administrator/components/com_installer/View/Update/HtmlView.php @@ -0,0 +1,89 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + $paths = new \stdClass; + $paths->first = ''; + + $this->paths = &$paths; + + if (count($this->items) > 0) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_INSTALLER_MSG_WARNINGS_UPDATE_NOTICE'), 'notice'); + } + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + ToolbarHelper::custom('update.update', 'upload', 'upload', 'COM_INSTALLER_TOOLBAR_UPDATE', true); + ToolbarHelper::custom('update.find', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_FIND_UPDATES', false); + ToolbarHelper::custom('update.purge', 'purge', 'purge', 'COM_INSTALLER_TOOLBAR_PURGE', false); + ToolbarHelper::divider(); + + \JHtmlSidebar::setAction('index.php?option=com_installer&view=manage'); + + parent::addToolbar(); + ToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_UPDATE'); + } +} diff --git a/administrator/components/com_installer/View/Updatesites/HtmlView.php b/administrator/components/com_installer/View/Updatesites/HtmlView.php new file mode 100644 index 0000000000000..4a84c64f37438 --- /dev/null +++ b/administrator/components/com_installer/View/Updatesites/HtmlView.php @@ -0,0 +1,100 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Include the component HTML helpers. + HTMLHelper::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Display the view + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.4 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_installer'); + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publish('updatesites.publish', 'JTOOLBAR_ENABLE', true); + ToolbarHelper::unpublish('updatesites.unpublish', 'JTOOLBAR_DISABLE', true); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'updatesites.delete', 'JTOOLBAR_DELETE'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::custom('updatesites.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); + } + + \JHtmlSidebar::setAction('index.php?option=com_installer&view=updatesites'); + + parent::addToolbar(); + ToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_UPDATESITES'); + } +} diff --git a/administrator/components/com_installer/View/Warnings/HtmlView.php b/administrator/components/com_installer/View/Warnings/HtmlView.php new file mode 100644 index 0000000000000..6b7b4d4e6d5e3 --- /dev/null +++ b/administrator/components/com_installer/View/Warnings/HtmlView.php @@ -0,0 +1,55 @@ +get('Items'); + $this->messages = &$items; + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + parent::addToolbar(); + + ToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_WARNINGS'); + } +} diff --git a/administrator/components/com_installer/access.xml b/administrator/components/com_installer/access.xml index 1c90bfc488ca8..81b20069a62c8 100644 --- a/administrator/components/com_installer/access.xml +++ b/administrator/components/com_installer/access.xml @@ -1,10 +1,10 @@
- - - - - + + + + +
diff --git a/administrator/components/com_installer/config.xml b/administrator/components/com_installer/config.xml index cc833115accf3..c920e96e8a8fd 100644 --- a/administrator/components/com_installer/config.xml +++ b/administrator/components/com_installer/config.xml @@ -6,23 +6,10 @@ description="COM_INSTALLER_PREFERENCES_DESCRIPTION" > - - - - - diff --git a/administrator/components/com_installer/controller.php b/administrator/components/com_installer/controller.php deleted file mode 100644 index 12ecac70e9a9f..0000000000000 --- a/administrator/components/com_installer/controller.php +++ /dev/null @@ -1,64 +0,0 @@ -input->get('view', 'install'); - $vFormat = $document->getType(); - $lName = $this->input->get('layout', 'default', 'string'); - - // Get and render the view. - if ($view = $this->getView($vName, $vFormat)) - { - $ftp = JClientHelper::setCredentialsFromRequest('ftp'); - $view->ftp = &$ftp; - - // Get the model for the view. - $model = $this->getModel($vName); - - // Push the model into the view (as default). - $view->setModel($model, true); - $view->setLayout($lName); - - // Push document object into the view. - $view->document = $document; - - // Load the submenu. - InstallerHelper::addSubmenu($vName); - $view->display(); - } - - return $this; - } -} diff --git a/administrator/components/com_installer/controllers/database.php b/administrator/components/com_installer/controllers/database.php deleted file mode 100644 index c4f0fa936c4dd..0000000000000 --- a/administrator/components/com_installer/controllers/database.php +++ /dev/null @@ -1,42 +0,0 @@ -getModel('database'); - $model->fix(); - - // Purge updates - JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_joomlaupdate/models', 'JoomlaupdateModel'); - $updateModel = JModelLegacy::getInstance('default', 'JoomlaupdateModel'); - $updateModel->purge(); - - // Refresh versionable assets cache - JFactory::getApplication()->flushAssets(); - - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=database', false)); - } -} diff --git a/administrator/components/com_installer/controllers/discover.php b/administrator/components/com_installer/controllers/discover.php deleted file mode 100644 index 28d8220c7b13f..0000000000000 --- a/administrator/components/com_installer/controllers/discover.php +++ /dev/null @@ -1,59 +0,0 @@ -getModel('discover'); - $model->discover(); - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false)); - } - - /** - * Install a discovered extension. - * - * @return void - * - * @since 1.6 - */ - public function install() - { - $this->getModel('discover')->discover_install(); - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=discover', false)); - } - - /** - * Clean out the discovered extension cache. - * - * @return void - * - * @since 1.6 - */ - public function purge() - { - $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 deleted file mode 100644 index f39ead23a3ac1..0000000000000 --- a/administrator/components/com_installer/controllers/install.php +++ /dev/null @@ -1,96 +0,0 @@ -getModel('install'); - - // TODO: Reset the users acl here as well to kill off any missing bits. - $result = $model->install(); - - $app = JFactory::getApplication(); - $redirect_url = $app->getUserState('com_installer.redirect_url'); - - if (!$redirect_url) - { - $redirect_url = base64_decode($app->input->get('return')); - } - - // Don't redirect to an external URL. - if (!JUri::isInternal($redirect_url)) - { - $redirect_url = ''; - } - - if (empty($redirect_url)) - { - $redirect_url = JRoute::_('index.php?option=com_installer&view=install', false); - } - else - { - // Wipe out the user state when we're going to redirect. - $app->setUserState('com_installer.redirect_url', ''); - $app->setUserState('com_installer.message', ''); - $app->setUserState('com_installer.extension_message', ''); - } - - $this->setRedirect($redirect_url); - - return $result; - } - - /** - * Install an extension from drag & drop ajax upload. - * - * @return void - * - * @since 3.7.0 - */ - public function ajax_upload() - { - $app = JFactory::getApplication(); - $message = $app->getUserState('com_installer.message'); - - // Do install - $result = $this->install(); - - // Get redirect URL - $redirect = $this->redirect; - - // Push message queue to session because we will redirect page by Javascript, not $app->redirect(). - // The "application.queue" is only set in redirect() method, so we must manually store it. - $app->getSession()->set('application.queue', $app->getMessageQueue()); - - header('Content-Type: application/json'); - - echo new JResponseJson(array('redirect' => $redirect), $message, !$result); - - exit(); - } -} diff --git a/administrator/components/com_installer/controllers/manage.php b/administrator/components/com_installer/controllers/manage.php deleted file mode 100644 index 3c0c17c746205..0000000000000 --- a/administrator/components/com_installer/controllers/manage.php +++ /dev/null @@ -1,130 +0,0 @@ -registerTask('unpublish', 'publish'); - $this->registerTask('publish', 'publish'); - } - - /** - * Enable/Disable an extension (if supported). - * - * @return void - * - * @since 1.6 - */ - public function publish() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = $this->input->get('cid', array(), 'array'); - $values = array('publish' => 1, 'unpublish' => 0); - $task = $this->getTask(); - $value = ArrayHelper::getValue($values, $task, 0, 'int'); - - if (empty($ids)) - { - JError::raiseWarning(500, JText::_('COM_INSTALLER_ERROR_NO_EXTENSIONS_SELECTED')); - } - else - { - // Get the model. - /** @var InstallerModelManage $model */ - $model = $this->getModel('manage'); - - // Change the state of the records. - if (!$model->publish($ids, $value)) - { - JError::raiseWarning(500, implode('
', $model->getErrors())); - } - else - { - if ($value == 1) - { - $ntext = 'COM_INSTALLER_N_EXTENSIONS_PUBLISHED'; - } - elseif ($value == 0) - { - $ntext = 'COM_INSTALLER_N_EXTENSIONS_UNPUBLISHED'; - } - - $this->setMessage(JText::plural($ntext, count($ids))); - } - } - - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=manage', false)); - } - - /** - * Remove an extension (Uninstall). - * - * @return void - * - * @since 1.5 - */ - public function remove() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $eid = $this->input->get('cid', array(), 'array'); - - /** @var InstallerModelManage $model */ - $model = $this->getModel('manage'); - - $eid = ArrayHelper::toInteger($eid, array()); - $model->remove($eid); - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=manage', false)); - } - - /** - * Refreshes the cached metadata about an extension. - * - * Useful for debugging and testing purposes when the XML file might change. - * - * @return void - * - * @since 1.6 - */ - public function refresh() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $uid = $this->input->get('cid', array(), 'array'); - $model = $this->getModel('manage'); - - $uid = ArrayHelper::toInteger($uid, array()); - $model->refresh($uid); - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=manage', false)); - } -} diff --git a/administrator/components/com_installer/controllers/update.php b/administrator/components/com_installer/controllers/update.php deleted file mode 100644 index 87d8b06861fc0..0000000000000 --- a/administrator/components/com_installer/controllers/update.php +++ /dev/null @@ -1,200 +0,0 @@ -getModel('update'); - $uid = $this->input->get('cid', array(), 'array'); - - $uid = ArrayHelper::toInteger($uid, array()); - - // Get the minimum stability. - $component = JComponentHelper::getComponent('com_installer'); - $params = $component->params; - $minimum_stability = $params->get('minimum_stability', JUpdater::STABILITY_STABLE, 'int'); - - $model->update($uid, $minimum_stability); - - $app = JFactory::getApplication(); - $redirect_url = $app->getUserState('com_installer.redirect_url'); - - // Don't redirect to an external URL. - if (!JUri::isInternal($redirect_url)) - { - $redirect_url = ''; - } - - if (empty($redirect_url)) - { - $redirect_url = JRoute::_('index.php?option=com_installer&view=update', false); - } - else - { - // Wipe out the user state when we're going to redirect. - $app->setUserState('com_installer.redirect_url', ''); - $app->setUserState('com_installer.message', ''); - $app->setUserState('com_installer.extension_message', ''); - } - - $this->setRedirect($redirect_url); - } - - /** - * Find new updates. - * - * @return void - * - * @since 1.6 - */ - public function find() - { - (JSession::checkToken() or JSession::checkToken('get')) or jexit(JText::_('JINVALID_TOKEN')); - - // Get the caching duration. - $component = JComponentHelper::getComponent('com_installer'); - $params = $component->params; - $cache_timeout = $params->get('cachetimeout', 6, 'int'); - $cache_timeout = 3600 * $cache_timeout; - - // Get the minimum stability. - $minimum_stability = $params->get('minimum_stability', JUpdater::STABILITY_STABLE, 'int'); - - // Find updates. - /** @var InstallerModelUpdate $model */ - $model = $this->getModel('update'); - - $disabledUpdateSites = $model->getDisabledUpdateSites(); - - if ($disabledUpdateSites) - { - $updateSitesUrl = JRoute::_('index.php?option=com_installer&view=updatesites'); - $this->setMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATE_SITES_COUNT_CHECK', $updateSitesUrl), 'warning'); - } - - $model->findUpdates(0, $cache_timeout, $minimum_stability); - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=update', false)); - } - - /** - * Purges updates. - * - * @return void - * - * @since 1.6 - */ - public function purge() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $model = $this->getModel('update'); - $model->purge(); - - /** - * We no longer need to enable update sites in Joomla! 3.4 as we now allow the users to manage update sites - * themselves. - * $model->enableSites(); - */ - - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=update', false), $model->_message); - } - - /** - * Fetch and report updates in JSON format, for AJAX requests - * - * @return void - * - * @since 2.5 - */ - public function ajax() - { - $app = JFactory::getApplication(); - - if (!JSession::checkToken('get')) - { - $app->setHeader('status', 403, true); - $app->sendHeaders(); - echo JText::_('JINVALID_TOKEN'); - $app->close(); - } - - $eid = $this->input->getInt('eid', 0); - $skip = $this->input->get('skip', array(), 'array'); - $cache_timeout = $this->input->getInt('cache_timeout', 0); - $minimum_stability = $this->input->getInt('minimum_stability', -1); - - $component = JComponentHelper::getComponent('com_installer'); - $params = $component->params; - - if ($cache_timeout == 0) - { - $cache_timeout = $params->get('cachetimeout', 6, 'int'); - $cache_timeout = 3600 * $cache_timeout; - } - - if ($minimum_stability < 0) - { - $minimum_stability = $params->get('minimum_stability', JUpdater::STABILITY_STABLE, 'int'); - } - - /** @var InstallerModelUpdate $model */ - $model = $this->getModel('update'); - $model->findUpdates($eid, $cache_timeout, $minimum_stability); - - $model->setState('list.start', 0); - $model->setState('list.limit', 0); - - if ($eid != 0) - { - $model->setState('filter.extension_id', $eid); - } - - $updates = $model->getItems(); - - if (!empty($skip)) - { - $unfiltered_updates = $updates; - $updates = array(); - - foreach ($unfiltered_updates as $update) - { - if (!in_array($update->extension_id, $skip)) - { - $updates[] = $update; - } - } - } - - echo json_encode($updates); - - $app->close(); - } -} diff --git a/administrator/components/com_installer/controllers/updatesites.php b/administrator/components/com_installer/controllers/updatesites.php deleted file mode 100644 index d004167f0a49e..0000000000000 --- a/administrator/components/com_installer/controllers/updatesites.php +++ /dev/null @@ -1,125 +0,0 @@ -registerTask('unpublish', 'publish'); - $this->registerTask('publish', 'publish'); - $this->registerTask('delete', 'delete'); - $this->registerTask('rebuild', 'rebuild'); - } - - /** - * Enable/Disable an extension (if supported). - * - * @return void - * - * @since 3.4 - * - * @throws Exception on error - */ - public function publish() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = $this->input->get('cid', array(), 'array'); - $values = array('publish' => 1, 'unpublish' => 0); - $task = $this->getTask(); - $value = ArrayHelper::getValue($values, $task, 0, 'int'); - - if (empty($ids)) - { - throw new Exception(JText::_('COM_INSTALLER_ERROR_NO_UPDATESITES_SELECTED'), 500); - } - - // Get the model. - $model = $this->getModel('Updatesites'); - - // Change the state of the records. - if (!$model->publish($ids, $value)) - { - throw new Exception(implode('
', $model->getErrors()), 500); - } - - $ntext = ($value == 0) ? 'COM_INSTALLER_N_UPDATESITES_UNPUBLISHED' : 'COM_INSTALLER_N_UPDATESITES_PUBLISHED'; - - $this->setMessage(JText::plural($ntext, count($ids))); - - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=updatesites', false)); - } - - /** - * Deletes an update site (if supported). - * - * @return void - * - * @since 3.6 - * - * @throws Exception on error - */ - public function delete() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = $this->input->get('cid', array(), 'array'); - - if (empty($ids)) - { - throw new Exception(JText::_('COM_INSTALLER_ERROR_NO_UPDATESITES_SELECTED'), 500); - } - - // Delete the records. - $this->getModel('Updatesites')->delete($ids); - - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=updatesites', false)); - } - - /** - * Rebuild update sites tables. - * - * @return void - * - * @since 3.6 - */ - public function rebuild() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Rebuild the update sites. - $this->getModel('Updatesites')->rebuild(); - - $this->setRedirect(JRoute::_('index.php?option=com_installer&view=updatesites', false)); - } -} diff --git a/administrator/components/com_installer/forms/filter_database.xml b/administrator/components/com_installer/forms/filter_database.xml new file mode 100644 index 0000000000000..8d38d598453bf --- /dev/null +++ b/administrator/components/com_installer/forms/filter_database.xml @@ -0,0 +1,68 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_installer/models/forms/filter_discover.xml b/administrator/components/com_installer/forms/filter_discover.xml similarity index 88% rename from administrator/components/com_installer/models/forms/filter_discover.xml rename to administrator/components/com_installer/forms/filter_discover.xml index b11e1f2dd4379..e8fa7f22f752d 100644 --- a/administrator/components/com_installer/models/forms/filter_discover.xml +++ b/administrator/components/com_installer/forms/filter_discover.xml @@ -1,7 +1,5 @@ -
-
- + @@ -61,9 +57,6 @@ diff --git a/administrator/components/com_installer/forms/filter_languages.xml b/administrator/components/com_installer/forms/filter_languages.xml new file mode 100644 index 0000000000000..d8f3f05d93e0a --- /dev/null +++ b/administrator/components/com_installer/forms/filter_languages.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_installer/models/forms/filter_manage.xml b/administrator/components/com_installer/forms/filter_manage.xml similarity index 86% rename from administrator/components/com_installer/models/forms/filter_manage.xml rename to administrator/components/com_installer/forms/filter_manage.xml index c6553e2e1b989..056d8b9ab483d 100644 --- a/administrator/components/com_installer/models/forms/filter_manage.xml +++ b/administrator/components/com_installer/forms/filter_manage.xml @@ -1,7 +1,5 @@ -
-
- + @@ -44,14 +40,22 @@ > + + + + + + @@ -75,9 +79,6 @@ diff --git a/administrator/components/com_installer/models/forms/filter_update.xml b/administrator/components/com_installer/forms/filter_update.xml similarity index 87% rename from administrator/components/com_installer/models/forms/filter_update.xml rename to administrator/components/com_installer/forms/filter_update.xml index 27493b8e90ee4..6dfaddb4f870a 100644 --- a/administrator/components/com_installer/models/forms/filter_update.xml +++ b/administrator/components/com_installer/forms/filter_update.xml @@ -1,7 +1,5 @@ - -
- + @@ -54,9 +50,6 @@ diff --git a/administrator/components/com_installer/models/forms/filter_updatesites.xml b/administrator/components/com_installer/forms/filter_updatesites.xml similarity index 87% rename from administrator/components/com_installer/models/forms/filter_updatesites.xml rename to administrator/components/com_installer/forms/filter_updatesites.xml index ec17aeec0647d..3037d25c8a51b 100644 --- a/administrator/components/com_installer/models/forms/filter_updatesites.xml +++ b/administrator/components/com_installer/forms/filter_updatesites.xml @@ -1,7 +1,5 @@ - -
- + @@ -47,8 +43,6 @@ @@ -71,9 +65,6 @@ diff --git a/administrator/components/com_installer/helpers/html/manage.php b/administrator/components/com_installer/helpers/html/manage.php index 4aaf19ee502c0..a457acc5d4cc1 100644 --- a/administrator/components/com_installer/helpers/html/manage.php +++ b/administrator/components/com_installer/helpers/html/manage.php @@ -9,6 +9,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\HTML\HTMLHelper; + /** * Installer HTML class. * @@ -62,6 +64,6 @@ public static function state($value, $i, $enabled = true, $checkbox = 'cb') ), ); - return JHtml::_('jgrid.state', $states, $value, $i, 'manage.', $enabled, true, $checkbox); + return HTMLHelper::_('jgrid.state', $states, $value, $i, 'manage.', $enabled, true, $checkbox); } } diff --git a/administrator/components/com_installer/helpers/html/updatesites.php b/administrator/components/com_installer/helpers/html/updatesites.php index 6a69aa0a49561..d25309fac922d 100644 --- a/administrator/components/com_installer/helpers/html/updatesites.php +++ b/administrator/components/com_installer/helpers/html/updatesites.php @@ -9,6 +9,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\HTML\HTMLHelper; + /** * Installer HTML class. * @@ -52,6 +54,6 @@ public static function state($value, $i, $enabled = true, $checkbox = 'cb') ), ); - return JHtml::_('jgrid.state', $states, $value, $i, 'updatesites.', $enabled, true, $checkbox); + return HTMLHelper::_('jgrid.state', $states, $value, $i, 'updatesites.', $enabled, true, $checkbox); } } diff --git a/administrator/components/com_installer/helpers/installer.php b/administrator/components/com_installer/helpers/installer.php index 6ca57ffb1d6e7..5782954a3b90b 100644 --- a/administrator/components/com_installer/helpers/installer.php +++ b/administrator/components/com_installer/helpers/installer.php @@ -14,174 +14,7 @@ * * @since 1.6 */ -class InstallerHelper +class InstallerHelper extends \Joomla\Component\Installer\Administrator\Helper\InstallerHelper { - /** - * Configure the Linkbar. - * - * @param string $vName The name of the active view. - * - * @return void - */ - public static function addSubmenu($vName = 'install') - { - JHtmlSidebar::addEntry( - JText::_('COM_INSTALLER_SUBMENU_INSTALL'), - 'index.php?option=com_installer', - $vName == 'install' - ); - JHtmlSidebar::addEntry( - JText::_('COM_INSTALLER_SUBMENU_UPDATE'), - 'index.php?option=com_installer&view=update', - $vName == 'update' - ); - JHtmlSidebar::addEntry( - JText::_('COM_INSTALLER_SUBMENU_MANAGE'), - 'index.php?option=com_installer&view=manage', - $vName == 'manage' - ); - JHtmlSidebar::addEntry( - JText::_('COM_INSTALLER_SUBMENU_DISCOVER'), - 'index.php?option=com_installer&view=discover', - $vName == 'discover' - ); - JHtmlSidebar::addEntry( - JText::_('COM_INSTALLER_SUBMENU_DATABASE'), - 'index.php?option=com_installer&view=database', - $vName == 'database' - ); - JHtmlSidebar::addEntry( - 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' - ); - JHtmlSidebar::addEntry( - JText::_('COM_INSTALLER_SUBMENU_UPDATESITES'), - 'index.php?option=com_installer&view=updatesites', - $vName == 'updatesites' - ); - } - /** - * Get a list of filter options for the extension types. - * - * @return array An array of stdClass objects. - * - * @since 3.0 - */ - public static function getExtensionTypes() - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('DISTINCT type') - ->from('#__extensions'); - $db->setQuery($query); - $types = $db->loadColumn(); - - $options = array(); - - foreach ($types as $type) - { - $options[] = JHtml::_('select.option', $type, JText::_('COM_INSTALLER_TYPE_' . strtoupper($type))); - } - - return $options; - } - - /** - * Get a list of filter options for the extension types. - * - * @return array An array of stdClass objects. - * - * @since 3.0 - */ - public static function getExtensionGroupes() - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('DISTINCT folder') - ->from('#__extensions') - ->where('folder != ' . $db->quote('')) - ->order('folder'); - $db->setQuery($query); - $folders = $db->loadColumn(); - - $options = array(); - - foreach ($folders as $folder) - { - $options[] = JHtml::_('select.option', $folder, $folder); - } - - return $options; - } - - /** - * Gets a list of the actions that can be performed. - * - * @return JObject - * - * @since 1.6 - * @deprecated 3.2 Use JHelperContent::getActions() instead - */ - public static function getActions() - { - // Log usage of deprecated function - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Get list of actions - return JHelperContent::getActions('com_installer'); - } - - /** - * Get a list of filter options for the application clients. - * - * @return array An array of JHtmlOption elements. - * - * @since 3.5 - */ - public static function getClientOptions() - { - // Build the filter options. - $options = array(); - $options[] = JHtml::_('select.option', '0', JText::_('JSITE')); - $options[] = JHtml::_('select.option', '1', JText::_('JADMINISTRATOR')); - - return $options; - } - - /** - * Get a list of filter options for the application statuses. - * - * @return array An array of JHtmlOption elements. - * - * @since 3.5 - */ - public static function getStateOptions() - { - // Build the filter options. - $options = array(); - $options[] = JHtml::_('select.option', '0', JText::_('JDISABLED')); - $options[] = JHtml::_('select.option', '1', JText::_('JENABLED')); - $options[] = JHtml::_('select.option', '2', JText::_('JPROTECTED')); - $options[] = JHtml::_('select.option', '3', JText::_('JUNPROTECTED')); - - return $options; - } } diff --git a/administrator/components/com_installer/installer.php b/administrator/components/com_installer/installer.php deleted file mode 100644 index 301771b9dcb76..0000000000000 --- a/administrator/components/com_installer/installer.php +++ /dev/null @@ -1,20 +0,0 @@ -authorise('core.manage', 'com_installer')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('Installer'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_installer/installer.xml b/administrator/components/com_installer/installer.xml index e787399132ba3..977262c5f45ae 100644 --- a/administrator/components/com_installer/installer.xml +++ b/administrator/components/com_installer/installer.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 COM_INSTALLER_XML_DESCRIPTION + Joomla\Component\Installer config.xml diff --git a/administrator/components/com_installer/models/database.php b/administrator/components/com_installer/models/database.php deleted file mode 100644 index 800519e36889b..0000000000000 --- a/administrator/components/com_installer/models/database.php +++ /dev/null @@ -1,327 +0,0 @@ -setState('message', $app->getUserState('com_installer.message')); - $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); - $app->setUserState('com_installer.message', ''); - $app->setUserState('com_installer.extension_message', ''); - - // Prepare the utf8mb4 conversion check table - $this->prepareUtf8mb4StatusTable(); - - parent::populateState($ordering, $direction); - } - - /** - * Fixes database problems. - * - * @return void - */ - public function fix() - { - if (!$changeSet = $this->getItems()) - { - return false; - } - - $changeSet->fix(); - $this->fixSchemaVersion($changeSet); - $this->fixUpdateVersion(); - $installer = new JoomlaInstallerScript; - $installer->deleteUnexistingFiles(); - $this->fixDefaultTextFilters(); - - /* - * Finally, if the schema updates succeeded, make sure the database is - * converted to utf8mb4 or, if not suported by the server, compatible to it. - */ - $statusArray = $changeSet->getStatus(); - - if (count($statusArray['error']) == 0) - { - $installer->convertTablesToUtf8mb4(false); - } - } - - /** - * Gets the changeset object. - * - * @return JSchemaChangeset - */ - public function getItems() - { - $folder = JPATH_ADMINISTRATOR . '/components/com_admin/sql/updates/'; - - try - { - $changeSet = JSchemaChangeset::getInstance($this->getDbo(), $folder); - } - catch (RuntimeException $e) - { - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'warning'); - - return false; - } - - return $changeSet; - } - - /** - * Method to get a JPagination object for the data set. - * - * @return boolean - * - * @since 12.2 - */ - public function getPagination() - { - return true; - } - - /** - * Get version from #__schemas table. - * - * @return mixed the return value from the query, or null if the query fails. - * - * @throws Exception - */ - public function getSchemaVersion() - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('version_id') - ->from($db->quoteName('#__schemas')) - ->where('extension_id = 700'); - $db->setQuery($query); - $result = $db->loadResult(); - - return $result; - } - - /** - * Fix schema version if wrong. - * - * @param JSchemaChangeSet $changeSet Schema change set. - * - * @return mixed string schema version if success, false if fail. - */ - public function fixSchemaVersion($changeSet) - { - // Get correct schema version -- last file in array. - $schema = $changeSet->getSchema(); - - // Check value. If ok, don't do update. - if ($schema == $this->getSchemaVersion()) - { - return $schema; - } - - // Delete old row. - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->delete($db->quoteName('#__schemas')) - ->where($db->quoteName('extension_id') . ' = 700'); - $db->setQuery($query); - $db->execute(); - - // Add new row. - $query->clear() - ->insert($db->quoteName('#__schemas')) - ->columns($db->quoteName('extension_id') . ',' . $db->quoteName('version_id')) - ->values('700, ' . $db->quote($schema)); - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (JDatabaseExceptionExecuting $e) - { - return false; - } - - return $schema; - } - - /** - * Get current version from #__extensions table. - * - * @return mixed version if successful, false if fail. - */ - public function getUpdateVersion() - { - $table = JTable::getInstance('Extension'); - $table->load('700'); - $cache = new Registry($table->manifest_cache); - - return $cache->get('version'); - } - - /** - * Fix Joomla version in #__extensions table if wrong (doesn't equal JVersion short version). - * - * @return mixed string update version if success, false if fail. - */ - public function fixUpdateVersion() - { - $table = JTable::getInstance('Extension'); - $table->load('700'); - $cache = new Registry($table->manifest_cache); - $updateVersion = $cache->get('version'); - $cmsVersion = new JVersion; - - if ($updateVersion == $cmsVersion->getShortVersion()) - { - return $updateVersion; - } - - $cache->set('version', $cmsVersion->getShortVersion()); - $table->manifest_cache = $cache->toString(); - - if ($table->store()) - { - return $cmsVersion->getShortVersion(); - } - - return false; - } - - /** - * For version 2.5.x only - * Check if com_config parameters are blank. - * - * @return string default text filters (if any). - */ - public function getDefaultTextFilters() - { - $table = JTable::getInstance('Extension'); - $table->load($table->find(array('name' => 'com_config'))); - - return $table->params; - } - - /** - * For version 2.5.x only - * Check if com_config parameters are blank. If so, populate with com_content text filters. - * - * @return mixed boolean true if params are updated, null otherwise. - */ - public function fixDefaultTextFilters() - { - $table = JTable::getInstance('Extension'); - $table->load($table->find(array('name' => 'com_config'))); - - // Check for empty $config and non-empty content filters. - if (!$table->params) - { - // Get filters from com_content and store if you find them. - $contentParams = JComponentHelper::getParams('com_content'); - - if ($contentParams->get('filters')) - { - $newParams = new Registry; - $newParams->set('filters', $contentParams->get('filters')); - $table->params = (string) $newParams; - $table->store(); - - return true; - } - } - } - - /** - * Prepare the table to save the status of utf8mb4 conversion - * Make sure it contains 1 initialized record if there is not - * already exactly 1 record. - * - * @return void - * - * @since 3.5 - */ - private function prepareUtf8mb4StatusTable() - { - $db = JFactory::getDbo(); - - $serverType = $db->getServerType(); - - if ($serverType != 'mysql') - { - return; - } - - $creaTabSql = 'CREATE TABLE IF NOT EXISTS ' . $db->quoteName('#__utf8_conversion') - . ' (' . $db->quoteName('converted') . ' tinyint(4) NOT NULL DEFAULT 0' - . ') ENGINE=InnoDB'; - - if ($db->hasUTF8mb4Support()) - { - $creaTabSql = $creaTabSql - . ' DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;'; - } - else - { - $creaTabSql = $creaTabSql - . ' DEFAULT CHARSET=utf8 DEFAULT COLLATE=utf8_unicode_ci;'; - } - - $db->setQuery($creaTabSql)->execute(); - - $db->setQuery('SELECT COUNT(*) FROM ' . $db->quoteName('#__utf8_conversion') . ';'); - - $count = $db->loadResult(); - - if ($count > 1) - { - // Table messed up somehow, clear it - $db->setQuery('DELETE FROM ' . $db->quoteName('#__utf8_conversion') . ';') - ->execute(); - $db->setQuery('INSERT INTO ' . $db->quoteName('#__utf8_conversion') - . ' (' . $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(); - } - } -} diff --git a/administrator/components/com_installer/models/discover.php b/administrator/components/com_installer/models/discover.php deleted file mode 100644 index e2c45141ba8c3..0000000000000 --- a/administrator/components/com_installer/models/discover.php +++ /dev/null @@ -1,258 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); - $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); - $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); - - $this->setState('message', $app->getUserState('com_installer.message')); - $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); - - $app->setUserState('com_installer.message', ''); - $app->setUserState('com_installer.extension_message', ''); - - parent::populateState($ordering, $direction); - } - - /** - * Method to get the database query. - * - * @return JDatabaseQuery the database query - * - * @since 3.1 - */ - protected function getListQuery() - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('*') - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('state') . ' = -1'); - - // Process select filters. - $type = $this->getState('filter.type'); - $clientId = $this->getState('filter.client_id'); - $folder = $this->getState('filter.folder'); - - if ($type) - { - $query->where($db->quoteName('type') . ' = ' . $db->quote($type)); - } - - if ($clientId != '') - { - $query->where($db->quoteName('client_id') . ' = ' . (int) $clientId); - } - - if ($folder != '' && in_array($type, array('plugin', 'library', ''))) - { - $query->where($db->quoteName('folder') . ' = ' . $db->quote($folder == '*' ? '' : $folder)); - } - - // Process search filter. - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where($db->quoteName('extension_id') . ' = ' . (int) substr($search, 3)); - } - } - - // Note: The search for name, ordering and pagination are processed by the parent InstallerModel class (in extension.php). - - return $query; - } - - /** - * Discover extensions. - * - * Finds uninstalled extensions - * - * @return void - * - * @since 1.6 - */ - public function discover() - { - // Purge the list of discovered extensions and fetch them again. - $this->purge(); - $results = JInstaller::getInstance()->discover(); - - // Get all templates, including discovered ones - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName(array('extension_id', 'element', 'folder', 'client_id', 'type'))) - ->from($db->quoteName('#__extensions')); - $db->setQuery($query); - $installedtmp = $db->loadObjectList(); - - $extensions = array(); - - foreach ($installedtmp as $install) - { - $key = implode(':', array($install->type, $install->element, $install->folder, $install->client_id)); - $extensions[$key] = $install; - } - - foreach ($results as $result) - { - // Check if we have a match on the element - $key = implode(':', array($result->type, $result->element, $result->folder, $result->client_id)); - - if (!array_key_exists($key, $extensions)) - { - // Put it into the table - $result->check(); - $result->store(); - } - } - } - - /** - * Installs a discovered extension. - * - * @return void - * - * @since 1.6 - */ - public function discover_install() - { - $app = JFactory::getApplication(); - $input = $app->input; - $eid = $input->get('cid', 0, 'array'); - - if (is_array($eid) || $eid) - { - if (!is_array($eid)) - { - $eid = array($eid); - } - - $eid = ArrayHelper::toInteger($eid); - $failed = false; - - foreach ($eid as $id) - { - $installer = new JInstaller; - - $result = $installer->discover_install($id); - - if (!$result) - { - $failed = true; - $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_INSTALLFAILED') . ': ' . $id); - } - } - - // TODO - We are only receiving the message for the last JInstaller instance - $this->setState('action', 'remove'); - $this->setState('name', $installer->get('name')); - $app->setUserState('com_installer.message', $installer->message); - $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); - - if (!$failed) - { - $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_INSTALLSUCCESSFUL')); - } - } - else - { - $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DISCOVER_NOEXTENSIONSELECTED')); - } - } - - /** - * Cleans out the list of discovered extensions. - * - * @return boolean True on success - * - * @since 1.6 - */ - public function purge() - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->delete($db->quoteName('#__extensions')) - ->where($db->quoteName('state') . ' = -1'); - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (JDatabaseExceptionExecuting $e) - { - $this->_message = JText::_('COM_INSTALLER_MSG_DISCOVER_FAILEDTOPURGEEXTENSIONS'); - - return false; - } - - $this->_message = JText::_('COM_INSTALLER_MSG_DISCOVER_PURGEDDISCOVEREDEXTENSIONS'); - - return true; - } -} diff --git a/administrator/components/com_installer/models/extension.php b/administrator/components/com_installer/models/extension.php deleted file mode 100644 index 2d6c1239215be..0000000000000 --- a/administrator/components/com_installer/models/extension.php +++ /dev/null @@ -1,224 +0,0 @@ -getState('list.ordering', 'name'); - $listDirn = $this->getState('list.direction', 'asc'); - - // Replace slashes so preg_match will work - $search = $this->getState('filter.search'); - $search = str_replace('/', ' ', $search); - $db = $this->getDbo(); - - // Define which fields have to be processed in a custom way because of translation. - $customOrderFields = array('name', 'client_translated', 'type_translated', 'folder_translated'); - - // Process searching, ordering and pagination for fields that need to be translated. - if (in_array($listOrder, $customOrderFields) || (!empty($search) && stripos($search, 'id:') !== 0)) - { - // Get results from database and translate them. - $db->setQuery($query); - $result = $db->loadObjectList(); - $this->translate($result); - - // Process searching. - if (!empty($search) && stripos($search, 'id:') !== 0) - { - $escapedSearchString = $this->refineSearchStringToRegex($search, '/'); - - // By default search only the extension name field. - $searchFields = array('name'); - - // If in update sites view search also in the update site name field. - if ($this instanceof InstallerModelUpdatesites) - { - $searchFields[] = 'update_site_name'; - } - - foreach ($result as $i => $item) - { - // 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})) - { - $found = 1; - } - } - - // If search string was not found in any of the fields searched remove it from results array. - if (!$found) - { - unset($result[$i]); - } - } - } - - // Process ordering. - // Sort array object by selected ordering and selected direction. Sort is case insensative 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) - { - $limitstart = 0; - $this->setState('list.start', 0); - } - - return array_slice($result, $limitstart, $limit ?: null); - } - - // Process searching, ordering and pagination for regular database fields. - $query->order($db->quoteName($listOrder) . ' ' . $db->escape($listDirn)); - $result = parent::_getList($query, $limitstart, $limit); - $this->translate($result); - - return $result; - } - - /** - * Translate a list of objects - * - * @param array &$items The array of objects - * - * @return array The array of translated objects - */ - protected function translate(&$items) - { - $lang = JFactory::getLanguage(); - - foreach ($items as &$item) - { - if (strlen($item->manifest_cache) && $data = json_decode($item->manifest_cache)) - { - foreach ($data as $key => $value) - { - if ($key == 'type') - { - // Ignore the type field - continue; - } - - $item->$key = $value; - } - } - - $item->author_info = @$item->authorEmail . '
' . @$item->authorUrl; - $item->client = $item->client_id ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); - $item->client_translated = $item->client; - $item->type_translated = JText::_('COM_INSTALLER_TYPE_' . strtoupper($item->type)); - $item->folder_translated = @$item->folder ? $item->folder : JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); - - $path = $item->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE; - - switch ($item->type) - { - case 'component': - $extension = $item->element; - $source = JPATH_ADMINISTRATOR . '/components/' . $extension; - $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) - || $lang->load("$extension.sys", $source, null, false, true); - break; - case 'file': - $extension = 'files_' . $item->element; - $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); - break; - case 'module': - $extension = $item->element; - $source = $path . '/modules/' . $extension; - $lang->load("$extension.sys", $path, null, false, true) - || $lang->load("$extension.sys", $source, null, false, true); - break; - case 'plugin': - $extension = 'plg_' . $item->folder . '_' . $item->element; - $source = JPATH_PLUGINS . '/' . $item->folder . '/' . $item->element; - $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) - || $lang->load("$extension.sys", $source, null, false, true); - break; - case 'template': - $extension = 'tpl_' . $item->element; - $source = $path . '/templates/' . $item->element; - $lang->load("$extension.sys", $path, null, false, true) - || $lang->load("$extension.sys", $source, null, false, true); - break; - case 'package': - default: - $extension = $item->element; - $lang->load("$extension.sys", JPATH_SITE, null, false, true); - break; - } - - // Translate the extension name if possible - $item->name = JText::_($item->name); - - settype($item->description, 'string'); - - if (!in_array($item->type, array('language'))) - { - $item->description = JText::_($item->description); - } - } - } -} diff --git a/administrator/components/com_installer/models/fields/extensionstatus.php b/administrator/components/com_installer/models/fields/extensionstatus.php deleted file mode 100644 index 987b90d1a4525..0000000000000 --- a/administrator/components/com_installer/models/fields/extensionstatus.php +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/administrator/components/com_installer/models/install.php b/administrator/components/com_installer/models/install.php deleted file mode 100644 index 963c515b24ac7..0000000000000 --- a/administrator/components/com_installer/models/install.php +++ /dev/null @@ -1,415 +0,0 @@ -setState('message', $app->getUserState('com_installer.message')); - $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); - $app->setUserState('com_installer.message', ''); - $app->setUserState('com_installer.extension_message', ''); - - parent::populateState(); - } - - /** - * Install an extension from either folder, URL or upload. - * - * @return boolean result of install. - * - * @since 1.5 - */ - public function install() - { - $this->setState('action', 'install'); - - // Set FTP credentials, if given. - JClientHelper::setCredentialsFromRequest('ftp'); - $app = JFactory::getApplication(); - - // Load installer plugins for assistance if required: - JPluginHelper::importPlugin('installer'); - $dispatcher = JEventDispatcher::getInstance(); - - $package = null; - - // This event allows an input pre-treatment, a custom pre-packing or custom installation. - // (e.g. from a JSON description). - $results = $dispatcher->trigger('onInstallerBeforeInstallation', array($this, &$package)); - - if (in_array(true, $results, true)) - { - return true; - } - - if (in_array(false, $results, true)) - { - return false; - } - - $installType = $app->input->getWord('installtype'); - - if ($package === null) - { - switch ($installType) - { - case 'folder': - // Remember the 'Install from Directory' path. - $app->getUserStateFromRequest($this->_context . '.install_directory', 'install_directory'); - $package = $this->_getPackageFromFolder(); - break; - - case 'upload': - $package = $this->_getPackageFromUpload(); - break; - - case 'url': - $package = $this->_getPackageFromUrl(); - break; - - default: - $app->setUserState('com_installer.message', JText::_('COM_INSTALLER_NO_INSTALL_TYPE_FOUND')); - - return false; - break; - } - } - - // This event allows a custom installation of the package or a customization of the package: - $results = $dispatcher->trigger('onInstallerBeforeInstaller', array($this, &$package)); - - if (in_array(true, $results, true)) - { - return true; - } - - if (in_array(false, $results, true)) - { - if (in_array($installType, array('upload', 'url'))) - { - JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); - } - - return false; - } - - // Get an installer instance. - $installer = JInstaller::getInstance(); - - /* - * Check for a Joomla core package. - * To do this we need to set the source path to find the manifest (the same first step as JInstaller::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'])) - { - $installer->setPath('source', $package['dir']); - - if (!$installer->findManifest()) - { - // If a manifest isn't found at the source, this may be a Joomla package; check the package directory for the Joomla manifest - if (file_exists($package['dir'] . '/administrator/manifests/files/joomla.xml')) - { - // We have a Joomla package - if (in_array($installType, array('upload', 'url'))) - { - JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); - } - - $app->enqueueMessage( - JText::sprintf('COM_INSTALLER_UNABLE_TO_INSTALL_JOOMLA_PACKAGE', JRoute::_('index.php?option=com_joomlaupdate')), - 'warning' - ); - - return false; - } - } - } - - // Was the package unpacked? - if (!$package || !$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'); - - return false; - } - - // Install the package. - if (!$installer->install($package['dir'])) - { - // There was an error installing the package. - $msg = JText::sprintf('COM_INSTALLER_INSTALL_ERROR', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); - $result = false; - $msgType = 'error'; - } - else - { - // Package installed successfully. - $msg = JText::sprintf('COM_INSTALLER_INSTALL_SUCCESS', JText::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type']))); - $result = true; - $msgType = 'message'; - } - - // This event allows a custom a post-flight: - $dispatcher->trigger('onInstallerAfterInstaller', array($this, &$package, $installer, &$result, &$msg)); - - // Set some model state values. - $app = JFactory::getApplication(); - $app->enqueueMessage($msg, $msgType); - $this->setState('name', $installer->get('name')); - $this->setState('result', $result); - $app->setUserState('com_installer.message', $installer->message); - $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); - $app->setUserState('com_installer.redirect_url', $installer->get('redirect_url')); - - // Cleanup the install files. - if (!is_file($package['packagefile'])) - { - $config = JFactory::getConfig(); - $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; - } - - JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); - - // Clear the cached extension data and menu cache - $this->cleanCache('_system', 0); - $this->cleanCache('_system', 1); - $this->cleanCache('com_modules', 0); - $this->cleanCache('com_modules', 1); - $this->cleanCache('com_plugins', 0); - $this->cleanCache('com_plugins', 1); - $this->cleanCache('mod_menu', 0); - $this->cleanCache('mod_menu', 1); - - return $result; - } - - /** - * Works out an installation package from a HTTP upload. - * - * @return package definition or false on failure. - */ - protected function _getPackageFromUpload() - { - // Get the uploaded file information. - $input = JFactory::getApplication()->input; - - // Do not change the filter type 'raw'. We need this to let files containing PHP code to upload. See JInputFiles::get. - $userfile = $input->files->get('install_package', null, 'raw'); - - // Make sure that file uploads are enabled in php. - if (!(bool) ini_get('file_uploads')) - { - JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLFILE')); - - return false; - } - - // Make sure that zlib is loaded so that the package can be unpacked. - if (!extension_loaded('zlib')) - { - JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB')); - - return false; - } - - // If there is no uploaded file, we have a problem... - if (!is_array($userfile)) - { - JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_NO_FILE_SELECTED')); - - return false; - } - - // Is the PHP tmp directory missing? - if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_NO_TMP_DIR)) - { - JError::raiseWarning( - '', - JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET') - ); - - return false; - } - - // Is the max upload size too small in php.ini? - if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_INI_SIZE)) - { - JError::raiseWarning( - '', - JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE') - ); - - return false; - } - - // Check if there was a different problem uploading the file. - if ($userfile['error'] || $userfile['size'] < 1) - { - JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR')); - - return false; - } - - // Build the appropriate paths. - $config = JFactory::getConfig(); - $tmp_dest = $config->get('tmp_path') . '/' . $userfile['name']; - $tmp_src = $userfile['tmp_name']; - - // Move uploaded file. - jimport('joomla.filesystem.file'); - JFile::upload($tmp_src, $tmp_dest, false, true); - - // Unpack the downloaded package file. - $package = JInstallerHelper::unpack($tmp_dest, true); - - return $package; - } - - /** - * Install an extension from a directory - * - * @return array Package details or false on failure - * - * @since 1.5 - */ - protected function _getPackageFromFolder() - { - $input = JFactory::getApplication()->input; - - // Get the path to the package to install. - $p_dir = $input->getString('install_directory'); - $p_dir = JPath::clean($p_dir); - - // Did you give us a valid directory? - if (!is_dir($p_dir)) - { - JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_PLEASE_ENTER_A_PACKAGE_DIRECTORY')); - - return false; - } - - // Detect the package type - $type = JInstallerHelper::detectType($p_dir); - - // Did you give us a valid package? - if (!$type) - { - JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_PATH_DOES_NOT_HAVE_A_VALID_PACKAGE')); - } - - $package['packagefile'] = null; - $package['extractdir'] = null; - $package['dir'] = $p_dir; - $package['type'] = $type; - - return $package; - } - - /** - * Install an extension from a URL. - * - * @return Package details or false on failure. - * - * @since 1.5 - */ - protected function _getPackageFromUrl() - { - $input = JFactory::getApplication()->input; - - // Get the URL of the package to install. - $url = $input->getString('install_url'); - - // Did you give us a URL? - if (!$url) - { - JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_ENTER_A_URL')); - - return false; - } - - // Handle updater XML file case: - if (preg_match('/\.xml\s*$/', $url)) - { - jimport('joomla.updater.update'); - $update = new JUpdate; - $update->loadFromXml($url); - $package_url = trim($update->get('downloadurl', false)->_data); - - if ($package_url) - { - $url = $package_url; - } - - unset($update); - } - - // Download the package at the URL given. - $p_file = JInstallerHelper::downloadPackage($url); - - // Was the package downloaded? - if (!$p_file) - { - JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_INVALID_URL')); - - return false; - } - - $config = JFactory::getConfig(); - $tmp_dest = $config->get('tmp_path'); - - // Unpack the downloaded package file. - $package = JInstallerHelper::unpack($tmp_dest . '/' . $p_file, true); - - return $package; - } -} diff --git a/administrator/components/com_installer/models/languages.php b/administrator/components/com_installer/models/languages.php deleted file mode 100644 index 63f8c3b6ed199..0000000000000 --- a/administrator/components/com_installer/models/languages.php +++ /dev/null @@ -1,253 +0,0 @@ -getDbo(); - $query = $db->getQuery(true) - ->select($db->qn('us.location')) - ->from($db->qn('#__extensions', 'e')) - ->where($db->qn('e.type') . ' = ' . $db->q('package')) - ->where($db->qn('e.element') . ' = ' . $db->q('pkg_en-GB')) - ->where($db->qn('e.client_id') . ' = 0') - ->join('LEFT', $db->qn('#__update_sites_extensions', 'use') . ' ON ' . $db->qn('use.extension_id') . ' = ' . $db->qn('e.extension_id')) - ->join('LEFT', $db->qn('#__update_sites', 'us') . ' ON ' . $db->qn('us.update_site_id') . ' = ' . $db->qn('use.update_site_id')); - - return $db->setQuery($query)->loadResult(); - } - - /** - * Method to get an array of data items. - * - * @return mixed An array of data items on success, false on failure. - * - * @since 3.7.0 - */ - public function getItems() - { - // Get a storage key. - $store = $this->getStoreId(); - - // Try to load the data from internal storage. - if (isset($this->cache[$store])) - { - return $this->cache[$store]; - } - - try - { - // Load the list items and add the items to the internal cache. - $this->cache[$store] = $this->getLanguages(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - return $this->cache[$store]; - } - - /** - * Gets an array of objects from the updatesite. - * - * @return object[] An array of results. - * - * @since 3.0 - * @throws RuntimeException - */ - protected function getLanguages() - { - $updateSite = $this->getUpdateSite(); - - $http = new JHttp; - - try - { - $response = $http->get($updateSite); - } - catch (RuntimeException $e) - { - $response = null; - } - - if ($response === null || $response->code !== 200) - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNING_NO_LANGUAGES_UPDATESERVER'), 'warning'); - - return; - } - - $updateSiteXML = simplexml_load_string($response->body); - $languages = array(); - $search = strtolower($this->getState('filter.search')); - - foreach ($updateSiteXML->extension as $extension) - { - $language = new stdClass; - - foreach ($extension->attributes() as $key => $value) - { - $language->$key = (string) $value; - } - - if ($search) - { - if (strpos(strtolower($language->name), $search) === false - && strpos(strtolower($language->element), $search) === false) - { - continue; - } - } - - $languages[$language->name] = $language; - } - - // Workaround for php 5.3 - $that = $this; - - // Sort the array by value of subarray - usort( - $languages, - function($a, $b) use ($that) - { - $ordering = $that->getState('list.ordering'); - - if (strtolower($that->getState('list.direction')) === 'asc') - { - return StringHelper::strcmp($a->$ordering, $b->$ordering); - } - else - { - return StringHelper::strcmp($b->$ordering, $a->$ordering); - } - } - ); - - // Count the non-paginated list - $this->languageCount = count($languages); - $limit = ($this->getState('list.limit') > 0) ? $this->getState('list.limit') : $this->languageCount; - - return array_slice($languages, $this->getStart(), $limit); - } - - /** - * Returns a record count for the updatesite. - * - * @param JDatabaseQuery|string $query The query. - * - * @return integer Number of rows for query. - * - * @since 3.7.0 - */ - protected function _getListCount($query) - { - return $this->languageCount; - } - - /** - * Method to get a store id based on model configuration state. - * - * @param string $id A prefix for the store id. - * - * @return string A store id. - * - * @since 2.5.7 - */ - 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 list order - * @param string $direction direction in the list - * - * @return void - * - * @since 2.5.7 - */ - protected function populateState($ordering = 'name', $direction = 'asc') - { - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - - $this->setState('extension_message', JFactory::getApplication()->getUserState('com_installer.extension_message')); - - parent::populateState($ordering, $direction); - } - - /** - * Method to compare two languages in order to sort them. - * - * @param object $lang1 The first language. - * @param object $lang2 The second language. - * - * @return integer - * - * @since 3.7.0 - */ - protected function compareLanguages($lang1, $lang2) - { - return strcmp($lang1->name, $lang2->name); - } -} diff --git a/administrator/components/com_installer/models/manage.php b/administrator/components/com_installer/models/manage.php deleted file mode 100644 index a046a110407b1..0000000000000 --- a/administrator/components/com_installer/models/manage.php +++ /dev/null @@ -1,350 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); - $this->setState('filter.status', $this->getUserStateFromRequest($this->context . '.filter.status', 'filter_status', '', 'string')); - $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); - $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); - - $this->setState('message', $app->getUserState('com_installer.message')); - $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); - $app->setUserState('com_installer.message', ''); - $app->setUserState('com_installer.extension_message', ''); - - parent::populateState($ordering, $direction); - } - - /** - * Enable/Disable an extension. - * - * @param array &$eid Extension ids to un/publish - * @param int $value Publish value - * - * @return boolean True on success - * - * @since 1.5 - */ - public function publish(&$eid = array(), $value = 1) - { - $user = JFactory::getUser(); - - if (!$user->authorise('core.edit.state', 'com_installer')) - { - JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - - return false; - } - - $result = true; - - /* - * Ensure eid is an array of extension ids - * TODO: If it isn't an array do we want to set an error and fail? - */ - if (!is_array($eid)) - { - $eid = array($eid); - } - - // Get a table object for the extension type - $table = JTable::getInstance('Extension'); - JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_templates/tables'); - - // Enable the extension in the table and store it in the database - foreach ($eid as $i => $id) - { - $table->load($id); - - if ($table->type == 'template') - { - $style = JTable::getInstance('Style', 'TemplatesTable'); - - if ($style->load(array('template' => $table->element, 'client_id' => $table->client_id, 'home' => 1))) - { - JError::raiseNotice(403, JText::_('COM_INSTALLER_ERROR_DISABLE_DEFAULT_TEMPLATE_NOT_PERMITTED')); - unset($eid[$i]); - continue; - } - } - - if ($table->protected == 1) - { - $result = false; - JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - } - else - { - $table->enabled = $value; - } - - if (!$table->store()) - { - $this->setError($table->getError()); - $result = false; - } - } - - // Clear the cached extension data and menu cache - $this->cleanCache('_system', 0); - $this->cleanCache('_system', 1); - $this->cleanCache('com_modules', 0); - $this->cleanCache('com_modules', 1); - $this->cleanCache('mod_menu', 0); - $this->cleanCache('mod_menu', 1); - - return $result; - } - - /** - * Refreshes the cached manifest information for an extension. - * - * @param int $eid extension identifier (key in #__extensions) - * - * @return boolean result of refresh - * - * @since 1.6 - */ - public function refresh($eid) - { - if (!is_array($eid)) - { - $eid = array($eid => 0); - } - - // Get an installer object for the extension type - $installer = JInstaller::getInstance(); - $result = 0; - - // Uninstall the chosen extensions - foreach ($eid as $id) - { - $result |= $installer->refreshManifestCache($id); - } - - return $result; - } - - /** - * Remove (uninstall) an extension - * - * @param array $eid An array of identifiers - * - * @return boolean True on success - * - * @since 1.5 - */ - public function remove($eid = array()) - { - $user = JFactory::getUser(); - - if (!$user->authorise('core.delete', 'com_installer')) - { - JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); - - return false; - } - - /* - * Ensure eid is an array of extension ids in the form id => client_id - * TODO: If it isn't an array do we want to set an error and fail? - */ - if (!is_array($eid)) - { - $eid = array($eid => 0); - } - - // Get an installer object for the extension type - $installer = JInstaller::getInstance(); - $row = JTable::getInstance('extension'); - - // Uninstall the chosen extensions - $msgs = array(); - $result = false; - - foreach ($eid as $id) - { - $id = trim($id); - $row->load($id); - $result = false; - - $langstring = 'COM_INSTALLER_TYPE_TYPE_' . strtoupper($row->type); - $rowtype = JText::_($langstring); - - if (strpos($rowtype, $langstring) !== false) - { - $rowtype = $row->type; - } - - if ($row->type) - { - $result = $installer->uninstall($row->type, $id); - - // Build an array of extensions that failed to uninstall - if ($result === false) - { - // There was an error in uninstalling the package - $msgs[] = JText::sprintf('COM_INSTALLER_UNINSTALL_ERROR', $rowtype); - - continue; - } - - // Package uninstalled successfully - $msgs[] = JText::sprintf('COM_INSTALLER_UNINSTALL_SUCCESS', $rowtype); - $result = true; - - continue; - } - - // There was an error in uninstalling the package - $msgs[] = JText::sprintf('COM_INSTALLER_UNINSTALL_ERROR', $rowtype); - } - - $msg = implode('
', $msgs); - $app = JFactory::getApplication(); - $app->enqueueMessage($msg); - $this->setState('action', 'remove'); - $this->setState('name', $installer->get('name')); - $app->setUserState('com_installer.message', $installer->message); - $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); - - // Clear the cached extension data and menu cache - $this->cleanCache('_system', 0); - $this->cleanCache('_system', 1); - $this->cleanCache('com_modules', 0); - $this->cleanCache('com_modules', 1); - $this->cleanCache('com_plugins', 0); - $this->cleanCache('com_plugins', 1); - $this->cleanCache('mod_menu', 0); - $this->cleanCache('mod_menu', 1); - - return $result; - } - - /** - * Method to get the database query - * - * @return JDatabaseQuery The database query - * - * @since 1.6 - */ - protected function getListQuery() - { - $query = $this->getDbo()->getQuery(true) - ->select('*') - ->select('2*protected+(1-protected)*enabled AS status') - ->from('#__extensions') - ->where('state = 0'); - - // Process select filters. - $status = $this->getState('filter.status'); - $type = $this->getState('filter.type'); - $clientId = $this->getState('filter.client_id'); - $folder = $this->getState('filter.folder'); - - if ($status != '') - { - if ($status == '2') - { - $query->where('protected = 1'); - } - elseif ($status == '3') - { - $query->where('protected = 0'); - } - else - { - $query->where('protected = 0') - ->where('enabled = ' . (int) $status); - } - } - - if ($type) - { - $query->where('type = ' . $this->_db->quote($type)); - } - - if ($clientId != '') - { - $query->where('client_id = ' . (int) $clientId); - } - - if ($folder != '') - { - $query->where('folder = ' . $this->_db->quote($folder == '*' ? '' : $folder)); - } - - // Process search filter (extension id). - $search = $this->getState('filter.search'); - - if (!empty($search) && stripos($search, 'id:') === 0) - { - $query->where('extension_id = ' . (int) substr($search, 3)); - } - - // Note: The search for name, ordering and pagination are processed by the parent InstallerModel class (in extension.php). - - return $query; - } -} diff --git a/administrator/components/com_installer/models/update.php b/administrator/components/com_installer/models/update.php deleted file mode 100644 index a77fdd8ac8558..0000000000000 --- a/administrator/components/com_installer/models/update.php +++ /dev/null @@ -1,602 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); - $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); - $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); - - $app = JFactory::getApplication(); - $this->setState('message', $app->getUserState('com_installer.message')); - $this->setState('extension_message', $app->getUserState('com_installer.extension_message')); - $app->setUserState('com_installer.message', ''); - $app->setUserState('com_installer.extension_message', ''); - - parent::populateState($ordering, $direction); - } - - /** - * Method to get the database query - * - * @return JDatabaseQuery The database query - * - * @since 1.6 - */ - protected function getListQuery() - { - $db = $this->getDbo(); - - // Grab updates ignoring new installs - $query = $db->getQuery(true) - ->select('u.*') - ->select($db->quoteName('e.manifest_cache')) - ->from($db->quoteName('#__updates', 'u')) - ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON ' . $db->quoteName('e.extension_id') . ' = ' . $db->quoteName('u.extension_id')) - ->where($db->quoteName('u.extension_id') . ' != ' . $db->quote(0)); - - // Process select filters. - $clientId = $this->getState('filter.client_id'); - $type = $this->getState('filter.type'); - $folder = $this->getState('filter.folder'); - $extensionId = $this->getState('filter.extension_id'); - - if ($type) - { - $query->where($db->quoteName('u.type') . ' = ' . $db->quote($type)); - } - - if ($clientId != '') - { - $query->where($db->quoteName('u.client_id') . ' = ' . (int) $clientId); - } - - if ($folder != '' && in_array($type, array('plugin', 'library', ''))) - { - $query->where($db->quoteName('u.folder') . ' = ' . $db->quote($folder == '*' ? '' : $folder)); - } - - if ($extensionId) - { - $query->where($db->quoteName('u.extension_id') . ' = ' . $db->quote((int) $extensionId)); - } - else - { - $query->where($db->quoteName('u.extension_id') . ' != ' . $db->quote(0)) - ->where($db->quoteName('u.extension_id') . ' != ' . $db->quote(700)); - } - - // Process search filter. - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'eid:') !== false) - { - $query->where($db->quoteName('u.extension_id') . ' = ' . (int) substr($search, 4)); - } - else - { - if (stripos($search, 'uid:') !== false) - { - $query->where($db->quoteName('u.update_site_id') . ' = ' . (int) substr($search, 4)); - } - elseif (stripos($search, 'id:') !== false) - { - $query->where($db->quoteName('u.update_id') . ' = ' . (int) substr($search, 3)); - } - else - { - $query->where($db->quoteName('u.name') . ' LIKE ' . $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true)) . '%')); - } - } - } - - return $query; - } - - /** - * Translate a list of objects - * - * @param array &$items The array of objects - * - * @return array The array of translated objects - * - * @since 3.5 - */ - protected function translate(&$items) - { - foreach ($items as &$item) - { - $item->client_translated = $item->client_id ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); - $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 ?: JText::_('COM_INSTALLER_TYPE_NONAPPLICABLE'); - $item->install_type = $item->extension_id ? JText::_('COM_INSTALLER_MSG_UPDATE_UPDATE') : JText::_('COM_INSTALLER_NEW_INSTALL'); - } - - return $items; - } - - /** - * Returns an object list - * - * @param string $query The query - * @param int $limitstart Offset - * @param int $limit The number of records - * - * @return array - * - * @since 3.5 - */ - protected function _getList($query, $limitstart = 0, $limit = 0) - { - $db = $this->getDbo(); - $listOrder = $this->getState('list.ordering', 'u.name'); - $listDirn = $this->getState('list.direction', 'asc'); - - // Process ordering. - if (in_array($listOrder, array('client_translated', 'folder_translated', 'type_translated'))) - { - $db->setQuery($query); - $result = $db->loadObjectList(); - $this->translate($result); - $result = ArrayHelper::sortObjects($result, $listOrder, strtolower($listDirn) === 'desc' ? -1 : 1, true, true); - $total = count($result); - - if ($total < $limitstart) - { - $limitstart = 0; - $this->setState('list.start', 0); - } - - return array_slice($result, $limitstart, $limit ?: null); - } - else - { - $query->order($db->quoteName($listOrder) . ' ' . $db->escape($listDirn)); - - $result = parent::_getList($query, $limitstart, $limit); - $this->translate($result); - - return $result; - } - } - - /** - * Get the count of disabled update sites - * - * @return integer - * - * @since 3.4 - */ - public function getDisabledUpdateSites() - { - $db = $this->getDbo(); - - $query = $db->getQuery(true) - ->select('COUNT(*)') - ->from($db->quoteName('#__update_sites')) - ->where($db->quoteName('enabled') . ' = 0'); - - $db->setQuery($query); - - return $db->loadResult(); - } - - /** - * 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) - * - * @return boolean Result - * - * @since 1.6 - */ - public function findUpdates($eid = 0, $cache_timeout = 0, $minimum_stability = JUpdater::STABILITY_STABLE) - { - // Purge the updates list - $this->purge(); - - JUpdater::getInstance()->findUpdates($eid, $cache_timeout, $minimum_stability); - - return true; - } - - /** - * Removes all of the updates from the table. - * - * @return boolean result of operation - * - * @since 1.6 - */ - public function purge() - { - $db = $this->getDbo(); - - // Note: TRUNCATE is a DDL operation - // This may or may not mean depending on your database - $db->setQuery('TRUNCATE TABLE #__updates'); - - try - { - $db->execute(); - } - catch (JDatabaseExceptionExecuting $e) - { - $this->_message = JText::_('JLIB_INSTALLER_FAILED_TO_PURGE_UPDATES'); - - return false; - } - - // Reset the last update check timestamp - $query = $db->getQuery(true) - ->update($db->quoteName('#__update_sites')) - ->set($db->quoteName('last_check_timestamp') . ' = ' . $db->quote(0)); - $db->setQuery($query); - $db->execute(); - $this->_message = JText::_('JLIB_INSTALLER_PURGED_UPDATES'); - - return true; - } - - /** - * Enables any disabled rows in #__update_sites table - * - * @return boolean result of operation - * - * @since 1.6 - */ - public function enableSites() - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->update($db->quoteName('#__update_sites')) - ->set($db->quoteName('enabled') . ' = 1') - ->where($db->quoteName('enabled') . ' = 0'); - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (JDatabaseExceptionExecuting $e) - { - $this->_message .= JText::_('COM_INSTALLER_FAILED_TO_ENABLE_UPDATES'); - - return false; - } - - if ($rows = $db->getAffectedRows()) - { - $this->_message .= JText::plural('COM_INSTALLER_ENABLED_UPDATES', $rows); - } - - return true; - } - - /** - * Update function. - * - * 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} - * - * @return void - * - * @since 1.6 - */ - public function update($uids, $minimum_stability = JUpdater::STABILITY_STABLE) - { - $result = true; - - foreach ($uids as $uid) - { - $update = new JUpdate; - $instance = JTable::getInstance('update'); - $instance->load($uid); - $update->loadFromXml($instance->detailsurl, $minimum_stability); - $update->set('extra_query', $instance->extra_query); - - $this->preparePreUpdate($update, $instance); - - // Install sets state and enqueues messages - $res = $this->install($update); - - if ($res) - { - $instance->delete($uid); - } - - $result = $res & $result; - } - - // Clear the cached extension data and menu cache - $this->cleanCache('_system', 0); - $this->cleanCache('_system', 1); - $this->cleanCache('com_modules', 0); - $this->cleanCache('com_modules', 1); - $this->cleanCache('com_plugins', 0); - $this->cleanCache('com_plugins', 1); - $this->cleanCache('mod_menu', 0); - $this->cleanCache('mod_menu', 1); - - // Set the final state - $this->setState('result', $result); - } - - /** - * Handles the actual update installation. - * - * @param JUpdate $update An update definition - * - * @return boolean Result of install - * - * @since 1.6 - */ - private function install($update) - { - $app = JFactory::getApplication(); - - if (!isset($update->get('downloadurl')->_data)) - { - JError::raiseWarning('', JText::_('COM_INSTALLER_INVALID_EXTENSION_UPDATE')); - - return false; - } - - $url = $update->downloadurl->_data; - $sources = $update->get('downloadSources', array()); - - if ($extra_query = $update->get('extra_query')) - { - $url .= (strpos($url, '?') === false) ? '?' : '&'; - $url .= $extra_query; - } - - $mirror = 0; - - while (!($p_file = JInstallerHelper::downloadPackage($url)) && isset($sources[$mirror])) - { - $name = $sources[$mirror]; - $url = $name->url; - - if ($extra_query) - { - $url .= (strpos($url, '?') === false) ? '?' : '&'; - $url .= $extra_query; - } - - $mirror++; - } - - // Was the package downloaded? - if (!$p_file) - { - JError::raiseWarning('', JText::sprintf('COM_INSTALLER_PACKAGE_DOWNLOAD_FAILED', $url)); - - return false; - } - - $config = JFactory::getConfig(); - $tmp_dest = $config->get('tmp_path'); - - // Unpack the downloaded package file - $package = JInstallerHelper::unpack($tmp_dest . '/' . $p_file); - - // Get an installer instance - $installer = JInstaller::getInstance(); - $update->set('type', $package['type']); - - // 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']))); - $result = false; - } - else - { - // Package updated successfully - $msg = 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); - $app->setUserState('com_installer.message', $installer->message); - $app->setUserState('com_installer.extension_message', $installer->get('extension_message')); - - // Cleanup the install files - if (!is_file($package['packagefile'])) - { - $config = JFactory::getConfig(); - $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; - } - - JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); - - return $result; - } - - /** - * Method to get the row form. - * - * @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 mixed A JForm object on success, false on failure - * - * @since 2.5.2 - */ - public function getForm($data = array(), $loadData = true) - { - // Get the form. - JForm::addFormPath(JPATH_COMPONENT . '/models/forms'); - JForm::addFieldPath(JPATH_COMPONENT . '/models/fields'); - $form = JForm::getInstance('com_installer.update', 'update', array('load_data' => $loadData)); - - // Check for an error. - if ($form == false) - { - $this->setError($form->getMessage()); - - return false; - } - - // Check the session for previously entered form data. - $data = $this->loadFormData(); - - // Bind the form data if present. - if (!empty($data)) - { - $form->bind($data); - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 2.5.2 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState($this->context, array()); - - return $data; - } - - /** - * Method to add parameters to the update - * - * @param JUpdate $update An update definition - * @param JTableUpdate $table The update instance from the database - * - * @return void - * - * @since 3.7.0 - */ - protected function preparePreUpdate($update, $table) - { - jimport('joomla.filesystem.file'); - - switch ($table->type) - { - // Components could have a helper which adds additional data - case 'component': - $ename = str_replace('com_', '', $table->element); - $fname = $ename . '.php'; - $cname = ucfirst($ename) . 'Helper'; - - $path = JPATH_ADMINISTRATOR . '/components/' . $table->element . '/helpers/' . $fname; - - if (JFile::exists($path)) - { - require_once $path; - - if (class_exists($cname) && is_callable(array($cname, 'prepareUpdate'))) - { - call_user_func_array(array($cname, 'prepareUpdate'), array(&$update, &$table)); - } - } - - break; - - // Modules could have a helper which adds additional data - case 'module': - $cname = str_replace('_', '', $table->element) . 'Helper'; - $path = ($table->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/modules/' . $table->element . '/helper.php'; - - if (JFile::exists($path)) - { - require_once $path; - - if (class_exists($cname) && is_callable(array($cname, 'prepareUpdate'))) - { - call_user_func_array(array($cname, 'prepareUpdate'), array(&$update, &$table)); - } - } - - break; - - // If we have a plugin, we can use the plugin trigger "onInstallerBeforePackageDownload" - // But we should make sure, that our plugin is loaded, so we don't need a second "installer" plugin - case 'plugin': - $cname = str_replace('plg_', '', $table->element); - JPluginHelper::importPlugin($table->folder, $cname); - break; - } - } -} diff --git a/administrator/components/com_installer/models/updatesites.php b/administrator/components/com_installer/models/updatesites.php deleted file mode 100644 index 10ba2f3937fd4..0000000000000 --- a/administrator/components/com_installer/models/updatesites.php +++ /dev/null @@ -1,469 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.client_id', $this->getUserStateFromRequest($this->context . '.filter.client_id', 'filter_client_id', null, 'int')); - $this->setState('filter.enabled', $this->getUserStateFromRequest($this->context . '.filter.enabled', 'filter_enabled', '', 'string')); - $this->setState('filter.type', $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type', '', 'string')); - $this->setState('filter.folder', $this->getUserStateFromRequest($this->context . '.filter.folder', 'filter_folder', '', 'string')); - - parent::populateState($ordering, $direction); - } - - /** - * Enable/Disable an extension. - * - * @param array &$eid Extension ids to un/publish - * @param int $value Publish value - * - * @return boolean True on success - * - * @since 3.4 - * - * @throws Exception on ACL error - */ - public function publish(&$eid = array(), $value = 1) - { - if (!JFactory::getUser()->authorise('core.edit.state', 'com_installer')) - { - throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 403); - } - - $result = true; - - // Ensure eid is an array of extension ids - if (!is_array($eid)) - { - $eid = array($eid); - } - - // Get a table object for the extension type - $table = JTable::getInstance('Updatesite'); - - // Enable the update site in the table and store it in the database - foreach ($eid as $i => $id) - { - $table->load($id); - $table->enabled = $value; - - if (!$table->store()) - { - $this->setError($table->getError()); - $result = false; - } - } - - return $result; - } - - /** - * Deletes an update site. - * - * @param array $ids Extension ids to delete. - * - * @return void - * - * @since 3.6 - * - * @throws Exception on ACL error - */ - public function delete($ids = array()) - { - if (!JFactory::getUser()->authorise('core.delete', 'com_installer')) - { - throw new Exception(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 403); - } - - // Ensure eid is an array of extension ids - if (!is_array($ids)) - { - $ids = array($ids); - } - - $db = JFactory::getDbo(); - $app = JFactory::getApplication(); - - $count = 0; - - // Gets the update site names. - $query = $db->getQuery(true) - ->select($db->qn(array('update_site_id', 'name'))) - ->from($db->qn('#__update_sites')) - ->where($db->qn('update_site_id') . ' IN (' . implode(', ', $ids) . ')'); - $db->setQuery($query); - $updateSitesNames = $db->loadObjectList('update_site_id'); - - // Gets Joomla core update sites Ids. - $joomlaUpdateSitesIds = $this->getJoomlaUpdateSitesIds(0); - - // Enable the update site in the table and store it in the database - foreach ($ids as $i => $id) - { - // Don't allow to delete Joomla Core update sites. - if (in_array((int) $id, $joomlaUpdateSitesIds)) - { - $app->enqueueMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATESITES_DELETE_CANNOT_DELETE', $updateSitesNames[$id]->name), 'error'); - continue; - } - - // Delete the update site from all tables. - try - { - $query = $db->getQuery(true) - ->delete($db->qn('#__update_sites')) - ->where($db->qn('update_site_id') . ' = ' . (int) $id); - $db->setQuery($query); - $db->execute(); - - $query = $db->getQuery(true) - ->delete($db->qn('#__update_sites_extensions')) - ->where($db->qn('update_site_id') . ' = ' . (int) $id); - $db->setQuery($query); - $db->execute(); - - $query = $db->getQuery(true) - ->delete($db->qn('#__updates')) - ->where($db->qn('update_site_id') . ' = ' . (int) $id); - $db->setQuery($query); - $db->execute(); - - $count++; - } - catch (RuntimeException $e) - { - $app->enqueueMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATESITES_DELETE_ERROR', $updateSitesNames[$id]->name, $e->getMessage()), 'error'); - } - } - - if ($count > 0) - { - $app->enqueueMessage(JText::plural('COM_INSTALLER_MSG_UPDATESITES_N_DELETE_UPDATESITES_DELETED', $count), 'message'); - } - } - - /** - * Rebuild update sites tables. - * - * @return void - * - * @since 3.6 - * - * @throws Exception on ACL error - */ - public function rebuild() - { - if (!JFactory::getUser()->authorise('core.admin', 'com_installer')) - { - throw new Exception(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_NOT_PERMITTED'), 403); - } - - $db = JFactory::getDbo(); - $app = JFactory::getApplication(); - - // Check if Joomla Extension plugin is enabled. - if (!JPluginHelper::isEnabled('extension', 'joomla')) - { - $query = $db->getQuery(true) - ->select($db->quoteName('extension_id')) - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) - ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')) - ->where($db->quoteName('folder') . ' = ' . $db->quote('extension')); - $db->setQuery($query); - - $pluginId = (int) $db->loadResult(); - - $link = JRoute::_('index.php?option=com_plugins&task=plugin.edit&extension_id=' . $pluginId); - $app->enqueueMessage(JText::sprintf('COM_INSTALLER_MSG_UPDATESITES_REBUILD_EXTENSION_PLUGIN_NOT_ENABLED', $link), 'error'); - - return; - } - - $clients = array(JPATH_SITE, JPATH_ADMINISTRATOR); - $extensionGroupFolders = array('components', 'modules', 'plugins', 'templates', 'language', 'manifests'); - - $pathsToSearch = array(); - - // Identifies which folders to search for manifest files. - foreach ($clients as $clientPath) - { - foreach ($extensionGroupFolders as $extensionGroupFolderName) - { - // Components, modules, plugins, templates, languages and manifest (files, libraries, etc) - if ($extensionGroupFolderName != 'plugins') - { - foreach (glob($clientPath . '/' . $extensionGroupFolderName . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $extensionFolderPath) - { - $pathsToSearch[] = $extensionFolderPath; - } - } - - // Plugins (another directory level is needed) - else - { - foreach (glob($clientPath . '/' . $extensionGroupFolderName . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $pluginGroupFolderPath) - { - foreach (glob($pluginGroupFolderPath . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $extensionFolderPath) - { - $pathsToSearch[] = $extensionFolderPath; - } - } - } - } - } - - // Gets Joomla core update sites Ids. - $joomlaUpdateSitesIds = implode(', ', $this->getJoomlaUpdateSitesIds(0)); - - // Delete from all tables (except joomla core update sites). - $query = $db->getQuery(true) - ->delete($db->quoteName('#__update_sites')) - ->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); - $db->setQuery($query); - $db->execute(); - - $query = $db->getQuery(true) - ->delete($db->quoteName('#__update_sites_extensions')) - ->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); - $db->setQuery($query); - $db->execute(); - - $query = $db->getQuery(true) - ->delete($db->quoteName('#__updates')) - ->where($db->quoteName('update_site_id') . ' NOT IN (' . $joomlaUpdateSitesIds . ')'); - $db->setQuery($query); - $db->execute(); - - $count = 0; - - // Gets Joomla core extension Ids. - $joomlaCoreExtensionIds = implode(', ', $this->getJoomlaUpdateSitesIds(1)); - - // Search for updateservers in manifest files inside the folders to search. - foreach ($pathsToSearch as $extensionFolderPath) - { - $tmpInstaller = new JInstaller; - - $tmpInstaller->setPath('source', $extensionFolderPath); - - // Main folder manifests (higher priority) - $parentXmlfiles = JFolder::files($tmpInstaller->getPath('source'), '.xml$', false, true); - - // Search for children manifests (lower priority) - $allXmlFiles = JFolder::files($tmpInstaller->getPath('source'), '.xml$', 1, true); - - // Create an unique array of files ordered by priority - $xmlfiles = array_unique(array_merge($parentXmlfiles, $allXmlFiles)); - - if (!empty($xmlfiles)) - { - foreach ($xmlfiles as $file) - { - // Is it a valid Joomla installation manifest file? - $manifest = $tmpInstaller->isManifest($file); - - if (!is_null($manifest)) - { - // Search if the extension exists in the extensions table. Excluding joomla core extensions (id < 10000) and discovered 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('type') . ' = ' . $db->quote($manifest['type'])) - ->where($db->quoteName('extension_id') . ' NOT IN (' . $joomlaCoreExtensionIds . ')') - ->where($db->quoteName('state') . ' != -1'); - $db->setQuery($query); - - $eid = (int) $db->loadResult(); - - if ($eid && $manifest->updateservers) - { - // Set the manifest object and path - $tmpInstaller->manifest = $manifest; - $tmpInstaller->setPath('manifest', $file); - - // Load the extension plugin (if not loaded yet). - JPluginHelper::importPlugin('extension', 'joomla'); - - // Fire the onExtensionAfterUpdate - JEventDispatcher::getInstance()->trigger('onExtensionAfterUpdate', array('installer' => $tmpInstaller, 'eid' => $eid)); - - $count++; - } - } - } - } - } - - if ($count > 0) - { - $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_SUCCESS'), 'message'); - } - else - { - $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_UPDATESITES_REBUILD_MESSAGE'), 'message'); - } - } - - /** - * Fetch the Joomla update sites ids. - * - * @param integer $column Column to return. 0 for update site ids, 1 for extension ids. - * - * @return array Array with joomla core update site ids. - * - * @since 3.6.0 - */ - protected function getJoomlaUpdateSitesIds($column = 0) - { - $db = JFactory::getDbo(); - - // Fetch the Joomla core update sites ids and their extension ids. We search for all except the core joomla extension with update sites. - $query = $db->getQuery(true) - ->select($db->quoteName(array('use.update_site_id', 'e.extension_id'))) - ->from($db->quoteName('#__update_sites_extensions', 'use')) - ->join('LEFT', $db->quoteName('#__update_sites', 'us') . ' ON ' . $db->qn('us.update_site_id') . ' = ' . $db->qn('use.update_site_id')) - ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON ' . $db->qn('e.extension_id') . ' = ' . $db->qn('use.extension_id')) - ->where('(' - . '(' . $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); - } - - /** - * Method to get the database query - * - * @return JDatabaseQuery The database query - * - * @since 3.4 - */ - protected function getListQuery() - { - $query = JFactory::getDbo()->getQuery(true) - ->select( - array( - 's.update_site_id', - 's.name AS update_site_name', - 's.type AS update_site_type', - 's.location', - 's.enabled', - 'e.extension_id', - 'e.name', - 'e.type', - 'e.element', - 'e.folder', - 'e.client_id', - 'e.state', - 'e.manifest_cache', - ) - ) - ->from('#__update_sites AS s') - ->innerJoin('#__update_sites_extensions AS se ON (se.update_site_id = s.update_site_id)') - ->innerJoin('#__extensions AS e ON (e.extension_id = se.extension_id)') - ->where('state = 0'); - - // Process select filters. - $enabled = $this->getState('filter.enabled'); - $type = $this->getState('filter.type'); - $clientId = $this->getState('filter.client_id'); - $folder = $this->getState('filter.folder'); - - if ($enabled != '') - { - $query->where('s.enabled = ' . (int) $enabled); - } - - if ($type) - { - $query->where('e.type = ' . $this->_db->quote($type)); - } - - if ($clientId != '') - { - $query->where('e.client_id = ' . (int) $clientId); - } - - if ($folder != '' && in_array($type, array('plugin', 'library', ''))) - { - $query->where('e.folder = ' . $this->_db->quote($folder == '*' ? '' : $folder)); - } - - // Process search filter (update site id). - $search = $this->getState('filter.search'); - - if (!empty($search) && stripos($search, 'id:') === 0) - { - $query->where('s.update_site_id = ' . (int) substr($search, 3)); - } - - // Note: The search for name, ordering and pagination are processed by the parent InstallerModel class (in extension.php). - - return $query; - } -} diff --git a/administrator/components/com_installer/models/warnings.php b/administrator/components/com_installer/models/warnings.php deleted file mode 100644 index 6f7856a674e89..0000000000000 --- a/administrator/components/com_installer/models/warnings.php +++ /dev/null @@ -1,169 +0,0 @@ - JText::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADSDISABLED'), - 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_FILEUPLOADISDISABLEDDESC')); - } - - $upload_dir = ini_get('upload_tmp_dir'); - - if (!$upload_dir) - { - $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), - 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSETDESC')); - } - else - { - if (!is_writeable($upload_dir)) - { - $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLE'), - 'description' => JText::sprintf('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLEDESC', $upload_dir)); - } - } - - $config = JFactory::getConfig(); - $tmp_path = $config->get('tmp_path'); - - if (!$tmp_path) - { - $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSET'), - 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSETDESC')); - } - else - { - if (!is_writeable($tmp_path)) - { - $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLE'), - 'description' => JText::sprintf('COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTWRITEABLEDESC', $tmp_path)); - } - } - - $memory_limit = $this->return_bytes(ini_get('memory_limit')); - - if ($memory_limit < (8 * 1024 * 1024) && $memory_limit != -1) - { - // 8MB - $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYWARN'), - 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_LOWMEMORYDESC')); - } - elseif ($memory_limit < (16 * 1024 * 1024) && $memory_limit != -1) - { - // 16MB - $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYWARN'), - 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_MEDMEMORYDESC')); - } - - $post_max_size = $this->return_bytes(ini_get('post_max_size')); - $upload_max_filesize = $this->return_bytes(ini_get('upload_max_filesize')); - - if ($post_max_size < $upload_max_filesize) - { - $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOST'), - 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_UPLOADBIGGERTHANPOSTDESC')); - } - - if ($post_max_size < (8 * 1024 * 1024)) // 8MB - { - $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZE'), - 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLPOSTSIZEDESC')); - } - - if ($upload_max_filesize < (8 * 1024 * 1024)) // 8MB - { - $messages[] = array('message' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), - 'description' => JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZEDESC')); - } - - return $messages; - } -} diff --git a/administrator/components/com_installer/services/provider.php b/administrator/components/com_installer/services/provider.php new file mode 100644 index 0000000000000..97f58264ced96 --- /dev/null +++ b/administrator/components/com_installer/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Installer')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Installer')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_installer/tmpl/database/default.php b/administrator/components/com_installer/tmpl/database/default.php new file mode 100644 index 0000000000000..f79bc41d661f9 --- /dev/null +++ b/administrator/components/com_installer/tmpl/database/default.php @@ -0,0 +1,134 @@ +escape($this->state->get('list.ordering')); +$listDirection = $this->escape($this->state->get('list.direction')); + +?> +
+
+
+
+ sidebar; ?> +
+
+
+
+ $this)); ?> + changeSet)) : ?> + + + + + + + + + + + + + + + + + + changeSet as $i => $item) : ?> + + manifest_cache); ?> + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ extension_id); ?> + + + + client_translated; ?> + + type_translated; ?> + + + + + + version_id; ?> + + version; ?> + + folder_translated; ?> + + extension_id; ?> +
+ + + pagination->getListFooter(); ?> + + +
+ + + +
+
+
+
+
diff --git a/administrator/components/com_installer/views/database/tmpl/default.xml b/administrator/components/com_installer/tmpl/database/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_installer/views/database/tmpl/default.xml rename to administrator/components/com_installer/tmpl/database/default.xml diff --git a/administrator/components/com_installer/tmpl/discover/default.php b/administrator/components/com_installer/tmpl/discover/default.php new file mode 100644 index 0000000000000..25f06a3e72827 --- /dev/null +++ b/administrator/components/com_installer/tmpl/discover/default.php @@ -0,0 +1,123 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+
+
+ sidebar; ?> +
+
+
+ showMessage) : ?> + loadTemplate('message'); ?> + + ftp) : ?> + loadTemplate('ftp'); ?> + + $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ extension_id); ?> + + + + client_translated; ?> + + type_translated; ?> + + version != '' ? $item->version : ' '; ?> + + creationDate != '' ? $item->creationDate : ' '; ?> + + + author != '' ? $item->author : ' '; ?> + + + folder_translated; ?> + + extension_id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
+
diff --git a/administrator/components/com_installer/views/discover/tmpl/default.xml b/administrator/components/com_installer/tmpl/discover/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_installer/views/discover/tmpl/default.xml rename to administrator/components/com_installer/tmpl/discover/default.xml diff --git a/administrator/components/com_installer/tmpl/discover/default_item.php b/administrator/components/com_installer/tmpl/discover/default_item.php new file mode 100644 index 0000000000000..829dbffbd3806 --- /dev/null +++ b/administrator/components/com_installer/tmpl/discover/default_item.php @@ -0,0 +1,39 @@ + +item->style; ?>> + + item->cbd; ?>> + item->name; ?> + + + item->type ?> + + + item->element) : ?> + X + + item->img, $this->item->alt, array('title' => $this->item->action)); ?> + + + item->folder != '' ? $this->item->folder : 'N/A'; ?> + item->client != '' ? $this->item->client : 'N/A'; ?> + + + item->author != '' ? $this->item->author : ' '; ?> + + + diff --git a/administrator/components/com_installer/tmpl/install/default.php b/administrator/components/com_installer/tmpl/install/default.php new file mode 100644 index 0000000000000..9907b49ca4aa3 --- /dev/null +++ b/administrator/components/com_installer/tmpl/install/default.php @@ -0,0 +1,78 @@ + + +
+ +
+
+
+ sidebar; ?> +
+
+
+ + showMessage) : ?> + loadTemplate('message'); ?> + + + triggerEvent('onInstallerViewBeforeFirstTab', array()); ?> + triggerEvent('onInstallerAddInstallationTab', array()); ?> + $tabs[0]['name'])); ?> + + + +
+ +
+ + + + triggerEvent('onInstallerViewAfterLastTab', array()); ?> + + + enqueueMessage(Text::_('COM_INSTALLER_NO_INSTALLATION_PLUGINS_FOUND'), 'warning'); ?> + + + ftp) : ?> + + loadTemplate('ftp'); ?> + + + + + + + + +
+
+
+
+
+
diff --git a/administrator/components/com_installer/views/install/tmpl/default.xml b/administrator/components/com_installer/tmpl/install/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_installer/views/install/tmpl/default.xml rename to administrator/components/com_installer/tmpl/install/default.xml diff --git a/administrator/components/com_installer/tmpl/installer/default_ftp.php b/administrator/components/com_installer/tmpl/installer/default_ftp.php new file mode 100644 index 0000000000000..efc78402c7aea --- /dev/null +++ b/administrator/components/com_installer/tmpl/installer/default_ftp.php @@ -0,0 +1,45 @@ + +
+ + + + + ftp instanceof Exception) : ?> +

ftp->getMessage()); ?>

+ + + + + + + + + + + + + +
+ + + +
+ + + +
+ +
diff --git a/administrator/components/com_installer/views/default/tmpl/default_message.php b/administrator/components/com_installer/tmpl/installer/default_message.php similarity index 83% rename from administrator/components/com_installer/views/default/tmpl/default_message.php rename to administrator/components/com_installer/tmpl/installer/default_message.php index ed015443bd505..d7a25f6592d99 100644 --- a/administrator/components/com_installer/views/default/tmpl/default_message.php +++ b/administrator/components/com_installer/tmpl/installer/default_message.php @@ -15,15 +15,15 @@ ?> -
-
+
+
-
-
+
+
diff --git a/administrator/components/com_installer/tmpl/languages/default.php b/administrator/components/com_installer/tmpl/languages/default.php new file mode 100644 index 0000000000000..42057be51af28 --- /dev/null +++ b/administrator/components/com_installer/tmpl/languages/default.php @@ -0,0 +1,105 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+
+
+ sidebar; ?> +
+
+
+ $this, 'options' => array('filterButton' => false))); ?> + items)) : ?> + + + + + + + + + + + + + + getShortVersion()); + $i = 0; + foreach ($this->items as $language) : + preg_match('#^pkg_([a-z]{2,3}-[A-Z]{2})$#', $language->element, $element); + $language->code = $element[1]; + ?> + + + + + + + + + + +
+ + + + + + + +
+ installedLang[0][$language->code]) || isset($this->installedLang[1][$language->code])) ? 'REINSTALL' : 'INSTALL'; ?> + detailsurl . '\'; Joomla.submitbutton(\'install.install\');'; ?> + + + name; ?> + + code; ?> + + + + version, 0, 3) != $minorVersion || substr($language->version, 0, 5) != $currentShortVersion) : ?> + version; ?> + + version; ?> + + + detailsurl; ?> +
+ + + pagination->getListFooter(); ?> + + + + + + + + +
+
+
+
+
diff --git a/administrator/components/com_installer/views/languages/tmpl/default.xml b/administrator/components/com_installer/tmpl/languages/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_installer/views/languages/tmpl/default.xml rename to administrator/components/com_installer/tmpl/languages/default.xml diff --git a/administrator/components/com_installer/tmpl/manage/default.php b/administrator/components/com_installer/tmpl/manage/default.php new file mode 100644 index 0000000000000..4024519b2e52d --- /dev/null +++ b/administrator/components/com_installer/tmpl/manage/default.php @@ -0,0 +1,140 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+
+
+ sidebar; ?> +
+
+
+ showMessage) : ?> + loadTemplate('message'); ?> + + ftp) : ?> + loadTemplate('ftp'); ?> + + $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ extension_id); ?> + + element) : ?> + X + + status, $i, $item->status < 2, 'cb'); ?> + + + + + client_translated; ?> + + type_translated; ?> + + version != '' ? $item->version : ' '; ?> + + creationDate != '' ? $item->creationDate : ' '; ?> + + + author != '' ? $item->author : ' '; ?> + + + folder_translated; ?> + + package_id ?: ' '; ?> + + extension_id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
+
diff --git a/administrator/components/com_installer/views/manage/tmpl/default.xml b/administrator/components/com_installer/tmpl/manage/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_installer/views/manage/tmpl/default.xml rename to administrator/components/com_installer/tmpl/manage/default.xml diff --git a/administrator/components/com_installer/tmpl/update/default.php b/administrator/components/com_installer/tmpl/update/default.php new file mode 100644 index 0000000000000..a95b32e00ffc5 --- /dev/null +++ b/administrator/components/com_installer/tmpl/update/default.php @@ -0,0 +1,134 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+
+
+ sidebar; ?> +
+
+
+ showMessage) : ?> + loadTemplate('message'); ?> + + + ftp) : ?> + loadTemplate('ftp'); ?> + + $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + client_id ? Text::_('JADMINISTRATOR') : Text::_('JSITE'); + $manifest = json_decode($item->manifest_cache); + $current_version = $manifest->version ?? Text::_('JLIB_UNKNOWN'); + ?> + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ update_id); ?> + + + + client_translated; ?> + + type_translated; ?> + + current_version; ?> + + version; ?> + + folder_translated; ?> + + install_type; ?> + + + detailsurl; ?> + infourl)) : ?> +
+ escape($item->infourl); ?> + +
+
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
+
diff --git a/administrator/components/com_installer/views/update/tmpl/default.xml b/administrator/components/com_installer/tmpl/update/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_installer/views/update/tmpl/default.xml rename to administrator/components/com_installer/tmpl/update/default.xml diff --git a/administrator/components/com_installer/tmpl/updatesites/default.php b/administrator/components/com_installer/tmpl/updatesites/default.php new file mode 100644 index 0000000000000..550b97aab1535 --- /dev/null +++ b/administrator/components/com_installer/tmpl/updatesites/default.php @@ -0,0 +1,118 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ update_site_id); ?> + + element) : ?> + X + + enabled, $i, $item->enabled < 2, 'cb'); ?> + + + + + + name; ?> + + + client_translated; ?> + + type_translated; ?> + + folder_translated; ?> + + update_site_id; ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
+
diff --git a/administrator/components/com_installer/views/updatesites/tmpl/default.xml b/administrator/components/com_installer/tmpl/updatesites/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_installer/views/updatesites/tmpl/default.xml rename to administrator/components/com_installer/tmpl/updatesites/default.xml diff --git a/administrator/components/com_installer/tmpl/warnings/default.php b/administrator/components/com_installer/tmpl/warnings/default.php new file mode 100644 index 0000000000000..768f6b2985022 --- /dev/null +++ b/administrator/components/com_installer/tmpl/warnings/default.php @@ -0,0 +1,50 @@ + +
+
+
+
+ sidebar; ?> +
+
+
+ messages)) : ?> + messages as $message) : ?> + +

+

+
+ + +

+

+
+ + +

+

+
+ +
+ + +
+
+
+
+
+
diff --git a/administrator/components/com_installer/views/warnings/tmpl/default.xml b/administrator/components/com_installer/tmpl/warnings/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_installer/views/warnings/tmpl/default.xml rename to administrator/components/com_installer/tmpl/warnings/default.xml diff --git a/administrator/components/com_installer/views/database/tmpl/default.php b/administrator/components/com_installer/views/database/tmpl/default.php deleted file mode 100644 index ee591b46645f7..0000000000000 --- a/administrator/components/com_installer/views/database/tmpl/default.php +++ /dev/null @@ -1,77 +0,0 @@ - -
-
- - sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - errorCount === 0) : ?> - 'other')); ?> - - 'problems')); ?> - errorCount)); ?> -
-
    - filterParams) : ?> -
  • - - - schemaVersion != $this->changeSet->getSchema()) : ?> -
  • schemaVersion, $this->changeSet->getSchema()); ?>
  • - - - updateVersion, JVERSION) != 0) : ?> -
  • updateVersion, JVERSION); ?>
  • - - - errors as $line => $error) : ?> - 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] : ' '; - $message = JText::sprintf($key, $file, $msg0, $msg1, $msg2); ?> -
  • - -
-
- - - -
-
-
    -
  • schemaVersion); ?>
  • -
  • updateVersion); ?>
  • -
  • name); ?>
  • -
  • results['ok'])); ?>
  • -
  • results['skipped'])); ?>
  • -
-
-
- - - - - - -
- -
diff --git a/administrator/components/com_installer/views/database/view.html.php b/administrator/components/com_installer/views/database/view.html.php deleted file mode 100644 index 392f3dc0861d7..0000000000000 --- a/administrator/components/com_installer/views/database/view.html.php +++ /dev/null @@ -1,92 +0,0 @@ -state = $this->get('State'); - $this->changeSet = $this->get('Items'); - $this->errors = $this->changeSet->check(); - $this->results = $this->changeSet->getStatus(); - $this->schemaVersion = $this->get('SchemaVersion'); - $this->updateVersion = $this->get('UpdateVersion'); - $this->filterParams = $this->get('DefaultTextFilters'); - $this->schemaVersion = $this->schemaVersion ?: JText::_('JNONE'); - $this->updateVersion = $this->updateVersion ?: JText::_('JNONE'); - $this->pagination = $this->get('Pagination'); - $this->errorCount = count($this->errors); - - if ($this->schemaVersion != $this->changeSet->getSchema()) - { - $this->errorCount++; - } - - if (!$this->filterParams) - { - $this->errorCount++; - } - - if (version_compare($this->updateVersion, JVERSION) != 0) - { - $this->errorCount++; - } - - if ($this->errorCount === 0) - { - $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DATABASE_OK'), 'notice'); - } - else - { - $app->enqueueMessage(JText::_('COM_INSTALLER_MSG_DATABASE_ERRORS'), 'warning'); - } - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - /* - * Set toolbar items for the page. - */ - JToolbarHelper::custom('database.fix', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_DATABASE_FIX', false); - JToolbarHelper::divider(); - parent::addToolbar(); - JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_DATABASE'); - } -} diff --git a/administrator/components/com_installer/views/default/tmpl/default_ftp.php b/administrator/components/com_installer/views/default/tmpl/default_ftp.php deleted file mode 100644 index 30b834dbade8f..0000000000000 --- a/administrator/components/com_installer/views/default/tmpl/default_ftp.php +++ /dev/null @@ -1,42 +0,0 @@ - -
- - - - - ftp instanceof Exception) : ?> -

ftp->getMessage()); ?>

- - - - - - - - - - - - - -
- - - -
- - - -
- -
diff --git a/administrator/components/com_installer/views/default/view.php b/administrator/components/com_installer/views/default/view.php deleted file mode 100644 index a95d5cac0aa35..0000000000000 --- a/administrator/components/com_installer/views/default/view.php +++ /dev/null @@ -1,86 +0,0 @@ -_addPath('template', $this->_basePath . '/views/default/tmpl'); - $this->_addPath('template', JPATH_THEMES . '/' . $app->getTemplate() . '/html/com_installer/default'); - } - - /** - * Display the view. - * - * @param string $tpl Template - * - * @return void - * - * @since 1.5 - */ - public function display($tpl = null) - { - // Get data from the model. - $state = $this->get('State'); - - // Are there messages to display? - $showMessage = false; - - if (is_object($state)) - { - $message1 = $state->get('message'); - $message2 = $state->get('extension_message'); - $showMessage = ($message1 || $message2); - } - - $this->showMessage = $showMessage; - $this->state = &$state; - - $this->addToolbar(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_installer'); - JToolbarHelper::title(JText::_('COM_INSTALLER_HEADER_' . $this->getName()), 'puzzle install'); - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_installer'); - JToolbarHelper::divider(); - } - - // Render side bar. - $this->sidebar = JHtmlSidebar::render(); - } -} diff --git a/administrator/components/com_installer/views/discover/tmpl/default.php b/administrator/components/com_installer/views/discover/tmpl/default.php deleted file mode 100644 index 164e4da354b67..0000000000000 --- a/administrator/components/com_installer/views/discover/tmpl/default.php +++ /dev/null @@ -1,127 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
-
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - showMessage) : ?> - loadTemplate('message'); ?> - - ftp) : ?> - loadTemplate('ftp'); ?> - - $this)); ?> -
-
- -
- items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - - - - items as $i => $item) : ?> - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
pagination->getListFooter(); ?>
- extension_id); ?> - - - - client_translated; ?> - - type_translated; ?> - - version != '' ? $item->version : ' '; ?> - - creationDate != '' ? $item->creationDate : ' '; ?> - - - author != '' ? $item->author : ' '; ?> - - - folder_translated; ?> - - extension_id; ?> -
- - - - -
- -
diff --git a/administrator/components/com_installer/views/discover/tmpl/default_item.php b/administrator/components/com_installer/views/discover/tmpl/default_item.php deleted file mode 100644 index aa3789f736567..0000000000000 --- a/administrator/components/com_installer/views/discover/tmpl/default_item.php +++ /dev/null @@ -1,35 +0,0 @@ - -item->style; ?>> - - item->cbd; ?> /> - - item->name; ?> - - - item->type ?> - - - item->element) : ?> - X - - item->img, $this->item->alt, array('title' => $this->item->action)); ?> - - - item->folder != '' ? $this->item->folder : 'N/A'; ?> - item->client != '' ? $this->item->client : 'N/A'; ?> - - - item->author != '' ? $this->item->author : ' '; ?> - - - diff --git a/administrator/components/com_installer/views/discover/view.html.php b/administrator/components/com_installer/views/discover/view.html.php deleted file mode 100644 index 906928f683fce..0000000000000 --- a/administrator/components/com_installer/views/discover/view.html.php +++ /dev/null @@ -1,97 +0,0 @@ -checkExtensions()) - { - $this->getModel('discover')->discover(); - } - - // Get data from the model. - $this->state = $this->get('State'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $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); - } - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 3.1 - */ - protected function addToolbar() - { - /* - * Set toolbar items for the page. - */ - JToolbarHelper::custom('discover.install', 'upload', 'upload', 'JTOOLBAR_INSTALL', true); - JToolbarHelper::custom('discover.refresh', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_DISCOVER', false); - JToolbarHelper::divider(); - - JHtmlSidebar::setAction('index.php?option=com_installer&view=discover'); - - parent::addToolbar(); - JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_DISCOVER'); - } - - /** - * Check extensions. - * - * Checks uninstalled extensions in extensions table. - * - * @return boolean True if there are discovered extensions on the database. - * - * @since 3.5 - */ - public function checkExtensions() - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('*') - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('state') . ' = -1'); - $db->setQuery($query); - $discoveredExtensions = $db->loadObjectList(); - - return (count($discoveredExtensions) === 0) ? false : true; - } -} diff --git a/administrator/components/com_installer/views/install/tmpl/default.php b/administrator/components/com_installer/views/install/tmpl/default.php deleted file mode 100644 index bfc386882c342..0000000000000 --- a/administrator/components/com_installer/views/install/tmpl/default.php +++ /dev/null @@ -1,163 +0,0 @@ -addScriptDeclaration( - ' - Joomla.submitbutton4 = function() { - var form = document.getElementById("adminForm"); - - // do field validation - if (form.install_url.value == "" || form.install_url.value == "http://" || form.install_url.value == "https://") { - alert("' . JText::_('COM_INSTALLER_MSG_INSTALL_ENTER_A_URL', true) . '"); - } - else - { - JoomlaInstaller.showLoading(); - - form.installtype.value = "url"; - form.submit(); - } - }; - - Joomla.submitbuttonInstallWebInstaller = function() { - var form = document.getElementById("adminForm"); - - form.install_url.value = "https://appscdn.joomla.org/webapps/jedapps/webinstaller.xml"; - - Joomla.submitbutton4(); - }; - - // Add spindle-wheel for installations: - jQuery(document).ready(function($) { - var outerDiv = $("#installer-install"); - - JoomlaInstaller.getLoadingOverlay() - .css("top", outerDiv.position().top - $(window).scrollTop()) - .css("left", "0") - .css("width", "100%") - .css("height", "100%") - .css("display", "none") - .css("margin-top", "-10px"); - }); - - var JoomlaInstaller = { - getLoadingOverlay: function () { - return jQuery("#loading"); - }, - showLoading: function () { - this.getLoadingOverlay().css("display", "block"); - }, - hideLoading: function () { - this.getLoadingOverlay().css("display", "none"); - } - }; - ' -); - -JFactory::getDocument()->addStyleDeclaration( - ' - #loading { - background: rgba(255, 255, 255, .8) url(\'' . JHtml::_('image', 'jui/ajax-loader.gif', '', null, true, true) . '\') 50% 15% no-repeat; - position: fixed; - opacity: 0.8; - -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity = 80); - filter: alpha(opacity = 80); - overflow: hidden; - } - ' -); - -?> - - - -
-
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - - showMessage) : ?> - loadTemplate('message'); ?> - showJedAndWebInstaller) : ?> -
- ' . 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')) . '"' - ); - ?> -

-

- -
- - - - trigger('onInstallerViewBeforeFirstTab', array()); ?> - - trigger('onInstallerAddInstallationTab', array()); ?> - - -
- -
- - - - trigger('onInstallerViewAfterLastTab', array()); ?> - - - enqueueMessage(JText::_('COM_INSTALLER_NO_INSTALLATION_PLUGINS_FOUND'), 'warning'); ?> - - - ftp) : ?> - - loadTemplate('ftp'); ?> - - - - - - - - -
- -
-
diff --git a/administrator/components/com_installer/views/install/view.html.php b/administrator/components/com_installer/views/install/view.html.php deleted file mode 100644 index 0fbd0b052655d..0000000000000 --- a/administrator/components/com_installer/views/install/view.html.php +++ /dev/null @@ -1,61 +0,0 @@ -first = ''; - $state = $this->get('state'); - - $this->paths = &$paths; - $this->state = &$state; - - $this->showJedAndWebInstaller = JComponentHelper::getParams('com_installer')->get('show_jed_info', 1); - - JPluginHelper::importPlugin('installer'); - - $dispatcher = JEventDispatcher::getInstance(); - $dispatcher->trigger('onInstallerBeforeDisplay', array(&$this->showJedAndWebInstaller, $this)); - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - parent::addToolbar(); - JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_INSTALL'); - } -} diff --git a/administrator/components/com_installer/views/languages/tmpl/default.php b/administrator/components/com_installer/views/languages/tmpl/default.php deleted file mode 100644 index 1ee670c771f48..0000000000000 --- a/administrator/components/com_installer/views/languages/tmpl/default.php +++ /dev/null @@ -1,108 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
-
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this, 'options' => array('filterButton' => false))); ?> -
- items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - getShortVersion()); - $i = 0; - foreach ($this->items as $language) : - preg_match('#^pkg_([a-z]{2,3}-[A-Z]{2})$#', $language->element, $element); - $language->code = $element[1]; - ?> - - - - - - - - - - -
- - - - - - - -
- pagination->getListFooter(); ?> -
- installedLang[0][$language->code]) || isset($this->installedLang[1][$language->code])) ? 'REINSTALL' : 'INSTALL'; ?> - detailsurl . '\'; Joomla.submitbutton(\'install.install\');'; ?> - - - name; ?> - - code; ?> - - - - version, 0, 3) != $minorVersion || substr($language->version, 0, 5) != $currentShortVersion) : ?> - version; ?> - - version; ?> - - - detailsurl; ?> -
- - - - - - - -
- -
diff --git a/administrator/components/com_installer/views/languages/view.html.php b/administrator/components/com_installer/views/languages/view.html.php deleted file mode 100644 index 45f158971979a..0000000000000 --- a/administrator/components/com_installer/views/languages/view.html.php +++ /dev/null @@ -1,80 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - $this->installedLang = JLanguageHelper::getInstalledLanguages(); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_installer'); - JToolBarHelper::title(JText::_('COM_INSTALLER_HEADER_' . $this->getName()), 'puzzle install'); - - if ($canDo->get('core.admin')) - { - parent::addToolbar(); - - // TODO: this help screen will need to be created. - JToolBarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_LANGUAGES'); - } - } -} diff --git a/administrator/components/com_installer/views/manage/tmpl/default.php b/administrator/components/com_installer/views/manage/tmpl/default.php deleted file mode 100644 index d7dcd2444a834..0000000000000 --- a/administrator/components/com_installer/views/manage/tmpl/default.php +++ /dev/null @@ -1,144 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
-
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - showMessage) : ?> - loadTemplate('message'); ?> - - ftp) : ?> - loadTemplate('ftp'); ?> - - $this)); ?> -
- items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - - - - - items as $i => $item) : ?> - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- extension_id); ?> - - element) : ?> - X - - status, $i, $item->status < 2, 'cb'); ?> - - - - - client_translated; ?> - - type_translated; ?> - - version != '' ? $item->version : ' '; ?> - - creationDate != '' ? $item->creationDate : ' '; ?> - - - author != '' ? $item->author : ' '; ?> - - - folder_translated; ?> - - package_id ?: ' '; ?> - - extension_id; ?> -
- - - - - -
- -
diff --git a/administrator/components/com_installer/views/manage/view.html.php b/administrator/components/com_installer/views/manage/view.html.php deleted file mode 100644 index 3fe03cda7161b..0000000000000 --- a/administrator/components/com_installer/views/manage/view.html.php +++ /dev/null @@ -1,92 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $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); - } - - // Include the component HTML helpers. - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - - // Display the view. - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_installer'); - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publish('manage.publish', 'JTOOLBAR_ENABLE', true); - JToolbarHelper::unpublish('manage.unpublish', 'JTOOLBAR_DISABLE', true); - JToolbarHelper::divider(); - } - - JToolbarHelper::custom('manage.refresh', 'refresh', 'refresh', 'JTOOLBAR_REFRESH_CACHE', true); - JToolbarHelper::divider(); - - if ($canDo->get('core.delete')) - { - JToolbarHelper::deleteList('COM_INSTALLER_CONFIRM_UNINSTALL', 'manage.remove', 'JTOOLBAR_UNINSTALL'); - JToolbarHelper::divider(); - } - - JHtmlSidebar::setAction('index.php?option=com_installer&view=manage'); - - parent::addToolbar(); - JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_MANAGE'); - } -} diff --git a/administrator/components/com_installer/views/update/tmpl/default.php b/administrator/components/com_installer/views/update/tmpl/default.php deleted file mode 100644 index 0c5b6faf0123f..0000000000000 --- a/administrator/components/com_installer/views/update/tmpl/default.php +++ /dev/null @@ -1,138 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
-
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - showMessage) : ?> - loadTemplate('message'); ?> - - - ftp) : ?> - loadTemplate('ftp'); ?> - - - $this)); ?> -
- items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - - - items as $i => $item) : ?> - client_id ? JText::_('JADMINISTRATOR') : JText::_('JSITE'); - $manifest = json_decode($item->manifest_cache); - $current_version = isset($manifest->version) ? $manifest->version : JText::_('JLIB_UNKNOWN'); - ?> - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- update_id); ?> - - - - client_translated; ?> - - type_translated; ?> - - current_version; ?> - - version; ?> - - folder_translated; ?> - - install_type; ?> - - - detailsurl; ?> - infourl)) : ?> -
- escape($item->infourl); ?> - -
-
- - - - -
- -
diff --git a/administrator/components/com_installer/views/update/view.html.php b/administrator/components/com_installer/views/update/view.html.php deleted file mode 100644 index d5ee00be10ab1..0000000000000 --- a/administrator/components/com_installer/views/update/view.html.php +++ /dev/null @@ -1,92 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - $paths = new stdClass; - $paths->first = ''; - - $this->paths = &$paths; - - if (count($this->items) > 0) - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNINGS_UPDATE_NOTICE'), 'notice'); - } - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JToolbarHelper::custom('update.update', 'upload', 'upload', 'COM_INSTALLER_TOOLBAR_UPDATE', true); - JToolbarHelper::custom('update.find', 'refresh', 'refresh', 'COM_INSTALLER_TOOLBAR_FIND_UPDATES', false); - JToolbarHelper::custom('update.purge', 'purge', 'purge', 'COM_INSTALLER_TOOLBAR_PURGE', false); - JToolbarHelper::divider(); - - JHtmlSidebar::setAction('index.php?option=com_installer&view=manage'); - - parent::addToolbar(); - JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_UPDATE'); - } -} diff --git a/administrator/components/com_installer/views/updatesites/tmpl/default.php b/administrator/components/com_installer/views/updatesites/tmpl/default.php deleted file mode 100644 index 77a7bca4349e5..0000000000000 --- a/administrator/components/com_installer/views/updatesites/tmpl/default.php +++ /dev/null @@ -1,121 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
-
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> -
- items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - - items as $i => $item) : ?> - - - - - - - - - - - - -
- - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- update_site_id); ?> - - element) : ?> - X - - enabled, $i, $item->enabled < 2, 'cb'); ?> - - - - - - name; ?> - - - client_translated; ?> - - type_translated; ?> - - folder_translated; ?> - - update_site_id; ?> -
- - - - -
- -
diff --git a/administrator/components/com_installer/views/updatesites/view.html.php b/administrator/components/com_installer/views/updatesites/view.html.php deleted file mode 100644 index a6065eb17028e..0000000000000 --- a/administrator/components/com_installer/views/updatesites/view.html.php +++ /dev/null @@ -1,98 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $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); - } - - // Include the component HTML helpers. - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - - // Display the view - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 3.4 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_installer'); - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publish('updatesites.publish', 'JTOOLBAR_ENABLE', true); - JToolbarHelper::unpublish('updatesites.unpublish', 'JTOOLBAR_DISABLE', true); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'updatesites.delete', 'JTOOLBAR_DELETE'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::custom('updatesites.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); - } - - JHtmlSidebar::setAction('index.php?option=com_installer&view=updatesites'); - - parent::addToolbar(); - JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_UPDATESITES'); - } -} diff --git a/administrator/components/com_installer/views/warnings/tmpl/default.php b/administrator/components/com_installer/views/warnings/tmpl/default.php deleted file mode 100644 index fa4a21dd8b50c..0000000000000 --- a/administrator/components/com_installer/views/warnings/tmpl/default.php +++ /dev/null @@ -1,41 +0,0 @@ - -
-
- sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - messages)) : ?> - 'warning0')); ?> - - messages as $message) : ?> - - - - - - - - - -
- - -
-
- -
diff --git a/administrator/components/com_installer/views/warnings/view.html.php b/administrator/components/com_installer/views/warnings/view.html.php deleted file mode 100644 index e3d12bf1225ec..0000000000000 --- a/administrator/components/com_installer/views/warnings/view.html.php +++ /dev/null @@ -1,58 +0,0 @@ -get('Items'); - $this->messages = &$items; - parent::display($tpl); - - if (count($items) > 0) - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNINGS_NOTICE'), 'warning'); - } - else - { - JFactory::getApplication()->enqueueMessage(JText::_('COM_INSTALLER_MSG_WARNINGS_NONE'), 'notice'); - } - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - parent::addToolbar(); - JToolbarHelper::help('JHELP_EXTENSIONS_EXTENSION_MANAGER_WARNINGS'); - } -} diff --git a/administrator/components/com_joomlaupdate/Controller/DisplayController.php b/administrator/components/com_joomlaupdate/Controller/DisplayController.php new file mode 100644 index 0000000000000..bdaf667a17898 --- /dev/null +++ b/administrator/components/com_joomlaupdate/Controller/DisplayController.php @@ -0,0 +1,78 @@ +input->get('view', 'Joomlaupdate'); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + $ftp = ClientHelper::setCredentialsFromRequest('ftp'); + $view->ftp = &$ftp; + + // Get the model for the view. + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + + $warningsModel = new WarningsModel; + + if (is_object($warningsModel)) + { + $view->setModel($warningsModel, false); + } + + // Perform update source preference check and refresh update information. + $model->applyUpdateSite(); + $model->refreshUpdates(); + + // Push the model into the view (as default). + $view->setModel($model, true); + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + $view->display(); + } + + return $this; + } +} diff --git a/administrator/components/com_joomlaupdate/Controller/UpdateController.php b/administrator/components/com_joomlaupdate/Controller/UpdateController.php new file mode 100644 index 0000000000000..99311d879503a --- /dev/null +++ b/administrator/components/com_joomlaupdate/Controller/UpdateController.php @@ -0,0 +1,518 @@ +id, $user->name, \JVERSION), Log::INFO, 'Update'); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + $this->_applyCredentials(); + + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + $file = $model->download(); + + $message = null; + $messageType = null; + + if ($file) + { + $this->app->setUserState('com_joomlaupdate.file', $file); + $url = 'index.php?option=com_joomlaupdate&task=update.install&' . $this->app->getSession()->getFormToken() . '=1'; + + try + { + Log::add(Text::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_FILE', $file), Log::INFO, 'Update'); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + } + else + { + $this->app->setUserState('com_joomlaupdate.file', null); + $url = 'index.php?option=com_joomlaupdate'; + $message = Text::_('COM_JOOMLAUPDATE_VIEW_UPDATE_DOWNLOADFAILED'); + $messageType = 'error'; + } + + $this->setRedirect($url, $message, $messageType); + } + + /** + * Start the installation of the new Joomla! version + * + * @return void + * + * @since 2.5.4 + */ + public function install() + { + Session::checkToken('get') or jexit(Text::_('JINVALID_TOKEN')); + + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'joomla_update.php'; + Log::addLogger($options, Log::INFO, array('Update', 'databasequery', 'jerror')); + + try + { + Log::add(Text::_('COM_JOOMLAUPDATE_UPDATE_LOG_INSTALL'), Log::INFO, 'Update'); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + $this->_applyCredentials(); + + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + + $file = Factory::getApplication()->getUserState('com_joomlaupdate.file', null); + $model->createRestorationFile($file); + + $this->display(); + } + + /** + * Finalise the upgrade by running the necessary scripts + * + * @return void + * + * @since 2.5.4 + */ + public function finalise() + { + /* + * Finalize with login page. Used for pre-token check versions + * to allow updates without problems but with a maximum of security. + */ + if (!Session::checkToken('get')) + { + $this->setRedirect('index.php?option=com_joomlaupdate&view=update&layout=finaliseconfirm'); + + return false; + } + + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'joomla_update.php'; + Log::addLogger($options, Log::INFO, array('Update', 'databasequery', 'jerror')); + + try + { + Log::add(Text::_('COM_JOOMLAUPDATE_UPDATE_LOG_FINALISE'), Log::INFO, 'Update'); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + $this->_applyCredentials(); + + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + + $model->finaliseUpgrade(); + + $url = 'index.php?option=com_joomlaupdate&task=update.cleanup&' . Session::getFormToken() . '=1'; + $this->setRedirect($url); + } + + /** + * Clean up after ourselves + * + * @return void + * + * @since 2.5.4 + */ + public function cleanup() + { + /* + * Cleanup with login page. Used for pre-token check versions to be able to update + * from =< 3.2.7 to allow updates without problems but with a maximum of security. + */ + if (!Session::checkToken('get')) + { + $this->setRedirect('index.php?option=com_joomlaupdate&view=update&layout=finaliseconfirm'); + + return false; + } + + $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; + $options['text_file'] = 'joomla_update.php'; + Log::addLogger($options, Log::INFO, array('Update', 'databasequery', 'jerror')); + + try + { + Log::add(Text::_('COM_JOOMLAUPDATE_UPDATE_LOG_CLEANUP'), Log::INFO, 'Update'); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + $this->_applyCredentials(); + + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + + $model->cleanUp(); + + $url = 'index.php?option=com_joomlaupdate&view=joomlaupdate&layout=complete'; + $this->setRedirect($url); + + try + { + Log::add(Text::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_COMPLETE', \JVERSION), Log::INFO, 'Update'); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + } + + /** + * Purges updates. + * + * @return void + * + * @since 3.0 + */ + public function purge() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Purge updates + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + $model->purge(); + + $url = 'index.php?option=com_joomlaupdate'; + $this->setRedirect($url, $model->_message); + } + + /** + * Uploads an update package to the temporary directory, under a random name + * + * @return void + * + * @since 3.6.0 + */ + public function upload() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? + Factory::getUser()->authorise('core.admin') or jexit(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN')); + + $this->_applyCredentials(); + + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + + try + { + $model->upload(); + } + catch (\RuntimeException $e) + { + $url = 'index.php?option=com_joomlaupdate'; + $this->setRedirect($url, $e->getMessage(), 'error'); + } + + $token = Session::getFormToken(); + $url = 'index.php?option=com_joomlaupdate&task=update.captive&' . $token . '=1'; + $this->setRedirect($url); + } + + /** + * Checks there is a valid update package and redirects to the captive view for super admin authentication. + * + * @return array + * + * @since 3.6.0 + */ + public function captive() + { + // Check for request forgeries + Session::checkToken('get') or jexit(Text::_('JINVALID_TOKEN')); + + // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? + if (!Factory::getUser()->authorise('core.admin')) + { + throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Do I really have an update package? + $tempFile = Factory::getApplication()->getUserState('com_joomlaupdate.temp_file', null); + + if (empty($tempFile) || !File::exists($tempFile)) + { + throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + $this->input->set('view', 'upload'); + $this->input->set('layout', 'captive'); + + $this->display(); + } + + /** + * Checks the admin has super administrator privileges and then proceeds with the update. + * + * @return array + * + * @since 3.6.0 + */ + public function confirm() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? + if (!$this->app->getIdentity()->authorise('core.admin')) + { + throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Get the model + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + + // Get the captive file before the session resets + $tempFile = $this->app->getUserState('com_joomlaupdate.temp_file', null); + + // Do I really have an update package? + if (!$model->captiveFileExists()) + { + throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Try to log in + $credentials = array( + 'username' => $this->input->post->get('username', '', 'username'), + 'password' => $this->input->post->get('passwd', '', 'raw'), + 'secretkey' => $this->input->post->get('secretkey', '', 'raw'), + ); + + $result = $model->captiveLogin($credentials); + + if (!$result) + { + $model->removePackageFiles(); + + throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Set the update source in the session + $this->app->setUserState('com_joomlaupdate.file', basename($tempFile)); + + try + { + Log::add(Text::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_FILE', $tempFile), Log::INFO, 'Update'); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + // Redirect to the actual update page + $url = 'index.php?option=com_joomlaupdate&task=update.install&' . Session::getFormToken() . '=1'; + $this->setRedirect($url); + } + + /** + * 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 static This object to support chaining. + * + * @since 2.5.4 + */ + public function display($cachable = false, $urlparams = array()) + { + // Get the document object. + $document = Factory::getDocument(); + + // Set the default view name and format from the Request. + $vName = $this->input->get('view', 'update'); + $vFormat = $document->getType(); + $lName = $this->input->get('layout', 'default', 'string'); + + // Get and render the view. + if ($view = $this->getView($vName, $vFormat)) + { + // Get the model for the view. + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + + // Push the model into the view (as default). + $view->setModel($model, true); + $view->setLayout($lName); + + // Push document object into the view. + $view->document = $document; + $view->display(); + } + + return $this; + } + + /** + * Applies FTP credentials to Joomla! itself, when required + * + * @return void + * + * @since 2.5.4 + */ + protected function _applyCredentials() + { + $this->app->getUserStateFromRequest('com_joomlaupdate.method', 'method', 'direct', 'cmd'); + + if (!ClientHelper::hasCredentials('ftp')) + { + $user = $this->app->getUserStateFromRequest('com_joomlaupdate.ftp_user', 'ftp_user', null, 'raw'); + $pass = $this->app->getUserStateFromRequest('com_joomlaupdate.ftp_pass', 'ftp_pass', null, 'raw'); + + if ($user != '' && $pass != '') + { + // Add credentials to the session + if (!ClientHelper::setCredentials('ftp', $user, $pass)) + { + $this->app->enqueueMessage(Text::_('JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED'), 'warning'); + } + } + } + } + + /** + * Checks the admin has super administrator privileges and then proceeds with the final & cleanup steps. + * + * @return array + * + * @since 3.6.3 + */ + public function finaliseconfirm() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Did a non Super User try do this? + if (!Factory::getUser()->authorise('core.admin')) + { + throw new \RuntimeException(Text::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); + } + + // Get the model + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel('Update'); + + // Try to log in + $credentials = array( + 'username' => $this->input->post->get('username', '', 'username'), + 'password' => $this->input->post->get('passwd', '', 'raw'), + 'secretkey' => $this->input->post->get('secretkey', '', 'raw'), + ); + + $result = $model->captiveLogin($credentials); + + // The login fails? + if (!$result) + { + $this->setMessage(Text::_('JGLOBAL_AUTH_INVALID_PASS'), 'warning'); + $this->setRedirect('index.php?option=com_joomlaupdate&view=update&layout=finaliseconfirm'); + + return false; + } + + // Redirect back to the actual finalise page + $this->setRedirect('index.php?option=com_joomlaupdate&task=update.finalise&' . Session::getFormToken() . '=1'); + } + + /** + * Fetch Extension update XML proxy. Used to prevent Access-Control-Allow-Origin errors. + * Prints a JSON string. + * Called from JS. + * + * @since 4.0.0 + * + * @return void + */ + public function fetchExtensionCompatibility() + { + $extensionID = $this->input->get('extension-id', '', 'DEFAULT'); + $joomlaTargetVersion = $this->input->get('joomla-target-version', '', 'DEFAULT'); + + /** @var JoomlaupdateModelDefault $model */ + $model = $this->getModel('default'); + $updateFileUrl = $model->fetchCompatibility($extensionID, $joomlaTargetVersion); + + $this->app = Factory::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 JsonResponse($updateFileUrl); + } + catch (Exception $e) + { + echo $e; + } + + $this->app->close(); + } +} diff --git a/administrator/components/com_joomlaupdate/Helper/Select.php b/administrator/components/com_joomlaupdate/Helper/Select.php new file mode 100644 index 0000000000000..bd46af2f6f470 --- /dev/null +++ b/administrator/components/com_joomlaupdate/Helper/Select.php @@ -0,0 +1,44 @@ +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; + + // "Testing" + case 'testing': + $updateURL = 'https://update.joomla.org/core/test/list_test.xml'; + break; + + // "Custom" + // TODO: check if the customurl is valid and not just "not empty". + case 'custom': + if (trim($params->get('customurl', '')) != '') + { + $updateURL = trim($params->get('customurl', '')); + } + else + { + return Factory::getApplication()->enqueueMessage(Text::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM_ERROR'), 'error'); + } + break; + + /** + * "Minor & Patch Release for Current version (recommended and default)". + * The commented "case" below are for documenting where 'default' and legacy options falls + * case 'default': + * case 'lts': + * case 'nochange': + */ + default: + $updateURL = 'https://update.joomla.org/core/list.xml'; + } + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('us') . '.*') + ->from($db->quoteName('#__update_sites_extensions') . ' AS ' . $db->quoteName('map')) + ->join( + 'INNER', $db->quoteName('#__update_sites') . ' AS ' . $db->quoteName('us') + . ' ON (' . 'us.update_site_id = map.update_site_id)' + ) + ->where('map.extension_id = ' . $db->quote(700)); + $db->setQuery($query); + $update_site = $db->loadObject(); + + if ($update_site->location != $updateURL) + { + // Modify the database record. + $update_site->last_check_timestamp = 0; + $update_site->location = $updateURL; + $db->updateObject('#__update_sites', $update_site, 'update_site_id'); + + // Remove cached updates. + $query->clear() + ->delete($db->quoteName('#__updates')) + ->where($db->quoteName('extension_id') . ' = ' . $db->quote('700')); + $db->setQuery($query); + $db->execute(); + } + } + + /** + * Makes sure that the Joomla! update cache is up-to-date. + * + * @param boolean $force Force reload, ignoring the cache timeout. + * + * @return void + * + * @since 2.5.4 + */ + public function refreshUpdates($force = false) + { + if ($force) + { + $cache_timeout = 0; + } + else + { + $update_params = ComponentHelper::getParams('com_installer'); + $cache_timeout = $update_params->get('cachetimeout', 6, 'int'); + $cache_timeout = 3600 * $cache_timeout; + } + + $updater = Updater::getInstance(); + + $reflection = new \ReflectionObject($updater); + $reflectionMethod = $reflection->getMethod('findUpdates'); + $methodParameters = $reflectionMethod->getParameters(); + + if (count($methodParameters) >= 4) + { + // Reinstall support is available in Updater + $updater->findUpdates(700, $cache_timeout, Updater::STABILITY_STABLE, true); + } + else + { + $updater->findUpdates(700, $cache_timeout, Updater::STABILITY_STABLE); + } + } + + /** + * Returns an array with the Joomla! update information. + * + * @return array + * + * @since 2.5.4 + */ + public function getUpdateInformation() + { + if ($this->updateInformation) + { + return $this->updateInformation; + } + + // Initialise the return array. + $this->updateInformation = array( + 'installed' => \JVERSION, + 'latest' => null, + 'object' => null, + 'hasUpdate' => false + ); + + // Fetch the update information from the database. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__updates')) + ->where($db->quoteName('extension_id') . ' = ' . $db->quote(700)); + $db->setQuery($query); + $updateObject = $db->loadObject(); + + if (is_null($updateObject)) + { + $this->updateInformation['latest'] = \JVERSION; + + return $this->updateInformation; + } + + $this->updateInformation['latest'] = $updateObject->version; + $this->updateInformation['hasUpdate'] = $updateObject->version != \JVERSION; + + // Fetch the full update details from the update details URL. + $update = new Update; + $update->loadFromXML($updateObject->detailsurl); + + $this->updateInformation['object'] = $update; + + return $this->updateInformation; + } + + /** + * Returns an array with the configured FTP options. + * + * @return array + * + * @since 2.5.4 + */ + public function getFTPOptions() + { + $config = Factory::getApplication()->getConfig(); + + return array( + 'host' => $config->get('ftp_host'), + 'port' => $config->get('ftp_port'), + 'username' => $config->get('ftp_user'), + 'password' => $config->get('ftp_pass'), + 'directory' => $config->get('ftp_root'), + 'enabled' => $config->get('ftp_enable'), + ); + } + + /** + * Removes all of the updates from the table and enable all update streams. + * + * @return boolean Result of operation. + * + * @since 3.0 + */ + 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'); + + $query = $db->getQuery(true) + ->delete($db->quoteName('#__updates')) + ->where($db->quoteName('update_site_id') . ' = ' . $db->quote('1')); + $db->setQuery($query); + + if ($db->execute()) + { + $this->_message = Text::_('COM_JOOMLAUPDATE_CHECKED_UPDATES'); + + return true; + } + else + { + $this->_message = Text::_('COM_JOOMLAUPDATE_FAILED_TO_CHECK_UPDATES'); + + return false; + } + } + + /** + * Downloads the update package to the site. + * + * @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; + $sources = $updateInfo['object']->get('downloadSources', array()); + $headers = get_headers($packageURL, 1); + + // Follow the Location headers until the actual download URL is known + while (isset($headers['Location'])) + { + $packageURL = $headers['Location']; + $headers = get_headers($packageURL, 1); + } + + // Remove protocol, path and query string from URL + $basename = basename($packageURL); + + if (strpos($basename, '?') !== false) + { + $basename = substr($basename, 0, strpos($basename, '?')); + } + + // Find the path to the temp directory and the local package. + $config = Factory::getConfig(); + $tempdir = $config->get('tmp_path'); + $target = $tempdir . '/' . $basename; + + // Do we have a cached file? + $exists = File::exists($target); + + if (!$exists) + { + // Not there, let's fetch it. + $mirror = 0; + + while (!($download = $this->downloadPackage($packageURL, $target)) && isset($sources[$mirror])) + { + $name = $sources[$mirror]; + $packageURL = $name->url; + $mirror++; + } + + return $download; + } + else + { + // Is it a 0-byte file? If so, re-download please. + $filesize = @filesize($target); + + if (empty($filesize)) + { + $mirror = 0; + + while (!($download = $this->downloadPackage($packageURL, $target)) && isset($sources[$mirror])) + { + $name = $sources[$mirror]; + $packageURL = $name->url; + $mirror++; + } + + return $download; + } + + // Yes, it's there, skip downloading. + return $basename; + } + } + + /** + * Downloads a package file to a specific directory + * + * @param string $url The URL to download from + * @param string $target The directory to store the file + * + * @return boolean True on success + * + * @since 2.5.4 + */ + protected function downloadPackage($url, $target) + { + try + { + Log::add(Text::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_URL', $url), Log::INFO, 'Update'); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + // Make sure the target does not exist. + File::delete($target); + + // Download the package + try + { + $result = HttpFactory::getHttp([], ['curl', 'stream'])->get($url); + } + catch (\RuntimeException $e) + { + return false; + } + + if (!$result || ($result->code != 200 && $result->code != 310)) + { + return false; + } + + // Write the file to disk + File::write($target, $result->body); + + return basename($target); + } + + /** + * Create restoration file. + * + * @param string $basename Optional base path to the file. + * + * @return boolean True if successful; false otherwise. + * + * @since 2.5.4 + */ + public function createRestorationFile($basename = null) + { + // Get a password + $password = UserHelper::genRandomPassword(32); + $app = Factory::getApplication(); + $app->setUserState('com_joomlaupdate.password', $password); + + // Do we have to use FTP? + $method = Factory::getApplication()->getUserStateFromRequest('com_joomlaupdate.method', 'method', 'direct', 'cmd'); + + // Get the absolute path to site's root. + $siteroot = JPATH_SITE; + + // If the package name is not specified, get it from the update info. + if (empty($basename)) + { + $updateInfo = $this->getUpdateInformation(); + $packageURL = $updateInfo['object']->downloadurl->_data; + $basename = basename($packageURL); + } + + // Get the package name. + $config = $app->getConfig(); + $tempdir = $config->get('tmp_path'); + $file = $tempdir . '/' . $basename; + + $filesize = @filesize($file); + $app->setUserState('com_joomlaupdate.password', $password); + $app->setUserState('com_joomlaupdate.filesize', $filesize); + + $data = " '$password', + 'kickstart.tuning.max_exec_time' => '5', + 'kickstart.tuning.run_time_bias' => '75', + 'kickstart.tuning.min_exec_time' => '0', + 'kickstart.procengine' => '$method', + 'kickstart.setup.sourcefile' => '$file', + 'kickstart.setup.destdir' => '$siteroot', + 'kickstart.setup.restoreperms' => '0', + 'kickstart.setup.filetype' => 'zip', + 'kickstart.setup.dryrun' => '0', + 'kickstart.setup.renamefiles' => array(), + 'kickstart.setup.postrenamefiles' => false +ENDDATA; + + if ($method != 'direct') + { + /* + * Fetch the FTP parameters from the request. Note: The password should be + * allowed as raw mode, otherwise something like !@43H% would be + * sanitised to !@43H% which is just plain wrong. + */ + $ftp_host = $app->input->get('ftp_host', ''); + $ftp_port = $app->input->get('ftp_port', '21'); + $ftp_user = $app->input->get('ftp_user', ''); + $ftp_pass = addcslashes($app->input->get('ftp_pass', '', 'raw'), "'\\"); + $ftp_root = $app->input->get('ftp_root', ''); + + // Is the tempdir really writable? + $writable = @is_writable($tempdir); + + if ($writable) + { + // Let's be REALLY sure. + $fp = @fopen($tempdir . '/test.txt', 'w'); + + if ($fp === false) + { + $writable = false; + } + else + { + fclose($fp); + unlink($tempdir . '/test.txt'); + } + } + + // If the tempdir is not writable, create a new writable subdirectory. + if (!$writable) + { + $FTPOptions = ClientHelper::getCredentials('ftp'); + $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); + $dest = Path::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $tempdir . '/admintools'), '/'); + + if (!@mkdir($tempdir . '/admintools')) + { + $ftp->mkdir($dest); + } + + if (!@chmod($tempdir . '/admintools', 511)) + { + $ftp->chmod($dest, 511); + } + + $tempdir .= '/admintools'; + } + + // \Just in case the temp-directory was off-root, try using the default tmp directory. + $writable = @is_writable($tempdir); + + if (!$writable) + { + $tempdir = JPATH_ROOT . '/tmp'; + + // Does the JPATH_ROOT/tmp directory exist? + if (!is_dir($tempdir)) + { + Folder::create($tempdir, 511); + $htaccessContents = "order deny,allow\ndeny from all\nallow from none\n"; + File::write($tempdir . '/.htaccess', $htaccessContents); + } + + // If it exists and it is unwritable, try creating a writable admintools subdirectory. + if (!is_writable($tempdir)) + { + $FTPOptions = ClientHelper::getCredentials('ftp'); + $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); + $dest = Path::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $tempdir . '/admintools'), '/'); + + if (!@mkdir($tempdir . '/admintools')) + { + $ftp->mkdir($dest); + } + + if (!@chmod($tempdir . '/admintools', 511)) + { + $ftp->chmod($dest, 511); + } + + $tempdir .= '/admintools'; + } + } + + // If we still have no writable directory, we'll try /tmp and the system's temp-directory. + $writable = @is_writable($tempdir); + + if (!$writable) + { + if (@is_dir('/tmp') && @is_writable('/tmp')) + { + $tempdir = '/tmp'; + } + else + { + // Try to find the system temp path. + $tmpfile = @tempnam('dummy', ''); + $systemp = @dirname($tmpfile); + @unlink($tmpfile); + + if (!empty($systemp)) + { + if (@is_dir($systemp) && @is_writable($systemp)) + { + $tempdir = $systemp; + } + } + } + } + + $data .= << '0', + 'kickstart.ftp.passive' => '1', + 'kickstart.ftp.host' => '$ftp_host', + 'kickstart.ftp.port' => '$ftp_port', + 'kickstart.ftp.user' => '$ftp_user', + 'kickstart.ftp.pass' => '$ftp_pass', + 'kickstart.ftp.dir' => '$ftp_root', + 'kickstart.ftp.tempdir' => '$tempdir' +ENDDATA; + } + + $data .= ');'; + + // Remove the old file, if it's there... + $configpath = JPATH_COMPONENT_ADMINISTRATOR . '/restoration.php'; + + if (File::exists($configpath)) + { + File::delete($configpath); + } + + // Write new file. First try with File. + $result = File::write($configpath, $data); + + // In case File used FTP but direct access could help. + if (!$result) + { + if (function_exists('file_put_contents')) + { + $result = @file_put_contents($configpath, $data); + + if ($result !== false) + { + $result = true; + } + } + else + { + $fp = @fopen($configpath, 'wt'); + + if ($fp !== false) + { + $result = @fwrite($fp, $data); + + if ($result !== false) + { + $result = true; + } + + @fclose($fp); + } + } + } + + return $result; + } + + /** + * Runs the schema update SQL files, the PHP update script and updates the + * manifest cache and #__extensions entry. Essentially, it is identical to + * InstallerFile::install() without the file copy. + * + * @return boolean True on success. + * + * @since 2.5.4 + */ + public function finaliseUpgrade() + { + $installer = Installer::getInstance(); + + $manifest = $installer->isManifest(JPATH_MANIFESTS . '/files/joomla.xml'); + + if ($manifest === false) + { + $installer->abort(Text::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST')); + + return false; + } + + $installer->manifest = $manifest; + + $installer->setUpgrade(true); + $installer->setOverwrite(true); + + $installer->extension = new \Joomla\CMS\Table\Extension(Factory::getDbo()); + $installer->extension->load(700); + + $installer->setAdapter($installer->extension->type); + + $installer->setPath('manifest', JPATH_MANIFESTS . '/files/joomla.xml'); + $installer->setPath('source', JPATH_MANIFESTS . '/files'); + $installer->setPath('extension_root', JPATH_ROOT); + + // Run the script file. + \JLoader::register('JoomlaInstallerScript', JPATH_ADMINISTRATOR . '/components/com_admin/script.php'); + + $manifestClass = new \JoomlaInstallerScript; + + ob_start(); + ob_implicit_flush(false); + + if ($manifestClass && method_exists($manifestClass, 'preflight')) + { + if ($manifestClass->preflight('update', $installer) === false) + { + $installer->abort(Text::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE')); + + return false; + } + } + + // Create msg object; first use here. + $msg = ob_get_contents(); + ob_end_clean(); + + // Get a database connector object. + $db = $this->getDbo(); + + /* + * Check to see if a file extension by the same name is already installed. + * If it is, then update the table because if the files aren't there + * we can assume that it was (badly) uninstalled. + * If it isn't, add an entry to extensions. + */ + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('file')) + ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + // Install failed, roll back changes. + $installer->abort( + Text::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', Text::_('JLIB_INSTALLER_UPDATE'), $e->getMessage()) + ); + + return false; + } + + $id = $db->loadResult(); + $row = new \Joomla\CMS\Table\Extension(Factory::getDbo()); + + if ($id) + { + // Load the entry and update the manifest_cache. + $row->load($id); + + // Update name. + $row->set('name', 'files_joomla'); + + // Update manifest. + $row->manifest_cache = $installer->generateManifestCache(); + + if (!$row->store()) + { + // Install failed, roll back changes. + $installer->abort( + Text::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', Text::_('JLIB_INSTALLER_UPDATE'), $row->getError()) + ); + + return false; + } + } + else + { + // Add an entry to the extension table with a whole heap of defaults. + $row->set('name', 'files_joomla'); + $row->set('type', 'file'); + $row->set('element', 'joomla'); + + // There is no folder for files so leave it blank. + $row->set('folder', ''); + $row->set('enabled', 1); + $row->set('protected', 0); + $row->set('access', 0); + $row->set('client_id', 0); + $row->set('params', ''); + $row->set('manifest_cache', $installer->generateManifestCache()); + + if (!$row->store()) + { + // Install failed, roll back changes. + $installer->abort(Text::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_ROLLBACK', $row->getError())); + + return false; + } + + // Set the insert id. + $row->set('extension_id', $db->insertid()); + + // Since we have created a module item, we add it to the installation step stack + // so that if we have to rollback the changes we can undo it. + $installer->pushStep(array('type' => 'extension', 'extension_id' => $row->extension_id)); + } + + $result = $installer->parseSchemaUpdates($manifest->update->schemas, $row->extension_id); + + if ($result === false) + { + // Install failed, rollback changes (message already logged by the installer). + $installer->abort(); + + return false; + } + + // Start Joomla! 1.6. + ob_start(); + ob_implicit_flush(false); + + if ($manifestClass && method_exists($manifestClass, 'update')) + { + if ($manifestClass->update($installer) === false) + { + // Install failed, rollback changes. + $installer->abort(Text::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE')); + + return false; + } + } + + // Append messages. + $msg .= ob_get_contents(); + ob_end_clean(); + + // Clobber any possible pending updates. + $update = new \Joomla\CMS\Table\Update(Factory::getDbo()); + $uid = $update->find( + array('element' => 'joomla', 'type' => 'file', 'client_id' => '0', 'folder' => '') + ); + + if ($uid) + { + $update->delete($uid); + } + + // And now we run the postflight. + ob_start(); + ob_implicit_flush(false); + + if ($manifestClass && method_exists($manifestClass, 'postflight')) + { + $manifestClass->postflight('update', $installer); + } + + // Append messages. + $msg .= ob_get_contents(); + ob_end_clean(); + + if ($msg != '') + { + $installer->set('extension_message', $msg); + } + + // Refresh versionable assets cache. + Factory::getApplication()->flushAssets(); + + return true; + } + + /** + * Removes the extracted package file. + * + * @return void + * + * @since 2.5.4 + */ + public function cleanUp() + { + // Remove the update package. + $config = Factory::getConfig(); + $tempdir = $config->get('tmp_path'); + + $file = Factory::getApplication()->getUserState('com_joomlaupdate.file', null); + $target = $tempdir . '/' . $file; + + if (!@unlink($target)) + { + File::delete($target); + } + + // Remove the restoration.php file. + $target = JPATH_COMPONENT_ADMINISTRATOR . '/restoration.php'; + + if (!@unlink($target)) + { + File::delete($target); + } + + // Remove joomla.xml from the site's root. + $target = JPATH_ROOT . '/joomla.xml'; + + if (!@unlink($target)) + { + File::delete($target); + } + + // Unset the update filename from the session. + Factory::getApplication()->setUserState('com_joomlaupdate.file', null); + } + + /** + * Uploads what is presumably an update ZIP file under a mangled name in the temporary directory. + * + * @return void + * + * @since 3.6.0 + */ + public function upload() + { + // Get the uploaded file information. + $input = Factory::getApplication()->input; + + // Do not change the filter type 'raw'. We need this to let files containing PHP code to upload. See \JInputFiles::get. + $userfile = $input->files->get('install_package', null, 'raw'); + + // Make sure that file uploads are enabled in php. + if (!(bool) ini_get('file_uploads')) + { + throw new \RuntimeException(Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLFILE'), 500); + } + + // Make sure that zlib is loaded so that the package can be unpacked. + if (!extension_loaded('zlib')) + { + throw new \RuntimeException(Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB'), 500); + } + + // If there is no uploaded file, we have a problem... + if (!is_array($userfile)) + { + throw new \RuntimeException(Text::_('COM_INSTALLER_MSG_INSTALL_NO_FILE_SELECTED'), 500); + } + + // Is the PHP tmp directory missing? + if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_NO_TMP_DIR)) + { + throw new \RuntimeException( + Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . + Text::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), + 500 + ); + } + + // Is the max upload size too small in php.ini? + if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_INI_SIZE)) + { + throw new \RuntimeException( + Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . Text::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), + 500 + ); + } + + // Check if there was a different problem uploading the file. + if ($userfile['error'] || $userfile['size'] < 1) + { + throw new \RuntimeException(Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR'), 500); + } + + // Build the appropriate paths. + $config = Factory::getConfig(); + $tmp_dest = tempnam($config->get('tmp_path'), 'ju'); + $tmp_src = $userfile['tmp_name']; + + // Move uploaded file. + if (version_compare(\JVERSION, '3.4.0', 'ge')) + { + $result = File::upload($tmp_src, $tmp_dest, false, true); + } + else + { + // Old Joomla! versions didn't have UploadShield and don't need the fourth parameter to accept uploads + $result = File::upload($tmp_src, $tmp_dest); + } + + if (!$result) + { + throw new \RuntimeException(Text::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR'), 500); + } + + Factory::getApplication()->setUserState('com_joomlaupdate.temp_file', $tmp_dest); + } + + /** + * Checks the super admin credentials are valid for the currently logged in users + * + * @param array $credentials The credentials to authenticate the user with + * + * @return boolean + * + * @since 3.6.0 + */ + public function captiveLogin($credentials) + { + // Make sure the username matches + $username = $credentials['username'] ?? null; + $user = Factory::getUser(); + + if (strtolower($user->username) != strtolower($username)) + { + return false; + } + + // Make sure the user we're authorising is a Super User + if (!$user->authorise('core.admin')) + { + return false; + } + + // Get the global Authentication object. + $authenticate = Authentication::getInstance(); + $response = $authenticate->authenticate($credentials); + + if ($response->status !== Authentication::STATUS_SUCCESS) + { + return false; + } + + return true; + } + + /** + * Does the captive (temporary) file we uploaded before still exist? + * + * @return boolean + * + * @since 3.6.0 + */ + public function captiveFileExists() + { + $file = Factory::getApplication()->getUserState('com_joomlaupdate.temp_file', null); + + if (empty($file) || !File::exists($file)) + { + return false; + } + + return true; + } + + /** + * Remove the captive (temporary) file we uploaded before and the . + * + * @return void + * + * @since 3.6.0 + */ + public function removePackageFiles() + { + $files = array( + Factory::getApplication()->getUserState('com_joomlaupdate.temp_file', null), + Factory::getApplication()->getUserState('com_joomlaupdate.file', null), + ); + + foreach ($files as $file) + { + if (File::exists($file)) + { + if (!@unlink($file)) + { + File::delete($file); + } + } + } + } + + /** + * Gets PHP options. + * TODO: Outsource, build common code base for pre install and pre update check + * + * @return array Array of PHP config options + * + * @since 4.0.0 + */ + public function getPhpOptions() + { + $options = array(); + + /* + * Check the PHP Version. It is already checked in Update. + * 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 = Text::sprintf('INSTL_PHP_VERSION_NEWER', $this->getTargetMinimumPHPVersion()); + $option->state = $this->isPhpVersionSupported(); + $option->notice = null; + $options[] = $option; + + // Check for zlib support. + $option = new \stdClass; + $option->label = Text::_('INSTL_ZLIB_COMPRESSION_SUPPORT'); + $option->state = extension_loaded('zlib'); + $option->notice = null; + $options[] = $option; + + // Check for XML support. + $option = new \stdClass; + $option->label = Text::_('INSTL_XML_SUPPORT'); + $option->state = extension_loaded('xml'); + $option->notice = null; + $options[] = $option; + + // Check if configured database is compatible with Joomla 4 + if (version_compare($this->getUpdateInformation()['latest'], '4', '>=')) + { + $option = new \stdClass; + $option->label = Text::sprintf('INSTL_DATABASE_SUPPORTED', $this->getConfiguredDatabaseType()); + $option->state = $this->isDatabaseTypeSupported(); + $option->notice = null; + $options[] = $option; + } + + // Check for mbstring options. + if (extension_loaded('mbstring')) + { + // Check for default MB language. + $option = new \stdClass; + $option->label = Text::_('INSTL_MB_LANGUAGE_IS_DEFAULT'); + $option->state = strtolower(ini_get('mbstring.language')) === 'neutral'; + $option->notice = $option->state ? null : Text::_('INSTL_NOTICEMBLANGNOTDEFAULT'); + $options[] = $option; + + // Check for MB function overload. + $option = new \stdClass; + $option->label = Text::_('INSTL_MB_STRING_OVERLOAD_OFF'); + $option->state = ini_get('mbstring.func_overload') == 0; + $option->notice = $option->state ? null : Text::_('INSTL_NOTICEMBSTRINGOVERLOAD'); + $options[] = $option; + } + + // Check for a missing native parse_ini_file implementation. + $option = new \stdClass; + $option->label = Text::_('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 = Text::_('INSTL_JSON_SUPPORT_AVAILABLE'); + $option->state = function_exists('json_encode') && function_exists('json_decode'); + $option->notice = null; + $options[] = $option; + + return $options; + } + + /** + * Gets PHP Settings. + * TODO: Outsource, build common code base for pre install and pre update check + * + * @return array + * + * @since 4.0.0 + */ + public function getPhpSettings() + { + $settings = array(); + + // Check for display errors. + $setting = new \stdClass; + $setting->label = Text::_('INSTL_DISPLAY_ERRORS'); + $setting->state = (bool) ini_get('display_errors'); + $setting->recommended = false; + $settings[] = $setting; + + // Check for file uploads. + $setting = new \stdClass; + $setting->label = Text::_('INSTL_FILE_UPLOADS'); + $setting->state = (bool) ini_get('file_uploads'); + $setting->recommended = true; + $settings[] = $setting; + + // Check for output buffering. + $setting = new \stdClass; + $setting->label = Text::_('INSTL_OUTPUT_BUFFERING'); + $setting->state = (bool) ini_get('output_buffering'); + $setting->recommended = false; + $settings[] = $setting; + + // Check for session auto-start. + $setting = new \stdClass; + $setting->label = Text::_('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 = Text::_('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 4.0.0 + */ + private function getConfiguredDatabaseType() + { + return Factory::getApplication()->get('dbtype'); + } + + /** + * Returns true, if J! version is < 4 or current configured + * database type is compatible with the update. + * + * @return boolean + * + * @since 4.0.0 + */ + public function isDatabaseTypeSupported() + { + if (version_compare($this->getUpdateInformation()['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 4.0.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 4.0.0 + */ + private function getTargetMinimumPHPVersion() + { + return isset($this->getUpdateInformation()['object']->php_minimum) ? + $this->getUpdateInformation()['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 4.0.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; + } + + /** + * Gets an array containing all installed extensions, that are not core extensions. + * + * @return array name,version,updateserver + * + * @since 4.0.0 + */ + public function getNonCoreExtensions() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query->select( + $db->quoteName('ex.name') . ', ' . + $db->quoteName('ex.extension_id') . ', ' . + $db->quoteName('ex.manifest_cache') . ', ' . + $db->quoteName('ex.type') . ', ' . + $db->quoteName('ex.folder') . ', ' . + $db->quoteName('ex.element') . ', ' . + $db->quoteName('ex.client_id') . ', ' . + $db->quoteName('si.location') + )->from( + $db->quoteName('#__extensions', 'ex') + )->leftJoin( + $db->quoteName('#__update_sites_extensions', 'se') . + ' ON ' . $db->quoteName('se.extension_id') . ' = ' . $db->quoteName('ex.extension_id') + )->leftJoin( + $db->quoteName('#__update_sites', 'si') . + ' ON ' . $db->quoteName('si.update_site_id') . ' = ' . $db->quoteName('se.update_site_id') + )->where( + $db->quoteName('ex.package_id') . ' = 0' + ); + + $db->setQuery($query); + $rows = $db->loadObjectList(); + $rows = array_filter($rows, self::class . '::isNonCoreExtension'); + + foreach ($rows as $extension) + { + $decode = json_decode($extension->manifest_cache); + $this->translateExtensionName($extension); + $extension->version = $decode->version; + unset($extension->manifest_cache); + } + + 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 4.0.0 + */ + private static function isNonCoreExtension($extension) + { + $coreExtensions = ExtensionHelper::getCoreExtensions(); + + foreach ($coreExtensions as $coreExtension) + { + if ($coreExtension[1] == $extension->element) + { + return false; + } + } + + return true; + + } + + /** + * 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 4.0.0 + */ + public function fetchCompatibility($extensionID, $joomlaTargetVersion) + { + $updateFileUrl = $this->getUpdateSiteLocation($extensionID); + + if (!$updateFileUrl) + { + return (object) array('state' => 2); + } + else + { + $compatibleVersion = $this->checkCompatibility($updateFileUrl, $joomlaTargetVersion); + + if ($compatibleVersion) + { + return (object) array('state' => 1, 'compatibleVersion' => $compatibleVersion->_data); + } + else + { + return (object) array('state' => 0); + } + } + } + + /** + * Get the URL to the update server for a given extension ID + * + * @param int $extensionID The extension ID + * + * @return mixed URL or false + * + * @since 4.0.0 + */ + private function getUpdateSiteLocation($extensionID) + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query->select($db->quoteName('us.location')) + ->from($db->quoteName('#__update_sites', 'us')) + ->leftJoin( + $db->quoteName('#__update_sites_extensions', 'e') + . ' ON ' . $db->quoteName('e.update_site_id') . ' = ' . $db->quoteName('us.update_site_id') + ) + ->where($db->quoteName('e.extension_id') . ' = ' . (int) $extensionID); + + $db->setQuery($query); + + $rows = $db->loadObjectList(); + + return count($rows) >= 1 ? end($rows)->location : false; + } + + /** + * 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 mixed An array of data items or false. + * + * @since 4.0.0 + */ + private function checkCompatibility($updateFileUrl, $joomlaTargetVersion) + { + $update = new \Joomla\CMS\Updater\Update; + $update->set('jversion.full', $joomlaTargetVersion); + $update->loadFromXML($updateFileUrl); + + $downloadUrl = $update->get('downloadurl'); + + return !empty($downloadUrl) && !empty($downloadUrl->_data) ? $update->get('version') : false; + } + + /** + * Translates an extension name + * + * @param object &$item The extension of which the name needs to be translated + * + * @return void + * + * @since 4.0.0 + */ + protected function translateExtensionName(&$item) + { + // ToDo: Cleanup duplicated code. from com_installer/models/extension.php + $lang = Factory::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 = Text::_($item->name); + } +} diff --git a/administrator/components/com_joomlaupdate/View/Joomlaupdate/HtmlView.php b/administrator/components/com_joomlaupdate/View/Joomlaupdate/HtmlView.php new file mode 100644 index 0000000000000..bed665791d6a8 --- /dev/null +++ b/administrator/components/com_joomlaupdate/View/Joomlaupdate/HtmlView.php @@ -0,0 +1,286 @@ +state = $this->get('State'); + + // Load useful classes. + /* @var \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel $model */ + $model = $this->getModel(); + $this->loadHelper('select'); + + // Assign view variables. + $ftp = $model->getFTPOptions(); + $defaultMethod = $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(); + + // Set the toolbar information. + ToolbarHelper::title(Text::_('COM_JOOMLAUPDATE_OVERVIEW'), 'loop install'); + ToolbarHelper::custom('update.purge', 'loop', 'loop', 'COM_JOOMLAUPDATE_TOOLBAR_CHECK', false); + + // Add toolbar buttons. + $user = Factory::getUser(); + + if ($user->authorise('core.admin', 'com_joomlaupdate') || $user->authorise('core.options', 'com_joomlaupdate')) + { + ToolbarHelper::preferences('com_joomlaupdate'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_COMPONENTS_JOOMLA_UPDATE'); + + if (!is_null($this->updateInfo['object'])) + { + // Show the message if an update is found. + Factory::getApplication()->enqueueMessage(Text::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATE_NOTICE'), 'notice'); + } + + $this->ftpFieldsDisplay = $this->ftp['enabled'] ? '' : 'style = "display: none"'; + $params = ComponentHelper::getParams('com_joomlaupdate'); + + 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 = Text::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_NEXT'); + break; + + // "Testing" + case 'testing': + $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_TESTING'; + $this->updateSourceKey = Text::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_TESTING'); + break; + + // "Custom" + case 'custom': + $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_CUSTOM'; + $this->updateSourceKey = Text::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM'); + break; + + /** + * "Minor & Patch Release for Current version (recommended and default)". + * The commented "case" below are for documenting where 'default' and legacy options falls + * case 'default': + * case 'lts': + * case 'nochange': + */ + default: + $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_DEFAULT'; + $this->updateSourceKey = Text::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_DEFAULT'); + } + + $this->warnings = array(); + /** @var \Joomla\Component\Installer\Administrator\Model\WarningsModel $warningsModel */ + $warningsModel = $this->getModel('warnings'); + + if (is_object($warningsModel) && $warningsModel instanceof \Joomla\CMS\MVC\Model\BaseDatabaseModel) + { + $language = Factory::getLanguage(); + $language->load('com_installer', JPATH_ADMINISTRATOR, 'en-GB', false, true); + $language->load('com_installer', JPATH_ADMINISTRATOR, null, true); + + $this->warnings = $warningsModel->getItems(); + } + + $this->selfUpdate = $this->checkForSelfUpdate(); + + // Only Super Users have access to the Update & Install for obvious security reasons + $this->showUploadAndUpdate = Factory::getUser()->authorise('core.admin'); + + // Remove temporary files + $model->removePackageFiles(); + + // Render the view. + parent::display($tpl); + } + + /** + * Makes sure that the Joomla! Update Component Update is in the database and check if there is a new version. + * + * @return boolean True if there is an update else false + * + * @since 3.6.3 + */ + private function checkForSelfUpdate() + { + $db = Factory::getDbo(); + + $query = $db->getQuery(true) + ->select($db->quoteName('extension_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('element') . ' = ' . $db->quote('com_joomlaupdate')); + $db->setQuery($query); + + try + { + // Get the component extension ID + $joomlaUpdateComponentId = $db->loadResult(); + } + catch (\RuntimeException $e) + { + // Something is wrong here! + $joomlaUpdateComponentId = 0; + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + // Try the update only if we have an extension id + if ($joomlaUpdateComponentId != 0) + { + // Allways force to check for an update! + $cache_timeout = 0; + + $updater = Updater::getInstance(); + $updater->findUpdates($joomlaUpdateComponentId, $cache_timeout, Updater::STABILITY_STABLE); + + // Fetch the update information from the database. + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__updates')) + ->where($db->quoteName('extension_id') . ' = ' . $db->quote($joomlaUpdateComponentId)); + $db->setQuery($query); + + try + { + $joomlaUpdateComponentObject = $db->loadObject(); + } + catch (\RuntimeException $e) + { + // Something is wrong here! + $joomlaUpdateComponentObject = null; + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + if (is_null($joomlaUpdateComponentObject)) + { + // No Update great! + return false; + } + + 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 4.0.0 + */ + public function shouldDisplayPreUpdateCheck() + { + return isset($this->updateInfo['object']->downloadurl->_data) + && $this->getModel()->isDatabaseTypeSupported() + && $this->getModel()->isPhpVersionSupported(); + } +} diff --git a/administrator/components/com_joomlaupdate/View/Update/HtmlView.php b/administrator/components/com_joomlaupdate/View/Update/HtmlView.php new file mode 100644 index 0000000000000..59cd29f59ccea --- /dev/null +++ b/administrator/components/com_joomlaupdate/View/Update/HtmlView.php @@ -0,0 +1,43 @@ +input->set('hidemainmenu', true); + + // Set the toolbar information. + ToolbarHelper::title(Text::_('COM_JOOMLAUPDATE_OVERVIEW'), 'loop install'); + + // Render the view. + parent::display($tpl); + } +} diff --git a/administrator/components/com_joomlaupdate/View/Upload/HtmlView.php b/administrator/components/com_joomlaupdate/View/Upload/HtmlView.php new file mode 100644 index 0000000000000..fcd96e1806fcc --- /dev/null +++ b/administrator/components/com_joomlaupdate/View/Upload/HtmlView.php @@ -0,0 +1,50 @@ +load('com_installer', JPATH_ADMINISTRATOR, 'en-GB', false, true); + $language->load('com_installer', JPATH_ADMINISTRATOR, null, true); + + // Render the view. + parent::display($tpl); + } +} diff --git a/administrator/components/com_joomlaupdate/access.xml b/administrator/components/com_joomlaupdate/access.xml index c8c9f3dd739df..b88d1a684fb02 100644 --- a/administrator/components/com_joomlaupdate/access.xml +++ b/administrator/components/com_joomlaupdate/access.xml @@ -1,10 +1,10 @@
- - - - - + + + + +
diff --git a/administrator/components/com_joomlaupdate/config.xml b/administrator/components/com_joomlaupdate/config.xml index 0253763b333d3..722dbf209a05c 100644 --- a/administrator/components/com_joomlaupdate/config.xml +++ b/administrator/components/com_joomlaupdate/config.xml @@ -10,7 +10,6 @@ name="updatesource" type="list" label="COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_LABEL" - description="COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_DESC" default="default" > @@ -26,7 +25,6 @@ name="customurl" type="text" label="COM_JOOMLAUPDATE_CONFIG_CUSTOMURL_LABEL" - description="COM_JOOMLAUPDATE_CONFIG_CUSTOMURL_DESC" default="" length="50" showon="updatesource:custom" diff --git a/administrator/components/com_joomlaupdate/controller.php b/administrator/components/com_joomlaupdate/controller.php deleted file mode 100644 index c6bb6b22ccfec..0000000000000 --- a/administrator/components/com_joomlaupdate/controller.php +++ /dev/null @@ -1,74 +0,0 @@ -input->get('view', 'default'); - $vFormat = $document->getType(); - $lName = $this->input->get('layout', 'default', 'string'); - - // Get and render the view. - if ($view = $this->getView($vName, $vFormat)) - { - $ftp = JClientHelper::setCredentialsFromRequest('ftp'); - $view->ftp = &$ftp; - - // Get the model for the view. - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('default'); - - // Push the Installer Warnings model into the view, if we can load it - static::addModelPath(JPATH_ADMINISTRATOR . '/components/com_installer/models', 'InstallerModel'); - - $warningsModel = $this->getModel('warnings', 'InstallerModel'); - - if (is_object($warningsModel)) - { - $view->setModel($warningsModel, false); - } - - // Perform update source preference check and refresh update information. - $model->applyUpdateSite(); - $model->refreshUpdates(); - - // Push the model into the view (as default). - $view->setModel($model, true); - $view->setLayout($lName); - - // Push document object into the view. - $view->document = $document; - $view->display(); - } - - return $this; - } -} diff --git a/administrator/components/com_joomlaupdate/controllers/update.php b/administrator/components/com_joomlaupdate/controllers/update.php deleted file mode 100644 index cb57d84c7f072..0000000000000 --- a/administrator/components/com_joomlaupdate/controllers/update.php +++ /dev/null @@ -1,473 +0,0 @@ -id, $user->name, JVERSION), JLog::INFO, 'Update'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $this->_applyCredentials(); - - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('Default'); - $file = $model->download(); - - $message = null; - $messageType = null; - - if ($file) - { - JFactory::getApplication()->setUserState('com_joomlaupdate.file', $file); - $url = 'index.php?option=com_joomlaupdate&task=update.install&' . JFactory::getSession()->getFormToken() . '=1'; - - try - { - JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_FILE', $file), JLog::INFO, 'Update'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - } - else - { - JFactory::getApplication()->setUserState('com_joomlaupdate.file', null); - $url = 'index.php?option=com_joomlaupdate'; - $message = JText::_('COM_JOOMLAUPDATE_VIEW_UPDATE_DOWNLOADFAILED'); - $messageType = 'error'; - } - - $this->setRedirect($url, $message, $messageType); - } - - /** - * Start the installation of the new Joomla! version - * - * @return void - * - * @since 2.5.4 - */ - public function install() - { - JSession::checkToken('get') or jexit(JText::_('JINVALID_TOKEN')); - - $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; - $options['text_file'] = 'joomla_update.php'; - JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); - - try - { - JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_INSTALL'), JLog::INFO, 'Update'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $this->_applyCredentials(); - - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('Default'); - - $file = JFactory::getApplication()->getUserState('com_joomlaupdate.file', null); - $model->createRestorationFile($file); - - $this->display(); - } - - /** - * Finalise the upgrade by running the necessary scripts - * - * @return void - * - * @since 2.5.4 - */ - public function finalise() - { - /* - * Finalize with login page. Used for pre-token check versions - * to allow updates without problems but with a maximum of security. - */ - if (!JSession::checkToken('get')) - { - $this->setRedirect('index.php?option=com_joomlaupdate&view=update&layout=finaliseconfirm'); - - return false; - } - - $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; - $options['text_file'] = 'joomla_update.php'; - JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); - - try - { - JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_FINALISE'), JLog::INFO, 'Update'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $this->_applyCredentials(); - - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('Default'); - - $model->finaliseUpgrade(); - - $url = 'index.php?option=com_joomlaupdate&task=update.cleanup&' . JFactory::getSession()->getFormToken() . '=1'; - $this->setRedirect($url); - } - - /** - * Clean up after ourselves - * - * @return void - * - * @since 2.5.4 - */ - public function cleanup() - { - /* - * Cleanup with login page. Used for pre-token check versions to be able to update - * from =< 3.2.7 to allow updates without problems but with a maximum of security. - */ - if (!JSession::checkToken('get')) - { - $this->setRedirect('index.php?option=com_joomlaupdate&view=update&layout=finaliseconfirm'); - - return false; - } - - $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}'; - $options['text_file'] = 'joomla_update.php'; - JLog::addLogger($options, JLog::INFO, array('Update', 'databasequery', 'jerror')); - - try - { - JLog::add(JText::_('COM_JOOMLAUPDATE_UPDATE_LOG_CLEANUP'), JLog::INFO, 'Update'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $this->_applyCredentials(); - - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('Default'); - - $model->cleanUp(); - - $url = 'index.php?option=com_joomlaupdate&view=default&layout=complete'; - $this->setRedirect($url); - - try - { - JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_COMPLETE', JVERSION), JLog::INFO, 'Update'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - } - - /** - * Purges updates. - * - * @return void - * - * @since 3.0 - */ - public function purge() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Purge updates - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('Default'); - $model->purge(); - - $url = 'index.php?option=com_joomlaupdate'; - $this->setRedirect($url, $model->_message); - } - - /** - * Uploads an update package to the temporary directory, under a random name - * - * @return void - * - * @since 3.6.0 - */ - public function upload() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // 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')); - - $this->_applyCredentials(); - - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('Default'); - - try - { - $model->upload(); - } - catch (RuntimeException $e) - { - $url = 'index.php?option=com_joomlaupdate'; - $this->setRedirect($url, $e->getMessage(), 'error'); - } - - $token = JSession::getFormToken(); - $url = 'index.php?option=com_joomlaupdate&task=update.captive&' . $token . '=1'; - $this->setRedirect($url); - } - - /** - * Checks there is a valid update package and redirects to the captive view for super admin authentication. - * - * @return array - * - * @since 3.6.0 - */ - public function captive() - { - // Check for request forgeries - JSession::checkToken('get') or jexit(JText::_('JINVALID_TOKEN')); - - // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? - if (!JFactory::getUser()->authorise('core.admin')) - { - throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); - } - - // Do I really have an update package? - $tempFile = JFactory::getApplication()->getUserState('com_joomlaupdate.temp_file', null); - - JLoader::import('joomla.filesystem.file'); - - if (empty($tempFile) || !JFile::exists($tempFile)) - { - throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); - } - - $this->input->set('view', 'upload'); - $this->input->set('layout', 'captive'); - - $this->display(); - } - - /** - * Checks the admin has super administrator privileges and then proceeds with the update. - * - * @return array - * - * @since 3.6.0 - */ - public function confirm() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Did a non Super User tried to upload something (a.k.a. pathetic hacking attempt)? - if (!JFactory::getUser()->authorise('core.admin')) - { - throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); - } - - // Get the model - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('default'); - - // Get the captive file before the session resets - $tempFile = JFactory::getApplication()->getUserState('com_joomlaupdate.temp_file', null); - - // Do I really have an update package? - if (!$model->captiveFileExists()) - { - throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); - } - - // Try to log in - $credentials = array( - 'username' => $this->input->post->get('username', '', 'username'), - 'password' => $this->input->post->get('passwd', '', 'raw'), - 'secretkey' => $this->input->post->get('secretkey', '', 'raw'), - ); - - $result = $model->captiveLogin($credentials); - - if (!$result) - { - $model->removePackageFiles(); - - throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); - } - - // Set the update source in the session - JFactory::getApplication()->setUserState('com_joomlaupdate.file', basename($tempFile)); - - try - { - JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_FILE', $tempFile), JLog::INFO, 'Update'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Redirect to the actual update page - $url = 'index.php?option=com_joomlaupdate&task=update.install&' . JFactory::getSession()->getFormToken() . '=1'; - $this->setRedirect($url); - } - - /** - * 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 JoomlaupdateControllerUpdate This object to support chaining. - * - * @since 2.5.4 - */ - public function display($cachable = false, $urlparams = array()) - { - // Get the document object. - $document = JFactory::getDocument(); - - // Set the default view name and format from the Request. - $vName = $this->input->get('view', 'update'); - $vFormat = $document->getType(); - $lName = $this->input->get('layout', 'default', 'string'); - - // Get and render the view. - if ($view = $this->getView($vName, $vFormat)) - { - // Get the model for the view. - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('Default'); - - // Push the model into the view (as default). - $view->setModel($model, true); - $view->setLayout($lName); - - // Push document object into the view. - $view->document = $document; - $view->display(); - } - - return $this; - } - - /** - * Applies FTP credentials to Joomla! itself, when required - * - * @return void - * - * @since 2.5.4 - */ - protected function _applyCredentials() - { - JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.method', 'method', 'direct', 'cmd'); - - if (!JClientHelper::hasCredentials('ftp')) - { - $user = JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_user', 'ftp_user', null, 'raw'); - $pass = JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_pass', 'ftp_pass', null, 'raw'); - - if ($user != '' && $pass != '') - { - // Add credentials to the session - if (!JClientHelper::setCredentials('ftp', $user, $pass)) - { - JError::raiseWarning(500, JText::_('JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED')); - } - } - } - } - - /** - * Checks the admin has super administrator privileges and then proceeds with the final & cleanup steps. - * - * @return array - * - * @since 3.6.3 - */ - public function finaliseconfirm() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Did a non Super User try do this? - if (!JFactory::getUser()->authorise('core.admin')) - { - throw new RuntimeException(JText::_('JLIB_APPLICATION_ERROR_ACCESS_FORBIDDEN'), 403); - } - - // Get the model - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel('default'); - - // Try to log in - $credentials = array( - 'username' => $this->input->post->get('username', '', 'username'), - 'password' => $this->input->post->get('passwd', '', 'raw'), - 'secretkey' => $this->input->post->get('secretkey', '', 'raw'), - ); - - $result = $model->captiveLogin($credentials); - - // The login fails? - if (!$result) - { - JFactory::getApplication()->enqueueMessage(JText::_('JGLOBAL_AUTH_INVALID_PASS'), 'warning'); - $this->setRedirect('index.php?option=com_joomlaupdate&view=update&layout=finaliseconfirm'); - - return false; - } - - // Redirect back to the actual finalise page - $this->setRedirect('index.php?option=com_joomlaupdate&task=update.finalise&' . JFactory::getSession()->getFormToken() . '=1'); - } -} diff --git a/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php b/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php deleted file mode 100644 index 0044abdfc364e..0000000000000 --- a/administrator/components/com_joomlaupdate/helpers/joomlaupdate.php +++ /dev/null @@ -1,46 +0,0 @@ -authorise('core.manage', 'com_joomlaupdate')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('Joomlaupdate'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_joomlaupdate/joomlaupdate.xml b/administrator/components/com_joomlaupdate/joomlaupdate.xml index c84bfe31608f5..3f9f45548010a 100644 --- a/administrator/components/com_joomlaupdate/joomlaupdate.xml +++ b/administrator/components/com_joomlaupdate/joomlaupdate.xml @@ -9,6 +9,7 @@ www.joomla.org 3.6.2 COM_JOOMLAUPDATE_XML_DESCRIPTION + Joomla\Component\Joomlaupdate js diff --git a/administrator/components/com_joomlaupdate/models/default.php b/administrator/components/com_joomlaupdate/models/default.php deleted file mode 100644 index 6b046699bf8a8..0000000000000 --- a/administrator/components/com_joomlaupdate/models/default.php +++ /dev/null @@ -1,1026 +0,0 @@ -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; - - // "Testing" - case 'testing': - $updateURL = 'https://update.joomla.org/core/test/list_test.xml'; - break; - - // "Custom" - // TODO: check if the customurl is valid and not just "not empty". - case 'custom': - if (trim($params->get('customurl', '')) != '') - { - $updateURL = trim($params->get('customurl', '')); - } - else - { - return JError::raiseWarning(403, JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM_ERROR')); - } - break; - - /** - * "Minor & Patch Release for Current version (recommended and default)". - * The commented "case" below are for documenting where 'default' and legacy options falls - * case 'default': - * case 'lts': - * case 'nochange': - */ - default: - $updateURL = 'https://update.joomla.org/core/list.xml'; - } - - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('us') . '.*') - ->from($db->quoteName('#__update_sites_extensions') . ' AS ' . $db->quoteName('map')) - ->join( - 'INNER', $db->quoteName('#__update_sites') . ' AS ' . $db->quoteName('us') - . ' ON (' . 'us.update_site_id = map.update_site_id)' - ) - ->where('map.extension_id = ' . $db->quote(700)); - $db->setQuery($query); - $update_site = $db->loadObject(); - - if ($update_site->location != $updateURL) - { - // Modify the database record. - $update_site->last_check_timestamp = 0; - $update_site->location = $updateURL; - $db->updateObject('#__update_sites', $update_site, 'update_site_id'); - - // Remove cached updates. - $query->clear() - ->delete($db->quoteName('#__updates')) - ->where($db->quoteName('extension_id') . ' = ' . $db->quote('700')); - $db->setQuery($query); - $db->execute(); - } - } - - /** - * Makes sure that the Joomla! update cache is up-to-date. - * - * @param boolean $force Force reload, ignoring the cache timeout. - * - * @return void - * - * @since 2.5.4 - */ - public function refreshUpdates($force = false) - { - if ($force) - { - $cache_timeout = 0; - } - else - { - $update_params = JComponentHelper::getParams('com_installer'); - $cache_timeout = $update_params->get('cachetimeout', 6, 'int'); - $cache_timeout = 3600 * $cache_timeout; - } - - $updater = JUpdater::getInstance(); - - $reflection = new ReflectionObject($updater); - $reflectionMethod = $reflection->getMethod('findUpdates'); - $methodParameters = $reflectionMethod->getParameters(); - - if (count($methodParameters) >= 4) - { - // Reinstall support is available in JUpdater - $updater->findUpdates(700, $cache_timeout, JUpdater::STABILITY_STABLE, true); - } - else - { - $updater->findUpdates(700, $cache_timeout, JUpdater::STABILITY_STABLE); - } - } - - /** - * Returns an array with the Joomla! update information. - * - * @return array - * - * @since 2.5.4 - */ - public function getUpdateInformation() - { - // Initialise the return array. - $ret = array( - 'installed' => JVERSION, - 'latest' => null, - 'object' => null, - 'hasUpdate' => false - ); - - // Fetch the update information from the database. - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('*') - ->from($db->quoteName('#__updates')) - ->where($db->quoteName('extension_id') . ' = ' . $db->quote(700)); - $db->setQuery($query); - $updateObject = $db->loadObject(); - - if (is_null($updateObject)) - { - $ret['latest'] = JVERSION; - - return $ret; - } - - $ret['latest'] = $updateObject->version; - $ret['hasUpdate'] = $updateObject->version != JVERSION; - - // Fetch the full update details from the update details URL. - jimport('joomla.updater.update'); - $update = new JUpdate; - $update->loadFromXML($updateObject->detailsurl); - - $ret['object'] = $update; - - return $ret; - } - - /** - * Returns an array with the configured FTP options. - * - * @return array - * - * @since 2.5.4 - */ - public function getFTPOptions() - { - $config = JFactory::getConfig(); - - return array( - 'host' => $config->get('ftp_host'), - 'port' => $config->get('ftp_port'), - 'username' => $config->get('ftp_user'), - 'password' => $config->get('ftp_pass'), - 'directory' => $config->get('ftp_root'), - 'enabled' => $config->get('ftp_enable'), - ); - } - - /** - * Removes all of the updates from the table and enable all update streams. - * - * @return boolean Result of operation. - * - * @since 3.0 - */ - 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'); - - $query = $db->getQuery(true) - ->delete($db->quoteName('#__updates')) - ->where($db->quoteName('update_site_id') . ' = ' . $db->quote('1')); - $db->setQuery($query); - - if ($db->execute()) - { - $this->_message = JText::_('COM_JOOMLAUPDATE_CHECKED_UPDATES'); - - return true; - } - else - { - $this->_message = JText::_('COM_JOOMLAUPDATE_FAILED_TO_CHECK_UPDATES'); - - return false; - } - } - - /** - * Downloads the update package to the site. - * - * @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; - $sources = $updateInfo['object']->get('downloadSources', array()); - $headers = get_headers($packageURL, 1); - - // Follow the Location headers until the actual download URL is known - while (isset($headers['Location'])) - { - $packageURL = $headers['Location']; - $headers = get_headers($packageURL, 1); - } - - // Remove protocol, path and query string from URL - $basename = basename($packageURL); - - if (strpos($basename, '?') !== false) - { - $basename = substr($basename, 0, strpos($basename, '?')); - } - - // Find the path to the temp directory and the local package. - $config = JFactory::getConfig(); - $tempdir = $config->get('tmp_path'); - $target = $tempdir . '/' . $basename; - - // Do we have a cached file? - $exists = JFile::exists($target); - - if (!$exists) - { - // Not there, let's fetch it. - $mirror = 0; - - while (!($download = $this->downloadPackage($packageURL, $target)) && isset($sources[$mirror])) - { - $name = $sources[$mirror]; - $packageURL = $name->url; - $mirror++; - } - - return $download; - } - else - { - // Is it a 0-byte file? If so, re-download please. - $filesize = @filesize($target); - - if (empty($filesize)) - { - $mirror = 0; - - while (!($download = $this->downloadPackage($packageURL, $target)) && isset($sources[$mirror])) - { - $name = $sources[$mirror]; - $packageURL = $name->url; - $mirror++; - } - - return $download; - } - - // Yes, it's there, skip downloading. - return $basename; - } - } - - /** - * Downloads a package file to a specific directory - * - * @param string $url The URL to download from - * @param string $target The directory to store the file - * - * @return boolean True on success - * - * @since 2.5.4 - */ - protected function downloadPackage($url, $target) - { - JLoader::import('helpers.download', JPATH_COMPONENT_ADMINISTRATOR); - - try - { - JLog::add(JText::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_URL', $url), JLog::INFO, 'Update'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Get the handler to download the package - try - { - $http = JHttpFactory::getHttp(null, array('curl', 'stream')); - } - catch (RuntimeException $e) - { - return false; - } - - jimport('joomla.filesystem.file'); - - // Make sure the target does not exist. - JFile::delete($target); - - // Download the package - try - { - $result = $http->get($url); - } - catch (RuntimeException $e) - { - return false; - } - - if (!$result || ($result->code != 200 && $result->code != 310)) - { - return false; - } - - // Write the file to disk - JFile::write($target, $result->body); - - return basename($target); - } - - /** - * Create restoration file. - * - * @param string $basename Optional base path to the file. - * - * @return boolean True if successful; false otherwise. - * - * @since 2.5.4 - */ - public function createRestorationFile($basename = null) - { - // Get a password - $password = JUserHelper::genRandomPassword(32); - $app = JFactory::getApplication(); - $app->setUserState('com_joomlaupdate.password', $password); - - // Do we have to use FTP? - $method = JFactory::getApplication()->getUserStateFromRequest('com_joomlaupdate.method', 'method', 'direct', 'cmd'); - - // Get the absolute path to site's root. - $siteroot = JPATH_SITE; - - // If the package name is not specified, get it from the update info. - if (empty($basename)) - { - $updateInfo = $this->getUpdateInformation(); - $packageURL = $updateInfo['object']->downloadurl->_data; - $basename = basename($packageURL); - } - - // Get the package name. - $config = JFactory::getConfig(); - $tempdir = $config->get('tmp_path'); - $file = $tempdir . '/' . $basename; - - $filesize = @filesize($file); - $app->setUserState('com_joomlaupdate.password', $password); - $app->setUserState('com_joomlaupdate.filesize', $filesize); - - $data = " '$password', - 'kickstart.tuning.max_exec_time' => '5', - 'kickstart.tuning.run_time_bias' => '75', - 'kickstart.tuning.min_exec_time' => '0', - 'kickstart.procengine' => '$method', - 'kickstart.setup.sourcefile' => '$file', - 'kickstart.setup.destdir' => '$siteroot', - 'kickstart.setup.restoreperms' => '0', - 'kickstart.setup.filetype' => 'zip', - 'kickstart.setup.dryrun' => '0', - 'kickstart.setup.renamefiles' => array(), - 'kickstart.setup.postrenamefiles' => false -ENDDATA; - - if ($method != 'direct') - { - /* - * Fetch the FTP parameters from the request. Note: The password should be - * allowed as raw mode, otherwise something like !@43H% would be - * sanitised to !@43H% which is just plain wrong. - */ - $ftp_host = $app->input->get('ftp_host', ''); - $ftp_port = $app->input->get('ftp_port', '21'); - $ftp_user = $app->input->get('ftp_user', ''); - $ftp_pass = addcslashes($app->input->get('ftp_pass', '', 'raw'), "'\\"); - $ftp_root = $app->input->get('ftp_root', ''); - - // Is the tempdir really writable? - $writable = @is_writeable($tempdir); - - if ($writable) - { - // Let's be REALLY sure. - $fp = @fopen($tempdir . '/test.txt', 'w'); - - if ($fp === false) - { - $writable = false; - } - else - { - fclose($fp); - unlink($tempdir . '/test.txt'); - } - } - - // If the tempdir is not writable, create a new writable subdirectory. - if (!$writable) - { - $FTPOptions = JClientHelper::getCredentials('ftp'); - $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); - $dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $tempdir . '/admintools'), '/'); - - if (!@mkdir($tempdir . '/admintools')) - { - $ftp->mkdir($dest); - } - - if (!@chmod($tempdir . '/admintools', 511)) - { - $ftp->chmod($dest, 511); - } - - $tempdir .= '/admintools'; - } - - // Just in case the temp-directory was off-root, try using the default tmp directory. - $writable = @is_writeable($tempdir); - - if (!$writable) - { - $tempdir = JPATH_ROOT . '/tmp'; - - // Does the JPATH_ROOT/tmp directory exist? - if (!is_dir($tempdir)) - { - JFolder::create($tempdir, 511); - $htaccessContents = "order deny,allow\ndeny from all\nallow from none\n"; - JFile::write($tempdir . '/.htaccess', $htaccessContents); - } - - // If it exists and it is unwritable, try creating a writable admintools subdirectory. - if (!is_writable($tempdir)) - { - $FTPOptions = JClientHelper::getCredentials('ftp'); - $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); - $dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $tempdir . '/admintools'), '/'); - - if (!@mkdir($tempdir . '/admintools')) - { - $ftp->mkdir($dest); - } - - if (!@chmod($tempdir . '/admintools', 511)) - { - $ftp->chmod($dest, 511); - } - - $tempdir .= '/admintools'; - } - } - - // If we still have no writable directory, we'll try /tmp and the system's temp-directory. - $writable = @is_writeable($tempdir); - - if (!$writable) - { - if (@is_dir('/tmp') && @is_writable('/tmp')) - { - $tempdir = '/tmp'; - } - else - { - // Try to find the system temp path. - $tmpfile = @tempnam('dummy', ''); - $systemp = @dirname($tmpfile); - @unlink($tmpfile); - - if (!empty($systemp)) - { - if (@is_dir($systemp) && @is_writable($systemp)) - { - $tempdir = $systemp; - } - } - } - } - - $data .= << '0', - 'kickstart.ftp.passive' => '1', - 'kickstart.ftp.host' => '$ftp_host', - 'kickstart.ftp.port' => '$ftp_port', - 'kickstart.ftp.user' => '$ftp_user', - 'kickstart.ftp.pass' => '$ftp_pass', - 'kickstart.ftp.dir' => '$ftp_root', - 'kickstart.ftp.tempdir' => '$tempdir' -ENDDATA; - } - - $data .= ');'; - - // Remove the old file, if it's there... - $configpath = JPATH_COMPONENT_ADMINISTRATOR . '/restoration.php'; - - if (JFile::exists($configpath)) - { - JFile::delete($configpath); - } - - // Write new file. First try with JFile. - $result = JFile::write($configpath, $data); - - // In case JFile used FTP but direct access could help. - if (!$result) - { - if (function_exists('file_put_contents')) - { - $result = @file_put_contents($configpath, $data); - - if ($result !== false) - { - $result = true; - } - } - else - { - $fp = @fopen($configpath, 'wt'); - - if ($fp !== false) - { - $result = @fwrite($fp, $data); - - if ($result !== false) - { - $result = true; - } - - @fclose($fp); - } - } - } - - return $result; - } - - /** - * Runs the schema update SQL files, the PHP update script and updates the - * manifest cache and #__extensions entry. Essentially, it is identical to - * JInstallerFile::install() without the file copy. - * - * @return boolean True on success. - * - * @since 2.5.4 - */ - public function finaliseUpgrade() - { - $installer = JInstaller::getInstance(); - - $manifest = $installer->isManifest(JPATH_MANIFESTS . '/files/joomla.xml'); - - if ($manifest === false) - { - $installer->abort(JText::_('JLIB_INSTALLER_ABORT_DETECTMANIFEST')); - - return false; - } - - $installer->manifest = $manifest; - - $installer->setUpgrade(true); - $installer->setOverwrite(true); - - $installer->extension = JTable::getInstance('extension'); - $installer->extension->load(700); - - $installer->setAdapter($installer->extension->type); - - $installer->setPath('manifest', JPATH_MANIFESTS . '/files/joomla.xml'); - $installer->setPath('source', JPATH_MANIFESTS . '/files'); - $installer->setPath('extension_root', JPATH_ROOT); - - // Run the script file. - JLoader::register('JoomlaInstallerScript', JPATH_ADMINISTRATOR . '/components/com_admin/script.php'); - - $manifestClass = new JoomlaInstallerScript; - - ob_start(); - ob_implicit_flush(false); - - if ($manifestClass && method_exists($manifestClass, 'preflight')) - { - if ($manifestClass->preflight('update', $installer) === false) - { - $installer->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE')); - - return false; - } - } - - // Create msg object; first use here. - $msg = ob_get_contents(); - ob_end_clean(); - - // Get a database connector object. - $db = $this->getDbo(); - - /* - * Check to see if a file extension by the same name is already installed. - * If it is, then update the table because if the files aren't there - * we can assume that it was (badly) uninstalled. - * If it isn't, add an entry to extensions. - */ - $query = $db->getQuery(true) - ->select($db->quoteName('extension_id')) - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('type') . ' = ' . $db->quote('file')) - ->where($db->quoteName('element') . ' = ' . $db->quote('joomla')); - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (RuntimeException $e) - { - // Install failed, roll back changes. - $installer->abort( - JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_UPDATE'), $e->getMessage()) - ); - - return false; - } - - $id = $db->loadResult(); - $row = JTable::getInstance('extension'); - - if ($id) - { - // Load the entry and update the manifest_cache. - $row->load($id); - - // Update name. - $row->set('name', 'files_joomla'); - - // Update manifest. - $row->manifest_cache = $installer->generateManifestCache(); - - if (!$row->store()) - { - // Install failed, roll back changes. - $installer->abort( - JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_UPDATE'), $row->getError()) - ); - - return false; - } - } - else - { - // Add an entry to the extension table with a whole heap of defaults. - $row->set('name', 'files_joomla'); - $row->set('type', 'file'); - $row->set('element', 'joomla'); - - // There is no folder for files so leave it blank. - $row->set('folder', ''); - $row->set('enabled', 1); - $row->set('protected', 0); - $row->set('access', 0); - $row->set('client_id', 0); - $row->set('params', ''); - $row->set('system_data', ''); - $row->set('manifest_cache', $installer->generateManifestCache()); - - if (!$row->store()) - { - // Install failed, roll back changes. - $installer->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_ROLLBACK', $row->getError())); - - return false; - } - - // Set the insert id. - $row->set('extension_id', $db->insertid()); - - // Since we have created a module item, we add it to the installation step stack - // so that if we have to rollback the changes we can undo it. - $installer->pushStep(array('type' => 'extension', 'extension_id' => $row->extension_id)); - } - - $result = $installer->parseSchemaUpdates($manifest->update->schemas, $row->extension_id); - - if ($result === false) - { - // Install failed, rollback changes. - $installer->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_UPDATE_SQL_ERROR', $db->stderr(true))); - - return false; - } - - // Start Joomla! 1.6. - ob_start(); - ob_implicit_flush(false); - - if ($manifestClass && method_exists($manifestClass, 'update')) - { - if ($manifestClass->update($installer) === false) - { - // Install failed, rollback changes. - $installer->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE')); - - return false; - } - } - - // Append messages. - $msg .= ob_get_contents(); - ob_end_clean(); - - // Clobber any possible pending updates. - $update = JTable::getInstance('update'); - $uid = $update->find( - array('element' => 'joomla', 'type' => 'file', 'client_id' => '0', 'folder' => '') - ); - - if ($uid) - { - $update->delete($uid); - } - - // And now we run the postflight. - ob_start(); - ob_implicit_flush(false); - - if ($manifestClass && method_exists($manifestClass, 'postflight')) - { - $manifestClass->postflight('update', $installer); - } - - // Append messages. - $msg .= ob_get_contents(); - ob_end_clean(); - - if ($msg != '') - { - $installer->set('extension_message', $msg); - } - - // Refresh versionable assets cache. - JFactory::getApplication()->flushAssets(); - - return true; - } - - /** - * Removes the extracted package file. - * - * @return void - * - * @since 2.5.4 - */ - public function cleanUp() - { - // Remove the update package. - $config = JFactory::getConfig(); - $tempdir = $config->get('tmp_path'); - - $file = JFactory::getApplication()->getUserState('com_joomlaupdate.file', null); - $target = $tempdir . '/' . $file; - - if (!@unlink($target)) - { - JFile::delete($target); - } - - // Remove the restoration.php file. - $target = JPATH_COMPONENT_ADMINISTRATOR . '/restoration.php'; - - if (!@unlink($target)) - { - JFile::delete($target); - } - - // Remove joomla.xml from the site's root. - $target = JPATH_ROOT . '/joomla.xml'; - - if (!@unlink($target)) - { - JFile::delete($target); - } - - // Unset the update filename from the session. - JFactory::getApplication()->setUserState('com_joomlaupdate.file', null); - } - - /** - * Uploads what is presumably an update ZIP file under a mangled name in the temporary directory. - * - * @return void - * - * @since 3.6.0 - */ - public function upload() - { - // Get the uploaded file information. - $input = JFactory::getApplication()->input; - - // Do not change the filter type 'raw'. We need this to let files containing PHP code to upload. See JInputFiles::get. - $userfile = $input->files->get('install_package', null, 'raw'); - - // Make sure that file uploads are enabled in php. - if (!(bool) ini_get('file_uploads')) - { - throw new RuntimeException(JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLFILE'), 500); - } - - // 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); - } - - // If there is no uploaded file, we have a problem... - if (!is_array($userfile)) - { - throw new RuntimeException(JText::_('COM_INSTALLER_MSG_INSTALL_NO_FILE_SELECTED'), 500); - } - - // Is the PHP tmp directory missing? - if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_NO_TMP_DIR)) - { - throw new RuntimeException( - JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . - JText::_('COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET'), - 500 - ); - } - - // Is the max upload size too small in php.ini? - if ($userfile['error'] && ($userfile['error'] == UPLOAD_ERR_INI_SIZE)) - { - throw new RuntimeException( - JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR') . '
' . JText::_('COM_INSTALLER_MSG_WARNINGS_SMALLUPLOADSIZE'), - 500 - ); - } - - // Check if there was a different problem uploading the file. - if ($userfile['error'] || $userfile['size'] < 1) - { - throw new RuntimeException(JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR'), 500); - } - - // Build the appropriate paths. - $config = JFactory::getConfig(); - $tmp_dest = tempnam($config->get('tmp_path'), 'ju'); - $tmp_src = $userfile['tmp_name']; - - // Move uploaded file. - jimport('joomla.filesystem.file'); - - if (version_compare(JVERSION, '3.4.0', 'ge')) - { - $result = JFile::upload($tmp_src, $tmp_dest, false, true); - } - else - { - // Old Joomla! versions didn't have UploadShield and don't need the fourth parameter to accept uploads - $result = JFile::upload($tmp_src, $tmp_dest); - } - - if (!$result) - { - throw new RuntimeException(JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR'), 500); - } - - JFactory::getApplication()->setUserState('com_joomlaupdate.temp_file', $tmp_dest); - } - - /** - * Checks the super admin credentials are valid for the currently logged in users - * - * @param array $credentials The credentials to authenticate the user with - * - * @return boolean - * - * @since 3.6.0 - */ - public function captiveLogin($credentials) - { - // Make sure the username matches - $username = isset($credentials['username']) ? $credentials['username'] : null; - $user = JFactory::getUser(); - - if (strtolower($user->username) != strtolower($username)) - { - return false; - } - - // Make sure the user we're authorising is a Super User - if (!$user->authorise('core.admin')) - { - return false; - } - - // Get the global JAuthentication object. - $authenticate = JAuthentication::getInstance(); - $response = $authenticate->authenticate($credentials); - - if ($response->status !== JAuthentication::STATUS_SUCCESS) - { - return false; - } - - return true; - } - - /** - * Does the captive (temporary) file we uploaded before still exist? - * - * @return boolean - * - * @since 3.6.0 - */ - public function captiveFileExists() - { - $file = JFactory::getApplication()->getUserState('com_joomlaupdate.temp_file', null); - - JLoader::import('joomla.filesystem.file'); - - if (empty($file) || !JFile::exists($file)) - { - return false; - } - - return true; - } - - /** - * Remove the captive (temporary) file we uploaded before and the . - * - * @return void - * - * @since 3.6.0 - */ - public function removePackageFiles() - { - $files = array( - JFactory::getApplication()->getUserState('com_joomlaupdate.temp_file', null), - JFactory::getApplication()->getUserState('com_joomlaupdate.file', null), - ); - - JLoader::import('joomla.filesystem.file'); - - foreach ($files as $file) - { - if (JFile::exists($file)) - { - if (!@unlink($file)) - { - JFile::delete($file); - } - } - } - } -} diff --git a/administrator/components/com_joomlaupdate/restore.php b/administrator/components/com_joomlaupdate/restore.php index 4c16959c42f82..2f5f2ebec2384 100644 --- a/administrator/components/com_joomlaupdate/restore.php +++ b/administrator/components/com_joomlaupdate/restore.php @@ -123,11 +123,6 @@ function getQueryParam($key, $default = null) $value = $_REQUEST[$key]; } - if (get_magic_quotes_gpc() && !is_null($value)) - { - $value = stripslashes($value); - } - return $value; } @@ -1354,7 +1349,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); } @@ -4190,7 +4185,7 @@ private function processTypeLink() } } - $filename = isset($this->fileHeader->realFile) ? $this->fileHeader->realFile : $this->fileHeader->file; + $filename = $this->fileHeader->realFile ?? $this->fileHeader->file; if (!AKFactory::get('kickstart.setup.dryrun', '0')) { diff --git a/administrator/components/com_joomlaupdate/restore_finalisation.php b/administrator/components/com_joomlaupdate/restore_finalisation.php index 24eaa99a52694..78f4730b1b010 100644 --- a/administrator/components/com_joomlaupdate/restore_finalisation.php +++ b/administrator/components/com_joomlaupdate/restore_finalisation.php @@ -5,186 +5,194 @@ * * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt + * + * Important Notes: + * - Unlike other files, this file requires multiple namespace declarations in order to overload core classes during the update process + * - Also unlike other files, the normal constant defined checks must be within the global namespace declaration and can't be outside of it */ -// Require the restoration environment or fail cold. Prevents direct web access. -defined('_AKEEBA_RESTORATION') or die(); - -// Fake a miniature Joomla environment -if (!defined('_JEXEC')) +namespace { - define('_JEXEC', 1); -} + // Require the restoration environment or fail cold. Prevents direct web access. + defined('_AKEEBA_RESTORATION') or die(); -if (!function_exists('jimport')) -{ - /** - * We don't use it but the post-update script is using it anyway, so LET'S FAKE IT! - * - * @param string $path A dot syntax path. - * @param string $base Search this directory for the class. - * - * @return boolean True on success. - * - * @since 11.1 - */ - function jimport($path, $base = null) + // Fake a miniature Joomla environment + if (!defined('_JEXEC')) { - // Do nothing + define('_JEXEC', 1); } -} -// Fake the JFile class, mapping it to Restore's post-processing class -if (!class_exists('JFile')) -{ - /** - * JFile mock class proxing behaviour in the post-upgrade script to that of either native PHP or restore.php - * - * @since 3.5.1 - */ - abstract class JFile + if (!function_exists('jimport')) { /** - * Proxies checking a folder exists to the native php version + * We don't use it but the post-update script is using it anyway, so LET'S FAKE IT! * - * @param string $fileName The path to the file to be checked + * @param string $path A dot syntax path. + * @param string $base Search this directory for the class. * - * @return boolean + * @return boolean True on success. * - * @since 3.5.1 + * @since 11.1 */ - public static function exists($fileName) + function jimport($path, $base = null) { - return @file_exists($fileName); + // Do nothing } + } + if (!function_exists('finalizeRestore')) + { /** - * Proxies deleting a file to the restore.php version + * Run part of the Joomla! finalisation script, namely the part that cleans up unused files/folders * - * @param string $fileName The path to the file to be deleted + * @param string $siteRoot The root to the Joomla! site + * @param string $restorePath The base path to restore.php * - * @return boolean + * @return void * * @since 3.5.1 */ - public static function delete($fileName) + function finalizeRestore($siteRoot, $restorePath) { - $postproc = AKFactory::getPostProc(); - $postproc->unlink($fileName); + if (!defined('JPATH_ROOT')) + { + define('JPATH_ROOT', $siteRoot); + } + + $filePath = JPATH_ROOT . '/administrator/components/com_admin/script.php'; + + if (file_exists($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 + if (class_exists('JoomlaInstallerScript')) + { + (new JoomlaInstallerScript)->deleteUnexistingFiles(); + } + + // Clear OPcache + if (function_exists('opcache_reset')) + { + opcache_reset(); + } } } } -// Fake the JFolder class, mapping it to Restore's post-processing class -if (!class_exists('JFolder')) +namespace Joomla\CMS\Filesystem { - /** - * JFolder mock class proxing behaviour in the post-upgrade script to that of either native PHP or restore.php - * - * @since 3.5.1 - */ - abstract class JFolder + // Fake the JFile class, mapping it to Restore's post-processing class + if (!class_exists('File')) { /** - * Proxies checking a folder exists to the native php version - * - * @param string $folderName The path to the folder to be checked + * JFile mock class proxing behaviour in the post-upgrade script to that of either native PHP or restore.php * - * @return boolean - * - * @since 3.5.1 + * @since 3.5.1 */ - public static function exists($folderName) + abstract class File { - return @is_dir($folderName); - } + /** + * Proxies checking a folder exists to the native php version + * + * @param string $fileName The path to the file to be checked + * + * @return boolean + * + * @since 3.5.1 + */ + public static function exists($fileName) + { + return @file_exists($fileName); + } - /** - * Proxies deleting a folder to the restore.php version - * - * @param string $folderName The path to the folder to be deleted - * - * @return void - * - * @since 3.5.1 - */ - public static function delete($folderName) - { - recursive_remove_directory($folderName); + /** + * Proxies deleting a file to the restore.php version + * + * @param string $fileName The path to the file to be deleted + * + * @return boolean + * + * @since 3.5.1 + */ + public static function delete($fileName) + { + $postproc = AKFactory::getPostProc(); + $postproc->unlink($fileName); + } } } -} -// Fake the JText class - we aren't going to show errors to people anyhow -if (!class_exists('JText')) -{ - /** - * JText mock class proxing behaviour in the post-upgrade script to that of either native PHP or restore.php - * - * @since 3.5.1 - */ - abstract class JText + // Fake the Folder class, mapping it to Restore's post-processing class + if (!class_exists('Folder')) { /** - * No need for translations in a non-interactive script, so always return an empty string here - * - * @param string $text A language constant - * - * @return string + * Folder mock class proxing behaviour in the post-upgrade script to that of either native PHP or restore.php * - * @since 3.5.1 + * @since 3.5.1 */ - public static function sprintf($text) + abstract class Folder { - return ''; + /** + * Proxies checking a folder exists to the native php version + * + * @param string $folderName The path to the folder to be checked + * + * @return boolean + * + * @since 3.5.1 + */ + public static function exists($folderName) + { + return @is_dir($folderName); + } + + /** + * Proxies deleting a folder to the restore.php version + * + * @param string $folderName The path to the folder to be deleted + * + * @return void + * + * @since 3.5.1 + */ + public static function delete($folderName) + { + recursive_remove_directory($folderName); + } } } } -if (!function_exists('finalizeRestore')) +namespace Joomla\CMS\Language { - /** - * Run part of the Joomla! finalisation script, namely the part that cleans up unused files/folders - * - * @param string $siteRoot The root to the Joomla! site - * @param string $restorePath The base path to restore.php - * - * @return void - * - * @since 3.5.1 - */ - function finalizeRestore($siteRoot, $restorePath) + // Fake the Text class - we aren't going to show errors to people anyhow + if (!class_exists('Text')) { - if (!defined('JPATH_ROOT')) - { - define('JPATH_ROOT', $siteRoot); - } - - $filePath = JPATH_ROOT . '/administrator/components/com_admin/script.php'; - - if (file_exists($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 - if (class_exists('JoomlaInstallerScript')) - { - $script = new JoomlaInstallerScript; - $script->deleteUnexistingFiles(); - } - - // Clear OPcache - if (function_exists('opcache_reset')) - { - opcache_reset(); - } - elseif (function_exists('apc_clear_cache')) + /** + * Text mock class proxing behaviour in the post-upgrade script to that of either native PHP or restore.php + * + * @since 3.5.1 + */ + abstract class Text { - @apc_clear_cache(); + /** + * No need for translations in a non-interactive script, so always return an empty string here + * + * @param string $text A language constant + * + * @return string + * + * @since 3.5.1 + */ + public static function sprintf($text) + { + return ''; + } } } } diff --git a/administrator/components/com_joomlaupdate/services/provider.php b/administrator/components/com_joomlaupdate/services/provider.php new file mode 100644 index 0000000000000..f6dad31cf419e --- /dev/null +++ b/administrator/components/com_joomlaupdate/services/provider.php @@ -0,0 +1,54 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Joomlaupdate')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Joomlaupdate')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/complete.php b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/complete.php new file mode 100644 index 0000000000000..00a27ed2cc507 --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/complete.php @@ -0,0 +1,27 @@ + + +
+ + + + +
+
+ + +
diff --git a/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default.php b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default.php new file mode 100644 index 0000000000000..eba5dd9e597a8 --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default.php @@ -0,0 +1,83 @@ + 'auto', 'relative' => true)); +Text::script('COM_INSTALLER_MSG_INSTALL_PLEASE_SELECT_A_PACKAGE', true); +Text::script('JYES'); +Text::script('JNO'); +Text::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_VERSION_MISSING'); +Text::script('COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_WARNING_UNKNOWN'); + +$latestJoomlaVersion = $this->updateInfo['latest']; +?> + +
+ showUploadAndUpdate) : ?> + $this->shouldDisplayPreUpdateCheck() ? 'pre-update-check' : 'online-update')); ?> + shouldDisplayPreUpdateCheck()) : ?> + + loadTemplate('preupdatecheck'); ?> + + + + + +
+ + selfUpdate) : ?> + + enqueueMessage(Text::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALL_SELF_UPDATE_FIRST'), 'error'); ?> + loadTemplate('updatemefirst'); ?> + + updateInfo['object']->downloadurl->_data) + && $this->updateInfo['installed'] < $this->updateInfo['latest']) + || !$this->getModel()->isDatabaseTypeSupported() + || !$this->getModel()->isPhpVersionSupported()) : ?> + + loadTemplate('nodownload'); ?> + updateInfo['hasUpdate']) : ?> + + loadTemplate('reinstall'); ?> + + + loadTemplate('update'); ?> + + + + + + + +
+ + + showUploadAndUpdate) : ?> + + + loadTemplate('upload'); ?> + + + + + +
+
diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default.xml b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_joomlaupdate/views/default/tmpl/default.xml rename to administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default.xml diff --git a/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_nodownload.php b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_nodownload.php new file mode 100644 index 0000000000000..05be6a6fab7c2 --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_nodownload.php @@ -0,0 +1,44 @@ + + +
+ 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/tmpl/joomlaupdate/default_preupdatecheck.php b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_preupdatecheck.php new file mode 100644 index 0000000000000..afe305b286ece --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_preupdatecheck.php @@ -0,0 +1,133 @@ + + +

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

+ +
+
+ + + + + + phpOptions as $option) : ?> + + + + + + +
+ label; ?> + + + state ? 'JYES' : 'JNO'); ?> + notice) : ?> + + + +
+
+ +
+ + + +

+ +

+ + + + + + + + + + + phpSettings as $setting) : ?> + + + + + + + +
+ + + + + +
+ label; ?> + + recommended ? 'JON' : 'JOFF'); ?> + + + state ? 'JON' : 'JOFF'); ?> + +
+
+
+ +
+
+ + + + + + + + + + + + + + nonCoreExtensions as $extension) : ?> + + + + + + + +
+ + + + + +
+ name); ?> + + + + version; ?> +
+
+
+ +

+

+

diff --git a/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_reinstall.php b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_reinstall.php new file mode 100644 index 0000000000000..a283afdce09a5 --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_reinstall.php @@ -0,0 +1,111 @@ + +
+ +

langKey, $this->updateSourceKey); ?>

+ + + + updateInfo['object']) && ($this->updateInfo['object'] instanceof Update)) : ?> + + + + + + + updateInfo['object']->get('infourl')->_data) + && isset($this->updateInfo['object']->get('infourl')->title)) : ?> + + + + + + + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + + + + + + + +
+ + + + updateInfo['object']->downloadurl->_data; ?> + +
+ + + + updateInfo['object']->get('infourl')->title; ?> + +
+ + + methodSelect; ?> +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
  + +
+ + +
diff --git a/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_update.php b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_update.php new file mode 100644 index 0000000000000..ba30b96d1a6e2 --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_update.php @@ -0,0 +1,126 @@ + + +
+ + + +

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

+ + + + + + + + + + + + + + + + updateInfo['object']->get('infourl')->_data) + && isset($this->updateInfo['object']->get('infourl')->title)) : ?> + + + + + + + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + + + + + + + +
+ + + updateInfo['installed']; ?> +
+ + + updateInfo['latest']; ?> +
+ + + + updateInfo['object']->downloadurl->_data; ?> + +
+ + + + updateInfo['object']->get('infourl')->title; ?> + +
+ + + methodSelect; ?> +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
  + +
+
diff --git a/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_updatemefirst.php b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_updatemefirst.php new file mode 100644 index 0000000000000..dba036fbd0dad --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_updatemefirst.php @@ -0,0 +1,19 @@ + + +
+ +

+
diff --git a/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_upload.php b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_upload.php new file mode 100644 index 0000000000000..00a4d3b75a977 --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/joomlaupdate/default_upload.php @@ -0,0 +1,128 @@ + + + +

+ + +

+
+ +warnings)) : ?> +
+ + + + + + 'warning' . $i)); ?> + warnings as $message) : ?> + + + + + + + + +
+ + +
+
+ + + + + + + + + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + ftpFieldsDisplay; ?>> + + + + + + + + + + +
+ + + + + +
+ + + methodSelectUpload; ?> +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
  + +
+
+ + + + + +
diff --git a/administrator/components/com_joomlaupdate/tmpl/update/default.php b/administrator/components/com_joomlaupdate/tmpl/update/default.php new file mode 100644 index 0000000000000..ab5ec6baedc60 --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/update/default.php @@ -0,0 +1,66 @@ + 'auto', 'relative' => true)); +HTMLHelper::_('script', 'com_joomlaupdate/update.js', array('version' => 'auto', 'relative' => true)); + +$password = Factory::getApplication()->getUserState('com_joomlaupdate.password', null); +$filesize = Factory::getApplication()->getUserState('com_joomlaupdate.filesize', null); +$ajaxUrl = Uri::base() . 'components/com_joomlaupdate/restore.php'; +$returnUrl = 'index.php?option=com_joomlaupdate&task=update.finalise&' . Factory::getSession()->getFormToken() . '=1'; + +HTMLHelper::_('script', 'com_joomlaupdate/admin-update-default.js', ['relative' => true, 'version' => 'auto']); + +Factory::getDocument()->addScriptOptions( + 'joomlaupdate', + [ + 'password' => $password, + 'totalsize' => $filesize, + 'ajax_url' => $ajaxUrl, + 'return_url' => $returnUrl, + ] +); +?> + +

+ +
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
diff --git a/administrator/components/com_joomlaupdate/tmpl/update/finaliseconfirm.php b/administrator/components/com_joomlaupdate/tmpl/update/finaliseconfirm.php new file mode 100644 index 0000000000000..a4ade3046ed10 --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/update/finaliseconfirm.php @@ -0,0 +1,101 @@ + + + +

+ +

+

+ get('sitename')); ?> +

+
+ +
+ +
+
+
+
+
+ + + + + + + +
+
+
+
+
+
+ + + + + + + +
+
+
+ 1) : ?> +
+
+
+ + + + + + + +
+
+
+ +
+
+
+ + + + +
+
+
+ + + + +
+
diff --git a/administrator/components/com_joomlaupdate/tmpl/upload/captive.php b/administrator/components/com_joomlaupdate/tmpl/upload/captive.php new file mode 100644 index 0000000000000..c1d8d16473b39 --- /dev/null +++ b/administrator/components/com_joomlaupdate/tmpl/upload/captive.php @@ -0,0 +1,101 @@ + + + +

+ +

+

+ get('sitename')); ?> +

+
+ +
+ +
+
+
+
+
+ + + + + + + +
+
+
+
+
+
+ + + + + + + +
+
+
+ 1) : ?> +
+
+
+ + + + + + + +
+
+
+ +
+
+
+ + + + +
+
+
+ + + + +
+
diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php b/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php deleted file mode 100644 index 45b2f9c6847db..0000000000000 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/complete.php +++ /dev/null @@ -1,24 +0,0 @@ - - -
- - - -

- -

-
-
- - -
diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default.php deleted file mode 100644 index cbeacb47c4d19..0000000000000 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default.php +++ /dev/null @@ -1,83 +0,0 @@ - 'auto', 'relative' => true)); - -JFactory::getDocument()->addScriptDeclaration(" -jQuery(document).ready(function($) { - $('#extraction_method').change(function(e){ - extractionMethodHandler('#extraction_method', 'row_ftp'); - }); - $('#upload_method').change(function(e){ - extractionMethodHandler('#upload_method', 'upload_ftp'); - }); - - $('button.submit').on('click', function() { - $('div.download_message').show(); - }); -});"); -?> - -
- - showUploadAndUpdate) : ?> - 'online-update')); ?> - - - -
- - selfUpdate) : ?> - - enqueueMessage(JText::_('COM_JOOMLAUPDATE_VIEW_DEFAULT_INSTALL_SELF_UPDATE_FIRST'), 'error'); ?> - loadTemplate('updatemefirst'); ?> - - updateInfo['object']->downloadurl->_data) && $this->updateInfo['installed'] < $this->updateInfo['latest']) : ?> - - loadTemplate('nodownload'); ?> - updateInfo['hasUpdate']) : ?> - - loadTemplate('reinstall'); ?> - - - loadTemplate('update'); ?> - - - - - - - -
- - - showUploadAndUpdate) : ?> - - - loadTemplate('upload'); ?> - - - - - -
-
diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php deleted file mode 100644 index 9ea9f1a01c264..0000000000000 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_nodownload.php +++ /dev/null @@ -1,21 +0,0 @@ - - -
- - - -

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

-
diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php deleted file mode 100644 index d124c14d79bde..0000000000000 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_reinstall.php +++ /dev/null @@ -1,116 +0,0 @@ - -
- - - -

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

- -
- -
- - updateInfo['object']) && ($this->updateInfo['object'] instanceof JUpdate)) : ?> - - - - - - - updateInfo['object']->get('infourl')->_data) - && isset($this->updateInfo['object']->get('infourl')->title)) : ?> - - - - - - - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - - - - - - - -
- - - - updateInfo['object']->downloadurl->_data; ?> - -
- - - - updateInfo['object']->get('infourl')->title; ?> - -
- - - methodSelect; ?> -
- - - -
- - - -
- - - -
- - - -
- - - -
-   - - -
- - -
diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php deleted file mode 100644 index 5b5bd3cf63d1e..0000000000000 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_update.php +++ /dev/null @@ -1,125 +0,0 @@ - -
- - - -

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

- - - - - - - - - - - - - - - - updateInfo['object']->get('infourl')->_data) - && isset($this->updateInfo['object']->get('infourl')->title)) : ?> - - - - - - - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - - - - - - - -
- - - updateInfo['installed']; ?> -
- - - updateInfo['latest']; ?> -
- - - - updateInfo['object']->downloadurl->_data; ?> - -
- - - - updateInfo['object']->get('infourl')->title; ?> - -
- - - methodSelect; ?> -
- - - -
- - - -
- - - -
- - - -
- - - -
-   - - -
-
diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php deleted file mode 100644 index 8cf3621599414..0000000000000 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_updatemefirst.php +++ /dev/null @@ -1,21 +0,0 @@ - - -
- - - -

- -

-
diff --git a/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php b/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php deleted file mode 100644 index f745d06486322..0000000000000 --- a/administrator/components/com_joomlaupdate/views/default/tmpl/default_upload.php +++ /dev/null @@ -1,170 +0,0 @@ -addScriptDeclaration($js); - -$ajaxLoaderImage = JHtml::_('image', 'jui/ajax-loader.gif', '', null, true, true); -$css = <<< CSS - #loading { - background: rgba(255, 255, 255, .8) url('$ajaxLoaderImage') 50% 15% no-repeat; - position: fixed; - opacity: 1; - -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity = 80); - filter: alpha(opacity = 80); - overflow: hidden; - } -CSS; -JFactory::getDocument()->addStyleDeclaration($css); -?> - -
-

- - -

-
- -warnings)) : ?> -
- - - - - - 'warning' . $i)); ?> - warnings as $message) : ?> - - - - - - - - -
- - -
-
- - - - - - - - - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - ftpFieldsDisplay; ?>> - - - - - - - - - - -
- - -
- - -
- - - methodSelectUpload; ?> -
- - - -
- - - -
- - - -
- - - -
- - - -
-   - - -
-
- - - - - -
diff --git a/administrator/components/com_joomlaupdate/views/default/view.html.php b/administrator/components/com_joomlaupdate/views/default/view.html.php deleted file mode 100644 index bf818032ed2be..0000000000000 --- a/administrator/components/com_joomlaupdate/views/default/view.html.php +++ /dev/null @@ -1,220 +0,0 @@ -state = $this->get('State'); - - // Load useful classes. - /** @var JoomlaupdateModelDefault $model */ - $model = $this->getModel(); - $this->loadHelper('select'); - - // Assign view variables. - $ftp = $model->getFTPOptions(); - $defaultMethod = $ftp['enabled'] ? 'hybrid' : 'direct'; - - $this->updateInfo = $model->getUpdateInformation(); - $this->methodSelect = JoomlaupdateHelperSelect::getMethods($defaultMethod); - $this->methodSelectUpload = JoomlaupdateHelperSelect::getMethods($defaultMethod, 'method', 'upload_method'); - - // 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')) - { - JToolbarHelper::preferences('com_joomlaupdate'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_COMPONENTS_JOOMLA_UPDATE'); - - 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'); - } - - $this->ftpFieldsDisplay = $this->ftp['enabled'] ? '' : 'style = "display: none"'; - $params = JComponentHelper::getParams('com_joomlaupdate'); - - 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'); - break; - - // "Testing" - case 'testing': - $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_TESTING'; - $this->updateSourceKey = JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_TESTING'); - break; - - // "Custom" - case 'custom': - $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_CUSTOM'; - $this->updateSourceKey = JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM'); - break; - - /** - * "Minor & Patch Release for Current version (recommended and default)". - * The commented "case" below are for documenting where 'default' and legacy options falls - * case 'default': - * case 'lts': - * case 'nochange': - */ - default: - $this->langKey = 'COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_DEFAULT'; - $this->updateSourceKey = JText::_('COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_DEFAULT'); - } - - $this->warnings = array(); - /** @var InstallerModelWarnings $warningsModel */ - $warningsModel = $this->getModel('warnings'); - - if (is_object($warningsModel) && $warningsModel instanceof JModelLegacy) - { - $language = JFactory::getLanguage(); - $language->load('com_installer', JPATH_ADMINISTRATOR, 'en-GB', false, true); - $language->load('com_installer', JPATH_ADMINISTRATOR, null, true); - - $this->warnings = $warningsModel->getItems(); - } - - $this->selfUpdate = $this->checkForSelfUpdate(); - - // Only Super Users have access to the Update & Install for obvious security reasons - $this->showUploadAndUpdate = JFactory::getUser()->authorise('core.admin'); - - // Remove temporary files - $model->removePackageFiles(); - - // Render the view. - parent::display($tpl); - } - - /** - * Makes sure that the Joomla! Update Component Update is in the database and check if there is a new version. - * - * @return boolean True if there is an update else false - * - * @since 3.6.3 - */ - private function checkForSelfUpdate() - { - $db = JFactory::getDbo(); - - $query = $db->getQuery(true) - ->select($db->quoteName('extension_id')) - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('element') . ' = ' . $db->quote('com_joomlaupdate')); - $db->setQuery($query); - - try - { - // Get the component extension ID - $joomlaUpdateComponentId = $db->loadResult(); - } - catch (RuntimeException $e) - { - // Something is wrong here! - $joomlaUpdateComponentId = 0; - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); - } - - // Try the update only if we have an extension id - if ($joomlaUpdateComponentId != 0) - { - // Allways force to check for an update! - $cache_timeout = 0; - - $updater = JUpdater::getInstance(); - $updater->findUpdates($joomlaUpdateComponentId, $cache_timeout, JUpdater::STABILITY_STABLE); - - // Fetch the update information from the database. - $query = $db->getQuery(true) - ->select('*') - ->from($db->quoteName('#__updates')) - ->where($db->quoteName('extension_id') . ' = ' . $db->quote($joomlaUpdateComponentId)); - $db->setQuery($query); - - try - { - $joomlaUpdateComponentObject = $db->loadObject(); - } - catch (RuntimeException $e) - { - // Something is wrong here! - $joomlaUpdateComponentObject = null; - JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error'); - } - - if (is_null($joomlaUpdateComponentObject)) - { - // No Update great! - return false; - } - - return true; - } - } -} diff --git a/administrator/components/com_joomlaupdate/views/update/tmpl/default.php b/administrator/components/com_joomlaupdate/views/update/tmpl/default.php deleted file mode 100644 index cba3286f460c6..0000000000000 --- a/administrator/components/com_joomlaupdate/views/update/tmpl/default.php +++ /dev/null @@ -1,63 +0,0 @@ - 'auto', 'relative' => true)); -JHtml::_('script', 'com_joomlaupdate/encryption.js', array('version' => 'auto', 'relative' => true)); -JHtml::_('script', 'com_joomlaupdate/update.js', array('version' => 'auto', 'relative' => true)); - -$password = JFactory::getApplication()->getUserState('com_joomlaupdate.password', null); -$filesize = JFactory::getApplication()->getUserState('com_joomlaupdate.filesize', null); -$ajaxUrl = JUri::base() . 'components/com_joomlaupdate/restore.php'; -$returnUrl = 'index.php?option=com_joomlaupdate&task=update.finalise&' . JFactory::getSession()->getFormToken() . '=1'; - -JFactory::getDocument()->addScriptDeclaration( - " - var joomlaupdate_password = '$password'; - var joomlaupdate_totalsize = '$filesize'; - var joomlaupdate_ajax_url = '$ajaxUrl'; - var joomlaupdate_return_url = '$returnUrl'; - - jQuery(document).ready(function(){ - window.pingExtract(); - }); - " -); -?> - -

- -
-
-
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
diff --git a/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php b/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php deleted file mode 100644 index eedb4d9ecdcf7..0000000000000 --- a/administrator/components/com_joomlaupdate/views/update/tmpl/finaliseconfirm.php +++ /dev/null @@ -1,95 +0,0 @@ - - -
-

- -

-

- get('sitename')); ?> -

-
- -
- -
-
-
-
-
- - - - - -
-
-
-
-
-
- - - - - -
-
-
- 1) : ?> -
-
-
- - - - - - - - -
-
-
- -
-
-
- - - -
-
- -
-
-
- - - - -
-
\ 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 deleted file mode 100644 index cbbab460a9044..0000000000000 --- a/administrator/components/com_joomlaupdate/views/update/view.html.php +++ /dev/null @@ -1,39 +0,0 @@ -input->set('hidemainmenu', true); - - // Set the toolbar information. - JToolbarHelper::title(JText::_('COM_JOOMLAUPDATE_OVERVIEW'), 'loop install'); - - // Import com_login's model - JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_login/models', 'LoginModel'); - - // Render the view. - parent::display($tpl); - } -} diff --git a/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php b/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php deleted file mode 100644 index 3f3d46fd5ea47..0000000000000 --- a/administrator/components/com_joomlaupdate/views/upload/tmpl/captive.php +++ /dev/null @@ -1,94 +0,0 @@ - -
-

- -

-

- get('sitename')); ?> -

-
- -
- -
-
-
-
-
- - - - - -
-
-
-
-
-
- - - - - -
-
-
- 1) : ?> -
-
-
- - - - - - - - -
-
-
- -
-
-
- - - -
-
- -
-
-
- - - - -
-
diff --git a/administrator/components/com_joomlaupdate/views/upload/view.html.php b/administrator/components/com_joomlaupdate/views/upload/view.html.php deleted file mode 100644 index aafadcf81448c..0000000000000 --- a/administrator/components/com_joomlaupdate/views/upload/view.html.php +++ /dev/null @@ -1,46 +0,0 @@ -load('com_installer', JPATH_ADMINISTRATOR, 'en-GB', false, true); - $language->load('com_installer', JPATH_ADMINISTRATOR, null, true); - - // Import com_login's model - JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_login/models', 'LoginModel'); - - // Render the view. - parent::display($tpl); - } -} diff --git a/administrator/components/com_languages/Controller/DisplayController.php b/administrator/components/com_languages/Controller/DisplayController.php new file mode 100644 index 0000000000000..8ead1f82c4a87 --- /dev/null +++ b/administrator/components/com_languages/Controller/DisplayController.php @@ -0,0 +1,59 @@ +input->get('view', $this->default_view); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + // Check for edit form. + if ($view == 'language' && $layout == 'edit' && !$this->checkEditId('com_languages.edit.language', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_languages&view=languages', false)); + + return false; + } + + return parent::display(); + } +} diff --git a/administrator/components/com_languages/Controller/InstalledController.php b/administrator/components/com_languages/Controller/InstalledController.php new file mode 100644 index 0000000000000..7646a07a09c43 --- /dev/null +++ b/administrator/components/com_languages/Controller/InstalledController.php @@ -0,0 +1,104 @@ +input->get('cid', ''); + $model = $this->getModel('installed'); + + if ($model->publish($cid)) + { + // Switching to the new administrator language for the message + if ($model->getState('client_id') == 1) + { + $language = Factory::getLanguage(); + $newLang = Language::getInstance($cid); + Factory::$language = $newLang; + Factory::getApplication()->loadLanguage($language = $newLang); + $newLang->load('com_languages', JPATH_ADMINISTRATOR); + } + + $msg = Text::_('COM_LANGUAGES_MSG_DEFAULT_LANGUAGE_SAVED'); + $type = 'message'; + } + else + { + $msg = $model->getError(); + $type = 'error'; + } + + $clientId = $model->getState('client_id'); + $this->setRedirect('index.php?option=com_languages&view=installed&client=' . $clientId, $msg, $type); + } + + /** + * Task to switch the administrator language. + * + * @return void + */ + public function switchAdminLanguage() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $cid = $this->input->get('cid', ''); + $model = $this->getModel('installed'); + + // Fetching the language name from the xx-XX.xml + $file = JPATH_ADMINISTRATOR . '/language/' . $cid . '/' . $cid . '.xml'; + $info = Installer::parseXMLInstallFile($file); + $languageName = $info['name']; + + if ($model->switchAdminLanguage($cid)) + { + // Switching to the new language for the message + $language = Factory::getLanguage(); + $newLang = Language::getInstance($cid); + Factory::$language = $newLang; + Factory::getApplication()->loadLanguage($language = $newLang); + $newLang->load('com_languages', JPATH_ADMINISTRATOR); + + $msg = Text::sprintf('COM_LANGUAGES_MSG_SWITCH_ADMIN_LANGUAGE_SUCCESS', $languageName); + $type = 'message'; + } + else + { + $msg = $model->getError(); + $type = 'error'; + } + + $this->setRedirect('index.php?option=com_languages&view=installed', $msg, $type); + } +} diff --git a/administrator/components/com_languages/Controller/LanguageController.php b/administrator/components/com_languages/Controller/LanguageController.php new file mode 100644 index 0000000000000..7beb036496fa1 --- /dev/null +++ b/administrator/components/com_languages/Controller/LanguageController.php @@ -0,0 +1,37 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_languages/Controller/OverrideController.php b/administrator/components/com_languages/Controller/OverrideController.php new file mode 100644 index 0000000000000..013485f9f3905 --- /dev/null +++ b/administrator/components/com_languages/Controller/OverrideController.php @@ -0,0 +1,210 @@ +app->allowCache(false); + + $app = Factory::getApplication(); + $cid = $this->input->post->get('cid', array(), 'array'); + $context = "$this->option.edit.$this->context"; + + // Get the constant name. + $recordId = (count($cid) ? $cid[0] : $this->input->get('id')); + + // Access check. + if (!$this->allowEdit()) + { + $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'), 'error'); + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + + return; + } + + $app->setUserState($context . '.data', null); + $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id')); + } + + /** + * Method to save an override. + * + * @param string $key The name of the primary key of the URL variable (not used here). + * @param string $urlVar The name of the URL variable if different from the primary key (not used here). + * + * @return void + * + * @since 2.5 + */ + public function save($key = null, $urlVar = null) + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $app = $this->app; + $model = $this->getModel(); + $data = $this->input->post->get('jform', array(), 'array'); + $context = "$this->option.edit.$this->context"; + $task = $this->getTask(); + + $recordId = $this->input->get('id'); + $data['id'] = $recordId; + + // Access check. + if (!$this->allowSave($data, 'id')) + { + $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + + return; + } + + // Validate the posted data. + $form = $model->getForm($data, false); + + if (!$form) + { + $app->enqueueMessage($model->getError(), 'error'); + + return; + } + + // Require helper for filter functions called by \JForm. + \JLoader::register('LanguagesHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/languages.php'); + + // Test whether the data is valid. + $validData = $model->validate($form, $data); + + // Check for validation errors. + if ($validData === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // 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) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState($context . '.data', $data); + + // Redirect back to the edit screen. + $this->setRedirect( + Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id'), false) + ); + + return; + } + + // Attempt to save the data. + if (!$model->save($validData)) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + // Redirect back to the edit screen. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); + $this->setRedirect( + Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id'), false) + ); + + return; + } + + // Add message of success. + $this->setMessage(Text::_('COM_LANGUAGES_VIEW_OVERRIDE_SAVE_SUCCESS')); + + // Redirect the user and adjust session state based on the chosen task. + switch ($task) + { + case 'apply': + // Set the record data in the session. + $app->setUserState($context . '.data', null); + + // Redirect back to the edit screen + $this->setRedirect( + Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($validData['key'], 'id'), false) + ); + break; + + case 'save2new': + // Clear the record id and data from the session. + $app->setUserState($context . '.data', null); + + // Redirect back to the edit screen + $this->setRedirect( + Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(null, 'id'), false) + ); + break; + + default: + // Clear the record id and data from the session. + $app->setUserState($context . '.data', null); + + // Redirect to the list screen. + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + break; + } + } + + /** + * Method to cancel an edit. + * + * @param string $key The name of the primary key of the URL variable (not used here). + * + * @return void + * + * @since 2.5 + */ + public function cancel($key = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $context = "$this->option.edit.$this->context"; + + $this->app->setUserState($context . '.data', null); + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); + } +} diff --git a/administrator/components/com_languages/Controller/OverridesController.php b/administrator/components/com_languages/Controller/OverridesController.php new file mode 100644 index 0000000000000..d10206c9e2436 --- /dev/null +++ b/administrator/components/com_languages/Controller/OverridesController.php @@ -0,0 +1,85 @@ +input->get('cid', array(), 'array'); + + if (!is_array($cid) || count($cid) < 1) + { + $this->setMessage(Text::_($this->text_prefix . '_NO_ITEM_SELECTED'), 'warning'); + } + else + { + // Get the model. + $model = $this->getModel('overrides'); + + // Remove the items. + if ($model->delete($cid)) + { + $this->setMessage(Text::plural($this->text_prefix . '_N_ITEMS_DELETED', count($cid))); + } + else + { + $this->setMessage($model->getError(), 'error'); + } + } + + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); + } + + /** + * Method to purge the overrider table. + * + * @return void + * + * @since 3.4.2 + */ + public function purge() + { + $model = $this->getModel('overrides'); + $model->purge(); + $this->setRedirect(Route::_('index.php?option=com_languages&view=overrides', false)); + } +} diff --git a/administrator/components/com_languages/Controller/StringsController.php b/administrator/components/com_languages/Controller/StringsController.php new file mode 100644 index 0000000000000..6831d90736045 --- /dev/null +++ b/administrator/components/com_languages/Controller/StringsController.php @@ -0,0 +1,47 @@ +getModel('strings')->refresh()); + } + + /** + * Method for searching language strings + * + * @return void + * + * @since 2.5 + */ + public function search() + { + echo new JsonResponse($this->getModel('strings')->search()); + } +} diff --git a/administrator/components/com_languages/Helper/LanguagesHelper.php b/administrator/components/com_languages/Helper/LanguagesHelper.php new file mode 100644 index 0000000000000..663193355f875 --- /dev/null +++ b/administrator/components/com_languages/Helper/LanguagesHelper.php @@ -0,0 +1,113 @@ +clean($value, 'cmd')); + } + + /** + * Filter method for language strings. + * This method will be called by \JForm while filtering the form data. + * + * @param string $value The language string to filter. + * + * @return string The filtered language string. + * + * @since 2.5 + */ + public static function filterText($value) + { + $filter = \JFilterInput::getInstance(null, null, 1, 1); + + return $filter->clean($value); + } +} diff --git a/administrator/components/com_languages/Helper/MultilangstatusHelper.php b/administrator/components/com_languages/Helper/MultilangstatusHelper.php new file mode 100644 index 0000000000000..65d3f3a13f5cd --- /dev/null +++ b/administrator/components/com_languages/Helper/MultilangstatusHelper.php @@ -0,0 +1,329 @@ +getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__menu')) + ->where('home = 1') + ->where('published = 1') + ->where('client_id = 0'); + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * Method to get the number of published language switcher modules. + * + * @return integer + */ + public static function getLangswitchers() + { + // Check if switcher is published. + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from($db->quoteName('#__modules')) + ->where('module = ' . $db->quote('mod_languages')) + ->where('published = 1') + ->where('client_id = 0'); + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * Method to return a list of published content languages. + * + * @return array of language objects. + */ + public static function getContentlangs() + { + // Check for published Content Languages. + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('a.lang_code AS lang_code') + ->select('a.published AS published') + ->from('#__languages AS a'); + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Method to return a list of published site languages. + * + * @return array of language extension objects. + * + * @deprecated 4.0 Use LanguageHelper::getInstalledLanguages(0) instead. + */ + public static function getSitelangs() + { + try + { + Log::add( + sprintf('%s() is deprecated, use LanguageHelper::getInstalledLanguages(0) instead.', __METHOD__), + Log::WARNING, + 'deprecated' + ); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + return LanguageHelper::getInstalledLanguages(0); + } + + /** + * Method to return a list of language home page menu items. + * + * @return array of menu objects. + * + * @deprecated 4.0 Use Multilanguage::getSiteHomePages() instead. + */ + public static function getHomepages() + { + try + { + Log::add( + sprintf('%s() is deprecated, use LanguageHelper::getSiteHomePages() instead.', __METHOD__), + Log::WARNING, + 'deprecated' + ); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + return Multilanguage::getSiteHomePages(); + } + + /** + * Method to return combined language status. + * + * @return array of language objects. + */ + public static function getStatus() + { + // Check for combined status. + $db = Factory::getDbo(); + $query = $db->getQuery(true); + + // Select all fields from the languages table. + $query->select('a.*', 'l.home') + ->select('a.published AS published') + ->select('a.lang_code AS lang_code') + ->from('#__languages AS a'); + + // Select the language home pages. + $query->select('l.home AS home') + ->select('l.language AS home_language') + ->join('LEFT', '#__menu AS l ON l.language = a.lang_code AND l.home=1 AND l.published=1 AND l.language <> \'*\'') + ->select('e.enabled AS enabled') + ->select('e.element AS element') + ->join('LEFT', '#__extensions AS e ON e.element = a.lang_code') + ->where('e.client_id = 0') + ->where('e.enabled = 1') + ->where('e.state = 0'); + + $db->setQuery($query); + + return $db->loadObjectList(); + } + + /** + * Method to return a list of contact objects. + * + * @return array of contact objects. + */ + public static function getContacts() + { + $db = Factory::getDbo(); + $languages = count(LanguageHelper::getLanguages()); + + // Get the number of contact with all as language + $alang = $db->getQuery(true) + ->select('count(*)') + ->from('#__contact_details AS cd') + ->where('cd.user_id=u.id') + ->where('cd.published=1') + ->where('cd.language=' . $db->quote('*')); + + // Get the number of languages for the contact + $slang = $db->getQuery(true) + ->select('count(distinct(l.lang_code))') + ->from('#__languages as l') + ->join('LEFT', '#__contact_details AS cd ON cd.language=l.lang_code') + ->where('cd.user_id=u.id') + ->where('cd.published=1') + ->where('l.published=1'); + + // Get the number of multiple contact/language + $mlang = $db->getQuery(true) + ->select('count(*)') + ->from('#__languages as l') + ->join('LEFT', '#__contact_details AS cd ON cd.language=l.lang_code') + ->where('cd.user_id=u.id') + ->where('cd.published=1') + ->where('l.published=1') + ->group('l.lang_code') + ->having('count(*) > 1'); + + // Get the contacts + $query = $db->getQuery(true) + ->select('u.name, (' . $alang . ') as alang, (' . $slang . ') as slang, (' . $mlang . ') as mlang') + ->from('#__users AS u') + ->join('LEFT', '#__contact_details AS cd ON cd.user_id=u.id') + ->where('EXISTS (SELECT 1 from #__content as c where c.created_by=u.id)') + ->group('u.id, u.name'); + + $db->setQuery($query); + $warnings = $db->loadObjectList(); + + foreach ($warnings as $index => $warn) + { + if ($warn->alang == 1 && $warn->slang == 0) + { + unset($warnings[$index]); + } + + if ($warn->alang == 0 && $warn->slang == 0 && empty($warn->mlang)) + { + unset($warnings[$index]); + } + + if ($warn->alang == 0 && $warn->slang == $languages && empty($warn->mlang)) + { + unset($warnings[$index]); + } + } + + return $warnings; + } + + /** + * Method to get the status of the module displaying the menutype of the default Home page set to All languages. + * + * @return boolean True if the module is published, false otherwise. + * + * @since 3.7.0 + */ + public static function getDefaultHomeModule() + { + // Find Default Home menutype. + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('menutype')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('home') . ' = ' . $db->quote('1')) + ->where($db->quoteName('published') . ' = ' . $db->quote('1')) + ->where($db->quoteName('client_id') . ' = ' . $db->quote('0')) + ->where($db->quoteName('language') . ' = ' . $db->quote('*')); + + $db->setQuery($query); + + $menutype = $db->loadResult(); + + // Get published site menu modules titles. + $query->clear() + ->select($db->quoteName('title')) + ->from($db->quoteName('#__modules')) + ->where($db->quoteName('module') . ' = ' . $db->quote('mod_menu')) + ->where($db->quoteName('published') . ' = ' . $db->quote('1')) + ->where($db->quoteName('client_id') . ' = ' . $db->quote('0')); + + $db->setQuery($query); + + $menutitles = $db->loadColumn(); + + // Do we have a published menu module displaying the default Home menu item set to all languages? + foreach ($menutitles as $menutitle) + { + $module = self::getModule('mod_menu', $menutitle); + $moduleParams = new Registry($module->params); + $param = $moduleParams->get('menutype', ''); + + if ($param && $param != $menutype) + { + continue; + } + + return true; + } + } + + /** + * Get module by name + * + * @param string $moduleName The name of the module + * @param string $instanceTitle The title of the module, optional + * + * @return \stdClass The Module object + * + * @since 3.7.0 + */ + public static function getModule($moduleName, $instanceTitle = null) + { + $db = Factory::getDbo(); + + $query = $db->getQuery(true) + ->select('id, title, module, position, content, showtitle, params') + ->from($db->quoteName('#__modules')) + ->where($db->quoteName('module') . ' = ' . $db->quote($moduleName)) + ->where($db->quoteName('published') . ' = ' . $db->quote('1')) + ->where($db->quoteName('client_id') . ' = ' . $db->quote('0')); + + if ($instanceTitle) + { + $query->where($db->quoteName('title') . ' = ' . $db->quote($instanceTitle)); + } + + $db->setQuery($query); + + try + { + $modules = $db->loadObject(); + } + catch (\RuntimeException $e) + { + Log::add(Text::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage()), Log::WARNING, 'jerror'); + } + + return $modules; + } +} diff --git a/administrator/components/com_languages/Model/InstalledModel.php b/administrator/components/com_languages/Model/InstalledModel.php new file mode 100644 index 0000000000000..2943bdd47ce63 --- /dev/null +++ b/administrator/components/com_languages/Model/InstalledModel.php @@ -0,0 +1,499 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + // Special case for client id. + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; + $this->setState('client_id', $clientId); + + // Load the parameters. + $params = ComponentHelper::getParams('com_languages'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('client_id'); + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Method to get the client object. + * + * @return object + * + * @since 1.6 + */ + public function getClient() + { + return ApplicationHelper::getClientInfo($this->getState('client_id', 0)); + } + + /** + * Method to get the ftp credentials. + * + * @return object + * + * @since 1.6 + */ + public function getFtp() + { + if (is_null($this->ftp)) + { + $this->ftp = ClientHelper::setCredentialsFromRequest('ftp'); + } + + return $this->ftp; + } + + /** + * Method to get the option. + * + * @return object + * + * @since 1.6 + */ + public function getOption() + { + $option = $this->getState('option'); + + return $option; + } + + /** + * Method to get Languages item data. + * + * @return array + * + * @since 1.6 + */ + public function getData() + { + // Fetch language data if not fetched yet. + if (is_null($this->data)) + { + $this->data = array(); + + $isCurrentLanguageRtl = Factory::getLanguage()->isRtl(); + $params = ComponentHelper::getParams('com_languages'); + $installedLanguages = LanguageHelper::getInstalledLanguages(null, true, true, null, null, null); + + // Compute all the languages. + foreach ($installedLanguages as $clientId => $languages) + { + $defaultLanguage = $params->get(ApplicationHelper::getClientInfo($clientId)->name, 'en-GB'); + + foreach ($languages as $lang) + { + $row = new \stdClass; + $row->language = $lang->element; + $row->name = $lang->metadata['name']; + $row->nativeName = $lang->metadata['nativeName'] ?? '-'; + $row->client_id = (int) $lang->client_id; + $row->extension_id = (int) $lang->extension_id; + $row->author = $lang->manifest['author']; + $row->creationDate = $lang->manifest['creationDate']; + $row->authorEmail = $lang->manifest['authorEmail']; + $row->version = $lang->manifest['version']; + $row->published = $defaultLanguage === $row->language ? 1 : 0; + $row->checked_out = 0; + + // Fix wrongly set parentheses in RTL languages + if ($isCurrentLanguageRtl) + { + $row->name = html_entity_decode($row->name . '‎', ENT_QUOTES, 'UTF-8'); + $row->nativeName = html_entity_decode($row->nativeName . '‎', ENT_QUOTES, 'UTF-8'); + } + + $this->data[] = $row; + } + } + } + + $installedLanguages = array_merge($this->data); + + // Process filters. + $clientId = (int) $this->getState('client_id'); + $search = $this->getState('filter.search'); + + foreach ($installedLanguages as $key => $installedLanguage) + { + // Filter by client id. + if (in_array($clientId, array(0, 1))) + { + if ($installedLanguage->client_id !== $clientId) + { + unset($installedLanguages[$key]); + continue; + } + } + + // Filter by search term. + if (!empty($search)) + { + if (stripos($installedLanguage->name, $search) === false + && stripos($installedLanguage->nativeName, $search) === false + && stripos($installedLanguage->language, $search) === false) + { + unset($installedLanguages[$key]); + continue; + } + } + } + + // Process ordering. + $listOrder = $this->getState('list.ordering', 'name'); + $listDirn = $this->getState('list.direction', 'ASC'); + $installedLanguages = ArrayHelper::sortObjects($installedLanguages, $listOrder, strtolower($listDirn) === 'desc' ? -1 : 1, true, true); + + // Process pagination. + $limit = (int) $this->getState('list.limit', 25); + + // Sets the total for pagination. + $this->total = count($installedLanguages); + + if ($limit !== 0) + { + $start = (int) $this->getState('list.start', 0); + + return array_slice($installedLanguages, $start, $limit); + } + + return $installedLanguages; + } + + /** + * Method to get installed languages data. + * + * @return string An SQL query. + * + * @since 1.6 + * + * @deprecated 4.0 + */ + protected function getLanguageList() + { + // Create a new db object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $client = $this->getState('client_id'); + $type = 'language'; + + // Select field element from the extensions table. + $query->select($this->getState('list.select', 'a.element')) + ->from('#__extensions AS a'); + + $type = $db->quote($type); + $query->where('(a.type = ' . $type . ')') + ->where('state = 0') + ->where('enabled = 1') + ->where('client_id=' . (int) $client); + + // For client_id = 1 do we need to check language table also? + $db->setQuery($query); + + $this->langlist = $db->loadColumn(); + + return $this->langlist; + } + + /** + * Method to get the total number of Languages items. + * + * @return integer + * + * @since 1.6 + */ + public function getTotal() + { + if (is_null($this->total)) + { + $this->getData(); + } + + return $this->total; + } + + /** + * Method to set the default language. + * + * @param integer $cid Id of the language to publish. + * + * @return boolean + * + * @since 1.6 + */ + public function publish($cid) + { + if ($cid) + { + $client = $this->getClient(); + + $params = ComponentHelper::getParams('com_languages'); + $params->set($client->name, $cid); + + $table = Table::getInstance('extension', 'Joomla\\CMS\\Table\\'); + $id = $table->find(array('element' => 'com_languages')); + + // Load. + if (!$table->load($id)) + { + $this->setError($table->getError()); + + return false; + } + + $table->params = (string) $params; + + // Pre-save checks. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Save the changes. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + else + { + $this->setError(Text::_('COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED')); + + return false; + } + + // Clean the cache of com_languages and component cache. + $this->cleanCache(); + $this->cleanCache('_system', 0); + $this->cleanCache('_system', 1); + + return true; + } + + /** + * Method to get the folders. + * + * @return array Languages folders. + * + * @since 1.6 + */ + protected function getFolders() + { + if (is_null($this->folders)) + { + $path = $this->getPath(); + $this->folders = Folder::folders($path, '.', false, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'pdf_fonts', 'overrides')); + } + + return $this->folders; + } + + /** + * Method to get the path. + * + * @return string The path to the languages folders. + * + * @since 1.6 + */ + protected function getPath() + { + if (is_null($this->path)) + { + $client = $this->getClient(); + $this->path = LanguageHelper::getLanguagePath($client->path); + } + + return $this->path; + } + + /** + * Method to compare two languages in order to sort them. + * + * @param object $lang1 The first language. + * @param object $lang2 The second language. + * + * @return integer + * + * @since 1.6 + * + * @deprecated 4.0 + */ + protected function compareLanguages($lang1, $lang2) + { + return strcmp($lang1->name, $lang2->name); + } + + /** + * Method to switch the administrator language. + * + * @param string $cid The language tag. + * + * @return boolean + * + * @since 3.5 + */ + public function switchAdminLanguage($cid) + { + if ($cid) + { + $client = $this->getClient(); + + if ($client->name == 'administrator') + { + Factory::getApplication()->setUserState('application.lang', $cid); + } + } + else + { + Factory::getApplication()->enqueueMessage(Text::_('COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED'), 'error'); + + return false; + } + + return true; + } +} diff --git a/administrator/components/com_languages/Model/LanguageModel.php b/administrator/components/com_languages/Model/LanguageModel.php new file mode 100644 index 0000000000000..8627f16836203 --- /dev/null +++ b/administrator/components/com_languages/Model/LanguageModel.php @@ -0,0 +1,280 @@ + 'onExtensionAfterSave', + 'event_before_save' => 'onExtensionBeforeSave', + 'events_map' => array( + 'save' => 'extension' + ) + ), $config + ); + + parent::__construct($config, $factory); + } + + /** + * Override to get the table. + * + * @param string $name Name of the table. + * @param string $prefix Table name prefix. + * @param array $options Array of options. + * + * @return Table + * + * @since 1.6 + */ + public function getTable($name = '', $prefix = '', $options = array()) + { + return Table::getInstance('Language', 'Joomla\\CMS\\Table\\'); + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = Factory::getApplication(); + $params = ComponentHelper::getParams('com_languages'); + + // Load the User state. + $langId = $app->input->getInt('lang_id'); + $this->setState('language.id', $langId); + + // Load the parameters. + $this->setState('params', $params); + } + + /** + * Method to get a member item. + * + * @param integer $langId The id of the member to get. + * + * @return mixed User data object on success, false on failure. + * + * @since 1.0 + */ + public function getItem($langId = null) + { + $langId = (!empty($langId)) ? $langId : (int) $this->getState('language.id'); + + // Get a member row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($langId); + + // Check for a table object error. + if ($return === false && $table->getError()) + { + $this->setError($table->getError()); + + return false; + } + + // Set a valid accesslevel in case '0' is stored due to a bug in the installation SQL (was fixed with PR 2714). + if ($table->access == '0') + { + $table->access = (int) Factory::getConfig()->get('access'); + } + + $properties = $table->getProperties(1); + $value = ArrayHelper::toObject($properties, 'JObject'); + + return $value; + } + + /** + * Method to get the group form. + * + * @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 mixed A \JForm object on success, false on failure. + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_languages.language', 'language', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_languages.edit.language.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_languages.language', $data); + + return $data; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $langId = (!empty($data['lang_id'])) ? $data['lang_id'] : (int) $this->getState('language.id'); + $isNew = true; + + PluginHelper::importPlugin($this->events_map['save']); + + $table = $this->getTable(); + $context = $this->option . '.' . $this->name; + + // Load the row if saving an existing item. + if ($langId > 0) + { + $table->load($langId); + $isNew = false; + } + + // Prevent white spaces, including East Asian double bytes. + $spaces = array('/\xE3\x80\x80/', ' '); + + $data['lang_code'] = str_replace($spaces, '', $data['lang_code']); + + // Prevent saving an incorrect language tag + if (!preg_match('#\b([a-z]{2,3})[-]([A-Z]{2})\b#', $data['lang_code'])) + { + $this->setError(Text::_('COM_LANGUAGES_ERROR_LANG_TAG')); + + return false; + } + + $data['sef'] = str_replace($spaces, '', $data['sef']); + $data['sef'] = ApplicationHelper::stringURLSafe($data['sef']); + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = Factory::getApplication()->triggerEvent($this->event_before_save, array($context, &$table, $isNew)); + + // Check the event responses. + if (in_array(false, $result, true)) + { + $this->setError($table->getError()); + + return false; + } + + // Store the data. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after save event. + Factory::getApplication()->triggerEvent($this->event_after_save, array($context, &$table, $isNew)); + + $this->setState('language.id', $table->lang_id); + + // Clean the cache. + $this->cleanCache(); + + return true; + } + + /** + * Custom clean cache method. + * + * @param string $group Optional cache group name. + * @param integer $client_id Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $client_id = 0) + { + parent::cleanCache('_system'); + parent::cleanCache('com_languages'); + } +} diff --git a/administrator/components/com_languages/Model/LanguagesModel.php b/administrator/components/com_languages/Model/LanguagesModel.php new file mode 100644 index 0000000000000..6fe54b13f5cc7 --- /dev/null +++ b/administrator/components/com_languages/Model/LanguagesModel.php @@ -0,0 +1,223 @@ +setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.published'); + + return parent::getStoreId($id); + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select all fields from the languages table. + $query->select($this->getState('list.select', 'a.*', 'l.home')) + ->from($db->quoteName('#__languages') . ' AS a'); + + // Join over the asset groups. + $query->select('ag.title AS access_level') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + + // Select the language home pages. + $query->select('l.home AS home') + ->join('LEFT', $db->quoteName('#__menu') . ' AS l ON l.language = a.lang_code AND l.home=1 AND l.language <> ' . $db->quote('*')); + + // Filter on the published state. + $published = (string) $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.published IN (0, 1))'); + } + + // Filter by search in title. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(a.title LIKE ' . $search . ')'); + } + + // Filter by access level. + if ($access = $this->getState('filter.access')) + { + $query->where('a.access = ' . (int) $access); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Set the published language(s). + * + * @param array $cid An array of language IDs. + * @param integer $value The value of the published state. + * + * @return boolean True on success, false otherwise. + * + * @since 1.6 + */ + public function setPublished($cid, $value = 0) + { + return Table::getInstance('Language', 'Joomla\\CMS\\Table\\')->publish($cid, $value); + } + + /** + * Method to delete records. + * + * @param array $pks An array of item primary keys. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function delete($pks) + { + // Sanitize the array. + $pks = (array) $pks; + + // Get a row instance. + $table = Table::getInstance('Language', 'Joomla\\CMS\\Table\\'); + + // Iterate the items to delete each one. + foreach ($pks as $itemId) + { + if (!$table->delete((int) $itemId)) + { + $this->setError($table->getError()); + + return false; + } + } + + // Clean the cache. + $this->cleanCache(); + + return true; + } + + /** + * Custom clean cache method, 2 places for 2 clients. + * + * @param string $group Optional cache group name. + * @param integer $client_id Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $client_id = 0) + { + parent::cleanCache('_system'); + parent::cleanCache('com_languages'); + } +} diff --git a/administrator/components/com_languages/Model/OverrideModel.php b/administrator/components/com_languages/Model/OverrideModel.php new file mode 100644 index 0000000000000..477457920c691 --- /dev/null +++ b/administrator/components/com_languages/Model/OverrideModel.php @@ -0,0 +1,220 @@ +loadForm('com_languages.override', 'override', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + $client = $this->getState('filter.client', 'site'); + $language = $this->getState('filter.language', 'en-GB'); + $langName = Language::getInstance($language)->getName(); + + if (!$langName) + { + // 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; + } + + $form->setValue('client', null, Text::_('COM_LANGUAGES_VIEW_OVERRIDE_CLIENT_' . strtoupper($client))); + $form->setValue('language', null, Text::sprintf('COM_LANGUAGES_VIEW_OVERRIDE_LANGUAGE', $langName, $language)); + $form->setValue('file', null, Path::clean(constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $language . '.override.ini')); + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 2.5 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_languages.edit.override.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_languages.override', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @param string $pk The key name. + * + * @return mixed Object on success, false otherwise. + * + * @since 2.5 + */ + public function getItem($pk = null) + { + $input = Factory::getApplication()->input; + $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); + + $result = new \stdClass; + $result->key = ''; + $result->override = ''; + + if (isset($strings[$pk])) + { + $result->key = $pk; + $result->override = $strings[$pk]; + } + + $opposite_filename = 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]); + + return $result; + } + + /** + * 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. + * + * @return boolean True on success, false otherwise. + * + * @since 2.5 + */ + public function save($data, $opposite_client = false) + { + $app = Factory::getApplication(); + + $client = $app->getUserState('com_languages.overrides.filter.client', 0); + $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); + + // If the override should be created for both. + if ($opposite_client) + { + $client = 1 - $client; + } + + // Return false if the constant is a reserved word, i.e. YES, NO, NULL, FALSE, ON, OFF, NONE, TRUE + $blacklist = array('YES', 'NO', 'NULL', 'FALSE', 'ON', 'OFF', 'NONE', 'TRUE'); + + if (in_array($data['key'], $blacklist)) + { + $this->setError(Text::_('COM_LANGUAGES_OVERRIDE_ERROR_RESERVED_WORDS')); + + return 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); + + if (isset($strings[$data['id']])) + { + // If an existent string was edited check whether + // the name of the constant is still the same. + if ($data['key'] == $data['id']) + { + // If yes, simply override it. + $strings[$data['key']] = $data['override']; + } + else + { + // If no, delete the old string and prepend the new one. + unset($strings[$data['id']]); + $strings = array($data['key'] => $data['override']) + $strings; + } + } + else + { + // If it is a new override simply prepend it. + $strings = array($data['key'] => $data['override']) + $strings; + } + + // Write override.ini file with the strings. + if (LanguageHelper::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) + { + return $this->save($data, true); + } + + return true; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 2.5 + */ + protected function populateState() + { + $app = Factory::getApplication(); + + $client = $app->getUserStateFromRequest('com_languages.overrides.filter.client', 'filter_client', 0, 'int') ? 'administrator' : 'site'; + $this->setState('filter.client', $client); + + $language = $app->getUserStateFromRequest('com_languages.overrides.filter.language', 'filter_language', 'en-GB', 'cmd'); + $this->setState('filter.language', $language); + } +} diff --git a/administrator/components/com_languages/Model/OverridesModel.php b/administrator/components/com_languages/Model/OverridesModel.php new file mode 100644 index 0000000000000..edba68fedd7ba --- /dev/null +++ b/administrator/components/com_languages/Model/OverridesModel.php @@ -0,0 +1,311 @@ +filter_fields = array('key', 'text'); + } + + /** + * Retrieves the overrides data + * + * @param boolean $all True if all overrides shall be returned without considering pagination, defaults to false + * + * @return array Array of objects containing the overrides of the override.ini file + * + * @since 2.5 + */ + public function getOverrides($all = false) + { + // Get a storage key. + $store = $this->getStoreId(); + + // Try to load the data from internal storage. + if (!empty($this->cache[$store])) + { + return $this->cache[$store]; + } + + $client = in_array($this->state->get('filter.client'), array(0, 'site')) ? 'SITE' : 'ADMINISTRATOR'; + + // 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); + + // Delete the override.ini file if empty. + if (file_exists($filename) && empty($strings)) + { + File::delete($filename); + } + + // Filter the loaded strings according to the search box. + $search = $this->getState('filter.search'); + + if ($search != '') + { + $search = preg_quote($search, '~'); + $matchvals = preg_grep('~' . $search . '~i', $strings); + $matchkeys = array_intersect_key($strings, array_flip(preg_grep('~' . $search . '~i', array_keys($strings)))); + $strings = array_merge($matchvals, $matchkeys); + } + + // Consider the ordering + if ($this->getState('list.ordering') == 'text') + { + if (strtoupper($this->getState('list.direction')) == 'DESC') + { + arsort($strings); + } + else + { + asort($strings); + } + } + else + { + if (strtoupper($this->getState('list.direction')) == 'DESC') + { + krsort($strings); + } + else + { + ksort($strings); + } + } + + // Consider the pagination. + if (!$all && $this->getState('list.limit') && $this->getTotal() > $this->getState('list.limit')) + { + $strings = array_slice($strings, $this->getStart(), $this->getState('list.limit'), true); + } + + // Add the items to the internal cache. + $this->cache[$store] = $strings; + + return $this->cache[$store]; + } + + /** + * Method to get the total number of overrides. + * + * @return integer The total number of overrides. + * + * @since 2.5 + */ + public function getTotal() + { + // Get a storage key. + $store = $this->getStoreId('getTotal'); + + // Try to load the data from internal storage + if (!empty($this->cache[$store])) + { + return $this->cache[$store]; + } + + // Add the total to the internal cache. + $this->cache[$store] = count($this->getOverrides(true)); + + return $this->cache[$store]; + } + + /** + * 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 2.5 + */ + protected function populateState($ordering = 'key', $direction = 'asc') + { + $app = Factory::getApplication(); + + // Use default language of frontend for default filter. + $default = ComponentHelper::getParams('com_languages')->get('site') . '0'; + + $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'); + + 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'); + } + + // 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('filter.client', $client ? 'administrator' : 'site'); + $this->setState('filter.language', $language); + + // 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 = LanguageHelper::getKnownLanguages(JPATH_SITE); + $admin_languages = LanguageHelper::getKnownLanguages(JPATH_ADMINISTRATOR); + + // Create a single array of them. + foreach ($site_languages as $tag => $language) + { + $languages[$tag . '0'] = Text::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], Text::_('JSITE')); + } + + foreach ($admin_languages as $tag => $language) + { + $languages[$tag . '1'] = Text::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], Text::_('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']; + } + + /** + * Method to delete one or more overrides. + * + * @param array $cids Array of keys to delete. + * + * @return integer Number of successfully deleted overrides, boolean false if an error occurred. + * + * @since 2.5 + */ + public function delete($cids) + { + // Check permissions first. + if (!Factory::getUser()->authorise('core.delete', 'com_languages')) + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + + return false; + } + + $filterclient = Factory::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); + + // Unset strings that shall be deleted + foreach ($cids as $key) + { + if (isset($strings[$key])) + { + unset($strings[$key]); + } + } + + // Write override.ini file with the strings. + if (LanguageHelper::saveToIniFile($filename, $strings) === false) + { + return false; + } + + $this->cleanCache(); + + return count($cids); + } + + /** + * Removes all of the cached strings from the table. + * + * @return boolean result of operation + * + * @since 3.4.2 + */ + public function purge() + { + $db = Factory::getDbo(); + + // Note: TRUNCATE is a DDL operation + // This may or may not mean depending on your database + try + { + $db->truncateTable('#__overrider'); + } + catch (\RuntimeException $e) + { + return $e; + } + + Factory::getApplication()->enqueueMessage(Text::_('COM_LANGUAGES_VIEW_OVERRIDES_PURGE_SUCCESS')); + } +} diff --git a/administrator/components/com_languages/Model/StringsModel.php b/administrator/components/com_languages/Model/StringsModel.php new file mode 100644 index 0000000000000..3374f2ae5f395 --- /dev/null +++ b/administrator/components/com_languages/Model/StringsModel.php @@ -0,0 +1,173 @@ +getDbo(); + + $app->setUserState('com_languages.overrides.cachedtime', null); + + // Empty the database cache first. + try + { + $db->truncateTable('#__overrider'); + } + catch (\RuntimeException $e) + { + return $e; + } + + // Create the insert query. + $query = $db->getQuery(true) + ->insert($db->quoteName('#__overrider')) + ->columns('constant, string, file'); + + // Initialize some variables. + $client = $app->getUserState('com_languages.overrides.filter.client', 'site') ? 'administrator' : 'site'; + $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); + + $base = constant('JPATH_' . strtoupper($client)); + $path = $base . '/language/' . $language; + + $files = array(); + + // Parse common language directory. + if (is_dir($path)) + { + $files = Folder::files($path, $language . '.*ini$', false, true); + } + + // Parse language directories of components. + $files = array_merge($files, Folder::files($base . '/components', $language . '.*ini$', 3, true)); + + // Parse language directories of modules. + $files = array_merge($files, Folder::files($base . '/modules', $language . '.*ini$', 3, true)); + + // Parse language directories of templates. + $files = array_merge($files, Folder::files($base . '/templates', $language . '.*ini$', 3, true)); + + // Parse language directories of plugins. + $files = array_merge($files, Folder::files(JPATH_PLUGINS, $language . '.*ini$', 4, true)); + + // Parse all found ini files and add the strings to the database cache. + foreach ($files as $file) + { + $strings = LanguagesHelper::parseFile($file); + + if ($strings && count($strings)) + { + $query->clear('values'); + + foreach ($strings as $key => $string) + { + $query->values($db->quote($key) . ',' . $db->quote($string) . ',' . $db->quote(Path::clean($file))); + } + + try + { + $db->setQuery($query); + $db->execute(); + } + catch (\RuntimeException $e) + { + return $e; + } + } + } + + // Update the cached time. + $app->setUserState('com_languages.overrides.cachedtime.' . $client . '.' . $language, time()); + + return true; + } + + /** + * Method for searching language strings. + * + * @return array|\Exception Array of resuls on success, \Exception object otherwise. + * + * @since 2.5 + */ + public function search() + { + $results = array(); + $input = Factory::getApplication()->input; + $filter = InputFilter::getInstance(); + $db = $this->getDbo(); + $searchTerm = $input->getString('searchstring'); + + $limitstart = $input->getInt('more'); + + try + { + $searchstring = $db->quote('%' . $filter->clean($searchTerm, 'TRIM') . '%'); + + // Create the search query. + $query = $db->getQuery(true) + ->select('constant, string, file') + ->from($db->quoteName('#__overrider')); + + if ($input->get('searchtype') == 'constant') + { + $query->where('constant LIKE ' . $searchstring); + } + else + { + $query->where('string LIKE ' . $searchstring); + } + + // Consider the limitstart according to the 'more' parameter and load the results. + $db->setQuery($query, $limitstart, 10); + $results['results'] = $db->loadObjectList(); + + // Check whether there are more results than already loaded. + $query->clear('select')->clear('limit') + ->select('COUNT(id)'); + $db->setQuery($query); + + if ($db->loadResult() > $limitstart + 10) + { + // If this is set a 'More Results' link will be displayed in the view. + $results['more'] = $limitstart + 10; + } + } + catch (\RuntimeException $e) + { + return $e; + } + + return $results; + } +} diff --git a/administrator/components/com_languages/View/Installed/HtmlView.php b/administrator/components/com_languages/View/Installed/HtmlView.php new file mode 100644 index 0000000000000..7b0134895189c --- /dev/null +++ b/administrator/components/com_languages/View/Installed/HtmlView.php @@ -0,0 +1,168 @@ +ftp = $this->get('Ftp'); + $this->option = $this->get('Option'); + $this->pagination = $this->get('Pagination'); + $this->rows = $this->get('Data'); + $this->total = $this->get('Total'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + LanguagesHelper::addSubmenu('installed'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_languages'); + + if ((int) $this->state->get('client_id') === 1) + { + ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_INSTALLED_ADMIN_TITLE'), 'comments-2 langmanager'); + } + else + { + ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_INSTALLED_SITE_TITLE'), 'comments-2 langmanager'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::makeDefault('installed.setDefault'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.admin')) + { + // Add install languages link to the lang installer component. + $bar = Toolbar::getInstance('toolbar'); + + // Switch administrator language + if ($this->state->get('client_id', 0) == 1) + { + ToolbarHelper::custom('installed.switchadminlanguage', 'refresh', 'refresh', 'COM_LANGUAGES_SWITCH_ADMIN', false); + ToolbarHelper::divider(); + } + + $bar->appendButton('Link', 'upload', 'COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages'); + ToolbarHelper::divider(); + + ToolbarHelper::preferences('com_languages'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_INSTALLED'); + + $this->sidebar = \JHtmlSidebar::render(); + } +} diff --git a/administrator/components/com_languages/View/Language/HtmlView.php b/administrator/components/com_languages/View/Language/HtmlView.php new file mode 100644 index 0000000000000..0304f81e29afb --- /dev/null +++ b/administrator/components/com_languages/View/Language/HtmlView.php @@ -0,0 +1,129 @@ +item = $this->get('Item'); + $this->form = $this->get('Form'); + $this->state = $this->get('State'); + $this->canDo = ContentHelper::getActions('com_languages'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', 1); + $isNew = empty($this->item->lang_id); + $canDo = $this->canDo; + + ToolbarHelper::title( + Text::_($isNew ? 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_NEW_TITLE' : 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_EDIT_TITLE'), 'comments-2 langmanager' + ); + + $toolbarButtons = []; + + if (($isNew && $canDo->get('core.create')) || (!$isNew && $canDo->get('core.edit'))) + { + $toolbarButtons[] = ['apply', 'language.apply']; + $toolbarButtons[] = ['save', 'language.save']; + } + + // If an existing item, can save to a copy only if we have create rights. + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2new', 'language.save2new']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if ($isNew) + { + ToolbarHelper::cancel('language.cancel'); + } + else + { + ToolbarHelper::cancel('language.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_EDIT'); + } +} diff --git a/administrator/components/com_languages/View/Languages/HtmlView.php b/administrator/components/com_languages/View/Languages/HtmlView.php new file mode 100644 index 0000000000000..f543f6779cf9b --- /dev/null +++ b/administrator/components/com_languages/View/Languages/HtmlView.php @@ -0,0 +1,179 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + LanguagesHelper::addSubmenu('languages'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_languages'); + + ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_LANGUAGES_TITLE'), 'comments-2 langmanager'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('language.add'); + } + + if ($canDo->get('core.edit.state')) + { + if ($this->state->get('filter.published') != 2) + { + ToolbarHelper::publishList('languages.publish'); + ToolbarHelper::unpublishList('languages.unpublish'); + } + } + + if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'languages.delete', 'JTOOLBAR_EMPTY_TRASH'); + ToolbarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('languages.trash'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.admin')) + { + // Add install languages link to the lang installer component. + $bar = Toolbar::getInstance('toolbar'); + $bar->appendButton('Link', 'upload', 'COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages'); + ToolbarHelper::divider(); + + ToolbarHelper::preferences('com_languages'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_CONTENT'); + + \JHtmlSidebar::setAction('index.php?option=com_languages&view=languages'); + + } + + /** + * Returns an array of fields the table can be sorted by. + * + * @return array Array containing the field name to sort by as the key and display text as value. + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.ordering' => Text::_('JGRID_HEADING_ORDERING'), + 'a.published' => Text::_('JSTATUS'), + 'a.title' => Text::_('JGLOBAL_TITLE'), + 'a.title_native' => Text::_('COM_LANGUAGES_HEADING_TITLE_NATIVE'), + 'a.lang_code' => Text::_('COM_LANGUAGES_FIELD_LANG_TAG_LABEL'), + 'a.sef' => Text::_('COM_LANGUAGES_FIELD_LANG_CODE_LABEL'), + 'a.image' => Text::_('COM_LANGUAGES_HEADING_LANG_IMAGE'), + 'a.access' => Text::_('JGRID_HEADING_ACCESS'), + 'a.lang_id' => Text::_('JGRID_HEADING_ID') + ); + } +} diff --git a/administrator/components/com_languages/View/Multilangstatus/HtmlView.php b/administrator/components/com_languages/View/Multilangstatus/HtmlView.php new file mode 100644 index 0000000000000..1563ad374406e --- /dev/null +++ b/administrator/components/com_languages/View/Multilangstatus/HtmlView.php @@ -0,0 +1,47 @@ +homes = MultilangstatusHelper::getHomes(); + $this->language_filter = Multilanguage::isEnabled(); + $this->switchers = MultilangstatusHelper::getLangswitchers(); + $this->listUsersError = MultilangstatusHelper::getContacts(); + $this->contentlangs = MultilangstatusHelper::getContentlangs(); + $this->site_langs = LanguageHelper::getInstalledLanguages(0); + $this->statuses = MultilangstatusHelper::getStatus(); + $this->homepages = Multilanguage::getSiteHomePages(); + $this->defaultHome = MultilangstatusHelper::getDefaultHomeModule(); + + parent::display($tpl); + } +} diff --git a/administrator/components/com_languages/View/Override/HtmlView.php b/administrator/components/com_languages/View/Override/HtmlView.php new file mode 100644 index 0000000000000..4c72fd47fca26 --- /dev/null +++ b/administrator/components/com_languages/View/Override/HtmlView.php @@ -0,0 +1,137 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors)); + } + + // Check whether the cache has to be refreshed. + $cached_time = Factory::getApplication()->getUserState( + 'com_languages.overrides.cachedtime.' . $this->state->get('filter.client') . '.' . $this->state->get('filter.language'), + 0 + ); + + if (time() - $cached_time > 60 * 5) + { + $this->state->set('cache_expired', true); + } + + // Add strings for translations in \Javascript. + Text::script('COM_LANGUAGES_VIEW_OVERRIDE_NO_RESULTS'); + Text::script('COM_LANGUAGES_VIEW_OVERRIDE_REQUEST_ERROR'); + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Adds the page title and toolbar. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $canDo = ContentHelper::getActions('com_languages'); + + ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_TITLE'), 'comments-2 langmanager'); + + $toolbarButtons = []; + + if ($canDo->get('core.edit')) + { + $toolbarButtons[] = ['apply', 'override.apply']; + $toolbarButtons[] = ['save', 'override.save']; + } + + // This component does not support Save as Copy. + if ($canDo->get('core.edit') && $canDo->get('core.create')) + { + $toolbarButtons[] = ['save2new', 'override.save2new']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (empty($this->item->key)) + { + ToolbarHelper::cancel('override.cancel'); + } + else + { + ToolbarHelper::cancel('override.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT'); + } +} diff --git a/administrator/components/com_languages/View/Overrides/HtmlView.php b/administrator/components/com_languages/View/Overrides/HtmlView.php new file mode 100644 index 0000000000000..fc351fd579032 --- /dev/null +++ b/administrator/components/com_languages/View/Overrides/HtmlView.php @@ -0,0 +1,145 @@ +state = $this->get('State'); + $this->items = $this->get('Overrides'); + $this->languages = $this->get('Languages'); + $this->pagination = $this->get('Pagination'); + + LanguagesHelper::addSubmenu('overrides'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors)); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Adds the page title and toolbar. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + // Get the results for each action + $canDo = ContentHelper::getActions('com_languages'); + + ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_OVERRIDES_TITLE'), 'comments-2 langmanager'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('override.add'); + } + + if ($canDo->get('core.delete') && $this->pagination->total) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'overrides.delete', 'JTOOLBAR_DELETE'); + } + + if (Factory::getUser()->authorise('core.admin')) + { + ToolbarHelper::custom('overrides.purge', 'refresh.png', 'refresh_f2.png', 'COM_LANGUAGES_VIEW_OVERRIDES_PURGE', false); + } + + if ($canDo->get('core.admin')) + { + ToolbarHelper::preferences('com_languages'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES'); + + \JHtmlSidebar::setAction('index.php?option=com_languages&view=overrides'); + + \JHtmlSidebar::addFilter( + '', + 'filter_language_client', + HTMLHelper::_('select.options', $this->languages, null, 'text', $this->state->get('filter.language_client')), + true + ); + + $this->sidebar = \JHtmlSidebar::render(); + } +} diff --git a/administrator/components/com_languages/access.xml b/administrator/components/com_languages/access.xml index bad626c9c5ba5..84be69f5ab141 100644 --- a/administrator/components/com_languages/access.xml +++ b/administrator/components/com_languages/access.xml @@ -1,11 +1,11 @@
- - - - - - + + + + + +
diff --git a/administrator/components/com_languages/controller.php b/administrator/components/com_languages/controller.php deleted file mode 100644 index e8fdc6643e811..0000000000000 --- a/administrator/components/com_languages/controller.php +++ /dev/null @@ -1,56 +0,0 @@ -input->get('view', 'languages'); - $layout = $this->input->get('layout', 'default'); - $id = $this->input->getInt('id'); - - // Check for edit form. - if ($view == 'language' && $layout == 'edit' && !$this->checkEditId('com_languages.edit.language', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_languages&view=languages', false)); - - return false; - } - - return parent::display(); - } -} diff --git a/administrator/components/com_languages/controllers/installed.php b/administrator/components/com_languages/controllers/installed.php deleted file mode 100644 index ce4716af02049..0000000000000 --- a/administrator/components/com_languages/controllers/installed.php +++ /dev/null @@ -1,95 +0,0 @@ -input->get('cid', ''); - $model = $this->getModel('installed'); - - if ($model->publish($cid)) - { - // Switching to the new administrator language for the message - if ($model->getState('client_id') == 1) - { - $language = JFactory::getLanguage(); - $newLang = JLanguage::getInstance($cid); - JFactory::$language = $newLang; - JFactory::getApplication()->loadLanguage($language = $newLang); - $newLang->load('com_languages', JPATH_ADMINISTRATOR); - } - - $msg = JText::_('COM_LANGUAGES_MSG_DEFAULT_LANGUAGE_SAVED'); - $type = 'message'; - } - else - { - $msg = $this->getError(); - $type = 'error'; - } - - $clientId = $model->getState('client_id'); - $this->setredirect('index.php?option=com_languages&view=installed&client=' . $clientId, $msg, $type); - } - - /** - * Task to switch the administrator language. - * - * @return void - */ - public function switchAdminLanguage() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $cid = $this->input->get('cid', ''); - $model = $this->getModel('installed'); - - // Fetching the language name from the xx-XX.xml - $file = JPATH_ADMINISTRATOR . '/language/' . $cid . '/' . $cid . '.xml'; - $info = JInstaller::parseXMLInstallFile($file); - $languageName = $info['name']; - - if ($model->switchAdminLanguage($cid)) - { - // Switching to the new language for the message - $language = JFactory::getLanguage(); - $newLang = JLanguage::getInstance($cid); - JFactory::$language = $newLang; - JFactory::getApplication()->loadLanguage($language = $newLang); - $newLang->load('com_languages', JPATH_ADMINISTRATOR); - - $msg = JText::sprintf('COM_LANGUAGES_MSG_SWITCH_ADMIN_LANGUAGE_SUCCESS', $languageName); - $type = 'message'; - } - else - { - $msg = $this->getError(); - $type = 'error'; - } - - $this->setredirect('index.php?option=com_languages&view=installed', $msg, $type); - } -} diff --git a/administrator/components/com_languages/controllers/language.php b/administrator/components/com_languages/controllers/language.php deleted file mode 100644 index 5c658edb0d1c8..0000000000000 --- a/administrator/components/com_languages/controllers/language.php +++ /dev/null @@ -1,33 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Method to save the submitted ordering values for records via AJAX. - * - * @return void - * - * @since 3.1 - */ - public function saveOrderAjax() - { - $pks = $this->input->post->get('cid', array(), 'array'); - $order = $this->input->post->get('order', array(), 'array'); - - // Sanitize the input. - $pks = ArrayHelper::toInteger($pks); - $order = ArrayHelper::toInteger($order); - - // Get the model. - $model = $this->getModel(); - - // Save the ordering. - $return = $model->saveorder($pks, $order); - - if ($return) - { - echo '1'; - } - - // Close the application. - JFactory::getApplication()->close(); - } -} diff --git a/administrator/components/com_languages/controllers/override.php b/administrator/components/com_languages/controllers/override.php deleted file mode 100644 index 24815acfec737..0000000000000 --- a/administrator/components/com_languages/controllers/override.php +++ /dev/null @@ -1,206 +0,0 @@ -allowCache(false); - - $app = JFactory::getApplication(); - $cid = $this->input->post->get('cid', array(), 'array'); - $context = "$this->option.edit.$this->context"; - - // Get the constant name. - $recordId = (count($cid) ? $cid[0] : $this->input->get('id')); - - // Access check. - if (!$this->allowEdit()) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED')); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); - - return; - } - - $app->setUserState($context . '.data', null); - $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id')); - } - - /** - * Method to save an override. - * - * @param string $key The name of the primary key of the URL variable (not used here). - * @param string $urlVar The name of the URL variable if different from the primary key (not used here). - * - * @return void - * - * @since 2.5 - */ - public function save($key = null, $urlVar = null) - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $model = $this->getModel(); - $data = $this->input->post->get('jform', array(), 'array'); - $context = "$this->option.edit.$this->context"; - $task = $this->getTask(); - - $recordId = $this->input->get('id'); - $data['id'] = $recordId; - - // Access check. - if (!$this->allowSave($data, 'id')) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED')); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); - - return; - } - - // Validate the posted data. - $form = $model->getForm($data, false); - - if (!$form) - { - $app->enqueueMessage($model->getError(), 'error'); - - return; - } - - // Require helper for filter functions called by JForm. - JLoader::register('LanguagesHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/languages.php'); - - // Test whether the data is valid. - $validData = $model->validate($form, $data); - - // Check for validation errors. - if ($validData === false) - { - // Get the validation messages. - $errors = $model->getErrors(); - - // 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) - { - $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); - } - else - { - $app->enqueueMessage($errors[$i], 'warning'); - } - } - - // Save the data in the session. - $app->setUserState($context . '.data', $data); - - // Redirect back to the edit screen. - $this->setRedirect( - JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id'), false) - ); - - return; - } - - // Attempt to save the data. - if (!$model->save($validData)) - { - // Save the data in the session. - $app->setUserState($context . '.data', $validData); - - // 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=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id'), false) - ); - - return; - } - - // Add message of success. - $this->setMessage(JText::_('COM_LANGUAGES_VIEW_OVERRIDE_SAVE_SUCCESS')); - - // Redirect the user and adjust session state based on the chosen task. - switch ($task) - { - case 'apply': - // Set the record data in the session. - $app->setUserState($context . '.data', null); - - // Redirect back to the edit screen - $this->setRedirect( - JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($validData['key'], 'id'), false) - ); - break; - - case 'save2new': - // Clear the record id and data from the session. - $app->setUserState($context . '.data', null); - - // Redirect back to the edit screen - $this->setRedirect( - JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(null, 'id'), false) - ); - break; - - default: - // Clear the record id and data from the session. - $app->setUserState($context . '.data', null); - - // Redirect to the list screen. - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); - break; - } - } - - /** - * Method to cancel an edit. - * - * @param string $key The name of the primary key of the URL variable (not used here). - * - * @return void - * - * @since 2.5 - */ - public function cancel($key = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $context = "$this->option.edit.$this->context"; - - $app->setUserState($context . '.data', null); - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); - } -} diff --git a/administrator/components/com_languages/controllers/overrides.php b/administrator/components/com_languages/controllers/overrides.php deleted file mode 100644 index 53699d55889b4..0000000000000 --- a/administrator/components/com_languages/controllers/overrides.php +++ /dev/null @@ -1,78 +0,0 @@ -input->get('cid', array(), 'array'); - - if (!is_array($cid) || count($cid) < 1) - { - $this->setMessage(JText::_($this->text_prefix . '_NO_ITEM_SELECTED'), 'warning'); - } - else - { - // Get the model. - $model = $this->getModel('overrides'); - - // Remove the items. - if ($model->delete($cid)) - { - $this->setMessage(JText::plural($this->text_prefix . '_N_ITEMS_DELETED', count($cid))); - } - else - { - $this->setMessage($model->getError()); - } - } - - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); - } - - /** - * Method to purge the overrider table. - * - * @return void - * - * @since 3.4.2 - */ - public function purge() - { - $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 deleted file mode 100644 index a7466ea622790..0000000000000 --- a/administrator/components/com_languages/controllers/strings.json.php +++ /dev/null @@ -1,42 +0,0 @@ -getModel('strings')->refresh()); - } - - /** - * Method for searching language strings - * - * @return void - * - * @since 2.5 - */ - public function search() - { - echo new JResponseJson($this->getModel('strings')->search()); - } -} diff --git a/administrator/components/com_languages/models/forms/filter_installed.xml b/administrator/components/com_languages/forms/filter_installed.xml similarity index 87% rename from administrator/components/com_languages/models/forms/filter_installed.xml rename to administrator/components/com_languages/forms/filter_installed.xml index 2ab9f1e90cc89..ac6a9cb6ddb3c 100644 --- a/administrator/components/com_languages/models/forms/filter_installed.xml +++ b/administrator/components/com_languages/forms/filter_installed.xml @@ -23,8 +23,6 @@ @@ -33,8 +31,8 @@ - - + + @@ -51,9 +49,6 @@ diff --git a/administrator/components/com_languages/forms/filter_languages.xml b/administrator/components/com_languages/forms/filter_languages.xml new file mode 100644 index 0000000000000..c93dd2b91ffa8 --- /dev/null +++ b/administrator/components/com_languages/forms/filter_languages.xml @@ -0,0 +1,63 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/administrator/components/com_languages/forms/language.xml b/administrator/components/com_languages/forms/language.xml new file mode 100644 index 0000000000000..c57a58ae799a9 --- /dev/null +++ b/administrator/components/com_languages/forms/language.xml @@ -0,0 +1,117 @@ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ +
+
diff --git a/administrator/components/com_languages/models/forms/override.xml b/administrator/components/com_languages/forms/override.xml similarity index 79% rename from administrator/components/com_languages/models/forms/override.xml rename to administrator/components/com_languages/forms/override.xml index 8d1a2ddb64e1d..08a2f7886d93e 100644 --- a/administrator/components/com_languages/models/forms/override.xml +++ b/administrator/components/com_languages/forms/override.xml @@ -5,7 +5,6 @@ name="key" type="text" label="COM_LANGUAGES_OVERRIDE_FIELD_KEY_LABEL" - description="COM_LANGUAGES_OVERRIDE_FIELD_KEY_DESC" size="60" required="true" filter="LanguagesHelper::filterKey" @@ -15,7 +14,6 @@ name="override" type="textarea" label="COM_LANGUAGES_OVERRIDE_FIELD_OVERRIDE_LABEL" - description="COM_LANGUAGES_OVERRIDE_FIELD_OVERRIDE_DESC" cols="50" rows="5" filter="LanguagesHelper::filterText" @@ -25,7 +23,6 @@ name="both" type="checkbox" label="COM_LANGUAGES_OVERRIDE_FIELD_BOTH_LABEL" - description="COM_LANGUAGES_OVERRIDE_FIELD_BOTH_DESC" value="true" filter="boolean" /> @@ -42,7 +39,6 @@ name="searchtype" type="list" label="COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_LABEL" - description="COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_DESC" default="value" > @@ -53,7 +49,6 @@ name="language" type="text" label="COM_LANGUAGES_OVERRIDE_FIELD_LANGUAGE_LABEL" - description="COM_LANGUAGES_OVERRIDE_FIELD_LANGUAGE_DESC" filter="unset" readonly="true" class="readonly" @@ -64,7 +59,6 @@ name="client" type="text" label="COM_LANGUAGES_OVERRIDE_FIELD_CLIENT_LABEL" - description="COM_LANGUAGES_OVERRIDE_FIELD_CLIENT_DESC" filter="unset" readonly="true" class="readonly" @@ -75,7 +69,6 @@ name="file" type="text" label="COM_LANGUAGES_OVERRIDE_FIELD_FILE_LABEL" - description="COM_LANGUAGES_OVERRIDE_FIELD_FILE_DESC" filter="unset" readonly="true" class="readonly" diff --git a/administrator/components/com_languages/helpers/html/languages.php b/administrator/components/com_languages/helpers/html/languages.php index 252b07f41a3ec..19f742d681961 100644 --- a/administrator/components/com_languages/helpers/html/languages.php +++ b/administrator/components/com_languages/helpers/html/languages.php @@ -9,6 +9,9 @@ defined('_JEXEC') or die; +use Joomla\CMS\Language\Text; +use Joomla\CMS\HTML\HTMLHelper; + /** * Utility class working with languages * @@ -30,7 +33,7 @@ public static function published($published) return ' '; } - return JHtml::_('image', 'menu/icon-16-default.png', JText::_('COM_LANGUAGES_HEADING_DEFAULT'), null, true); + return HTMLHelper::_('image', 'menu/icon-16-default.png', Text::_('COM_LANGUAGES_HEADING_DEFAULT'), null, true); } /** @@ -50,7 +53,7 @@ public static function id($rowNum, $language) . ' value="' . htmlspecialchars($language, ENT_COMPAT, 'UTF-8') . '"' . ' onclick="Joomla.isChecked(this.checked);"' . ' title="' . ($rowNum + 1) . '"' - . '/>'; + . '>'; } /** @@ -61,8 +64,8 @@ public static function id($rowNum, $language) public static function clients() { return array( - JHtml::_('select.option', 0, JText::_('JSITE')), - JHtml::_('select.option', 1, JText::_('JADMINISTRATOR')) + HTMLHelper::_('select.option', 0, Text::_('JSITE')), + HTMLHelper::_('select.option', 1, Text::_('JADMINISTRATOR')) ); } @@ -77,10 +80,10 @@ public static function publishedOptions() { // Build the active state filter options. $options = array(); - $options[] = JHtml::_('select.option', '1', 'JPUBLISHED'); - $options[] = JHtml::_('select.option', '0', 'JUNPUBLISHED'); - $options[] = JHtml::_('select.option', '-2', 'JTRASHED'); - $options[] = JHtml::_('select.option', '*', 'JALL'); + $options[] = HTMLHelper::_('select.option', '1', 'JPUBLISHED'); + $options[] = HTMLHelper::_('select.option', '0', 'JUNPUBLISHED'); + $options[] = HTMLHelper::_('select.option', '-2', 'JTRASHED'); + $options[] = HTMLHelper::_('select.option', '*', 'JALL'); return $options; } diff --git a/administrator/components/com_languages/helpers/jsonresponse.php b/administrator/components/com_languages/helpers/jsonresponse.php deleted file mode 100644 index a5ef8f0c1e2cc..0000000000000 --- a/administrator/components/com_languages/helpers/jsonresponse.php +++ /dev/null @@ -1,134 +0,0 @@ -success, - * so you can use both flags equivalently. - * - * @var boolean - * @since 2.5 - */ - public $error = false; - - /** - * The main response message. - * - * @var string - * @since 2.5 - */ - public $message = null; - - /** - * Array of messages gathered in the JApplication object. - * - * @var array - * @since 2.5 - */ - public $messages = null; - - /** - * The response data. - * - * @var mixed - * @since 2.5 - */ - public $data = null; - - /** - * Constructor - * - * @param mixed $response The Response data. - * @param string $message The main response message. - * @param boolean $error True, if the success flag shall be set to false, defaults to false. - * - * @since 2.5 - * @deprecated 4.0 Use JResponseJson instead. - */ - public function __construct($response = null, $message = null, $error = false) - { - try - { - JLog::add(sprintf('%s is deprecated, use JResponseJson instead.', __CLASS__), JLog::WARNING, 'deprecated'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $this->message = $message; - - // Get the message queue. - $messages = JFactory::getApplication()->getMessageQueue(); - - // Build the sorted messages list. - if (is_array($messages) && count($messages)) - { - foreach ($messages as $message) - { - if (isset($message['type']) && isset($message['message'])) - { - $lists[$message['type']][] = $message['message']; - } - } - } - - // If messages exist add them to the output. - if (isset($lists) && is_array($lists)) - { - $this->messages = $lists; - } - - // Check if we are dealing with an error. - if ($response instanceof Exception) - { - // Prepare the error response. - $this->success = false; - $this->error = true; - $this->message = $response->getMessage(); - } - else - { - // Prepare the response data. - $this->success = !$error; - $this->error = $error; - $this->data = $response; - } - } - - /** - * Magic toString method for sending the response in JSON format. - * - * @return string The response in JSON format. - * - * @since 2.5 - */ - public function __toString() - { - return json_encode($this); - } -} diff --git a/administrator/components/com_languages/helpers/languages.php b/administrator/components/com_languages/helpers/languages.php deleted file mode 100644 index 72adc9c4d62ed..0000000000000 --- a/administrator/components/com_languages/helpers/languages.php +++ /dev/null @@ -1,136 +0,0 @@ -clean($value, 'cmd')); - } - - /** - * Filter method for language strings. - * This method will be called by JForm while filtering the form data. - * - * @param string $value The language string to filter. - * - * @return string The filtered language string. - * - * @since 2.5 - */ - public static function filterText($value) - { - $filter = JFilterInput::getInstance(null, null, 1, 1); - - return $filter->clean($value); - } -} diff --git a/administrator/components/com_languages/helpers/multilangstatus.php b/administrator/components/com_languages/helpers/multilangstatus.php deleted file mode 100644 index 3c453ae88e0d6..0000000000000 --- a/administrator/components/com_languages/helpers/multilangstatus.php +++ /dev/null @@ -1,321 +0,0 @@ -getQuery(true) - ->select('COUNT(*)') - ->from($db->quoteName('#__menu')) - ->where('home = 1') - ->where('published = 1') - ->where('client_id = 0'); - $db->setQuery($query); - - return $db->loadResult(); - } - - /** - * Method to get the number of published language switcher modules. - * - * @return integer - */ - public static function getLangswitchers() - { - // Check if switcher is published. - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('COUNT(*)') - ->from($db->quoteName('#__modules')) - ->where('module = ' . $db->quote('mod_languages')) - ->where('published = 1') - ->where('client_id = 0'); - $db->setQuery($query); - - return $db->loadResult(); - } - - /** - * Method to return a list of published content languages. - * - * @return array of language objects. - */ - public static function getContentlangs() - { - // Check for published Content Languages. - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('a.lang_code AS lang_code') - ->select('a.published AS published') - ->from('#__languages AS a'); - $db->setQuery($query); - - return $db->loadObjectList(); - } - - /** - * Method to return a list of published site languages. - * - * @return array of language extension objects. - * - * @deprecated 4.0 Use JLanguageHelper::getInstalledLanguages(0) instead. - */ - public static function getSitelangs() - { - try - { - JLog::add( - sprintf('%s() is deprecated, use JLanguageHelper::getInstalledLanguages(0) instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - return JLanguageHelper::getInstalledLanguages(0); - } - - /** - * Method to return a list of language home page menu items. - * - * @return array of menu objects. - * - * @deprecated 4.0 Use JLanguageMultilang::getSiteHomePages() instead. - */ - public static function getHomepages() - { - try - { - JLog::add( - sprintf('%s() is deprecated, use JLanguageHelper::getSiteHomePages() instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - return JLanguageMultilang::getSiteHomePages(); - } - - /** - * Method to return combined language status. - * - * @return array of language objects. - */ - public static function getStatus() - { - // Check for combined status. - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - // Select all fields from the languages table. - $query->select('a.*', 'l.home') - ->select('a.published AS published') - ->select('a.lang_code AS lang_code') - ->from('#__languages AS a'); - - // Select the language home pages. - $query->select('l.home AS home') - ->select('l.language AS home_language') - ->join('LEFT', '#__menu AS l ON l.language = a.lang_code AND l.home=1 AND l.published=1 AND l.language <> \'*\'') - ->select('e.enabled AS enabled') - ->select('e.element AS element') - ->join('LEFT', '#__extensions AS e ON e.element = a.lang_code') - ->where('e.client_id = 0') - ->where('e.enabled = 1') - ->where('e.state = 0'); - - $db->setQuery($query); - - return $db->loadObjectList(); - } - - /** - * Method to return a list of contact objects. - * - * @return array of contact objects. - */ - public static function getContacts() - { - $db = JFactory::getDbo(); - $languages = count(JLanguageHelper::getLanguages()); - - // Get the number of contact with all as language - $alang = $db->getQuery(true) - ->select('count(*)') - ->from('#__contact_details AS cd') - ->where('cd.user_id=u.id') - ->where('cd.published=1') - ->where('cd.language=' . $db->quote('*')); - - // Get the number of languages for the contact - $slang = $db->getQuery(true) - ->select('count(distinct(l.lang_code))') - ->from('#__languages as l') - ->join('LEFT', '#__contact_details AS cd ON cd.language=l.lang_code') - ->where('cd.user_id=u.id') - ->where('cd.published=1') - ->where('l.published=1'); - - // Get the number of multiple contact/language - $mlang = $db->getQuery(true) - ->select('count(*)') - ->from('#__languages as l') - ->join('LEFT', '#__contact_details AS cd ON cd.language=l.lang_code') - ->where('cd.user_id=u.id') - ->where('cd.published=1') - ->where('l.published=1') - ->group('l.lang_code') - ->having('count(*) > 1'); - - // Get the contacts - $query = $db->getQuery(true) - ->select('u.name, (' . $alang . ') as alang, (' . $slang . ') as slang, (' . $mlang . ') as mlang') - ->from('#__users AS u') - ->join('LEFT', '#__contact_details AS cd ON cd.user_id=u.id') - ->where('EXISTS (SELECT 1 from #__content as c where c.created_by=u.id)') - ->group('u.id'); - - $db->setQuery($query); - $warnings = $db->loadObjectList(); - - foreach ($warnings as $index => $warn) - { - if ($warn->alang == 1 && $warn->slang == 0) - { - unset($warnings[$index]); - } - - if ($warn->alang == 0 && $warn->slang == 0 && empty($warn->mlang)) - { - unset($warnings[$index]); - } - - if ($warn->alang == 0 && $warn->slang == $languages && empty($warn->mlang)) - { - unset($warnings[$index]); - } - } - - return $warnings; - } - - /** - * Method to get the status of the module displaying the menutype of the default Home page set to All languages. - * - * @return boolean True if the module is published, false otherwise. - * - * @since 3.7.0 - */ - public static function getDefaultHomeModule() - { - // Find Default Home menutype. - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->qn('menutype')) - ->from($db->qn('#__menu')) - ->where($db->qn('home') . ' = ' . $db->q('1')) - ->where($db->qn('published') . ' = ' . $db->q('1')) - ->where($db->qn('client_id') . ' = ' . $db->q('0')) - ->where($db->qn('language') . ' = ' . $db->q('*')); - - $db->setQuery($query); - - $menutype = $db->loadResult(); - - // Get published site menu modules titles. - $query->clear() - ->select($db->qn('title')) - ->from($db->qn('#__modules')) - ->where($db->qn('module') . ' = ' . $db->q('mod_menu')) - ->where($db->qn('published') . ' = ' . $db->q('1')) - ->where($db->qn('client_id') . ' = ' . $db->q('0')); - - $db->setQuery($query); - - $menutitles = $db->loadColumn(); - - // Do we have a published menu module displaying the default Home menu item set to all languages? - foreach ($menutitles as $menutitle) - { - $module = self::getModule('mod_menu', $menutitle); - $moduleParams = new JRegistry($module->params); - $param = $moduleParams->get('menutype', ''); - - if ($param && $param != $menutype) - { - continue; - } - - return true; - } - } - - /** - * Get module by name - * - * @param string $moduleName The name of the module - * @param string $instanceTitle The title of the module, optional - * - * @return stdClass The Module object - * - * @since 3.7.0 - */ - public static function getModule($moduleName, $instanceTitle = null) - { - $db = JFactory::getDbo(); - - $query = $db->getQuery(true) - ->select('id, title, module, position, content, showtitle, params') - ->from($db->qn('#__modules')) - ->where($db->qn('module') . ' = ' . $db->q($moduleName)) - ->where($db->qn('published') . ' = ' . $db->q('1')) - ->where($db->qn('client_id') . ' = ' . $db->q('0')); - - if ($instanceTitle) - { - $query->where($db->qn('title') . ' = ' . $db->q($instanceTitle)); - } - - $db->setQuery($query); - - try - { - $modules = $db->loadObject(); - } - catch (RuntimeException $e) - { - JLog::add(JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage()), JLog::WARNING, 'jerror'); - } - - return $modules; - } -} diff --git a/administrator/components/com_languages/languages.php b/administrator/components/com_languages/languages.php deleted file mode 100644 index 219b308e9ea8b..0000000000000 --- a/administrator/components/com_languages/languages.php +++ /dev/null @@ -1,20 +0,0 @@ -authorise('core.manage', 'com_languages')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('Languages'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_languages/languages.xml b/administrator/components/com_languages/languages.xml index 33e98d4cccb4c..67d5a58bf0aae 100644 --- a/administrator/components/com_languages/languages.xml +++ b/administrator/components/com_languages/languages.xml @@ -9,15 +9,19 @@ www.joomla.org 3.0.0 COM_LANGUAGES_XML_DESCRIPTION + Joomla\Component\Languages + access.xml config.xml - controller.php - languages.php - controllers + dispatcher.php + Controller + Helper helpers + layouts + Model models - tables + View views diff --git a/administrator/components/com_languages/models/forms/filter_languages.xml b/administrator/components/com_languages/models/forms/filter_languages.xml deleted file mode 100644 index b770f5b0e76d1..0000000000000 --- a/administrator/components/com_languages/models/forms/filter_languages.xml +++ /dev/null @@ -1,68 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/administrator/components/com_languages/models/forms/language.xml b/administrator/components/com_languages/models/forms/language.xml deleted file mode 100644 index 61e900bc6844e..0000000000000 --- a/administrator/components/com_languages/models/forms/language.xml +++ /dev/null @@ -1,128 +0,0 @@ - -
-
- - - - - - - - - - - - - - - - - - - - - - - -
-
- - - -
-
- -
-
diff --git a/administrator/components/com_languages/models/installed.php b/administrator/components/com_languages/models/installed.php deleted file mode 100644 index 55a491f59f996..0000000000000 --- a/administrator/components/com_languages/models/installed.php +++ /dev/null @@ -1,487 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - - // Special case for client id. - $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); - $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; - $this->setState('client_id', $clientId); - - // Load the parameters. - $params = JComponentHelper::getParams('com_languages'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - * - * @since 1.6 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('client_id'); - $id .= ':' . $this->getState('filter.search'); - - return parent::getStoreId($id); - } - - /** - * Method to get the client object. - * - * @return object - * - * @since 1.6 - */ - public function getClient() - { - return JApplicationHelper::getClientInfo($this->getState('client_id', 0)); - } - - /** - * Method to get the ftp credentials. - * - * @return object - * - * @since 1.6 - */ - public function getFtp() - { - if (is_null($this->ftp)) - { - $this->ftp = JClientHelper::setCredentialsFromRequest('ftp'); - } - - return $this->ftp; - } - - /** - * Method to get the option. - * - * @return object - * - * @since 1.6 - */ - public function getOption() - { - $option = $this->getState('option'); - - return $option; - } - - /** - * Method to get Languages item data. - * - * @return array - * - * @since 1.6 - */ - public function getData() - { - // Fetch language data if not fetched yet. - if (is_null($this->data)) - { - $this->data = array(); - - $isCurrentLanguageRtl = JFactory::getLanguage()->isRtl(); - $params = JComponentHelper::getParams('com_languages'); - $installedLanguages = JLanguageHelper::getInstalledLanguages(null, true, true, null, null, null); - - // Compute all the languages. - foreach ($installedLanguages as $clientId => $languages) - { - $defaultLanguage = $params->get(JApplicationHelper::getClientInfo($clientId)->name, 'en-GB'); - - foreach ($languages as $lang) - { - $row = new stdClass; - $row->language = $lang->element; - $row->name = $lang->metadata['name']; - $row->nativeName = isset($lang->metadata['nativeName']) ? $lang->metadata['nativeName'] : '-'; - $row->client_id = (int) $lang->client_id; - $row->extension_id = (int) $lang->extension_id; - $row->author = $lang->manifest['author']; - $row->creationDate = $lang->manifest['creationDate']; - $row->authorEmail = $lang->manifest['authorEmail']; - $row->version = $lang->manifest['version']; - $row->published = $defaultLanguage === $row->language ? 1 : 0; - $row->checked_out = 0; - - // Fix wrongly set parentheses in RTL languages - if ($isCurrentLanguageRtl) - { - $row->name = html_entity_decode($row->name . '‎', ENT_QUOTES, 'UTF-8'); - $row->nativeName = html_entity_decode($row->nativeName . '‎', ENT_QUOTES, 'UTF-8'); - } - - $this->data[] = $row; - } - } - } - - $installedLanguages = array_merge($this->data); - - // Process filters. - $clientId = (int) $this->getState('client_id'); - $search = $this->getState('filter.search'); - - foreach ($installedLanguages as $key => $installedLanguage) - { - // Filter by client id. - if (in_array($clientId, array(0, 1))) - { - if ($installedLanguage->client_id !== $clientId) - { - unset($installedLanguages[$key]); - continue; - } - } - - // Filter by search term. - if (!empty($search)) - { - if (stripos($installedLanguage->name, $search) === false - && stripos($installedLanguage->nativeName, $search) === false - && stripos($installedLanguage->language, $search) === false) - { - unset($installedLanguages[$key]); - continue; - } - } - } - - // Process ordering. - $listOrder = $this->getState('list.ordering', 'name'); - $listDirn = $this->getState('list.direction', 'ASC'); - $installedLanguages = ArrayHelper::sortObjects($installedLanguages, $listOrder, strtolower($listDirn) === 'desc' ? -1 : 1, true, true); - - // Process pagination. - $limit = (int) $this->getState('list.limit', 25); - - // Sets the total for pagination. - $this->total = count($installedLanguages); - - if ($limit !== 0) - { - $start = (int) $this->getState('list.start', 0); - - return array_slice($installedLanguages, $start, $limit); - } - - return $installedLanguages; - } - - /** - * Method to get installed languages data. - * - * @return string An SQL query. - * - * @since 1.6 - * - * @deprecated 4.0 - */ - protected function getLanguageList() - { - // Create a new db object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - $client = $this->getState('client_id'); - $type = 'language'; - - // Select field element from the extensions table. - $query->select($this->getState('list.select', 'a.element')) - ->from('#__extensions AS a'); - - $type = $db->quote($type); - $query->where('(a.type = ' . $type . ')') - ->where('state = 0') - ->where('enabled = 1') - ->where('client_id=' . (int) $client); - - // For client_id = 1 do we need to check language table also? - $db->setQuery($query); - - $this->langlist = $db->loadColumn(); - - return $this->langlist; - } - - /** - * Method to get the total number of Languages items. - * - * @return integer - * - * @since 1.6 - */ - public function getTotal() - { - if (is_null($this->total)) - { - $this->getData(); - } - - return $this->total; - } - - /** - * Method to set the default language. - * - * @param integer $cid Id of the language to publish. - * - * @return boolean - * - * @since 1.6 - */ - public function publish($cid) - { - if ($cid) - { - $client = $this->getClient(); - - $params = JComponentHelper::getParams('com_languages'); - $params->set($client->name, $cid); - - $table = JTable::getInstance('extension'); - $id = $table->find(array('element' => 'com_languages')); - - // Load. - if (!$table->load($id)) - { - $this->setError($table->getError()); - - return false; - } - - $table->params = (string) $params; - - // Pre-save checks. - if (!$table->check()) - { - $this->setError($table->getError()); - - return false; - } - - // Save the changes. - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - } - else - { - $this->setError(JText::_('COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED')); - - return false; - } - - // Clean the cache of com_languages and component cache. - $this->cleanCache(); - $this->cleanCache('_system', 0); - $this->cleanCache('_system', 1); - - return true; - } - - /** - * Method to get the folders. - * - * @return array Languages folders. - * - * @since 1.6 - */ - protected function getFolders() - { - if (is_null($this->folders)) - { - $path = $this->getPath(); - jimport('joomla.filesystem.folder'); - $this->folders = JFolder::folders($path, '.', false, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'pdf_fonts', 'overrides')); - } - - return $this->folders; - } - - /** - * Method to get the path. - * - * @return string The path to the languages folders. - * - * @since 1.6 - */ - protected function getPath() - { - if (is_null($this->path)) - { - $client = $this->getClient(); - $this->path = JLanguageHelper::getLanguagePath($client->path); - } - - return $this->path; - } - - /** - * Method to compare two languages in order to sort them. - * - * @param object $lang1 The first language. - * @param object $lang2 The second language. - * - * @return integer - * - * @since 1.6 - * - * @deprecated 4.0 - */ - protected function compareLanguages($lang1, $lang2) - { - return strcmp($lang1->name, $lang2->name); - } - - /** - * Method to switch the administrator language. - * - * @param string $cid The language tag. - * - * @return boolean - * - * @since 3.5 - */ - public function switchAdminLanguage($cid) - { - if ($cid) - { - $client = $this->getClient(); - - if ($client->name == 'administrator') - { - JFactory::getApplication()->setUserState('application.lang', $cid); - } - } - else - { - JError::raiseWarning(500, JText::_('COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED')); - - return false; - } - - return true; - } -} diff --git a/administrator/components/com_languages/models/language.php b/administrator/components/com_languages/models/language.php deleted file mode 100644 index 92416726e1771..0000000000000 --- a/administrator/components/com_languages/models/language.php +++ /dev/null @@ -1,267 +0,0 @@ - 'onExtensionAfterSave', - 'event_before_save' => 'onExtensionBeforeSave', - 'events_map' => array( - 'save' => 'extension' - ) - ), $config - ); - - parent::__construct($config); - } - - /** - * Override to get the table. - * - * @param string $name Name of the table. - * @param string $prefix Table name prefix. - * @param array $options Array of options. - * - * @return JTable - * - * @since 1.6 - */ - public function getTable($name = '', $prefix = '', $options = array()) - { - return JTable::getInstance('Language'); - } - - /** - * Method to auto-populate the model state. - * - * Note. Calling getState in this method will result in recursion. - * - * @return void - * - * @since 1.6 - */ - protected function populateState() - { - $app = JFactory::getApplication('administrator'); - $params = JComponentHelper::getParams('com_languages'); - - // Load the User state. - $langId = $app->input->getInt('lang_id'); - $this->setState('language.id', $langId); - - // Load the parameters. - $this->setState('params', $params); - } - - /** - * Method to get a member item. - * - * @param integer $langId The id of the member to get. - * - * @return mixed User data object on success, false on failure. - * - * @since 1.0 - */ - public function getItem($langId = null) - { - $langId = (!empty($langId)) ? $langId : (int) $this->getState('language.id'); - - // Get a member row instance. - $table = $this->getTable(); - - // Attempt to load the row. - $return = $table->load($langId); - - // Check for a table object error. - if ($return === false && $table->getError()) - { - $this->setError($table->getError()); - - return false; - } - - // Set a valid accesslevel in case '0' is stored due to a bug in the installation SQL (was fixed with PR 2714). - if ($table->access == '0') - { - $table->access = (int) JFactory::getConfig()->get('access'); - } - - $properties = $table->getProperties(1); - $value = ArrayHelper::toObject($properties, 'JObject'); - - return $value; - } - - /** - * Method to get the group form. - * - * @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 mixed A JForm object on success, false on failure. - * - * @since 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - // Get the form. - $form = $this->loadForm('com_languages.language', 'language', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_languages.edit.language.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - $this->preprocessData('com_languages.language', $data); - - return $data; - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function save($data) - { - $langId = (!empty($data['lang_id'])) ? $data['lang_id'] : (int) $this->getState('language.id'); - $isNew = true; - - $dispatcher = JEventDispatcher::getInstance(); - JPluginHelper::importPlugin($this->events_map['save']); - - $table = $this->getTable(); - $context = $this->option . '.' . $this->name; - - // Load the row if saving an existing item. - if ($langId > 0) - { - $table->load($langId); - $isNew = false; - } - - // Prevent white spaces, including East Asian double bytes. - $spaces = array('/\xE3\x80\x80/', ' '); - - $data['lang_code'] = str_replace($spaces, '', $data['lang_code']); - - // Prevent saving an incorrect language tag - if (!preg_match('#\b([a-z]{2,3})[-]([A-Z]{2})\b#', $data['lang_code'])) - { - $this->setError(JText::_('COM_LANGUAGES_ERROR_LANG_TAG')); - - return false; - } - - $data['sef'] = str_replace($spaces, '', $data['sef']); - $data['sef'] = JApplicationHelper::stringURLSafe($data['sef']); - - // Bind the data. - if (!$table->bind($data)) - { - $this->setError($table->getError()); - - return false; - } - - // Check the data. - if (!$table->check()) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the before save event. - $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, $isNew)); - - // Check the event responses. - if (in_array(false, $result, true)) - { - $this->setError($table->getError()); - - return false; - } - - // Store the data. - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the after save event. - $dispatcher->trigger($this->event_after_save, array($context, &$table, $isNew)); - - $this->setState('language.id', $table->lang_id); - - // Clean the cache. - $this->cleanCache(); - - return true; - } - - /** - * Custom clean cache method. - * - * @param string $group Optional cache group name. - * @param integer $client_id Application client id. - * - * @return void - * - * @since 1.6 - */ - protected function cleanCache($group = null, $client_id = 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 deleted file mode 100644 index 2cf61483c335e..0000000000000 --- a/administrator/components/com_languages/models/languages.php +++ /dev/null @@ -1,220 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.access', $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', '', 'cmd')); - $this->setState('filter.published', $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string')); - - // Load the parameters. - $params = JComponentHelper::getParams('com_languages'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - * - * @since 1.6 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.access'); - $id .= ':' . $this->getState('filter.published'); - - return parent::getStoreId($id); - } - - /** - * Method to build an SQL query to load the list data. - * - * @return string An SQL query - * - * @since 1.6 - */ - protected function getListQuery() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - - // Select all fields from the languages table. - $query->select($this->getState('list.select', 'a.*', 'l.home')) - ->from($db->quoteName('#__languages') . ' AS a'); - - // Join over the asset groups. - $query->select('ag.title AS access_level') - ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); - - // Select the language home pages. - $query->select('l.home AS home') - ->join('LEFT', $db->quoteName('#__menu') . ' AS l ON l.language = a.lang_code AND l.home=1 AND l.language <> ' . $db->quote('*')); - - // Filter on the published state. - $published = $this->getState('filter.published'); - - if (is_numeric($published)) - { - $query->where('a.published = ' . (int) $published); - } - elseif ($published === '') - { - $query->where('(a.published IN (0, 1))'); - } - - // Filter by search in title. - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('(a.title LIKE ' . $search . ')'); - } - - // Filter by access level. - if ($access = $this->getState('filter.access')) - { - $query->where('a.access = ' . (int) $access); - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - return $query; - } - - /** - * Set the published language(s). - * - * @param array $cid An array of language IDs. - * @param integer $value The value of the published state. - * - * @return boolean True on success, false otherwise. - * - * @since 1.6 - */ - public function setPublished($cid, $value = 0) - { - return JTable::getInstance('Language')->publish($cid, $value); - } - - /** - * Method to delete records. - * - * @param array $pks An array of item primary keys. - * - * @return boolean Returns true on success, false on failure. - * - * @since 1.6 - */ - public function delete($pks) - { - // Sanitize the array. - $pks = (array) $pks; - - // Get a row instance. - $table = JTable::getInstance('Language'); - - // Iterate the items to delete each one. - foreach ($pks as $itemId) - { - if (!$table->delete((int) $itemId)) - { - $this->setError($table->getError()); - - return false; - } - } - - // Clean the cache. - $this->cleanCache(); - - return true; - } - - /** - * Custom clean cache method, 2 places for 2 clients. - * - * @param string $group Optional cache group name. - * @param integer $client_id Application client id. - * - * @return void - * - * @since 1.6 - */ - protected function cleanCache($group = null, $client_id = 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 deleted file mode 100644 index 29682a48c66a5..0000000000000 --- a/administrator/components/com_languages/models/override.php +++ /dev/null @@ -1,215 +0,0 @@ -loadForm('com_languages.override', 'override', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - $client = $this->getState('filter.client', 'site'); - $language = $this->getState('filter.language', 'en-GB'); - $langName = JLanguage::getInstance($language)->getName(); - - if (!$langName) - { - // 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; - } - - $form->setValue('client', null, JText::_('COM_LANGUAGES_VIEW_OVERRIDE_CLIENT_' . strtoupper($client))); - $form->setValue('language', null, JText::sprintf('COM_LANGUAGES_VIEW_OVERRIDE_LANGUAGE', $langName, $language)); - $form->setValue('file', null, JPath::clean(constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $language . '.override.ini')); - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 2.5 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_languages.edit.override.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - $this->preprocessData('com_languages.override', $data); - - return $data; - } - - /** - * Method to get a single record. - * - * @param string $pk The key name. - * - * @return mixed Object on success, false otherwise. - * - * @since 2.5 - */ - 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'))) - . '/language/overrides/' . $this->getState('filter.language', 'en-GB') . '.override.ini'; - $strings = LanguagesHelper::parseFile($filename); - - $result = new stdClass; - $result->key = ''; - $result->override = ''; - - if (isset($strings[$pk])) - { - $result->key = $pk; - $result->override = $strings[$pk]; - } - - $opposite_filename = 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]); - - return $result; - } - - /** - * 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. - * - * @return boolean True on success, false otherwise. - * - * @since 2.5 - */ - public function save($data, $opposite_client = false) - { - JLoader::register('LanguagesHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/languages.php'); - jimport('joomla.filesystem.file'); - - $app = JFactory::getApplication(); - - $client = $app->getUserState('com_languages.overrides.filter.client', 0); - $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); - - // If the override should be created for both. - if ($opposite_client) - { - $client = 1 - $client; - } - - // Return false if the constant is a reserved word, i.e. YES, NO, NULL, FALSE, ON, OFF, NONE, TRUE - $blacklist = array('YES', 'NO', 'NULL', 'FALSE', 'ON', 'OFF', 'NONE', 'TRUE'); - - if (in_array($data['key'], $blacklist)) - { - $this->setError(JText::_('COM_LANGUAGES_OVERRIDE_ERROR_RESERVED_WORDS')); - - return 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); - - if (isset($strings[$data['id']])) - { - // If an existent string was edited check whether - // the name of the constant is still the same. - if ($data['key'] == $data['id']) - { - // If yes, simply override it. - $strings[$data['key']] = $data['override']; - } - else - { - // If no, delete the old string and prepend the new one. - unset($strings[$data['id']]); - $strings = array($data['key'] => $data['override']) + $strings; - } - } - else - { - // If it is a new override simply prepend it. - $strings = array($data['key'] => $data['override']) + $strings; - } - - // Write override.ini file with the strings. - 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) - { - return $this->save($data, true); - } - - return true; - } - - /** - * Method to auto-populate the model state. - * - * Note. Calling getState in this method will result in recursion. - * - * @return void - * - * @since 2.5 - */ - protected function populateState() - { - $app = JFactory::getApplication(); - - $client = $app->getUserStateFromRequest('com_languages.overrides.filter.client', 'filter_client', 0, 'int') ? 'administrator' : 'site'; - $this->setState('filter.client', $client); - - $language = $app->getUserStateFromRequest('com_languages.overrides.filter.language', 'filter_language', 'en-GB', 'cmd'); - $this->setState('filter.language', $language); - } -} diff --git a/administrator/components/com_languages/models/overrides.php b/administrator/components/com_languages/models/overrides.php deleted file mode 100644 index a7baba6a8bfb0..0000000000000 --- a/administrator/components/com_languages/models/overrides.php +++ /dev/null @@ -1,301 +0,0 @@ -filter_fields = array('key', 'text'); - } - - /** - * Retrieves the overrides data - * - * @param boolean $all True if all overrides shall be returned without considering pagination, defaults to false - * - * @return array Array of objects containing the overrides of the override.ini file - * - * @since 2.5 - */ - public function getOverrides($all = false) - { - // Get a storage key. - $store = $this->getStoreId(); - - // Try to load the data from internal storage. - if (!empty($this->cache[$store])) - { - return $this->cache[$store]; - } - - $client = in_array($this->state->get('filter.client'), array(0, 'site')) ? 'SITE' : 'ADMINISTRATOR'; - - // 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); - - // Delete the override.ini file if empty. - if (file_exists($filename) && empty($strings)) - { - JFile::delete($filename); - } - - // Filter the loaded strings according to the search box. - $search = $this->getState('filter.search'); - - if ($search != '') - { - $search = preg_quote($search, '~'); - $matchvals = preg_grep('~' . $search . '~i', $strings); - $matchkeys = array_intersect_key($strings, array_flip(preg_grep('~' . $search . '~i', array_keys($strings)))); - $strings = array_merge($matchvals, $matchkeys); - } - - // Consider the ordering - if ($this->getState('list.ordering') == 'text') - { - if (strtoupper($this->getState('list.direction')) == 'DESC') - { - arsort($strings); - } - else - { - asort($strings); - } - } - else - { - if (strtoupper($this->getState('list.direction')) == 'DESC') - { - krsort($strings); - } - else - { - ksort($strings); - } - } - - // Consider the pagination. - if (!$all && $this->getState('list.limit') && $this->getTotal() > $this->getState('list.limit')) - { - $strings = array_slice($strings, $this->getStart(), $this->getState('list.limit'), true); - } - - // Add the items to the internal cache. - $this->cache[$store] = $strings; - - return $this->cache[$store]; - } - - /** - * Method to get the total number of overrides. - * - * @return integer The total number of overrides. - * - * @since 2.5 - */ - public function getTotal() - { - // Get a storage key. - $store = $this->getStoreId('getTotal'); - - // Try to load the data from internal storage - if (!empty($this->cache[$store])) - { - return $this->cache[$store]; - } - - // Add the total to the internal cache. - $this->cache[$store] = count($this->getOverrides(true)); - - return $this->cache[$store]; - } - - /** - * 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 2.5 - */ - 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'; - - $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'); - - 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'); - } - - // 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('filter.client', $client ? 'administrator' : 'site'); - $this->setState('filter.language', $language); - - // 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']; - } - - /** - * Method to delete one or more overrides. - * - * @param array $cids Array of keys to delete. - * - * @return integer Number of successfully deleted overrides, boolean false if an error occurred. - * - * @since 2.5 - */ - public function delete($cids) - { - // Check permissions first. - if (!JFactory::getUser()->authorise('core.delete', 'com_languages')) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); - - return false; - } - - 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); - - // Unset strings that shall be deleted - foreach ($cids as $key) - { - if (isset($strings[$key])) - { - unset($strings[$key]); - } - } - - // Write override.ini file with the strings. - if (JLanguageHelper::saveToIniFile($filename, $strings) === false) - { - return false; - } - - $this->cleanCache(); - - return count($cids); - } - - /** - * Removes all of the cached strings from the table. - * - * @return boolean result of operation - * - * @since 3.4.2 - */ - public function purge() - { - $db = JFactory::getDbo(); - - // Note: TRUNCATE is a DDL operation - // This may or may not mean depending on your database - try - { - $db->truncateTable('#__overrider'); - } - catch (RuntimeException $e) - { - return $e; - } - - JFactory::getApplication()->enqueueMessage(JText::_('COM_LANGUAGES_VIEW_OVERRIDES_PURGE_SUCCESS')); - } -} diff --git a/administrator/components/com_languages/models/strings.php b/administrator/components/com_languages/models/strings.php deleted file mode 100644 index a0e5751d5f408..0000000000000 --- a/administrator/components/com_languages/models/strings.php +++ /dev/null @@ -1,167 +0,0 @@ -setUserState('com_languages.overrides.cachedtime', null); - - // Empty the database cache first. - try - { - $this->_db->setQuery('TRUNCATE TABLE ' . $this->_db->quoteName('#__overrider')); - $this->_db->execute(); - } - catch (RuntimeException $e) - { - return $e; - } - - // Create the insert query. - $query = $this->_db->getQuery(true) - ->insert($this->_db->quoteName('#__overrider')) - ->columns('constant, string, file'); - - // Initialize some variables. - $client = $app->getUserState('com_languages.overrides.filter.client', 'site') ? 'administrator' : 'site'; - $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); - - $base = constant('JPATH_' . strtoupper($client)); - $path = $base . '/language/' . $language; - - $files = array(); - - // Parse common language directory. - jimport('joomla.filesystem.folder'); - - if (is_dir($path)) - { - $files = JFolder::files($path, $language . '.*ini$', false, true); - } - - // Parse language directories of components. - $files = array_merge($files, JFolder::files($base . '/components', $language . '.*ini$', 3, true)); - - // Parse language directories of modules. - $files = array_merge($files, JFolder::files($base . '/modules', $language . '.*ini$', 3, true)); - - // Parse language directories of templates. - $files = array_merge($files, JFolder::files($base . '/templates', $language . '.*ini$', 3, true)); - - // Parse language directories of plugins. - $files = array_merge($files, JFolder::files(JPATH_PLUGINS, $language . '.*ini$', 4, true)); - - // Parse all found ini files and add the strings to the database cache. - foreach ($files as $file) - { - $strings = LanguagesHelper::parseFile($file); - - if ($strings && count($strings)) - { - $query->clear('values'); - - foreach ($strings as $key => $string) - { - $query->values($this->_db->quote($key) . ',' . $this->_db->quote($string) . ',' . $this->_db->quote(JPath::clean($file))); - } - - try - { - $this->_db->setQuery($query); - $this->_db->execute(); - } - catch (RuntimeException $e) - { - return $e; - } - } - } - - // Update the cached time. - $app->setUserState('com_languages.overrides.cachedtime.' . $client . '.' . $language, time()); - - return true; - } - - /** - * Method for searching language strings. - * - * @return array Array of resuls on success, Exception object otherwise. - * - * @since 2.5 - */ - public function search() - { - $results = array(); - $input = JFactory::getApplication()->input; - $filter = JFilterInput::getInstance(); - $searchTerm = $input->getString('searchstring'); - - $limitstart = $input->getInt('more'); - - try - { - $searchstring = $this->_db->quote('%' . $filter->clean($searchTerm, 'TRIM') . '%'); - - // Create the search query. - $query = $this->_db->getQuery(true) - ->select('constant, string, file') - ->from($this->_db->quoteName('#__overrider')); - - if ($input->get('searchtype') == 'constant') - { - $query->where('constant LIKE ' . $searchstring); - } - else - { - $query->where('string LIKE ' . $searchstring); - } - - // Consider the limitstart according to the 'more' parameter and load the results. - $this->_db->setQuery($query, $limitstart, 10); - $results['results'] = $this->_db->loadObjectList(); - - // Check whether there are more results than already loaded. - $query->clear('select')->clear('limit') - ->select('COUNT(id)'); - $this->_db->setQuery($query); - - if ($this->_db->loadResult() > $limitstart + 10) - { - // If this is set a 'More Results' link will be displayed in the view. - $results['more'] = $limitstart + 10; - } - } - catch (RuntimeException $e) - { - return $e; - } - - return $results; - } -} diff --git a/administrator/components/com_languages/services/provider.php b/administrator/components/com_languages/services/provider.php new file mode 100644 index 0000000000000..f2c89da614c0b --- /dev/null +++ b/administrator/components/com_languages/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Languages')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Languages')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_languages/tmpl/installed/default.php b/administrator/components/com_languages/tmpl/installed/default.php new file mode 100644 index 0000000000000..79a5a547c52ed --- /dev/null +++ b/administrator/components/com_languages/tmpl/installed/default.php @@ -0,0 +1,135 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + rows)) : ?> + + + + + + + + + + + + + + + + + + + getShortVersion()); + foreach ($this->rows as $i => $row) : + $canCreate = $user->authorise('core.create', 'com_languages'); + $canEdit = $user->authorise('core.edit', 'com_languages'); + $canChange = $user->authorise('core.edit.state', 'com_languages'); + ?> + + + + + + + + + + + + + + +
+   + + + + + + + + + + + + + + + + + + +
+ language); ?> + + + + escape($row->nativeName); ?> + + escape($row->language); ?> + + published, $i, 'installed.', !$row->published && $canChange); ?> + + + + version, 0, 3) != $minorVersion || substr($row->version, 0, 5) != $currentShortVersion) : ?> + version; ?> + + version; ?> + + + escape($row->creationDate); ?> + + escape($row->author); ?> + + escape($row->authorEmail)); ?> + + escape($row->extension_id); ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_languages/views/installed/tmpl/default.xml b/administrator/components/com_languages/tmpl/installed/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_languages/views/installed/tmpl/default.xml rename to administrator/components/com_languages/tmpl/installed/default.xml diff --git a/administrator/components/com_languages/tmpl/language/edit.php b/administrator/components/com_languages/tmpl/language/edit.php new file mode 100644 index 0000000000000..b84a8a7700a60 --- /dev/null +++ b/administrator/components/com_languages/tmpl/language/edit.php @@ -0,0 +1,69 @@ + true, 'version' => 'auto']); +?> + +
+ + + +
+ 'details')); ?> + + + form->renderField('title'); ?> + form->renderField('title_native'); ?> + form->renderField('lang_code'); ?> + form->renderField('sef'); ?> +
+
+ form->getLabel('image'); ?> +
+
+ form->getInput('image'); ?> + + form->getValue('image') . '.gif', $this->form->getValue('image'), null, true); ?> + +
+
+ canDo->get('core.edit.state')) : ?> + form->renderField('published'); ?> + + + form->renderField('access'); ?> + form->renderField('description'); ?> + form->renderField('lang_id'); ?> + + + + form->renderFieldset('metadata'); ?> + + + + form->renderFieldset('site_name'); ?> + + + +
+ + +
diff --git a/administrator/components/com_languages/tmpl/languages/default.php b/administrator/components/com_languages/tmpl/languages/default.php new file mode 100644 index 0000000000000..1255dd5b8a470 --- /dev/null +++ b/administrator/components/com_languages/tmpl/languages/default.php @@ -0,0 +1,166 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_languages&task=languages.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('sortablelist.sortable', 'contentList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); +} +?> +
+
+
+ sidebar; ?> +
+
+
+ $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_languages'); + $canEdit = $user->authorise('core.edit', 'com_languages'); + $canChange = $user->authorise('core.edit.state', 'com_languages'); + ?> + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + lang_id); ?> + + published, $i, 'languages.', $canChange); ?> + + + + + escape($item->title); ?> + + escape($item->title); ?> + + + + escape($item->title_native); ?> + + escape($item->lang_code); ?> + + escape($item->sef); ?> + + image) : ?> + image . '.gif', $item->image, null, true); ?> escape($item->image); ?> + + + + + escape($item->access_level); ?> + + home == '1') ? Text::_('JYES') : Text::_('JNO'); ?> + + escape($item->lang_id); ?> +
+ + + pagination->getListFooter(); ?> + + + + + +
+
+
+
diff --git a/administrator/components/com_languages/views/languages/tmpl/default.xml b/administrator/components/com_languages/tmpl/languages/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_languages/views/languages/tmpl/default.xml rename to administrator/components/com_languages/tmpl/languages/default.xml diff --git a/administrator/components/com_languages/tmpl/multilangstatus/default.php b/administrator/components/com_languages/tmpl/multilangstatus/default.php new file mode 100644 index 0000000000000..f5027247549c4 --- /dev/null +++ b/administrator/components/com_languages/tmpl/multilangstatus/default.php @@ -0,0 +1,270 @@ +homes == 2 || $this->homes == 1 || $this->homes - 1 != count($this->contentlangs) && ($this->language_filter || $this->switchers != 0); +$notice_disabled = !$this->language_filter && ($this->homes > 1 || $this->switchers != 0); +$notice_switchers = !$this->switchers && ($this->homes > 1 || $this->language_filter); +?> +
+ language_filter && $this->switchers == 0) : ?> + homes == 1) : ?> + + + + + + + + defaultHome == true) : ?> + + + + + + + + + + + + + + + + + + + + + + + + contentlangs as $contentlang) : ?> + lang_code, $this->homepages) && (!array_key_exists($contentlang->lang_code, $this->site_langs) || !$contentlang->published)) : ?> + + + + + + lang_code, $this->site_langs)) : ?> + + + + + + + listUsersError) : ?> + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + lang_code); ?> +
+ + + + lang_code); ?> +
+ + + + +
    + listUsersError as $user) : ?> +
  • + name); ?> +
  • + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + language_filter) : ?> + + + + +
+ + + switchers != 0) : ?> + switchers; ?> + + + +
+ homes > 1) : ?> + + + + + + homes > 1) : ?> + homes; ?> + + + +
+ + + + + + + + + + + statuses as $status) : ?> + element) : ?> + + + + + element) : ?> + + + + + + lang_code && $status->published) : ?> + + + + + + home_language) : ?> + + + + + + + contentlangs as $contentlang) : ?> + lang_code, $this->site_langs)) : ?> + + + + + + + + + +
+ + + + + + + +
+ element; ?> + + + + + + + + + + + + + + + + + +
+ lang_code; ?> + + + + + published) : ?> + + + published && array_key_exists($contentlang->lang_code, $this->homepages)) : ?> + + + published) : ?> + + + + + lang_code, $this->homepages)) : ?> + + + + + + +
+ +
diff --git a/administrator/components/com_languages/tmpl/override/edit.php b/administrator/components/com_languages/tmpl/override/edit.php new file mode 100644 index 0000000000000..2ec1bdbf44499 --- /dev/null +++ b/administrator/components/com_languages/tmpl/override/edit.php @@ -0,0 +1,143 @@ +state->get('cache_expired') == 1 ) ? '1' : ''; + +HTMLHelper::_('stylesheet', 'com_languages/overrider.css', array('version' => 'auto', 'relative' => true)); + +HTMLHelper::_('behavior.core'); +HTMLHelper::_('jquery.framework'); +HTMLHelper::_('script', 'com_languages/overrider.min.js', array('version' => 'auto', 'relative' => true)); +HTMLHelper::_('script', 'com_languages/admin-override-edit-refresh-searchstring.js', ['relative' => true, 'version' => 'auto']); +?> + +
+
+
+
+ item->key) ? Text::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_NEW_OVERRIDE_LEGEND') : Text::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_EDIT_OVERRIDE_LEGEND'); ?> +
+
+ form->getLabel('language'); ?> +
+
+ form->getInput('language'); ?> +
+
+ +
+
+ form->getLabel('client'); ?> +
+
+ form->getInput('client'); ?> +
+
+ +
+
+ form->getLabel('key'); ?> +
+
+ form->getInput('key'); ?> +
+
+ +
+
+ form->getLabel('override'); ?> +
+
+ form->getInput('override'); ?> +
+
+ + state->get('filter.client') == 'administrator') : ?> +
+
+ form->getLabel('both'); ?> +
+
+ form->getInput('both'); ?> +
+
+ + +
+
+ form->getLabel('file'); ?> +
+
+ form->getInput('file'); ?> +
+
+
+ +
+ +
+
+ + + + +
+
+ form->getInput('searchstring'); ?> + + + +
+ + + + +
+
+
+ form->getLabel('searchtype'); ?> +
+
+ form->getInput('searchtype'); ?> +
+
+ +
+ +
+ +
+ + + + + +
+ + + + + +
+
+
diff --git a/administrator/components/com_languages/tmpl/overrides/default.php b/administrator/components/com_languages/tmpl/overrides/default.php new file mode 100644 index 0000000000000..827cadd8290ae --- /dev/null +++ b/administrator/components/com_languages/tmpl/overrides/default.php @@ -0,0 +1,125 @@ +state->get('filter.client') == '0' ? Text::_('JSITE') : Text::_('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' ? Text::_('JSITE') : Text::_('JADMINISTRATOR'); +$opposite_filename = constant('JPATH_' . strtoupper(1 - $this->state->get('filter.client')? 'administrator' : 'site')) + . '/language/overrides/' . $this->state->get('filter.language', 'en-GB') . '.override.ini'; +$opposite_strings = LanguagesHelper::parseFile($opposite_filename); +?> + +
+
+
+ sidebar; ?> +
+
+
+
+ +
+ + pagination->getLimitBox(); ?> +
+
+ items)) : ?> + + + + + + + + + + + + + + authorise('core.edit', 'com_languages'); ?> + + items as $key => $text) : ?> + + + + + + + + + + +
+ + + + + + + + + +
+ + + + + escape($key); ?> + + escape($key); ?> + + + escape($text); ?> + + + + + +
+ + + pagination->getListFooter(); ?> + + + + + + + + +
+
+
+
diff --git a/administrator/components/com_languages/views/overrides/tmpl/default.xml b/administrator/components/com_languages/tmpl/overrides/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_languages/views/overrides/tmpl/default.xml rename to administrator/components/com_languages/tmpl/overrides/default.xml diff --git a/administrator/components/com_languages/views/installed/tmpl/default.php b/administrator/components/com_languages/views/installed/tmpl/default.php deleted file mode 100644 index dcbad173ea007..0000000000000 --- a/administrator/components/com_languages/views/installed/tmpl/default.php +++ /dev/null @@ -1,132 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
-sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> - total > 0) : ?> - - - - - - - - - - - - - - - - - - - - - - getShortVersion()); - foreach ($this->rows as $i => $row) : - $canCreate = $user->authorise('core.create', 'com_languages'); - $canEdit = $user->authorise('core.edit', 'com_languages'); - $canChange = $user->authorise('core.edit.state', 'com_languages'); - ?> - - - - - - - - - - - - - - -
-   - - - - - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- language); ?> - - - - escape($row->nativeName); ?> - - escape($row->language); ?> - - published, $i, 'installed.', !$row->published && $canChange); ?> - - - - version, 0, 3) != $minorVersion || substr($row->version, 0, 5) != $currentShortVersion) : ?> - version; ?> - - version; ?> - - - escape($row->creationDate); ?> - - escape($row->author); ?> - - escape($row->authorEmail)); ?> - - escape($row->extension_id); ?> -
- - - - -
- diff --git a/administrator/components/com_languages/views/installed/view.html.php b/administrator/components/com_languages/views/installed/view.html.php deleted file mode 100644 index 9f5fcae7db305..0000000000000 --- a/administrator/components/com_languages/views/installed/view.html.php +++ /dev/null @@ -1,130 +0,0 @@ -ftp = $this->get('Ftp'); - $this->option = $this->get('Option'); - $this->pagination = $this->get('Pagination'); - $this->rows = $this->get('Data'); - $this->total = $this->get('Total'); - $this->state = $this->get('State'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - LanguagesHelper::addSubmenu('installed'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->addToolbar(); - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_languages'); - - if ((int) $this->state->get('client_id') === 1) - { - JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_INSTALLED_ADMIN_TITLE'), 'comments-2 langmanager'); - } - else - { - JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_INSTALLED_SITE_TITLE'), 'comments-2 langmanager'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::makeDefault('installed.setDefault'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin')) - { - // Add install languages link to the lang installer component. - $bar = JToolbar::getInstance('toolbar'); - - // Switch administrator language - if ($this->state->get('client_id', 0) == 1) - { - JToolbarHelper::custom('installed.switchadminlanguage', 'refresh', 'refresh', 'COM_LANGUAGES_SWITCH_ADMIN', false); - JToolbarHelper::divider(); - } - - $bar->appendButton('Link', 'upload', 'COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages'); - JToolbarHelper::divider(); - - JToolbarHelper::preferences('com_languages'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_INSTALLED'); - - $this->sidebar = JHtmlSidebar::render(); - } -} diff --git a/administrator/components/com_languages/views/language/tmpl/edit.php b/administrator/components/com_languages/views/language/tmpl/edit.php deleted file mode 100644 index 17889ecef501e..0000000000000 --- a/administrator/components/com_languages/views/language/tmpl/edit.php +++ /dev/null @@ -1,86 +0,0 @@ -addScriptDeclaration( - ' - Joomla.submitbutton = function(task) - { - if (task == "language.cancel" || document.formvalidator.isValid(document.getElementById("language-form"))) - { - Joomla.submitform(task, document.getElementById("language-form")); - } - }; - - jQuery(document).ready(function() { - jQuery("#jform_image").on("change", function() { - var flag = this.value; - if (flag) { - jQuery("#flag img").attr("src", "' . JUri::root(true) . '" + "/media/mod_languages/images/" + flag + ".gif").attr("alt", flag); - } - else - { - jQuery("#flag img").removeAttr("src").removeAttr("alt"); - } - }); -});' -); -?> - -
- - - -
- 'details')); ?> - - - form->renderField('title'); ?> - form->renderField('title_native'); ?> - form->renderField('lang_code'); ?> - form->renderField('sef'); ?> -
-
- form->getLabel('image'); ?> -
-
- form->getInput('image'); ?> - - form->getValue('image') . '.gif', $this->form->getValue('image'), null, true); ?> - -
-
- canDo->get('core.edit.state')) : ?> - form->renderField('published'); ?> - - - form->renderField('access'); ?> - form->renderField('description'); ?> - form->renderField('lang_id'); ?> - - - - form->renderFieldset('metadata'); ?> - - - - form->renderFieldset('site_name'); ?> - - - -
- - -
diff --git a/administrator/components/com_languages/views/language/view.html.php b/administrator/components/com_languages/views/language/view.html.php deleted file mode 100644 index 1c0d0a96e9107..0000000000000 --- a/administrator/components/com_languages/views/language/view.html.php +++ /dev/null @@ -1,92 +0,0 @@ -item = $this->get('Item'); - $this->form = $this->get('Form'); - $this->state = $this->get('State'); - $this->canDo = JHelperContent::getActions('com_languages'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->addToolbar(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JLoader::register('LanguagesHelper', JPATH_ADMINISTRATOR . '/components/com_languages/helpers/languages.php'); - - JFactory::getApplication()->input->set('hidemainmenu', 1); - $isNew = empty($this->item->lang_id); - $canDo = $this->canDo; - - JToolbarHelper::title( - JText::_($isNew ? 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_NEW_TITLE' : 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_EDIT_TITLE'), 'comments-2 langmanager' - ); - - if (($isNew && $canDo->get('core.create')) || (!$isNew && $canDo->get('core.edit'))) - { - JToolbarHelper::apply('language.apply'); - JToolbarHelper::save('language.save'); - } - - // If an existing item, can save to a copy only if we have create rights. - if ($canDo->get('core.create')) - { - JToolbarHelper::save2new('language.save2new'); - } - - if ($isNew) - { - JToolbarHelper::cancel('language.cancel'); - } - else - { - JToolbarHelper::cancel('language.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_EDIT'); - } -} diff --git a/administrator/components/com_languages/views/languages/tmpl/default.php b/administrator/components/com_languages/views/languages/tmpl/default.php deleted file mode 100644 index bcdd7506580c6..0000000000000 --- a/administrator/components/com_languages/views/languages/tmpl/default.php +++ /dev/null @@ -1,166 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$saveOrder = $listOrder == 'a.ordering'; - -if ($saveOrder) -{ - $saveOrderingUrl = 'index.php?option=com_languages&task=languages.saveOrderAjax&tmpl=component'; - JHtml::_('sortablelist.sortable', 'contentList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); -} -?> -
-sidebar)) : ?> -
- sidebar; ?> -
-
- -
- - $this)); ?> -
- items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - - - - - - - items as $i => $item) : - $canCreate = $user->authorise('core.create', 'com_languages'); - $canEdit = $user->authorise('core.edit', 'com_languages'); - $canChange = $user->authorise('core.edit.state', 'com_languages'); - ?> - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - - - - - - - - - - lang_id); ?> - - published, $i, 'languages.', $canChange); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - - - escape($item->title_native); ?> - - escape($item->lang_code); ?> - - escape($item->sef); ?> - - image) : ?> - image . '.gif', $item->image, null, true); ?> escape($item->image); ?> - - - - - escape($item->access_level); ?> - - home == '1') ? JText::_('JYES') : JText::_('JNO'); ?> - - escape($item->lang_id); ?> -
- - - - -
- diff --git a/administrator/components/com_languages/views/languages/view.html.php b/administrator/components/com_languages/views/languages/view.html.php deleted file mode 100644 index ba09b0e8eaa4f..0000000000000 --- a/administrator/components/com_languages/views/languages/view.html.php +++ /dev/null @@ -1,136 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - LanguagesHelper::addSubmenu('languages'); - - // 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 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_languages'); - - JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_LANGUAGES_TITLE'), 'comments-2 langmanager'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('language.add'); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('language.edit'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.edit.state')) - { - if ($this->state->get('filter.published') != 2) - { - JToolbarHelper::publishList('languages.publish'); - JToolbarHelper::unpublishList('languages.unpublish'); - } - } - - if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'languages.delete', 'JTOOLBAR_EMPTY_TRASH'); - JToolbarHelper::divider(); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('languages.trash'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin')) - { - // Add install languages link to the lang installer component. - $bar = JToolbar::getInstance('toolbar'); - $bar->appendButton('Link', 'upload', 'COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages'); - JToolbarHelper::divider(); - - JToolbarHelper::preferences('com_languages'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_CONTENT'); - - JHtmlSidebar::setAction('index.php?option=com_languages&view=languages'); - - } - - /** - * Returns an array of fields the table can be sorted by. - * - * @return array Array containing the field name to sort by as the key and display text as value. - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), - 'a.published' => JText::_('JSTATUS'), - 'a.title' => JText::_('JGLOBAL_TITLE'), - 'a.title_native' => JText::_('COM_LANGUAGES_HEADING_TITLE_NATIVE'), - 'a.lang_code' => JText::_('COM_LANGUAGES_FIELD_LANG_TAG_LABEL'), - 'a.sef' => JText::_('COM_LANGUAGES_FIELD_LANG_CODE_LABEL'), - 'a.image' => JText::_('COM_LANGUAGES_HEADING_LANG_IMAGE'), - 'a.access' => JText::_('JGRID_HEADING_ACCESS'), - 'a.lang_id' => JText::_('JGRID_HEADING_ID'), - ); - } -} diff --git a/administrator/components/com_languages/views/multilangstatus/tmpl/default.php b/administrator/components/com_languages/views/multilangstatus/tmpl/default.php deleted file mode 100644 index f88f5d59a0483..0000000000000 --- a/administrator/components/com_languages/views/multilangstatus/tmpl/default.php +++ /dev/null @@ -1,251 +0,0 @@ -homes == 2 || $this->homes == 1 || $this->homes - 1 != count($this->contentlangs) && ($this->language_filter || $this->switchers != 0); -$notice_disabled = !$this->language_filter && ($this->homes > 1 || $this->switchers != 0); -$notice_switchers = !$this->switchers && ($this->homes > 1 || $this->language_filter); -?> -
- language_filter && $this->switchers == 0) : ?> - homes == 1) : ?> -
- -
- - - - - defaultHome == true) : ?> - - - - - - - - - - - - - - - - - - - - - - - - contentlangs as $contentlang) : ?> - lang_code, $this->homepages) && (!array_key_exists($contentlang->lang_code, $this->site_langs) || !$contentlang->published)) : ?> - - - - - - lang_code, $this->site_langs)) : ?> - - - - - - - listUsersError) : ?> - - - - - - -
- - - -
- - - -
- - - -
- - - -
- - - lang_code); ?> -
- - - lang_code); ?> -
- - - -
    - listUsersError as $user) : ?> -
  • - name); ?> -
  • - -
-
- - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - language_filter) : ?> - - - - -
- - - switchers != 0) : ?> - switchers; ?> - - - -
- homes > 1) : ?> - - - - - - homes > 1) : ?> - homes; ?> - - - -
- - - - - - - - - - - statuses as $status) : ?> - element) : ?> - - - - - element) : ?> - - - - - - lang_code && $status->published) : ?> - - - - - - home_language) : ?> - - - - - - - - contentlangs as $contentlang) : ?> - lang_code, $this->site_langs)) : ?> - - - - - - - - - -
- - - - - - - -
- element; ?> - - - - - - - - - - - - -
- lang_code; ?> - - - - published) : ?> - - published && array_key_exists($contentlang->lang_code, $this->homepages)) : ?> - - published) : ?> - - - - lang_code, $this->homepages)) : ?> - - - - -
- -
diff --git a/administrator/components/com_languages/views/multilangstatus/view.html.php b/administrator/components/com_languages/views/multilangstatus/view.html.php deleted file mode 100644 index 4f8612fe97069..0000000000000 --- a/administrator/components/com_languages/views/multilangstatus/view.html.php +++ /dev/null @@ -1,42 +0,0 @@ -homes = MultilangstatusHelper::getHomes(); - $this->language_filter = JLanguageMultilang::isEnabled(); - $this->switchers = MultilangstatusHelper::getLangswitchers(); - $this->listUsersError = MultilangstatusHelper::getContacts(); - $this->contentlangs = MultilangstatusHelper::getContentlangs(); - $this->site_langs = JLanguageHelper::getInstalledLanguages(0); - $this->statuses = MultilangstatusHelper::getStatus(); - $this->homepages = JLanguageMultilang::getSiteHomePages(); - $this->defaultHome = MultilangstatusHelper::getDefaultHomeModule(); - - parent::display($tpl); - } -} diff --git a/administrator/components/com_languages/views/override/tmpl/edit.php b/administrator/components/com_languages/views/override/tmpl/edit.php deleted file mode 100644 index 1718789fa4d2a..0000000000000 --- a/administrator/components/com_languages/views/override/tmpl/edit.php +++ /dev/null @@ -1,155 +0,0 @@ -state->get('cache_expired') == 1 ) ? '1' : ''; - -JHtml::_('stylesheet', 'overrider/overrider.css', array('version' => 'auto', 'relative' => true)); - -JHtml::_('behavior.core'); -JHtml::_('jquery.framework'); -JHtml::_('script', 'overrider/overrider.min.js', array('version' => 'auto', 'relative' => true)); - -JFactory::getDocument()->addScriptDeclaration(' - jQuery(document).ready(function($) { - $("#jform_searchstring").on("focus", function() { - if (!Joomla.overrider.states.refreshed) - { - var expired = "' . $expired . '"; - if (expired) - { - Joomla.overrider.refreshCache(); - Joomla.overrider.states.refreshed = true; - } - } - $(this).removeClass("invalid"); - }); - }); - - Joomla.submitbutton = function(task) { - if (task == "override.cancel" || document.formvalidator.isValid(document.getElementById("override-form"))) - { - Joomla.submitform(task, document.getElementById("override-form")); - } - }; -'); -?> - -
-
-
-
- item->key) ? JText::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_NEW_OVERRIDE_LEGEND') : JText::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_EDIT_OVERRIDE_LEGEND'); ?> -
-
- form->getLabel('language'); ?> -
-
- form->getInput('language'); ?> -
-
- -
-
- form->getLabel('client'); ?> -
-
- form->getInput('client'); ?> -
-
- -
-
- form->getLabel('key'); ?> -
-
- form->getInput('key'); ?> -
-
- -
-
- form->getLabel('override'); ?> -
-
- form->getInput('override'); ?> -
-
- - state->get('filter.client') == 'administrator') : ?> -
-
- form->getLabel('both'); ?> -
-
- form->getInput('both'); ?> -
-
- - -
-
- form->getLabel('file'); ?> -
-
- form->getInput('file'); ?> -
-
-
- -
- -
-
- - -

- -
- form->getInput('searchstring'); ?> - - - - -
-
-
- form->getLabel('searchtype'); ?> -
-
- form->getInput('searchtype'); ?> -
-
- -
- -
- - - - - -
- - - - - -
-
-
diff --git a/administrator/components/com_languages/views/override/view.html.php b/administrator/components/com_languages/views/override/view.html.php deleted file mode 100644 index 30d74e9963ad9..0000000000000 --- a/administrator/components/com_languages/views/override/view.html.php +++ /dev/null @@ -1,122 +0,0 @@ -form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors)); - } - - // Check whether the cache has to be refreshed. - $cached_time = JFactory::getApplication()->getUserState( - 'com_languages.overrides.cachedtime.' . $this->state->get('filter.client') . '.' . $this->state->get('filter.language'), - 0 - ); - - if (time() - $cached_time > 60 * 5) - { - $this->state->set('cache_expired', true); - } - - // Add strings for translations in Javascript. - JText::script('COM_LANGUAGES_VIEW_OVERRIDE_NO_RESULTS'); - JText::script('COM_LANGUAGES_VIEW_OVERRIDE_REQUEST_ERROR'); - - $this->addToolbar(); - parent::display($tpl); - } - - /** - * Adds the page title and toolbar. - * - * @return void - * - * @since 2.5 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - - $canDo = JHelperContent::getActions('com_languages'); - - JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_TITLE'), 'comments-2 langmanager'); - - if ($canDo->get('core.edit')) - { - JToolbarHelper::apply('override.apply'); - JToolbarHelper::save('override.save'); - } - - // This component does not support Save as Copy. - if ($canDo->get('core.edit') && $canDo->get('core.create')) - { - JToolbarHelper::save2new('override.save2new'); - } - - if (empty($this->item->key)) - { - JToolbarHelper::cancel('override.cancel'); - } - else - { - JToolbarHelper::cancel('override.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT'); - } -} diff --git a/administrator/components/com_languages/views/overrides/tmpl/default.php b/administrator/components/com_languages/views/overrides/tmpl/default.php deleted file mode 100644 index 779689363d7a3..0000000000000 --- a/administrator/components/com_languages/views/overrides/tmpl/default.php +++ /dev/null @@ -1,123 +0,0 @@ -state->get('filter.client') == '0' ? 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')) - . '/language/overrides/' . $this->state->get('filter.language', 'en-GB') . '.override.ini'; -$opposite_strings = LanguagesHelper::parseFile($opposite_filename); -?> - -
-sidebar)) : ?> -
- sidebar; ?> -
-
- -
- -
- -
- - -
-
- - pagination->getLimitBox(); ?> -
-
- items)) : ?> -
- -
- - - - - - - - - - - - - - - - - - authorise('core.edit', 'com_languages'); ?> - - items as $key => $text) : ?> - - - - - - - - - - -
- - - - - - - - - -
- pagination->getListFooter(); ?> -
- - - - escape($key); ?> - - escape($key); ?> - - - escape($text); ?> - - - - -
- - - - - - - -
- diff --git a/administrator/components/com_languages/views/overrides/view.html.php b/administrator/components/com_languages/views/overrides/view.html.php deleted file mode 100644 index ef88e5e918f6c..0000000000000 --- a/administrator/components/com_languages/views/overrides/view.html.php +++ /dev/null @@ -1,124 +0,0 @@ -state = $this->get('State'); - $this->items = $this->get('Overrides'); - $this->languages = $this->get('Languages'); - $this->pagination = $this->get('Pagination'); - - LanguagesHelper::addSubmenu('overrides'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors)); - } - - $this->addToolbar(); - parent::display($tpl); - } - - /** - * Adds the page title and toolbar. - * - * @return void - * - * @since 2.5 - */ - protected function addToolbar() - { - // Get the results for each action - $canDo = JHelperContent::getActions('com_languages'); - - JToolbarHelper::title(JText::_('COM_LANGUAGES_VIEW_OVERRIDES_TITLE'), 'comments-2 langmanager'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('override.add'); - } - - if ($canDo->get('core.edit') && $this->pagination->total) - { - JToolbarHelper::editList('override.edit'); - } - - if ($canDo->get('core.delete') && $this->pagination->total) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'overrides.delete', 'JTOOLBAR_DELETE'); - } - - if (JFactory::getUser()->authorise('core.admin')) - { - JToolbarHelper::custom('overrides.purge', 'refresh.png', 'refresh_f2.png', 'COM_LANGUAGES_VIEW_OVERRIDES_PURGE', false); - } - - if ($canDo->get('core.admin')) - { - JToolbarHelper::preferences('com_languages'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES'); - - 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/DisplayController.php b/administrator/components/com_login/Controller/DisplayController.php new file mode 100644 index 0000000000000..1bf7ae0fba93d --- /dev/null +++ b/administrator/components/com_login/Controller/DisplayController.php @@ -0,0 +1,144 @@ +input->set('view', 'login'); + $this->input->set('layout', 'default'); + + // For non-html formats we do not have login view, so just display 403 instead + if ($this->input->get('format', 'html') !== 'html') + { + throw new \RuntimeException(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + /** + * 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 + */ + $this->app->setHeader('X-Frame-Options', 'SAMEORIGIN'); + + parent::display(); + } + + /** + * Method to log in a user. + * + * @return void + */ + public function login() + { + // Check for request forgeries. + Session::checkToken('request') or jexit(Text::_('JINVALID_TOKEN')); + + $app = $this->app; + + $model = $this->getModel('login'); + $credentials = $model->getState('credentials'); + $return = $model->getState('return'); + + $result = $app->login($credentials, array('action' => 'core.login.admin')); + + if ($result && !($result instanceof \Exception)) + { + // Only redirect to an internal URL. + if (Uri::isInternal($return)) + { + // If &tmpl=component - redirect to index.php + if (strpos($return, 'tmpl=component') === false) + { + $app->redirect($return); + } + else + { + $app->redirect('index.php'); + } + } + } + + $this->display(); + } + + /** + * Method to log out a user. + * + * @return void + */ + public function logout() + { + Session::checkToken('request') or jexit(Text::_('JINVALID_TOKEN')); + + $app = $this->app; + + $userid = $this->input->getInt('uid', null); + + if ($app->get('shared_session', '0')) + { + $clientid = null; + } + else + { + $clientid = $userid ? 0 : 1; + } + + $options = array( + 'clientid' => $clientid, + ); + + $result = $app->logout($userid, $options); + + if (!($result instanceof \Exception)) + { + $model = $this->getModel('login'); + $return = $model->getState('return'); + + // Only redirect to an internal URL. + if (Uri::isInternal($return)) + { + $app->redirect($return); + } + } + + parent::display(); + } +} diff --git a/administrator/components/com_login/Dispatcher/Dispatcher.php b/administrator/components/com_login/Dispatcher/Dispatcher.php new file mode 100644 index 0000000000000..cf260ed8ae3f5 --- /dev/null +++ b/administrator/components/com_login/Dispatcher/Dispatcher.php @@ -0,0 +1,51 @@ +input->get('task'); + + if ($task != 'login' && $task != 'logout') + { + $this->input->set('task', ''); + } + + parent::dispatch(); + } + + /** + * com_login does not require check permission, so we override checkAccess method and have it empty + * + * @return void + */ + protected function checkAccess() + { + } +} diff --git a/administrator/components/com_login/Model/LoginModel.php b/administrator/components/com_login/Model/LoginModel.php new file mode 100644 index 0000000000000..9f05c03b98f90 --- /dev/null +++ b/administrator/components/com_login/Model/LoginModel.php @@ -0,0 +1,194 @@ +input; + $method = $input->getMethod(); + + $credentials = array( + 'username' => $input->$method->get('username', '', 'USERNAME'), + 'password' => $input->$method->get('passwd', '', 'RAW'), + 'secretkey' => $input->$method->get('secretkey', '', 'RAW'), + ); + $this->setState('credentials', $credentials); + + // Check for return URL from the request first. + if ($return = $input->$method->get('return', '', 'BASE64')) + { + $return = base64_decode($return); + + if (!Uri::isInternal($return)) + { + $return = ''; + } + } + + // Set the return URL if empty. + if (empty($return)) + { + $return = 'index.php'; + } + + $this->setState('return', $return); + } + + /** + * Get the administrator login module by name (real, eg 'login' or folder, eg 'mod_login'). + * + * @param string $name The name of the module. + * @param string $title The title of the module, optional. + * + * @return object The Module object. + * + * @since 11.1 + */ + public static function getLoginModule($name = 'mod_login', $title = null) + { + $result = null; + $modules = self::_load($name); + $total = count($modules); + + for ($i = 0; $i < $total; $i++) + { + // Match the title if we're looking for a specific instance of the module. + if (!$title || $modules[$i]->title == $title) + { + $result = $modules[$i]; + break; + } + } + + // If we didn't find it, and the name is mod_something, create a dummy object. + if (is_null($result) && substr($name, 0, 4) == 'mod_') + { + $result = new \stdClass; + $result->id = 0; + $result->title = ''; + $result->module = $name; + $result->position = ''; + $result->content = ''; + $result->showtitle = 0; + $result->control = ''; + $result->params = ''; + $result->user = 0; + } + + return $result; + } + + /** + * Load login modules. + * + * Note that we load regardless of state or access level since access + * for public is the only thing that makes sense since users are not logged in + * and the module lets them log in. + * This is put in as a failsafe to avoid super user lock out caused by an unpublished + * login module or by a module set to have a viewing access level that is not Public. + * + * @param string $module The name of the module. + * + * @return array + * + * @since 11.1 + */ + protected static function _load($module) + { + static $clean; + + if (isset($clean)) + { + return $clean; + } + + $app = Factory::getApplication(); + $lang = Factory::getLanguage()->getTag(); + $clientId = (int) $app->getClientId(); + + /** @var CallbackController $cache */ + $cache = Factory::getCache('com_modules', 'callback'); + + $loader = function () use ($app, $lang, $module) { + $db = Factory::getDbo(); + + $query = $db->getQuery(true) + ->select('m.id, m.title, m.module, m.position, m.showtitle, m.params') + ->from('#__modules AS m') + ->where('m.module =' . $db->quote($module) . ' AND m.client_id = 1') + ->join('LEFT', '#__extensions AS e ON e.element = m.module AND e.client_id = m.client_id') + ->where('e.enabled = 1'); + + // Filter by language. + if ($app->isClient('site') && $app->getLanguageFilter()) + { + $query->where('m.language IN (' . $db->quote($lang) . ',' . $db->quote('*') . ')'); + } + + $query->order('m.position, m.ordering'); + + // Set the query. + $db->setQuery($query); + + return $db->loadObjectList(); + }; + + try + { + return $clean = $cache->get($loader, array(), md5(serialize(array($clientId, $lang)))); + } + catch (CacheExceptionInterface $cacheException) + { + try + { + return $loader(); + } + catch (ExecutionFailureException $databaseException) + { + Factory::getApplication()->enqueueMessage(Text::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $databaseException->getMessage()), 'error'); + + return array(); + } + } + catch (ExecutionFailureException $databaseException) + { + Factory::getApplication()->enqueueMessage(Text::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $databaseException->getMessage()), 'error'); + + return array(); + } + } +} diff --git a/administrator/components/com_login/View/Login/HtmlView.php b/administrator/components/com_login/View/Login/HtmlView.php new file mode 100644 index 0000000000000..3ccb64f63d049 --- /dev/null +++ b/administrator/components/com_login/View/Login/HtmlView.php @@ -0,0 +1,24 @@ +input->set('view', 'login'); - $this->input->set('layout', 'default'); - - // For non-html formats we do not have login view, so just display 403 instead - if ($this->input->get('format', 'html') !== 'html') - { - throw new RuntimeException(JText::_('JERROR_ALERTNOAUTHOR'), 403); - } - - parent::display(); - } - - /** - * Method to log in a user. - * - * @return void - */ - public function login() - { - // Check for request forgeries. - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - - $model = $this->getModel('login'); - $credentials = $model->getState('credentials'); - $return = $model->getState('return'); - - $result = $app->login($credentials, array('action' => 'core.login.admin')); - - if ($result && !($result instanceof Exception)) - { - // Only redirect to an internal URL. - if (JUri::isInternal($return)) - { - // If &tmpl=component - redirect to index.php - if (strpos($return, 'tmpl=component') === false) - { - $app->redirect($return); - } - else - { - $app->redirect('index.php'); - } - } - } - - $this->display(); - } - - /** - * Method to log out a user. - * - * @return void - */ - public function logout() - { - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - - $userid = $this->input->getInt('uid', null); - - if ($app->get('shared_session', '0')) - { - $clientid = null; - } - else - { - $clientid = $userid ? 0 : 1; - } - - $options = array( - 'clientid' => $clientid, - ); - - $result = $app->logout($userid, $options); - - if (!($result instanceof Exception)) - { - $model = $this->getModel('login'); - $return = $model->getState('return'); - - // Only redirect to an internal URL. - if (JUri::isInternal($return)) - { - $app->redirect($return); - } - } - - parent::display(); - } -} diff --git a/administrator/components/com_login/login.php b/administrator/components/com_login/login.php deleted file mode 100644 index c270b8cfafcba..0000000000000 --- a/administrator/components/com_login/login.php +++ /dev/null @@ -1,23 +0,0 @@ -input; -$task = $input->get('task'); - -if ($task != 'login' && $task != 'logout') -{ - $input->set('task', ''); - $task = ''; -} - -$controller = JControllerLegacy::getInstance('Login'); -$controller->execute($task); -$controller->redirect(); diff --git a/administrator/components/com_login/login.xml b/administrator/components/com_login/login.xml index 82bebcabe5647..817faf50fcad2 100644 --- a/administrator/components/com_login/login.xml +++ b/administrator/components/com_login/login.xml @@ -9,12 +9,14 @@ www.joomla.org 3.0.0 COM_LOGIN_XML_DESCRIPTION + Joomla\Component\Login - controller.php - login.php + dispatcher.php + Controller + Model + View views - models language/en-GB.com_login.ini diff --git a/administrator/components/com_login/models/login.php b/administrator/components/com_login/models/login.php deleted file mode 100644 index 32bff5ba9839b..0000000000000 --- a/administrator/components/com_login/models/login.php +++ /dev/null @@ -1,185 +0,0 @@ -input; - $method = $input->getMethod(); - - $credentials = array( - 'username' => $input->$method->get('username', '', 'USERNAME'), - 'password' => $input->$method->get('passwd', '', 'RAW'), - 'secretkey' => $input->$method->get('secretkey', '', 'RAW'), - ); - $this->setState('credentials', $credentials); - - // Check for return URL from the request first. - if ($return = $input->$method->get('return', '', 'BASE64')) - { - $return = base64_decode($return); - - if (!JUri::isInternal($return)) - { - $return = ''; - } - } - - // Set the return URL if empty. - if (empty($return)) - { - $return = 'index.php'; - } - - $this->setState('return', $return); - } - - /** - * Get the administrator login module by name (real, eg 'login' or folder, eg 'mod_login'). - * - * @param string $name The name of the module. - * @param string $title The title of the module, optional. - * - * @return object The Module object. - * - * @since 11.1 - */ - public static function getLoginModule($name = 'mod_login', $title = null) - { - $result = null; - $modules = self::_load($name); - $total = count($modules); - - for ($i = 0; $i < $total; $i++) - { - // Match the title if we're looking for a specific instance of the module. - if (!$title || $modules[$i]->title == $title) - { - $result = $modules[$i]; - break; - } - } - - // If we didn't find it, and the name is mod_something, create a dummy object. - if (is_null($result) && substr($name, 0, 4) == 'mod_') - { - $result = new stdClass; - $result->id = 0; - $result->title = ''; - $result->module = $name; - $result->position = ''; - $result->content = ''; - $result->showtitle = 0; - $result->control = ''; - $result->params = ''; - $result->user = 0; - } - - return $result; - } - - /** - * Load login modules. - * - * Note that we load regardless of state or access level since access - * for public is the only thing that makes sense since users are not logged in - * and the module lets them log in. - * This is put in as a failsafe to avoid super user lock out caused by an unpublished - * login module or by a module set to have a viewing access level that is not Public. - * - * @param string $module The name of the module. - * - * @return array - * - * @since 11.1 - */ - protected static function _load($module) - { - static $clean; - - if (isset($clean)) - { - return $clean; - } - - $app = JFactory::getApplication(); - $lang = JFactory::getLanguage()->getTag(); - $clientId = (int) $app->getClientId(); - - /** @var JCacheControllerCallback $cache */ - $cache = JFactory::getCache('com_modules', 'callback'); - - $loader = function () use ($app, $lang, $module) { - $db = JFactory::getDbo(); - - $query = $db->getQuery(true) - ->select('m.id, m.title, m.module, m.position, m.showtitle, m.params') - ->from('#__modules AS m') - ->where('m.module =' . $db->quote($module) . ' AND m.client_id = 1') - ->join('LEFT', '#__extensions AS e ON e.element = m.module AND e.client_id = m.client_id') - ->where('e.enabled = 1'); - - // Filter by language. - if ($app->isClient('site') && $app->getLanguageFilter()) - { - $query->where('m.language IN (' . $db->quote($lang) . ',' . $db->quote('*') . ')'); - } - - $query->order('m.position, m.ordering'); - - // Set the query. - $db->setQuery($query); - - return $db->loadObjectList(); - }; - - try - { - return $clean = $cache->get($loader, array(), md5(serialize(array($clientId, $lang)))); - } - catch (JCacheException $cacheException) - { - try - { - return $loader(); - } - catch (JDatabaseExceptionExecuting $databaseException) - { - JError::raiseWarning(500, JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $databaseException->getMessage())); - - return array(); - } - } - catch (JDatabaseExceptionExecuting $databaseException) - { - JError::raiseWarning(500, JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $databaseException->getMessage())); - - return array(); - } - } -} diff --git a/administrator/components/com_login/services/provider.php b/administrator/components/com_login/services/provider.php new file mode 100644 index 0000000000000..548ae07ecb74d --- /dev/null +++ b/administrator/components/com_login/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Login')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Login')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_login/tmpl/login/default.php b/administrator/components/com_login/tmpl/login/default.php new file mode 100644 index 0000000000000..f13423f9ead68 --- /dev/null +++ b/administrator/components/com_login/tmpl/login/default.php @@ -0,0 +1,34 @@ + 'rounded', 'id' => 'section-box')); + + +/** + * Get any other modules in the login position. + * If you want to use a different position for the modules, change the name here in your override. + */ +$modules = ModuleHelper::getModules('login'); + +foreach ($modules as $module) +// Render the login modules + +if ($module->module != 'mod_login'){ + echo ModuleHelper::renderModule($module, array('style' => 'rounded', 'id' => 'section-box')); +} diff --git a/administrator/components/com_login/views/login/tmpl/default.php b/administrator/components/com_login/views/login/tmpl/default.php deleted file mode 100644 index 0774f913000ec..0000000000000 --- a/administrator/components/com_login/views/login/tmpl/default.php +++ /dev/null @@ -1,32 +0,0 @@ - 'rounded', 'id' => 'section-box')); - - -/** - * Get any other modules in the login position. - * If you want to use a different position for the modules, change the name here in your override. - */ -$modules = JModuleHelper::getModules('login'); - -foreach ($modules as $module) -// Render the login modules - -if ($module->module != 'mod_login'){ - echo JModuleHelper::renderModule($module, array('style' => 'rounded', 'id' => 'section-box')); -} diff --git a/administrator/components/com_login/views/login/view.html.php b/administrator/components/com_login/views/login/view.html.php deleted file mode 100644 index 9b3840c3662c6..0000000000000 --- a/administrator/components/com_login/views/login/view.html.php +++ /dev/null @@ -1,41 +0,0 @@ -setHeader('X-Frame-Options', 'SAMEORIGIN'); - - return parent::display($tpl); - } -} diff --git a/administrator/components/com_mailto/services/provider.php b/administrator/components/com_mailto/services/provider.php new file mode 100644 index 0000000000000..ecb1a20167599 --- /dev/null +++ b/administrator/components/com_mailto/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Mailto')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Mailto')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_media/.babelrc b/administrator/components/com_media/.babelrc new file mode 100644 index 0000000000000..c970805e960e1 --- /dev/null +++ b/administrator/components/com_media/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["es2015"], + "plugins": ["transform-runtime"] +} \ No newline at end of file diff --git a/administrator/components/com_media/access.xml b/administrator/components/com_media/access.xml index d4b0fee8c6fcc..2b49b018b6953 100644 --- a/administrator/components/com_media/access.xml +++ b/administrator/components/com_media/access.xml @@ -1,10 +1,10 @@
- - - - - + + + + +
diff --git a/administrator/components/com_media/config.xml b/administrator/components/com_media/config.xml index 294fe96f9f790..67021b27c866b 100644 --- a/administrator/components/com_media/config.xml +++ b/administrator/components/com_media/config.xml @@ -19,7 +19,6 @@ description="COM_MEDIA_FIELD_MAXIMUM_SIZE_DESC" validate="number" min="0" - size="50" default="10" /> @@ -34,7 +33,7 @@ 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" /> @@ -53,11 +52,11 @@ type="radio" label="COM_MEDIA_FIELD_RESTRICT_UPLOADS_LABEL" description="COM_MEDIA_FIELD_RESTRICT_UPLOADS_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" > - + - + getType(); - $vName = $this->input->get('view', 'media'); - - switch ($vName) - { - case 'images': - $vLayout = $this->input->get('layout', 'default', 'string'); - $mName = 'manager'; - - break; - - case 'imagesList': - $mName = 'list'; - $vLayout = $this->input->get('layout', 'default', 'string'); - - break; - - case 'mediaList': - $app = JFactory::getApplication(); - $mName = 'list'; - $vLayout = $app->getUserStateFromRequest('media.list.layout', 'layout', 'thumbs', 'word'); - - break; - - case 'media': - default: - $vName = 'media'; - $vLayout = $this->input->get('layout', 'default', 'string'); - $mName = 'manager'; - - break; - } - - // Get/Create the view - $view = $this->getView($vName, $vType, '', array('base_path' => JPATH_COMPONENT_ADMINISTRATOR)); - - // Get/Create the model - if ($model = $this->getModel($mName)) - { - // Push the model into the view (as default) - $view->setModel($model, true); - } - - // Set the layout - $view->setLayout($vLayout); - - // Display the view - $view->display(); - - return $this; - } - - /** - * Validate FTP credentials - * - * @return void - * - * @since 1.5 - */ - public function ftpValidate() - { - // Set FTP credentials, if given - JClientHelper::setCredentialsFromRequest('ftp'); - } -} diff --git a/administrator/components/com_media/controllers/file.json.php b/administrator/components/com_media/controllers/file.json.php deleted file mode 100644 index a76b13b96ba2b..0000000000000 --- a/administrator/components/com_media/controllers/file.json.php +++ /dev/null @@ -1,261 +0,0 @@ - '0', - 'message' => JText::_('JINVALID_TOKEN'), - 'error' => JText::_('JINVALID_TOKEN') - ); - echo json_encode($response); - - return; - } - - // Get the user - $user = JFactory::getUser(); - JLog::addLogger(array('text_file' => 'upload.error.php'), JLog::ALL, array('upload')); - - // Get some data from the request - $file = $this->input->files->get('Filedata', '', 'array'); - $folder = $this->input->get('folder', '', 'path'); - - // Instantiate the media helper - $mediaHelper = new JHelperMedia; - - if ($_SERVER['CONTENT_LENGTH'] > ($params->get('upload_maxsize', 0) * 1024 * 1024) - || $_SERVER['CONTENT_LENGTH'] > $mediaHelper->toBytes(ini_get('upload_max_filesize')) - || $_SERVER['CONTENT_LENGTH'] > $mediaHelper->toBytes(ini_get('post_max_size')) - || $_SERVER['CONTENT_LENGTH'] > $mediaHelper->toBytes(ini_get('memory_limit'))) - { - $response = array( - 'status' => '0', - 'message' => JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE'), - 'error' => JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE') - ); - echo json_encode($response); - - return; - } - - // Set FTP credentials, if given - JClientHelper::setCredentialsFromRequest('ftp'); - - if (isset($file['name'])) - { - // Make the filename safe - $file['name'] = JFile::makeSafe($file['name']); - - // We need a URL safe name - $fileparts = pathinfo(COM_MEDIA_BASE . '/' . $folder . '/' . $file['name']); - - // Transform filename to punycode - $fileparts['filename'] = JStringPunycode::toPunycode($fileparts['filename']); - $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; - - // Create filepath with safe-filename - $files['final'] = $fileparts['dirname'] . DIRECTORY_SEPARATOR . $safeFileName; - $file['name'] = $safeFileName; - - $filepath = JPath::clean($files['final']); - - if (!$mediaHelper->canUpload($file, 'com_media')) - { - try - { - JLog::add('Invalid: ' . $filepath, JLog::INFO, 'upload'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $response = array( - 'status' => '0', - 'message' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE'), - 'error' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE') - ); - - echo json_encode($response); - - 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)); - - if (in_array(false, $result, true)) - { - // There are some errors in the plugins - try - { - JLog::add( - 'Errors before save: ' . $object_file->filepath . ' : ' . implode(', ', $object_file->getErrors()), - JLog::INFO, - 'upload' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $response = array( - 'status' => '0', - 'message' => JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors)), - 'error' => JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors)) - ); - - echo json_encode($response); - - return; - } - - if (JFile::exists($object_file->filepath)) - { - // File exists - try - { - JLog::add('File exists: ' . $object_file->filepath . ' by user_id ' . $user->id, JLog::INFO, 'upload'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $response = array( - 'status' => '0', - 'message' => JText::_('COM_MEDIA_ERROR_FILE_EXISTS'), - 'error' => JText::_('COM_MEDIA_ERROR_FILE_EXISTS'), - 'location' => str_replace(JPATH_ROOT, '', $filepath) - ); - - echo json_encode($response); - - return; - } - elseif (!$user->authorise('core.create', 'com_media')) - { - // File does not exist and user is not authorised to create - try - { - JLog::add('Create not permitted: ' . $object_file->filepath . ' by user_id ' . $user->id, JLog::INFO, 'upload'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $response = array( - 'status' => '0', - 'error' => JText::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED'), - 'message' => JText::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED') - ); - - echo json_encode($response); - - return; - } - - if (!JFile::upload($object_file->tmp_name, $object_file->filepath)) - { - // Error in upload - try - { - JLog::add('Error on upload: ' . $object_file->filepath, JLog::INFO, 'upload'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $response = array( - 'status' => '0', - 'message' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE'), - 'error' => JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE') - ); - - echo json_encode($response); - - return; - } - else - { - // Trigger the onContentAfterSave event. - $dispatcher->trigger('onContentAfterSave', array('com_media.file', &$object_file, true)); - - try - { - JLog::add($folder, JLog::INFO, 'upload'); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $returnUrl = str_replace(JPATH_ROOT, '', $object_file->filepath); - - $response = array( - 'status' => '1', - 'message' => JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', $returnUrl), - 'error' => JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', $returnUrl), - 'location' => str_replace('\\', '/', $returnUrl) - ); - - echo json_encode($response); - - return; - } - } - else - { - $response = array( - 'status' => '0', - 'error' => JText::_('COM_MEDIA_ERROR_BAD_REQUEST'), - 'message' => JText::_('COM_MEDIA_ERROR_BAD_REQUEST') - ); - - echo json_encode($response); - - return; - } - } -} diff --git a/administrator/components/com_media/controllers/file.php b/administrator/components/com_media/controllers/file.php deleted file mode 100644 index 891a5bd3e0d07..0000000000000 --- a/administrator/components/com_media/controllers/file.php +++ /dev/null @@ -1,332 +0,0 @@ -input->files->get('Filedata', array(), 'array'); - $return = JFactory::getSession()->get('com_media.return_url'); - $this->folder = $this->input->get('folder', '', 'path'); - - // Don't redirect to an external URL. - if (!JUri::isInternal($return)) - { - $return = ''; - } - - // Set the redirect - if ($return) - { - $this->setRedirect($return . '&folder=' . $this->folder); - } - else - { - $this->setRedirect('index.php?option=com_media&folder=' . $this->folder); - } - - if (!$files) - { - // If we could not get any data from the request we can not upload it. - JFactory::getApplication()->enqueueMessage(JText::_('COM_MEDIA_ERROR_WARNFILENOTSAFE'), 'error'); - - return false; - } - - // Authorize the user - if (!$this->authoriseUser('create')) - { - return false; - } - - // If there are no files to upload - then bail - if (empty($files)) - { - return false; - } - - // Total length of post back data in bytes. - $contentLength = (int) $_SERVER['CONTENT_LENGTH']; - - // Instantiate the media helper - $mediaHelper = new JHelperMedia; - - // Maximum allowed size of post back data in MB. - $postMaxSize = $mediaHelper->toBytes(ini_get('post_max_size')); - - // Maximum allowed size of script execution in MB. - $memoryLimit = $mediaHelper->toBytes(ini_get('memory_limit')); - - // Check for the total size of post back data. - if (($postMaxSize > 0 && $contentLength > $postMaxSize) - || ($memoryLimit != -1 && $contentLength > $memoryLimit)) - { - JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNUPLOADTOOLARGE')); - - 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']); - $file['filepath'] = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $this->folder, $file['name']))); - - if (($file['error'] == 1) - || ($uploadMaxSize > 0 && $file['size'] > $uploadMaxSize) - || ($uploadMaxFileSize > 0 && $file['size'] > $uploadMaxFileSize)) - { - // File size exceed either 'upload_max_filesize' or 'upload_maxsize'. - JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_WARNFILETOOLARGE')); - - return false; - } - - if (JFile::exists($file['filepath'])) - { - // A file with this name already exists - JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_FILE_EXISTS')); - - return false; - } - - if (!isset($file['name'])) - { - // No filename (after the name was cleaned by JFile::makeSafe) - $this->setRedirect('index.php', JText::_('COM_MEDIA_INVALID_REQUEST'), 'error'); - - return false; - } - } - - // Set FTP credentials, if given - JClientHelper::setCredentialsFromRequest('ftp'); - JPluginHelper::importPlugin('content'); - $dispatcher = JEventDispatcher::getInstance(); - - foreach ($files as &$file) - { - // The request is valid - $err = null; - - if (!MediaHelper::canUpload($file, $err)) - { - // The file can't be uploaded - return false; - } - - // Trigger the onContentBeforeSave event. - $object_file = new JObject($file); - $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.file', &$object_file, true)); - - if (in_array(false, $result, true)) - { - // There are some errors in the plugins - JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors))); - - return false; - } - - if (!JFile::upload($object_file->tmp_name, $object_file->filepath)) - { - // Error in upload - JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE')); - - return false; - } - - // Trigger the onContentAfterSave event. - $dispatcher->trigger('onContentAfterSave', array('com_media.file', &$object_file, true)); - $this->setMessage(JText::sprintf('COM_MEDIA_UPLOAD_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); - } - - return true; - } - - /** - * Check that the user is authorized to perform this action - * - * @param string $action - the action to be peformed (create or delete) - * - * @return boolean - * - * @since 1.6 - */ - protected function authoriseUser($action) - { - if (!JFactory::getUser()->authorise('core.' . strtolower($action), 'com_media')) - { - // User is not authorised - JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_' . strtoupper($action) . '_NOT_PERMITTED')); - - return false; - } - - return true; - } - - /** - * Deletes paths from the current path - * - * @return boolean - * - * @since 1.5 - */ - public function delete() - { - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); - - $user = JFactory::getUser(); - - // Get some data from the request - $tmpl = $this->input->get('tmpl'); - $paths = $this->input->get('rm', array(), 'array'); - $folder = $this->input->get('folder', '', 'path'); - - $redirect = 'index.php?option=com_media&folder=' . $folder; - - if ($tmpl == 'component') - { - // We are inside the iframe - $redirect .= '&view=mediaList&tmpl=component'; - } - - $this->setRedirect($redirect); - - // Just return if there's nothing to do - if (empty($paths)) - { - $this->setMessage(JText::_('JERROR_NO_ITEMS_SELECTED'), 'error'); - - return true; - } - - if (!$user->authorise('core.delete', 'com_media')) - { - // User is not authorised to delete - JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); - - return false; - } - - // Need this to enqueue messages. - $app = JFactory::getApplication(); - - // Set FTP credentials, if given - JClientHelper::setCredentialsFromRequest('ftp'); - - JPluginHelper::importPlugin('content'); - $dispatcher = JEventDispatcher::getInstance(); - - $ret = true; - - $safePaths = array_intersect($paths, array_map(array('JFile', 'makeSafe'), $paths)); - $unsafePaths = array_diff($paths, $safePaths); - - foreach ($unsafePaths as $path) - { - $path = JPath::clean(implode(DIRECTORY_SEPARATOR, array($folder, $path))); - $path = htmlspecialchars($path, ENT_COMPAT, 'UTF-8'); - $app->enqueueMessage(JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FILE_WARNFILENAME', $path), 'error'); - } - - foreach ($safePaths as $path) - { - $fullPath = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path))); - $object_file = new JObject(array('filepath' => $fullPath)); - - if (is_file($object_file->filepath)) - { - // Trigger the onContentBeforeDelete event. - $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.file', &$object_file)); - - if (in_array(false, $result, true)) - { - // There are some errors in the plugins - $errors = $object_file->getErrors(); - JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors), implode('
', $errors))); - - continue; - } - - $ret &= JFile::delete($object_file->filepath); - - // Trigger the onContentAfterDelete event. - $dispatcher->trigger('onContentAfterDelete', array('com_media.file', &$object_file)); - $app->enqueueMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); - } - elseif (is_dir($object_file->filepath)) - { - $contents = JFolder::files($object_file->filepath, '.', true, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'index.html')); - - if (!empty($contents)) - { - // This makes no sense... - $folderPath = substr($object_file->filepath, strlen(COM_MEDIA_BASE)); - JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_NOT_EMPTY', $folderPath)); - - continue; - } - - // Trigger the onContentBeforeDelete event. - $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.folder', &$object_file)); - - if (in_array(false, $result, true)) - { - // There are some errors in the plugins - $errors = $object_file->getErrors(); - JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors), implode('
', $errors))); - - continue; - } - - $ret &= !JFolder::delete($object_file->filepath); - - // Trigger the onContentAfterDelete event. - $dispatcher->trigger('onContentAfterDelete', array('com_media.folder', &$object_file)); - $app->enqueueMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); - } - } - - return $ret; - } -} diff --git a/administrator/components/com_media/controllers/folder.php b/administrator/components/com_media/controllers/folder.php deleted file mode 100644 index f1439adbc9034..0000000000000 --- a/administrator/components/com_media/controllers/folder.php +++ /dev/null @@ -1,232 +0,0 @@ -input->get('tmpl'); - $paths = $this->input->get('rm', array(), 'array'); - $folder = $this->input->get('folder', '', 'path'); - - $redirect = 'index.php?option=com_media&folder=' . $folder; - - if ($tmpl == 'component') - { - // We are inside the iframe - $redirect .= '&view=mediaList&tmpl=component'; - } - - $this->setRedirect($redirect); - - // Just return if there's nothing to do - if (empty($paths)) - { - $this->setMessage(JText::_('JERROR_NO_ITEMS_SELECTED'), 'error'); - - return true; - } - - if (!$user->authorise('core.delete', 'com_media')) - { - // User is not authorised to delete - JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); - - return false; - } - - // Need this to enqueue messages. - $app = JFactory::getApplication(); - - // Set FTP credentials, if given - JClientHelper::setCredentialsFromRequest('ftp'); - - JPluginHelper::importPlugin('content'); - $dispatcher = JEventDispatcher::getInstance(); - - $ret = true; - - $safePaths = array_intersect($paths, array_map(array('JFile', 'makeSafe'), $paths)); - $unsafePaths = array_diff($paths, $safePaths); - - foreach ($unsafePaths as $path) - { - $path = JPath::clean(implode(DIRECTORY_SEPARATOR, array($folder, $path))); - $path = htmlspecialchars($path, ENT_COMPAT, 'UTF-8'); - $app->enqueueMessage(JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FILE_WARNFILENAME', $path), 'error'); - } - - foreach ($safePaths as $path) - { - $fullPath = JPath::clean(implode(DIRECTORY_SEPARATOR, array(COM_MEDIA_BASE, $folder, $path))); - $object_file = new JObject(array('filepath' => $fullPath)); - - if (is_file($object_file->filepath)) - { - // Trigger the onContentBeforeDelete event. - $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.file', &$object_file)); - - if (in_array(false, $result, true)) - { - // There are some errors in the plugins - $errors = $object_file->getErrors(); - JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors), implode('
', $errors))); - - continue; - } - - $ret &= JFile::delete($object_file->filepath); - - // Trigger the onContentAfterDelete event. - $dispatcher->trigger('onContentAfterDelete', array('com_media.file', &$object_file)); - $app->enqueueMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); - } - elseif (is_dir($object_file->filepath)) - { - $contents = JFolder::files($object_file->filepath, '.', true, false, array('.svn', 'CVS', '.DS_Store', '__MACOSX', 'index.html')); - - if (!empty($contents)) - { - // This makes no sense... - $folderPath = substr($object_file->filepath, strlen(COM_MEDIA_BASE)); - JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_NOT_EMPTY', $folderPath)); - - continue; - } - - // Trigger the onContentBeforeDelete event. - $result = $dispatcher->trigger('onContentBeforeDelete', array('com_media.folder', &$object_file)); - - if (in_array(false, $result, true)) - { - // There are some errors in the plugins - $errors = $object_file->getErrors(); - JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_DELETE', count($errors), implode('
', $errors))); - - continue; - } - - $ret &= !JFolder::delete($object_file->filepath); - - // Trigger the onContentAfterDelete event. - $dispatcher->trigger('onContentAfterDelete', array('com_media.folder', &$object_file)); - $app->enqueueMessage(JText::sprintf('COM_MEDIA_DELETE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); - } - } - - return $ret; - } - - /** - * Create a folder - * - * @return boolean - * - * @since 1.5 - */ - public function create() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $user = JFactory::getUser(); - - $folder = $this->input->get('foldername', ''); - $folderCheck = (string) $this->input->get('foldername', null, 'raw'); - $parent = $this->input->get('folderbase', '', 'path'); - - $this->setRedirect('index.php?option=com_media&folder=' . $parent . '&tmpl=' . $this->input->get('tmpl', 'index')); - - if (strlen($folder) > 0) - { - if (!$user->authorise('core.create', 'com_media')) - { - // User is not authorised to create - JError::raiseWarning(403, JText::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED')); - - return false; - } - - // Set FTP credentials, if given - JClientHelper::setCredentialsFromRequest('ftp'); - - $this->input->set('folder', $parent); - - if (($folderCheck !== null) && ($folder !== $folderCheck)) - { - $app = JFactory::getApplication(); - $app->enqueueMessage(JText::_('COM_MEDIA_ERROR_UNABLE_TO_CREATE_FOLDER_WARNDIRNAME'), 'warning'); - - return false; - } - - $path = JPath::clean(COM_MEDIA_BASE . '/' . $parent . '/' . $folder); - - if (!is_dir($path) && !is_file($path)) - { - // Trigger the onContentBeforeSave event. - $object_file = new JObject(array('filepath' => $path)); - JPluginHelper::importPlugin('content'); - $dispatcher = JEventDispatcher::getInstance(); - $result = $dispatcher->trigger('onContentBeforeSave', array('com_media.folder', &$object_file, true)); - - if (in_array(false, $result, true)) - { - // There are some errors in the plugins - JError::raiseWarning(100, JText::plural('COM_MEDIA_ERROR_BEFORE_SAVE', count($errors = $object_file->getErrors()), implode('
', $errors))); - - return false; - } - - if (JFolder::create($object_file->filepath)) - { - $data = "\n\n\n"; - JFile::write($object_file->filepath . '/index.html', $data); - - // Trigger the onContentAfterSave event. - $dispatcher->trigger('onContentAfterSave', array('com_media.folder', &$object_file, true)); - $this->setMessage(JText::sprintf('COM_MEDIA_CREATE_COMPLETE', substr($object_file->filepath, strlen(COM_MEDIA_BASE)))); - } - } - - $this->input->set('folder', ($parent) ? $parent . '/' . $folder : $folder); - } - else - { - // File name is of zero length (null). - JError::raiseWarning(100, JText::_('COM_MEDIA_ERROR_UNABLE_TO_CREATE_FOLDER_WARNDIRNAME')); - - return false; - } - - return true; - } -} diff --git a/administrator/components/com_media/forms/file.xml b/administrator/components/com_media/forms/file.xml new file mode 100644 index 0000000000000..65281da5bfdb5 --- /dev/null +++ b/administrator/components/com_media/forms/file.xml @@ -0,0 +1,3 @@ + +
+
diff --git a/administrator/components/com_media/helpers/media.php b/administrator/components/com_media/helpers/media.php deleted file mode 100644 index 03213eb80b4a4..0000000000000 --- a/administrator/components/com_media/helpers/media.php +++ /dev/null @@ -1,200 +0,0 @@ -isImage($fileName); - } - - /** - * Gets the file extension for the purpose of using an icon. - * - * @param string $fileName The filename - * - * @return string File extension - * - * @since 1.5 - * @deprecated 4.0 Use JHelperMedia::getTypeIcon instead - */ - public static function getTypeIcon($fileName) - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHelperMedia::getTypeIcon() instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $mediaHelper = new JHelperMedia; - - return $mediaHelper->getTypeIcon($fileName); - } - - /** - * Checks if the file can be uploaded - * - * @param array $file File information - * @param string $error An error message to be returned - * - * @return boolean - * - * @since 1.5 - * @deprecated 4.0 Use JHelperMedia::canUpload instead - */ - public static function canUpload($file, $error = '') - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHelperMedia::canUpload() instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $mediaHelper = new JHelperMedia; - - return $mediaHelper->canUpload($file, 'com_media'); - } - - /** - * Method to parse a file size - * - * @param integer $size The file size in bytes - * - * @return string The converted file size - * - * @since 1.6 - * @deprecated 4.0 Use JHtml::_('number.bytes') instead - */ - public static function parseSize($size) - { - try - { - JLog::add( - sprintf("%s() is deprecated. Use JHtml::_('number.bytes') instead.", __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - return JHtml::_('number.bytes', $size); - } - - /** - * Calculate the size of a resized image - * - * @param integer $width Image width - * @param integer $height Image height - * @param integer $target Target size - * - * @return array The new width and height - * - * @since 3.2 - * @deprecated 4.0 Use JHelperMedia::imageResize instead - */ - public static function imageResize($width, $height, $target) - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHelperMedia::imageResize() instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $mediaHelper = new JHelperMedia; - - return $mediaHelper->imageResize($width, $height, $target); - } - - /** - * Counts the files and directories in a directory that are not php or html files. - * - * @param string $dir Directory name - * - * @return array The number of files and directories in the given directory - * - * @since 1.5 - * @deprecated 4.0 Use JHelperMedia::countFiles instead - */ - public static function countFiles($dir) - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHelperMedia::countFiles() instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - $mediaHelper = new JHelperMedia; - - return $mediaHelper->countFiles($dir); - } -} diff --git a/administrator/components/com_media/layouts/toolbar/create-folder.php b/administrator/components/com_media/layouts/toolbar/create-folder.php new file mode 100644 index 0000000000000..f19753d40a6d1 --- /dev/null +++ b/administrator/components/com_media/layouts/toolbar/create-folder.php @@ -0,0 +1,18 @@ + + diff --git a/administrator/components/com_media/layouts/toolbar/delete.php b/administrator/components/com_media/layouts/toolbar/delete.php new file mode 100644 index 0000000000000..bdf2fc52f5280 --- /dev/null +++ b/administrator/components/com_media/layouts/toolbar/delete.php @@ -0,0 +1,18 @@ + + \ No newline at end of file diff --git a/administrator/components/com_media/layouts/toolbar/deletemedia.php b/administrator/components/com_media/layouts/toolbar/deletemedia.php deleted file mode 100644 index e605566750f19..0000000000000 --- a/administrator/components/com_media/layouts/toolbar/deletemedia.php +++ /dev/null @@ -1,32 +0,0 @@ - - - - diff --git a/administrator/components/com_media/layouts/toolbar/newfolder.php b/administrator/components/com_media/layouts/toolbar/newfolder.php deleted file mode 100644 index b62eeebc1dc4e..0000000000000 --- a/administrator/components/com_media/layouts/toolbar/newfolder.php +++ /dev/null @@ -1,16 +0,0 @@ - - diff --git a/administrator/components/com_media/layouts/toolbar/upload.php b/administrator/components/com_media/layouts/toolbar/upload.php new file mode 100644 index 0000000000000..0ccf094e4d5e9 --- /dev/null +++ b/administrator/components/com_media/layouts/toolbar/upload.php @@ -0,0 +1,18 @@ + + \ No newline at end of file diff --git a/administrator/components/com_media/layouts/toolbar/uploadmedia.php b/administrator/components/com_media/layouts/toolbar/uploadmedia.php deleted file mode 100644 index 2d0f501739dfb..0000000000000 --- a/administrator/components/com_media/layouts/toolbar/uploadmedia.php +++ /dev/null @@ -1,16 +0,0 @@ - - diff --git a/administrator/components/com_media/media.php b/administrator/components/com_media/media.php deleted file mode 100644 index 7069de516037a..0000000000000 --- a/administrator/components/com_media/media.php +++ /dev/null @@ -1,46 +0,0 @@ -input; -$user = JFactory::getUser(); -$asset = $input->get('asset'); -$author = $input->get('author'); - -// Access check. -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)))) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$params = JComponentHelper::getParams('com_media'); - -// Load the helper class -JLoader::register('MediaHelper', JPATH_ADMINISTRATOR . '/components/com_media/helpers/media.php'); - -// Set the path definitions -$popup_upload = $input->get('pop_up', null); -$path = 'file_path'; -$view = $input->get('view'); - -if (substr(strtolower($view), 0, 6) == 'images' || $popup_upload == 1) -{ - $path = 'image_path'; -} - -define('COM_MEDIA_BASE', JPATH_ROOT . '/' . $params->get($path, 'images')); -define('COM_MEDIA_BASEURL', JUri::root() . $params->get($path, 'images')); - -$controller = JControllerLegacy::getInstance('Media', array('base_path' => JPATH_COMPONENT_ADMINISTRATOR)); -$controller->execute($input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_media/media.xml b/administrator/components/com_media/media.xml index 9bdf880abd6a9..07145a2034882 100644 --- a/administrator/components/com_media/media.xml +++ b/administrator/components/com_media/media.xml @@ -17,14 +17,14 @@ language/en-GB.com_media.ini + Joomla\Component\Media config.xml controller.php media.php controllers - helpers - layouts + legacy models views diff --git a/administrator/components/com_media/models/list.php b/administrator/components/com_media/models/list.php deleted file mode 100644 index ef6848a639362..0000000000000 --- a/administrator/components/com_media/models/list.php +++ /dev/null @@ -1,248 +0,0 @@ -input; - $folder = $input->get('folder', '', 'path'); - $this->setState('folder', $folder); - - $parent = str_replace("\\", '/', dirname($folder)); - $parent = ($parent == '.') ? null : $parent; - $this->setState('parent', $parent); - $set = true; - } - - return parent::getState($property, $default); - } - - /** - * Get the images on the current folder - * - * @return array - * - * @since 1.5 - */ - public function getImages() - { - $list = $this->getList(); - - return $list['images']; - } - - /** - * Get the folders on the current folder - * - * @return array - * - * @since 1.5 - */ - public function getFolders() - { - $list = $this->getList(); - - return $list['folders']; - } - - /** - * Get the documents on the current folder - * - * @return array - * - * @since 1.5 - */ - public function getDocuments() - { - $list = $this->getList(); - - return $list['docs']; - } - - /** - * Build imagelist - * - * @return array - * - * @since 1.5 - */ - public function getList() - { - static $list; - - // Only process the list once per request - if (is_array($list)) - { - return $list; - } - - // Get current path from request - $current = (string) $this->getState('folder'); - - $basePath = COM_MEDIA_BASE . ((strlen($current) > 0) ? '/' . $current : ''); - $mediaBase = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE . '/'); - - $images = array (); - $folders = array (); - $docs = array (); - $videos = array (); - - $fileList = false; - $folderList = false; - - if (file_exists($basePath)) - { - // Get the list of files and folders from the given folder - $fileList = JFolder::files($basePath); - $folderList = JFolder::folders($basePath); - } - - // 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 = clone $tmpBaseObject; - $tmp->name = $file; - $tmp->title = $file; - $tmp->path = str_replace(DIRECTORY_SEPARATOR, '/', JPath::clean($basePath . '/' . $file)); - $tmp->path_relative = str_replace($mediaBase, '', $tmp->path); - $tmp->size = filesize($tmp->path); - - $ext = strtolower(JFile::getExt($file)); - - switch ($ext) - { - // Image - case 'jpg': - case 'png': - case 'gif': - case 'xcf': - case 'odg': - case 'bmp': - case 'jpeg': - case 'ico': - $info = @getimagesize($tmp->path); - $tmp->width = @$info[0]; - $tmp->height = @$info[1]; - $tmp->type = @$info[2]; - $tmp->mime = @$info['mime']; - - if (($info[0] > 60) || ($info[1] > 60)) - { - $dimensions = MediaHelper::imageResize($info[0], $info[1], 60); - $tmp->width_60 = $dimensions[0]; - $tmp->height_60 = $dimensions[1]; - } - else - { - $tmp->width_60 = $tmp->width; - $tmp->height_60 = $tmp->height; - } - - if (($info[0] > 16) || ($info[1] > 16)) - { - $dimensions = MediaHelper::imageResize($info[0], $info[1], 16); - $tmp->width_16 = $dimensions[0]; - $tmp->height_16 = $dimensions[1]; - } - else - { - $tmp->width_16 = $tmp->width; - $tmp->height_16 = $tmp->height; - } - - $images[] = $tmp; - break; - - // Video - case 'mp4': - $tmp->icon_32 = 'media/mime-icon-32/' . $ext . '.png'; - $tmp->icon_16 = 'media/mime-icon-16/' . $ext . '.png'; - $videos[] = $tmp; - break; - - // Non-image document - default: - $tmp->icon_32 = 'media/mime-icon-32/' . $ext . '.png'; - $tmp->icon_16 = 'media/mime-icon-16/' . $ext . '.png'; - $docs[] = $tmp; - break; - } - } - } - } - - // Iterate over the folders if they exist - if ($folderList !== false) - { - $tmpBaseObject = new JObject; - - foreach ($folderList as $folder) - { - $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); - $count = MediaHelper::countFiles($tmp->path); - $tmp->files = $count[0]; - $tmp->folders = $count[1]; - - $folders[] = $tmp; - } - } - - $list = array('folders' => $folders, 'docs' => $docs, 'images' => $images, 'videos' => $videos); - - return $list; - } - - /** - * Get the videos on the current folder - * - * @return array - * - * @since 3.5 - */ - public function getVideos() - { - $list = $this->getList(); - - return $list['videos']; - } -} diff --git a/administrator/components/com_media/models/manager.php b/administrator/components/com_media/models/manager.php deleted file mode 100644 index bb8987e0d2ca6..0000000000000 --- a/administrator/components/com_media/models/manager.php +++ /dev/null @@ -1,178 +0,0 @@ -input; - - $folder = $input->get('folder', '', 'path'); - $this->setState('folder', $folder); - - $fieldid = $input->get('fieldid', ''); - $this->setState('field.id', $fieldid); - - $parent = str_replace("\\", '/', dirname($folder)); - $parent = ($parent == '.') ? null : $parent; - $this->setState('parent', $parent); - $set = true; - } - - return parent::getState($property, $default); - } - - /** - * Get a select field with a list of available folders - * - * @param string $base The image directory to display - * - * @return html - * - * @since 1.5 - */ - public function getFolderList($base = null) - { - // Get some paths from the request - if (empty($base)) - { - $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); - - // Get the list of folders - jimport('joomla.filesystem.folder'); - $folders = JFolder::folders($base, '.', true, true); - - $document = JFactory::getDocument(); - $document->setTitle(JText::_('COM_MEDIA_INSERT_IMAGE')); - - // Build the array of select options for the folder list - $options[] = JHtml::_('select.option', '', '/'); - - foreach ($folders as $folder) - { - $folder = str_replace($com_media_base_uni, '', str_replace(DIRECTORY_SEPARATOR, '/', $folder)); - $value = substr($folder, 1); - $text = str_replace(DIRECTORY_SEPARATOR, '/', $folder); - $options[] = JHtml::_('select.option', $value, $text); - } - - // Sort the folder list array - if (is_array($options)) - { - sort($options); - } - - // Get asset and author id (use integer filter) - $input = JFactory::getApplication()->input; - $asset = $input->get('asset', 0, 'integer'); - - // For new items the asset is a string. JAccess always checks type first - // so both string and integer are supported. - if ($asset == 0) - { - $asset = htmlspecialchars(json_encode(trim($input->get('asset', 0, 'cmd'))), ENT_COMPAT, 'UTF-8'); - } - - $author = $input->get('author', 0, 'integer'); - - // Create the dropdown folder select list - $attribs = 'size="1" onchange="ImageManager.setFolder(this.options[this.selectedIndex].value, ' . $asset . ', ' . $author . ')" '; - $list = JHtml::_('select.genericlist', $options, 'folderlist', $attribs, 'value', 'text', $base); - - return $list; - } - - /** - * Get the folder tree - * - * @param mixed $base Base folder | null for using base media folder - * - * @return array - * - * @since 1.5 - */ - public function getFolderTree($base = null) - { - // Get some paths from the request - if (empty($base)) - { - $base = COM_MEDIA_BASE; - } - - $mediaBase = str_replace(DIRECTORY_SEPARATOR, '/', COM_MEDIA_BASE . '/'); - - // Get the list of folders - jimport('joomla.filesystem.folder'); - $folders = JFolder::folders($base, '.', true, true); - - $tree = array(); - - foreach ($folders as $folder) - { - $folder = str_replace(DIRECTORY_SEPARATOR, '/', $folder); - $name = substr($folder, strrpos($folder, '/') + 1); - $relative = str_replace($mediaBase, '', $folder); - $absolute = $folder; - $path = explode('/', $relative); - $node = (object) array('name' => $name, 'relative' => $relative, 'absolute' => $absolute); - $tmp = &$tree; - - for ($i = 0, $n = count($path); $i < $n; $i++) - { - if (!isset($tmp['children'])) - { - $tmp['children'] = array(); - } - - if ($i == $n - 1) - { - // We need to place the node - $tmp['children'][$relative] = array('data' => $node, 'children' => array()); - - break; - } - - if (array_key_exists($key = implode('/', array_slice($path, 0, $i + 1)), $tmp['children'])) - { - $tmp = &$tmp['children'][$key]; - } - } - } - - $tree['data'] = (object) array('name' => JText::_('COM_MEDIA_MEDIA'), 'relative' => '', 'absolute' => $base); - - return $tree; - } -} diff --git a/administrator/components/com_media/package-lock.json b/administrator/components/com_media/package-lock.json new file mode 100644 index 0000000000000..96f624a06d88c --- /dev/null +++ b/administrator/components/com_media/package-lock.json @@ -0,0 +1,7819 @@ +{ + "name": "com_media", + "version": "4.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "JSONStream": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.3.tgz", + "integrity": "sha512-3Sp6WZZ/lXl+nTDoGpGWHEpTnnC6X5fnkolYZR6nwIfzbxxvA8utPWe1gCt7i0m9uVGsSz2IS8K8mJ7HmlduMg==", + "dev": true, + "requires": { + "jsonparse": "1.3.1", + "through": "2.3.8" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "acorn": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", + "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", + "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "dev": true, + "requires": { + "acorn": "5.7.1" + } + }, + "acorn-node": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.5.2.tgz", + "integrity": "sha512-krFKvw/d1F17AN3XZbybIUzEY4YEPNiGo05AfP3dBlfVKrMHETKpgjpuZkSF8qDNt9UkQcqj7am8yJLseklCMg==", + "dev": true, + "requires": { + "acorn": "5.7.1", + "acorn-dynamic-import": "3.0.0", + "xtend": "4.0.1" + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ajv-keywords": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "3.1.10", + "normalize-path": "2.1.1" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "4.17.10" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", + "dev": true + }, + "autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000872", + "normalize-range": "0.1.2", + "num2fraction": "1.2.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000872", + "electron-to-chromium": "1.3.52" + } + } + } + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "aws4": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + }, + "dependencies": { + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + } + } + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.1", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.1", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.10", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.10", + "source-map": "0.5.7", + "trim-right": "1.0.1" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-loader": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-6.4.1.tgz", + "integrity": "sha1-CzQRLVsHSKjc2/Uaz2+b1C1QuMo=", + "dev": true, + "requires": { + "find-cache-dir": "0.1.1", + "loader-utils": "0.2.17", + "mkdirp": "0.5.1", + "object-assign": "4.1.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "6.26.0", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "regexpu-core": "2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "0.10.1" + } + }, + "babel-plugin-transform-runtime": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", + "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" + } + }, + "babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0", + "browserslist": "3.2.8", + "invariant": "2.2.4", + "semver": "5.5.0" + } + }, + "babel-preset-es2015": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", + "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "6.26.3", + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "home-or-tmp": "2.0.0", + "lodash": "4.17.10", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "2.5.7", + "regenerator-runtime": "0.11.1" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.10" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.4", + "lodash": "4.17.10" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.10", + "to-fast-properties": "1.0.3" + } + }, + "babelify": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "dev": true, + "requires": { + "babel-core": "6.26.3", + "object-assign": "4.1.1" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "repeat-element": "1.1.2", + "snapdragon": "0.8.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "1.3.3", + "combine-source-map": "0.8.0", + "defined": "1.0.0", + "safe-buffer": "5.1.2", + "through2": "2.0.3", + "umd": "3.0.3" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browserify": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-13.3.0.tgz", + "integrity": "sha1-tanJAgJD8McORnW+yCI7xifkFc4=", + "dev": true, + "requires": { + "JSONStream": "1.3.3", + "assert": "1.4.1", + "browser-pack": "6.1.0", + "browser-resolve": "1.11.3", + "browserify-zlib": "0.1.4", + "buffer": "4.9.1", + "cached-path-relative": "1.0.1", + "concat-stream": "1.5.2", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "defined": "1.0.0", + "deps-sort": "2.0.0", + "domain-browser": "1.1.7", + "duplexer2": "0.1.4", + "events": "1.1.1", + "glob": "7.1.2", + "has": "1.0.3", + "htmlescape": "1.1.1", + "https-browserify": "0.0.1", + "inherits": "2.0.3", + "insert-module-globals": "7.2.0", + "labeled-stream-splicer": "2.0.1", + "module-deps": "4.1.1", + "os-browserify": "0.1.2", + "parents": "1.0.1", + "path-browserify": "0.0.1", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "read-only-stream": "2.0.0", + "readable-stream": "2.3.6", + "resolve": "1.8.1", + "shasum": "1.0.2", + "shell-quote": "1.6.1", + "stream-browserify": "2.0.1", + "stream-http": "2.8.3", + "string_decoder": "0.10.31", + "subarg": "1.0.0", + "syntax-error": "1.4.0", + "through2": "2.0.3", + "timers-browserify": "1.4.2", + "tty-browserify": "0.0.1", + "url": "0.11.0", + "util": "0.10.4", + "vm-browserify": "0.0.4", + "xtend": "4.0.1" + } + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "1.2.0", + "browserify-des": "1.0.2", + "evp_bytestokey": "1.0.3" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "randombytes": "2.0.6" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.1" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "0.2.9" + } + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "1.0.30000865", + "electron-to-chromium": "1.3.52" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "1.3.0", + "ieee754": "1.1.12", + "isarray": "1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" + } + }, + "cached-path-relative": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", + "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "2.1.1", + "map-obj": "1.0.1" + } + }, + "caniuse-api": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-db": "1.0.30000872", + "lodash.memoize": "4.1.2", + "lodash.uniq": "4.5.0" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000872", + "electron-to-chromium": "1.3.52" + } + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + } + } + }, + "caniuse-db": { + "version": "1.0.30000872", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000872.tgz", + "integrity": "sha1-P25Ttj03N2i/meiWEz1m74nEmZk=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000865", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000865.tgz", + "integrity": "sha512-vs79o1mOSKRGv/1pSkp4EXgl4ZviWeYReXw60XfacPU64uQWZwJT6vZNmxRF9O+6zu71sJwMxLK5JXxbzuVrLw==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.2", + "fsevents": "1.2.4", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "lodash.debounce": "4.0.8", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.1.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "clap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", + "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", + "dev": true, + "requires": { + "chalk": "1.1.3" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "coa": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", + "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "dev": true, + "requires": { + "q": "1.5.1" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "1.0.0", + "object-visit": "1.0.1" + } + }, + "color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "dev": true, + "requires": { + "clone": "1.0.4", + "color-convert": "1.9.2", + "color-string": "0.3.0" + } + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "dev": true, + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", + "dev": true + }, + "color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "dev": true, + "requires": { + "color-name": "1.1.1" + } + }, + "colormin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "dev": true, + "requires": { + "color": "0.11.4", + "css-color-names": "0.0.4", + "has": "1.0.3" + } + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "1.1.3", + "inline-source-map": "0.6.2", + "lodash.memoize": "3.0.4", + "source-map": "0.5.7" + }, + "dependencies": { + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + } + } + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "dev": true, + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", + "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.0.6", + "typedarray": "0.0.6" + }, + "dependencies": { + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + } + } + }, + "config-chain": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz", + "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=", + "dev": true, + "requires": { + "ini": "1.3.5", + "proto-list": "1.2.4" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "0.1.4" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "consolidate": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.14.5.tgz", + "integrity": "sha1-WiUEe8dvcwcmZ8jLUsmJiI9JTGM=", + "dev": true, + "requires": { + "bluebird": "3.5.1" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cosmiconfig": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", + "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", + "dev": true, + "requires": { + "is-directory": "0.3.1", + "js-yaml": "3.7.0", + "minimist": "1.2.0", + "object-assign": "4.1.1", + "os-homedir": "1.0.2", + "parse-json": "2.2.0", + "require-from-string": "1.2.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "elliptic": "6.4.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "md5.js": "1.3.4", + "ripemd160": "2.0.2", + "sha.js": "2.4.11" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "inherits": "2.0.3", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" + } + }, + "cross-env": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-3.2.4.tgz", + "integrity": "sha1-ngWF8neGTtQhznVvgamA/w1piro=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "is-windows": "1.0.2" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "4.1.3", + "shebang-command": "1.2.0", + "which": "1.3.1" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "requires": { + "boom": "2.10.1" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "1.0.1", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.3", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "diffie-hellman": "5.0.3", + "inherits": "2.0.3", + "pbkdf2": "3.0.16", + "public-encrypt": "4.0.2", + "randombytes": "2.0.6", + "randomfill": "1.0.4" + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-loader": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.25.0.tgz", + "integrity": "sha1-w/68jOKPTINXa2sTcH9H+Qw5AiM=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "css-selector-tokenizer": "0.6.0", + "cssnano": "3.10.0", + "loader-utils": "0.2.17", + "lodash.camelcase": "3.0.1", + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-modules-extract-imports": "1.1.0", + "postcss-modules-local-by-default": "1.2.0", + "postcss-modules-scope": "1.1.0", + "postcss-modules-values": "1.3.0", + "source-list-map": "0.1.8" + } + }, + "css-selector-tokenizer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.6.0.tgz", + "integrity": "sha1-ZEX1gseTDSQdzFAHpD1vy48HMVI=", + "dev": true, + "requires": { + "cssesc": "0.1.0", + "fastparse": "1.1.1", + "regexpu-core": "1.0.0" + }, + "dependencies": { + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "requires": { + "regenerate": "1.4.0", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + } + } + }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true + }, + "cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "dev": true, + "requires": { + "autoprefixer": "6.7.7", + "decamelize": "1.2.0", + "defined": "1.0.0", + "has": "1.0.3", + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-calc": "5.3.1", + "postcss-colormin": "2.2.2", + "postcss-convert-values": "2.6.1", + "postcss-discard-comments": "2.0.4", + "postcss-discard-duplicates": "2.1.0", + "postcss-discard-empty": "2.1.0", + "postcss-discard-overridden": "0.1.1", + "postcss-discard-unused": "2.2.3", + "postcss-filter-plugins": "2.0.3", + "postcss-merge-idents": "2.1.7", + "postcss-merge-longhand": "2.0.2", + "postcss-merge-rules": "2.1.2", + "postcss-minify-font-values": "1.0.5", + "postcss-minify-gradients": "1.0.5", + "postcss-minify-params": "1.2.2", + "postcss-minify-selectors": "2.1.1", + "postcss-normalize-charset": "1.1.1", + "postcss-normalize-url": "3.0.8", + "postcss-ordered-values": "2.2.3", + "postcss-reduce-idents": "2.4.0", + "postcss-reduce-initial": "1.0.1", + "postcss-reduce-transforms": "1.0.4", + "postcss-svgo": "2.1.6", + "postcss-unique-selectors": "2.0.2", + "postcss-value-parser": "3.3.0", + "postcss-zindex": "2.2.0" + } + }, + "csso": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "dev": true, + "requires": { + "clap": "1.2.3", + "source-map": "0.5.7" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "1.0.2" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.45" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deepmerge": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.1.1.tgz", + "integrity": "sha512-urQxA1smbLZ2cBbXbaYObM1dJ82aJ2H57A1C/Kklfh/ZN1bgH4G/n5KWhdNfOK11W98gqZfyYj7W4frJJRwA2w==" + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "1.0.2", + "isobject": "3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "1.3.3", + "shasum": "1.0.2", + "subarg": "1.0.0", + "through2": "2.0.3" + } + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" + } + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "detective": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", + "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", + "dev": true, + "requires": { + "acorn": "5.7.1", + "defined": "1.0.0" + } + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" + } + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "2.3.6" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "0.1.1", + "safer-buffer": "2.1.2" + } + }, + "editorconfig": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.13.3.tgz", + "integrity": "sha512-WkjsUNVCu+ITKDj73QDvi0trvpdDWdkDyHybDGSXPfekLCqwmpD7CP7iPbvBgosNuLcI96XTDwNa75JyFl7tEQ==", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "commander": "2.16.0", + "lru-cache": "3.2.0", + "semver": "5.5.0", + "sigmund": "1.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", + "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", + "dev": true, + "requires": { + "pseudomap": "1.0.2" + } + } + } + }, + "electron-to-chromium": { + "version": "1.3.52", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.52.tgz", + "integrity": "sha1-0tnxJwuko7lnuDHEDvcftNmrXOA=", + "dev": true + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.5", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "enhanced-resolve": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", + "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "memory-fs": "0.4.1", + "object-assign": "4.1.1", + "tapable": "0.2.8" + } + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es5-ext": { + "version": "0.10.45", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", + "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "next-tick": "1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.1", + "estraverse": "4.2.0" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.45" + } + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "1.3.4", + "safe-buffer": "5.1.2" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "extract-text-webpack-plugin": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", + "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", + "dev": true, + "requires": { + "async": "2.6.1", + "loader-utils": "1.1.0", + "schema-utils": "0.3.0", + "webpack-sources": "1.1.0" + }, + "dependencies": { + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fastparse": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", + "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", + "dev": true + }, + "file-loader": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.9.0.tgz", + "integrity": "sha1-HS2t3UJM5tGwfP4/eXMb7TYXq0I=", + "dev": true, + "requires": { + "loader-utils": "0.2.17" + } + }, + "file-saver": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.8.tgz", + "integrity": "sha512-spKHSBQIxxS81N/O21WmuXA2F6wppUCsutpzenOeZzOCCJ5gEfcbqJP983IrpLXzYmXnMUa6J03SubcNPdKrlg==" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "dev": true, + "requires": { + "commondir": "1.0.1", + "mkdirp": "0.5.1", + "pkg-dir": "1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.19" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "dev": true, + "optional": true, + "requires": { + "nan": "2.10.0", + "node-pre-gyp": "0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "2.2.4" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": "2.1.2" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "5.1.1", + "yallist": "3.0.2" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "2.2.4" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "2.6.9", + "iconv-lite": "0.4.21", + "sax": "1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "1.0.3", + "mkdirp": "0.5.1", + "needle": "2.2.0", + "nopt": "4.0.1", + "npm-packlist": "1.1.10", + "npmlog": "4.1.2", + "rc": "1.2.7", + "rimraf": "2.6.2", + "semver": "5.5.0", + "tar": "4.4.1" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1.1.1", + "osenv": "0.1.5" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.3" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "0.5.1", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "1.0.1", + "fs-minipass": "1.2.5", + "minipass": "2.2.4", + "minizlib": "1.1.0", + "mkdirp": "0.5.1", + "safe-buffer": "5.1.1", + "yallist": "3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true + } + } + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.3" + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "globule": "1.2.1" + } + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + } + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globule": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", + "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", + "dev": true, + "requires": { + "glob": "7.1.2", + "lodash": "4.17.10", + "minimatch": "3.0.4" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "har-schema": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "dev": true + }, + "har-validator": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "har-schema": "1.0.5" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, + "hash.js": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", + "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" + } + }, + "hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "requires": { + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "1.1.5", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "requires": { + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.14.2" + } + }, + "https-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", + "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "dev": true + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "dev": true + }, + "in-publish": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "1.3.3", + "acorn-node": "1.5.2", + "combine-source-map": "0.8.0", + "concat-stream": "1.6.2", + "is-buffer": "1.1.6", + "path-is-absolute": "1.0.1", + "process": "0.11.10", + "through2": "2.0.3", + "undeclared-identifiers": "1.1.2", + "xtend": "4.0.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "1.1.1", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" + } + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "1.4.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "1.11.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-svg": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "dev": true, + "requires": { + "html-comment-regex": "1.1.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-base64": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.8.tgz", + "integrity": "sha512-hm2nYpDrwoO/OzBhdcqs/XGT6XjSuSSCVEpia+Kl2J6x4CYt5hISlVL/AYU1khoDXv0AQVgxtdJySb9gjAn56Q==", + "dev": true + }, + "js-beautify": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.7.5.tgz", + "integrity": "sha512-9OhfAqGOrD7hoQBLJMTA+BKuKmoEtTJXzZ7WDF/9gvjtey1koVLuZqIY6c51aPDjbNdNtIXAkiWKVhziawE9Og==", + "dev": true, + "requires": { + "config-chain": "1.1.11", + "editorconfig": "0.13.3", + "mkdirp": "0.5.1", + "nopt": "3.0.6" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "dev": true, + "requires": { + "argparse": "1.0.10", + "esprima": "2.7.3" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "isarray": "2.0.4", + "stream-splicer": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "loader-runner": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", + "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", + "dev": true + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1", + "object-assign": "4.1.1" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "lodash._createcompounder": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._createcompounder/-/lodash._createcompounder-3.0.0.tgz", + "integrity": "sha1-XdLLVTctbnDg4jkvsjBNZjEJEHU=", + "dev": true, + "requires": { + "lodash.deburr": "3.2.0", + "lodash.words": "3.2.0" + } + }, + "lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + }, + "lodash.camelcase": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-3.0.1.tgz", + "integrity": "sha1-kyyLh/ikN3iXxnGXUzKC+Xrqwpg=", + "dev": true, + "requires": { + "lodash._createcompounder": "3.0.0" + } + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.deburr": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-3.2.0.tgz", + "integrity": "sha1-baj1QzSjZqfPTEx2742Aqhs2XtU=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + } + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "dev": true + }, + "lodash.tail": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", + "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "lodash.words": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.words/-/lodash.words-3.2.0.tgz", + "integrity": "sha1-TiqGSbwIdFsXxpWxo86P7llmI7M=", + "dev": true, + "requires": { + "lodash._root": "3.0.1" + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" + } + }, + "lru-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", + "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "1.0.1" + } + }, + "math-expression-evaluator": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", + "dev": true + }, + "md5.js": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", + "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "1.2.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "0.1.7", + "readable-stream": "2.3.6" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.13", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0" + } + }, + "mime-db": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", + "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", + "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "dev": true, + "requires": { + "mime-db": "1.35.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "1.0.2", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "module-deps": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", + "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", + "dev": true, + "requires": { + "JSONStream": "1.3.3", + "browser-resolve": "1.11.3", + "cached-path-relative": "1.0.1", + "concat-stream": "1.5.2", + "defined": "1.0.0", + "detective": "4.7.1", + "duplexer2": "0.1.4", + "inherits": "2.0.3", + "parents": "1.0.1", + "readable-stream": "2.3.6", + "resolve": "1.8.1", + "stream-combiner2": "1.1.1", + "subarg": "1.0.0", + "through2": "2.0.3", + "xtend": "4.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "neo-async": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz", + "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "node-gyp": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.7.0.tgz", + "integrity": "sha512-qDQE/Ft9xXP6zphwx4sD0t+VhwV7yFaloMpfbL2QnnDZcyaiakWlLdtFGGQfTAwpFHdpbRhRxVhIHN1OKAjgbg==", + "dev": true, + "requires": { + "fstream": "1.0.11", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "npmlog": "4.1.2", + "osenv": "0.1.5", + "request": "2.81.0", + "rimraf": "2.6.2", + "semver": "5.3.0", + "tar": "2.2.1", + "which": "1.3.1" + }, + "dependencies": { + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.7.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.2", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.19", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.2", + "stringstream": "0.0.6", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.3.2" + } + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } + } + }, + "node-libs-browser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", + "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "dev": true, + "requires": { + "assert": "1.4.1", + "browserify-zlib": "0.2.0", + "buffer": "4.9.1", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "domain-browser": "1.1.7", + "events": "1.1.1", + "https-browserify": "1.0.0", + "os-browserify": "0.3.0", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "readable-stream": "2.3.6", + "stream-browserify": "2.0.1", + "stream-http": "2.8.3", + "string_decoder": "1.1.1", + "timers-browserify": "2.0.10", + "tty-browserify": "0.0.0", + "url": "0.11.0", + "util": "0.10.4", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "1.0.6" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "timers-browserify": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "dev": true, + "requires": { + "setimmediate": "1.0.5" + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + } + } + }, + "node-sass": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.2.tgz", + "integrity": "sha512-LdxoJLZutx0aQXHtWIYwJKMj+9pTjneTcLWJgzf2XbGu0q5pRNqW5QvFCEdm3mc5rJOdru/mzln5d0EZLacf6g==", + "dev": true, + "requires": { + "async-foreach": "0.1.3", + "chalk": "1.1.3", + "cross-spawn": "3.0.1", + "gaze": "1.1.3", + "get-stdin": "4.0.1", + "glob": "7.1.2", + "in-publish": "2.0.0", + "lodash.assign": "4.2.0", + "lodash.clonedeep": "4.5.0", + "lodash.mergewith": "4.6.1", + "meow": "3.7.0", + "mkdirp": "0.5.1", + "nan": "2.10.0", + "node-gyp": "3.7.0", + "npmlog": "4.1.2", + "request": "2.87.0", + "sass-graph": "2.2.4", + "stdout-stream": "1.4.0", + "true-case-path": "1.0.2" + }, + "dependencies": { + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "requires": { + "lru-cache": "4.1.3", + "which": "1.3.1" + } + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.1.1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "2.7.1", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "prepend-http": "1.0.4", + "query-string": "4.3.4", + "sort-keys": "1.1.2" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "1.1.5", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "os-browserify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz", + "integrity": "sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.3.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "dev": true, + "requires": { + "asn1.js": "4.10.1", + "browserify-aes": "1.2.0", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.16" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "1.3.2" + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pbkdf2": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", + "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "dev": true, + "requires": { + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" + } + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "1.1.2" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "requires": { + "chalk": "1.1.3", + "js-base64": "2.4.8", + "source-map": "0.5.7", + "supports-color": "3.2.3" + }, + "dependencies": { + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "postcss-calc": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-message-helpers": "2.0.0", + "reduce-css-calc": "1.3.0" + } + }, + "postcss-colormin": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "dev": true, + "requires": { + "colormin": "1.1.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-convert-values": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-discard-comments": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-duplicates": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-empty": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-overridden": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-discard-unused": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "uniqs": "2.0.0" + } + }, + "postcss-filter-plugins": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz", + "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-load-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", + "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1", + "postcss-load-options": "1.2.0", + "postcss-load-plugins": "2.3.0" + } + }, + "postcss-load-options": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", + "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-load-plugins": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", + "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=", + "dev": true, + "requires": { + "cosmiconfig": "2.2.2", + "object-assign": "4.1.1" + } + }, + "postcss-merge-idents": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", + "dev": true, + "requires": { + "has": "1.0.3", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-merge-longhand": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-merge-rules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "dev": true, + "requires": { + "browserslist": "1.7.7", + "caniuse-api": "1.6.1", + "postcss": "5.2.18", + "postcss-selector-parser": "2.2.3", + "vendors": "1.0.2" + }, + "dependencies": { + "browserslist": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, + "requires": { + "caniuse-db": "1.0.30000872", + "electron-to-chromium": "1.3.52" + } + } + } + }, + "postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", + "dev": true + }, + "postcss-minify-font-values": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-minify-gradients": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-minify-params": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0", + "uniqs": "2.0.0" + } + }, + "postcss-minify-selectors": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "has": "1.0.3", + "postcss": "5.2.18", + "postcss-selector-parser": "2.2.3" + } + }, + "postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", + "dev": true, + "requires": { + "postcss": "6.0.23" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.2" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "2.4.1", + "source-map": "0.6.1", + "supports-color": "5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, + "requires": { + "css-selector-tokenizer": "0.7.0", + "postcss": "6.0.23" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.2" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "css-selector-tokenizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", + "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "dev": true, + "requires": { + "cssesc": "0.1.0", + "fastparse": "1.1.1", + "regexpu-core": "1.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "2.4.1", + "source-map": "0.6.1", + "supports-color": "5.4.0" + } + }, + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "requires": { + "regenerate": "1.4.0", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, + "requires": { + "css-selector-tokenizer": "0.7.0", + "postcss": "6.0.23" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.2" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "css-selector-tokenizer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", + "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "dev": true, + "requires": { + "cssesc": "0.1.0", + "fastparse": "1.1.1", + "regexpu-core": "1.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "2.4.1", + "source-map": "0.6.1", + "supports-color": "5.4.0" + } + }, + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "requires": { + "regenerate": "1.4.0", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, + "requires": { + "icss-replace-symbols": "1.1.0", + "postcss": "6.0.23" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.2" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "2.4.1", + "source-map": "0.6.1", + "supports-color": "5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "postcss-normalize-charset": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-normalize-url": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "dev": true, + "requires": { + "is-absolute-url": "2.1.0", + "normalize-url": "1.9.1", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-ordered-values": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-reduce-idents": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", + "dev": true, + "requires": { + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-reduce-initial": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "dev": true, + "requires": { + "postcss": "5.2.18" + } + }, + "postcss-reduce-transforms": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "dev": true, + "requires": { + "has": "1.0.3", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0" + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "requires": { + "flatten": "1.0.2", + "indexes-of": "1.0.1", + "uniq": "1.0.1" + } + }, + "postcss-svgo": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "dev": true, + "requires": { + "is-svg": "2.1.0", + "postcss": "5.2.18", + "postcss-value-parser": "3.3.0", + "svgo": "0.7.2" + } + }, + "postcss-unique-selectors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "dev": true, + "requires": { + "alphanum-sort": "1.0.2", + "postcss": "5.2.18", + "uniqs": "2.0.0" + } + }, + "postcss-value-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "dev": true + }, + "postcss-zindex": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", + "dev": true, + "requires": { + "has": "1.0.3", + "postcss": "5.2.18", + "uniqs": "2.0.0" + } + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "dev": true, + "requires": { + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "parse-asn1": "5.1.1", + "randombytes": "2.0.6" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "strict-uri-encode": "1.1.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "2.0.6", + "safe-buffer": "5.1.2" + } + }, + "read-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "2.3.6" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + } + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "minimatch": "3.0.4", + "readable-stream": "2.3.6", + "set-immediate-shim": "1.0.1" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "2.1.0", + "strip-indent": "1.0.1" + } + }, + "reduce-css-calc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "math-expression-evaluator": "1.2.17", + "reduce-function-call": "1.0.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + } + } + }, + "reduce-function-call": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "dev": true, + "requires": { + "balanced-match": "0.4.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + } + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "1.4.0", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "request": { + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "dev": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.7.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.2", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.19", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.3.2" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.19" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, + "requires": { + "ajv": "5.5.2", + "har-schema": "2.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.2" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "3.0.4", + "inherits": "2.0.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "0.1.15" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass-graph": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", + "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "dev": true, + "requires": { + "glob": "7.1.2", + "lodash": "4.17.10", + "scss-tokenizer": "0.2.3", + "yargs": "7.1.0" + } + }, + "sass-loader": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-5.0.1.tgz", + "integrity": "sha1-SqgvRCQqvmLtj9zSjWMxo07yfC0=", + "dev": true, + "requires": { + "async": "2.6.1", + "loader-utils": "0.2.17", + "lodash.tail": "4.1.1", + "pify": "2.3.0" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", + "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", + "dev": true, + "requires": { + "ajv": "5.5.2" + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "requires": { + "js-base64": "2.4.8", + "source-map": "0.4.4" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "2.0.3", + "safe-buffer": "5.1.2" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "0.0.1", + "sha.js": "2.4.11" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "requires": { + "array-filter": "0.0.1", + "array-map": "0.0.0", + "array-reduce": "0.0.0", + "jsonify": "0.0.0" + } + }, + "shvl": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/shvl/-/shvl-1.3.1.tgz", + "integrity": "sha512-+rRPP46hloYUAEImJcqprUgXu+05Ikqr4h4V+w5i2zJy37nAqtkQKufs3+3S2fDq6JNRrHMIQhB/Vaex+jgAAw==" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.2", + "use": "3.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "requires": { + "hoek": "2.16.3" + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "1.1.0" + } + }, + "source-list-map": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", + "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "2.1.1", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" + } + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "dev": true, + "requires": { + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "3.0.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "dev": true, + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.2", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.2", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "safer-buffer": "2.1.2", + "tweetnacl": "0.14.5" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "0.2.5", + "object-copy": "0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "stdout-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", + "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "dev": true, + "requires": { + "readable-stream": "2.3.6" + } + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.6" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "0.1.4", + "readable-stream": "2.3.6" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.6" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "4.0.1" + } + }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "dev": true, + "requires": { + "minimist": "1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "svgo": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "dev": true, + "requires": { + "coa": "1.0.4", + "colors": "1.1.2", + "csso": "2.3.2", + "js-yaml": "3.7.0", + "mkdirp": "0.5.1", + "sax": "1.2.4", + "whet.extend": "0.9.9" + } + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "1.5.2" + } + }, + "tapable": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", + "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", + "dev": true + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.3.6", + "xtend": "4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "0.11.10" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "repeat-string": "1.6.1" + } + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "requires": { + "punycode": "1.4.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "true-case-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz", + "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=", + "dev": true, + "requires": { + "glob": "6.0.4" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "requires": { + "source-map": "0.5.7", + "uglify-js": "2.8.29", + "webpack-sources": "1.1.0" + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz", + "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==", + "dev": true, + "requires": { + "acorn-node": "1.5.2", + "get-assigned-identifiers": "1.2.0", + "simple-concat": "1.0.0", + "xtend": "4.0.1" + } + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "0.3.1", + "isobject": "3.0.1" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "dev": true, + "requires": { + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" + } + }, + "vendors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", + "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "vue": { + "version": "2.5.16", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.16.tgz", + "integrity": "sha512-/ffmsiVuPC8PsWcFkZngdpas19ABm5mh2wA7iDqcltyCTwlgZjHGeJYOXkBMo422iPwIcviOtrTCUpSfXmToLQ==" + }, + "vue-focus": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vue-focus/-/vue-focus-2.1.0.tgz", + "integrity": "sha1-egM3zpB01e8D0VpLW4Ys9F5eBOM=", + "requires": { + "loose-envify": "1.4.0" + } + }, + "vue-hot-reload-api": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz", + "integrity": "sha512-2j/t+wIbyVMP5NvctQoSUvLkYKoWAAk2QlQiilrM2a6/ulzFgdcLUJfTvs4XQ/3eZhHiBmmEojbjmM4AzZj8JA==", + "dev": true + }, + "vue-loader": { + "version": "12.2.2", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-12.2.2.tgz", + "integrity": "sha512-DD+sYaWQ1esYL/tEwJpoEGE/PFUu32fp7iOuMf4Sra3dgxqr4haTOkVam2VY0/5D4LG8eAcB94ruXKeQW2/ikw==", + "dev": true, + "requires": { + "consolidate": "0.14.5", + "hash-sum": "1.0.2", + "js-beautify": "1.7.5", + "loader-utils": "1.1.0", + "lru-cache": "4.1.3", + "postcss": "5.2.18", + "postcss-load-config": "1.2.0", + "postcss-selector-parser": "2.2.3", + "resolve": "1.8.1", + "source-map": "0.5.7", + "vue-hot-reload-api": "2.3.0", + "vue-style-loader": "3.1.2", + "vue-template-es2015-compiler": "1.6.0" + }, + "dependencies": { + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + } + } + }, + "vue-style-loader": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-3.1.2.tgz", + "integrity": "sha512-ICtVdK/p+qXWpdSs2alWtsXt9YnDoYjQe0w5616j9+/EhjoxZkbun34uWgsMFnC1MhrMMwaWiImz3K2jK1Yp2Q==", + "dev": true, + "requires": { + "hash-sum": "1.0.2", + "loader-utils": "1.1.0" + }, + "dependencies": { + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + } + } + }, + "vue-template-compiler": { + "version": "2.5.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.5.16.tgz", + "integrity": "sha512-ZbuhCcF/hTYmldoUOVcu2fcbeSAZnfzwDskGduOrnjBiIWHgELAd+R8nAtX80aZkceWDKGQ6N9/0/EUpt+l22A==", + "dev": true, + "requires": { + "de-indent": "1.0.2", + "he": "1.1.1" + } + }, + "vue-template-es2015-compiler": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz", + "integrity": "sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==", + "dev": true + }, + "vueify": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/vueify/-/vueify-9.4.1.tgz", + "integrity": "sha1-0pqXdaM8S4qGAeGGqF2iq4AMoNY=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "convert-source-map": "1.5.1", + "cssnano": "3.10.0", + "hash-sum": "1.0.2", + "json5": "0.5.1", + "lru-cache": "4.1.3", + "object-assign": "4.1.1", + "postcss": "5.2.18", + "postcss-selector-parser": "2.2.3", + "source-map": "0.5.7", + "through": "2.3.8", + "vue-hot-reload-api": "2.3.0", + "vue-template-compiler": "2.5.16", + "vue-template-es2015-compiler": "1.6.0" + } + }, + "vuex": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-2.5.0.tgz", + "integrity": "sha512-5oJPOJySBgSgSzoeO+gZB/BbN/XsapgIF6tz34UwJqnGZMQurzIO3B4KIBf862gfc9ya+oduY5sSkq+5/oOilQ==" + }, + "vuex-persistedstate": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-2.5.4.tgz", + "integrity": "sha512-XYJhKIwO+ZVlTaXyxKxnplrJ88Fnvk5aDw753bxzRw5/yMKLQ6lq9CDCBex2fwZaQcLibhtgJOxGCHjy9GLSlQ==", + "requires": { + "deepmerge": "2.1.1", + "shvl": "1.3.1" + } + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "2.0.4", + "graceful-fs": "4.1.11", + "neo-async": "2.5.1" + } + }, + "webpack": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.12.0.tgz", + "integrity": "sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ==", + "dev": true, + "requires": { + "acorn": "5.7.1", + "acorn-dynamic-import": "2.0.2", + "ajv": "6.5.2", + "ajv-keywords": "3.2.0", + "async": "2.6.1", + "enhanced-resolve": "3.4.1", + "escope": "3.6.0", + "interpret": "1.1.0", + "json-loader": "0.5.7", + "json5": "0.5.1", + "loader-runner": "2.3.0", + "loader-utils": "1.1.0", + "memory-fs": "0.4.1", + "mkdirp": "0.5.1", + "node-libs-browser": "2.1.0", + "source-map": "0.5.7", + "supports-color": "4.5.0", + "tapable": "0.2.8", + "uglifyjs-webpack-plugin": "0.4.6", + "watchpack": "1.6.0", + "webpack-sources": "1.1.0", + "yargs": "8.0.2" + }, + "dependencies": { + "acorn-dynamic-import": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", + "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "dev": true, + "requires": { + "acorn": "4.0.13" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + } + } + }, + "ajv": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.2.tgz", + "integrity": "sha512-hOs7GfvI6tUI1LfZddH82ky6mOMyTuY0mk7kE2pWpmhhUSkumzaTO5vbVwij39MdwPQWCV4Zv57Eo06NtL/GVA==", + "dev": true, + "requires": { + "fast-deep-equal": "2.0.1", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.4.1", + "uri-js": "4.2.2" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "3.2.0", + "emojis-list": "2.1.0", + "json5": "0.5.1" + } + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "2.3.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.3", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } + }, + "webpack-sources": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "dev": true, + "requires": { + "source-list-map": "2.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "whet.extend": { + "version": "0.9.9", + "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", + "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "1.0.2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.3", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + } + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + } + } + } + } +} diff --git a/administrator/components/com_media/package.json b/administrator/components/com_media/package.json new file mode 100644 index 0000000000000..82aac2c4746bd --- /dev/null +++ b/administrator/components/com_media/package.json @@ -0,0 +1,38 @@ +{ + "name": "com_media", + "version": "4.0.0", + "description": "Component for managing site media", + "license": "GPL-2.0", + "author": "", + "scripts": { + "dev": "cross-env NODE_ENV=development webpack --progress --hide-modules", + "watch": "cross-env NODE_ENV=development webpack --progress --hide-modules --watch", + "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" + }, + "dependencies": { + "file-saver": "^1.3.3", + "vue": "^2.5.13", + "vue-focus": "^2.1.0", + "vuex": "^2.5.0", + "vuex-persistedstate": "^2.4.2" + }, + "devDependencies": { + "babel-core": "^6.0.0", + "babel-loader": "^6.0.0", + "babel-plugin-transform-runtime": "^6.23.0", + "babel-preset-env": "^1.6.1", + "babel-preset-es2015": "^6.24.0", + "babelify": "^7.2.0", + "browserify": "^13.0.1", + "cross-env": "^3.0.0", + "css-loader": "^0.25.0", + "extract-text-webpack-plugin": "^3.0.2", + "file-loader": "^0.9.0", + "node-sass": "^4.7.2", + "sass-loader": "^5.0.1", + "vue-loader": "^12.1.0", + "vue-template-compiler": "^2.5.13", + "vueify": "^9.4.1", + "webpack": "^3.10.0" + } +} diff --git a/administrator/components/com_media/resources/scripts/app/Api.js b/administrator/components/com_media/resources/scripts/app/Api.js new file mode 100644 index 0000000000000..40a078811aa24 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/app/Api.js @@ -0,0 +1,271 @@ +import {notifications} from "./Notifications"; + +const path = require('path'); + +/** + * Api class for communication with the server + */ +class Api { + + /** + * Store constructor + */ + constructor() { + const options = Joomla.getOptions('com_media', {}); + if (options.apiBaseUrl === undefined) { + throw new TypeError('Media api baseUrl is not defined'); + } + if (options.csrfToken === undefined) { + throw new TypeError('Media api csrf token is not defined'); + } + + this._baseUrl = options.apiBaseUrl; + this._csrfToken = Joomla.getOptions('csrf.token'); + } + + /** + * Get the contents of a directory from the server + * @param {string} dir The directory path + * @param {number} full whether or not the persistent url should be returned + * @param {number} content whether or not the content should be returned + * @returns {Promise} + */ + getContents(dir, full, content) { + // Wrap the ajax call into a real promise + return new Promise((resolve, reject) => { + // Do a check on full + if (["0", "1"].indexOf(full) !== -1) { + throw "Invalid parameter: full"; + } + // Do a check on download + if (["0", "1"].indexOf(content) !== -1) { + throw "Invalid parameter: content"; + } + + let url = this._baseUrl + '&task=api.files&path=' + dir; + + if (full) { + url += '&url=' + full; + } + + if (content) { + url += '&content=' + content; + } + + Joomla.request({ + url: url, + method: 'GET', + headers: {'Content-Type': 'application/json'}, + onSuccess: (response) => { + resolve(this._normalizeArray(JSON.parse(response).data)) + }, + onError: (xhr) => { + reject(xhr) + } + }); + }).catch(this._handleError); + } + + /** + * Create a directory + * @param name + * @param parent + * @returns {Promise.} + */ + createDirectory(name, parent) { + // Wrap the ajax call into a real promise + return new Promise((resolve, reject) => { + const url = this._baseUrl + '&task=api.files&path=' + parent; + const data = {[this._csrfToken]: '1', name: name}; + + Joomla.request({ + url: url, + method: 'POST', + data: JSON.stringify(data), + headers: {'Content-Type': 'application/json'}, + onSuccess: (response) => { + notifications.success('COM_MEDIA_CREATE_NEW_FOLDER_SUCCESS'); + resolve(this._normalizeItem(JSON.parse(response).data)) + }, + onError: (xhr) => { + notifications.error('COM_MEDIA_CREATE_NEW_FOLDER_ERROR'); + reject(xhr) + } + }); + }).catch(this._handleError); + } + + /** + * Upload a file + * @param name + * @param parent + * @param content base64 encoded string + * @param override boolean whether or not we should override existing files + * @return {Promise.} + */ + upload(name, parent, content, override) { + // Wrap the ajax call into a real promise + return new Promise((resolve, reject) => { + const url = this._baseUrl + '&task=api.files&path=' + parent; + const data = { + [this._csrfToken]: '1', + name: name, + content: content, + }; + + // Append override + if (override === true) { + data.override = true; + } + + Joomla.request({ + url: url, + method: 'POST', + data: JSON.stringify(data), + headers: {'Content-Type': 'application/json'}, + onSuccess: (response) => { + notifications.success('COM_MEDIA_UPDLOAD_SUCCESS'); + resolve(this._normalizeItem(JSON.parse(response).data)) + }, + onError: (xhr) => { + reject(xhr) + } + }); + + }).catch(this._handleError); + } + + /** + * Rename an item + * @param path + * @param newName + * @return {Promise.} + */ + rename(path, newPath) { + // Wrap the ajax call into a real promise + return new Promise((resolve, reject) => { + const url = this._baseUrl + '&task=api.files&path=' + path; + const data = { + [this._csrfToken]: '1', + newPath: newPath, + }; + + Joomla.request({ + url: url, + method: 'PUT', + data: JSON.stringify(data), + headers: {'Content-Type': 'application/json'}, + onSuccess: (response) => { + notifications.success('COM_MEDIA_RENAME_SUCCESS'); + resolve(this._normalizeItem(JSON.parse(response).data)) + }, + onError: (xhr) => { + notifications.error('COM_MEDIA_RENAME_ERROR'); + reject(xhr) + } + }); + + }).catch(this._handleError); + } + + /** + * Delete a file + * @param path + * @return {Promise.} + */ + delete(path) { + // Wrap the ajax call into a real promise + return new Promise((resolve, reject) => { + + const url = this._baseUrl + '&task=api.files&path=' + path; + const data = {[this._csrfToken]: '1',}; + + Joomla.request({ + url: url, + method: 'DELETE', + data: JSON.stringify(data), + headers: {'Content-Type': 'application/json'}, + onSuccess: () => { + notifications.success('COM_MEDIA_DELETE_SUCCESS'); + resolve(); + }, + onError: (xhr) => { + notifications.error('COM_MEDIA_DELETE_ERROR'); + reject(xhr); + } + }); + }).catch(this._handleError); + } + + /** + * Normalize a single item + * @param item + * @returns {*} + * @private + */ + _normalizeItem(item) { + if (item.type === 'dir') { + item.directories = []; + item.files = []; + } + + item.directory = path.dirname(item.path); + + if (item.directory.indexOf(':', item.directory.length - 1) !== -1) { + item.directory += '/'; + } + + return item; + } + + /** + * Normalize array data + * @param data + * @returns {{directories, files}} + * @private + */ + _normalizeArray(data) { + const directories = data.filter(item => (item.type === 'dir')) + .map(directory => this._normalizeItem(directory)); + const files = data.filter(item => (item.type === 'file')) + .map(file => this._normalizeItem(file)); + + return { + directories: directories, + files: files, + } + } + + /** + * Handle errors + * @param error + * @private + * + * @TODO DN improve error handling + */ + _handleError(error) { + switch (error.status) { + case 409: + // Handled in consumer + break; + case 404: + notifications.error('COM_MEDIA_ERROR_NOT_FOUND'); + break; + case 401: + notifications.error('COM_MEDIA_ERROR_NOT_AUTHENTICATED'); + break; + case 403: + notifications.error('COM_MEDIA_ERROR_NOT_AUTHORIZED'); + break; + case 500: + notifications.error('COM_MEDIA_SERVER_ERROR'); + break; + default: + notifications.error('COM_MEDIA_ERROR'); + } + + throw error; + } +} + +export let api = new Api(); diff --git a/administrator/components/com_media/resources/scripts/app/Event.js b/administrator/components/com_media/resources/scripts/app/Event.js new file mode 100644 index 0000000000000..4c4d7c3076eb0 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/app/Event.js @@ -0,0 +1,32 @@ +import Vue from "vue"; + +/** + * Media Event bus - used for communication between joomla and vue + */ +export default class Event { + + /** + * Media Event constructor + */ + constructor() { + this.vue = new Vue(); + } + + /** + * Fire an event + * @param event + * @param data + */ + fire(event, data = null) { + this.vue.$emit(event, data); + } + + /** + * Listen to events + * @param event + * @param callback + */ + listen(event, callback) { + this.vue.$on(event, callback); + } +} diff --git a/administrator/components/com_media/resources/scripts/app/Notifications.js b/administrator/components/com_media/resources/scripts/app/Notifications.js new file mode 100644 index 0000000000000..1739f1ee5b6b0 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/app/Notifications.js @@ -0,0 +1,37 @@ +class Notifications { + + /* Send and success notification */ + success(message, options) { + notifications.notify(message, Object.assign({ + type: 'success', + dismiss: true + }, options)); + } + + /* Send an error notification */ + error(message, options) { + notifications.notify(message, Object.assign({ + type: 'danger', + dismiss: true + }, options)); + } + + /* Ask the user a question */ + ask(message, options) { + return window.confirm(message); + } + + /* Send a notification */ + notify(message, options) { + const alert = document.createElement('joomla-alert'); + alert.setAttribute('type', options.type || 'info'); + alert.setAttribute('dismiss', options.dismiss || true); + alert.setAttribute('auto-dismiss', options.autoDismiss || true); + alert.innerHTML = Joomla.JText._(message, message) || ''; + + const messageContainer = document.getElementById('system-message'); + messageContainer.appendChild(alert); + } +} + +export let notifications = new Notifications(); \ No newline at end of file diff --git a/administrator/components/com_media/resources/scripts/components/app.vue b/administrator/components/com_media/resources/scripts/components/app.vue new file mode 100644 index 0000000000000..739cee1d3e0a1 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/app.vue @@ -0,0 +1,66 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/scripts/components/breadcrumb/breadcrumb.vue b/administrator/components/com_media/resources/scripts/components/breadcrumb/breadcrumb.vue new file mode 100644 index 0000000000000..5f8fcbd33692b --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/breadcrumb/breadcrumb.vue @@ -0,0 +1,68 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/scripts/components/browser/browser.vue b/administrator/components/com_media/resources/scripts/components/browser/browser.vue new file mode 100644 index 0000000000000..0d65c2b3d77fc --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/browser/browser.vue @@ -0,0 +1,156 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/browser/items/directory.vue b/administrator/components/com_media/resources/scripts/components/browser/items/directory.vue new file mode 100644 index 0000000000000..d3902a7c5b2fe --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/browser/items/directory.vue @@ -0,0 +1,72 @@ + + diff --git a/administrator/components/com_media/resources/scripts/components/browser/items/file.vue b/administrator/components/com_media/resources/scripts/components/browser/items/file.vue new file mode 100644 index 0000000000000..c66979dd35514 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/browser/items/file.vue @@ -0,0 +1,84 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/browser/items/image.vue b/administrator/components/com_media/resources/scripts/components/browser/items/image.vue new file mode 100644 index 0000000000000..aec1ebb7c8c7f --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/browser/items/image.vue @@ -0,0 +1,114 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/scripts/components/browser/items/item.js b/administrator/components/com_media/resources/scripts/components/browser/items/item.js new file mode 100644 index 0000000000000..7ed31be0b273a --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/browser/items/item.js @@ -0,0 +1,121 @@ +import Directory from "./directory.vue"; +import File from "./file.vue"; +import Image from "./image.vue"; +import Video from "./video.vue"; +import Row from "./row.vue"; +import * as types from "./../../../store/mutation-types"; + +export default { + functional: true, + props: ['item'], + render: function (createElement, context) { + + const store = context.parent.$store; + const item = context.props.item; + + /** + * Return the correct item type component + */ + function itemType() { + if (store.state.listView == 'table') { + return Row; + } + + let imageExtensions = ['jpg', 'jpeg', 'png', 'gif']; + let videoExtensions = ['mp4']; + + // Render directory items + if (item.type === 'dir') return Directory; + + // Render image items + if (item.extension && imageExtensions.indexOf(item.extension.toLowerCase()) !== -1) { + return Image; + } + + // Render video items + if (item.extension && videoExtensions.indexOf(item.extension.toLowerCase()) !== -1) { + return Video; + } + + // Default to file type + return File; + } + + /** + * Get the styles for the media browser item + * @returns {{}} + */ + function styles() { + if (store.state.listView == 'table') { + return {}; + } + + return { + 'width': 'calc(' + store.state.gridSize + '% - 20px)', + }; + } + + /** + * Whether or not the item is currently selected + * @returns {boolean} + */ + function isSelected() { + return store.state.selectedItems.some(selected => selected.path === item.path); + } + + /** + * Handle the click event + * @param event + */ + function handleClick(event) { + let path = false; + const data = { + path: path, + thumb: false, + fileType: item.mime_type ? item.mime_type : false, + extension: item.extension ? item.extension : false, + }; + + if (item.type === 'file') { + data.path = item.path; + data.thumb = item.thumb ? item.thumb : false; + + const ev = new CustomEvent('onMediaFileSelected', {"bubbles":true, "cancelable":false, "detail": data}); + window.parent.document.dispatchEvent(ev); + } + + // Handle clicks when the item was not selected + if (!isSelected()) { + // Unselect all other selected items, if the shift key was not pressed during the click event + if (!(event.shiftKey || event.keyCode === 13)) { + store.commit(types.UNSELECT_ALL_BROWSER_ITEMS); + } + store.commit(types.SELECT_BROWSER_ITEM, item); + return; + } + + // If more than one item was selected and the user clicks again on the selected item, + // he most probably wants to unselect all other items. + if (store.state.selectedItems.length > 1) { + store.commit(types.UNSELECT_ALL_BROWSER_ITEMS); + store.commit(types.SELECT_BROWSER_ITEM, item); + } + } + + return createElement('div', { + 'class': { + 'media-browser-item': true, + selected: isSelected(), + }, + on: { + click: handleClick, + } + }, + [ + createElement(itemType(), { + props: context.props, + }) + ] + ); + } +} diff --git a/administrator/components/com_media/resources/scripts/components/browser/items/row.vue b/administrator/components/com_media/resources/scripts/components/browser/items/row.vue new file mode 100644 index 0000000000000..e8c1b1af80e62 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/browser/items/row.vue @@ -0,0 +1,62 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/browser/items/video.vue b/administrator/components/com_media/resources/scripts/components/browser/items/video.vue new file mode 100644 index 0000000000000..bf18c0e8fe414 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/browser/items/video.vue @@ -0,0 +1,90 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/infobar/infobar.vue b/administrator/components/com_media/resources/scripts/components/infobar/infobar.vue new file mode 100644 index 0000000000000..e0af862215f64 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/infobar/infobar.vue @@ -0,0 +1,76 @@ + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/scripts/components/modals/confirm-delete-modal.vue b/administrator/components/com_media/resources/scripts/components/modals/confirm-delete-modal.vue new file mode 100644 index 0000000000000..14f9a1badf92c --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/modals/confirm-delete-modal.vue @@ -0,0 +1,39 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/modals/create-folder-modal.vue b/administrator/components/com_media/resources/scripts/components/modals/create-folder-modal.vue new file mode 100644 index 0000000000000..fbaad34e93015 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/modals/create-folder-modal.vue @@ -0,0 +1,66 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/modals/modal.vue b/administrator/components/com_media/resources/scripts/components/modals/modal.vue new file mode 100644 index 0000000000000..2a25ea8fe347f --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/modals/modal.vue @@ -0,0 +1,71 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/scripts/components/modals/preview-modal.vue b/administrator/components/com_media/resources/scripts/components/modals/preview-modal.vue new file mode 100644 index 0000000000000..c6e7d1a0ab8cd --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/modals/preview-modal.vue @@ -0,0 +1,42 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/modals/rename-modal.vue b/administrator/components/com_media/resources/scripts/components/modals/rename-modal.vue new file mode 100644 index 0000000000000..a475275497f28 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/modals/rename-modal.vue @@ -0,0 +1,99 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/modals/share-modal.vue b/administrator/components/com_media/resources/scripts/components/modals/share-modal.vue new file mode 100644 index 0000000000000..17e2a4a559abf --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/modals/share-modal.vue @@ -0,0 +1,74 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/toolbar/toolbar.vue b/administrator/components/com_media/resources/scripts/components/toolbar/toolbar.vue new file mode 100644 index 0000000000000..f80f2b2821301 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/toolbar/toolbar.vue @@ -0,0 +1,109 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/tree/disk.vue b/administrator/components/com_media/resources/scripts/components/tree/disk.vue new file mode 100644 index 0000000000000..193eb6eb19837 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/tree/disk.vue @@ -0,0 +1,13 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/tree/drive.vue b/administrator/components/com_media/resources/scripts/components/tree/drive.vue new file mode 100644 index 0000000000000..8c11770800b26 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/tree/drive.vue @@ -0,0 +1,22 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/tree/item.vue b/administrator/components/com_media/resources/scripts/components/tree/item.vue new file mode 100644 index 0000000000000..62895e66ed868 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/tree/item.vue @@ -0,0 +1,48 @@ + + + diff --git a/administrator/components/com_media/resources/scripts/components/tree/tree.vue b/administrator/components/com_media/resources/scripts/components/tree/tree.vue new file mode 100644 index 0000000000000..b5a6ef45a8cf2 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/tree/tree.vue @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/scripts/components/upload/upload.vue b/administrator/components/com_media/resources/scripts/components/upload/upload.vue new file mode 100644 index 0000000000000..579c749c0dfe5 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/components/upload/upload.vue @@ -0,0 +1,67 @@ + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/scripts/mediamanager.js b/administrator/components/com_media/resources/scripts/mediamanager.js new file mode 100644 index 0000000000000..e16264b7ae466 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/mediamanager.js @@ -0,0 +1,56 @@ +import Vue from "vue"; +import Event from './app/Event'; +import App from "./components/app.vue"; +import Disk from "./components/tree/disk.vue"; +import Drive from "./components/tree/drive.vue"; +import Tree from "./components/tree/tree.vue"; +import TreeItem from "./components/tree/item.vue"; +import Toolbar from "./components/toolbar/toolbar.vue"; +import Breadcrumb from "./components/breadcrumb/breadcrumb.vue"; +import Browser from "./components/browser/browser.vue"; +import BrowserItem from "./components/browser/items/item"; +import Modal from "./components/modals/modal.vue"; +import CreateFolderModal from "./components/modals/create-folder-modal.vue"; +import PreviewModal from "./components/modals/preview-modal.vue"; +import RenameModal from "./components/modals/rename-modal.vue"; +import ShareModal from "./components/modals/share-modal.vue"; +import ConfirmDeleteModal from "./components/modals/confirm-delete-modal.vue"; +import Infobar from "./components/infobar/infobar.vue"; +import Upload from "./components/upload/upload.vue"; +import Translate from "./plugins/translate"; +import store from './store/store'; + +// Add the plugins +Vue.use(Translate); + +// Register the vue components +Vue.component('media-drive', Drive); +Vue.component('media-disk', Disk); +Vue.component('media-tree', Tree); +Vue.component('media-tree-item', TreeItem); +Vue.component('media-toolbar', Toolbar); +Vue.component('media-breadcrumb', Breadcrumb); +Vue.component('media-browser', Browser); +Vue.component('media-browser-item', BrowserItem); +Vue.component('media-modal', Modal); +Vue.component('media-create-folder-modal', CreateFolderModal); +Vue.component('media-preview-modal', PreviewModal); +Vue.component('media-rename-modal', RenameModal); +Vue.component('media-share-modal', ShareModal); +Vue.component('media-confirm-delete-modal', ConfirmDeleteModal); +Vue.component('media-infobar', Infobar); +Vue.component('media-upload', Upload); + +// Register MediaManager namespace +window.MediaManager = window.MediaManager || {}; +// Register the media manager event bus +window.MediaManager.Event = new Event(); + +// Create the root Vue instance +document.addEventListener("DOMContentLoaded", + (e) => new Vue({ + el: '#com-media', + store, + render: h => h(App) + }) +) diff --git a/administrator/components/com_media/resources/scripts/mixins/navigable.js b/administrator/components/com_media/resources/scripts/mixins/navigable.js new file mode 100644 index 0000000000000..5ba9542a9f960 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/mixins/navigable.js @@ -0,0 +1,7 @@ +export default { + methods: { + navigateTo: function (path) { + this.$store.dispatch('getContents', path); + } + } +} diff --git a/administrator/components/com_media/resources/scripts/plugins/translate.js b/administrator/components/com_media/resources/scripts/plugins/translate.js new file mode 100644 index 0000000000000..e122b7adc5a91 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/plugins/translate.js @@ -0,0 +1,40 @@ +/** + * Translate plugin + */ + +let Translate = {}; + +Translate.translate = function (key) { + // Translate from Joomla text + return Joomla.JText._(key, key); +} + + +Translate.sprintf = function (string, ...args) { + string = this.translate(string); + var i = 0; + return string.replace(/%((%)|s|d)/g, function (m) { + var val = args[i]; + + if (m == '%d') { + val = parseFloat(val); + if (isNaN(val)) { + val = 0; + } + } + i++; + return val; + }); +} + +Translate.install = function (Vue, options) { + Vue.mixin({ + methods: { + translate: function (key) { + return Translate.translate(key); + } + } + }) +} + +export default Translate; diff --git a/administrator/components/com_media/resources/scripts/store/actions.js b/administrator/components/com_media/resources/scripts/store/actions.js new file mode 100644 index 0000000000000..a693f327880dd --- /dev/null +++ b/administrator/components/com_media/resources/scripts/store/actions.js @@ -0,0 +1,235 @@ +import {api} from "../app/Api"; +import * as types from "./mutation-types"; +import translate from "../plugins/translate"; +import {notifications} from "../app/Notifications"; +import * as FileSaver from './../../../node_modules/file-saver/FileSaver'; + +// Actions are similar to mutations, the difference being that: +// - Instead of mutating the state, actions commit mutations. +// - Actions can contain arbitrary asynchronous operations. + +// TODO move to utils +function updateUrlPath(path) { + if (path == null) { + path = ''; + } + let url = window.location.href; + var pattern = new RegExp('\\b(path=).*?(&|$)'); + + if (url.search(pattern) >= 0) { + history.pushState(null, '', url.replace(pattern, '$1' + path + '$2')); + } else { + history.pushState(null, '', url + (url.indexOf('?') > 0 ? '&' : '?') + 'path=' + path); + } +} + +/** + * Get contents of a directory from the api + * @param commit + * @param payload + */ +export const getContents = (context, payload) => { + + // Update the url + updateUrlPath(payload); + context.commit(types.SET_IS_LOADING, true); + + api.getContents(payload, 0) + .then(contents => { + context.commit(types.LOAD_CONTENTS_SUCCESS, contents); + context.commit(types.UNSELECT_ALL_BROWSER_ITEMS); + context.commit(types.SELECT_DIRECTORY, payload); + context.commit(types.SET_IS_LOADING, false); + }) + .catch(error => { + // TODO error handling + context.commit(types.SET_IS_LOADING, false); + console.log("error", error); + }); +} + +/** + * Get the full contents of a directory + * @param context + * @param payload + */ +export const getFullContents = (context, payload) => { + context.commit(types.SET_IS_LOADING, true); + api.getContents(payload.path, 1) + .then(contents => { + context.commit(types.LOAD_FULL_CONTENTS_SUCCESS, contents.files[0]); + context.commit(types.SET_IS_LOADING, false); + }) + .catch(error => { + // TODO error handling + context.commit(types.SET_IS_LOADING, false); + console.log("error", error); + }); +} + +/** + * Download a file + * @param context + * @param payload + */ +export const download = (context, payload) => { + api.getContents(payload.path, 0, 1) + .then(contents => { + var file = contents.files[0]; + + // Converte the base 64 encoded string to a blob + var byteCharacters = atob(file.content); + var byteArrays = []; + + for (var offset = 0; offset < byteCharacters.length; offset += 512) { + var slice = byteCharacters.slice(offset, offset + 512); + + var byteNumbers = new Array(slice.length); + for (var i = 0; i < slice.length; i++) { + byteNumbers[i] = slice.charCodeAt(i); + } + + var byteArray = new Uint8Array(byteNumbers); + + byteArrays.push(byteArray); + } + + // Open the save as file dialog + FileSaver.saveAs(new Blob(byteArrays, {type: file.mime_type}), file.name); + }) + .catch(error => { + console.log("error", error); + }); +} + +/** + * Toggle the selection state of an item + * @param commit + * @param payload + */ +export const toggleBrowserItemSelect = (context, payload) => { + const item = payload; + const isSelected = context.state.selectedItems.some(selected => selected.path === item.path); + if (!isSelected) { + context.commit(types.SELECT_BROWSER_ITEM, item); + } else { + context.commit(types.UNSELECT_BROWSER_ITEM, item); + } +} + +/** + * Create a new folder + * @param commit + * @param payload object with the new folder name and its parent directory + */ +export const createDirectory = (context, payload) => { + context.commit(types.SET_IS_LOADING, true); + api.createDirectory(payload.name, payload.parent) + .then(folder => { + context.commit(types.CREATE_DIRECTORY_SUCCESS, folder); + context.commit(types.HIDE_CREATE_FOLDER_MODAL); + context.commit(types.SET_IS_LOADING, false); + }) + .catch(error => { + // TODO error handling + context.commit(types.SET_IS_LOADING, false); + console.log("error", error); + }) +} + +/** + * Create a new folder + * @param commit + * @param payload object with the new folder name and its parent directory + */ +export const uploadFile = (context, payload) => { + context.commit(types.SET_IS_LOADING, true); + api.upload(payload.name, payload.parent, payload.content, payload.override || false) + .then(file => { + context.commit(types.UPLOAD_SUCCESS, file); + context.commit(types.SET_IS_LOADING, false); + }) + .catch(error => { + context.commit(types.SET_IS_LOADING, false); + + // Handle file exists + if (error.status === 409) { + if (notifications.ask(translate.sprintf('COM_MEDIA_FILE_EXISTS_AND_OVERRIDE', payload.name), {})) { + payload.override = true; + uploadFile(context, payload); + } + } + }) +} + +/** + * Delete a single item + * @param context + * @param payload object: the item to delete + */ +export const deleteItem = (context, payload) => { + context.commit(types.SET_IS_LOADING, true); + const item = payload; + api.delete(item.path) + .then(() => { + context.commit(types.DELETE_SUCCESS, item); + context.commit(types.UNSELECT_ALL_BROWSER_ITEMS); + context.commit(types.SET_IS_LOADING, false); + }) + .catch(error => { + // TODO error handling + context.commit(types.SET_IS_LOADING, false); + console.log("error", error); + }) +} + +/** + * Rename an item + * @param context + * @param payload object: the old and the new path + */ +export const renameItem = (context, payload) => { + context.commit(types.SET_IS_LOADING, true); + api.rename(payload.path, payload.newPath) + .then((item) => { + context.commit(types.RENAME_SUCCESS, { + item: item, + oldPath: payload.path, + }); + context.commit(types.HIDE_RENAME_MODAL); + context.commit(types.SET_IS_LOADING, false); + }) + .catch(error => { + // TODO error handling + context.commit(types.SET_IS_LOADING, false); + console.log("error", error); + }) +} + +/** + * Delete the selected items + * @param context + * @param payload object + */ +export const deleteSelectedItems = (context, payload) => { + context.commit(types.SET_IS_LOADING, true); + // Get the selected items from the store + const selectedItems = context.state.selectedItems; + if (selectedItems.length > 0) { + selectedItems.forEach(item => { + api.delete(item.path) + .then(() => { + context.commit(types.DELETE_SUCCESS, item); + context.commit(types.UNSELECT_ALL_BROWSER_ITEMS); + context.commit(types.SET_IS_LOADING, false); + }) + .catch(error => { + // TODO error handling + context.commit(types.SET_IS_LOADING, false); + console.log("error", error); + }) + }) + } else { + // TODO notify the user that he has to select at least one item + } +} diff --git a/administrator/components/com_media/resources/scripts/store/getters.js b/administrator/components/com_media/resources/scripts/store/getters.js new file mode 100644 index 0000000000000..809a808d7656e --- /dev/null +++ b/administrator/components/com_media/resources/scripts/store/getters.js @@ -0,0 +1,48 @@ +// Sometimes we may need to compute derived state based on store state, +// for example filtering through a list of items and counting them. + +/** + * Get the currently selected directory + * @param state + * @returns {*} + */ +export const getSelectedDirectory = (state) => { + return state.directories.find(directory => (directory.path === state.selectedDirectory)); +} + +/** + * Get the sudirectories of the currently selected directory + * @param state + * @param getters + * @returns {Array|directories|{/}|computed.directories|*|Object} + */ +export const getSelectedDirectoryDirectories = (state, getters) => { + return state.directories.filter( + directory => (directory.directory === state.selectedDirectory) + ); +} + +/** + * Get the files of the currently selected directory + * @param state + * @param getters + * @returns {Array|files|{}|FileList|*} + */ +export const getSelectedDirectoryFiles = (state, getters) => { + return state.files.filter( + file => (file.directory === state.selectedDirectory) + ); +} + +/** + * Whether or not all items of the current directory are selected + * @param state + * @param getters + * @returns Array + */ +export const getSelectedDirectoryContents = (state, getters) => { + return [ + ...getters.getSelectedDirectoryDirectories, + ...getters.getSelectedDirectoryFiles, + ]; +} diff --git a/administrator/components/com_media/resources/scripts/store/mutation-types.js b/administrator/components/com_media/resources/scripts/store/mutation-types.js new file mode 100644 index 0000000000000..7d5f9e86131dd --- /dev/null +++ b/administrator/components/com_media/resources/scripts/store/mutation-types.js @@ -0,0 +1,52 @@ +// Loading state +export const SET_IS_LOADING = 'SET_IS_LOADING'; + +// Selecting media items +export const SELECT_DIRECTORY = 'SELECT_DIRECTORY'; +export const SELECT_BROWSER_ITEM = 'SELECT_BROWSER_ITEM'; +export const SELECT_BROWSER_ITEMS = 'SELECT_BROWSER_ITEMS'; +export const UNSELECT_BROWSER_ITEM = 'UNSELECT_BROWSER_ITEM'; +export const UNSELECT_ALL_BROWSER_ITEMS = 'UNSELECT_ALL_BROWSER_ITEMS'; + +// In/Decrease grid item size +export const INCREASE_GRID_SIZE = 'INCREASE_GRID_SIZE'; +export const DECREASE_GRID_SIZE = 'DECREASE_GRID_SIZE'; + +// Api handlers +export const LOAD_CONTENTS_SUCCESS = 'LOAD_CONTENTS_SUCCESS'; +export const LOAD_FULL_CONTENTS_SUCCESS = 'LOAD_FULL_CONTENTS_SUCCESS'; +export const CREATE_DIRECTORY_SUCCESS = 'CREATE_DIRECTORY_SUCCESS'; +export const UPLOAD_SUCCESS = 'UPLOAD_SUCCESS'; + +// Create folder modal +export const SHOW_CREATE_FOLDER_MODAL = 'SHOW_CREATE_FOLDER_MODAL'; +export const HIDE_CREATE_FOLDER_MODAL = 'HIDE_CREATE_FOLDER_MODAL'; + +// Confirm Delete Modal +export const SHOW_CONFIRM_DELETE_MODAL = 'SHOW_CONFIRM_DELETE_MODAL'; +export const HIDE_CONFIRM_DELETE_MODAL = 'HIDE_CONFIRM_DELETE_MODAL'; + +// Infobar +export const SHOW_INFOBAR = 'SHOW_INFOBAR'; +export const HIDE_INFOBAR = 'HIDE_INFOBAR'; + +// Delete items +export const DELETE_SUCCESS = 'DELETE_SUCCESS'; + +// List view +export const CHANGE_LIST_VIEW = 'CHANGE_LIST_VIEW'; + +// Preview modal +export const SHOW_PREVIEW_MODAL = 'SHOW_PREVIEW_MODAL'; +export const HIDE_PREVIEW_MODAL = 'HIDE_PREVIEW_MODAL'; + +// Rename modal +export const SHOW_RENAME_MODAL = 'SHOW_RENAME_MODAL'; +export const HIDE_RENAME_MODAL = 'HIDE_RENAME_MODAL'; +export const RENAME_SUCCESS = 'RENAME_SUCCESS'; + +// Share model +export const SHOW_SHARE_MODAL = 'SHOW_SHARE_MODAL'; +export const HIDE_SHARE_MODAL = 'HIDE_SHARE_MODAL'; +// Search Query +export const SET_SEARCH_QUERY = 'SET_SEARCH_QUERY'; diff --git a/administrator/components/com_media/resources/scripts/store/mutations.js b/administrator/components/com_media/resources/scripts/store/mutations.js new file mode 100644 index 0000000000000..4586cabcafad6 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/store/mutations.js @@ -0,0 +1,415 @@ +import * as types from "./mutation-types"; + +const nodePath = require('path'); + +// The only way to actually change state in a store is by committing a mutation. +// Mutations are very similar to events: each mutation has a string type and a handler. +// The handler function is where we perform actual state modifications, and it will receive the state as the first argument. + +// The grid item sizes +const gridItemSizes = ['xs', 'sm', 'md', 'lg', 'xl']; + +export default { + + /** + * Select a directory + * @param state + * @param payload + */ + [types.SELECT_DIRECTORY]: (state, payload) => { + state.selectedDirectory = payload; + }, + + /** + * The load content success mutation + * @param state + * @param payload + */ + [types.LOAD_CONTENTS_SUCCESS]: (state, payload) => { + + /** + * Create the directory structure + * @param path + */ + function createDirectoryStructureFromPath(path) { + const exists = state.directories.some(existing => (existing.path === path)); + if (!exists) { + const directory = directoryFromPath(path); + + // Add the sub directories and files + directory.directories = state.directories + .filter((existing) => existing.directory === directory.path) + .map((existing) => existing.path); + + // Add the directory + state.directories.push(directory); + + if (directory.directory) { + createDirectoryStructureFromPath(directory.directory); + } + } + } + + /** + * Create a directory from a path + * @param path + */ + function directoryFromPath(path) { + const parts = path.split('/'); + let directory = nodePath.dirname(path); + if (directory.indexOf(':', directory.length - 1) !== -1) { + directory += '/'; + } + return { + path: path, + name: parts[parts.length - 1], + directories: [], + files: [], + directory: (directory !== '.') ? directory : null, + type: 'dir', + mime_type: 'directory', + } + } + + /** + * Add a directory + * @param state + * @param directory + */ + function addDirectory(state, directory) { + const parentDirectory = state.directories.find((existing) => (existing.path === directory.directory)); + const parentDirectoryIndex = state.directories.indexOf(parentDirectory); + let index = state.directories.findIndex((existing) => (existing.path === directory.path)); + if (index === -1) { + index = state.directories.length; + } + + // Add the directory + state.directories.splice(index, 1, directory); + + // Update the relation to the parent directory + if (parentDirectoryIndex !== -1) { + state.directories.splice(parentDirectoryIndex, 1, Object.assign({}, parentDirectory, { + directories: [...parentDirectory.directories, directory.path] + })); + } + } + + /** + * Add a file + * @param state + * @param directory + */ + function addFile(state, file) { + const parentDirectory = state.directories.find((directory) => (directory.path === file.directory)); + const parentDirectoryIndex = state.directories.indexOf(parentDirectory); + let index = state.files.findIndex((existing) => (existing.path === file.path)); + if (index === -1) { + index = state.files.length; + } + + // Add the file + state.files.splice(index, 1, file); + + // Update the relation to the parent directory + if (parentDirectoryIndex !== -1) { + state.directories.splice(parentDirectoryIndex, 1, Object.assign({}, parentDirectory, { + files: [...parentDirectory.files, file.path] + })); + } + } + + // Create the parent directory structure if it does not exist + createDirectoryStructureFromPath(state.selectedDirectory); + + // Add directories + payload.directories.forEach((directory) => { + addDirectory(state, directory); + }); + + // Add files + payload.files.forEach((file) => { + addFile(state, file); + }); + }, + + /** + * The upload success mutation + * @param state + * @param payload + */ + [types.UPLOAD_SUCCESS]: (state, payload) => { + const file = payload; + const isNew = (!state.files.some(existing => (existing.path === file.path))); + + // TODO handle file_exists + if (isNew) { + const parentDirectory = state.directories.find((existing) => (existing.path === file.directory)); + const parentDirectoryIndex = state.directories.indexOf(parentDirectory); + + // Add the new file to the files array + state.files.push(file); + + // Update the relation to the parent directory + state.directories.splice(parentDirectoryIndex, 1, Object.assign({}, parentDirectory, { + files: [...parentDirectory.files, file.path] + })); + } + }, + + /** + * The create directory success mutation + * @param state + * @param payload + */ + [types.CREATE_DIRECTORY_SUCCESS]: (state, payload) => { + + const directory = payload; + const isNew = (!state.directories.some(existing => (existing.path === directory.path))); + + if (isNew) { + const parentDirectory = state.directories.find((existing) => (existing.path === directory.directory)); + const parentDirectoryIndex = state.directories.indexOf(parentDirectory); + + // Add the new directory to the directory + state.directories.push(directory); + + // Update the relation to the parent directory + state.directories.splice(parentDirectoryIndex, 1, Object.assign({}, parentDirectory, { + directories: [...parentDirectory.directories, directory.path] + })); + } + }, + + /** + * The rename success handler + * @param state + * @param payload + */ + [types.RENAME_SUCCESS]: (state, payload) => { + + const item = payload.item; + const oldPath = payload.oldPath; + if (item.type === 'file') { + const index = state.files.findIndex((file) => (file.path === oldPath)); + state.files.splice(index, 1, item) + } else { + const index = state.directories.findIndex((directory) => (directory.path === oldPath)); + state.directories.splice(index, 1, item) + } + }, + + /** + * The delete success mutation + * @param state + * @param payload + */ + [types.DELETE_SUCCESS]: (state, payload) => { + const item = payload; + + // Delete file + if (item.type === 'file') { + state.files.splice(state.files.findIndex( + file => file.path === item.path + ), 1); + } + + // Delete dir + if (item.type === 'dir') { + state.directories.splice(state.directories.findIndex( + directory => directory.path === item.path + ), 1); + } + }, + + /** + * Select a browser item + * @param state + * @param payload the item + */ + [types.SELECT_BROWSER_ITEM]: (state, payload) => { + state.selectedItems.push(payload); + }, + + /** + * Select browser items + * @param state + * @param payload the items + */ + [types.SELECT_BROWSER_ITEMS]: (state, payload) => { + state.selectedItems = payload; + }, + + /** + * Unselect a browser item + * @param state + * @param payload the item + */ + [types.UNSELECT_BROWSER_ITEM]: (state, payload) => { + const item = payload; + state.selectedItems.splice(state.selectedItems.findIndex( + selectedItem => selectedItem.path === item.path + ), 1); + }, + + /** + * Unselect all browser items + * @param state + * @param payload the item + */ + [types.UNSELECT_ALL_BROWSER_ITEMS]: (state, payload) => { + state.selectedItems = []; + }, + + /** + * Show the create folder modal + * @param state + */ + [types.SHOW_CREATE_FOLDER_MODAL]: (state) => { + state.showCreateFolderModal = true; + }, + + /** + * Hide the create folder modal + * @param state + */ + [types.HIDE_CREATE_FOLDER_MODAL]: (state) => { + state.showCreateFolderModal = false; + }, + + /** + * Show the info bar + * @param state + */ + [types.SHOW_INFOBAR]: (state) => { + state.showInfoBar = true; + }, + + /** + * Show the info bar + * @param state + */ + [types.HIDE_INFOBAR]: (state) => { + state.showInfoBar = false; + }, + + /** + * Define the list grid view + * @param state + */ + [types.CHANGE_LIST_VIEW]: (state, view) => { + state.listView = view; + }, + + /** + * FUll content is loaded + * @param state + * @param payload + */ + [types.LOAD_FULL_CONTENTS_SUCCESS]: (state, payload) => { + state.previewItem = payload; + }, + + /** + * Show the preview modal + * @param state + */ + [types.SHOW_PREVIEW_MODAL]: (state) => { + state.showPreviewModal = true; + }, + + /** + * Hide the preview modal + * @param state + */ + [types.HIDE_PREVIEW_MODAL]: (state) => { + state.showPreviewModal = false; + }, + + /** + * Set the is loading state + * @param state + */ + [types.SET_IS_LOADING]: (state, payload) => { + state.isLoading = payload; + }, + + /** + * Show the rename modal + * @param state + */ + [types.SHOW_RENAME_MODAL]: (state) => { + state.showRenameModal = true; + }, + + /** + * Hide the rename modal + * @param state + */ + [types.HIDE_RENAME_MODAL]: (state) => { + state.showRenameModal = false; + }, + + /** + * Show the share modal + * @param state + */ + [types.SHOW_SHARE_MODAL]: (state) => { + state.showShareModal = true; + }, + + /** + * Hide the share modal + * @param state + */ + [types.HIDE_SHARE_MODAL]: (state) => { + state.showShareModal = false; + }, + + /** + * Increase the size of the grid items + * @param state + */ + [types.INCREASE_GRID_SIZE]: (state) => { + let currentSizeIndex = gridItemSizes.indexOf(state.gridSize); + if (currentSizeIndex >= 0 && currentSizeIndex < gridItemSizes.length - 1) { + state.gridSize = gridItemSizes[++currentSizeIndex]; + } + }, + + /** + * Increase the size of the grid items + * @param state + */ + [types.DECREASE_GRID_SIZE]: (state) => { + let currentSizeIndex = gridItemSizes.indexOf(state.gridSize); + if (currentSizeIndex > 0 && currentSizeIndex < gridItemSizes.length) { + state.gridSize = gridItemSizes[--currentSizeIndex]; + } + }, + + /** + * Set search query + * @param state + * @param query + */ + [types.SET_SEARCH_QUERY]: (state, query) => { + state.search = query; + }, + + /** + * Show the confirm modal + * @param state + */ + [types.SHOW_CONFIRM_DELETE_MODAL]: (state) => { + state.showConfirmDeleteModal = true; + }, + + /** + * Hide the confirm modal + * @param state + */ + [types.HIDE_CONFIRM_DELETE_MODAL]: (state) => { + state.showConfirmDeleteModal = false; + }, +} diff --git a/administrator/components/com_media/resources/scripts/store/plugins/persisted-state.js b/administrator/components/com_media/resources/scripts/store/plugins/persisted-state.js new file mode 100644 index 0000000000000..70fe40fe79971 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/store/plugins/persisted-state.js @@ -0,0 +1,11 @@ +// The options for persisting state +export const persistedStateOptions = { + key: 'joomla.mediamanager', + paths: [ + 'selectedDirectory', + 'showInfoBar', + 'listView', + 'gridSize', + ], + storage: window.sessionStorage, +}; \ No newline at end of file diff --git a/administrator/components/com_media/resources/scripts/store/state.js b/administrator/components/com_media/resources/scripts/store/state.js new file mode 100644 index 0000000000000..4979e0f2fbaa8 --- /dev/null +++ b/administrator/components/com_media/resources/scripts/store/state.js @@ -0,0 +1,77 @@ +import {persistedStateOptions} from "./plugins/persisted-state"; + +// Get the disks from joomla option storage +const options = Joomla.getOptions('com_media', {}); +if (options.providers === undefined || options.providers.length === 0) { + throw new TypeError('Media providers are not defined.'); +} + +// Load disks from options +let loadedDisks = options.providers.map((disk) => { + return { + displayName: disk.displayName, + drives: disk.adapterNames.map( + (account, index) => { + return {root: disk.name + '-' + index + ':/', displayName: account,} + } + ), + } +}); + +if (loadedDisks[0].drives[0] === undefined || loadedDisks[0].drives.length === 0) { + throw new TypeError("No default media drive was found"); +} + +// Override the storage if we have a path +if (options.currentPath) { + const storedState = JSON.parse(persistedStateOptions.storage.getItem(persistedStateOptions.key)); + if (storedState && storedState.selectedDirectory && (storedState.selectedDirectory !== options.currentPath)) { + storedState.selectedDirectory = options.currentPath; + persistedStateOptions.storage.setItem(persistedStateOptions.key, JSON.stringify(storedState)); + } +} + +// The initial state +export default { + // The general loading state + isLoading: false, + // Will hold the activated filesystem disks + disks: loadedDisks, + // The loaded directories + directories: loadedDisks.map((disk) => { + return { + path: disk.drives[0].root, + name: disk.displayName, + directories: [], + files: [], + directory: null + } + }), + // The loaded files + files: [], + // The selected disk. Providers are ordered by plugin ordering, so we set the first provider + // in the list as the default provider and load first drive on it as default + selectedDirectory: options.currentPath || loadedDisks[0].drives[0].root, + // The currently selected items + selectedItems: [], + // The state of the infobar + showInfoBar: false, + // List view + listView: 'grid', + // The size of the grid items + gridSize: 'md', + // The state of confirm delete model + showConfirmDeleteModal: false, + // The state of create folder model + showCreateFolderModal: false, + // The state of preview model + showPreviewModal: false, + // The state of share model + showShareModal: false, + // The state of model + showRenameModal: false, + // The preview item + previewItem: null, + // The Search Query + search: '', +} diff --git a/administrator/components/com_media/resources/scripts/store/store.js b/administrator/components/com_media/resources/scripts/store/store.js new file mode 100644 index 0000000000000..9f4670e4455fc --- /dev/null +++ b/administrator/components/com_media/resources/scripts/store/store.js @@ -0,0 +1,20 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import state from './state'; +import * as getters from './getters'; +import * as actions from './actions'; +import mutations from './mutations'; +import createPersistedState from 'vuex-persistedstate' +import {persistedStateOptions} from "./plugins/persisted-state"; + +Vue.use(Vuex); + +// A Vuex instance is created by combining the state, mutations, actions, and getters. +export default new Vuex.Store({ + state, + getters, + actions, + mutations, + plugins: [createPersistedState(persistedStateOptions)], + strict: false +}) \ No newline at end of file diff --git a/administrator/components/com_media/resources/styles/components/_animations.scss b/administrator/components/com_media/resources/styles/components/_animations.scss new file mode 100644 index 0000000000000..7460a6eb0a116 --- /dev/null +++ b/administrator/components/com_media/resources/styles/components/_animations.scss @@ -0,0 +1,54 @@ +/* Animations */ + +// slide-fade +.slide-fade-enter-active { + transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1); +} + +.slide-fade-leave-active { + transition: all .2s cubic-bezier(0.4, 0.0, 0.2, 1); +} + +.slide-fade-enter, .slide-fade-leave-to { + transform: translateY(-10px); + opacity: 0; +} + +// Infobar +.infobar-enter-active { + animation: slideOutRight .2s reverse; +} + +.infobar-leave-active { + animation: slideOutRight .2s; +} + +// Slide out right animation +@keyframes slideOutRight { + from { + transform: translate3d(0, 0, 0); + } + + to { + visibility: hidden; + transform: translate3d(100%, 0, 0); + } +} + +// Bounce in animation +.fade-in-enter-active { + animation: fadeIn .2s; +} + +.fade-in-leave-active { + animation: fadeIn .2s reverse; +} + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} \ No newline at end of file diff --git a/administrator/components/com_media/resources/styles/components/_layout.scss b/administrator/components/com_media/resources/styles/components/_layout.scss new file mode 100644 index 0000000000000..2dc95a04e4a95 --- /dev/null +++ b/administrator/components/com_media/resources/styles/components/_layout.scss @@ -0,0 +1,47 @@ +/* General layout */ +.media-container { + display: flex; + flex-wrap: wrap; + margin-right: -($col-gutter-width / 2); + margin-left: -($col-gutter-width / 2); +} + +.media-col-main-panel { + flex: 0 0 $col-main-panel-width; + max-width: $col-main-panel-width; +} + +.media-col-side-panel { + flex: 0 0 $col-side-panel-width; + max-width: $col-side-panel-width; +} + +[class^='media-col'], [class*=' media-col'] { + position: relative; + width: 100%; + min-height: 1px; + padding-right: ($col-gutter-width / 2); + padding-left: ($col-gutter-width / 2); +} + +@media (min-width: 768px) { + [class^='media-col'], [class*=' media-col'] { + flex: 0 0 100%; + max-width: 100%; + } +} + +.media-main { + position: relative; + height: calc(100vh - 160px); + overflow: hidden; + background-color: #fff; + border: 1px solid $border-color; + border-radius: $border-radius; + box-shadow: $col-box-shadow; +} + +.media-sidebar { + height: calc(100vh - 160px); + overflow-y: auto; +} \ No newline at end of file diff --git a/administrator/components/com_media/resources/styles/components/_media-breadcrumb.scss b/administrator/components/com_media/resources/styles/components/_media-breadcrumb.scss new file mode 100644 index 0000000000000..c9271c9bf1496 --- /dev/null +++ b/administrator/components/com_media/resources/styles/components/_media-breadcrumb.scss @@ -0,0 +1,59 @@ +.media-breadcrumb { + display: flex; + padding: 0; + margin: 0 auto 0 0; + font-size: .9rem; + line-height: $toolbar-height; + list-style: outside none none; + background: transparent; + border-left: 1px solid $border-color; + & > li > a { + cursor: pointer; + } +} + +.media-breadcrumb-item { + padding: 0 8px 0 22px; + background-color: $breadcrumbs-bg; + &:first-of-type { + padding-left: 16px; + } + &:last-of-type { + background-color: $breadcrumbs-current-bg; + &::after { + border-left-color: $breadcrumbs-current-bg; + } + } + &:hover { + color: $highlight-color; + } +} + +.media-breadcrumb-item { + position: relative; + &::before, &::after { + position: absolute; + top: 0; + bottom: 0; + left: 100%; + z-index: 2; + display: block; + width: 0; + height: 0; + margin: auto; + content: "" !important; + border-top: 23px solid transparent; + border-bottom: 23px solid transparent; + border-left: 10px solid transparent; + } + &::before { + border-left-color: $border-color; + } + &::after { + border-left-color: $breadcrumbs-bg; + } +} + +.breadcrumb-item + .breadcrumb-item::before { + display: none; +} diff --git a/administrator/components/com_media/resources/styles/components/_media-browser.scss b/administrator/components/com_media/resources/styles/components/_media-browser.scss new file mode 100644 index 0000000000000..1b38cd101c151 --- /dev/null +++ b/administrator/components/com_media/resources/styles/components/_media-browser.scss @@ -0,0 +1,434 @@ +/* Media browser */ +.media-browser { + position: relative; + width: 75%; + height: calc(100vh - 208px); + overflow-y: auto; + transition: width .3s cubic-bezier(.4, .0, .2, 1); +} + +// Grid View +.media-browser-grid { + padding: $grid-outside-padding 0 $grid-outside-padding $grid-outside-padding; +} + +.media-browser-items { + display: flex; + flex-wrap: wrap; +} + +.media-browser-item { + position: relative; + margin-right: $grid-gutter-width; + margin-bottom: $grid-gutter-width; + cursor: pointer; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + .media-browser-items-xs & { + width: calc(#{$grid-item-width-xs} - #{$grid-gutter-width}); + } + .media-browser-items-sm & { + width: calc(#{$grid-item-width-sm} - #{$grid-gutter-width}); + } + .media-browser-items-md & { + width: calc(#{$grid-item-width-md} - #{$grid-gutter-width}); + } + .media-browser-items-lg & { + width: calc(#{$grid-item-width-lg} - #{$grid-gutter-width}); + } + .media-browser-items-xl & { + width: calc(#{$grid-item-width-xl} - #{$grid-gutter-width}); + } +} + +.media-browser-item-preview { + position: relative; + font-size: 60px; + color: #007eb7; + border-radius: $grid-item-border-radius; + &::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + content: ""; + background-color: $grid-item-hover-color; + border-radius: $grid-item-border-radius; + opacity: 0; + transition: opacity .2s cubic-bezier(.4, .0, .2, 1); + .media-browser-item:hover &, .selected & { + opacity: 1; + } + } +} + +.media-browser-item-info { + padding: 0 2px; + font-size: .9rem; + line-height: 28px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.media-browser-select { + position: absolute; + top: 6px; + left: 6px; + width: calc(#{$grid-item-icon-size} * 1.54); + height: calc(#{$grid-item-icon-size} * 1.54); + content: ""; + background-color: $grid-item-icon-bg-color; + border: 2px solid $grid-item-icon-bg-color-hover; + border-radius: $grid-item-border-radius; + box-shadow: inset 0 0 0 0 $grid-item-icon-color; + opacity: 0; + transition: all .3s cubic-bezier(.4, .0, .2, 1); + .media-browser-item:hover & { + opacity: 1; + } + &::after { + position: absolute; + top: 0; + left: 0; + width: calc(#{$grid-item-icon-size} * 1.3); + content: "\f00c"; + font-family: FontAwesome; + font-size: $grid-item-icon-size; + height: calc(#{$grid-item-icon-size} * 1.3); + line-height: calc(#{$grid-item-icon-size} * 1.3); + text-align: center; + transform: scale(.5); + opacity: 0; + transition: all .3s cubic-bezier(.4, .0, .2, 1); + .selected & { + transform: scale(1); + opacity: 1; + } + } + .selected & { + color: $grid-item-icon-color-hover; + background-color: $grid-item-icon-bg-color-hover; + box-shadow: inset 0 0 0 15px $grid-item-icon-bg-color-hover; + opacity: 1; + } +} + +.media-browser-actions { + position: absolute; + right: 0; + top: 4px; + padding: 2px; + overflow: hidden; + > a { + opacity: 0; + .media-browser-item:hover & { + opacity: 1; + } + } + &.active { + > a { + display: none; + } + } +} + +.media-browser-actions-list { + display: flex; + flex-direction: column; + a { + position: relative; + top: 0; + margin-bottom: 3px; + opacity: 0; + transition: all 0s ease; + transition-delay: 0s; + visibility: hidden; + .media-browser-actions.active & { + top: 0; + opacity: 1; + visibility: visible; + transition-duration: .2s; + &:first-of-type { + transition-delay: .1s; + } + &:nth-of-type(2) { + transition-delay: .15s; + } + &:nth-of-type(3) { + transition-delay: .2s; + } + &:nth-of-type(4) { + transition-delay: .25s; + } + } + } +} + +.image-browser-action { + width: calc(#{$grid-item-icon-size} * 1.55); + height: calc(#{$grid-item-icon-size} * 1.55); + margin-right: 4px; + margin-left: 4px; + color: $grid-item-icon-color; + text-align: center; + cursor: pointer; + background-color: $grid-item-icon-bg-color; + border-radius: $grid-item-border-radius; + .action-delete & { + background-color: $grid-item-icon-warning-icon-bg; + } + &::before { + font-size: $grid-item-icon-size; + line-height: calc(#{$grid-item-icon-size} * 1.55); + } + &:hover { + color: $grid-item-icon-color-hover; + background-color: $grid-item-icon-bg-color-hover; + } +} + +.image-brackground { + background-color: white; + background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%), linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%); + background-position: 0 0, 10px 10px; + background-size: 20px 20px; +} + +.image-cropped { + padding-bottom: 100%; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + border-radius: $grid-item-border-radius; +} + +.file-background, .folder-background { + padding-bottom: 100%; + background-color: $grid-item-no-preview-bg; + border-radius: $grid-item-border-radius; +} + +.file-icon, .folder-icon { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + align-items: center; + justify-content: center; + color: #bbb; +} + +.media-dragoutline { + position: absolute; + top: 6px; + right: 6px; + bottom: 1px; + left: 6px; + z-index: 1040; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + visibility: hidden; + content: ""; + background-color: $dnd-bg; + border: $dnd-border; + border-radius: $border-radius; + opacity: 0; + transition: all .2s ease; + transition-delay: .2s; + transform: scale(.6); + .upload-icon { + font-size: 8rem; + color: $dnd-icon-color; + opacity: 0; + transition: all .2s ease; + transition-delay: .1s; + transform: translateY(50%); + } + p { + font-size: 1.4rem; + opacity: 0; + transition: all .2s ease; + transition-delay: 0s; + } + &.active { + visibility: visible; + opacity: 1; + transition-delay: 0s; + transform: scale(1); + .upload-icon { + opacity: 1; + transform: translateY(0); + } + p { + opacity: 1; + transition-delay: .2s; + } + } +} + +// Table View +.media-browser-table-head { + font-size: .8rem; + font-weight: bold; + .type { + margin-left: 1px; + &::before { + display: none; + } + } +} + +.media-browser-table { + overflow-y: auto; + font-size: .9rem; + line-height: $table-item-height; + transition: width .3s cubic-bezier(.4, .0, .2, 1); + .media-browser-item { + width: 100%; + margin: 0; + border: 1px solid rgba(0, 0, 0, .03); + &:hover { + background-color: $table-item-bg-hover; + } + } + ul { + display: flex; + padding: 0; + margin: 0; + list-style: none; + } + li { + padding: 0 10px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .name { + width: calc(30% - 40px); + } + .size { + width: 15%; + } + .dimension { + width: 15%; + } + .created { + width: 20%; + } + .modified { + width: 20%; + } + .type { + position: relative; + z-index: 0; + width: calc(#{$table-item-height} + 4px); + padding: 0; + font-size: $table-item-icon-size; + line-height: $table-item-height; + text-align: center; + background-color: $table-item-icon-bg; + border-right: 1px solid rgba(0, 0, 0, .03); + &::before, &::after { + transition: all .2s cubic-bezier(.4, .0, .2, 1); + } + &::before { + font-family: FontAwesome; + color: $table-item-icon-color; + .selected & { + color: $table-item-icon-color-selected; + } + } + &::after { + position: absolute; + top: -1px; + right: 100%; + bottom: -1px; + left: 0; + z-index: -1; + content: ""; + background-color: $table-item-icon-bg-selected; + } + span { + visibility: hidden; + } + } +} + +.selected { + .type { + &::before { + color: #fff; + } + &::after { + right: 0; + } + } +} + +.type { + &[data-type] { + &::before { + content: $icon-type-default; + } + } + // Folder + &[data-type=""] { + &::before { + content: $icon-type-folder; + } + } + // Images + &[data-type="jpg"], + &[data-type="png"], + &[data-type="gif"], + &[data-type="jpeg"], + &[data-type="tiff"], + &[data-type="bmp"], + &[data-type="svg"] { + &::before { + content: $icon-type-images; + } + } + // Video + &[data-type="mov"], + &[data-type="mkv"], + &[data-type="mp4"], + &[data-type="mpg"], + &[data-type="mpeg"] { + &::before { + content: $icon-type-video; + } + } + // Audio + &[data-type="mp3"], + &[data-type="wav"], + &[data-type="raw"], + &[data-type="wma"] { + &::before { + content: $icon-type-audio; + } + } + // Docs + &[data-type="doc"], + &[data-type="xls"], + &[data-type="pdf"], + &[data-type="txt"] { + &::before { + content: $icon-type-docs; + } + } + // Code + &[data-type="html"], + &[data-type="htm"] { + &::before { + content: $icon-type-code; + } + } +} diff --git a/administrator/components/com_media/resources/styles/components/_media-edit.scss b/administrator/components/com_media/resources/styles/components/_media-edit.scss new file mode 100644 index 0000000000000..99d8191f938c9 --- /dev/null +++ b/administrator/components/com_media/resources/styles/components/_media-edit.scss @@ -0,0 +1,40 @@ +#media-form { + .form-control { + max-width: 100%; + } + .control-group { + display: flex; + flex-direction: column; + .control-label { + width: 100%; + } + .controls { + margin-left: 0; + } + } + .input-group-addon { + font-size: .9rem; + } + .spacer hr { + width: 100%; + } + .custom-select { + min-width: 100%; + } +} + +.media-manager-edit { + > div { + padding: 0 $gutter-width; + } + h3 { + padding: 3px; + text-align: center; + opacity: .6; + } +} + +.tab-pane { + background-color: #fafafa; + border-left: 1px solid #f0f0f0; +} diff --git a/administrator/components/com_media/resources/styles/components/_media-infobar.scss b/administrator/components/com_media/resources/styles/components/_media-infobar.scss new file mode 100644 index 0000000000000..1323e33010510 --- /dev/null +++ b/administrator/components/com_media/resources/styles/components/_media-infobar.scss @@ -0,0 +1,74 @@ +.media-infobar { + position: absolute; + top: ($toolbar-height + 1px); + right: 0; + bottom: 0; + z-index: 4; + float: none; + width: 25%; + padding: $gutter-width; + overflow-y: scroll; + background-color: $info-bg; + border-left: 1px solid $border-color; + h2 { + padding: 10px ($gutter-width + 30px) 10px $gutter-width; + margin: (-$gutter-width) (-$gutter-width) $gutter-width; + font-weight: normal; + line-height: $info-title-height; + word-wrap: break-word; + background-color: $info-title-bg; + border-bottom: 1px solid #eee; + } + dl { + display: flex; + flex-wrap: wrap; + margin-right: -($col-gutter-width / 2); + margin-left: -($col-gutter-width / 2); + } + dt, dd { + position: relative; + width: 100%; + min-height: 1px; + padding-right: ($col-gutter-width / 2); + padding-left: ($col-gutter-width / 2); + } + dt { + flex: 0 0 $info-dt-width; + max-width: $info-dt-width; + font-weight: normal; + color: rgba(0, 0, 0, .54); + } + dd { + flex: 0 0 $info-dd-width; + max-width: $info-dd-width; + } +} + +.infobar-close { + position: absolute; + top: 0; + right: 0; + z-index: 2; + padding: 0 $gutter-width; + font-size: 2.6rem; + line-height: $info-title-height; + color: $info-close-color; + text-indent: 0; + text-shadow: none; + &:hover { + color: $info-close-color-hover; + cursor: pointer; + } +} + +.placeholder-icon.fa { + display: block; + width: 4rem; + height: 4rem; + margin: 20px auto 15px; + font-size: 2rem; + line-height: calc(4rem - 4px); + color: #ccc; + border: 2px solid #ccc; + border-radius: 50%; +} diff --git a/administrator/components/com_media/resources/styles/components/_media-modal.scss b/administrator/components/com_media/resources/styles/components/_media-modal.scss new file mode 100644 index 0000000000000..52cb3fb09265c --- /dev/null +++ b/administrator/components/com_media/resources/styles/components/_media-modal.scss @@ -0,0 +1,88 @@ +.media-modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1070; + display: table; + width: 100%; + height: 100%; + background-color: $modal-backdrop-color; + + .modal { + display: flex; + align-items: center; + justify-content: center; + animation: .5s ease 0s normal none 1 running fadeIn; + } + + .modal-body { + width: auto; + padding: 15px; + } + + .modal-content { + box-shadow: $modal-box-shadow; + } + +} + +.media-preview-modal { + color: $modal-preview-text-color; + + .modal-dialog { + max-width: 70vw; + max-height: 70vh; + } + .modal-content { + display: flex; + flex-direction: column; + align-items: flex-start; + background-color: transparent; + border: 0; + box-shadow: none; + } + .modal-header { + padding: 0; + border: 0; + > .close { + display: none; + } + } + .modal-body { + padding: 0; + background-color: #fff; + box-shadow: $modal-box-shadow; + img { + max-width: 100%; + } + } + .modal-footer { + display: none; + } +} + +.media-preview-close { + position: absolute; + top: 0; + right: 0; + margin: 5px 20px; + font-size: 3rem; + opacity: .7; + &:hover { + cursor: pointer; + opacity: 1; + } +} + +@keyframes fadeInUp { + from { + opacity: 0; + transition: transform .3s ease-out; + transform: translate(0, -25%); + } + + to { + opacity: 1; + transform: none; + } +} diff --git a/administrator/components/com_media/resources/styles/components/_media-toolbar.scss b/administrator/components/com_media/resources/styles/components/_media-toolbar.scss new file mode 100644 index 0000000000000..442e44e12f1c3 --- /dev/null +++ b/administrator/components/com_media/resources/styles/components/_media-toolbar.scss @@ -0,0 +1,71 @@ +.media-toolbar { + position: relative; + display: flex; + padding: 0; + background-color: $toolbar-bg; + border-bottom: 1px solid $border-color; + border-radius: $border-radius $border-radius 0 0; + input { + padding: .375rem .75rem; + color: #495057; + border: 1px solid #ced4da; + } +} + +.media-toolbar-icon { + display: inline-block; + width: $toolbar-icon-width; + font-size: 1.3rem; + line-height: $toolbar-height; + color: #464a4c; + text-align: center; + border-left: 1px solid $border-color; + box-shadow: 1px 0 #fefefe inset; + &:hover { + background-color: $toolbar-icon-bg-hover; + box-shadow: none; + } +} + +.media-view-icons { + display: flex; +} + +.media-view-icons { + .disabled { + span { + opacity: .3; + } + &:hover, span:hover { + cursor: default; + } + } +} + +.media-view-search-input { + display: flex; + align-items: center; + padding: 0 10px; +} + +.media-loader { + position: absolute; + right: 100%; + bottom: 0; + left: 0; + z-index: 10; + height: $toolbar-loader-height; + background-image: $toolbar-loader-color; + animation: 10s ease 0s normal none 1 running mediaLoader; + animation-fill-mode: forwards; +} + +@keyframes mediaLoader { + from { + right: 100%; + } + + to { + right: 0; + } +} \ No newline at end of file diff --git a/administrator/components/com_media/resources/styles/components/_media-tree.scss b/administrator/components/com_media/resources/styles/components/_media-tree.scss new file mode 100644 index 0000000000000..72e33f8760e7d --- /dev/null +++ b/administrator/components/com_media/resources/styles/components/_media-tree.scss @@ -0,0 +1,132 @@ +/* Media Tree */ + +ul.media-tree { + padding: 0 0 5px; + margin: 0; + overflow-x: visible; + list-style: none; + ul { + margin-left: 2px; + } + &:empty { + display: none; + } +} + +.media-disk { + margin-bottom: 10px; +} + +.media-drive { + overflow-x: auto; + background-color: $sidebar-drive-bg; + border: 1px solid $border-color; + + .media-drive { + border-top: 0; + } + > ul > li { + padding-left: 25px; + } +} + +.media-drive-name { + padding: 4px 10px; + &::before { + margin-right: 6px; + font-family: FontAwesome; + color: $sidebar-tree-icon-color; + content: $sidebar-tree-folder-icon; + } + &:hover { + cursor: pointer; + } +} + +.media-disk-name { + padding: 4px 1px; + font-size: .8em; + color: #aaa; + text-transform: uppercase; + letter-spacing: 1px; + &:empty { + display: none; + } +} + +.media-tree-item { + position: relative; + display: block; + &::before { + content: ''; + height: 1px; + width: 10px; + background-color: $sidebar-tree-line-color; + position: absolute; + top: ($sidebar-tree-line-height / 2); + left: 15px; + margin: auto; + } + &::after { + position: absolute; + top: 0; + bottom: 0; + left: 15px; + width: 1px; + height: 100%; + content: ""; + background-color: $sidebar-tree-line-color; + } + &:last-child { + &::after { + height: ($sidebar-tree-line-height / 2); + } + } + li { + padding-left: 25px; + &::before, &::after { + left: 13px; + } + } +} + +.media-tree-item a { + display: block; + padding: 0 7px; + cursor: pointer; + line-height: $sidebar-tree-line-height; + text-decoration: none; + white-space: nowrap; +} + +.media-tree-item.active > a { + &:hover { + text-decoration: none; + background-color: $sidebar-tree-item-hover-bg; + } +} + +.media-tree-item .item-icon { + display: inline-block; + padding-right: 2px; + font-size: 15px; + line-height: normal; + color: $sidebar-tree-icon-color; + vertical-align: middle; +} + +.media-tree-item.active > a .item-icon { + color: $sidebar-active-icon-color; +} + +.item-name { + display: inline-block; + overflow: hidden; + font-size: .9em; + text-overflow: ellipsis; + vertical-align: middle; + white-space: nowrap; +} + +.media-tree-item.active > a .item-name { + font-weight: bold; +} diff --git a/administrator/components/com_media/resources/styles/mediamanager.scss b/administrator/components/com_media/resources/styles/mediamanager.scss new file mode 100644 index 0000000000000..c3325e23779ce --- /dev/null +++ b/administrator/components/com_media/resources/styles/mediamanager.scss @@ -0,0 +1,14 @@ +// Imports +@import "variables"; + +// Components +@import "components/animations"; +@import "components/layout"; +@import "components/media-breadcrumb"; +@import "components/media-browser"; +@import "components/media-edit"; +@import "components/media-infobar"; +@import "components/media-toolbar"; +@import "components/media-tree"; +@import "components/media-modal"; + diff --git a/administrator/components/com_media/resources/styles/variables.scss b/administrator/components/com_media/resources/styles/variables.scss new file mode 100644 index 0000000000000..067bd1bb282df --- /dev/null +++ b/administrator/components/com_media/resources/styles/variables.scss @@ -0,0 +1,88 @@ +// Defaults +$gutter-width: 15px; +$highlight-color: #007eb7; +$border-color: #d8d8d8; +$border-radius: .25rem; + +// Layout +$col-main-panel-width: 83.3333%; +$col-side-panel-width: 16.6667%; +$col-gutter-width: $gutter-width; +$col-box-shadow: 0 0 3px rgba(0, 0, 0, .075); + +// Sidebar +$sidebar-drive-bg: #fff; +$sidebar-tree-line-color: $border-color; +$sidebar-tree-icon-color: #aaa; +$sidebar-tree-line-height: 26px; +$sidebar-tree-folder-icon: "\f114"; +$sidebar-tree-item-hover-bg: #e1e1e1; +$sidebar-active-icon-color: $highlight-color; + +// Toolbar +$toolbar-height: 46px; +$toolbar-bg: #f5f5f5; +$toolbar-icon-width: 50px; +$toolbar-icon-color: #464a4c; +$toolbar-icon-bg-hover: #f0f0f0; +$toolbar-loader-color: linear-gradient(to right, #59afff 0, #59daff 100%); +$toolbar-loader-height: 2px; + +// Breadcrumbs +$breadcrumbs-bg: #fafafa; +$breadcrumbs-current-bg: #fff; + +// Media Browser Grid +$grid-gutter-width: $col-gutter-width; +$grid-outside-padding: $col-gutter-width; +$grid-item-hover-color: rgba(#000, .5); +$grid-item-border-radius: $border-radius; +$grid-item-icon-size: 1.3rem; +$grid-item-icon-color: #fff; +$grid-item-icon-bg-color: rgba(0,0,0,.8); +$grid-item-icon-color-hover: rgba(0,0,0,.8); +$grid-item-icon-bg-color-hover: #fff; +$grid-item-icon-warning-icon-bg: #d9534f; +$grid-item-no-preview-bg: #f5f5f5; +$grid-item-width-xs: 8.333%; +$grid-item-width-sm: 12.5%; +$grid-item-width-md: 16.666%; +$grid-item-width-lg: 25%; +$grid-item-width-xl: 50%; + +// Media Browser Table +$table-item-height: 30px; +$table-item-icon-size: 1.2rem; +$table-item-icon-color: #656565; +$table-item-icon-bg: rgba(0, 0, 0, .015); +$table-item-icon-color-selected: #fff; +$table-item-icon-bg-selected: #006898; +$table-item-bg-hover: rgba(0, 0, 0, .03); + +// Media Info bar +$info-bg: #fafafa; +$info-title-bg: #f6f6f6; +$info-title-height: 2rem; +$info-dt-width: 33.33333%; +$info-dd-width: 66.66667%; +$info-close-color: #ccc; +$info-close-color-hover: #aaa; + +// Table Icon Mapping +$icon-type-default: "\f016"; +$icon-type-folder: "\f114"; +$icon-type-images: "\f1c5"; +$icon-type-video: "\f1c8"; +$icon-type-audio: "\f1c7"; +$icon-type-docs: "\f0f6"; +$icon-type-code: "\f1c9"; + +// Drag n Drop Upload +$dnd-bg: rgba(245, 245, 245, .8); +$dnd-icon-color: #1c3d5c; +$dnd-border: 3px dashed #999; + +// Modal +$modal-backdrop-color: rgba(0, 0, 0, .7); +$modal-box-shadow: 0 0 10px rgba(0, 0, 0, .5); +$modal-preview-text-color: #fff; diff --git a/administrator/components/com_media/services/provider.php b/administrator/components/com_media/services/provider.php new file mode 100644 index 0000000000000..befb4786278c4 --- /dev/null +++ b/administrator/components/com_media/services/provider.php @@ -0,0 +1,54 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Media')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Media')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_media/src/Adapter/AdapterInterface.php b/administrator/components/com_media/src/Adapter/AdapterInterface.php new file mode 100644 index 0000000000000..1a3a05041d024 --- /dev/null +++ b/administrator/components/com_media/src/Adapter/AdapterInterface.php @@ -0,0 +1,225 @@ +input->getMethod(); + + $this->task = $task; + $this->method = $method; + + try + { + // Check token for requests which do modify files (all except get requests) + if ($method !== 'GET' && !Session::checkToken('json')) + { + throw new \InvalidArgumentException(Text::_('JINVALID_TOKEN'), 403); + } + + $doTask = strtolower($method) . ucfirst($task); + + // Record the actual task being fired + $this->doTask = $doTask; + + if (!in_array($this->doTask, $this->taskMap)) + { + throw new \Exception(Text::sprintf('JLIB_APPLICATION_ERROR_TASK_NOT_FOUND', $task), 405); + } + + $data = $this->$doTask(); + + // Return the data + $this->sendResponse($data); + } + catch (FileNotFoundException $e) + { + $this->sendResponse($e, 404); + } + catch (FileExistsException $e) + { + $this->sendResponse($e, 409); + } + catch (InvalidPathException $e) + { + $this->sendResponse($e, 400); + } + catch (\Exception $e) + { + $errorCode = 500; + + if ($e->getCode() > 0) + { + $errorCode = $e->getCode(); + } + + $this->sendResponse($e, $errorCode); + } + } + + /** + * Files Get Method + * + * Examples: + * + * - GET a list of folders below the root: + * index.php?option=com_media&task=api.files + * /api/files + * - GET a list of files and subfolders of a given folder: + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop + * /api/files/sampledata/fruitshop + * - GET a list of files and subfolders of a given folder for a given search term: + * use recursive=1 to search recursively in the working directory + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop&search=apple + * /api/files/sampledata/fruitshop?search=apple + * To look up in same working directory set flag recursive=0 + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop&search=apple&recursive=0 + * /api/files/sampledata/fruitshop?search=apple&recursive=0 + * - GET file information for a specific file: + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop/test.jpg + * /api/files/sampledata/fruitshop/test.jpg + * - GET a temporary URL to a given file + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop/test.jpg&url=1&temp=1 + * /api/files/sampledata/fruitshop/test.jpg&url=1&temp=1 + * - GET a temporary URL to a given file + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop/test.jpg&url=1 + * /api/files/sampledata/fruitshop/test.jpg&url=1 + * + * @return array The data to send with the response + * + * @since 4.0.0 + * @throws \Exception + */ + public function getFiles() + { + // Grab options + $options = []; + $options['url'] = $this->input->getBool('url', false); + $options['temp'] = $this->input->getBool('temp', false); + $options['search'] = $this->input->getString('search', ''); + $options['recursive'] = $this->input->getBool('recursive', true); + $options['content'] = $this->input->getBool('content', false); + + return $this->getModel()->getFiles($this->getAdapter(), $this->getPath(), $options); + } + + /** + * Files delete Method + * + * Examples: + * + * - DELETE an existing folder in a specific folder: + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop/test + * /api/files/sampledata/fruitshop/test + * - DELETE an existing file in a specific folder: + * index.php?option=com_media&task=api.files&path=/sampledata/fruitshop/test.jpg + * /api/files/sampledata/fruitshop/test.jpg + * + * @return null + * + * @since 4.0.0 + * @throws \Exception + */ + public function deleteFiles() + { + $this->getModel()->delete($this->getAdapter(), $this->getPath()); + + return null; + } + + /** + * Files Post Method + * + * Examples: + * + * - POST a new file or folder into a specific folder, the file or folder information is returned: + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop + * /api/files/sampledata/fruitshop + * + * New file body: + * { + * "name": "test.jpg", + * "content":"base64 encoded image" + * } + * New folder body: + * { + * "name": "test", + * } + * + * @return array The data to send with the response + * + * @since 4.0.0 + * @throws \Exception + */ + public function postFiles() + { + $adapter = $this->getAdapter(); + $path = $this->getPath(); + $content = $this->input->json; + $name = $content->getString('name'); + $mediaContent = base64_decode($content->get('content', '', 'raw')); + $override = $content->get('override', false); + + if ($mediaContent) + { + $this->checkContent(); + + // A file needs to be created + $name = $this->getModel()->createFile($adapter, $name, $path, $mediaContent, $override); + } + else + { + // A file needs to be created + $name = $this->getModel()->createFolder($adapter, $name, $path, $override); + } + + return $this->getModel()->getFile($adapter, $path . '/' . $name); + } + + /** + * Files Put method + * + * Examples: + * + * - PUT a media file, the file or folder information is returned: + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop/test.jpg + * /api/files/sampledata/fruitshop/test.jpg + * + * Update file body: + * { + * "content":"base64 encoded image" + * } + * + * - PUT move a file, folder to another one + * path : will be taken as the source + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop/test.jpg + * /api/files/sampledata/fruitshop/test.jpg + * + * JSON body: + * { + * "newPath" : "/path/to/destination", + * "move" : "1" + * } + * + * - PUT copy a file, folder to another one + * path : will be taken as the source + * index.php?option=com_media&task=api.files&format=json&path=/sampledata/fruitshop/test.jpg + * /api/files/sampledata/fruitshop/test.jpg + * + * JSON body: + * { + * "newPath" : "/path/to/destination", + * "move" : "0" + * } + * + * @return array The data to send with the response + * + * @since 4.0.0 + * @throws \Exception + */ + public function putFiles() + { + $adapter = $this->getAdapter(); + $path = $this->getPath(); + + $content = $this->input->json; + $name = basename($path); + $mediaContent = base64_decode($content->get('content', '', 'raw')); + $newPath = $content->getString('newPath', null); + $move = $content->get('move', true); + + if ($mediaContent != null) + { + $this->checkContent(); + + $this->getModel()->updateFile($adapter, $name, str_replace($name, '', $path), $mediaContent); + } + + if ($newPath != null) + { + list($destinationAdapter, $destinationPath) = explode(':', $newPath, 2); + + if ($move) + { + $destinationPath = $this->getModel()->move($adapter, $path, $destinationPath, false); + } + else + { + $destinationPath = $this->getModel()->copy($adapter, $path, $destinationPath, false); + } + + $path = $destinationPath; + } + + return $this->getModel()->getFile($adapter, $path); + } + + /** + * Send the given data as JSON response in the following format: + * + * {"success":true,"message":"ok","messages":null,"data":[{"type":"dir","name":"banners","path":"//"}]} + * + * @param mixed $data The data to send + * @param integer $responseCode The response code + * + * @return void + * + * @since 4.0.0 + */ + private function sendResponse($data = null, int $responseCode = 200) + { + // Set the correct content type + $this->app->setHeader('Content-Type', 'application/json'); + + // Set the status code for the response + http_response_code($responseCode); + + // Send the data + echo new JsonResponse($data); + + $this->app->close(); + } + + /** + * 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 Model|boolean Model object on success; otherwise false on failure. + * + * @since 4.0.0 + */ + public function getModel($name = 'Api', $prefix = 'Administrator', $config = []) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Performs various checks if it is allowed to save the content. + * + * @return void + * + * @since 4.0.0 + * @throws \Exception + */ + private function checkContent() + { + if (!Factory::getUser()->authorise('core.create', 'com_media')) + { + throw new \Exception(Text::_('COM_MEDIA_ERROR_CREATE_NOT_PERMITTED'), 403); + } + + $params = ComponentHelper::getParams('com_media'); + + $helper = new MediaHelper; + $serverlength = $this->input->server->get('CONTENT_LENGTH'); + + if ($serverlength > ($params->get('upload_maxsize', 0) * 1024 * 1024) + || $serverlength > $helper->toBytes(ini_get('upload_max_filesize')) + || $serverlength > $helper->toBytes(ini_get('post_max_size')) + || $serverlength > $helper->toBytes(ini_get('memory_limit'))) + { + throw new \Exception(Text::_('COM_MEDIA_ERROR_WARNFILETOOLARGE'), 403); + } + } + + /** + * Get the Adapter. + * + * @return string + * + * @since 4.0.0 + */ + private function getAdapter() + { + $parts = explode(':', $this->input->getString('path', ''), 2); + + if (count($parts) < 1) + { + return null; + } + + return $parts[0]; + } + + /** + * Get the Path. + * + * @return string + * + * @since 4.0.0 + */ + private function getPath() + { + $parts = explode(':', $this->input->getString('path', ''), 2); + + if (count($parts) < 2) + { + return null; + } + + return $parts[1]; + } +} diff --git a/administrator/components/com_media/src/Controller/DisplayController.php b/administrator/components/com_media/src/Controller/DisplayController.php new file mode 100644 index 0000000000000..32fe3f636d024 --- /dev/null +++ b/administrator/components/com_media/src/Controller/DisplayController.php @@ -0,0 +1,66 @@ +input->getString('plugin', null); + $plugins = PluginHelper::getPlugin('filesystem'); + + // If plugin name was not found in parameters redirect back to control panel + if (!$pluginName || !$this->containsPlugin($plugins, $pluginName)) + { + throw new \Exception('Plugin not found!'); + } + + // Check if the plugin is disabled, if so redirect to control panel + if (!PluginHelper::isEnabled('filesystem', $pluginName)) + { + throw new \Exception('Plugin ' . $pluginName . ' is disabled.'); + } + + // Only import our required plugin, not entire group + PluginHelper::importPlugin('filesystem', $pluginName); + + // Event parameters + $eventParameters = ['context' => $pluginName, 'input' => $this->input]; + $event = new OAuthCallbackEvent('onFileSystemOAuthCallback', $eventParameters); + + // Get results from event + $eventResults = (array) $this->app->triggerEvent('onFileSystemOAuthCallback', $event); + + // If event was not triggered in the selected Plugin, raise a warning and fallback to Control Panel + if (!$eventResults) + { + throw new \Exception( + 'Plugin ' . $pluginName . ' should have implemented onFileSystemOAuthCallback method' + ); + } + + $action = $eventResults['action'] ?? null; + $message = null; + + // If there are any messages display them + if (isset($eventResults['message'])) + { + $message = $eventResults['message']; + $messageType = ($eventResults['message_type'] ?? ''); + + $this->app->enqueueMessage($message, $messageType); + } + + /** + * Execute actions defined by the plugin + * Supported actions + * - close : Closes the current window, use this only for windows opened by javascript + * - redirect : Redirect to a URI defined in 'redirect_uri' parameter, if not fallback to control panel + * - media-manager : Redirect to Media Manager + * - control-panel : Redirect to Control Panel + */ + switch ($action) + { + /** + * Close a window opened by developer + * Use this for close New Windows opened for OAuth Process + */ + case 'close': + $this->setRedirect(Route::_('index.php?option=com_media&view=plugin&action=close', false)); + break; + + // Redirect browser to any page specified by the user + case 'redirect': + if (!isset($eventResults['redirect_uri'])) + { + throw new \Exception("Redirect URI must be set in the plugin"); + } + $this->setRedirect($eventResults['redirect_uri']); + break; + + // Redirect browser to Control Panel + case 'control-panel': + $this->setRedirect(Route::_('index.php', false)); + break; + + // Redirect browser to Media Manager + case 'media-manager': + default: + $this->setRedirect(Route::_('index.php?option=com_media', false)); + } + } + catch (\Exception $e) + { + // Display any error + $this->app->enqueueMessage($e->getMessage(), 'error'); + $this->setRedirect(Route::_('index.php', false)); + } + + // Redirect + $this->redirect(); + } + + /** + * Check whether a plugin exists in given plugin array. + * + * @param array $plugins Array of plugin names + * @param string $pluginName Plugin name to look up + * + * @return bool + * + * @since 4.0.0 + */ + private function containsPlugin($plugins, $pluginName) + { + foreach ($plugins as $plugin) + { + if ($plugin->name == $pluginName) + { + return true; + } + } + + return false; + } +} diff --git a/administrator/components/com_media/src/Dispatcher/Dispatcher.php b/administrator/components/com_media/src/Dispatcher/Dispatcher.php new file mode 100644 index 0000000000000..f2f53b14a5504 --- /dev/null +++ b/administrator/components/com_media/src/Dispatcher/Dispatcher.php @@ -0,0 +1,47 @@ +app->getIdentity(); + $asset = $this->input->get('asset'); + $author = $this->input->get('author'); + + // Access check + 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)))) + { + throw new NotAllowed($this->app->getLanguage()->_('JERROR_ALERTNOAUTHOR'), 403); + } + } +} diff --git a/administrator/components/com_media/src/Event/MediaProviderEvent.php b/administrator/components/com_media/src/Event/MediaProviderEvent.php new file mode 100644 index 0000000000000..9ca3aba30e276 --- /dev/null +++ b/administrator/components/com_media/src/Event/MediaProviderEvent.php @@ -0,0 +1,57 @@ +providerManager; + } + + /** + * Set the ProviderManager + * + * @param ProviderManager $providerManager The Provider Manager to be set + * + * @return void + * + * @since 4.0.0 + */ + public function setProviderManager(ProviderManager $providerManager) + { + $this->providerManager = $providerManager; + } +} diff --git a/administrator/components/com_media/src/Event/OAuthCallbackEvent.php b/administrator/components/com_media/src/Event/OAuthCallbackEvent.php new file mode 100644 index 0000000000000..fb2b464784186 --- /dev/null +++ b/administrator/components/com_media/src/Event/OAuthCallbackEvent.php @@ -0,0 +1,91 @@ +context; + } + + /** + * Set the event context. + * + * @param string $context Event context + * + * @return void + * + * @since 4.0.0 + */ + public function setContext($context) + { + $this->context = $context; + } + + /** + * Get the event input. + * + * @return Input + * + * @since 4.0.0 + */ + public function getInput() + { + return $this->input; + } + + /** + * Set the event input. + * + * @param Input $input Event input + * + * @return void + * + * @since 4.0.0 + */ + public function setInput($input) + { + $this->input = $input; + } +} diff --git a/administrator/components/com_media/src/Exception/FileExistsException.php b/administrator/components/com_media/src/Exception/FileExistsException.php new file mode 100644 index 0000000000000..5d9735affc213 --- /dev/null +++ b/administrator/components/com_media/src/Exception/FileExistsException.php @@ -0,0 +1,21 @@ +providerManager == null) + { + $this->providerManager = new ProviderManager; + + // Fire the event to get the results + $eventParameters = ['context' => 'AdapterManager', 'providerManager' => $this->providerManager]; + $event = new MediaProviderEvent('onSetupProviders', $eventParameters); + PluginHelper::importPlugin('filesystem'); + Factory::getApplication()->triggerEvent('onSetupProviders', $event); + } + + return $this->providerManager->getAdapter($name); + } + + /** + * Returns the requested file or folder information. More information + * can be found in AdapterInterface::getFile(). + * + * @param string $adapter The adapter + * @param string $path The path to the file or folder + * @param array $options The options + * + * @return \stdClass + * + * @since 4.0.0 + * @throws \Exception + * @see AdapterInterface::getFile() + */ + public function getFile($adapter, $path = '/', $options = []) + { + // Add adapter prefix to the file returned + $file = $this->getAdapter($adapter)->getFile($path); + + // Check if it is a media file + if ($file->type == 'file' && !$this->isMediaFile($file->path)) + { + throw new InvalidPathException; + } + + if (isset($options['url']) && $options['url'] && $file->type == 'file') + { + if (isset($options['temp']) && $options['temp']) + { + $file->tempUrl = $this->getTemporaryUrl($adapter, $file->path); + } + else + { + $file->url = $this->getUrl($adapter, $file->path); + } + } + + if (isset($options['content']) && $options['content'] && $file->type == 'file') + { + $resource = $this->getAdapter($adapter)->getResource($file->path); + + if ($resource) + { + $file->content = base64_encode(stream_get_contents($resource)); + } + } + + $file->path = $adapter . ":" . $file->path; + $file->adapter = $adapter; + + return $file; + } + + /** + * Returns the folders and files for the given path. More information + * can be found in AdapterInterface::getFiles(). + * + * @param string $adapter The adapter + * @param string $path The folder + * @param array $options The options + * + * @return \stdClass[] + * + * @since 4.0.0 + * @throws \Exception + * @see AdapterInterface::getFile() + */ + public function getFiles($adapter, $path = '/', $options = []) + { + // Check whether user searching + if ($options['search'] != null) + { + // Do search + $files = $this->search($adapter, $options['search'], $path, $options['recursive']); + } + else + { + // Grab files for the path + $files = $this->getAdapter($adapter)->getFiles($path); + } + + // Add adapter prefix to all the files to be returned + foreach ($files as $key => $file) + { + // Check if the file is valid + if ($file->type == 'file' && !$this->isMediaFile($file->path)) + { + // Remove the file from the data + unset($files[$key]); + continue; + } + + // Check if we need more information + if (isset($options['url']) && $options['url'] && $file->type == 'file') + { + if (isset($options['temp']) && $options['temp']) + { + $file->tempUrl = $this->getTemporaryUrl($adapter, $file->path); + } + else + { + $file->url = $this->getUrl($adapter, $file->path); + } + } + + if (isset($options['content']) && $options['content'] && $file->type == 'file') + { + $resource = $this->getAdapter($adapter)->getResource($file->path); + + if ($resource) + { + $file->content = base64_encode(stream_get_contents($resource)); + } + } + + $file->path = $adapter . ":" . $file->path; + $file->adapter = $adapter; + } + + // Return array with proper indexes + return array_values($files); + } + + /** + * Creates a folder with the given name in the given path. More information + * can be found in AdapterInterface::createFolder(). + * + * @param string $adapter The adapter + * @param string $name The name + * @param string $path The folder + * @param boolean $override Should the folder being overriden when it exists + * + * @return string + * + * @since 4.0.0 + * @throws \Exception + * @see AdapterInterface::createFolder() + */ + public function createFolder($adapter, $name, $path, $override) + { + try + { + $file = $this->getFile($adapter, $path . '/' . $name); + } + catch (FileNotFoundException $e) + { + // Do nothing + } + + // Check if the file exists + if (isset($file) && !$override) + { + throw new FileExistsException; + } + + $object = $this->triggerEvent( + $adapter, + $name, + $path, + 0, + function ($object) + { + $object->name = $this->getAdapter($object->adapter)->createFolder($object->name, $object->path); + } + ); + + return $object->name; + } + + /** + * Creates a file with the given name in the given path with the data. More information + * can be found in AdapterInterface::createFile(). + * + * @param string $adapter The adapter + * @param string $name The name + * @param string $path The folder + * @param binary $data The data + * @param boolean $override Should the file being overriden when it exists + * + * @return string + * + * @since 4.0.0 + * @throws \Exception + * @see AdapterInterface::createFile() + */ + public function createFile($adapter, $name, $path, $data, $override) + { + try + { + $file = $this->getFile($adapter, $path . '/' . $name); + } + catch (FileNotFoundException $e) + { + // Do nothing + } + + // Check if the file exists + if (isset($file) && !$override) + { + throw new FileExistsException; + } + + // Check if it is a media file + if (!$this->isMediaFile($path . '/' . $name)) + { + throw new InvalidPathException; + } + + $object = $this->triggerEvent( + $adapter, + $name, + $path, + $data, + function ($object) + { + $object->name = $this->getAdapter($object->adapter)->createFile($object->name, $object->path, $object->data); + } + ); + + return $object->name; + } + + /** + * Updates the file with the given name in the given path with the data. More information + * can be found in AdapterInterface::updateFile(). + * + * @param string $adapter The adapter + * @param string $name The name + * @param string $path The folder + * @param binary $data The data + * + * @return void + * + * @since 4.0.0 + * @throws \Exception + * @see AdapterInterface::updateFile() + */ + public function updateFile($adapter, $name, $path, $data) + { + // Check if it is a media file + if (!$this->isMediaFile($path . '/' . $name)) + { + throw new InvalidPathException; + } + + $this->triggerEvent( + $adapter, + $name, + $path, + $data, + function ($object) + { + $this->getAdapter($object->adapter)->updateFile($object->name, $object->path, $object->data); + } + ); + } + + /** + * Deletes the folder or file of the given path. More information + * can be found in AdapterInterface::delete(). + * + * @param string $adapter The adapter + * @param string $path The path to the file or folder + * + * @return void + * + * @since 4.0.0 + * @throws \Exception + * @see AdapterInterface::delete() + */ + public function delete($adapter, $path) + { + $file = $this->getFile($adapter, $path); + + // Check if it is a media file + if ($file->type == 'file' && !$this->isMediaFile($file->path)) + { + throw new InvalidPathException; + } + + $this->getAdapter($adapter)->delete($path); + } + + /** + * Copies file or folder from source path to destination path + * If forced, existing files/folders would be overwritten + * + * @param string $adapter The adapter + * @param string $sourcePath Source path of the file or folder (relative) + * @param string $destinationPath Destination path(relative) + * @param bool $force Force to overwrite + * + * @return string + * + * @since 4.0.0 + * @throws \Exception + */ + public function copy($adapter, $sourcePath, $destinationPath, $force = false) + { + return $this->getAdapter($adapter)->copy($sourcePath, $destinationPath, $force); + } + + /** + * Moves file or folder from source path to destination path + * If forced, existing files/folders would be overwritten + * + * @param string $adapter The adapter + * @param string $sourcePath Source path of the file or folder (relative) + * @param string $destinationPath Destination path(relative) + * @param bool $force Force to overwrite + * + * @return string + * + * @since 4.0.0 + * @throws \Exception + */ + public function move($adapter, $sourcePath, $destinationPath, $force = false) + { + return $this->getAdapter($adapter)->move($sourcePath, $destinationPath, $force); + } + + /** + * Returns an url for serve media files from adapter. + * Url must provide a valid image type to be displayed on Joomla! site. + * + * @param string $adapter The adapter + * @param string $path The relative path for the file + * + * @return string Permalink to the relative file + * + * @since 4.0.0 + * @throws FileNotFoundException + */ + public function getUrl($adapter, $path) + { + // Check if it is a media file + if (!$this->isMediaFile($path)) + { + throw new InvalidPathException; + } + + return $this->getAdapter($adapter)->getUrl($path); + } + + /** + * Search for a pattern in a given path + * + * @param string $adapter The adapter to work on + * @param string $needle The search therm + * @param string $path The base path for the search + * @param bool $recursive Do a recursive search + * + * @return \stdClass[] + * + * @since 4.0.0 + * @throws \Exception + */ + public function search($adapter, $needle, $path = '/', $recursive = true) + { + return $this->getAdapter($adapter)->search($path, $needle, $recursive); + } + + /** + * Returns a temporary url for the given path. + * This is used internally in media manager + * + * @param string $adapter The adapter + * @param string $path The path to file + * + * @return string + * + * @since 4.0.0 + * @throws \Exception + */ + public function getTemporaryUrl($adapter, $path) + { + // Check if it is a media file + if (!$this->isMediaFile($path)) + { + throw new InvalidPathException; + } + + return $this->getAdapter($adapter)->getTemporaryUrl($path); + } + + /** + * Checks if the given path is an allowed media file. + * + * @param string $path The path to file + * + * @return boolean + * + * @since 4.0.0 + */ + private function isMediaFile($path) + { + // Check if there is an extension available + if (!strrpos($path, '.')) + { + return false; + } + + // Initialize the allowed extensions + if ($this->allowedExtensions === null) + { + // Get the setting from the params + $this->allowedExtensions = ComponentHelper::getParams('com_media')->get( + 'upload_extensions', + 'bmp,csv,doc,gif,ico,jpg,jpeg,odg,odp,ods,odt,pdf,png,ppt,txt,xcf,xls,BMP,CSV,DOC,GIF,ICO,JPG,JPEG,ODG,ODP,ODS,ODT,PDF,PNG,PPT,TXT,XCF,XLS' + ); + + // Make them an array + $this->allowedExtensions = explode(',', $this->allowedExtensions); + } + + // Extract the extension + $extension = substr($path, strrpos($path, '.') + 1); + + // Check if the extension exists in the allowed extensions + return in_array($extension, $this->allowedExtensions); + } + + /** + * Triggers the onContentBeforeSave and onContentAfterSave event when calling the + * given callable. + * + * If the onContentBeforeSave contains false, the operation will be aborted and an exception thrown. + * + * The object will be returned which got sent as part of the event. + * + * @param string $adapter The adapter + * @param string $name The name + * @param string $path The path + * @param binary $data The binary data + * @param callable $callback The callback + * + * @return CMSObject + * + * @throws \Exception + * @since 4.0.0 + */ + private function triggerEvent(string $adapter, string $name, string $path, $data, callable $callback) + { + $app = Factory::getApplication(); + + $object = new CMSObject; + $object->adapter = $adapter; + $object->name = $name; + $object->path = $path; + $object->data = $data; + $object->extension = strtolower(File::getExt($name)); + $object->type = $object->extension ? 'file' : 'dir'; + + // Also include the filesystem plugins, perhaps they support batch processing too + PluginHelper::importPlugin('media-action'); + + $result = $app->triggerEvent('onContentBeforeSave', ['com_media.' . $object->type, $object, true]); + + if (in_array(false, $result, true)) + { + throw new \Exception($object->getError()); + } + + $callback($object); + + $app->triggerEvent('onContentAfterSave', ['com_media.' . $object->type, $object, true]); + + return $object; + } +} diff --git a/administrator/components/com_media/src/Model/FileModel.php b/administrator/components/com_media/src/Model/FileModel.php new file mode 100644 index 0000000000000..0aeb8e6142d19 --- /dev/null +++ b/administrator/components/com_media/src/Model/FileModel.php @@ -0,0 +1,66 @@ +loadForm('com_media.file', 'file', ['control' => 'jform', 'load_data' => $loadData]); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the file information for the given path. Path must be + * in the format: adapter:path/to/file.extension + * + * @param string $path The path to get the information from. + * + * @return \stdClass A object with file information + * + * @since 4.0.0 + * @see ApiModel::getFile() + */ + public function getFileInformation($path) + { + list($adapter, $path) = explode(':', $path, 2); + + return (new ApiModel)->getFile($adapter, $path, ['url' => true, 'content' => true]); + } +} diff --git a/administrator/components/com_media/src/Model/MediaModel.php b/administrator/components/com_media/src/Model/MediaModel.php new file mode 100644 index 0000000000000..088f3a3ade27f --- /dev/null +++ b/administrator/components/com_media/src/Model/MediaModel.php @@ -0,0 +1,62 @@ + 'AdapterManager', 'providerManager' => $providerManager]; + $event = new MediaProviderEvent('onSetupProviders', $eventParameters); + $results = []; + + // Import plugin group and fire the event + PluginHelper::importPlugin('filesystem'); + Factory::getApplication()->triggerEvent('onSetupProviders', $event); + + foreach ($providerManager->getProviders() as $provider) + { + $result = new \stdClass; + $result->name = $provider->getID(); + $result->displayName = $provider->getDisplayName(); + + foreach ($provider->getAdapters() as $adapter) + { + $result->adapterNames[] = $adapter->getAdapterName(); + } + + $results[] = $result; + } + + return $results; + } +} diff --git a/administrator/components/com_media/src/Plugin/MediaActionPlugin.php b/administrator/components/com_media/src/Plugin/MediaActionPlugin.php new file mode 100644 index 0000000000000..41b57c92410ba --- /dev/null +++ b/administrator/components/com_media/src/Plugin/MediaActionPlugin.php @@ -0,0 +1,97 @@ +getName() != 'com_media.file') + { + return; + } + + $this->loadCss(); + $this->loadJs(); + + // The file with the params for the edit view + $paramsFile = JPATH_PLUGINS . '/media-action/' . $this->_name . '/form/' . $this->_name . '.xml'; + + // When the file exists, load it into the form + if (file_exists($paramsFile)) + { + $form->loadFile($paramsFile); + } + } + + /** + * Load the javascript files of the plugin. + * + * @return void + * + * @since 4.0.0 + */ + protected function loadJs() + { + HTMLHelper::_( + 'script', + 'plg_media-action_' . $this->_name . '/' . $this->_name . '.js', + ['version' => 'auto', 'relative' => true] + ); + } + + /** + * Load the CSS files of the plugin. + * + * @return void + * + * @since 4.0.0 + */ + protected function loadCss() + { + HTMLHelper::_( + 'stylesheet', + 'plg_media-action_' . $this->_name . '/' . $this->_name . '.css', + ['version' => 'auto', 'relative' => true] + ); + } +} diff --git a/administrator/components/com_media/src/Provider/ProviderInterface.php b/administrator/components/com_media/src/Provider/ProviderInterface.php new file mode 100644 index 0000000000000..ef0f71c44c275 --- /dev/null +++ b/administrator/components/com_media/src/Provider/ProviderInterface.php @@ -0,0 +1,49 @@ +providers; + } + + /** + * Register a provider into the ProviderManager + * + * @param ProviderInterface $provider The provider to be registered + * + * @return void + * + * @since 4.0.0 + */ + public function registerProvider(ProviderInterface $provider) + { + $this->providers[$provider->getID()] = $provider; + } + + /** + * Returns the provider for a particular ID + * + * @param string $id The ID for the provider + * + * @return ProviderInterface + * + * @throws \Exception + * + * @since 4.0.0 + */ + public function getProvider($id) + { + if (!isset($this->providers[$id])) + { + throw new \Exception("Media Provider not found"); + } + + return $this->providers[$id]; + } + + /** + * Returns an adapter for an account + * + * @param string $name The name of an adapter + * + * @return AdapterInterface + * + * @throws \Exception + * + * @since 4.0.0 + */ + public function getAdapter($name) + { + list($provider, $account) = array_pad(explode('-', $name, 2), 2, null); + + if ($account == null) + { + throw new \Exception('Account was not set'); + } + + $adapters = $this->getProvider($provider)->getAdapters(); + + if (!isset($adapters[$account])) + { + throw new \Exception("The account was not found"); + } + + return $adapters[$account]; + } +} diff --git a/administrator/components/com_media/src/View/File/HtmlView.php b/administrator/components/com_media/src/View/File/HtmlView.php new file mode 100644 index 0000000000000..8e3bb55336bcd --- /dev/null +++ b/administrator/components/com_media/src/View/File/HtmlView.php @@ -0,0 +1,77 @@ +input; + + $this->form = $this->get('Form'); + + // The component params + $this->params = ComponentHelper::getParams('com_media'); + + // The requested file + $this->file = $this->getModel()->getFileInformation($input->getString('path', null)); + + if (empty($this->file->content)) + { + // @todo error handling controller redirect files + throw new \Exception('No content available!'); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the toolbar buttons + * + * @return void + * + * @since 4.0.0 + */ + protected function addToolbar() + { + ToolbarHelper::title(Text::_('COM_MEDIA_EDIT'), 'images mediamanager'); + + ToolbarHelper::apply('apply'); + ToolbarHelper::save('save'); + ToolbarHelper::custom('reset', 'refresh', '', 'COM_MEDIA_RESET', false); + + ToolbarHelper::cancel('cancel'); + } +} diff --git a/administrator/components/com_media/src/View/Media/HtmlView.php b/administrator/components/com_media/src/View/Media/HtmlView.php new file mode 100644 index 0000000000000..29125ab276843 --- /dev/null +++ b/administrator/components/com_media/src/View/Media/HtmlView.php @@ -0,0 +1,134 @@ +prepareToolbar(); + + // Get enabled adapters + $this->providers = $this->get('Providers'); + + // Check that there are providers + if (!count($this->providers)) + { + $link = Route::_('index.php?option=com_plugins&view=plugins&filter[folder]=filesystem'); + Factory::getApplication()->enqueueMessage(Text::sprintf('COM_MEDIA_ERROR_NO_PROVIDERS', $link), CMSApplication::MSG_WARNING); + } + + $this->currentPath = Factory::getApplication()->input->getString('path'); + + parent::display($tpl); + } + + /** + * Prepare the toolbar. + * + * @return void + * + * @since 4.0.0 + */ + protected function prepareToolbar() + { + $tmpl = Factory::getApplication()->input->getCmd('tmpl'); + + // Get the toolbar object instance + $bar = Toolbar::getInstance('toolbar'); + $user = Factory::getUser(); + + // Set the title + ToolbarHelper::title(Text::_('COM_MEDIA'), 'images mediamanager'); + + // Add the upload and create folder buttons + if ($user->authorise('core.create', 'com_media')) + { + // Add the upload button + $layout = new FileLayout('toolbar.upload', JPATH_COMPONENT_ADMINISTRATOR . '/layouts'); + + $bar->appendButton('Custom', $layout->render([]), 'upload'); + ToolbarHelper::divider(); + + // Add the create folder button + $layout = new FileLayout('toolbar.create-folder', JPATH_COMPONENT_ADMINISTRATOR . '/layouts'); + + $bar->appendButton('Custom', $layout->render([]), 'new'); + ToolbarHelper::divider(); + } + + // Add a delete button + if ($user->authorise('core.delete', 'com_media')) + { + // Instantiate a new FileLayout instance and render the layout + $layout = new FileLayout('toolbar.delete'); + + $bar->appendButton('Custom', $layout->render([]), 'delete'); + ToolbarHelper::divider(); + } + + // Add the preferences button + if (($user->authorise('core.admin', 'com_media') || $user->authorise('core.options', 'com_media')) && $tmpl !== 'component') + { + ToolbarHelper::preferences('com_media'); + ToolbarHelper::divider(); + } + + if ($tmpl !== 'component') + { + ToolbarHelper::help('JHELP_CONTENT_MEDIA_MANAGER'); + } + } +} diff --git a/administrator/components/com_media/tmpl/file/default.php b/administrator/components/com_media/tmpl/file/default.php new file mode 100644 index 0000000000000..7f1593a4a13e0 --- /dev/null +++ b/administrator/components/com_media/tmpl/file/default.php @@ -0,0 +1,68 @@ + 'auto', 'relative' => true)); + +$params = ComponentHelper::getParams('com_media'); + +/** + * @var JForm $form + */ +$form = $this->form; + +$tmpl = Factory::getApplication()->input->getCmd('tmpl'); + +// Load the toolbar when we are in an iframe +if ($tmpl == 'component') +{ + echo Toolbar::getInstance('toolbar')->render(); +} + +// Populate the media config +$config = [ + 'apiBaseUrl' => Uri::root() . 'administrator/index.php?option=com_media&format=json', + 'csrfToken' => Session::getFormToken(), + 'uploadPath' => $this->file->path, + 'editViewUrl' => Uri::root() . 'administrator/index.php?option=com_media&view=file' . (!empty($tmpl) ? ('&tmpl=' . $tmpl) : ''), + 'allowedUploadExtensions' => $params->get('upload_extensions', ''), + 'maxUploadSizeMb' => $params->get('upload_maxsize', 10), + 'contents' => $this->file->content, +]; + +Factory::getDocument()->addScriptOptions('com_media', $config); + +$this->useCoreUI = true; +?> +
+
+ getFieldsets(); ?> + + 'attrib-' . reset($fieldSets)->name)); ?> +
'; ?> + + + + +
diff --git a/administrator/components/com_media/tmpl/media/default.php b/administrator/components/com_media/tmpl/media/default.php new file mode 100644 index 0000000000000..1b8ba132026ba --- /dev/null +++ b/administrator/components/com_media/tmpl/media/default.php @@ -0,0 +1,58 @@ +loadTemplate('texts'); + +$tmpl = Factory::getApplication()->input->getCmd('tmpl'); + +// Load the toolbar when we are in an iframe +if ($tmpl == 'component') +{ + echo Toolbar::getInstance('toolbar')->render(); +} + +// Populate the media config +$config = array( + 'apiBaseUrl' => Uri::root() . 'administrator/index.php?option=com_media&format=json', + 'csrfToken' => Session::getFormToken(), + 'filePath' => $params->get('file_path', 'images'), + 'fileBaseUrl' => Uri::root() . $params->get('file_path', 'images'), + 'fileBaseRelativeUrl' => $params->get('file_path', 'images'), + 'editViewUrl' => Uri::root() . 'administrator/index.php?option=com_media&view=file' . (!empty($tmpl) ? ('&tmpl=' . $tmpl) : ''), + 'allowedUploadExtensions' => $params->get('upload_extensions', ''), + 'maxUploadSizeMb' => $params->get('upload_maxsize', 10), + 'providers' => (array) $this->providers, + 'currentPath' => $this->currentPath, + 'isModal' => Factory::getApplication()->input->getCmd('tmpl', '') === 'component' ? true : false, +); +$doc->addScriptOptions('com_media', $config); +?> +
diff --git a/administrator/components/com_media/views/media/tmpl/default.xml b/administrator/components/com_media/tmpl/media/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_media/views/media/tmpl/default.xml rename to administrator/components/com_media/tmpl/media/default.xml diff --git a/administrator/components/com_media/tmpl/media/default_texts.php b/administrator/components/com_media/tmpl/media/default_texts.php new file mode 100644 index 0000000000000..b9b1e776546a9 --- /dev/null +++ b/administrator/components/com_media/tmpl/media/default_texts.php @@ -0,0 +1,59 @@ +input; -$params = JComponentHelper::getParams('com_media'); -$lang = JFactory::getLanguage(); -$onClick = ''; -$fieldInput = $this->state->get('field.id'); -$isMoo = $input->getInt('ismoo', 1); -$author = $input->getCmd('author'); -$asset = $input->getCmd('asset'); - -JHtml::_('formbehavior.chosen', 'select'); - -// Load tooltip instance without HTML support because we have a HTML tag in the tip -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)); - -if ($lang->isRtl()) -{ - JHtml::_('stylesheet', 'media/popup-imagemanager_rtl.css', array('version' => 'auto', 'relative' => true)); -} - -JFactory::getDocument()->addScriptOptions( - 'mediamanager', array( - 'base' => $params->get('image_path', 'images') . '/', - 'asset' => $asset, - 'author' => $author - ) -); - -/** - * Mootools compatibility - * - * There is an extra option passed in the URL for the iframe &ismoo=0 for the bootstrap fields. - * By default the value will be 1 or defaults to mootools behaviour - * - * This should be removed when mootools won't be shipped by Joomla. - */ -if (!empty($fieldInput)) // Media Form Field -{ - if ($isMoo) - { - $onClick = "window.parent.jInsertFieldValue(document.getElementById('f_url').value, '" . $fieldInput . "');window.parent.jModalClose();window.parent.jQuery('.modal.in').modal('hide');"; - } -} -else // XTD Image plugin -{ - $onClick = 'ImageManager.onok();window.parent.jModalClose();'; -} -?> -
- -
- - - -
-
-
-
- -
-
- folderList; ?> - -
-
-
- - -
-
-
- - - -
-
-
-
- -
-
- -
-
- state->get('field.id')) : ?> -
-
- -
-
- -
-
- -
- state->get('field.id')) : ?> -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
-
-
- -
-
- - - -
-
-
- - - - - - -
-
- - authorise('core.create', 'com_media')) : ?> -
-
-
-
-
- -
-
- -

- config->get('upload_maxsize'); ?> - - -

-
-
-
- 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 deleted file mode 100644 index d8e029a3ccd5b..0000000000000 --- a/administrator/components/com_media/views/images/view.html.php +++ /dev/null @@ -1,46 +0,0 @@ -session = JFactory::getSession(); - $this->config = $config; - $this->state = $this->get('state'); - $this->folderList = $this->get('folderList'); - $this->require_ftp = $ftp; - - parent::display($tpl); - } -} diff --git a/administrator/components/com_media/views/imageslist/tmpl/default.php b/administrator/components/com_media/views/imageslist/tmpl/default.php deleted file mode 100644 index dbae859ee82f1..0000000000000 --- a/administrator/components/com_media/views/imageslist/tmpl/default.php +++ /dev/null @@ -1,66 +0,0 @@ - 'auto', 'relative' => true)); - -if ($lang->isRtl()) -{ - JHtml::_('stylesheet', 'media/popup-imagelist_rtl.css', array('version' => 'auto', 'relative' => true)); -} - -JFactory::getDocument()->addScriptDeclaration('var ImageManager = window.parent.ImageManager;'); - -if ($lang->isRtl()) -{ - JFactory::getDocument()->addStyleDeclaration( - ' - @media (max-width: 767px) { - li.imgOutline.thumbnail.height-80.width-80.center { - float: right; - margin-right: 15px; - } - } - ' - ); -} -else -{ - JFactory::getDocument()->addStyleDeclaration( - ' - @media (max-width: 767px) { - li.imgOutline.thumbnail.height-80.width-80.center { - float: left; - margin-left: 15px; - } - } - ' - ); -} -?> -images) > 0 || count($this->folders) > 0) : ?> -
    - folders); $i < $n; $i++) : - $this->setFolder($i); - echo $this->loadTemplate('folder'); - endfor; ?> - - images); $i < $n; $i++) : - $this->setImage($i); - echo $this->loadTemplate('image'); - endfor; ?> -
- -
-
-
- diff --git a/administrator/components/com_media/views/imageslist/tmpl/default_folder.php b/administrator/components/com_media/views/imageslist/tmpl/default_folder.php deleted file mode 100644 index e3e503a054b00..0000000000000 --- a/administrator/components/com_media/views/imageslist/tmpl/default_folder.php +++ /dev/null @@ -1,23 +0,0 @@ -input; -?> -
  • - -
    - -
    -
    - _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 deleted file mode 100644 index 06dec4b41d7f6..0000000000000 --- a/administrator/components/com_media/views/imageslist/tmpl/default_image.php +++ /dev/null @@ -1,30 +0,0 @@ -trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params)); -?> - -
  • - -
    - 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)); ?> -
    -
    - _tmp_img->name, 10, false); ?> -
    -
    -
  • -trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params)); diff --git a/administrator/components/com_media/views/imageslist/view.html.php b/administrator/components/com_media/views/imageslist/view.html.php deleted file mode 100644 index 716cea8fe07d4..0000000000000 --- a/administrator/components/com_media/views/imageslist/view.html.php +++ /dev/null @@ -1,86 +0,0 @@ -allowCache(false); - - $images = $this->get('images'); - $folders = $this->get('folders'); - $state = $this->get('state'); - - $this->baseURL = COM_MEDIA_BASEURL; - $this->images = &$images; - $this->folders = &$folders; - $this->state = &$state; - - parent::display($tpl); - } - - /** - * Set the active folder - * - * @param integer $index Folder position - * - * @return void - * - * @since 1.0 - */ - public function setFolder($index = 0) - { - if (isset($this->folders[$index])) - { - $this->_tmp_folder = &$this->folders[$index]; - } - else - { - $this->_tmp_folder = new JObject; - } - } - - /** - * Set the active image - * - * @param integer $index Image position - * - * @return void - * - * @since 1.0 - */ - public function setImage($index = 0) - { - if (isset($this->images[$index])) - { - $this->_tmp_img = &$this->images[$index]; - } - else - { - $this->_tmp_img = new JObject; - } - } -} diff --git a/administrator/components/com_media/views/media/tmpl/default.php b/administrator/components/com_media/views/media/tmpl/default.php deleted file mode 100644 index 800cdd9e73620..0000000000000 --- a/administrator/components/com_media/views/media/tmpl/default.php +++ /dev/null @@ -1,149 +0,0 @@ -input; -$lang = JFactory::getLanguage(); -$style = JFactory::getApplication()->getUserStateFromRequest('media.list.layout', 'layout', 'thumbs', 'word'); - -if (DIRECTORY_SEPARATOR == '\\') -{ - $base = str_replace(DIRECTORY_SEPARATOR, "\\\\", COM_MEDIA_BASE); -} -else -{ - $base = COM_MEDIA_BASE; -} - -JFactory::getDocument()->addScriptDeclaration( - " - var basepath = '" . $base . "'; - var viewstyle = '" . $style . "'; - " -); - -JHtml::_('behavior.keepalive'); -JHtml::_('bootstrap.framework'); -JHtml::_('script', 'media/mediamanager.min.js', array('version' => 'auto', 'relative' => true)); -JHtml::_('script', 'media/mediaelement-and-player.js', array('version' => 'auto', 'relative' => true)); -JHtml::_('stylesheet', 'media/mediaelementplayer.css', array('version' => 'auto', 'relative' => true)); -JHtml::_('stylesheet', 'system/mootree.css', array('version' => 'auto', 'relative' => true)); - -if ($lang->isRtl()) -{ - JHtml::_('stylesheet', 'system/mootree_rtl.css', array('version' => 'auto', 'relative' => true)); -} -?> -
    - -
    - sidebar; ?> -
    -

    -
    - -
    - - - -
    - loadTemplate('navigation'); ?> - authorise('core.create', 'com_media')) and $this->require_ftp) : ?> -
    -
    - - - - - - - -
    -
    - - -
    - - - -
    - - authorise('core.create', 'com_media')) : ?> - -
    -
    -
    -
    - - -

    - config->get('upload_maxsize'); ?> - - -

    -
    - - set('com_media.return_url', 'index.php?option=com_media'); ?> -
    -
    -
    -
    -
    -
    - - - - -
    - -
    -
    - - -
    -
    -
    - -
    - -
    -
    -
    - JText::_('COM_MEDIA_PREVIEW'), - 'footer' => '', - ), - '
    preview
    ' -); - -echo JHtml::_( - 'bootstrap.renderModal', - 'videoPreview', - array( - 'title' => JText::_('COM_MEDIA_PREVIEW'), - '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 deleted file mode 100644 index 1d10cdf07cc3c..0000000000000 --- a/administrator/components/com_media/views/media/tmpl/default_folders.php +++ /dev/null @@ -1,30 +0,0 @@ -folders['data']->relative); - -?> - diff --git a/administrator/components/com_media/views/media/tmpl/default_navigation.php b/administrator/components/com_media/views/media/tmpl/default_navigation.php deleted file mode 100644 index 3e283776ef239..0000000000000 --- a/administrator/components/com_media/views/media/tmpl/default_navigation.php +++ /dev/null @@ -1,20 +0,0 @@ -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 deleted file mode 100644 index 813ac286f2aa5..0000000000000 --- a/administrator/components/com_media/views/media/view.html.php +++ /dev/null @@ -1,141 +0,0 @@ -isClient('administrator')) - { - return $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); - } - - /* - * Display form for FTP credentials? - * Don't set them here, as there are other functions called before this one if there is any file write operation - */ - $ftp = !JClientHelper::hasCredentials('ftp'); - - $session = JFactory::getSession(); - $state = $this->get('state'); - $this->session = $session; - $this->config = &$config; - $this->state = &$state; - $this->require_ftp = $ftp; - $this->folders_id = ' id="media-tree"'; - $this->folders = $this->get('folderTree'); - - $this->sidebar = JHtmlSidebar::render(); - - // Set the toolbar - $this->addToolbar(); - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - // Get the toolbar object instance - $bar = JToolbar::getInstance('toolbar'); - $user = JFactory::getUser(); - - // Set the titlebar text - JToolbarHelper::title(JText::_('COM_MEDIA'), 'images mediamanager'); - - // Add an upload button - if ($user->authorise('core.create', 'com_media')) - { - // Instantiate a new JLayoutFile instance and render the layout - $layout = new JLayoutFile('toolbar.uploadmedia'); - - $bar->appendButton('Custom', $layout->render(array()), 'upload'); - JToolbarHelper::divider(); - } - - // Add a create folder button - if ($user->authorise('core.create', 'com_media')) - { - // Instantiate a new JLayoutFile instance and render the layout - $layout = new JLayoutFile('toolbar.newfolder'); - - $bar->appendButton('Custom', $layout->render(array()), 'create'); - JToolbarHelper::divider(); - } - - // Add a delete button - if ($user->authorise('core.delete', 'com_media')) - { - // Instantiate a new JLayoutFile instance and render the layout - $layout = new JLayoutFile('toolbar.deletemedia'); - - $bar->appendButton('Custom', $layout->render(array()), 'delete'); - JToolbarHelper::divider(); - } - - // Add a preferences button - if ($user->authorise('core.admin', 'com_media') || $user->authorise('core.options', 'com_media')) - { - JToolbarHelper::preferences('com_media'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_CONTENT_MEDIA_MANAGER'); - } - - /** - * Display a folder level - * - * @param array $folder Array with folder data - * - * @return string - * - * @since 1.0 - */ - protected function getFolderLevel($folder) - { - $this->folders_id = null; - $txt = null; - - if (isset($folder['children']) && count($folder['children'])) - { - $tmp = $this->folders; - $this->folders = $folder; - $txt = $this->loadTemplate('folders'); - $this->folders = $tmp; - } - - return $txt; - } -} diff --git a/administrator/components/com_media/views/medialist/tmpl/default.php b/administrator/components/com_media/views/medialist/tmpl/default.php deleted file mode 100644 index 9b0f1f171162b..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/default.php +++ /dev/null @@ -1,10 +0,0 @@ -addScriptDeclaration( - " - Joomla.isChecked = function( isitchecked, form ) { - if ( typeof form === 'undefined' ) { - form = document.getElementById( 'mediamanager-form' ); - } - - form.boxchecked.value += isitchecked ? 1 : -1; - - // If we don't have a checkall-toggle, done. - if ( !form.elements[ 'checkall-toggle' ] ) return; - - // Toggle main toggle checkbox depending on checkbox selection - var c = true, - i, e, n; - - for ( i = 0, n = form.elements.length; i < n; i++ ) { - e = form.elements[ i ]; - - if ( e.type == 'checkbox' && e.name != 'checkall-toggle' && !e.checked ) { - c = false; - break; - } - } - - form.elements[ 'checkall-toggle' ].checked = c; - }; - " -); - -$doc->addScriptDeclaration( - " - jQuery(document).ready(function($){ - window.parent.document.updateUploader(); - $('.img-preview, .preview').each(function(index, value) { - $(this).on('click', function(e) { - window.parent.jQuery('#imagePreviewSrc').attr('src', $(this).attr('href')); - window.parent.jQuery('#imagePreview').modal('show'); - return false; - }); - }); - $('.video-preview').each(function(index, value) { - $(this).unbind('click'); - $(this).on('click', function(e) { - e.preventDefault(); - window.parent.jQuery('#videoPreview').modal('show'); - - var elementInitialised = window.parent.jQuery('#mejsPlayer').attr('src'); - - if (!elementInitialised) - { - window.parent.jQuery('#mejsPlayer').attr('src', $(this).attr('href')); - window.parent.jQuery('#mejsPlayer').mediaelementplayer(); - } - - window.parent.jQuery('#mejsPlayer')[0].player.media.setSrc($(this).attr('href')); - - return false; - }); - }); - }); - " -); -?> -
    -
    -

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

    -
    - -
    - - - - canDelete) : ?> - - - - - - - - canDelete) : ?> - - - - - - loadTemplate('up'), - $this->loadTemplate('folders'), - $this->loadTemplate('docs'), - $this->loadTemplate('videos'), - $this->loadTemplate('imgs'); - ?> - -
    - - - -
    -
    - - - - - - -
    diff --git a/administrator/components/com_media/views/medialist/tmpl/details_doc.php b/administrator/components/com_media/views/medialist/tmpl/details_doc.php deleted file mode 100644 index 9dda134d5ba70..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/details_doc.php +++ /dev/null @@ -1,42 +0,0 @@ -trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_doc, &$params)); -?> - - - - - _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->title; ?> - -   - - - - _tmp_doc->size); ?> - -authorise('core.delete', 'com_media')):?> - - - - - - -trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_doc, &$params)); diff --git a/administrator/components/com_media/views/medialist/tmpl/details_docs.php b/administrator/components/com_media/views/medialist/tmpl/details_docs.php deleted file mode 100644 index ad13877202b17..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/details_docs.php +++ /dev/null @@ -1,54 +0,0 @@ - - -documents as $i => $doc) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$doc, &$params)); ?> - - canDelete) : ?> - - 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); ?> - - - - - title; ?> - - -   - - - size); ?> - - - canDelete) : ?> - - - - - - - - - trigger('onContentAfterDisplay', array('com_media.file', &$doc, &$params)); ?> - diff --git a/administrator/components/com_media/views/medialist/tmpl/details_folder.php b/administrator/components/com_media/views/medialist/tmpl/details_folder.php deleted file mode 100644 index 52999c9580161..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/details_folder.php +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - _tmp_folder->name; ?> - -   - - -   - - - 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 deleted file mode 100644 index 078fd93c2aa75..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/details_folders.php +++ /dev/null @@ -1,42 +0,0 @@ - - -folders as $i => $folder) : ?> - path_relative; ?> - - canDelete) : ?> - - name, false, 'rm', 'cb-folder'); ?> - - - - - - - - name; ?> - - -   - -   - - 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 deleted file mode 100644 index 82ef0681e4c45..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/details_img.php +++ /dev/null @@ -1,42 +0,0 @@ -trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params)); -?> - - - - _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); ?> - - - _tmp_img->width, $this->_tmp_img->height); ?> - - - _tmp_img->size); ?> - - authorise('core.delete', 'com_media')):?> - - - - - - -trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params)); diff --git a/administrator/components/com_media/views/medialist/tmpl/details_imgs.php b/administrator/components/com_media/views/medialist/tmpl/details_imgs.php deleted file mode 100644 index 635fb7efb8551..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/details_imgs.php +++ /dev/null @@ -1,59 +0,0 @@ - - -images as $i => $image) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$image, &$params)); ?> - - canDelete) : ?> - - 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->title); ?> - - - - - width, $image->height); ?> - - - - size); ?> - - - canDelete) : ?> - - - - - - - - trigger('onContentAfterDisplay', array('com_media.file', &$image, &$params)); ?> - diff --git a/administrator/components/com_media/views/medialist/tmpl/details_up.php b/administrator/components/com_media/views/medialist/tmpl/details_up.php deleted file mode 100644 index 27dbe632dcd2c..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/details_up.php +++ /dev/null @@ -1,32 +0,0 @@ - -state->folder != '') : ?> - - canDelete) : ?> -   - - - - - - - .. - -   -   - authorise('core.delete', 'com_media')) : ?> -   - - - diff --git a/administrator/components/com_media/views/medialist/tmpl/details_video.php b/administrator/components/com_media/views/medialist/tmpl/details_video.php deleted file mode 100644 index 305ae3077839b..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/details_video.php +++ /dev/null @@ -1,54 +0,0 @@ -trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_video, &$params)); - -JFactory::getDocument()->addScriptDeclaration(" -jQuery(document).ready(function($){ - window.parent.jQuery('#videoPreview').on('hidden', function () { - window.parent.jQuery('#mejsPlayer')[0].player.pause(); - }); -}); -"); -?> - - - - _tmp_video->icon_16, $this->_tmp_video->title, null, true); ?> - - - - _tmp_video->name, 10, false); ?> - - - - - - - _tmp_video->size); ?> - - authorise('core.delete', 'com_media')):?> - - - - - - - -trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_video, &$params)); diff --git a/administrator/components/com_media/views/medialist/tmpl/details_videos.php b/administrator/components/com_media/views/medialist/tmpl/details_videos.php deleted file mode 100644 index 420d7621eb0cf..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/details_videos.php +++ /dev/null @@ -1,67 +0,0 @@ -addScriptDeclaration(" -jQuery(document).ready(function($){ - window.parent.jQuery('#videoPreview').on('hidden', function () { - window.parent.jQuery('#mejsPlayer')[0].player.pause(); - }); -}); -"); -?> - -videos as $i => $video) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$video, &$params)); ?> - - canDelete) : ?> - - name, false, 'rm', 'cb-video'); ?> - - - - - - icon_16, $video->title, null, true); ?> - - - - - - name, 10, false); ?> - - - - - - - - - size); ?> - - - canDelete) : ?> - - - - - - - - - trigger('onContentAfterDisplay', array('com_media.file', &$video, &$params)); ?> - diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs.php b/administrator/components/com_media/views/medialist/tmpl/thumbs.php deleted file mode 100644 index f1428a664f209..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs.php +++ /dev/null @@ -1,117 +0,0 @@ -addScriptDeclaration( - " - Joomla.isChecked = function( isitchecked, form ) { - if ( typeof form === 'undefined' ) { - form = document.getElementById( 'mediamanager-form' ); - } - - form.boxchecked.value += isitchecked ? 1 : -1; - - // If we don't have a checkall-toggle, done. - if ( !form.elements[ 'checkall-toggle' ] ) return; - - // Toggle main toggle checkbox depending on checkbox selection - var c = true, - i, e, n; - - for ( i = 0, n = form.elements.length; i < n; i++ ) { - e = form.elements[ i ]; - - if ( e.type == 'checkbox' && e.name != 'checkall-toggle' && !e.checked ) { - c = false; - break; - } - } - - form.elements[ 'checkall-toggle' ].checked = c; - }; - " -); - -$doc->addScriptDeclaration( - " - jQuery(document).ready(function($){ - window.parent.document.updateUploader(); - $('.img-preview, .preview').each(function(index, value) { - $(this).on('click', function(e) { - window.parent.jQuery('#imagePreviewSrc').attr('src', $(this).attr('href')); - window.parent.jQuery('#imagePreview').modal('show'); - return false; - }); - }); - $('.video-preview').each(function(index, value) { - $(this).unbind('click'); - $(this).on('click', function(e) { - e.preventDefault(); - window.parent.jQuery('#videoPreview').modal('show'); - - var elementInitialised = window.parent.jQuery('#mejsPlayer').attr('src'); - - if (!elementInitialised) - { - window.parent.jQuery('#mejsPlayer').attr('src', $(this).attr('href')); - window.parent.jQuery('#mejsPlayer').mediaelementplayer(); - } - - window.parent.jQuery('#mejsPlayer')[0].player.media.setSrc($(this).attr('href')); - - return false; - }); - }); - }); - " -); -?> -
    - - -
    - -
    - -
      - loadTemplate('up'), - $this->loadTemplate('folders'), - $this->loadTemplate('docs'), - $this->loadTemplate('videos'), - $this->loadTemplate('imgs'); - ?> - - - - - - -
    -
    diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php b/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php deleted file mode 100644 index 22854c73ed844..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_docs.php +++ /dev/null @@ -1,40 +0,0 @@ - - -documents as $i => $doc) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$doc, &$params)); ?> -
  • - canDelete) : ?> - × -
    - name, false, 'rm', 'cb-document'); ?> -
    -
    - - - - -
    - name, 10, false); ?> -
    -
  • - trigger('onContentAfterDisplay', array('com_media.file', &$doc, &$params)); ?> - diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php b/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php deleted file mode 100644 index 34e678046a4b1..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_folders.php +++ /dev/null @@ -1,35 +0,0 @@ - -folders as $i => $folder) : ?> -
  • - canDelete) : ?> - × -
    - 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 deleted file mode 100644 index 61ad6807862fb..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_imgs.php +++ /dev/null @@ -1,44 +0,0 @@ - - -images as $i => $img) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$img, &$params)); ?> -
  • - canDelete) : ?> - × -
    - name, false, 'rm', 'cb-image'); ?> -
    -
    - - - - - -
  • - trigger('onContentAfterDisplay', array('com_media.file', &$img, &$params)); ?> - diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php b/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php deleted file mode 100644 index eec7f167ad902..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_up.php +++ /dev/null @@ -1,27 +0,0 @@ - -state->folder != '') : ?> -
  • -
    -
    - - -
    -
    -
    -   -
    -
    - .. -
    -
  • - diff --git a/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php b/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php deleted file mode 100644 index 6b9502eb04883..0000000000000 --- a/administrator/components/com_media/views/medialist/tmpl/thumbs_videos.php +++ /dev/null @@ -1,47 +0,0 @@ -addScriptDeclaration(" -jQuery(document).ready(function($){ - window.parent.jQuery('#videoPreview').on('hidden', function () { - window.parent.jQuery('#mejsPlayer')[0].player.pause(); - }); -}); -"); -?> -videos as $i => $video) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$video, &$params)); ?> -
  • - canDelete) : ?> - × -
    - name, false, 'rm', 'cb-video'); ?> -
    -
    - - -
    - icon_32, $video->title, null, true); ?> -
    - - -
  • - trigger('onContentAfterDisplay', array('com_media.file', &$video, &$params)); ?> - diff --git a/administrator/components/com_media/views/medialist/view.html.php b/administrator/components/com_media/views/medialist/view.html.php deleted file mode 100644 index b8f082db27559..0000000000000 --- a/administrator/components/com_media/views/medialist/view.html.php +++ /dev/null @@ -1,63 +0,0 @@ -isClient('administrator')) - { - return $app->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'warning'); - } - - // Do not allow cache - $app->allowCache(false); - - $this->images = $this->get('images'); - $this->documents = $this->get('documents'); - $this->folders = $this->get('folders'); - $this->videos = $this->get('videos'); - $this->state = $this->get('state'); - - // Check for invalid folder name - if (empty($this->state->folder)) - { - $dirname = JFactory::getApplication()->input->getPath('folder', ''); - - if (!empty($dirname)) - { - $dirname = htmlspecialchars($dirname, ENT_COMPAT, 'UTF-8'); - JError::raiseWarning(100, JText::sprintf('COM_MEDIA_ERROR_UNABLE_TO_BROWSE_FOLDER_WARNDIRNAME', $dirname)); - } - } - - $user = JFactory::getUser(); - $this->canDelete = $user->authorise('core.delete', 'com_media'); - - parent::display($tpl); - } -} diff --git a/administrator/components/com_media/webpack.config.js b/administrator/components/com_media/webpack.config.js new file mode 100644 index 0000000000000..03e3f681c5c82 --- /dev/null +++ b/administrator/components/com_media/webpack.config.js @@ -0,0 +1,85 @@ +var path = require('path') +var webpack = require('webpack') +var ExtractTextPlugin = require('extract-text-webpack-plugin'); + +module.exports = { + entry: [ + './resources/scripts/mediamanager.js', + './resources/styles/mediamanager.scss', + ], + output: { + path: path.resolve(__dirname, './../../../media/com_media/js'), + publicPath: '/', + filename: 'mediamanager.min.js' + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + options: { + loaders: { + // Since sass-loader (weirdly) has SCSS as its default parse mode, we map + // the "scss" and "sass" values for the lang attribute to the right configs here. + // other preprocessors should work out of the box, no loader config like this necessary. + 'scss': 'vue-style-loader!css-loader!sass-loader', + 'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax' + } + // other vue-loader options go here + } + }, + { + test: /\.js$/, + loader: 'babel-loader', + exclude: /node_modules/ + }, + { + test: /\.(png|jpg|gif|svg)$/, + loader: 'file-loader', + options: { + name: '[name].[ext]?[hash]' + } + }, + { + test: /\.scss$/, + loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader']) + } + ] + }, + plugins: [ + new ExtractTextPlugin({ + filename: './../../../media/com_media/css/mediamanager.min.css', + allChunks: true, + }), + ], + resolve: { + alias: { + 'vue$': 'vue/dist/vue.esm.js' + } + }, + performance: { + hints: false + }, + devtool: '#eval-source-map' +} + +if (process.env.NODE_ENV === 'production') { + module.exports.devtool = '#source-map' + // http://vue-loader.vuejs.org/en/workflow/production.html + module.exports.plugins = (module.exports.plugins || []).concat([ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"production"' + } + }), + new webpack.optimize.UglifyJsPlugin({ + sourceMap: true, + compress: { + warnings: false + } + }), + new webpack.LoaderOptionsPlugin({ + minimize: true + }) + ]) +} \ No newline at end of file diff --git a/administrator/components/com_menus/Controller/DisplayController.php b/administrator/components/com_menus/Controller/DisplayController.php new file mode 100644 index 0000000000000..0060a6ce017cf --- /dev/null +++ b/administrator/components/com_menus/Controller/DisplayController.php @@ -0,0 +1,91 @@ +metadata['nativeName'])) + { + $languageName = $language->metadata['nativeName']; + } + else + { + $languageName = $language->metadata['name']; + } + + $langCodes[$language->metadata['tag']] = $languageName; + } + + $db = Factory::getDbo(); + $query = $db->getQuery(true); + + $query->select($db->quoteName('m.language')) + ->from($db->quoteName('#__modules', 'm')) + ->where($db->quoteName('m.module') . ' = ' . $db->quote('mod_menu')) + ->where($db->quoteName('m.published') . ' = 1') + ->where($db->quoteName('m.client_id') . ' = 1') + ->group($db->quoteName('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 = Factory::getApplication(); + $langMissing = array_intersect_key($langCodes, array_flip($langMissing)); + + $app->enqueueMessage(Text::sprintf('JMENU_MULTILANG_WARNING_MISSING_MODULES', implode(', ', $langMissing)), 'warning'); + } + } + + return parent::display(); + } +} diff --git a/administrator/components/com_menus/Controller/ItemController.php b/administrator/components/com_menus/Controller/ItemController.php new file mode 100644 index 0000000000000..e73510c82f27d --- /dev/null +++ b/administrator/components/com_menus/Controller/ItemController.php @@ -0,0 +1,625 @@ +input->getCmd('menutype', $data['menutype'] ?? ''); + + $menutypeID = 0; + + // Load menutype ID + if ($menuType) + { + $menutypeID = (int) $this->getMenuTypeId($menuType); + } + + return $user->authorise('core.create', 'com_menus.menu.' . $menutypeID); + } + + /** + * Method to check if you edit a record. + * + * Extended classes can override this if necessary. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key; default is id. + * + * @return boolean + * + * @since 3.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + $user = Factory::getUser(); + + $menutypeID = 0; + + if (isset($data[$key])) + { + $model = $this->getModel(); + $item = $model->getItem($data[$key]); + + if (!empty($item->menutype)) + { + // Protected menutype, do not allow edit + if ($item->menutype == 'main') + { + return false; + } + + $menutypeID = (int) $this->getMenuTypeId($item->menutype); + } + } + + return $user->authorise('core.edit', 'com_menus.menu.' . (int) $menutypeID); + } + + /** + * Loads the menutype ID by a given menutype string + * + * @param string $menutype The given menutype + * + * @return integer + * + * @since 3.6 + */ + protected function getMenuTypeId($menutype) + { + $model = $this->getModel(); + $table = $model->getTable('MenuType'); + + $table->load(array('menutype' => $menutype)); + + return (int) $table->id; + } + + /** + * Method to add a new menu item. + * + * @return mixed True if the record can be added, otherwise false. + * + * @since 1.6 + */ + public function add() + { + $result = parent::add(); + + if ($result) + { + $context = 'com_menus.edit.item'; + + $this->app->setUserState($context . '.type', null); + $this->app->setUserState($context . '.link', null); + } + + return $result; + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True if successful, false otherwise and internal error is set. + * + * @since 1.6 + */ + public function batch($model = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Menus\Administrator\Model\ItemModel $model */ + $model = $this->getModel('Item', 'Administrator', array()); + + // Preset the redirect + $this->setRedirect(Route::_('index.php?option=com_menus&view=items' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + + /** + * Method to cancel an edit. + * + * @param string $key The name of the primary key of the URL variable. + * + * @return boolean True if access level checks pass, false otherwise. + * + * @since 1.6 + */ + public function cancel($key = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $result = parent::cancel(); + + if ($result) + { + // Clear the ancillary data from the session. + $context = 'com_menus.edit.item'; + $this->app->setUserState($context . '.type', null); + $this->app->setUserState($context . '.link', null); + + // Redirect to the list screen. + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend() + . '&menutype=' . $this->app->getUserState('com_menus.items.menutype'), false + ) + ); + } + + return $result; + } + + /** + * Method to edit an existing record. + * + * @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 access level check and checkout passes, false otherwise. + * + * @since 1.6 + */ + public function edit($key = null, $urlVar = null) + { + $result = parent::edit(); + + if ($result) + { + // Push the new ancillary data into the session. + $this->app->setUserState('com_menus.edit.item.type', null); + $this->app->setUserState('com_menus.edit.item.link', null); + } + + return $result; + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since 12.2 + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') + { + $append = parent::getRedirectToItemAppend($recordId, $urlVar); + + if ($recordId) + { + /* @var \Joomla\Component\Menus\Administrator\Model\ItemModel $model */ + $model = $this->getModel(); + $item = $model->getItem($recordId); + $clientId = $item->client_id; + $append = '&client_id=' . $clientId . $append; + } + else + { + $clientId = $this->input->get('client_id', '0', 'int'); + $menuType = $this->input->get('menutype', 'mainmenu', 'cmd'); + $append = '&client_id=' . $clientId . ($menuType ? '&menutype=' . $menuType : '') . $append; + } + + return $append; + } + + /** + * Method to save a record. + * + * @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 1.6 + */ + public function save($key = null, $urlVar = null) + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $app = $this->app; + + /* @var \Joomla\Component\Menus\Administrator\Model\ItemModel $model */ + $model = $this->getModel('Item', 'Administrator', array()); + $table = $model->getTable(); + $data = $this->input->post->get('jform', array(), 'array'); + $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)) + { + $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); + + // Populate the row id from the session. + $data[$key] = $recordId; + + // The save2copy task needs to be handled slightly differently. + if ($task == 'save2copy') + { + // Check-in the original row. + if ($model->checkin($data['id']) === false) + { + // Check-in failed, go back to the item and display a notice. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'warning'); + + return false; + } + + // Reset the ID and then treat the request as for Apply. + $data['id'] = 0; + $data['associations'] = array(); + $task = 'apply'; + } + + // Access check. + if (!$this->allowSave($data, $key)) + { + $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . $this->getRedirectToListAppend(), false + ) + ); + + return false; + } + + // Validate the posted data. + // This post is made up of two forms, one for the item and one for params. + $form = $model->getForm($data); + + if (!$form) + { + throw new \Exception($model->getError(), 500); + + return false; + } + + if ($data['type'] == 'url') + { + $data['link'] = str_replace(array('"', '>', '<'), '', $data['link']); + + if (strstr($data['link'], ':')) + { + $segments = explode(':', $data['link']); + $protocol = strtolower($segments[0]); + $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)) + { + $app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'warning'); + $this->setRedirect( + Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false) + ); + + return false; + } + } + } + + $data = $model->validate($form, $data); + + // Preprocess request fields to ensure that we remove not set or empty request params + $request = $form->getGroup('request'); + + // Check for the special 'request' entry. + if ($data['type'] == 'component' && !empty($request)) + { + $removeArgs = array(); + + if (!isset($data['request']) || !is_array($data['request'])) + { + $data['request'] = array(); + } + + foreach ($request as $field) + { + $fieldName = $field->getAttribute('name'); + + if (!isset($data['request'][$fieldName]) || $data['request'][$fieldName] == '') + { + $removeArgs[$fieldName] = ''; + } + } + + // Parse the submitted link arguments. + $args = array(); + parse_str(parse_url($data['link'], PHP_URL_QUERY), $args); + + // Merge in the user supplied request arguments. + $args = array_merge($args, $data['request']); + + // Remove the unused request params + if (!empty($args) && !empty($removeArgs)) + { + $args = array_diff_key($args, $removeArgs); + } + + $data['link'] = 'index.php?' . urldecode(http_build_query($args, '', '&')); + unset($data['request']); + } + + // Check for validation errors. + if ($data === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // 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) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState('com_menus.edit.item.data', $data); + + // Redirect back to the edit screen. + $editUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); + $this->setRedirect(Route::_($editUrl, false)); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Save the data in the session. + $app->setUserState('com_menus.edit.item.data', $data); + + // Redirect back to the edit screen. + $editUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); + $this->setRedirect(Route::_($editUrl, false)); + + return false; + } + + // Save succeeded, check-in the row. + if ($model->checkin($data['id']) === false) + { + // Check-in failed, go back to the row and display a notice. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'warning'); + $redirectUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); + $this->setRedirect(Route::_($redirectUrl, false)); + + return false; + } + + $this->setMessage(Text::_('COM_MENUS_SAVE_SUCCESS')); + + // Redirect the user and adjust session state based on the chosen task. + switch ($task) + { + case 'apply': + // Set the row data in the session. + $recordId = $model->getState($this->context . '.id'); + $this->holdEditId($context, $recordId); + $app->setUserState('com_menus.edit.item.data', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); + + // Redirect back to the edit screen. + $editUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); + $this->setRedirect(Route::_($editUrl, false)); + break; + + case 'save2new': + // Clear the row id and data in the session. + $this->releaseEditId($context, $recordId); + $app->setUserState('com_menus.edit.item.data', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); + + // Redirect back to the edit screen. + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(), false)); + break; + + default: + // Clear the row id and data in the session. + $this->releaseEditId($context, $recordId); + $app->setUserState('com_menus.edit.item.data', null); + $app->setUserState('com_menus.edit.item.type', null); + $app->setUserState('com_menus.edit.item.link', null); + + // Redirect to the list screen. + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend() + . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false + ) + ); + break; + } + + return true; + } + + /** + * Sets the type of the menu item currently being edited. + * + * @return void + * + * @since 1.6 + */ + public function setType() + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $app = $this->app; + + // Get the posted values from the request. + $data = $this->input->post->get('jform', array(), 'array'); + + // Get the type. + $type = $data['type']; + + $type = json_decode(base64_decode($type)); + $title = $type->title ?? null; + $recordId = $type->id ?? 0; + + $specialTypes = array('alias', 'separator', 'url', 'heading', 'container'); + + if (!in_array($title, $specialTypes)) + { + $title = 'component'; + } + else + { + // Set correct component id to ensure proper 404 messages with system links + $data['component_id'] = 0; + } + + $app->setUserState('com_menus.edit.item.type', $title); + + if ($title == 'component') + { + if (isset($type->request)) + { + // Clean component name + $type->request->option = InputFilter::getInstance()->clean($type->request->option, 'CMD'); + + $component = ComponentHelper::getComponent($type->request->option); + $data['component_id'] = $component->id; + + $app->setUserState('com_menus.edit.item.link', 'index.php?' . Uri::buildQuery((array) $type->request)); + } + } + // If the type is alias you just need the item id from the menu item referenced. + elseif ($title == 'alias') + { + $app->setUserState('com_menus.edit.item.link', 'index.php?Itemid='); + } + + unset($data['request']); + + $data['type'] = $title; + + if ($this->input->get('fieldtype') == 'type') + { + $data['link'] = $app->getUserState('com_menus.edit.item.link'); + } + + // Save the data in the session. + $app->setUserState('com_menus.edit.item.data', $data); + + $this->type = $type; + $this->setRedirect( + Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false) + ); + } + + /** + * Gets the parent items of the menu location currently. + * + * @return void + * + * @since 3.2 + */ + public function getParentItem() + { + $app = $this->app; + + $results = array(); + $menutype = $this->input->get->get('menutype'); + + if ($menutype) + { + /* @var \Joomla\Component\Menus\Administrator\Model\ItemsModel $model */ + $model = $this->getModel('Items', 'Administrator', array()); + $model->getState(); + $model->setState('filter.menutype', $menutype); + $model->setState('list.select', 'a.id, a.title, a.level'); + $model->setState('list.start', '0'); + $model->setState('list.limit', '0'); + + $results = $model->getItems(); + + // Pad the option text with spaces using depth level as a multiplier. + for ($i = 0, $n = count($results); $i < $n; $i++) + { + $results[$i]->title = str_repeat(' - ', $results[$i]->level) . $results[$i]->title; + } + } + + // Output a \JSON object + echo json_encode($results); + + $app->close(); + } +} diff --git a/administrator/components/com_menus/Controller/ItemsController.php b/administrator/components/com_menus/Controller/ItemsController.php new file mode 100644 index 0000000000000..400e82a10e81d --- /dev/null +++ b/administrator/components/com_menus/Controller/ItemsController.php @@ -0,0 +1,329 @@ +registerTask('unsetDefault', 'setDefault'); + } + + /** + * Proxy for getModel. + * + * @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 1.6 + */ + public function getModel($name = 'Item', $prefix = 'Administrator', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Rebuild the nested set tree. + * + * @return boolean False on failure or error, true on success. + * + * @since 1.6 + */ + public function rebuild() + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $this->setRedirect('index.php?option=com_menus&view=items'); + + /* @var \Joomla\Component\Menus\Administrator\Model\ItemModel $model */ + $model = $this->getModel(); + + if ($model->rebuild()) + { + // Reorder succeeded. + $this->setMessage(Text::_('COM_MENUS_ITEMS_REBUILD_SUCCESS')); + + return true; + } + else + { + // Rebuild failed. + $this->setMessage(Text::sprintf('COM_MENUS_ITEMS_REBUILD_FAILED'), 'error'); + + return false; + } + } + + /** + * Save the manual order inputs from the menu items list view + * + * @return void + * + * @see \JControllerAdmin::saveorder() + * @deprecated 4.0 + */ + public function saveorder() + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + try + { + Log::add( + sprintf('%s() is deprecated. Function will be removed in 4.0.', __METHOD__), + Log::WARNING, + 'deprecated' + ); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + // Get the arrays from the Request + $order = $this->input->post->get('order', null, 'array'); + $originalOrder = explode(',', $this->input->getString('original_order_values')); + + // Make sure something has changed + if (!($order === $originalOrder)) + { + parent::saveorder(); + } + else + { + // Nothing to reorder + $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); + + return true; + } + } + + /** + * Method to set the home property for a list of items + * + * @return void + * + * @since 1.6 + */ + public function setDefault() + { + // Check for request forgeries + Session::checkToken('request') or die(Text::_('JINVALID_TOKEN')); + + $app = $this->app; + + // Get items to publish from the request. + $cid = $this->input->get('cid', array(), 'array'); + $data = array('setDefault' => 1, 'unsetDefault' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($data, $task, 0, 'int'); + + if (empty($cid)) + { + $this->setMessage(Text::_($this->text_prefix . '_NO_ITEM_SELECTED'), 'warning'); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Publish the items. + if (!$model->setHome($cid, $value)) + { + $this->setMessage($model->getError(), 'warning'); + } + else + { + if ($value == 1) + { + $ntext = 'COM_MENUS_ITEMS_SET_HOME'; + } + else + { + $ntext = 'COM_MENUS_ITEMS_UNSET_HOME'; + } + + $this->setMessage(Text::plural($ntext, count($cid))); + } + } + + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false + ) + ); + } + + /** + * Method to publish a list of items + * + * @return void + * + * @since 3.6.0 + */ + public function publish() + { + // Check for request forgeries + Session::checkToken() or die(Text::_('JINVALID_TOKEN')); + + // Get items to publish from the request. + $cid = $this->input->get('cid', array(), 'array'); + $data = array('publish' => 1, 'unpublish' => 0, 'trash' => -2, 'report' => -3); + $task = $this->getTask(); + $value = ArrayHelper::getValue($data, $task, 0, 'int'); + + if (empty($cid)) + { + try + { + Log::add(Text::_($this->text_prefix . '_NO_ITEM_SELECTED'), Log::WARNING, 'jerror'); + } + catch (\RuntimeException $exception) + { + $this->setMessage(Text::_($this->text_prefix . '_NO_ITEM_SELECTED'), 'warning'); + } + } + else + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $cid = ArrayHelper::toInteger($cid); + + // Publish the items. + try + { + $model->publish($cid, $value); + $errors = $model->getErrors(); + $messageType = 'message'; + + if ($value == 1) + { + if ($errors) + { + $messageType = 'error'; + $ntext = $this->text_prefix . '_N_ITEMS_FAILED_PUBLISHING'; + } + else + { + $ntext = $this->text_prefix . '_N_ITEMS_PUBLISHED'; + } + } + elseif ($value == 0) + { + $ntext = $this->text_prefix . '_N_ITEMS_UNPUBLISHED'; + } + else + { + $ntext = $this->text_prefix . '_N_ITEMS_TRASHED'; + } + + $this->setMessage(Text::plural($ntext, count($cid)), $messageType); + } + catch (\Exception $e) + { + $this->setMessage($e->getMessage(), 'error'); + } + } + + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list . '&menutype=' . + Factory::getApplication()->getUserState('com_menus.items.menutype'), + false + ) + ); + } + + /** + * Check in of one or more records. + * + * @return boolean True on success + * + * @since 3.6.0 + */ + public function checkin() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->post->get('cid', array(), 'array'); + + $model = $this->getModel(); + $return = $model->checkin($ids); + + if ($return === false) + { + // Checkin failed. + $message = Text::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()); + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&menutype=' . $this->app->getUserState('com_menus.items.menutype'), + false + ), + $message, + 'error' + ); + + return false; + } + else + { + // Checkin succeeded. + $message = Text::plural($this->text_prefix . '_N_ITEMS_CHECKED_IN', count($ids)); + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&menutype=' . $this->app->getUserState('com_menus.items.menutype'), + false + ), + $message + ); + + return true; + } + } +} diff --git a/administrator/components/com_menus/Controller/MenuController.php b/administrator/components/com_menus/Controller/MenuController.php new file mode 100644 index 0000000000000..696c32ed46693 --- /dev/null +++ b/administrator/components/com_menus/Controller/MenuController.php @@ -0,0 +1,220 @@ +setRedirect(Route::_('index.php?option=com_menus&view=menus', false)); + } + + /** + * Method to save a menu item. + * + * @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 1.6 + */ + public function save($key = null, $urlVar = null) + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $app = $this->app; + $data = $this->input->post->get('jform', array(), 'array'); + $context = 'com_menus.edit.menu'; + $task = $this->getTask(); + $recordId = $this->input->getInt('id'); + + // Prevent using 'main' as menutype as this is reserved for backend menus + if (strtolower($data['menutype']) == 'main') + { + $this->setMessage(Text::_('COM_MENUS_ERROR_MENUTYPE'), 'error'); + + // Redirect back to the edit screen. + $this->setRedirect(Route::_('index.php?option=com_menus&view=menu&layout=edit', false)); + + return false; + } + + // Populate the row id from the session. + $data['id'] = $recordId; + + // Get the model and attempt to validate the posted data. + /* @var \Joomla\Component\Menus\Administrator\Model\MenuModel $model */ + $model = $this->getModel('Menu'); + $form = $model->getForm(); + + if (!$form) + { + throw new \Exception($model->getError(), 500); + + return false; + } + + $validData = $model->validate($form, $data); + + // Check for validation errors. + if ($validData === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // 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) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState($context . '.data', $data); + + // Redirect back to the edit screen. + $this->setRedirect(Route::_('index.php?option=com_menus&view=menu&layout=edit', false)); + + return false; + } + + if (isset($validData['preset'])) + { + $preset = trim($validData['preset']) ?: null; + + unset($validData['preset']); + } + + // Attempt to save the data. + if (!$model->save($validData)) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + // Redirect back to the edit screen. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); + $this->setRedirect(Route::_('index.php?option=com_menus&view=menu&layout=edit', false)); + + return false; + } + + // Import the preset selected + if (isset($preset) && $data['client_id'] == 1) + { + try + { + MenusHelper::installPreset($preset, $data['menutype']); + + $this->setMessage(Text::_('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(Text::sprintf('COM_MENUS_PRESET_IMPORT_FAILED', $e->getMessage())); + } + } + else + { + $this->setMessage(Text::_('COM_MENUS_MENU_SAVE_SUCCESS')); + } + + // Redirect the user and adjust session state based on the chosen task. + switch ($task) + { + case 'apply': + // Set the record data in the session. + $recordId = $model->getState($this->context . '.id'); + $this->holdEditId($context, $recordId); + + // Redirect back to the edit screen. + $this->setRedirect(Route::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); + break; + + case 'save2new': + // Clear the record id and data from the session. + $this->releaseEditId($context, $recordId); + $app->setUserState($context . '.data', null); + + // Redirect back to the edit screen. + $this->setRedirect(Route::_('index.php?option=com_menus&view=menu&layout=edit', false)); + break; + + default: + // Clear the record id and data from the session. + $this->releaseEditId($context, $recordId); + $app->setUserState($context . '.data', null); + + // Redirect to the list screen. + $this->setRedirect(Route::_('index.php?option=com_menus&view=menus', false)); + 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(Text::_('COM_MENUS_SELECT_MENU_FIRST_EXPORT'), 'warning'); + + $this->setRedirect(Route::_('index.php?option=com_menus&view=menus', false)); + + return false; + } + + $this->setRedirect(Route::_('index.php?option=com_menus&view=menu&menutype=' . $item->menutype . '&format=xml', false)); + + return true; + } +} diff --git a/administrator/components/com_menus/Controller/MenusController.php b/administrator/components/com_menus/Controller/MenusController.php new file mode 100644 index 0000000000000..fd231e33c696e --- /dev/null +++ b/administrator/components/com_menus/Controller/MenusController.php @@ -0,0 +1,241 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Remove an item. + * + * @return void + * + * @since 1.6 + */ + public function delete() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $user = Factory::getUser(); + $app = Factory::getApplication(); + $cids = (array) $this->input->get('cid', array(), 'array'); + + if (count($cids) < 1) + { + $this->setMessage(Text::_('COM_MENUS_NO_MENUS_SELECTED'), 'warning'); + } + else + { + // Access checks. + foreach ($cids as $i => $id) + { + if (!$user->authorise('core.delete', 'com_menus.menu.' . (int) $id)) + { + // Prune items that you can't change. + unset($cids[$i]); + $app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'error'); + } + } + + if (count($cids) > 0) + { + // Get the model. + /* @var \Joomla\Component\Menus\Administrator\Model\MenuModel $model */ + $model = $this->getModel(); + + // Make sure the item ids are integers + $cids = ArrayHelper::toInteger($cids); + + // Remove the items. + if (!$model->delete($cids)) + { + $this->setMessage($model->getError(), 'error'); + } + else + { + $this->setMessage(Text::plural('COM_MENUS_N_MENUS_DELETED', count($cids))); + } + } + } + + $this->setRedirect('index.php?option=com_menus&view=menus'); + } + + /** + * Rebuild the menu tree. + * + * @return boolean False on failure or error, true on success. + * + * @since 1.6 + */ + public function rebuild() + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $this->setRedirect('index.php?option=com_menus&view=menus'); + + /* @var \Joomla\Component\Menus\Administrator\Model\ItemModel $model */ + $model = $this->getModel('Item'); + + if ($model->rebuild()) + { + // Reorder succeeded. + $this->setMessage(Text::_('JTOOLBAR_REBUILD_SUCCESS')); + + return true; + } + else + { + // Rebuild failed. + $this->setMessage(Text::sprintf('JTOOLBAR_REBUILD_FAILED', $model->getError()), 'error'); + + return false; + } + } + + /** + * Temporary method. This should go into the 1.5 to 1.6 upgrade routines. + * + * @return void + * + * @since 1.6 + */ + public function resync() + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $parts = null; + + try + { + $query->select('element, extension_id') + ->from('#__extensions') + ->where('type = ' . $db->quote('component')); + $db->setQuery($query); + + $components = $db->loadAssocList('element', 'extension_id'); + } + catch (\RuntimeException $e) + { + $this->setMessage($e->getMessage(), 'warning'); + + return; + } + + // Load all the component menu links + $query->select($db->quoteName('id')) + ->select($db->quoteName('link')) + ->select($db->quoteName('component_id')) + ->from('#__menu') + ->where($db->quoteName('type') . ' = ' . $db->quote('component.item')); + $db->setQuery($query); + + try + { + $items = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + $this->setMessage($e->getMessage(), 'warning'); + + return; + } + + foreach ($items as $item) + { + // Parse the link. + parse_str(parse_url($item->link, PHP_URL_QUERY), $parts); + + // Tease out the option. + if (isset($parts['option'])) + { + $option = $parts['option']; + + // Lookup the component ID + if (isset($components[$option])) + { + $componentId = $components[$option]; + } + else + { + // Mismatch. Needs human intervention. + $componentId = -1; + } + + // Check for mis-matched component id's in the menu link. + if ($item->component_id != $componentId) + { + // Update the menu table. + $log = "Link $item->id refers to $item->component_id, converting to $componentId ($item->link)"; + echo "
    $log"; + + $query->clear(); + $query->update('#__menu') + ->set('component_id = ' . $componentId) + ->where('id = ' . $item->id); + + try + { + $db->setQuery($query)->execute(); + } + catch (\RuntimeException $e) + { + $this->setMessage($e->getMessage(), 'warning'); + + return; + } + } + } + } + } +} diff --git a/administrator/components/com_menus/Extension/MenusComponent.php b/administrator/components/com_menus/Extension/MenusComponent.php new file mode 100644 index 0000000000000..b9384666a0d57 --- /dev/null +++ b/administrator/components/com_menus/Extension/MenusComponent.php @@ -0,0 +1,50 @@ +getRegistry()->register('menus', new Menus); + } +} diff --git a/administrator/components/com_menus/Field/ComponentscategoryField.php b/administrator/components/com_menus/Field/ComponentscategoryField.php new file mode 100644 index 0000000000000..7baa572e9a898 --- /dev/null +++ b/administrator/components/com_menus/Field/ComponentscategoryField.php @@ -0,0 +1,81 @@ +getQuery(true) + ->select('DISTINCT a.name AS text, a.element AS value') + ->from('#__extensions as a') + ->where('a.enabled >= 1') + ->where('a.type =' . $db->quote('component')) + ->join('INNER', '#__categories as b ON a.element=b.extension'); + + $items = $db->setQuery($query)->loadObjectList(); + + if (count($items)) + { + $lang = Factory::getLanguage(); + + foreach ($items as &$item) + { + // Load language + $extension = $item->value; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + + // Translate component name + $item->text = Text::_($item->text); + } + + // Sort by component name + $items = ArrayHelper::sortObjects($items, 'text', 1, true, true); + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $items); + + return $options; + } +} diff --git a/administrator/components/com_menus/Field/MenuItemByTypeField.php b/administrator/components/com_menus/Field/MenuItemByTypeField.php new file mode 100644 index 0000000000000..be3a26fa9184f --- /dev/null +++ b/administrator/components/com_menus/Field/MenuItemByTypeField.php @@ -0,0 +1,280 @@ +$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 = Factory::getApplication(); + $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 = Factory::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][] = HTMLHelper::_('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('- ', $link->level - 1); + + // Displays language code if not set to All + if ($link->language !== '*') + { + $lang = ' (' . $link->language . ')'; + } + else + { + $lang = ''; + } + + $groups[$menu->title][] = HTMLHelper::_('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/Field/MenuParentField.php b/administrator/components/com_menus/Field/MenuParentField.php new file mode 100644 index 0000000000000..f8c8e3f2f87f3 --- /dev/null +++ b/administrator/components/com_menus/Field/MenuParentField.php @@ -0,0 +1,112 @@ +getQuery(true) + ->select('DISTINCT(a.id) AS value, a.title AS text, a.level, a.lft') + ->from('#__menu AS a'); + + // Filter by menu type. + if ($menuType = $this->form->getValue('menutype')) + { + $query->where('a.menutype = ' . $db->quote($menuType)); + } + else + { + // Skip special menu types + $query->where('a.menutype != ' . $db->quote('')); + $query->where('a.menutype != ' . $db->quote('main')); + } + + // Filter by client id. + $clientId = $this->getAttribute('clientid'); + + if (!is_null($clientId)) + { + $query->where($db->quoteName('a.client_id') . ' = ' . (int) $clientId); + } + + // Prevent parenting to children of this item. + if ($id = $this->form->getValue('id')) + { + $query->join('LEFT', $db->quoteName('#__menu') . ' AS p ON p.id = ' . (int) $id) + ->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)'); + } + + $query->where('a.published != -2') + ->order('a.lft ASC'); + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + // Pad the option text with spaces using depth level as a multiplier. + for ($i = 0, $n = count($options); $i < $n; $i++) + { + if ($clientId != 0) + { + // Allow translation of custom admin menus + $options[$i]->text = str_repeat('- ', $options[$i]->level) . Text::_($options[$i]->text); + } + else + { + $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; + } + } + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } +} diff --git a/administrator/components/com_menus/Field/MenuPresetField.php b/administrator/components/com_menus/Field/MenuPresetField.php new file mode 100644 index 0000000000000..22310a786d6a0 --- /dev/null +++ b/administrator/components/com_menus/Field/MenuPresetField.php @@ -0,0 +1,54 @@ +name, Text::_($preset->title)); + } + + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_menus/Field/MenuorderingField.php b/administrator/components/com_menus/Field/MenuorderingField.php new file mode 100644 index 0000000000000..b4eeaf3521a99 --- /dev/null +++ b/administrator/components/com_menus/Field/MenuorderingField.php @@ -0,0 +1,125 @@ +form->getValue('parent_id', 0); + + if (empty($parent_id)) + { + return false; + } + + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('a.id AS value, a.title AS text, a.client_id AS ' . $db->quoteName('clientId')) + ->from('#__menu AS a') + + ->where('a.published >= 0') + ->where('a.parent_id =' . (int) $parent_id); + + if ($menuType = $this->form->getValue('menutype')) + { + $query->where('a.menutype = ' . $db->quote($menuType)); + } + else + { + $query->where('a.menutype != ' . $db->quote('')); + } + + $query->order('a.lft ASC'); + + // Get the options. + $db->setQuery($query); + + try + { + $options = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + // Allow translation of custom admin menus + foreach ($options as &$option) + { + if ($option->clientId != 0) + { + $option->text = Text::_($option->text); + } + } + + $options = array_merge( + array(array('value' => '-1', 'text' => Text::_('COM_MENUS_ITEM_FIELD_ORDERING_VALUE_FIRST'))), + $options, + array(array('value' => '-2', 'text' => Text::_('COM_MENUS_ITEM_FIELD_ORDERING_VALUE_LAST'))) + ); + + // Merge any additional options in the XML definition. + $options = array_merge(parent::getOptions(), $options); + + return $options; + } + + /** + * Method to get the field input markup. + * + * @return string The field input markup. + * + * @since 1.7 + */ + protected function getInput() + { + if ($this->form->getValue('id', 0) == 0) + { + return '' . Text::_('COM_MENUS_ITEM_FIELD_ORDERING_TEXT') . ''; + } + else + { + return parent::getInput(); + } + } +} diff --git a/administrator/components/com_menus/Field/MenutypeField.php b/administrator/components/com_menus/Field/MenutypeField.php new file mode 100644 index 0000000000000..4a5abc76f997b --- /dev/null +++ b/administrator/components/com_menus/Field/MenutypeField.php @@ -0,0 +1,115 @@ +form->getValue('id'); + $size = (string) ($v = $this->element['size']) ? ' size="' . $v . '"' : ''; + $class = (string) ($v = $this->element['class']) ? ' class="form-control ' . $v . '"' : 'class="form-control"'; + $required = (string) $this->element['required'] ? ' required="required"' : ''; + $clientId = (int) $this->element['clientid'] ?: 0; + + // Get a reverse lookup of the base link URL to Title + switch ($this->value) + { + case 'url': + $value = Text::_('COM_MENUS_TYPE_EXTERNAL_URL'); + break; + + case 'alias': + $value = Text::_('COM_MENUS_TYPE_ALIAS'); + break; + + case 'separator': + $value = Text::_('COM_MENUS_TYPE_SEPARATOR'); + break; + + case 'heading': + $value = Text::_('COM_MENUS_TYPE_HEADING'); + break; + + case 'container': + $value = Text::_('COM_MENUS_TYPE_CONTAINER'); + break; + + default: + $link = $this->form->getValue('link'); + + $model = Factory::getApplication()->bootComponent('com_menus')->createMVCFactory(Factory::getApplication()) + ->createModel('Menutypes', 'Administrator', array('ignore_request' => true)); + $model->setState('client_id', $clientId); + + $rlu = $model->getReverseLookup(); + + // Clean the link back to the option, view and layout + $value = Text::_(ArrayHelper::getValue($rlu, MenusHelper::getLinkKey($link))); + break; + } + + $link = Route::_('index.php?option=com_menus&view=menutypes&tmpl=component&client_id=' . $clientId . '&recordId=' . $recordId); + $html[] = ''; + $html[] = '' . ' ' + . Text::_('JSELECT') . ''; + $html[] = HTMLHelper::_( + 'bootstrap.renderModal', + 'menuTypeModal', + array( + 'url' => $link, + 'title' => Text::_('COM_MENUS_ITEM_FIELD_TYPE_LABEL'), + 'width' => '800px', + 'height' => '300px', + 'modalWidth' => 80, + 'bodyHeight' => 70, + 'footer' => '' + ) + ); + $html[] = ''; + + return implode("\n", $html); + } +} diff --git a/administrator/components/com_menus/Field/Modal/MenuField.php b/administrator/components/com_menus/Field/Modal/MenuField.php new file mode 100644 index 0000000000000..d0bc0a1d7454d --- /dev/null +++ b/administrator/components/com_menus/Field/Modal/MenuField.php @@ -0,0 +1,425 @@ +$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.7.0 + */ + public function __set($name, $value) + { + switch ($name) + { + case 'allowSelect': + case 'allowClear': + case 'allowNew': + case 'allowEdit': + $value = (string) $value; + $this->$name = !($value === 'false' || $value === 'off' || $value === '0'); + 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 FormField::setup() + * @since 3.7.0 + */ + public function setup(\SimpleXMLElement $element, $value, $group = null) + { + $return = parent::setup($element, $value, $group); + + if ($return) + { + $this->allowSelect = ((string) $this->element['select']) !== 'false'; + $this->allowClear = ((string) $this->element['clear']) !== 'false'; + $this->allowNew = ((string) $this->element['new']) === 'true'; + $this->allowEdit = ((string) $this->element['edit']) === 'true'; + } + + return $return; + } + + /** + * Method to get the field input markup. + * + * @return string The field input markup. + * + * @since 3.7.0 + */ + protected function getInput() + { + $clientId = (int) $this->element['clientid']; + + // Load language + Factory::getLanguage()->load('com_menus', JPATH_ADMINISTRATOR); + + // The active article id field. + $value = (int) $this->value > 0 ? (int) $this->value : ''; + + // Create the modal id. + $modalId = 'Item_' . $this->id; + + // Add the modal field script to the document head. + HTMLHelper::_('jquery.framework'); + HTMLHelper::_('script', 'system/fields/modal-fields.min.js', array('version' => 'auto', 'relative' => true)); + + // Script to proxy the select modal function to the modal-fields.js file. + if ($this->allowSelect) + { + static $scriptSelect = null; + + if (is_null($scriptSelect)) + { + $scriptSelect = array(); + } + + if (!isset($scriptSelect[$this->id])) + { + Factory::getDocument()->addScriptDeclaration(" + function jSelectMenu_" . $this->id . "(id, title, object) { + window.processModalSelect('Item', '" . $this->id . "', id, title, '', object); + } + " + ); + + $scriptSelect[$this->id] = true; + } + } + + // Setup variables for display. + $linkSuffix = '&layout=modal&client_id=' . $clientId . '&tmpl=component&' . Session::getFormToken() . '=1'; + $linkItems = 'index.php?option=com_menus&view=items' . $linkSuffix; + $linkItem = 'index.php?option=com_menus&view=item' . $linkSuffix; + $modalTitle = Text::_('COM_MENUS_CHANGE_MENUITEM'); + + if (isset($this->element['language'])) + { + $linkItems .= '&forcedLanguage=' . $this->element['language']; + $linkItem .= '&forcedLanguage=' . $this->element['language']; + $modalTitle .= ' — ' . $this->element['label']; + } + + $urlSelect = $linkItems . '&function=jSelectMenu_' . $this->id; + $urlEdit = $linkItem . '&task=item.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \''; + $urlNew = $linkItem . '&task=item.add'; + + if ($value) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('id') . ' = ' . (int) $value); + + $db->setQuery($query); + + try + { + $title = $db->loadResult(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + } + + // Placeholder if option is present or not + if (empty($title)) + { + if ($this->element->option && (string) $this->element->option['value'] == '') + { + $title_holder = Text::_($this->element->option); + } + else + { + $title_holder = Text::_('COM_MENUS_SELECT_A_MENUITEM'); + } + } + + $title = empty($title) ? $title_holder : htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); + + // The current menu item display field. + $html = ''; + if ($this->allowSelect || $this->allowNew || $this->allowEdit || $this->allowClear) + { + $html .= ''; + } + + $html .= ''; + + if ($this->allowSelect || $this->allowNew || $this->allowEdit || $this->allowClear) + { + $html .= ''; + } + + // Select menu item button + if ($this->allowSelect) + { + $html .= '' + . ' ' . Text::_('JSELECT') + . ''; + } + + // New menu item button + if ($this->allowNew) + { + $html .= '' + . ' ' . Text::_('JACTION_CREATE') + . ''; + } + + // Edit menu item button + if ($this->allowEdit) + { + $html .= '' + . ' ' . Text::_('JACTION_EDIT') + . ''; + } + + // Clear menu item button + if ($this->allowClear) + { + $html .= '' + . '' . Text::_('JCLEAR') + . ''; + } + + if ($this->allowSelect || $this->allowNew || $this->allowEdit || $this->allowClear) + { + $html .= ''; + } + + // Select menu item modal + if ($this->allowSelect) + { + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + 'ModalSelect' . $modalId, + array( + 'title' => $modalTitle, + 'url' => $urlSelect, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '', + ) + ); + } + + // New menu item modal + if ($this->allowNew) + { + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + 'ModalNew' . $modalId, + array( + 'title' => Text::_('COM_MENUS_NEW_MENUITEM'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlNew, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '' + . '' + . '', + ) + ); + } + + // Edit menu item modal + if ($this->allowEdit) + { + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + 'ModalEdit' . $modalId, + array( + 'title' => Text::_('COM_MENUS_EDIT_MENUITEM'), + 'backdrop' => 'static', + 'keyboard' => false, + 'closeButton' => false, + 'url' => $urlEdit, + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 70, + 'modalWidth' => 80, + 'footer' => '' + . '' + . '', + ) + ); + } + + // Note: class='required' for client side validation. + $class = $this->required ? ' class="required modal-value"' : ''; + + // Placeholder if option is present or not when clearing field + if ($this->element->option && (string) $this->element->option['value'] == '') + { + $title_holder = Text::_($this->element->option); + } + else + { + $title_holder = Text::_('COM_MENUS_SELECT_A_MENUITEM'); + } + + $html .= ''; + + return $html; + } + + /** + * Method to get the field label markup. + * + * @return string The field label markup. + * + * @since 3.7.0 + */ + protected function getLabel() + { + return str_replace($this->id, $this->id . '_id', parent::getLabel()); + } +} diff --git a/administrator/components/com_menus/Helper/AssociationsHelper.php b/administrator/components/com_menus/Helper/AssociationsHelper.php new file mode 100644 index 0000000000000..e42ea08e3ee18 --- /dev/null +++ b/administrator/components/com_menus/Helper/AssociationsHelper.php @@ -0,0 +1,184 @@ +getType($typeName); + + $context = $this->extension . '.item'; + + // Get the associations. + $associations = Associations::getAssociations( + $this->extension, + $type['tables']['a'], + $context, + $id, + 'id', + 'alias', + '' + ); + + return $associations; + } + + /** + * Get item information + * + * @param string $typeName The item type + * @param int $id The id of item for which we need the associated items + * + * @return JTable|null + * + * @since 3.7.0 + */ + public function getItem($typeName, $id) + { + if (empty($id)) + { + return null; + } + + $table = null; + + switch ($typeName) + { + case 'item': + $table = Table::getInstance('menu'); + break; + } + + if (is_null($table)) + { + return null; + } + + $table->load($id); + + return $table; + } + + /** + * Get information about the type + * + * @param string $typeName The item type + * + * @return array Array of item types + * + * @since 3.7.0 + */ + public function getType($typeName = '') + { + $fields = $this->getFieldsTemplate(); + $tables = array(); + $joins = array(); + $support = $this->getSupportTemplate(); + $title = ''; + + if (in_array($typeName, $this->itemTypes)) + { + switch ($typeName) + { + case 'item': + $fields['ordering'] = 'a.lft'; + $fields['level'] = 'a.level'; + $fields['catid'] = ''; + $fields['state'] = 'a.published'; + $fields['created_user_id'] = ''; + $fields['menutype'] = 'a.menutype'; + + $support['state'] = true; + $support['acl'] = true; + $support['checkout'] = true; + $support['level'] = true; + + $tables = array( + 'a' => '#__menu' + ); + + $title = 'menu'; + break; + } + } + + return array( + 'fields' => $fields, + 'support' => $support, + 'tables' => $tables, + 'joins' => $joins, + 'title' => $title + ); + } +} diff --git a/administrator/components/com_menus/Helper/MenusHelper.php b/administrator/components/com_menus/Helper/MenusHelper.php new file mode 100644 index 0000000000000..ab12b582b6d81 --- /dev/null +++ b/administrator/components/com_menus/Helper/MenusHelper.php @@ -0,0 +1,546 @@ + $value) + { + if ((!in_array($name, self::$_filter)) && (!($name == 'task' && !array_key_exists('view', $request)))) + { + // Remove the variables we want to ignore. + unset($request[$name]); + } + } + + ksort($request); + + return 'index.php?' . http_build_query($request, '', '&'); + } + + /** + * Get the menu list for create a menu module + * + * @param int $clientId Optional client id - viz 0 = site, 1 = administrator, can be NULL for all + * + * @return array The menu array list + * + * @since 1.6 + */ + public static function getMenuTypes($clientId = 0) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('a.menutype') + ->from('#__menu_types AS a'); + + if (isset($clientId)) + { + $query->where('a.client_id = ' . (int) $clientId); + } + + $db->setQuery($query); + + return $db->loadColumn(); + } + + /** + * Get a list of menu links for one or all menus. + * + * @param string $menuType An option menu to filter the list on, otherwise all menu with given client id links + * are returned as a grouped array. + * @param integer $parentId An optional parent ID to pivot results around. + * @param integer $mode An optional mode. If parent ID is set and mode=2, the parent and children are excluded from the list. + * @param array $published An optional array of states + * @param array $languages Optional array of specify which languages we want to filter + * @param int $clientId Optional client id - viz 0 = site, 1 = administrator, can be NULL for all (used only if menutype not givein) + * + * @return array + * + * @since 1.6 + */ + public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, $published = array(), $languages = array(), $clientId = 0) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT(a.id) AS value, + a.title AS text, + a.alias, + a.level, + a.menutype, + a.client_id, + a.type, + a.published, + a.template_style_id, + a.checked_out, + a.language, + a.lft' + ) + ->from('#__menu AS a'); + + $query->select('e.name as componentname, e.element') + ->join('left', '#__extensions e ON e.extension_id = a.component_id'); + + if (Multilanguage::isEnabled()) + { + $query->select('l.title AS language_title, l.image AS language_image, l.sef AS language_sef') + ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); + } + + // Filter by the type if given, this is more specific than client id + if ($menuType) + { + $query->where('(a.menutype = ' . $db->quote($menuType) . ' OR a.parent_id = 0)'); + } + elseif (isset($clientId)) + { + $query->where('a.client_id = ' . (int) $clientId); + } + + // Prevent the parent and children from showing if requested. + if ($parentId && $mode == 2) + { + $query->join('LEFT', '#__menu AS p ON p.id = ' . (int) $parentId) + ->where('(a.lft <= p.lft OR a.rgt >= p.rgt)'); + } + + if (!empty($languages)) + { + if (is_array($languages)) + { + $languages = '(' . implode(',', array_map(array($db, 'quote'), $languages)) . ')'; + } + + $query->where('a.language IN ' . $languages); + } + + if (!empty($published)) + { + if (is_array($published)) + { + $published = '(' . implode(',', $published) . ')'; + } + + $query->where('a.published IN ' . $published); + } + + $query->where('a.published != -2'); + $query->order('a.lft ASC'); + + // Get the options. + $db->setQuery($query); + + try + { + $links = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + if (empty($menuType)) + { + // If the menutype is empty, group the items by menutype. + $query->clear() + ->select('*') + ->from('#__menu_types') + ->where('menutype <> ' . $db->quote('')) + ->order('title, menutype'); + + if (isset($clientId)) + { + $query->where('client_id = ' . (int) $clientId); + } + + $db->setQuery($query); + + try + { + $menuTypes = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + // Create a reverse lookup and aggregate the links. + $rlu = array(); + + foreach ($menuTypes as &$type) + { + $rlu[$type->menutype] = & $type; + $type->links = array(); + } + + // Loop through the list of menu links. + foreach ($links as &$link) + { + if (isset($rlu[$link->menutype])) + { + $rlu[$link->menutype]->links[] = & $link; + + // Cleanup garbage. + unset($link->menutype); + } + } + + return $menuTypes; + } + else + { + return $links; + } + } + + /** + * Get the associations + * + * @param integer $pk Menu item id + * + * @return array + * + * @since 3.0 + */ + public static function getAssociations($pk) + { + $langAssociations = Associations::getAssociations('com_menus', '#__menu', 'com_menus.item', $pk, 'id', '', ''); + $associations = array(); + + foreach ($langAssociations as $langAssociation) + { + $associations[$langAssociation->language] = $langAssociation->id; + } + + 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 + */ + public static function getMenuItems($menutype, $enabledOnly = false, $exclude = array()) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + + // Prepare the query. + $query->select('m.*') + ->from('#__menu AS m') + ->where('m.menutype = ' . $db->quote($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(); + + Factory::getApplication()->enqueueMessage(Text::_('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(Text::_('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 = Factory::getDbo(); + $query = $db->getQuery(true); + + static $components = array(); + + if (!$components) + { + $query->select('extension_id, element')->from('#__extensions')->where('type = ' . $db->quote('component')); + $components = $db->setQuery($query)->loadObjectList(); + $components = ArrayHelper::getColumn((array) $components, 'element', 'extension_id'); + } + + Factory::getApplication()->triggerEvent('onPreprocessMenuItems', array('com_menus.administrator.import', &$items, null, true)); + + foreach ($items as &$item) + { + /** @var \JTableMenu $table */ + $table = Table::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/Model/ItemModel.php b/administrator/components/com_menus/Model/ItemModel.php new file mode 100644 index 0000000000000..0055c04ca23e5 --- /dev/null +++ b/administrator/components/com_menus/Model/ItemModel.php @@ -0,0 +1,1783 @@ + 'batchAccess', + 'language_id' => 'batchLanguage' + ); + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. + * + * @since 1.6 + */ + protected function canDelete($record) + { + $user = Factory::getUser(); + + if (!empty($record->id)) + { + // Only delete trashed items + if ($record->published != -2) + { + return false; + } + + $menuTypeId = 0; + + if (!empty($record->menutype)) + { + $menuTypeId = $this->getMenuTypeId($record->menutype); + } + + return $user->authorise('core.delete', 'com_menus.menu.' . (int) $menuTypeId); + } + + return false; + } + + /** + * Method to test whether the state of a record can be edited. + * + * @param object $record A record object. + * + * @return boolean True if allowed to change the state of the record. Defaults to the permission for the component. + * + * @since 3.6 + */ + protected function canEditState($record) + { + $menuTypeId = !empty($record->menutype) ? $this->getMenuTypeId($record->menutype) : 0; + $assetKey = $menuTypeId ? 'com_menus.menu.' . (int) $menuTypeId : 'com_menus'; + + return Factory::getUser()->authorise('core.edit.state', $assetKey); + } + + /** + * Batch copy menu items to a new menu or parent. + * + * @param integer $value The new menu or sub-item. + * @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 1.6 + */ + protected function batchCopy($value, $pks, $contexts) + { + // $value comes as {menutype}.{parent_id} + $parts = explode('.', $value); + $menuType = $parts[0]; + $parentId = ArrayHelper::getValue($parts, 1, 0, 'int'); + + $table = $this->getTable(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + $newIds = array(); + + // Check that the parent exists + if ($parentId) + { + if (!$table->load($parentId)) + { + if ($error = $table->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // Non-fatal error + $this->setError(Text::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); + $parentId = 0; + } + } + } + + // If the parent is 0, set it to the ID of the root item in the tree + if (empty($parentId)) + { + if (!$parentId = $table->getRootId()) + { + $this->setError($table->getError()); + + return false; + } + } + + // Check that user has create permission for menus + $user = Factory::getUser(); + + $menuTypeId = (int) $this->getMenuTypeId($menuType); + + if (!$user->authorise('core.create', 'com_menus.menu.' . $menuTypeId)) + { + $this->setError(Text::_('COM_MENUS_BATCH_MENU_ITEM_CANNOT_CREATE')); + + return false; + } + + // We need to log the parent ID + $parents = array(); + + // Calculate the emergency stop count as a precaution against a runaway loop bug + $query->select('COUNT(id)') + ->from($db->quoteName('#__menu')); + $db->setQuery($query); + + try + { + $count = $db->loadResult(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Parent exists so we let's proceed + while (!empty($pks) && $count > 0) + { + // 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; + } + else + { + // Not fatal error + $this->setError(Text::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // Copy is a bit tricky, because we also need to copy the children + $query->clear() + ->select('id') + ->from($db->quoteName('#__menu')) + ->where('lft > ' . (int) $table->lft) + ->where('rgt < ' . (int) $table->rgt); + $db->setQuery($query); + $childIds = $db->loadColumn(); + + // Add child ID's to the array only if they aren't already there. + foreach ($childIds as $childId) + { + if (!in_array($childId, $pks)) + { + $pks[] = $childId; + } + } + + // Make a copy of the old ID and Parent ID + $oldId = $table->id; + $oldParentId = $table->parent_id; + + // Reset the id because we are making a copy. + $table->id = 0; + + // If we a copying children, the Old ID will turn up in the parents list + // otherwise it's a new top level item + $table->parent_id = isset($parents[$oldParentId]) ? $parents[$oldParentId] : $parentId; + $table->menutype = $menuType; + + // Set the new location in the tree for the node. + $table->setLocation($table->parent_id, 'last-child'); + + // TODO: Deal with ordering? + // $table->ordering = 1; + $table->level = null; + $table->lft = null; + $table->rgt = null; + $table->home = 0; + + // Alter the title & alias + list($title, $alias) = $this->generateNewTitle($table->parent_id, $table->alias, $table->title); + $table->title = $title; + $table->alias = $alias; + + // 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; + + // Now we log the old 'parent' to the new 'parent' + $parents[$oldId] = $table->id; + $count--; + } + + // Rebuild the hierarchy. + if (!$table->rebuild()) + { + $this->setError($table->getError()); + + return false; + } + + // Rebuild the tree path. + if (!$table->rebuildPath($table->id)) + { + $this->setError($table->getError()); + + return false; + } + + // Clean the cache + $this->cleanCache(); + + return $newIds; + } + + /** + * Batch move menu items to a new menu or parent. + * + * @param integer $value The new menu or sub-item. + * @param array $pks An array of row IDs. + * @param array $contexts An array of item contexts. + * + * @return boolean True on success. + * + * @since 1.6 + */ + protected function batchMove($value, $pks, $contexts) + { + // $value comes as {menutype}.{parent_id} + $parts = explode('.', $value); + $menuType = $parts[0]; + $parentId = ArrayHelper::getValue($parts, 1, 0, 'int'); + + $table = $this->getTable(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Check that the parent exists. + if ($parentId) + { + if (!$table->load($parentId)) + { + if ($error = $table->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // Non-fatal error + $this->setError(Text::_('JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND')); + $parentId = 0; + } + } + } + + // Check that user has create and edit permission for menus + $user = Factory::getUser(); + + $menuTypeId = (int) $this->getMenuTypeId($menuType); + + if (!$user->authorise('core.create', 'com_menus.menu.' . $menuTypeId)) + { + $this->setError(Text::_('COM_MENUS_BATCH_MENU_ITEM_CANNOT_CREATE')); + + return false; + } + + if (!$user->authorise('core.edit', 'com_menus.menu.' . $menuTypeId)) + { + $this->setError(Text::_('COM_MENUS_BATCH_MENU_ITEM_CANNOT_EDIT')); + + return false; + } + + // We are going to store all the children and just moved the menutype + $children = array(); + + // Parent exists so we let's proceed + foreach ($pks as $pk) + { + // Check that the row actually exists + if (!$table->load($pk)) + { + if ($error = $table->getError()) + { + // Fatal error + $this->setError($error); + + return false; + } + else + { + // Not fatal error + $this->setError(Text::sprintf('JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND', $pk)); + continue; + } + } + + // Set the new location in the tree for the node. + $table->setLocation($parentId, 'last-child'); + + // Set the new Parent Id + $table->parent_id = $parentId; + + // Check if we are moving to a different menu + if ($menuType != $table->menutype) + { + // Add the child node ids to the children array. + $query->clear() + ->select($db->quoteName('id')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('lft') . ' BETWEEN ' . (int) $table->lft . ' AND ' . (int) $table->rgt); + $db->setQuery($query); + $children = array_merge($children, (array) $db->loadColumn()); + } + + // Check the row. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Store the row. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Rebuild the tree path. + if (!$table->rebuildPath()) + { + $this->setError($table->getError()); + + return false; + } + } + + // Process the child rows + if (!empty($children)) + { + // Remove any duplicates and sanitize ids. + $children = array_unique($children); + $children = ArrayHelper::toInteger($children); + + // Update the menutype field in all nodes where necessary. + $query->clear() + ->update($db->quoteName('#__menu')) + ->set($db->quoteName('menutype') . ' = ' . $db->quote($menuType)) + ->where($db->quoteName('id') . ' IN (' . implode(',', $children) . ')'); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to check if you can save a record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function canSave($data = array(), $key = 'id') + { + return Factory::getUser()->authorise('core.edit', $this->option); + } + + /** + * Method to get the row form. + * + * @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 mixed A \JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // The folder and element vars are passed when saving the form. + if (empty($data)) + { + $item = $this->getItem(); + + // The type should already be set. + $this->setState('item.link', $item->link); + } + else + { + $this->setState('item.link', ArrayHelper::getValue($data, 'link')); + $this->setState('item.type', ArrayHelper::getValue($data, 'type')); + } + + $clientId = $this->getState('item.client_id'); + + // Get the form. + if ($clientId == 1) + { + $form = $this->loadForm('com_menus.item.admin', 'itemadmin', array('control' => 'jform', 'load_data' => $loadData), true); + } + else + { + $form = $this->loadForm('com_menus.item', 'item', array('control' => 'jform', 'load_data' => $loadData), true); + } + + if (empty($form)) + { + return false; + } + + if ($loadData) + { + $data = $this->loadFormData(); + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('menuordering', 'disabled', 'true'); + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is an article you can edit. + $form->setFieldAttribute('menuordering', 'filter', 'unset'); + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + // Filter available menus + $action = $this->getState('item.id') > 0 ? 'edit' : 'create'; + + $form->setFieldAttribute('menutype', 'accesstype', $action); + $form->setFieldAttribute('type', 'clientid', $clientId); + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data, providing it has an ID and it is the same. + $itemData = (array) $this->getItem(); + $sessionData = (array) Factory::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 = Factory::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'] : Factory::getConfig()->get('access')); + } + + if (isset($data['menutype']) && !$this->getState('item.menutypeid')) + { + $menuTypeId = (int) $this->getMenuTypeId($data['menutype']); + + $this->setState('item.menutypeid', $menuTypeId); + } + + $this->preprocessData('com_menus.item', $data); + + return $data; + } + + /** + * Get the necessary data to load an item help screen. + * + * @return object An object with key, url, and local properties for loading the item help screen. + * + * @since 1.6 + */ + public function getHelp() + { + return (object) array('key' => $this->helpKey, 'url' => $this->helpURL, 'local' => $this->helpLocal); + } + + /** + * Method to get a menu item. + * + * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. + * + * @return mixed Menu item data object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('item.id'); + + // Get a level row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $table->load($pk); + + // Check for a table object error. + if ($error = $table->getError()) + { + $this->setError($error); + + return false; + } + + // Prime required properties. + + if ($type = $this->getState('item.type')) + { + $table->type = $type; + } + + if (empty($table->id)) + { + $table->parent_id = $this->getState('item.parent_id'); + $table->menutype = $this->getState('item.menutype'); + $table->client_id = $this->getState('item.client_id'); + $table->params = '{}'; + } + + // If the link has been set in the state, possibly changing link type. + 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) && (int) $table->id === (int) $this->getState('item.id')) + { + $table->link = $link; + } + } + + switch ($table->type) + { + case 'alias': + $table->component_id = 0; + $args = array(); + + parse_str(parse_url($table->link, PHP_URL_QUERY), $args); + break; + + case 'separator': + case 'heading': + case 'container': + $table->link = ''; + $table->component_id = 0; + break; + + case 'url': + $table->component_id = 0; + + $args = array(); + parse_str(parse_url($table->link, PHP_URL_QUERY), $args); + break; + + case 'component': + default: + // Enforce a valid type. + $table->type = 'component'; + + // Ensure the integrity of the component_id field is maintained, particularly when changing the menu item type. + $args = array(); + parse_str(parse_url($table->link, PHP_URL_QUERY), $args); + + if (isset($args['option'])) + { + // Load the language file for the component. + $lang = Factory::getLanguage(); + $lang->load($args['option'], JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($args['option'], JPATH_ADMINISTRATOR . '/components/' . $args['option'], null, false, true); + + // Determine the component id. + $component = ComponentHelper::getComponent($args['option']); + + if (isset($component->id)) + { + $table->component_id = $component->id; + } + } + break; + } + + // We have a valid type, inject it into the state for forms to use. + $this->setState('item.type', $table->type); + + // Convert to the \JObject before adding the params. + $properties = $table->getProperties(1); + $result = ArrayHelper::toObject($properties); + + // Convert the params field to an array. + $registry = new Registry($table->params); + $result->params = $registry->toArray(); + + // Merge the request arguments in to the params for a component. + if ($table->type == 'component') + { + // Note that all request arguments become reserved parameter names. + $result->request = $args; + $result->params = array_merge($result->params, $args); + + // Special case for the Login menu item. + // Display the login or logout redirect URL fields if not empty + if ($table->link == 'index.php?option=com_users&view=login') + { + if (!empty($result->params['login_redirect_url'])) + { + $result->params['loginredirectchoice'] = '0'; + } + + if (!empty($result->params['logout_redirect_url'])) + { + $result->params['logoutredirectchoice'] = '0'; + } + } + } + + if ($table->type == 'alias') + { + // Note that all request arguments become reserved parameter names. + $result->params = array_merge($result->params, $args); + } + + if ($table->type == 'url') + { + // Note that all request arguments become reserved parameter names. + $result->params = array_merge($result->params, $args); + } + + // Load associated menu items, only supported for frontend for now + if ($this->getState('item.client_id') == 0 && Associations::isEnabled()) + { + if ($pk != null) + { + $result->associations = MenusHelper::getAssociations($pk); + } + else + { + $result->associations = array(); + } + } + + $result->menuordering = $pk; + + return $result; + } + + /** + * Get the list of modules not in trash. + * + * @return mixed An array of module records (id, title, position), or false on error. + * + * @since 1.6 + */ + public function getModules() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Currently any setting that affects target page for a backend menu is not supported, hence load no modules. + if ($this->getState('item.client_id') == 1) + { + return false; + } + + /** + * Join on the module-to-menu mapping table. + * We are only interested if the module is displayed on ALL or THIS menu item (or the inverse ID number). + * sqlsrv changes for modulelink to menu manager + */ + $query->select('a.id, a.title, a.position, a.published, map.menuid') + ->from('#__modules AS a') + ->join('LEFT', sprintf('#__modules_menu AS map ON map.moduleid = a.id AND map.menuid IN (0, %1$d, -%1$d)', $this->getState('item.id'))) + ->select('(SELECT COUNT(*) FROM #__modules_menu WHERE moduleid = a.id AND menuid < 0) AS ' . $db->quoteName('except')); + + // Join on the asset groups table. + $query->select('ag.title AS access_title') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access') + ->where('a.published >= 0') + ->where('a.client_id = ' . (int) $this->getState('item.client_id')) + ->order('a.position, a.ordering'); + + $db->setQuery($query); + + try + { + $result = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $result; + } + + /** + * Get the list of all view levels + * + * @return \stdClass[]|boolean An array of all view levels (id, title). + * + * @since 3.4 + */ + public function getViewLevels() + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Get all the available view levels + $query->select($db->quoteName('id')) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__viewlevels')) + ->order($db->quoteName('id')); + + $db->setQuery($query); + + try + { + $result = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $result; + } + + /** + * Returns a Table object, always creating it + * + * @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 \Joomla\Cms\Table\Table|\Joomla\Cms\Table\Nested A database object. + * + * @since 1.6 + */ + public function getTable($type = 'Menu', $prefix = 'Administrator', $config = array()) + { + return parent::getTable($type, $prefix, $config); + } + + /** + * A protected method to get the where clause for the reorder. + * This ensures that the row will be moved relative to a row with the same menutype. + * + * @param \JTableMenu $table instance. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since 1.6 + */ + protected function getReorderConditions($table) + { + return array('menutype = ' . $this->_db->quote($table->get('menutype'))); + } + + /** + * Auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = Factory::getApplication(); + + // Load the User state. + $pk = $app->input->getInt('id'); + $this->setState('item.id', $pk); + + if (!($parentId = $app->getUserState('com_menus.edit.item.parent_id'))) + { + $parentId = $app->input->getInt('parent_id'); + } + + $this->setState('item.parent_id', $parentId); + + $menuType = $app->getUserStateFromRequest('com_menus.items.menutype', 'menutype', '', 'string'); + + // If we have a menutype we take client_id from there, unless forced otherwise + if ($menuType) + { + $menuTypeObj = $this->getMenuType($menuType); + + // An invalid menutype will be handled as clientId = 0 and menuType = '' + $menuType = (string) $menuTypeObj->menutype; + $menuTypeId = (int) $menuTypeObj->client_id; + $clientId = (int) $menuTypeObj->client_id; + } + else + { + $menuTypeId = 0; + $clientId = $app->getUserState('com_menus.items.client_id', 0); + } + + // Forced client id will override/clear menuType if conflicted + $forcedClientId = $app->input->get('client_id', null, 'string'); + + // Current item if not new, we don't allow changing client id at all + if ($pk) + { + $table = $this->getTable(); + $table->load($pk); + $forcedClientId = $table->get('client_id', $forcedClientId); + } + + if (isset($forcedClientId) && $forcedClientId != $clientId) + { + $clientId = $forcedClientId; + $menuType = ''; + $menuTypeId = 0; + } + + // Set the menu type and client id on the list view state, so we return to this menu after saving. + $app->setUserState('com_menus.items.menutype', $menuType); + $app->setUserState('com_menus.items.client_id', $clientId); + + $this->setState('item.menutype', $menuType); + $this->setState('item.client_id', $clientId); + $this->setState('item.menutypeid', $menuTypeId); + + if (!($type = $app->getUserState('com_menus.edit.item.type'))) + { + $type = $app->input->get('type'); + + /** + * Note: a new menu item will have no field type. + * The field is required so the user has to change it. + */ + } + + $this->setState('item.type', $type); + + if ($link = $app->getUserState('com_menus.edit.item.link')) + { + $this->setState('item.link', $link); + } + + // Load the parameters. + $params = ComponentHelper::getParams('com_menus'); + $this->setState('params', $params); + } + + /** + * Loads the menutype object by a given menutype string + * + * @param string $menutype The given menutype + * + * @return \stdClass + * + * @since 3.7.0 + */ + protected function getMenuType($menutype) + { + $table = $this->getTable('MenuType'); + + $table->load(array('menutype' => $menutype)); + + return (object) $table->getProperties(); + } + + /** + * Loads the menutype ID by a given menutype string + * + * @param string $menutype The given menutype + * + * @return integer + * + * @since 3.6 + */ + protected function getMenuTypeId($menutype) + { + $menu = $this->getMenuType($menutype); + + return (int) $menu->id; + } + + /** + * Method to preprocess the form. + * + * @param \JForm $form A \JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import. + * + * @return void + * + * @since 1.6 + * @throws \Exception if there is an error in the form event. + */ + protected function preprocessForm(\JForm $form, $data, $group = 'content') + { + $link = $this->getState('item.link'); + $type = $this->getState('item.type'); + $clientId = $this->getState('item.client_id'); + $formFile = false; + + // Load the specific type file + $typeFile = $clientId == 1 ? 'itemadmin_' . $type : 'item_' . $type; + $clientInfo = ApplicationHelper::getClientInfo($clientId); + + // Initialise form with component view params if available. + if ($type == 'component') + { + $link = htmlspecialchars_decode($link); + + // Parse the link arguments. + $args = array(); + parse_str(parse_url(htmlspecialchars_decode($link), PHP_URL_QUERY), $args); + + // Confirm that the option is defined. + $option = ''; + $base = ''; + + if (isset($args['option'])) + { + // The option determines the base path to work with. + $option = $args['option']; + $base = $clientInfo->path . '/components/' . $option; + } + + if (isset($args['view'])) + { + $view = $args['view']; + + // Determine the layout to search for. + if (isset($args['layout'])) + { + $layout = $args['layout']; + } + else + { + $layout = 'default'; + } + + // Check for the layout XML file. Use standard xml file if it exists. + $tplFolders = array( + $base . '/views/' . $view . '/tmpl', + $base . '/view/' . $view . '/tmpl', + $base . '/tmpl/' . $view + ); + $path = Path::find($tplFolders, $layout . '.xml'); + + if (is_file($path)) + { + $formFile = $path; + } + + // If custom layout, get the xml file from the template folder + // template folder is first part of file name -- template:folder + if (!$formFile && (strpos($layout, ':') > 0)) + { + list($altTmpl, $altLayout) = explode(':', $layout); + + $templatePath = Path::clean($clientInfo->path . '/templates/' . $altTmpl . '/html/' . $option . '/' . $view . '/' . $altLayout . '.xml'); + + if (is_file($templatePath)) + { + $formFile = $templatePath; + } + } + } + + // Now check for a view manifest file + if (!$formFile) + { + if (isset($view)) + { + $metadataFolders = array( + $base . '/view/' . $view, + $base . '/views/' . $view + ); + $metaPath = Path::find($metadataFolders, 'metadata.xml'); + + if (is_file($path = Path::clean($metaPath))) + { + $formFile = $path; + } + } + else + { + // Now check for a component manifest file + $path = Path::clean($base . '/metadata.xml'); + + if (is_file($path)) + { + $formFile = $path; + } + } + } + } + + if ($formFile) + { + // If an XML file was found in the component, load it first. + // We need to qualify the full path to avoid collisions with component file names. + + if ($form->loadFile($formFile, true, '/metadata') == false) + { + throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); + } + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($formFile)) + { + throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); + } + + // Get the help data from the XML file if present. + $help = $xml->xpath('/metadata/layout/help'); + } + else + { + // We don't have a component. Load the form XML to get the help path + $xmlFile = Path::find(JPATH_ADMINISTRATOR . '/components/com_menus/models/forms', $typeFile . '.xml'); + + if ($xmlFile) + { + if (!$xml = simplexml_load_file($xmlFile)) + { + throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); + } + + // Get the help data from the XML file if present. + $help = $xml->xpath('/form/help'); + } + } + + if (!empty($help)) + { + $helpKey = trim((string) $help[0]['key']); + $helpURL = trim((string) $help[0]['url']); + $helpLoc = trim((string) $help[0]['local']); + + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; + $this->helpLocal = (($helpLoc == 'true') || ($helpLoc == '1') || ($helpLoc == 'local')) ? true : false; + } + + if (!$form->loadFile($typeFile, true, false)) + { + throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); + } + + // Association menu items, we currently do not support this for admin menu… may be later + if ($clientId == 0 && Associations::isEnabled()) + { + $languages = LanguageHelper::getContentLanguages(false, true, null, 'ordering', 'asc'); + + if (count($languages) > 1) + { + $addform = new \SimpleXMLElement('
    '); + $fields = $addform->addChild('fields'); + $fields->addAttribute('name', 'associations'); + $fieldset = $fields->addChild('fieldset'); + $fieldset->addAttribute('name', 'item_associations'); + $fieldset->addAttribute('addfieldprefix', 'Joomla\Component\Menus\Administrator\Field'); + + foreach ($languages as $language) + { + $field = $fieldset->addChild('field'); + $field->addAttribute('name', $language->lang_code); + $field->addAttribute('type', 'modal_menu'); + $field->addAttribute('language', $language->lang_code); + $field->addAttribute('label', $language->title); + $field->addAttribute('translate_label', 'false'); + $field->addAttribute('select', 'true'); + $field->addAttribute('new', 'true'); + $field->addAttribute('edit', 'true'); + $field->addAttribute('clear', 'true'); + $option = $field->addChild('option', 'COM_MENUS_ITEM_FIELD_ASSOCIATION_NO_VALUE'); + $option->addAttribute('value', ''); + } + + $form->load($addform, false); + } + } + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * Method rebuild the entire nested set tree. + * + * @return boolean Boolean true on success, boolean false + * + * @since 1.6 + */ + public function rebuild() + { + // Initialise variables. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $table = $this->getTable(); + + try + { + $rebuildResult = $table->rebuild(); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (!$rebuildResult) + { + $this->setError($table->getError()); + + return false; + } + + $query->select('id, params') + ->from('#__menu') + ->where('params NOT LIKE ' . $db->quote('{%')) + ->where('params <> ' . $db->quote('')); + $db->setQuery($query); + + try + { + $items = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + foreach ($items as &$item) + { + $registry = new Registry($item->params); + $params = (string) $registry; + + $query->clear(); + $query->update('#__menu') + ->set('params = ' . $db->quote($params)) + ->where('id = ' . $item->id); + + try + { + $db->setQuery($query)->execute(); + } + catch (\RuntimeException $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + unset($registry); + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('item.id'); + $isNew = true; + $table = $this->getTable(); + $context = $this->option . '.' . $this->name; + + // Include the plugins for the on save events. + PluginHelper::importPlugin($this->events_map['save']); + + // Load the row if saving an existing item. + if ($pk > 0) + { + $table->load($pk); + $isNew = false; + } + + if (!$isNew) + { + if ($table->parent_id == $data['parent_id']) + { + // If first is chosen make the item the first child of the selected parent. + if ($data['menuordering'] == -1) + { + $table->setLocation($data['parent_id'], 'first-child'); + } + // If last is chosen make it the last child of the selected parent. + elseif ($data['menuordering'] == -2) + { + $table->setLocation($data['parent_id'], 'last-child'); + } + // Don't try to put an item after itself. All other ones put after the selected item. + // $data['id'] is empty means it's a save as copy + elseif ($data['menuordering'] && $table->id != $data['menuordering'] || empty($data['id'])) + { + $table->setLocation($data['menuordering'], 'after'); + } + // \Just leave it where it is if no change is made. + elseif ($data['menuordering'] && $table->id == $data['menuordering']) + { + unset($data['menuordering']); + } + } + // Set the new parent id if parent id not matched and put in last position + else + { + $table->setLocation($data['parent_id'], 'last-child'); + } + } + // We have a new item, so it is not a change. + else + { + $menuType = $this->getMenuType($data['menutype']); + + $data['client_id'] = $menuType->client_id; + + $table->setLocation($data['parent_id'], 'last-child'); + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Alter the title & alias for save as copy. Also, unset the home record. + if (!$isNew && $data['id'] == 0) + { + list($title, $alias) = $this->generateNewTitle($table->parent_id, $table->alias, $table->title); + + $table->title = $title; + $table->alias = $alias; + $table->published = 0; + $table->home = 0; + } + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = Factory::getApplication()->triggerEvent($this->event_before_save, array($context, &$table, $isNew)); + + // Store the data. + if (in_array(false, $result, true)|| !$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after save event. + Factory::getApplication()->triggerEvent($this->event_after_save, array($context, &$table, $isNew)); + + // Rebuild the tree path. + if (!$table->rebuildPath($table->id)) + { + $this->setError($table->getError()); + + return false; + } + + $this->setState('item.id', $table->id); + $this->setState('item.menutype', $table->menutype); + + // Load associated menu items, for now not supported for admin menu… may be later + if ($table->get('client_id') == 0 && Associations::isEnabled()) + { + // Adding self to the association + $associations = isset($data['associations']) ? $data['associations'] : array(); + + // Unset any invalid associations + $associations = ArrayHelper::toInteger($associations); + + foreach ($associations as $tag => $id) + { + if (!$id) + { + unset($associations[$tag]); + } + } + + // Detecting all item menus + $all_language = $table->language == '*'; + + if ($all_language && !empty($associations)) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_MENUS_ERROR_ALL_LANGUAGE_ASSOCIATED'), 'notice'); + } + + // Get associationskey for edited item + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('key')) + ->from($db->quoteName('#__associations')) + ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)) + ->where($db->quoteName('id') . ' = ' . (int) $table->id); + $db->setQuery($query); + $old_key = $db->loadResult(); + + // Deleting old associations for the associated items + $query = $db->getQuery(true) + ->delete($db->quoteName('#__associations')) + ->where($db->quoteName('context') . ' = ' . $db->quote($this->associationsContext)); + + if ($associations) + { + $query->where('(' . $db->quoteName('id') . ' IN (' . implode(',', $associations) . ') OR ' + . $db->quoteName('key') . ' = ' . $db->quote($old_key) . ')' + ); + } + else + { + $query->where($db->quoteName('key') . ' = ' . $db->quote($old_key)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Adding self to the association + if (!$all_language) + { + $associations[$table->language] = (int) $table->id; + } + + if (count($associations) > 1) + { + // Adding new association for these items + $key = md5(json_encode($associations)); + $query->clear() + ->insert('#__associations'); + + foreach ($associations as $id) + { + $query->values(((int) $id) . ',' . $db->quote($this->associationsContext) . ',' . $db->quote($key)); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + } + + // Clean the cache + $this->cleanCache(); + + if (isset($data['link'])) + { + $base = Uri::base(); + $juri = Uri::getInstance($base . $data['link']); + $option = $juri->getVar('option'); + + // Clean the cache + parent::cleanCache($option); + } + + return true; + } + + /** + * Method to save the reordered nested set tree. + * 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 + * + * @return boolean false on failuer or error, true otherwise. + * + * @since 1.6 + */ + public function saveorder($idArray = null, $lft_array = null) + { + // Get an instance of the table object. + $table = $this->getTable(); + + if (!$table->saveorder($idArray, $lft_array)) + { + $this->setError($table->getError()); + + return false; + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the home state of one or more items. + * + * @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. + * + * @since 1.6 + */ + public function setHome(&$pks, $value = 1) + { + $table = $this->getTable(); + $pks = (array) $pks; + + $languages = array(); + $onehome = false; + + // Remember that we can set a home page for different languages, + // so we need to loop through the primary key array. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + if (!array_key_exists($table->language, $languages)) + { + $languages[$table->language] = true; + + if ($table->home == $value) + { + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('COM_MENUS_ERROR_ALREADY_HOME'), 'notice'); + } + elseif ($table->menutype == 'main') + { + // Prune items that you can't change. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('COM_MENUS_ERROR_MENUTYPE_HOME'), 'error'); + } + else + { + $table->home = $value; + + if ($table->language == '*') + { + $table->published = 1; + } + + if (!$this->canSave($table)) + { + // Prune items that you can't change. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + } + elseif (!$table->check()) + { + // Prune the items that failed pre-save checks. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage($table->getError(), 'error'); + } + elseif (!$table->store()) + { + // Prune the items that could not be stored. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage($table->getError(), 'error'); + } + } + } + else + { + unset($pks[$i]); + + if (!$onehome) + { + $onehome = true; + Factory::getApplication()->enqueueMessage(Text::sprintf('COM_MENUS_ERROR_ONE_HOME'), 'notice'); + } + } + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the published state of one or more records. + * + * @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. + * + * @since 1.6 + */ + public function publish(&$pks, $value = 1) + { + $table = $this->getTable(); + $pks = (array) $pks; + + // Default menu item existence checks. + if ($value != 1) + { + foreach ($pks as $i => $pk) + { + if ($table->load($pk) && $table->home && $table->language == '*') + { + // Prune items that you can't change. + Factory::getApplication()->enqueueMessage(Text::_('JLIB_DATABASE_ERROR_MENU_UNPUBLISH_DEFAULT_HOME'), 'error'); + unset($pks[$i]); + break; + } + } + } + + // Clean the cache + $this->cleanCache(); + + // Ensure that previous checks doesn't empty the array + if (empty($pks)) + { + return true; + } + + return parent::publish($pks, $value); + } + + /** + * 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. + * + * @return array Contains the modified title and alias. + * + * @since 1.6 + */ + protected function generateNewTitle($parent_id, $alias, $title) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) + { + if ($title == $table->title) + { + $title = StringHelper::increment($title); + } + + $alias = StringHelper::increment($alias, 'dash'); + } + + return array($title, $alias); + } + + /** + * Custom clean the cache + * + * @param string $group Cache group name. + * @param integer $client_id Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $client_id = 0) + { + parent::cleanCache('com_menus', 0); + parent::cleanCache('com_modules'); + parent::cleanCache('mod_menu', 0); + parent::cleanCache('mod_menu', 1); + } +} diff --git a/administrator/components/com_menus/Model/ItemsModel.php b/administrator/components/com_menus/Model/ItemsModel.php new file mode 100644 index 0000000000000..7440f628fbc1b --- /dev/null +++ b/administrator/components/com_menus/Model/ItemsModel.php @@ -0,0 +1,600 @@ +input->get('forcedLanguage', '', 'cmd'); + + // Adjust the context to support modal layouts. + if ($layout = $app->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + // Adjust the context to support forced languages. + if ($forcedLanguage) + { + $this->context .= '.' . $forcedLanguage; + } + + $search = $this->getUserStateFromRequest($this->context . '.search', 'filter_search'); + $this->setState('filter.search', $search); + + $published = $this->getUserStateFromRequest($this->context . '.published', 'filter_published', ''); + $this->setState('filter.published', $published); + + $access = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access'); + $this->setState('filter.access', $access); + + $parentId = $this->getUserStateFromRequest($this->context . '.filter.parent_id', 'filter_parent_id'); + $this->setState('filter.parent_id', $parentId); + + $level = $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level'); + $this->setState('filter.level', $level); + + // Watch changes in client_id and menutype and keep sync whenever needed. + $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) + { + Factory::getLanguage()->load('mod_menu', JPATH_ADMINISTRATOR, null, false, true); + } + + $currentMenuType = $app->getUserState($this->context . '.menutype', ''); + $menuType = $app->input->getString('menutype', $currentMenuType); + + // If client_id changed clear menutype and reset pagination + if ($clientId != $currentClientId) + { + $menuType = ''; + + $app->input->set('limitstart', 0); + $app->input->set('menutype', ''); + } + + // If menutype changed reset pagination. + if ($menuType != $currentMenuType) + { + $app->input->set('limitstart', 0); + } + + if (!$menuType) + { + $app->setUserState($this->context . '.menutype', ''); + $this->setState('menutypetitle', ''); + $this->setState('menutypeid', ''); + } + // Special menu types, if selected explicitly, will be allowed as a filter + elseif ($menuType == 'main') + { + // Adjust client_id to match the menutype. This is safe as client_id was not changed in this request. + $app->input->set('client_id', 1); + + $app->setUserState($this->context . '.menutype', $menuType); + $this->setState('menutypetitle', ucfirst($menuType)); + $this->setState('menutypeid', -1); + } + // Get the menutype object with appropriate checks. + elseif ($cMenu = $this->getMenu($menuType, true)) + { + // Adjust client_id to match the menutype. This is safe as client_id was not changed in this request. + $app->input->set('client_id', $cMenu->client_id); + + $app->setUserState($this->context . '.menutype', $menuType); + $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'); + $this->setState('filter.client_id', $clientId); + + // Use a different filter file when client is administrator + if ($clientId == 1) + { + $this->filterFormName = 'filter_itemsadmin'; + } + + $this->setState('filter.menutype', $menuType); + + $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); + $this->setState('filter.language', $language); + + // Component parameters. + $params = ComponentHelper::getParams('com_menus'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + + // Force a language. + if (!empty($forcedLanguage)) + { + $this->setState('filter.language', $forcedLanguage); + } + } + + /** + * 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 A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.access'); + $id .= ':' . $this->getState('filter.published'); + $id .= ':' . $this->getState('filter.language'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.parent_id'); + $id .= ':' . $this->getState('filter.menutype'); + $id .= ':' . $this->getState('filter.client_id'); + + return parent::getStoreId($id); + } + + /** + * Builds an SQL query to load the list data. + * + * @return \Joomla\Database\DatabaseQuery A query object. + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + $user = Factory::getUser(); + + // Select all fields from the table. + $query->select( + $this->getState( + 'list.select', + $db->quoteName( + array( + 'a.id', 'a.menutype', 'a.title', 'a.alias', 'a.note', 'a.path', 'a.link', 'a.type', 'a.parent_id', + 'a.level', 'a.published', 'a.component_id', 'a.checked_out', 'a.checked_out_time', 'a.browserNav', + 'a.access', 'a.img', 'a.template_style_id', 'a.params', 'a.lft', 'a.rgt', 'a.home', 'a.language', 'a.client_id' + ), + array( + null, null, null, null, null, null, null, null, null, + null, 'a.published', null, null, null, null, + null, null, null, null, null, null, null, null, null + ) + ) + ) + ); + $query->select( + 'CASE ' . + ' WHEN a.type = ' . $db->quote('component') . ' THEN a.published+2*(e.enabled-1) ' . + ' WHEN a.type = ' . $db->quote('url') . ' AND a.published != -2 THEN a.published+2 ' . + ' WHEN a.type = ' . $db->quote('url') . ' AND a.published = -2 THEN a.published-1 ' . + ' WHEN a.type = ' . $db->quote('alias') . ' AND a.published != -2 THEN a.published+4 ' . + ' WHEN a.type = ' . $db->quote('alias') . ' AND a.published = -2 THEN a.published-1 ' . + ' WHEN a.type = ' . $db->quote('separator') . ' AND a.published != -2 THEN a.published+6 ' . + ' WHEN a.type = ' . $db->quote('separator') . ' AND a.published = -2 THEN a.published-1 ' . + ' WHEN a.type = ' . $db->quote('heading') . ' AND a.published != -2 THEN a.published+8 ' . + ' WHEN a.type = ' . $db->quote('heading') . ' AND a.published = -2 THEN a.published-1 ' . + ' WHEN a.type = ' . $db->quote('container') . ' AND a.published != -2 THEN a.published+8 ' . + ' WHEN a.type = ' . $db->quote('container') . ' AND a.published = -2 THEN a.published-1 ' . + ' END AS published ' + ); + $query->from($db->quoteName('#__menu') . ' AS a'); + + // Join over the language + $query->select('l.title AS language_title, l.image AS language_image, l.sef AS language_sef') + ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); + + // Join over the users. + $query->select('u.name AS editor') + ->join('LEFT', $db->quoteName('#__users') . ' AS u ON u.id = a.checked_out'); + + // Join over components + $query->select('c.element AS componentname') + ->join('LEFT', $db->quoteName('#__extensions') . ' AS c ON c.extension_id = a.component_id'); + + // Join over the asset groups. + $query->select('ag.title AS access_level') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + + // Join over the menu types. + $query->select($db->quoteName(array('mt.id', 'mt.title'), array('menutype_id', 'menutype_title'))) + ->join('LEFT', $db->quoteName('#__menu_types', 'mt') . ' ON ' . $db->quoteName('mt.menutype') . ' = ' . $db->quoteName('a.menutype')); + + // Join over the associations. + $assoc = Associations::isEnabled(); + + 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( + $db->quoteName( + array( + 'a.id', + 'a.menutype', + 'a.title', + 'a.alias', + 'a.note', + 'a.path', + 'a.link', + 'a.type', + 'a.parent_id', + 'a.level', + 'a.published', + 'a.component_id', + 'a.checked_out', + 'a.checked_out_time', + 'a.browserNav', + 'a.access', + 'a.img', + 'a.template_style_id', + 'a.params', + 'a.lft', + 'a.rgt', + 'a.home', + 'a.language', + 'a.client_id', + 'l.title', + 'l.image', + 'l.sef', + 'u.name', + 'c.element', + 'ag.title', + 'e.enabled', + 'e.name', + 'mt.id', + 'mt.title', + ) + ) + ); + } + + // Join over the extensions + $query->select('e.name AS name') + ->join('LEFT', '#__extensions AS e ON e.extension_id = a.component_id'); + + // Exclude the root category. + $query->where('a.id > 1') + ->where('a.client_id = ' . (int) $this->getState('filter.client_id')); + + // Filter on the published state. + $published = $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.published = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('a.published IN (0, 1)'); + } + + // Filter by search in title, alias or id + if ($search = trim($this->getState('filter.search'))) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'link:') === 0) + { + if ($search = substr($search, 5)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.link LIKE ' . $search); + } + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(' . 'a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); + } + } + + // Filter the items over the parent id if set. + $parentId = $this->getState('filter.parent_id'); + + if (!empty($parentId)) + { + $query->where('a.parent_id = ' . (int) $parentId); + } + + // Filter the items over the menu id if set. + $menuType = $this->getState('filter.menutype'); + + // A value "" means all + if ($menuType == '') + { + // Load all menu types we have manage access + $query2 = $this->getDbo()->getQuery(true) + ->select($this->getDbo()->quoteName(array('id', 'menutype'))) + ->from('#__menu_types') + ->where('client_id = ' . (int) $this->getState('filter.client_id')) + ->order('title'); + + // Show protected items on explicit filter only + $query->where('a.menutype != ' . $db->quote('main')); + + $menuTypes = $this->getDbo()->setQuery($query2)->loadObjectList(); + + if ($menuTypes) + { + $types = array(); + + foreach ($menuTypes as $type) + { + if ($user->authorise('core.manage', 'com_menus.menu.' . (int) $type->id)) + { + $types[] = $query->quote($type->menutype); + } + } + + $query->where($types ? 'a.menutype IN(' . implode(',', $types) . ')' : 0); + } + } + // Default behavior => load all items from a specific menu + elseif (strlen($menuType)) + { + $query->where('a.menutype = ' . $db->quote($menuType)); + } + // Empty menu type => error + else + { + $query->where('1 != 1'); + } + + // Filter on the access level. + if ($access = $this->getState('filter.access')) + { + $query->where('a.access = ' . (int) $access); + } + + // Implement View Level Access + if (!$user->authorise('core.admin')) + { + $groups = $user->getAuthorisedViewLevels(); + + if (!empty($groups)) + { + $query->where('a.access IN (' . implode(',', $groups) . ')'); + } + } + + // 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')) + { + $query->where('a.language = ' . $db->quote($language)); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to allow derived classes to preprocess the form. + * + * @param \JForm $form A \JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 3.2 + * @throws \Exception if there is an error in the form event. + */ + protected function preprocessForm(\JForm $form, $data, $group = 'content') + { + $name = $form->getName(); + + if ($name == 'com_menus.items.filter') + { + $clientId = $this->getState('filter.client_id'); + $form->setFieldAttribute('menutype', 'clientid', $clientId); + } + elseif (false !== strpos($name, 'com_menus.items.modal.')) + { + $form->removeField('client_id'); + + $clientId = $this->getState('filter.client_id'); + $form->setFieldAttribute('menutype', 'clientid', $clientId); + } + } + + /** + * Get the client id for a menu + * + * @param string $menuType The menutype identifier for the menu + * @param boolean $check Flag whether to perform check against ACL as well as existence + * + * @return integer + * + * @since 3.7.0 + */ + protected function getMenu($menuType, $check = false) + { + $query = $this->_db->getQuery(true); + + $query->select('a.*') + ->from($this->_db->quoteName('#__menu_types', 'a')) + ->where('menutype = ' . $this->_db->quote($menuType)); + + $cMenu = $this->_db->setQuery($query)->loadObject(); + + if ($check) + { + // Check if menu type exists. + if (!$cMenu) + { + Log::add(Text::_('COM_MENUS_ERROR_MENUTYPE_NOT_FOUND'), Log::ERROR, 'jerror'); + + return false; + } + // Check if menu type is valid against ACL. + elseif (!Factory::getUser()->authorise('core.manage', 'com_menus.menu.' . $cMenu->id)) + { + Log::add(Text::_('JERROR_ALERTNOAUTHOR'), Log::ERROR, 'jerror'); + + return false; + } + } + + return $cMenu; + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 12.2 + */ + public function getItems() + { + $store = $this->getStoreId(); + + if (!isset($this->cache[$store])) + { + $items = parent::getItems(); + $lang = Factory::getLanguage(); + $client = $this->state->get('filter.client_id'); + + if ($items) + { + foreach ($items as $item) + { + if ($extension = $item->componentname) + { + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", JPATH_ADMINISTRATOR . '/components/' . $extension, null, false, true); + } + + // Translate component name + if ($client === 1) + { + $item->title = Text::_($item->title); + } + } + } + + $this->cache[$store] = $items; + } + + return $this->cache[$store]; + } +} diff --git a/administrator/components/com_menus/Model/MenuModel.php b/administrator/components/com_menus/Model/MenuModel.php new file mode 100644 index 0000000000000..2d0de59420b1a --- /dev/null +++ b/administrator/components/com_menus/Model/MenuModel.php @@ -0,0 +1,361 @@ +authorise('core.delete', 'com_menus.menu.' . (int) $record->id); + } + + /** + * Method to test whether the state of a record can be 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) + { + return Factory::getUser()->authorise('core.edit.state', 'com_menus.menu.' . (int) $record->id); + } + + /** + * Returns a Table object, always creating it + * + * @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 + * + * @since 1.6 + */ + public function getTable($type = 'MenuType', $prefix = '\JTable', $config = array()) + { + return \JTable::getInstance($type, $prefix, $config); + } + + /** + * Auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = Factory::getApplication(); + + // Load the User state. + $id = $app->input->getInt('id'); + $this->setState('menu.id', $id); + + // Load the parameters. + $params = ComponentHelper::getParams('com_menus'); + $this->setState('params', $params); + } + + /** + * Method to get a menu item. + * + * @param integer $itemId The id of the menu item to get. + * + * @return mixed Menu item data object on success, false on failure. + * + * @since 1.6 + */ + public function &getItem($itemId = null) + { + $itemId = (!empty($itemId)) ? $itemId : (int) $this->getState('menu.id'); + + // Get a menu item row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($itemId); + + // Check for a table object error. + if ($return === false && $table->getError()) + { + $this->setError($table->getError()); + + return false; + } + + $properties = $table->getProperties(1); + $value = ArrayHelper::toObject($properties, 'JObject'); + + return $value; + } + + /** + * Method to get the menu item form. + * + * @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 A \JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_menus.menu', 'menu', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_menus.edit.menu.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + else + { + unset($data['preset']); + } + + $this->preprocessData('com_menus.menu', $data); + + return $data; + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + $id = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('menu.id'); + $isNew = true; + + // Get a row instance. + $table = $this->getTable(); + + // Include the plugins for the save events. + PluginHelper::importPlugin('content'); + + // Load the row if saving an existing item. + if ($id > 0) + { + $isNew = false; + $table->load($id); + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before event. + $result = Factory::getApplication()->triggerEvent('onContentBeforeSave', array($this->_context, &$table, $isNew)); + + // Store the data. + if (in_array(false, $result, true) || !$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after save event. + Factory::getApplication()->triggerEvent('onContentAfterSave', array($this->_context, &$table, $isNew)); + + $this->setState('menu.id', $table->id); + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to delete groups. + * + * @param array $itemIds An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function delete($itemIds) + { + // Sanitize the ids. + $itemIds = ArrayHelper::toInteger((array) $itemIds); + + // Get a group row instance. + $table = $this->getTable(); + + // Include the plugins for the delete events. + PluginHelper::importPlugin('content'); + + // Iterate the items to delete each one. + foreach ($itemIds as $itemId) + { + if ($table->load($itemId)) + { + // Trigger the before delete event. + $result = Factory::getApplication()->triggerEvent('onContentBeforeDelete', array($this->_context, $table)); + + if (in_array(false, $result, true) || !$table->delete($itemId)) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after delete event. + Factory::getApplication()->triggerEvent('onContentAfterDelete', array($this->_context, $table)); + + // TODO: Delete the menu associations - Menu items and Modules + } + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Gets a list of all mod_mainmenu modules and collates them by menutype + * + * @return array + * + * @since 1.6 + */ + public function &getModules() + { + $db = $this->getDbo(); + + $query = $db->getQuery(true) + ->from('#__modules as a') + ->select('a.id, a.title, a.params, a.position') + ->where('module = ' . $db->quote('mod_menu')) + ->select('ag.title AS access_title') + ->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access'); + $db->setQuery($query); + + $modules = $db->loadObjectList(); + + $result = array(); + + foreach ($modules as &$module) + { + $params = new Registry($module->params); + + $menuType = $params->get('menutype'); + + if (!isset($result[$menuType])) + { + $result[$menuType] = array(); + } + + $result[$menuType][] = & $module; + } + + return $result; + } + + /** + * Custom clean the cache + * + * @param string $group Cache group name. + * @param integer $client_id Application client id. + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $client_id = 0) + { + parent::cleanCache('com_menus', 0); + parent::cleanCache('com_modules'); + parent::cleanCache('mod_menu', 0); + parent::cleanCache('mod_menu', 1); + } +} diff --git a/administrator/components/com_menus/Model/MenusModel.php b/administrator/components/com_menus/Model/MenusModel.php new file mode 100644 index 0000000000000..bc5ba62a6ed0c --- /dev/null +++ b/administrator/components/com_menus/Model/MenusModel.php @@ -0,0 +1,250 @@ +getStoreId('getItems'); + + // Try to load the data from internal storage. + if (!empty($this->cache[$store])) + { + return $this->cache[$store]; + } + + // Load the list items. + $items = parent::getItems(); + + // If emtpy or an error, just return. + if (empty($items)) + { + return array(); + } + + // Getting the following metric by joins is WAY TOO SLOW. + // Faster to do three queries for very large menu trees. + + // Get the menu types of menus in the list. + $db = $this->getDbo(); + $menuTypes = ArrayHelper::getColumn((array) $items, 'menutype'); + + // Quote the strings. + $menuTypes = implode( + ',', + array_map(array($db, 'quote'), $menuTypes) + ); + + // Get the published menu counts. + $query = $db->getQuery(true) + ->select('m.menutype, COUNT(DISTINCT m.id) AS count_published') + ->from('#__menu AS m') + ->where('m.published = 1') + ->where('m.menutype IN (' . $menuTypes . ')') + ->group('m.menutype'); + + $db->setQuery($query); + + try + { + $countPublished = $db->loadAssocList('menutype', 'count_published'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Get the unpublished menu counts. + $query->clear('where') + ->where('m.published = 0') + ->where('m.menutype IN (' . $menuTypes . ')'); + $db->setQuery($query); + + try + { + $countUnpublished = $db->loadAssocList('menutype', 'count_published'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Get the trashed menu counts. + $query->clear('where') + ->where('m.published = -2') + ->where('m.menutype IN (' . $menuTypes . ')'); + $db->setQuery($query); + + try + { + $countTrashed = $db->loadAssocList('menutype', 'count_published'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Inject the values back into the array. + foreach ($items as $item) + { + $item->count_published = $countPublished[$item->menutype] ?? 0; + $item->count_unpublished = $countUnpublished[$item->menutype] ?? 0; + $item->count_trashed = $countTrashed[$item->menutype] ?? 0; + } + + // Add the items to the internal cache. + $this->cache[$store] = $items; + + return $this->cache[$store]; + } + + /** + * Method to build an SQL query to load the list data. + * + * @return string An SQL query + * + * @since 1.6 + */ + protected function getListQuery() + { + // Create a new query object. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Select all fields from the table. + $query->select($this->getState('list.select', 'a.id, a.menutype, a.title, a.description, a.client_id')) + ->from($db->quoteName('#__menu_types') . ' AS a') + ->where('a.id > 0'); + + $query->where('a.client_id = ' . (int) $this->getState('client_id')); + + // Filter by search in title or menutype + if ($search = trim($this->getState('filter.search'))) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(' . 'a.title LIKE ' . $search . ' OR a.menutype LIKE ' . $search . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.id')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * 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 1.6 + */ + protected function populateState($ordering = 'a.title', $direction = 'asc') + { + $search = $this->getUserStateFromRequest($this->context . '.search', 'filter_search'); + $this->setState('filter.search', $search); + + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $this->setState('client_id', $clientId); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * Gets the extension id of the core mod_menu module. + * + * @return integer + * + * @since 2.5 + */ + public function getModMenuId() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('e.extension_id') + ->from('#__extensions AS e') + ->where('e.type = ' . $db->quote('module')) + ->where('e.element = ' . $db->quote('mod_menu')) + ->where('e.client_id = ' . (int) $this->getState('client_id')); + $db->setQuery($query); + + return $db->loadResult(); + } + + /** + * Gets a list of all mod_mainmenu modules and collates them by menutype + * + * @return array + * + * @since 1.6 + */ + public function &getModules() + { + $model = new MenuModel(array('ignore_request' => true)); + $result = $model->getModules(); + + return $result; + } +} diff --git a/administrator/components/com_menus/Model/MenutypesModel.php b/administrator/components/com_menus/Model/MenutypesModel.php new file mode 100644 index 0000000000000..69109bbfa0649 --- /dev/null +++ b/administrator/components/com_menus/Model/MenutypesModel.php @@ -0,0 +1,640 @@ +input->get('client_id', 0); + + $this->state->set('client_id', $clientId); + } + + /** + * Method to get the reverse lookup of the base link URL to Title + * + * @return array Array of reverse lookup of the base link URL to Title + * + * @since 1.6 + */ + public function getReverseLookup() + { + if (empty($this->rlu)) + { + $this->getTypeOptions(); + } + + return $this->rlu; + } + + /** + * Method to get the available menu item type options. + * + * @return array Array of groups with menu item types. + * + * @since 1.6 + */ + public function getTypeOptions() + { + $lang = Factory::getLanguage(); + $list = array(); + + // Get the list of components. + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('name, element AS ' . $db->quoteName('option')) + ->from('#__extensions') + ->where('type = ' . $db->quote('component')) + ->where('enabled = 1') + ->order('name ASC'); + $db->setQuery($query); + $components = $db->loadObjectList(); + + foreach ($components as $component) + { + $options = $this->getTypeOptionsByComponent($component->option); + + if ($options) + { + $list[$component->name] = $options; + + // Create the reverse lookup for link-to-name. + foreach ($options as $option) + { + if (isset($option->request)) + { + $this->addReverseLookupUrl($option); + + if (isset($option->request['option'])) + { + $componentLanguageFolder = JPATH_ADMINISTRATOR . '/components/' . $option->request['option']; + $lang->load($option->request['option'] . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($option->request['option'] . '.sys', $componentLanguageFolder, null, false, true); + } + } + } + } + } + + // Allow a system plugin to insert dynamic menu types to the list shown in menus: + Factory::getApplication()->triggerEvent('onAfterGetMenuTypeOptions', array(&$list, $this)); + + return $list; + } + + /** + * Method to create the reverse lookup for link-to-name. + * (can be used from onAfterGetMenuTypeOptions handlers) + * + * @param \JObject $option with request array or string and title public variables + * + * @return void + * + * @since 3.1 + */ + public function addReverseLookupUrl($option) + { + $this->rlu[MenusHelper::getLinkKey($option->request)] = $option->get('title'); + } + + /** + * Get menu types by component. + * + * @param string $component Component URL option. + * + * @return array + * + * @since 1.6 + */ + protected function getTypeOptionsByComponent($component) + { + $options = array(); + $client = ApplicationHelper::getClientInfo($this->getState('client_id')); + $mainXML = $client->path . '/components/' . $component . '/metadata.xml'; + + if (is_file($mainXML)) + { + $options = $this->getTypeOptionsFromXml($mainXML, $component); + } + + if (empty($options)) + { + $options = $this->getTypeOptionsFromMvc($component); + } + + if ($client->id == 1 && empty($options)) + { + $options = $this->getTypeOptionsFromManifest($component); + } + + return $options; + } + + /** + * Get the menu types from an XML file + * + * @param string $file File path + * @param string $component Component option as in URL + * + * @return array|boolean + * + * @since 1.6 + */ + protected function getTypeOptionsFromXml($file, $component) + { + $options = array(); + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($file)) + { + return false; + } + + // Look for the first menu node off of the root node. + if (!$menu = $xml->xpath('menu[1]')) + { + return false; + } + else + { + $menu = $menu[0]; + } + + // If we have no options to parse, just add the base component to the list of options. + if (!empty($menu['options']) && $menu['options'] == 'none') + { + // Create the menu option for the component. + $o = new \JObject; + $o->title = (string) $menu['name']; + $o->description = (string) $menu['msg']; + $o->request = array('option' => $component); + + $options[] = $o; + + return $options; + } + + // Look for the first options node off of the menu node. + if (!$optionsNode = $menu->xpath('options[1]')) + { + return false; + } + else + { + $optionsNode = $optionsNode[0]; + } + + // Make sure the options node has children. + if (!$children = $optionsNode->children()) + { + return false; + } + + // Process each child as an option. + foreach ($children as $child) + { + if ($child->getName() == 'option') + { + // Create the menu option for the component. + $o = new \JObject; + $o->title = (string) $child['name']; + $o->description = (string) $child['msg']; + $o->request = array('option' => $component, (string) $optionsNode['var'] => (string) $child['value']); + + $options[] = $o; + } + elseif ($child->getName() == 'default') + { + // Create the menu option for the component. + $o = new \JObject; + $o->title = (string) $child['name']; + $o->description = (string) $child['msg']; + $o->request = array('option' => $component); + + $options[] = $o; + } + } + + return $options; + } + + /** + * Get menu types from MVC + * + * @param string $component Component option like in URLs + * + * @return array|boolean + * + * @since 1.6 + */ + protected function getTypeOptionsFromMvc($component) + { + $options = array(); + $views = array(); + + foreach ($this->getFolders($component) as $path) + { + if (!is_dir($path)) + { + continue; + } + + $views = array_merge($views, Folder::folders($path, '.', false, true)); + } + + foreach ($views as $viewPath) + { + $view = basename($viewPath); + + // Ignore private views. + if (strpos($view, '_') !== 0) + { + // Determine if a metadata file exists for the view. + $file = $viewPath . '/metadata.xml'; + + if (is_file($file)) + { + // Attempt to load the xml file. + if ($xml = simplexml_load_file($file)) + { + // Look for the first view node off of the root node. + if ($menu = $xml->xpath('view[1]')) + { + $menu = $menu[0]; + + // If the view is hidden from the menu, discard it and move on to the next view. + if (!empty($menu['hidden']) && $menu['hidden'] == 'true') + { + unset($xml); + continue; + } + + // Do we have an options node or should we process layouts? + // Look for the first options node off of the menu node. + if ($optionsNode = $menu->xpath('options[1]')) + { + $optionsNode = $optionsNode[0]; + + // Make sure the options node has children. + if ($children = $optionsNode->children()) + { + // Process each child as an option. + foreach ($children as $child) + { + if ($child->getName() == 'option') + { + // Create the menu option for the component. + $o = new \JObject; + $o->title = (string) $child['name']; + $o->description = (string) $child['msg']; + $o->request = array('option' => $component, 'view' => $view, (string) $optionsNode['var'] => (string) $child['value']); + + $options[] = $o; + } + elseif ($child->getName() == 'default') + { + // Create the menu option for the component. + $o = new \JObject; + $o->title = (string) $child['name']; + $o->description = (string) $child['msg']; + $o->request = array('option' => $component, 'view' => $view); + + $options[] = $o; + } + } + } + } + else + { + $options = array_merge($options, (array) $this->getTypeOptionsFromLayouts($component, $view)); + } + } + + unset($xml); + } + } + else + { + $options = array_merge($options, (array) $this->getTypeOptionsFromLayouts($component, $view)); + } + } + } + + return $options; + } + + /** + * Get menu types from Component manifest + * + * @param string $component Component option like in URLs + * + * @return array|boolean + * + * @since 3.7.0 + */ + protected function getTypeOptionsFromManifest($component) + { + // Load the component manifest + $fileName = JPATH_ADMINISTRATOR . '/components/' . $component . '/' . str_replace('com_', '', $component) . '.xml'; + + if (!is_file($fileName)) + { + return false; + } + + if (!($manifest = simplexml_load_file($fileName))) + { + return false; + } + + // Check for a valid XML root tag. + if ($manifest->getName() != 'extension') + { + return false; + } + + $options = array(); + + // Start with the component root menu. + $rootMenu = $manifest->administration->menu; + + // If the menu item doesn't exist or is hidden do nothing. + if (!$rootMenu || in_array((string) $rootMenu['hidden'], array('true', 'hidden'))) + { + return $options; + } + + // Create the root menu option. + $ro = new \stdClass; + $ro->title = (string) trim($rootMenu); + $ro->description = ''; + $ro->request = array('option' => $component); + + // Process submenu options. + $submenu = $manifest->administration->submenu; + + if (!$submenu) + { + return $options; + } + + foreach ($submenu->menu as $child) + { + $attributes = $child->attributes(); + + $o = new \stdClass; + $o->title = (string) trim($child); + $o->description = ''; + + if ((string) $attributes->link) + { + parse_str((string) $attributes->link, $request); + } + else + { + $request = array(); + + $request['option'] = $component; + $request['act'] = (string) $attributes->act; + $request['task'] = (string) $attributes->task; + $request['controller'] = (string) $attributes->controller; + $request['view'] = (string) $attributes->view; + $request['layout'] = (string) $attributes->layout; + $request['sub'] = (string) $attributes->sub; + } + + $o->request = array_filter($request, 'strlen'); + $options[] = new \JObject($o); + + // Do not repeat the default view link (index.php?option=com_abc). + if (count($o->request) == 1) + { + $ro = null; + } + } + + if ($ro) + { + $options[] = new \JObject($ro); + } + + return $options; + } + + /** + * Get the menu types from component layouts + * + * @param string $component Component option as in URLs + * @param string $view Name of the view + * + * @return array + * + * @since 1.6 + */ + protected function getTypeOptionsFromLayouts($component, $view) + { + $options = array(); + $layouts = array(); + $layoutNames = array(); + $lang = Factory::getLanguage(); + $client = ApplicationHelper::getClientInfo($this->getState('client_id')); + + // Get the views for this component. + foreach ($this->getFolders($component) as $folder) + { + $path = $folder . '/' . $view . '/tmpl'; + + if (!is_dir($path)) + { + $path = $folder . '/' . $view; + } + + if (!is_dir($path)) + { + continue; + } + + $layouts = array_merge($layouts, Folder::files($path, '.xml$', false, true)); + } + + // Build list of standard layout names + foreach ($layouts as $layout) + { + // Ignore private layouts. + if (strpos(basename($layout), '_') === false) + { + // Get the layout name. + $layoutNames[] = basename($layout, '.xml'); + } + } + + // Get the template layouts + // TODO: This should only search one template -- the current template for this item (default of specified) + $folders = Folder::folders($client->path . '/templates', '', false, true); + + // Array to hold association between template file names and templates + $templateName = array(); + + foreach ($folders as $folder) + { + if (is_dir($folder . '/html/' . $component . '/' . $view)) + { + $template = basename($folder); + $lang->load('tpl_' . $template . '.sys', $client->path, null, false, true) + || $lang->load('tpl_' . $template . '.sys', $client->path . '/templates/' . $template, null, false, true); + + $templateLayouts = Folder::files($folder . '/html/' . $component . '/' . $view, '.xml$', false, true); + + foreach ($templateLayouts as $layout) + { + // Get the layout name. + $templateLayoutName = basename($layout, '.xml'); + + // Add to the list only if it is not a standard layout + if (array_search($templateLayoutName, $layoutNames) === false) + { + $layouts[] = $layout; + + // Set template name array so we can get the right template for the layout + $templateName[$layout] = basename($folder); + } + } + } + } + + // Process the found layouts. + foreach ($layouts as $layout) + { + // Ignore private layouts. + if (strpos(basename($layout), '_') === false) + { + $file = $layout; + + // Get the layout name. + $layout = basename($layout, '.xml'); + + // Create the menu option for the layout. + $o = new \JObject; + $o->title = ucfirst($layout); + $o->description = ''; + $o->request = array('option' => $component, 'view' => $view); + + // Only add the layout request argument if not the default layout. + 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; + } + + // Load layout metadata if it exists. + if (is_file($file)) + { + // Attempt to load the xml file. + if ($xml = simplexml_load_file($file)) + { + // Look for the first view node off of the root node. + if ($menu = $xml->xpath('layout[1]')) + { + $menu = $menu[0]; + + // If the view is hidden from the menu, discard it and move on to the next view. + if (!empty($menu['hidden']) && $menu['hidden'] == 'true') + { + unset($xml); + unset($o); + continue; + } + + // Populate the title and description if they exist. + if (!empty($menu['title'])) + { + $o->title = trim((string) $menu['title']); + } + + if (!empty($menu->message[0])) + { + $o->description = trim((string) $menu->message[0]); + } + } + } + } + + // Add the layout to the options array. + $options[] = $o; + } + } + + return $options; + } + + /** + * Get the folders with template files for the given component. + * + * @param string $component Component option as in URLs + * + * @return array + * + * @since 4.0.0 + */ + private function getFolders($component) + { + $client = ApplicationHelper::getClientInfo($this->getState('client_id')); + + if (!is_dir($client->path . '/components/' . $component)) + { + return array(); + } + + $folders = Folder::folders($client->path . '/components/' . $component, '^view[s]?$', false, true); + $folders = array_merge($folders, Folder::folders($client->path . '/components/' . $component, '^tmpl?$', false, true)); + + if (!$folders) + { + return array(); + } + + return $folders; + } +} diff --git a/administrator/components/com_menus/Service/HTML/Menus.php b/administrator/components/com_menus/Service/HTML/Menus.php new file mode 100644 index 0000000000000..e8e38401d4157 --- /dev/null +++ b/administrator/components/com_menus/Service/HTML/Menus.php @@ -0,0 +1,263 @@ +getQuery(true) + ->select('m.id, m.title') + ->select('l.sef as lang_sef, l.lang_code') + ->select('mt.title as menu_title') + ->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'); + $db->setQuery($query); + + try + { + $items = $db->loadObjectList('id'); + } + catch (\RuntimeException $e) + { + throw new \Exception($e->getMessage(), 500); + } + + // Construct html + if ($items) + { + foreach ($items as &$item) + { + $text = strtoupper($item->lang_sef); + $url = Route::_('index.php?option=com_menus&task=item.edit&id=' . (int) $item->id); + $tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '
    ' . Text::sprintf('COM_MENUS_MENU_SPRINTF', $item->menu_title); + $classes = 'hasPopover badge badge-secondary'; + + $item->link = '' + . $text . ''; + } + } + + HTMLHelper::_('bootstrap.popover'); + + $html = LayoutHelper::render('joomla.content.associations', $items); + } + + return $html; + } + + /** + * Returns a published state on a grid + * + * @param integer $value The state value. + * @param integer $i The row index + * @param boolean $enabled An optional setting for access control on the action. + * @param string $checkbox An optional prefix for checkboxes. + * + * @return string The Html code + * + * @see JHtmlJGrid::state + * + * @since 1.7.1 + */ + public function state($value, $i, $enabled = true, $checkbox = 'cb') + { + $states = array( + 9 => array( + 'unpublish', + '', + 'COM_MENUS_HTML_UNPUBLISH_HEADING', + '', + true, + 'publish', + 'publish', + ), + 8 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH_HEADING', + '', + true, + 'unpublish', + 'unpublish', + ), + 7 => array( + 'unpublish', + '', + 'COM_MENUS_HTML_UNPUBLISH_SEPARATOR', + '', + true, + 'publish', + 'publish', + ), + 6 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH_SEPARATOR', + '', + true, + 'unpublish', + 'unpublish', + ), + 5 => array( + 'unpublish', + '', + 'COM_MENUS_HTML_UNPUBLISH_ALIAS', + '', + true, + 'publish', + 'publish', + ), + 4 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH_ALIAS', + '', + true, + 'unpublish', + 'unpublish', + ), + 3 => array( + 'unpublish', + '', + 'COM_MENUS_HTML_UNPUBLISH_URL', + '', + true, + 'publish', + 'publish', + ), + 2 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH_URL', + '', + true, + 'unpublish', + 'unpublish', + ), + 1 => array( + 'unpublish', + 'COM_MENUS_EXTENSION_PUBLISHED_ENABLED', + 'COM_MENUS_HTML_UNPUBLISH_ENABLED', + 'COM_MENUS_EXTENSION_PUBLISHED_ENABLED', + true, + 'publish', + 'publish', + ), + 0 => array( + 'publish', + 'COM_MENUS_EXTENSION_UNPUBLISHED_ENABLED', + 'COM_MENUS_HTML_PUBLISH_ENABLED', + 'COM_MENUS_EXTENSION_UNPUBLISHED_ENABLED', + true, + 'unpublish', + 'unpublish', + ), + -1 => array( + 'unpublish', + 'COM_MENUS_EXTENSION_PUBLISHED_DISABLED', + 'COM_MENUS_HTML_UNPUBLISH_DISABLED', + 'COM_MENUS_EXTENSION_PUBLISHED_DISABLED', + true, + 'warning', + 'warning', + ), + -2 => array( + 'publish', + 'COM_MENUS_EXTENSION_UNPUBLISHED_DISABLED', + 'COM_MENUS_HTML_PUBLISH_DISABLED', + 'COM_MENUS_EXTENSION_UNPUBLISHED_DISABLED', + true, + 'trash', + 'trash', + ), + -3 => array( + 'publish', + '', + 'COM_MENUS_HTML_PUBLISH', + '', + true, + 'trash', + 'trash', + ), + ); + + return HTMLHelper::_('jgrid.state', $states, $value, $i, 'items.', $enabled, true, $checkbox); + } + + /** + * Returns a visibility state on a grid + * + * @param integer $params Params of item. + * + * @return string The Html code + * + * @since 3.7.0 + */ + public function visibility($params) + { + $registry = new Registry; + + try + { + $registry->loadString($params); + } + catch (\Exception $e) + { + // Invalid JSON + } + + $show_menu = $registry->get('menu_show'); + + return ($show_menu === 0) ? '' . Text::_('COM_MENUS_LABEL_HIDDEN') . '' : ''; + } +} diff --git a/administrator/components/com_menus/Table/MenuTable.php b/administrator/components/com_menus/Table/MenuTable.php new file mode 100644 index 0000000000000..01204cfcd42bd --- /dev/null +++ b/administrator/components/com_menus/Table/MenuTable.php @@ -0,0 +1,50 @@ +getQuery(true) + ->delete($db->quoteName('#__modules_menu')) + ->where($db->quoteName('menuid') . ' = ' . $pk); + $db->setQuery($query); + $db->execute(); + } + + return $return; + } +} diff --git a/administrator/components/com_menus/Table/MenuTypeTable.php b/administrator/components/com_menus/Table/MenuTypeTable.php new file mode 100644 index 0000000000000..0a02dc5bf0d92 --- /dev/null +++ b/administrator/components/com_menus/Table/MenuTypeTable.php @@ -0,0 +1,22 @@ +state = $this->get('State'); + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->modules = $this->get('Modules'); + $this->levels = $this->get('ViewLevels'); + $this->canDo = ContentHelper::getActions('com_menus', 'menu', (int) $this->state->get('item.menutypeid')); + + // Check if we're allowed to edit this item + // No need to check for create, because then the moduletype select is empty + if (!empty($this->item->id) && !$this->canDo->get('core.edit')) + { + throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // If we are forcing a language in modal (used for associations). + if ($this->getLayout() === 'modal' && $forcedLanguage = Factory::getApplication()->input->get('forcedLanguage', '', 'cmd')) + { + // Set the language field to the forcedLanguage and disable changing it. + $this->form->setValue('language', null, $forcedLanguage); + $this->form->setFieldAttribute('language', 'readonly', 'true'); + + // Only allow to select categories with All language or with the forced language. + $this->form->setFieldAttribute('parent_id', 'language', '*,' . $forcedLanguage); + } + + parent::display($tpl); + $this->addToolbar(); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $input = Factory::getApplication()->input; + $input->set('hidemainmenu', true); + + $user = Factory::getUser(); + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + $canDo = $this->canDo; + + ToolbarHelper::title(Text::_($isNew ? 'COM_MENUS_VIEW_NEW_ITEM_TITLE' : 'COM_MENUS_VIEW_EDIT_ITEM_TITLE'), 'list menu-add'); + + $toolbarButtons = []; + + // If a new item, can save the item. Allow users with edit permissions to apply changes to prevent returning to grid. + if ($isNew && $canDo->get('core.create')) + { + if ($canDo->get('core.edit')) + { + $toolbarButtons[] = ['apply', 'item.apply']; + } + + $toolbarButtons[] = ['save', 'item.save']; + } + + // If not checked out, can save the item. + if (!$isNew && !$checkedOut && $canDo->get('core.edit')) + { + $toolbarButtons[] = ['apply', 'item.apply']; + $toolbarButtons[] = ['save', 'item.save']; + } + + // If the user can create new items, allow them to see Save & New + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2new', 'item.save2new']; + } + + // If an existing item, can save to a copy only if we have create rights. + if (!$isNew && $canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'item.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if ($isNew) + { + ToolbarHelper::cancel('item.cancel'); + } + else + { + ToolbarHelper::cancel('item.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + + // Get the help information for the menu item. + $lang = Factory::getLanguage(); + + $help = $this->get('Help'); + + if ($lang->hasKey($help->url)) + { + $debug = $lang->setDebug(false); + $url = Text::_($help->url); + $lang->setDebug($debug); + } + else + { + $url = $help->url; + } + + ToolbarHelper::help($help->key, $help->local, $url); + } +} diff --git a/administrator/components/com_menus/View/Items/HtmlView.php b/administrator/components/com_menus/View/Items/HtmlView.php new file mode 100644 index 0000000000000..cdaae3e80780c --- /dev/null +++ b/administrator/components/com_menus/View/Items/HtmlView.php @@ -0,0 +1,447 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->total = $this->get('Total'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + MenusHelper::addSubmenu('items'); + } + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->ordering = array(); + + // Preprocess the list of items to find ordering divisions. + foreach ($this->items as $item) + { + $this->ordering[$item->parent_id][] = $item->id; + + // Item type text + switch ($item->type) + { + case 'url': + $value = Text::_('COM_MENUS_TYPE_EXTERNAL_URL'); + break; + + case 'alias': + $value = Text::_('COM_MENUS_TYPE_ALIAS'); + break; + + case 'separator': + $value = Text::_('COM_MENUS_TYPE_SEPARATOR'); + break; + + case 'heading': + $value = Text::_('COM_MENUS_TYPE_HEADING'); + break; + + case 'container': + $value = Text::_('COM_MENUS_TYPE_CONTAINER'); + break; + + case 'component': + default: + // Load language + $lang->load($item->componentname . '.sys', JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($item->componentname . '.sys', JPATH_ADMINISTRATOR . '/components/' . $item->componentname, null, false, true); + + if (!empty($item->componentname)) + { + $titleParts = array(); + $titleParts[] = Text::_($item->componentname); + $vars = null; + + parse_str($item->link, $vars); + + if (isset($vars['view'])) + { + // Attempt to load the view xml file. + $file = JPATH_SITE . '/components/' . $item->componentname . '/views/' . $vars['view'] . '/metadata.xml'; + + if (!is_file($file)) + { + $file = JPATH_SITE . '/components/' . $item->componentname . '/view/' . $vars['view'] . '/metadata.xml'; + } + + if (is_file($file) && $xml = simplexml_load_file($file)) + { + // Look for the first view node off of the root node. + if ($view = $xml->xpath('view[1]')) + { + // Add view title if present. + if (!empty($view[0]['title'])) + { + $viewTitle = trim((string) $view[0]['title']); + + // Check if the key is valid. Needed due to B/C so we don't show untranslated keys. This check should be removed with Joomla 4. + if ($lang->hasKey($viewTitle)) + { + $titleParts[] = Text::_($viewTitle); + } + } + } + } + + $vars['layout'] = $vars['layout'] ?? 'default'; + + // Attempt to load the layout xml file. + // If Alternative Menu Item, get template folder for layout file + if (strpos($vars['layout'], ':') > 0) + { + // Use template folder for layout file + $temp = explode(':', $vars['layout']); + $file = JPATH_SITE . '/templates/' . $temp[0] . '/html/' . $item->componentname . '/' . $vars['view'] . '/' . $temp[1] . '.xml'; + + // Load template language file + $lang->load('tpl_' . $temp[0] . '.sys', JPATH_SITE, null, false, true) + || $lang->load('tpl_' . $temp[0] . '.sys', JPATH_SITE . '/templates/' . $temp[0], null, false, true); + } + else + { + // Get XML file from component folder for standard layouts + $file = JPATH_SITE . '/components/' . $item->componentname . '/tmpl/' . $vars['view'] + . '/' . $vars['layout'] . '.xml'; + + if (!file_exists($file)) + { + $file = JPATH_SITE . '/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'; + } + } + } + + if (is_file($file) && $xml = simplexml_load_file($file)) + { + // Look for the first view node off of the root node. + if ($layout = $xml->xpath('layout[1]')) + { + if (!empty($layout[0]['title'])) + { + $titleParts[] = Text::_(trim((string) $layout[0]['title'])); + } + } + + if (!empty($layout[0]->message[0])) + { + $item->item_type_desc = Text::_(trim((string) $layout[0]->message[0])); + } + } + + unset($xml); + + // Special case if neither a view nor layout title is found + if (count($titleParts) == 1) + { + $titleParts[] = $vars['view']; + } + } + + $value = implode(' » ', $titleParts); + } + else + { + if (preg_match("/^index.php\?option=([a-zA-Z\-0-9_]*)/", $item->link, $result)) + { + $value = Text::sprintf('COM_MENUS_TYPE_UNEXISTING', $result[1]); + } + else + { + $value = Text::_('COM_MENUS_TYPE_UNKNOWN'); + } + } + break; + } + + $item->item_type = $value; + $item->protected = $item->menutype == 'main'; + } + + // Levels filter. + $options = array(); + $options[] = HTMLHelper::_('select.option', '1', Text::_('J1')); + $options[] = HTMLHelper::_('select.option', '2', Text::_('J2')); + $options[] = HTMLHelper::_('select.option', '3', Text::_('J3')); + $options[] = HTMLHelper::_('select.option', '4', Text::_('J4')); + $options[] = HTMLHelper::_('select.option', '5', Text::_('J5')); + $options[] = HTMLHelper::_('select.option', '6', Text::_('J6')); + $options[] = HTMLHelper::_('select.option', '7', Text::_('J7')); + $options[] = HTMLHelper::_('select.option', '8', Text::_('J8')); + $options[] = HTMLHelper::_('select.option', '9', Text::_('J9')); + $options[] = HTMLHelper::_('select.option', '10', Text::_('J10')); + + $this->f_levels = $options; + + // We don't need toolbar in the modal window. + if ($this->getLayout() !== 'modal') + { + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + // We do not need to filter by language when multilingual is disabled + if (!Multilanguage::isEnabled()) + { + unset($this->activeFilters['language']); + $this->filterForm->removeField('language', 'filter'); + } + } + else + { + // In menu associations modal we need to remove language filter if forcing a language. + if ($forcedLanguage = Factory::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 a 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']); + } + } + + // Allow a system plugin to insert dynamic menu types to the list shown in menus: + Factory::getApplication()->triggerEvent('onBeforeRenderMenuItems', array($this)); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $menutypeId = (int) $this->state->get('menutypeid'); + + $canDo = ContentHelper::getActions('com_menus', 'menu', (int) $menutypeId); + $user = Factory::getUser(); + + // Get the menu title + $menuTypeTitle = $this->get('State')->get('menutypetitle'); + + // Get the toolbar object instance + $bar = Toolbar::getInstance('toolbar'); + + if ($menuTypeTitle) + { + ToolbarHelper::title(Text::sprintf('COM_MENUS_VIEW_ITEMS_MENU_TITLE', $menuTypeTitle), 'list menumgr'); + } + else + { + ToolbarHelper::title(Text::_('COM_MENUS_VIEW_ITEMS_ALL_TITLE'), 'list menumgr'); + } + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('item.add'); + } + + $protected = $this->state->get('filter.menutype') == 'main'; + + if ($canDo->get('core.edit.state') && !$protected) + { + ToolbarHelper::publish('items.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('items.unpublish', 'JTOOLBAR_UNPUBLISH', true); + } + + if (Factory::getUser()->authorise('core.admin') && !$protected) + { + ToolbarHelper::checkin('items.checkin', 'JTOOLBAR_CHECKIN', true); + } + + if ($canDo->get('core.edit.state') && $this->state->get('filter.client_id') == 0) + { + ToolbarHelper::makeDefault('items.setDefault', 'COM_MENUS_TOOLBAR_SET_HOME'); + } + + if (Factory::getUser()->authorise('core.admin')) + { + ToolbarHelper::custom('items.rebuild', 'refresh.png', 'refresh_f2.png', 'JToolbar_Rebuild', false); + } + + // Add a batch button + if (!$protected && $user->authorise('core.create', 'com_menus') + && $user->authorise('core.edit', 'com_menus') + && $user->authorise('core.edit.state', 'com_menus')) + { + $title = Text::_('JTOOLBAR_BATCH'); + + // Instantiate a new FileLayout instance and render the batch button + $layout = new FileLayout('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if (!$protected && $this->state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'items.delete', 'JTOOLBAR_EMPTY_TRASH'); + } + elseif (!$protected && $canDo->get('core.edit.state')) + { + ToolbarHelper::trash('items.trash'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::divider(); + ToolbarHelper::preferences('com_menus'); + } + + ToolbarHelper::help('JHELP_MENUS_MENU_ITEM_MANAGER'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + $this->state = $this->get('State'); + + if ($this->state->get('filter.client_id') == 0) + { + return array( + 'a.lft' => Text::_('JGRID_HEADING_ORDERING'), + 'a.published' => Text::_('JSTATUS'), + 'a.title' => Text::_('JGLOBAL_TITLE'), + 'a.home' => Text::_('COM_MENUS_HEADING_HOME'), + 'a.access' => Text::_('JGRID_HEADING_ACCESS'), + 'association' => Text::_('COM_MENUS_HEADING_ASSOCIATION'), + 'language' => Text::_('JGRID_HEADING_LANGUAGE'), + 'a.id' => Text::_('JGRID_HEADING_ID') + ); + } + else + { + return array( + 'a.lft' => Text::_('JGRID_HEADING_ORDERING'), + 'a.published' => Text::_('JSTATUS'), + 'a.title' => Text::_('JGLOBAL_TITLE'), + 'a.id' => Text::_('JGRID_HEADING_ID') + ); + } + } +} diff --git a/administrator/components/com_menus/View/Menu/HtmlView.php b/administrator/components/com_menus/View/Menu/HtmlView.php new file mode 100644 index 0000000000000..5e94d5dc1bd68 --- /dev/null +++ b/administrator/components/com_menus/View/Menu/HtmlView.php @@ -0,0 +1,141 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + $this->canDo = ContentHelper::getActions('com_menus', 'menu', $this->item->id); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + parent::display($tpl); + $this->addToolbar(); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $input = Factory::getApplication()->input; + $input->set('hidemainmenu', true); + + $isNew = ($this->item->id == 0); + + ToolbarHelper::title(Text::_($isNew ? 'COM_MENUS_VIEW_NEW_MENU_TITLE' : 'COM_MENUS_VIEW_EDIT_MENU_TITLE'), 'list menu'); + + $toolbarButtons = []; + + // If a new item, can save the item. Allow users with edit permissions to apply changes to prevent returning to grid. + if ($isNew && $this->canDo->get('core.create')) + { + if ($this->canDo->get('core.edit')) + { + $toolbarButtons[] = ['apply', 'menu.apply']; + } + + $toolbarButtons[] = ['save', 'menu.save']; + } + + // If user can edit, can save the item. + if (!$isNew && $this->canDo->get('core.edit')) + { + $toolbarButtons[] = ['apply', 'menu.apply']; + $toolbarButtons[] = ['save', 'menu.save']; + } + + // If the user can create new items, allow them to see Save & New + if ($this->canDo->get('core.create')) + { + $toolbarButtons[] = ['save2new', 'menu.save2new']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if ($isNew) + { + ToolbarHelper::cancel('menu.cancel'); + } + else + { + ToolbarHelper::cancel('menu.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_MENUS_MENU_MANAGER_EDIT'); + } +} diff --git a/administrator/components/com_menus/View/Menu/XmlView.php b/administrator/components/com_menus/View/Menu/XmlView.php new file mode 100644 index 0000000000000..66640ae4b2e4a --- /dev/null +++ b/administrator/components/com_menus/View/Menu/XmlView.php @@ -0,0 +1,179 @@ +input->getCmd('menutype'); + + if ($menutype) + { + $items = MenusHelper::getMenuItems($menutype, true); + } + + if (empty($items)) + { + Log::add(Text::_('COM_MENUS_SELECT_MENU_FIRST_EXPORT'), Log::WARNING, 'jerror'); + + $app->redirect(Route::_('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)) + { + Log::add("Headers already sent at $file:$line.", Log::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 = Factory::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/View/Menus/HtmlView.php b/administrator/components/com_menus/View/Menus/HtmlView.php new file mode 100644 index 0000000000000..69f672c2c961b --- /dev/null +++ b/administrator/components/com_menus/View/Menus/HtmlView.php @@ -0,0 +1,156 @@ +items = $this->get('Items'); + $this->modules = $this->get('Modules'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + + if ($this->getLayout() == 'default') + { + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + } + + MenusHelper::addSubmenu('menus'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_menus'); + + ToolbarHelper::title(Text::_('COM_MENUS_VIEW_MENUS_TITLE'), 'list menumgr'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('menu.add'); + } + + if ($canDo->get('core.delete')) + { + ToolbarHelper::divider(); + ToolbarHelper::deleteList('COM_MENUS_MENU_CONFIRM_DELETE', 'menus.delete', 'JTOOLBAR_DELETE'); + } + + ToolbarHelper::custom('menus.rebuild', 'refresh.png', 'refresh_f2.png', 'JTOOLBAR_REBUILD', false); + + if ($canDo->get('core.admin') && $this->state->get('client_id') == 1) + { + ToolbarHelper::custom('menu.exportXml', 'download', 'download', 'COM_MENUS_MENU_EXPORT_BUTTON', true); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::divider(); + ToolbarHelper::preferences('com_menus'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_MENUS_MENU_MANAGER'); + } +} diff --git a/administrator/components/com_menus/View/Menutypes/HtmlView.php b/administrator/components/com_menus/View/Menutypes/HtmlView.php new file mode 100644 index 0000000000000..1428795d8582d --- /dev/null +++ b/administrator/components/com_menus/View/Menutypes/HtmlView.php @@ -0,0 +1,166 @@ +recordId = $app->input->getInt('recordId'); + + $types = $this->get('TypeOptions'); + + $this->addCustomTypes($types); + + $sortedTypes = array(); + + foreach ($types as $name => $list) + { + $tmp = array(); + + foreach ($list as $item) + { + $tmp[Text::_($item->title)] = $item; + } + + ksort($tmp); + $sortedTypes[Text::_($name)] = $tmp; + } + + ksort($sortedTypes); + + $this->types = $sortedTypes; + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 3.0 + */ + protected function addToolbar() + { + // Add page title + ToolbarHelper::title(Text::_('COM_MENUS'), 'list menumgr'); + + // Get the toolbar object instance + $bar = Toolbar::getInstance('toolbar'); + + // Cancel + $title = Text::_('JTOOLBAR_CANCEL'); + $dhtml = ""; + $bar->appendButton('Custom', $dhtml, 'new'); + } + + /** + * Method to add system link types to the link types array + * + * @param array &$types The list of link types + * + * @return void + * + * @since 3.7.0 + */ + protected function addCustomTypes(&$types) + { + if (empty($types)) + { + $types = array(); + } + + // Adding System Links + $list = array(); + $o = new \JObject; + $o->title = 'COM_MENUS_TYPE_EXTERNAL_URL'; + $o->type = 'url'; + $o->description = 'COM_MENUS_TYPE_EXTERNAL_URL_DESC'; + $o->request = null; + $list[] = $o; + + $o = new \JObject; + $o->title = 'COM_MENUS_TYPE_ALIAS'; + $o->type = 'alias'; + $o->description = 'COM_MENUS_TYPE_ALIAS_DESC'; + $o->request = null; + $list[] = $o; + + $o = new \JObject; + $o->title = 'COM_MENUS_TYPE_SEPARATOR'; + $o->type = 'separator'; + $o->description = 'COM_MENUS_TYPE_SEPARATOR_DESC'; + $o->request = null; + $list[] = $o; + + $o = new \JObject; + $o->title = 'COM_MENUS_TYPE_HEADING'; + $o->type = 'heading'; + $o->description = 'COM_MENUS_TYPE_HEADING_DESC'; + $o->request = null; + $list[] = $o; + + if ($this->get('state')->get('client_id') == 1) + { + $o = new \JObject; + $o->title = 'COM_MENUS_TYPE_CONTAINER'; + $o->type = 'container'; + $o->description = 'COM_MENUS_TYPE_CONTAINER_DESC'; + $o->request = null; + $list[] = $o; + } + + $types['COM_MENUS_TYPE_SYSTEM'] = $list; + } +} diff --git a/administrator/components/com_menus/access.xml b/administrator/components/com_menus/access.xml index c709842eecf11..22cc5c6922ade 100644 --- a/administrator/components/com_menus/access.xml +++ b/administrator/components/com_menus/access.xml @@ -1,19 +1,19 @@
    - - - - - - - + + + + + + +
    - - - - - + + + + +
    diff --git a/administrator/components/com_menus/config.xml b/administrator/components/com_menus/config.xml index 3b1b94a2bbe44..94c1c18c54c54 100644 --- a/administrator/components/com_menus/config.xml +++ b/administrator/components/com_menus/config.xml @@ -9,28 +9,25 @@ name="page_title" type="text" label="COM_MENUS_ITEM_FIELD_PAGE_TITLE_LABEL" - description="COM_MENUS_ITEM_FIELD_PAGE_TITLE_DESC" default="" /> - - + + @@ -39,7 +36,6 @@ name="pageclass_sfx" type="text" label="COM_MENUS_ITEM_FIELD_PAGE_CLASS_LABEL" - description="COM_MENUS_ITEM_FIELD_PAGE_CLASS_DESC" default="" /> diff --git a/administrator/components/com_menus/controller.php b/administrator/components/com_menus/controller.php deleted file mode 100644 index 0a7c45189e892..0000000000000 --- a/administrator/components/com_menus/controller.php +++ /dev/null @@ -1,77 +0,0 @@ -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/item.php b/administrator/components/com_menus/controllers/item.php deleted file mode 100644 index e8ec6e2b9f33c..0000000000000 --- a/administrator/components/com_menus/controllers/item.php +++ /dev/null @@ -1,613 +0,0 @@ -input->getCmd('menutype', isset($data['menutype']) ? $data['menutype'] : ''); - - $menutypeID = 0; - - // Load menutype ID - if ($menuType) - { - $menutypeID = (int) $this->getMenuTypeId($menuType); - } - - return $user->authorise('core.create', 'com_menus.menu.' . $menutypeID); - } - - /** - * Method to check if you edit a record. - * - * Extended classes can override this if necessary. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key; default is id. - * - * @return boolean - * - * @since 3.6 - */ - protected function allowEdit($data = array(), $key = 'id') - { - $user = JFactory::getUser(); - - $menutypeID = 0; - - if (isset($data[$key])) - { - $model = $this->getModel(); - $item = $model->getItem($data[$key]); - - if (!empty($item->menutype)) - { - // Protected menutype, do not allow edit - if ($item->menutype == 'main') - { - return false; - } - - $menutypeID = (int) $this->getMenuTypeId($item->menutype); - } - } - - return $user->authorise('core.edit', 'com_menus.menu.' . (int) $menutypeID); - } - - /** - * Loads the menutype ID by a given menutype string - * - * @param string $menutype The given menutype - * - * @return integer - * - * @since 3.6 - */ - protected function getMenuTypeId($menutype) - { - $model = $this->getModel(); - $table = $model->getTable('MenuType', 'JTable'); - - $table->load(array('menutype' => $menutype)); - - return (int) $table->id; - } - - /** - * Method to add a new menu item. - * - * @return mixed True if the record can be added, a JError object if not. - * - * @since 1.6 - */ - public function add() - { - $app = JFactory::getApplication(); - $context = 'com_menus.edit.item'; - - $result = parent::add(); - - if ($result) - { - $app->setUserState($context . '.type', null); - $app->setUserState($context . '.link', null); - } - - return $result; - } - - /** - * Method to run batch operations. - * - * @param object $model The model. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 1.6 - */ - public function batch($model = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $model = $this->getModel('Item', '', array()); - - // Preset the redirect - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=items' . $this->getRedirectToListAppend(), false)); - - return parent::batch($model); - } - - /** - * Method to cancel an edit. - * - * @param string $key The name of the primary key of the URL variable. - * - * @return boolean True if access level checks pass, false otherwise. - * - * @since 1.6 - */ - public function cancel($key = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $context = 'com_menus.edit.item'; - $result = parent::cancel(); - - if ($result) - { - // Clear the ancillary data from the session. - $app->setUserState($context . '.type', null); - $app->setUserState($context . '.link', 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 - ) - ); - } - - return $result; - } - - /** - * Method to edit an existing record. - * - * @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 access level check and checkout passes, false otherwise. - * - * @since 1.6 - */ - public function edit($key = null, $urlVar = null) - { - $app = JFactory::getApplication(); - $result = parent::edit(); - - if ($result) - { - // Push the new ancillary data into the session. - $app->setUserState('com_menus.edit.item.type', null); - $app->setUserState('com_menus.edit.item.link', null); - } - - return $result; - } - - /** - * Gets the URL arguments to append to an item redirect. - * - * @param integer $recordId The primary key id for the item. - * @param string $urlVar The name of the URL variable for the id. - * - * @return string The arguments to append to the redirect URL. - * - * @since 12.2 - */ - protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') - { - $append = parent::getRedirectToItemAppend($recordId, $urlVar); - - if ($recordId) - { - $model = $this->getModel(); - $item = $model->getItem($recordId); - $clientId = $item->client_id; - $append = '&client_id=' . $clientId . $append; - } - else - { - $app = JFactory::getApplication(); - $clientId = $app->input->get('client_id', '0', 'int'); - $menuType = $app->input->get('menutype', 'mainmenu', 'cmd'); - $append = '&client_id=' . $clientId . ($menuType ? '&menutype=' . $menuType : '') . $append; - } - - return $append; - } - - /** - * Method to save a record. - * - * @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 1.6 - */ - public function save($key = null, $urlVar = null) - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $model = $this->getModel('Item', '', array()); - $table = $model->getTable(); - $data = $this->input->post->get('jform', array(), 'array'); - $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)) - { - $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); - - // Populate the row id from the session. - $data[$key] = $recordId; - - // The save2copy task needs to be handled slightly differently. - if ($task == 'save2copy') - { - // Check-in the original row. - if ($model->checkin($data['id']) === false) - { - // Check-in failed, go back to the item and display a notice. - $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'warning'); - - return false; - } - - // Reset the ID and then treat the request as for Apply. - $data['id'] = 0; - $data['associations'] = array(); - $task = 'apply'; - } - - // 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=' . $this->option . '&view=' . $this->view_list - . $this->getRedirectToListAppend(), false - ) - ); - - return false; - } - - // Validate the posted data. - // This post is made up of two forms, one for the item and one for params. - $form = $model->getForm($data); - - if (!$form) - { - JError::raiseError(500, $model->getError()); - - return false; - } - - if ($data['type'] == 'url') - { - $data['link'] = str_replace(array('"', '>', '<'), '', $data['link']); - - if (strstr($data['link'], ':')) - { - $segments = explode(':', $data['link']); - $protocol = strtolower($segments[0]); - $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)) - { - $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'warning'); - $this->setRedirect( - JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false) - ); - - return false; - } - } - } - - $data = $model->validate($form, $data); - - // Preprocess request fields to ensure that we remove not set or empty request params - $request = $form->getGroup('request'); - - // Check for the special 'request' entry. - if ($data['type'] == 'component' && !empty($request)) - { - $removeArgs = array(); - - if (!isset($data['request']) || !is_array($data['request'])) - { - $data['request'] = array(); - } - - foreach ($request as $field) - { - $fieldName = $field->getAttribute('name'); - - if (!isset($data['request'][$fieldName]) || $data['request'][$fieldName] == '') - { - $removeArgs[$fieldName] = ''; - } - } - - // Parse the submitted link arguments. - $args = array(); - parse_str(parse_url($data['link'], PHP_URL_QUERY), $args); - - // Merge in the user supplied request arguments. - $args = array_merge($args, $data['request']); - - // Remove the unused request params - if (!empty($args) && !empty($removeArgs)) - { - $args = array_diff_key($args, $removeArgs); - } - - $data['link'] = 'index.php?' . urldecode(http_build_query($args, '', '&')); - unset($data['request']); - } - - // Check for validation errors. - if ($data === false) - { - // Get the validation messages. - $errors = $model->getErrors(); - - // 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) - { - $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); - } - else - { - $app->enqueueMessage($errors[$i], 'warning'); - } - } - - // Save the data in the session. - $app->setUserState('com_menus.edit.item.data', $data); - - // Redirect back to the edit screen. - $editUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); - $this->setRedirect(JRoute::_($editUrl, false)); - - return false; - } - - // Attempt to save the data. - if (!$model->save($data)) - { - // Save the data in the session. - $app->setUserState('com_menus.edit.item.data', $data); - - // Redirect back to the edit screen. - $editUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); - $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); - $this->setRedirect(JRoute::_($editUrl, false)); - - return false; - } - - // Save succeeded, check-in the row. - if ($model->checkin($data['id']) === false) - { - // Check-in failed, go back to the row and display a notice. - $this->setMessage(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'warning'); - $redirectUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); - $this->setRedirect(JRoute::_($redirectUrl, false)); - - return false; - } - - $this->setMessage(JText::_('COM_MENUS_SAVE_SUCCESS')); - - // Redirect the user and adjust session state based on the chosen task. - switch ($task) - { - case 'apply': - // Set the row data in the session. - $recordId = $model->getState($this->context . '.id'); - $this->holdEditId($context, $recordId); - $app->setUserState('com_menus.edit.item.data', null); - $app->setUserState('com_menus.edit.item.type', null); - $app->setUserState('com_menus.edit.item.link', null); - - // Redirect back to the edit screen. - $editUrl = 'index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId); - $this->setRedirect(JRoute::_($editUrl, false)); - break; - - case 'save2new': - // Clear the row id and data in the session. - $this->releaseEditId($context, $recordId); - $app->setUserState('com_menus.edit.item.data', null); - $app->setUserState('com_menus.edit.item.type', null); - $app->setUserState('com_menus.edit.item.link', null); - - // Redirect back to the edit screen. - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(), false)); - break; - - default: - // Clear the row id and data in the session. - $this->releaseEditId($context, $recordId); - $app->setUserState('com_menus.edit.item.data', null); - $app->setUserState('com_menus.edit.item.type', null); - $app->setUserState('com_menus.edit.item.link', 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 - ) - ); - break; - } - - return true; - } - - /** - * Sets the type of the menu item currently being edited. - * - * @return void - * - * @since 1.6 - */ - public function setType() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - - // Get the posted values from the request. - $data = $this->input->post->get('jform', array(), 'array'); - - // Get the type. - $type = $data['type']; - - $type = json_decode(base64_decode($type)); - $title = isset($type->title) ? $type->title : null; - $recordId = isset($type->id) ? $type->id : 0; - - $specialTypes = array('alias', 'separator', 'url', 'heading', 'container'); - - if (!in_array($title, $specialTypes)) - { - $title = 'component'; - } - else - { - // Set correct component id to ensure proper 404 messages with system links - $data['component_id'] = 0; - } - - $app->setUserState('com_menus.edit.item.type', $title); - - if ($title == 'component') - { - 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; - - $app->setUserState('com_menus.edit.item.link', 'index.php?' . JUri::buildQuery((array) $type->request)); - } - } - // If the type is alias you just need the item id from the menu item referenced. - elseif ($title == 'alias') - { - $app->setUserState('com_menus.edit.item.link', 'index.php?Itemid='); - } - - unset($data['request']); - - $data['type'] = $title; - - if ($this->input->get('fieldtype') == 'type') - { - $data['link'] = $app->getUserState('com_menus.edit.item.link'); - } - - // Save the data in the session. - $app->setUserState('com_menus.edit.item.data', $data); - - $this->type = $type; - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId), false)); - } - - /** - * Gets the parent items of the menu location currently. - * - * @return void - * - * @since 3.2 - */ - public function getParentItem() - { - $app = JFactory::getApplication(); - - $results = array(); - $menutype = $this->input->get->get('menutype'); - - if ($menutype) - { - $model = $this->getModel('Items', '', array()); - $model->getState(); - $model->setState('filter.menutype', $menutype); - $model->setState('list.select', 'a.id, a.title, a.level'); - $model->setState('list.start', '0'); - $model->setState('list.limit', '0'); - - /** @var MenusModelItems $model */ - $results = $model->getItems(); - - // Pad the option text with spaces using depth level as a multiplier. - for ($i = 0, $n = count($results); $i < $n; $i++) - { - $results[$i]->title = str_repeat(' - ', $results[$i]->level) . $results[$i]->title; - } - } - - // Output a JSON object - echo json_encode($results); - - $app->close(); - } -} diff --git a/administrator/components/com_menus/controllers/items.php b/administrator/components/com_menus/controllers/items.php deleted file mode 100644 index b215017cc9bf0..0000000000000 --- a/administrator/components/com_menus/controllers/items.php +++ /dev/null @@ -1,315 +0,0 @@ -registerTask('unsetDefault', 'setDefault'); - } - - /** - * Proxy for getModel. - * - * @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 1.6 - */ - public function getModel($name = 'Item', $prefix = 'MenusModel', $config = array()) - { - return parent::getModel($name, $prefix, array('ignore_request' => true)); - } - - /** - * Rebuild the nested set tree. - * - * @return boolean False on failure or error, true on success. - * - * @since 1.6 - */ - public function rebuild() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $this->setRedirect('index.php?option=com_menus&view=items'); - - $model = $this->getModel(); - - if ($model->rebuild()) - { - // Reorder succeeded. - $this->setMessage(JText::_('COM_MENUS_ITEMS_REBUILD_SUCCESS')); - - return true; - } - else - { - // Rebuild failed. - $this->setMessage(JText::sprintf('COM_MENUS_ITEMS_REBUILD_FAILED'), 'error'); - - return false; - } - } - - /** - * Save the manual order inputs from the menu items list view - * - * @return void - * - * @see JControllerAdmin::saveorder() - * @deprecated 4.0 - */ - public function saveorder() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - try - { - JLog::add( - sprintf('%s() is deprecated. Function will be removed in 4.0.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Get the arrays from the Request - $order = $this->input->post->get('order', null, 'array'); - $originalOrder = explode(',', $this->input->getString('original_order_values')); - - // Make sure something has changed - if (!($order === $originalOrder)) - { - parent::saveorder(); - } - else - { - // Nothing to reorder - $this->setRedirect(JRoute::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); - - return true; - } - } - - /** - * Method to set the home property for a list of items - * - * @return void - * - * @since 1.6 - */ - public function setDefault() - { - // Check for request forgeries - JSession::checkToken('request') or die(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - - // Get items to publish from the request. - $cid = $this->input->get('cid', array(), 'array'); - $data = array('setDefault' => 1, 'unsetDefault' => 0); - $task = $this->getTask(); - $value = ArrayHelper::getValue($data, $task, 0, 'int'); - - if (empty($cid)) - { - JError::raiseWarning(500, JText::_($this->text_prefix . '_NO_ITEM_SELECTED')); - } - else - { - // Get the model. - $model = $this->getModel(); - - // Make sure the item ids are integers - $cid = ArrayHelper::toInteger($cid); - - // Publish the items. - if (!$model->setHome($cid, $value)) - { - JError::raiseWarning(500, $model->getError()); - } - else - { - if ($value == 1) - { - $ntext = 'COM_MENUS_ITEMS_SET_HOME'; - } - else - { - $ntext = 'COM_MENUS_ITEMS_UNSET_HOME'; - } - - $this->setMessage(JText::plural($ntext, count($cid))); - } - } - - $this->setRedirect( - JRoute::_( - 'index.php?option=' . $this->option . '&view=' . $this->view_list - . '&menutype=' . $app->getUserState('com_menus.items.menutype'), false - ) - ); - } - - /** - * Method to publish a list of items - * - * @return void - * - * @since 3.6.0 - */ - public function publish() - { - // Check for request forgeries - JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); - - // Get items to publish from the request. - $cid = JFactory::getApplication()->input->get('cid', array(), 'array'); - $data = array('publish' => 1, 'unpublish' => 0, 'trash' => -2, 'report' => -3); - $task = $this->getTask(); - $value = ArrayHelper::getValue($data, $task, 0, 'int'); - - if (empty($cid)) - { - try - { - JLog::add(JText::_($this->text_prefix . '_NO_ITEM_SELECTED'), JLog::WARNING, 'jerror'); - } - catch (RuntimeException $exception) - { - JFactory::getApplication()->enqueueMessage(JText::_($this->text_prefix . '_NO_ITEM_SELECTED'), 'warning'); - } - } - else - { - // Get the model. - $model = $this->getModel(); - - // Make sure the item ids are integers - $cid = ArrayHelper::toInteger($cid); - - // Publish the items. - try - { - $model->publish($cid, $value); - $errors = $model->getErrors(); - $messageType = 'message'; - - if ($value == 1) - { - if ($errors) - { - $messageType = 'error'; - $ntext = $this->text_prefix . '_N_ITEMS_FAILED_PUBLISHING'; - } - else - { - $ntext = $this->text_prefix . '_N_ITEMS_PUBLISHED'; - } - } - elseif ($value == 0) - { - $ntext = $this->text_prefix . '_N_ITEMS_UNPUBLISHED'; - } - else - { - $ntext = $this->text_prefix . '_N_ITEMS_TRASHED'; - } - - $this->setMessage(JText::plural($ntext, count($cid)), $messageType); - } - catch (Exception $e) - { - $this->setMessage($e->getMessage(), 'error'); - } - } - - $this->setRedirect( - JRoute::_( - 'index.php?option=' . $this->option . '&view=' . $this->view_list . '&menutype=' . - JFactory::getApplication()->getUserState('com_menus.items.menutype'), - false - ) - ); - } - - /** - * Check in of one or more records. - * - * @return boolean True on success - * - * @since 3.6.0 - */ - public function checkin() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = JFactory::getApplication()->input->post->get('cid', array(), 'array'); - - $model = $this->getModel(); - $return = $model->checkin($ids); - - if ($return === false) - { - // Checkin failed. - $message = JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()); - $this->setRedirect( - JRoute::_( - 'index.php?option=' . $this->option . '&view=' . $this->view_list - . '&menutype=' . JFactory::getApplication()->getUserState('com_menus.items.menutype'), - false - ), - $message, - 'error' - ); - - return false; - } - else - { - // Checkin succeeded. - $message = JText::plural($this->text_prefix . '_N_ITEMS_CHECKED_IN', count($ids)); - $this->setRedirect( - JRoute::_( - 'index.php?option=' . $this->option . '&view=' . $this->view_list - . '&menutype=' . JFactory::getApplication()->getUserState('com_menus.items.menutype'), - false - ), - $message - ); - - return true; - } - } -} diff --git a/administrator/components/com_menus/controllers/menu.php b/administrator/components/com_menus/controllers/menu.php deleted file mode 100644 index 4f115dd2bc804..0000000000000 --- a/administrator/components/com_menus/controllers/menu.php +++ /dev/null @@ -1,212 +0,0 @@ -setRedirect(JRoute::_('index.php?option=com_menus&view=menus', false)); - } - - /** - * Method to save a menu item. - * - * @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 1.6 - */ - public function save($key = null, $urlVar = null) - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $data = $this->input->post->get('jform', array(), 'array'); - $context = 'com_menus.edit.menu'; - $task = $this->getTask(); - $recordId = $this->input->getInt('id'); - - // Prevent using 'main' as menutype as this is reserved for backend menus - if (strtolower($data['menutype']) == 'main') - { - $msg = JText::_('COM_MENUS_ERROR_MENUTYPE'); - JFactory::getApplication()->enqueueMessage($msg, 'error'); - - // Redirect back to the edit screen. - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit', false)); - - return false; - } - - // Populate the row id from the session. - $data['id'] = $recordId; - - // Get the model and attempt to validate the posted data. - $model = $this->getModel('Menu'); - $form = $model->getForm(); - - if (!$form) - { - JError::raiseError(500, $model->getError()); - - return false; - } - - $validData = $model->validate($form, $data); - - // Check for validation errors. - if ($validData === false) - { - // Get the validation messages. - $errors = $model->getErrors(); - - // 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) - { - $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); - } - else - { - $app->enqueueMessage($errors[$i], 'warning'); - } - } - - // Save the data in the session. - $app->setUserState($context . '.data', $data); - - // Redirect back to the edit screen. - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit', false)); - - return false; - } - - if (isset($validData['preset'])) - { - $preset = trim($validData['preset']) ?: null; - - unset($validData['preset']); - } - - // Attempt to save the data. - if (!$model->save($validData)) - { - // Save the data in the session. - $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)); - - return false; - } - - // 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) - { - case 'apply': - // Set the record data in the session. - $recordId = $model->getState($this->context . '.id'); - $this->holdEditId($context, $recordId); - - // Redirect back to the edit screen. - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menu&layout=edit' . $this->getRedirectToItemAppend($recordId), false)); - break; - - case 'save2new': - // Clear the record id and data from the session. - $this->releaseEditId($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', false)); - break; - - default: - // Clear the record id and data from the session. - $this->releaseEditId($context, $recordId); - $app->setUserState($context . '.data', null); - - // Redirect to the list screen. - $this->setRedirect(JRoute::_('index.php?option=com_menus&view=menus', false)); - 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 deleted file mode 100644 index 3754891524460..0000000000000 --- a/administrator/components/com_menus/controllers/menus.php +++ /dev/null @@ -1,227 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Remove an item. - * - * @return void - * - * @since 1.6 - */ - public function delete() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $user = JFactory::getUser(); - $app = JFactory::getApplication(); - $cids = (array) $this->input->get('cid', array(), 'array'); - - if (count($cids) < 1) - { - $app->enqueueMessage(JText::_('COM_MENUS_NO_MENUS_SELECTED'), 'notice'); - } - else - { - // Access checks. - foreach ($cids as $i => $id) - { - if (!$user->authorise('core.delete', 'com_menus.menu.' . (int) $id)) - { - // Prune items that you can't change. - unset($cids[$i]); - $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 'error'); - } - } - - if (count($cids) > 0) - { - // Get the model. - $model = $this->getModel(); - - // Make sure the item ids are integers - $cids = ArrayHelper::toInteger($cids); - - // Remove the items. - if (!$model->delete($cids)) - { - $this->setMessage($model->getError(), 'error'); - } - else - { - $this->setMessage(JText::plural('COM_MENUS_N_MENUS_DELETED', count($cids))); - } - } - } - - $this->setRedirect('index.php?option=com_menus&view=menus'); - } - - /** - * Rebuild the menu tree. - * - * @return boolean False on failure or error, true on success. - * - * @since 1.6 - */ - public function rebuild() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $this->setRedirect('index.php?option=com_menus&view=menus'); - - $model = $this->getModel('Item'); - - if ($model->rebuild()) - { - // Reorder succeeded. - $this->setMessage(JText::_('JTOOLBAR_REBUILD_SUCCESS')); - - return true; - } - else - { - // Rebuild failed. - $this->setMessage(JText::sprintf('JTOOLBAR_REBUILD_FAILED', $model->getError()), 'error'); - - return false; - } - } - - /** - * Temporary method. This should go into the 1.5 to 1.6 upgrade routines. - * - * @return JException|void JException instance on error - * - * @since 1.6 - */ - public function resync() - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - $parts = null; - - try - { - $query->select('element, extension_id') - ->from('#__extensions') - ->where('type = ' . $db->quote('component')); - $db->setQuery($query); - - $components = $db->loadAssocList('element', 'extension_id'); - } - catch (RuntimeException $e) - { - return JError::raiseWarning(500, $e->getMessage()); - } - - // Load all the component menu links - $query->select($db->quoteName('id')) - ->select($db->quoteName('link')) - ->select($db->quoteName('component_id')) - ->from('#__menu') - ->where($db->quoteName('type') . ' = ' . $db->quote('component.item')); - $db->setQuery($query); - - try - { - $items = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - return JError::raiseWarning(500, $e->getMessage()); - } - - foreach ($items as $item) - { - // Parse the link. - parse_str(parse_url($item->link, PHP_URL_QUERY), $parts); - - // Tease out the option. - if (isset($parts['option'])) - { - $option = $parts['option']; - - // Lookup the component ID - if (isset($components[$option])) - { - $componentId = $components[$option]; - } - else - { - // Mismatch. Needs human intervention. - $componentId = -1; - } - - // Check for mis-matched component id's in the menu link. - if ($item->component_id != $componentId) - { - // Update the menu table. - $log = "Link $item->id refers to $item->component_id, converting to $componentId ($item->link)"; - echo "
    $log"; - - $query->clear(); - $query->update('#__menu') - ->set('component_id = ' . $componentId) - ->where('id = ' . $item->id); - - try - { - $db->setQuery($query)->execute(); - } - catch (RuntimeException $e) - { - return JError::raiseWarning(500, $e->getMessage()); - } - } - } - } - } -} diff --git a/administrator/components/com_menus/forms/filter_items.xml b/administrator/components/com_menus/forms/filter_items.xml new file mode 100644 index 0000000000000..94740135d3686 --- /dev/null +++ b/administrator/components/com_menus/forms/filter_items.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_menus/models/forms/filter_itemsadmin.xml b/administrator/components/com_menus/forms/filter_itemsadmin.xml similarity index 84% rename from administrator/components/com_menus/models/forms/filter_itemsadmin.xml rename to administrator/components/com_menus/forms/filter_itemsadmin.xml index d31482bd0584e..7fab348c2d518 100644 --- a/administrator/components/com_menus/models/forms/filter_itemsadmin.xml +++ b/administrator/components/com_menus/forms/filter_itemsadmin.xml @@ -14,8 +14,6 @@ @@ -46,8 +42,6 @@ @@ -37,9 +35,6 @@ diff --git a/administrator/components/com_menus/models/forms/item.xml b/administrator/components/com_menus/forms/item.xml similarity index 77% rename from administrator/components/com_menus/models/forms/item.xml rename to administrator/components/com_menus/forms/item.xml index 456723682a3be..cb7032424aded 100644 --- a/administrator/components/com_menus/models/forms/item.xml +++ b/administrator/components/com_menus/forms/item.xml @@ -1,11 +1,10 @@ -
    +
    @@ -26,7 +24,6 @@ name="alias" type="alias" label="JFIELD_ALIAS_LABEL" - description="JFIELD_ALIAS_DESC" hint="JFIELD_ALIAS_PLACEHOLDER" size="40" /> @@ -35,9 +32,7 @@ name="note" type="text" label="JFIELD_NOTE_LABEL" - description="COM_MENUS_ITEM_FIELD_NOTE_DESC" maxlength="255" - class="span12" size="40" /> @@ -45,7 +40,6 @@ name="link" type="link" label="COM_MENUS_ITEM_FIELD_LINK_LABEL" - description="COM_MENUS_ITEM_FIELD_LINK_DESC" readonly="true" class="input-xxlarge" size="50" @@ -55,7 +49,6 @@ name="menutype" type="menu" label="COM_MENUS_ITEM_FIELD_ASSIGNED_LABEL" - description="COM_MENUS_ITEM_FIELD_ASSIGNED_DESC" required="true" clientid="0" size="1" @@ -67,19 +60,17 @@ name="type" type="menutype" label="COM_MENUS_ITEM_FIELD_TYPE_LABEL" - description="COM_MENUS_ITEM_FIELD_TYPE_DESC" class="input-medium" required="true" - size="40" + size="40" /> @@ -121,7 +110,6 @@ name="browserNav" type="list" label="COM_MENUS_ITEM_FIELD_BROWSERNAV_LABEL" - description="COM_MENUS_ITEM_FIELD_BROWSERNAV_DESC" default="0" filter="int" > @@ -134,8 +122,6 @@ name="access" type="accesslevel" label="JFIELD_ACCESS_LABEL" - description="JFIELD_ACCESS_DESC" - id="access" filter="integer" /> @@ -143,7 +129,6 @@ name="template_style_id" type="templatestyle" label="COM_MENUS_ITEM_FIELD_TEMPLATE_LABEL" - description="COM_MENUS_ITEM_FIELD_TEMPLATE_DESC" client="site" filter="int" > @@ -154,20 +139,18 @@ name="home" type="radio" label="COM_MENUS_ITEM_FIELD_HOME_LABEL" - description="COM_MENUS_ITEM_FIELD_HOME_DESC" default="0" - class="btn-group btn-group-yesno" + class="switcher" filter="integer" > - + @@ -212,26 +195,24 @@ name="toggle_modules_assigned" type="radio" label="COM_MENUS_ITEM_FIELD_HIDE_UNASSIGNED_LABEL" - description="COM_MENUS_ITEM_FIELD_HIDE_UNASSIGNED_DESC" default="1" - class="btn-group btn-group-yesno" + class="switcher" filter="integer" > - + - +
    diff --git a/administrator/components/com_menus/models/forms/item_alias.xml b/administrator/components/com_menus/forms/item_alias.xml similarity index 76% rename from administrator/components/com_menus/models/forms/item_alias.xml rename to administrator/components/com_menus/forms/item_alias.xml index 3b09c6fc343bc..ddf0c18894495 100644 --- a/administrator/components/com_menus/models/forms/item_alias.xml +++ b/administrator/components/com_menus/forms/item_alias.xml @@ -1,5 +1,5 @@ - + @@ -9,7 +9,6 @@ name="aliasoptions" type="modal_menu" label="COM_MENUS_ITEM_FIELD_ALIAS_MENU_LABEL" - description="COM_MENUS_ITEM_FIELD_ALIAS_MENU_DESC" clientid="0" required="true" select="true" @@ -27,24 +26,21 @@ name="menu-anchor_title" type="text" label="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_LABEL" - description="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_DESC" /> - - + - +
    diff --git a/administrator/components/com_menus/forms/item_component.xml b/administrator/components/com_menus/forms/item_component.xml new file mode 100644 index 0000000000000..5eb940c5d0032 --- /dev/null +++ b/administrator/components/com_menus/forms/item_component.xml @@ -0,0 +1,125 @@ + + + +
    + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + +
    + +
    + + + + + + + + + + + +
    + +
    + + diff --git a/administrator/components/com_menus/models/forms/item_heading.xml b/administrator/components/com_menus/forms/item_heading.xml similarity index 75% rename from administrator/components/com_menus/models/forms/item_heading.xml rename to administrator/components/com_menus/forms/item_heading.xml index 39a36e7b843fc..1fc402c4501e2 100644 --- a/administrator/components/com_menus/models/forms/item_heading.xml +++ b/administrator/components/com_menus/forms/item_heading.xml @@ -8,24 +8,21 @@ name="menu-anchor_title" type="text" label="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_LABEL" - description="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_DESC" /> - - + - +
    diff --git a/administrator/components/com_menus/models/forms/item_separator.xml b/administrator/components/com_menus/forms/item_separator.xml similarity index 76% rename from administrator/components/com_menus/models/forms/item_separator.xml rename to administrator/components/com_menus/forms/item_separator.xml index 7bdb02facf1b1..85dd3130d55ae 100644 --- a/administrator/components/com_menus/models/forms/item_separator.xml +++ b/administrator/components/com_menus/forms/item_separator.xml @@ -9,17 +9,15 @@ name="menu-anchor_css" type="text" label="COM_MENUS_ITEM_FIELD_ANCHOR_CSS_LABEL" - description="COM_MENUS_ITEM_FIELD_ANCHOR_CSS_DESC" /> - - + - +
    diff --git a/administrator/components/com_menus/models/forms/item_url.xml b/administrator/components/com_menus/forms/item_url.xml similarity index 79% rename from administrator/components/com_menus/models/forms/item_url.xml rename to administrator/components/com_menus/forms/item_url.xml index 29696bab0fd5b..e73a450547f94 100644 --- a/administrator/components/com_menus/models/forms/item_url.xml +++ b/administrator/components/com_menus/forms/item_url.xml @@ -8,21 +8,18 @@ name="menu-anchor_title" type="text" label="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_LABEL" - description="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_DESC" /> @@ -44,10 +41,9 @@ name="menu_image" type="media" label="COM_MENUS_ITEM_FIELD_MENU_IMAGE_LABEL" - description="COM_MENUS_ITEM_FIELD_MENU_IMAGE_DESC" /> - - + - +
    diff --git a/administrator/components/com_menus/models/forms/itemadmin.xml b/administrator/components/com_menus/forms/itemadmin.xml similarity index 83% rename from administrator/components/com_menus/models/forms/itemadmin.xml rename to administrator/components/com_menus/forms/itemadmin.xml index 4ef196c7b9dbf..8a5212400b7ba 100644 --- a/administrator/components/com_menus/models/forms/itemadmin.xml +++ b/administrator/components/com_menus/forms/itemadmin.xml @@ -1,11 +1,10 @@ -
    +
    @@ -35,9 +32,8 @@ name="note" type="text" label="JFIELD_NOTE_LABEL" - description="COM_MENUS_ITEM_FIELD_NOTE_DESC" maxlength="255" - class="span12" + class="col-md-12" size="40" /> @@ -45,7 +41,6 @@ name="link" type="link" label="COM_MENUS_ITEM_FIELD_LINK_LABEL" - description="COM_MENUS_ITEM_FIELD_LINK_DESC" readonly="true" class="input-xxlarge" size="50" @@ -55,7 +50,6 @@ name="menutype" type="menu" label="COM_MENUS_ITEM_FIELD_ASSIGNED_LABEL" - description="COM_MENUS_ITEM_FIELD_ASSIGNED_DESC" required="true" clientid="1" size="1" @@ -67,7 +61,6 @@ name="type" type="menutype" label="COM_MENUS_ITEM_FIELD_TYPE_LABEL" - description="COM_MENUS_ITEM_FIELD_TYPE_DESC" class="input-medium" required="true" size="40" @@ -77,7 +70,6 @@ name="published" type="list" label="JSTATUS" - description="JFIELD_PUBLISHED_DESC" class="chzn-color-state" id="published" size="1" @@ -91,9 +83,8 @@ @@ -121,7 +111,6 @@ name="browserNav" type="list" label="COM_MENUS_ITEM_FIELD_BROWSERNAV_LABEL" - description="COM_MENUS_ITEM_FIELD_BROWSERNAV_DESC" default="0" filter="int" > diff --git a/administrator/components/com_menus/models/forms/itemadmin_alias.xml b/administrator/components/com_menus/forms/itemadmin_alias.xml similarity index 78% rename from administrator/components/com_menus/models/forms/itemadmin_alias.xml rename to administrator/components/com_menus/forms/itemadmin_alias.xml index 1cfc97e374e97..53006f1bcf751 100644 --- a/administrator/components/com_menus/models/forms/itemadmin_alias.xml +++ b/administrator/components/com_menus/forms/itemadmin_alias.xml @@ -1,5 +1,5 @@ - +
    @@ -7,7 +7,6 @@ name="aliasoptions" type="modal_menu" label="COM_MENUS_ITEM_FIELD_ALIAS_MENU_LABEL" - description="COM_MENUS_ITEM_FIELD_ALIAS_MENU_DESC" clientid="1" required="true" select="true" @@ -26,21 +25,18 @@ name="menu-anchor_title" type="text" label="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_LABEL" - description="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_DESC" /> - + - +
    diff --git a/administrator/components/com_menus/forms/itemadmin_component.xml b/administrator/components/com_menus/forms/itemadmin_component.xml new file mode 100644 index 0000000000000..7d0a1b0e3aaac --- /dev/null +++ b/administrator/components/com_menus/forms/itemadmin_component.xml @@ -0,0 +1,58 @@ + + + +
    + + + + + + + + + + + + + + + + + + +
    +
    + diff --git a/administrator/components/com_menus/models/forms/itemadmin_container.xml b/administrator/components/com_menus/forms/itemadmin_container.xml similarity index 82% rename from administrator/components/com_menus/models/forms/itemadmin_container.xml rename to administrator/components/com_menus/forms/itemadmin_container.xml index 54f506c32db34..7aadac29fefa7 100644 --- a/administrator/components/com_menus/models/forms/itemadmin_container.xml +++ b/administrator/components/com_menus/forms/itemadmin_container.xml @@ -20,21 +20,18 @@ name="menu-anchor_title" type="text" label="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_LABEL" - description="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_DESC" /> - + - +
    - + - + diff --git a/administrator/components/com_menus/models/forms/itemadmin_separator.xml b/administrator/components/com_menus/forms/itemadmin_separator.xml similarity index 100% rename from administrator/components/com_menus/models/forms/itemadmin_separator.xml rename to administrator/components/com_menus/forms/itemadmin_separator.xml diff --git a/administrator/components/com_menus/models/forms/itemadmin_url.xml b/administrator/components/com_menus/forms/itemadmin_url.xml similarity index 79% rename from administrator/components/com_menus/models/forms/itemadmin_url.xml rename to administrator/components/com_menus/forms/itemadmin_url.xml index 29bab56210474..149d062614120 100644 --- a/administrator/components/com_menus/models/forms/itemadmin_url.xml +++ b/administrator/components/com_menus/forms/itemadmin_url.xml @@ -6,21 +6,18 @@ name="menu-anchor_title" type="text" label="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_LABEL" - description="COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_DESC" /> @@ -42,10 +39,9 @@ name="menu_image" type="media" label="COM_MENUS_ITEM_FIELD_MENU_IMAGE_LABEL" - description="COM_MENUS_ITEM_FIELD_MENU_IMAGE_DESC" /> - - + - + diff --git a/administrator/components/com_menus/models/forms/menu.xml b/administrator/components/com_menus/forms/menu.xml similarity index 82% rename from administrator/components/com_menus/models/forms/menu.xml rename to administrator/components/com_menus/forms/menu.xml index b2199b31d3cd8..bbeb1f3434e6c 100644 --- a/administrator/components/com_menus/models/forms/menu.xml +++ b/administrator/components/com_menus/forms/menu.xml @@ -1,5 +1,5 @@ -
    +
    @@ -72,7 +68,7 @@ filter="rules" component="com_menus" section="menu" - validate="rules" + validate="rules" />
    diff --git a/administrator/components/com_menus/helpers/associations.php b/administrator/components/com_menus/helpers/associations.php deleted file mode 100644 index 780e9414fec7c..0000000000000 --- a/administrator/components/com_menus/helpers/associations.php +++ /dev/null @@ -1,165 +0,0 @@ -getType($typeName); - - $context = $this->extension . '.item'; - - // Get the associations. - $associations = JLanguageAssociations::getAssociations( - $this->extension, - $type['tables']['a'], - $context, - $id, - 'id', - 'alias', - '' - ); - - return $associations; - } - - /** - * Get item information - * - * @param string $typeName The item type - * @param int $id The id of item for which we need the associated items - * - * @return JTable|null - * - * @since 3.7.0 - */ - public function getItem($typeName, $id) - { - if (empty($id)) - { - return null; - } - - $table = null; - - switch ($typeName) - { - case 'item': - $table = JTable::getInstance('menu'); - break; - } - - if (is_null($table)) - { - return null; - } - - $table->load($id); - - return $table; - } - - /** - * Get information about the type - * - * @param string $typeName The item type - * - * @return array Array of item types - * - * @since 3.7.0 - */ - public function getType($typeName = '') - { - $fields = $this->getFieldsTemplate(); - $tables = array(); - $joins = array(); - $support = $this->getSupportTemplate(); - $title = ''; - - if (in_array($typeName, $this->itemTypes)) - { - switch ($typeName) - { - case 'item': - $fields['ordering'] = 'a.lft'; - $fields['level'] = 'a.level'; - $fields['catid'] = ''; - $fields['state'] = 'a.published'; - $fields['created_user_id'] = ''; - $fields['menutype'] = 'a.menutype'; - - $support['state'] = true; - $support['acl'] = true; - $support['checkout'] = true; - $support['level'] = true; - - $tables = array( - 'a' => '#__menu' - ); - - $title = 'menu'; - break; - } - } - - return array( - 'fields' => $fields, - 'support' => $support, - 'tables' => $tables, - 'joins' => $joins, - 'title' => $title - ); - } -} diff --git a/administrator/components/com_menus/helpers/html/menus.php b/administrator/components/com_menus/helpers/html/menus.php deleted file mode 100644 index a6bc2160a18f4..0000000000000 --- a/administrator/components/com_menus/helpers/html/menus.php +++ /dev/null @@ -1,258 +0,0 @@ -getQuery(true) - ->select('m.id, m.title') - ->select('l.sef as lang_sef, l.lang_code') - ->select('mt.title as menu_title') - ->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'); - $db->setQuery($query); - - try - { - $items = $db->loadObjectList('id'); - } - catch (runtimeException $e) - { - throw new Exception($e->getMessage(), 500); - } - - // Construct html - if ($items) - { - foreach ($items as &$item) - { - $text = strtoupper($item->lang_sef); - $url = JRoute::_('index.php?option=com_menus&task=item.edit&id=' . (int) $item->id); - - $tooltip = htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8') . '
    ' . JText::sprintf('COM_MENUS_MENU_SPRINTF', $item->menu_title); - $classes = 'hasPopover label label-association label-' . $item->lang_sef; - - $item->link = '' - . $text . ''; - } - } - - JHtml::_('bootstrap.popover'); - - $html = JLayoutHelper::render('joomla.content.associations', $items); - } - - return $html; - } - - /** - * Returns a published state on a grid - * - * @param integer $value The state value. - * @param integer $i The row index - * @param boolean $enabled An optional setting for access control on the action. - * @param string $checkbox An optional prefix for checkboxes. - * - * @return string The Html code - * - * @see JHtmlJGrid::state - * - * @since 1.7.1 - */ - public static function state($value, $i, $enabled = true, $checkbox = 'cb') - { - $states = array( - 9 => array( - 'unpublish', - '', - 'COM_MENUS_HTML_UNPUBLISH_HEADING', - '', - true, - 'publish', - 'publish', - ), - 8 => array( - 'publish', - '', - 'COM_MENUS_HTML_PUBLISH_HEADING', - '', - true, - 'unpublish', - 'unpublish', - ), - 7 => array( - 'unpublish', - '', - 'COM_MENUS_HTML_UNPUBLISH_SEPARATOR', - '', - true, - 'publish', - 'publish', - ), - 6 => array( - 'publish', - '', - 'COM_MENUS_HTML_PUBLISH_SEPARATOR', - '', - true, - 'unpublish', - 'unpublish', - ), - 5 => array( - 'unpublish', - '', - 'COM_MENUS_HTML_UNPUBLISH_ALIAS', - '', - true, - 'publish', - 'publish', - ), - 4 => array( - 'publish', - '', - 'COM_MENUS_HTML_PUBLISH_ALIAS', - '', - true, - 'unpublish', - 'unpublish', - ), - 3 => array( - 'unpublish', - '', - 'COM_MENUS_HTML_UNPUBLISH_URL', - '', - true, - 'publish', - 'publish', - ), - 2 => array( - 'publish', - '', - 'COM_MENUS_HTML_PUBLISH_URL', - '', - true, - 'unpublish', - 'unpublish', - ), - 1 => array( - 'unpublish', - 'COM_MENUS_EXTENSION_PUBLISHED_ENABLED', - 'COM_MENUS_HTML_UNPUBLISH_ENABLED', - 'COM_MENUS_EXTENSION_PUBLISHED_ENABLED', - true, - 'publish', - 'publish', - ), - 0 => array( - 'publish', - 'COM_MENUS_EXTENSION_UNPUBLISHED_ENABLED', - 'COM_MENUS_HTML_PUBLISH_ENABLED', - 'COM_MENUS_EXTENSION_UNPUBLISHED_ENABLED', - true, - 'unpublish', - 'unpublish', - ), - -1 => array( - 'unpublish', - 'COM_MENUS_EXTENSION_PUBLISHED_DISABLED', - 'COM_MENUS_HTML_UNPUBLISH_DISABLED', - 'COM_MENUS_EXTENSION_PUBLISHED_DISABLED', - true, - 'warning', - 'warning', - ), - -2 => array( - 'publish', - 'COM_MENUS_EXTENSION_UNPUBLISHED_DISABLED', - 'COM_MENUS_HTML_PUBLISH_DISABLED', - 'COM_MENUS_EXTENSION_UNPUBLISHED_DISABLED', - true, - 'trash', - 'trash', - ), - -3 => array( - 'publish', - '', - 'COM_MENUS_HTML_PUBLISH', - '', - true, - 'trash', - 'trash', - ), - ); - - return JHtml::_('jgrid.state', $states, $value, $i, 'items.', $enabled, true, $checkbox); - } - - /** - * Returns a visibility state on a grid - * - * @param integer $params Params of item. - * - * @return string The Html code - * - * @since 3.7.0 - */ - public static function visibility($params) - { - $registry = new Registry; - - try - { - $registry->loadString($params); - } - catch (Exception $e) - { - // Invalid JSON - } - - $show_menu = $registry->get('menu_show'); - - return ($show_menu === 0) ? '' . JText::_('COM_MENUS_LABEL_HIDDEN') . '' : ''; - } -} diff --git a/administrator/components/com_menus/helpers/menus.php b/administrator/components/com_menus/helpers/menus.php index 5563fecc88bda..8cbadaab6704f 100644 --- a/administrator/components/com_menus/helpers/menus.php +++ b/administrator/components/com_menus/helpers/menus.php @@ -7,566 +7,14 @@ * @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; /** * Menus component helper. * - * @since 1.6 + * @since 1.6 + * @deprecated 5.0 Use \Joomla\Component\Menus\Administrator\Helper\MenusHelper instead */ -class MenusHelper +class MenusHelper extends \Joomla\Component\Menus\Administrator\Helper\MenusHelper { - /** - * Defines the valid request variables for the reverse lookup. - * - * @since 1.6 - */ - protected static $_filter = array('option', 'view', 'layout'); - - /** - * Configure the Linkbar. - * - * @param string $vName The name of the active view. - * - * @return void - * - * @since 1.6 - */ - public static function addSubmenu($vName) - { - JHtmlSidebar::addEntry( - JText::_('COM_MENUS_SUBMENU_MENUS'), - 'index.php?option=com_menus&view=menus', - $vName == 'menus' - ); - JHtmlSidebar::addEntry( - JText::_('COM_MENUS_SUBMENU_ITEMS'), - 'index.php?option=com_menus&view=items', - $vName == 'items' - ); - } - - /** - * Gets a list of the actions that can be performed. - * - * @param integer $parentId The menu ID. - * - * @return JObject - * - * @since 1.6 - * @deprecated 3.2 Use JHelperContent::getActions() instead - */ - public static function getActions($parentId = 0) - { - // Log usage of deprecated function - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Get list of actions - return JHelperContent::getActions('com_menus'); - } - - /** - * Gets a standard form of a link for lookups. - * - * @param mixed $request A link string or array of request variables. - * - * @return mixed A link in standard option-view-layout form, or false if the supplied response is invalid. - * - * @since 1.6 - */ - public static function getLinkKey($request) - { - if (empty($request)) - { - return false; - } - - // Check if the link is in the form of index.php?... - if (is_string($request)) - { - $args = array(); - - if (strpos($request, 'index.php') === 0) - { - parse_str(parse_url(htmlspecialchars_decode($request), PHP_URL_QUERY), $args); - } - else - { - parse_str($request, $args); - } - - $request = $args; - } - - // Only take the option, view and layout parts. - foreach ($request as $name => $value) - { - if ((!in_array($name, self::$_filter)) && (!($name == 'task' && !array_key_exists('view', $request)))) - { - // Remove the variables we want to ignore. - unset($request[$name]); - } - } - - ksort($request); - - return 'index.php?' . http_build_query($request, '', '&'); - } - - /** - * Get the menu list for create a menu module - * - * @param int $clientId Optional client id - viz 0 = site, 1 = administrator, can be NULL for all - * - * @return array The menu array list - * - * @since 1.6 - */ - public static function getMenuTypes($clientId = 0) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('a.menutype') - ->from('#__menu_types AS a'); - - if (isset($clientId)) - { - $query->where('a.client_id = ' . (int) $clientId); - } - - $db->setQuery($query); - - return $db->loadColumn(); - } - - /** - * Get a list of menu links for one or all menus. - * - * @param string $menuType An option menu to filter the list on, otherwise all menu with given client id links - * are returned as a grouped array. - * @param integer $parentId An optional parent ID to pivot results around. - * @param integer $mode An optional mode. If parent ID is set and mode=2, the parent and children are excluded from the list. - * @param array $published An optional array of states - * @param array $languages Optional array of specify which languages we want to filter - * @param int $clientId Optional client id - viz 0 = site, 1 = administrator, can be NULL for all (used only if menutype not givein) - * - * @return array - * - * @since 1.6 - */ - public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, $published = array(), $languages = array(), $clientId = 0) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('DISTINCT(a.id) AS value, - a.title AS text, - a.alias, - a.level, - a.menutype, - a.client_id, - a.type, - a.published, - a.template_style_id, - a.checked_out, - a.language, - a.lft' - ) - ->from('#__menu AS a'); - - $query->select('e.name as componentname, e.element') - ->join('left', '#__extensions e ON e.extension_id = a.component_id'); - - if (JLanguageMultilang::isEnabled()) - { - $query->select('l.title AS language_title, l.image AS language_image, l.sef AS language_sef') - ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); - } - - // Filter by the type if given, this is more specific than client id - if ($menuType) - { - $query->where('(a.menutype = ' . $db->quote($menuType) . ' OR a.parent_id = 0)'); - } - elseif (isset($clientId)) - { - $query->where('a.client_id = ' . (int) $clientId); - } - - // Prevent the parent and children from showing if requested. - if ($parentId && $mode == 2) - { - $query->join('LEFT', '#__menu AS p ON p.id = ' . (int) $parentId) - ->where('(a.lft <= p.lft OR a.rgt >= p.rgt)'); - } - - if (!empty($languages)) - { - if (is_array($languages)) - { - $languages = '(' . implode(',', array_map(array($db, 'quote'), $languages)) . ')'; - } - - $query->where('a.language IN ' . $languages); - } - - if (!empty($published)) - { - if (is_array($published)) - { - $published = '(' . implode(',', $published) . ')'; - } - - $query->where('a.published IN ' . $published); - } - - $query->where('a.published != -2'); - $query->order('a.lft ASC'); - - // Get the options. - $db->setQuery($query); - - try - { - $links = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - - return false; - } - - if (empty($menuType)) - { - // If the menutype is empty, group the items by menutype. - $query->clear() - ->select('*') - ->from('#__menu_types') - ->where('menutype <> ' . $db->quote('')) - ->order('title, menutype'); - - if (isset($clientId)) - { - $query->where('client_id = ' . (int) $clientId); - } - - $db->setQuery($query); - - try - { - $menuTypes = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - JError::raiseWarning(500, $e->getMessage()); - - return false; - } - - // Create a reverse lookup and aggregate the links. - $rlu = array(); - - foreach ($menuTypes as &$type) - { - $rlu[$type->menutype] = & $type; - $type->links = array(); - } - - // Loop through the list of menu links. - foreach ($links as &$link) - { - if (isset($rlu[$link->menutype])) - { - $rlu[$link->menutype]->links[] = & $link; - - // Cleanup garbage. - unset($link->menutype); - } - } - - return $menuTypes; - } - else - { - return $links; - } - } - - /** - * Get the associations - * - * @param integer $pk Menu item id - * - * @return array - * - * @since 3.0 - */ - public static function getAssociations($pk) - { - $langAssociations = JLanguageAssociations::getAssociations('com_menus', '#__menu', 'com_menus.item', $pk, 'id', '', ''); - $associations = array(); - - foreach ($langAssociations as $langAssociation) - { - $associations[$langAssociation->language] = $langAssociation->id; - } - - 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 - */ - 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 fd8fa2d2ff1ef..a00ec8599fc33 100644 --- a/administrator/components/com_menus/layouts/joomla/menu/edit_modules.php +++ b/administrator/components/com_menus/layouts/joomla/menu/edit_modules.php @@ -9,7 +9,10 @@ defined('JPATH_BASE') or die; -$app = JFactory::getApplication(); +use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Factory; + +$app = Factory::getApplication(); $form = $displayData->getForm(); $input = $app->input; $component = $input->getCmd('option', 'com_content'); @@ -21,7 +24,7 @@ $component = $parts[0]; } -$saveHistory = JComponentHelper::getParams($component)->get('save_history', 0); +$saveHistory = ComponentHelper::getParams($component)->get('save_history', 0); $fields = $displayData->get('fields') ?: array( array('parent', 'parent_id'), @@ -44,7 +47,7 @@ } $html = array(); -$html[] = '
      '; +$html[] = '
        '; foreach ($fields as $field) { diff --git a/administrator/components/com_menus/layouts/joomla/searchtools/default.php b/administrator/components/com_menus/layouts/joomla/searchtools/default.php index 422ce2100612f..a061662441a2e 100644 --- a/administrator/components/com_menus/layouts/joomla/searchtools/default.php +++ b/administrator/components/com_menus/layouts/joomla/searchtools/default.php @@ -9,35 +9,19 @@ defined('JPATH_BASE') or die; +use Joomla\CMS\Factory; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Layout\LayoutHelper; + /** @var array $displayData */ $data = $displayData; // Receive overridable options $data['options'] = !empty($data['options']) ? $data['options'] : array(); -if ($data['view'] instanceof MenusViewItems || $data['view'] instanceof MenusViewMenus) +if ($data['view'] instanceof \Joomla\Component\Menus\Administrator\View\Items\HtmlView + || $data['view'] instanceof \Joomla\Component\Menus\Administrator\View\Menus\HtmlView) { - $doc = JFactory::getDocument(); - - $doc->addStyleDeclaration(" - /* Fixed filter field in search bar */ - .js-stools .js-stools-menutype, - .js-stools .js-stools-client_id { - float: left; - margin-right: 10px; - min-width: 220px; - } - html[dir=rtl] .js-stools .js-stools-menutype, - html[dir=rtl] .js-stools .js-stools-client_id { - float: right; - margin-left: 10px - margin-right: 0; - } - .js-stools .js-stools-container-bar .js-stools-field-filter .chzn-container { - padding: 3px 0; - } - "); - // Client selector doesn't have to activate the filter bar. unset($data['view']->activeFilters['client_id']); @@ -47,12 +31,10 @@ // Set some basic options $customOptions = array( - 'filtersHidden' => isset($data['options']['filtersHidden']) ? $data['options']['filtersHidden'] : empty($data['view']->activeFilters), - 'defaultLimit' => isset($data['options']['defaultLimit']) ? $data['options']['defaultLimit'] : JFactory::getApplication()->get('list_limit', 20), + 'filtersHidden' => $data['options']['filtersHidden'] ?? empty($data['view']->activeFilters), + 'defaultLimit' => $data['options']['defaultLimit'] ?? Factory::getApplication()->get('list_limit', 20), 'searchFieldSelector' => '#filter_search', 'orderFieldSelector' => '#list_fullordering', - 'totalResults' => isset($data['options']['totalResults']) ? $data['options']['totalResults'] : -1, - 'noResultsText' => isset($data['options']['noResultsText']) ? $data['options']['noResultsText'] : JText::_('JGLOBAL_NO_MATCHING_RESULTS'), ); $data['options'] = array_merge($customOptions, $data['options']); @@ -60,24 +42,53 @@ $formSelector = !empty($data['options']['formSelector']) ? $data['options']['formSelector'] : '#adminForm'; // Load search tools -JHtml::_('searchtools.form', $formSelector, $data['options']); +HTMLHelper::_('searchtools.form', $formSelector, $data['options']); $filtersClass = isset($data['view']->activeFilters) && $data['view']->activeFilters ? ' js-stools-container-filters-visible' : ''; ?> -
        -
        -
        - -
        -
        - -
        +
      @@ -378,14 +348,13 @@ - +
    @@ -400,12 +369,11 @@ name="show_feed_link" type="radio" label="JGLOBAL_SHOW_FEED_LINK_LABEL" - description="JGLOBAL_SHOW_FEED_LINK_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" > - +
    diff --git a/administrator/components/com_tags/controller.php b/administrator/components/com_tags/controller.php deleted file mode 100644 index cdd19de665200..0000000000000 --- a/administrator/components/com_tags/controller.php +++ /dev/null @@ -1,50 +0,0 @@ -input->get('view', 'tags'); - $layout = $this->input->get('layout', 'default'); - $id = $this->input->getInt('id'); - - // Check for edit form. - if ($view == 'tag' && $layout == 'edit' && !$this->checkEditId('com_tags.edit.tag', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_tags&view=tags', false)); - - return false; - } - - parent::display(); - - return $this; - } -} diff --git a/administrator/components/com_tags/controllers/tag.php b/administrator/components/com_tags/controllers/tag.php deleted file mode 100644 index 7623d25bbc0d3..0000000000000 --- a/administrator/components/com_tags/controllers/tag.php +++ /dev/null @@ -1,72 +0,0 @@ -authorise('core.create', 'com_tags'); - } - - /** - * Method to check if you can edit a record. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. - * - * @return boolean - * - * @since 3.1 - */ - protected function allowEdit($data = array(), $key = 'id') - { - // Since there is no asset tracking and no categories, revert to the component permissions. - return parent::allowEdit($data, $key); - } - - /** - * Method to run batch operations. - * - * @param object $model The model. - * - * @return boolean True if successful, false otherwise and internal error is set. - * - * @since 3.1 - */ - public function batch($model = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Set the model - $model = $this->getModel('Tag'); - - // Preset the redirect - $this->setRedirect('index.php?option=com_tags&view=tags'); - - return parent::batch($model); - } -} diff --git a/administrator/components/com_tags/controllers/tags.php b/administrator/components/com_tags/controllers/tags.php deleted file mode 100644 index 21df3c04538fd..0000000000000 --- a/administrator/components/com_tags/controllers/tags.php +++ /dev/null @@ -1,65 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Rebuild the nested set tree. - * - * @return boolean False on failure or error, true on success. - * - * @since 3.1 - */ - public function rebuild() - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $this->setRedirect(JRoute::_('index.php?option=com_tags&view=tags', false)); - - $model = $this->getModel(); - - if ($model->rebuild()) - { - // Rebuild succeeded. - $this->setMessage(JText::_('COM_TAGS_REBUILD_SUCCESS')); - - return true; - } - else - { - // Rebuild failed. - $this->setMessage(JText::_('COM_TAGS_REBUILD_FAILURE')); - - return false; - } - } -} diff --git a/administrator/components/com_tags/forms/filter_tags.xml b/administrator/components/com_tags/forms/filter_tags.xml new file mode 100644 index 0000000000000..20946f5e62a0a --- /dev/null +++ b/administrator/components/com_tags/forms/filter_tags.xml @@ -0,0 +1,79 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/administrator/components/com_tags/models/forms/tag.xml b/administrator/components/com_tags/forms/tag.xml similarity index 80% rename from administrator/components/com_tags/models/forms/tag.xml rename to administrator/components/com_tags/forms/tag.xml index 1ad116852bbcc..b8bd76e9b756f 100644 --- a/administrator/components/com_tags/models/forms/tag.xml +++ b/administrator/components/com_tags/forms/tag.xml @@ -4,7 +4,6 @@ name="id" type="number" label="JGLOBAL_FIELD_ID_LABEL" - description="JGLOBAL_FIELD_ID_DESC" default="0" class="readonly" readonly="true" @@ -14,7 +13,6 @@ name="hits" type="number" label="JGLOBAL_HITS" - description="COM_TAGS_FIELD_HITS_DESC" class="readonly" default="0" readonly="true" @@ -24,7 +22,6 @@ name="parent_id" type="tag" label="COM_TAGS_FIELD_PARENT_LABEL" - description="COM_TAGS_FIELD_PARENT_DESC" mode="nested" validate="notequals" field="id" @@ -65,8 +62,7 @@ name="title" type="text" label="JGLOBAL_TITLE" - description="JFIELD_TITLE_DESC" - class="input-xxlarge input-large-text" + class="input-xxlarge" size="40" required="true" /> @@ -75,7 +71,6 @@ name="note" type="text" label="COM_TAGS_FIELD_NOTE_LABEL" - description="COM_TAGS_FIELD_NOTE_DESC" maxlength="255" class="span12" size="40" @@ -85,7 +80,6 @@ name="description" type="editor" label="JGLOBAL_DESCRIPTION" - description="COM_TAGS_DESCRIPTION_DESC" filter="JComponentHelper::filterText" buttons="true" hide="readmore,pagebreak" @@ -95,8 +89,7 @@ name="published" type="list" label="JSTATUS" - description="JFIELD_PUBLISHED_DESC" - class="chzn-color-state" + class="custom-select-color-state" default="1" size="1" > @@ -122,14 +115,12 @@ name="access" type="accesslevel" label="JFIELD_ACCESS_LABEL" - description="JFIELD_ACCESS_DESC" /> @@ -138,7 +129,6 @@ name="metakey" type="textarea" label="JFIELD_META_KEYWORDS_LABEL" - description="JFIELD_META_KEYWORDS_DESC" rows="3" cols="40" /> @@ -147,8 +137,6 @@ name="alias" type="text" label="JFIELD_ALIAS_LABEL" - description="JFIELD_ALIAS_DESC" - hint="JFIELD_ALIAS_PLACEHOLDER" size="40" /> @@ -156,14 +144,12 @@ name="created_user_id" type="user" label="JGLOBAL_FIELD_CREATED_BY_LABEL" - description="JGLOBAL_FIELD_CREATED_BY_DESC" /> @@ -172,7 +158,6 @@ name="created_time" type="calendar" label="JGLOBAL_CREATED_DATE" - description="COM_TAGS_FIELD_CREATED_DATE_DESC" class="readonly" translateformat="true" showtime="true" @@ -193,7 +178,6 @@ name="modified_time" type="calendar" label="JGLOBAL_FIELD_MODIFIED_LABEL" - description="COM_TAGS_FIELD_MODIFIED_DESC" class="readonly" translateformat="true" showtime="true" @@ -205,7 +189,6 @@ name="language" type="contentlanguage" label="JFIELD_LANGUAGE_LABEL" - description="COM_TAGS_FIELD_LANGUAGE_DESC" > @@ -214,9 +197,8 @@ name="version_note" type="text" label="JGLOBAL_FIELD_VERSION_NOTE_LABEL" - description="JGLOBAL_FIELD_VERSION_NOTE_DESC" maxlength="255" - class="span12" size="45" + size="45" labelclass="control-label" /> @@ -230,7 +212,7 @@ name="tag_layout" type="componentlayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_COMPONENT_LAYOUT_DESC" + class="custom-select" labelclass="control-label" useglobal="true" extension="com_tags" @@ -241,7 +223,6 @@ name="tag_link_class" type="text" label="COM_TAGS_FIELD_TAG_LINK_CLASS" - description="COM_TAGS_FIELD_TAG_LINK_CLASS_DESC" labelclass="control-label" size="20" default="label label-info" @@ -256,7 +237,6 @@ name="image_intro" type="media" label="COM_TAGS_FIELD_INTRO_LABEL" - description="COM_TAGS_FIELD_INTRO_DESC" labelclass="control-label" /> @@ -264,7 +244,6 @@ name="float_intro" type="list" label="COM_TAGS_FLOAT_LABEL" - description="COM_TAGS_FLOAT_DESC" labelclass="control-label" > @@ -277,7 +256,6 @@ name="image_intro_alt" type="text" label="COM_TAGS_FIELD_IMAGE_ALT_LABEL" - description="COM_TAGS_FIELD_IMAGE_ALT_DESC" labelclass="control-label" size="20" /> @@ -286,7 +264,6 @@ name="image_intro_caption" type="text" label="COM_TAGS_FIELD_IMAGE_CAPTION_LABEL" - description="COM_TAGS_FIELD_IMAGE_CAPTION_DESC" size="20" labelclass="control-label" /> @@ -301,7 +278,6 @@ name="image_fulltext" type="media" label="COM_TAGS_FIELD_FULL_LABEL" - description="COM_TAGS_FIELD_FULL_DESC" labelclass="control-label" /> @@ -309,7 +285,6 @@ name="float_fulltext" type="list" label="COM_TAGS_FLOAT_LABEL" - description="COM_TAGS_FLOAT_DESC" labelclass="control-label" > @@ -322,7 +297,6 @@ name="image_fulltext_alt" type="text" label="COM_TAGS_FIELD_IMAGE_ALT_LABEL" - description="COM_TAGS_FIELD_IMAGE_ALT_DESC" labelclass="control-label" size="20" /> @@ -331,7 +305,6 @@ name="image_fulltext_caption" type="text" label="COM_TAGS_FIELD_IMAGE_CAPTION_LABEL" - description="COM_TAGS_FIELD_IMAGE_CAPTION_DESC" labelclass="control-label" size="20" /> @@ -345,7 +318,6 @@ name="author" type="text" label="JAUTHOR" - description="JFIELD_METADATA_AUTHOR_DESC" size="30" /> @@ -353,7 +325,6 @@ name="robots" type="list" label="JFIELD_METADATA_ROBOTS_LABEL" - description="JFIELD_METADATA_ROBOTS_DESC" > diff --git a/administrator/components/com_tags/helpers/tags.php b/administrator/components/com_tags/helpers/tags.php deleted file mode 100644 index 3ad8d607de439..0000000000000 --- a/administrator/components/com_tags/helpers/tags.php +++ /dev/null @@ -1,63 +0,0 @@ -/language - $lang->load($component, JPATH_BASE, null, false, true) - || $lang->load($component, JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); - } - } - } - } -} diff --git a/administrator/components/com_tags/models/forms/filter_tags.xml b/administrator/components/com_tags/models/forms/filter_tags.xml deleted file mode 100644 index 63d08d839488a..0000000000000 --- a/administrator/components/com_tags/models/forms/filter_tags.xml +++ /dev/null @@ -1,94 +0,0 @@ - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    diff --git a/administrator/components/com_tags/models/tag.php b/administrator/components/com_tags/models/tag.php deleted file mode 100644 index e4d43b2fcb89c..0000000000000 --- a/administrator/components/com_tags/models/tag.php +++ /dev/null @@ -1,444 +0,0 @@ - 'batchAccess', - 'language_id' => 'batchLanguage', - ); - - /** - * Method to test whether a record can be deleted. - * - * @param object $record A record object. - * - * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. - * - * @since 3.1 - */ - protected function canDelete($record) - { - if (!empty($record->id)) - { - if ($record->published != -2) - { - return false; - } - - return parent::canDelete($record); - } - } - - /** - * 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); - } - - /** - * Method to get a table object, load it if necessary. - * - * @param string $type The table name. Optional. - * @param string $prefix The class prefix. Optional. - * @param array $config Configuration array for model. Optional. - * - * @return JTable A JTable object - * - * @since 3.1 - */ - public function getTable($type = 'Tag', $prefix = 'TagsTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Auto-populate the model state. - * - * @note Calling getState in this method will result in recursion. - * - * @return void - * - * @since 3.1 - */ - protected function populateState() - { - $app = JFactory::getApplication('administrator'); - - $parentId = $app->input->getInt('parent_id'); - $this->setState('tag.parent_id', $parentId); - - // Load the User state. - $pk = $app->input->getInt('id'); - $this->setState($this->getName() . '.id', $pk); - - // Load the parameters. - $params = JComponentHelper::getParams('com_tags'); - $this->setState('params', $params); - } - - /** - * Method to get a tag. - * - * @param integer $pk An optional id of the object to get, otherwise the id from the model state is used. - * - * @return mixed Tag data object on success, false on failure. - * - * @since 3.1 - */ - public function getItem($pk = null) - { - if ($result = parent::getItem($pk)) - { - // Prime required properties. - if (empty($result->id)) - { - $result->parent_id = $this->getState('tag.parent_id'); - } - - // Convert the metadata field to an array. - $registry = new Registry($result->metadata); - $result->metadata = $registry->toArray(); - - // Convert the images field to an array. - $registry = new Registry($result->images); - $result->images = $registry->toArray(); - - // Convert the urls field to an array. - $registry = new Registry($result->urls); - $result->urls = $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; - } - } - - return $result; - } - - /** - * Method to get the row form. - * - * @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 mixed A JForm object on success, false on failure - * - * @since 3.1 - */ - public function getForm($data = array(), $loadData = true) - { - $jinput = JFactory::getApplication()->input; - - // Get the form. - $form = $this->loadForm('com_tags.tag', 'tag', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - $user = JFactory::getUser(); - - if (!$user->authorise('core.edit.state', 'com_tags' . $jinput->get('id'))) - { - // Disable fields for display. - $form->setFieldAttribute('ordering', 'disabled', 'true'); - $form->setFieldAttribute('published', 'disabled', 'true'); - - // Disable fields while saving. - // The controller has already verified this is a record you can edit. - $form->setFieldAttribute('ordering', 'filter', 'unset'); - $form->setFieldAttribute('published', 'filter', 'unset'); - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 3.1 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_tags.edit.tag.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - $this->preprocessData('com_tags.tag', $data); - - return $data; - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 3.1 - */ - public function save($data) - { - $dispatcher = JEventDispatcher::getInstance(); - $table = $this->getTable(); - $input = JFactory::getApplication()->input; - $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState($this->getName() . '.id'); - $isNew = true; - $context = $this->option . '.' . $this->name; - - // Include the plugins for the save events. - JPluginHelper::importPlugin($this->events_map['save']); - - // Load the row if saving an existing tag. - if ($pk > 0) - { - $table->load($pk); - $isNew = false; - } - - // Set the new parent id if parent id not matched OR while New/Save as Copy . - if ($table->parent_id != $data['parent_id'] || $data['id'] == 0) - { - $table->setLocation($data['parent_id'], 'last-child'); - } - - if (isset($data['images']) && is_array($data['images'])) - { - $registry = new Registry($data['images']); - $data['images'] = (string) $registry; - } - - if (isset($data['urls']) && is_array($data['urls'])) - { - $registry = new Registry($data['urls']); - $data['urls'] = (string) $registry; - } - - // 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; - } - - // Bind the data. - if (!$table->bind($data)) - { - $this->setError($table->getError()); - - return false; - } - - // Bind the rules. - if (isset($data['rules'])) - { - $rules = new JAccessRules($data['rules']); - $table->setRules($rules); - } - - // Check the data. - if (!$table->check()) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the before save event. - $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, $isNew)); - - if (in_array(false, $result, true)) - { - $this->setError($table->getError()); - - return false; - } - - // Store the data. - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the after save event. - $dispatcher->trigger($this->event_after_save, array($context, &$table, $isNew)); - - // Rebuild the path for the tag: - if (!$table->rebuildPath($table->id)) - { - $this->setError($table->getError()); - - return false; - } - - // Rebuild the paths of the tag's children: - if (!$table->rebuild($table->id, $table->lft, $table->level, $table->path)) - { - $this->setError($table->getError()); - - return false; - } - - $this->setState($this->getName() . '.id', $table->id); - - // Clear the cache - $this->cleanCache(); - - return true; - } - - /** - * Method rebuild the entire nested set tree. - * - * @return boolean False on failure or error, true otherwise. - * - * @since 3.1 - */ - public function rebuild() - { - // Get an instance of the table object. - $table = $this->getTable(); - - if (!$table->rebuild()) - { - $this->setError($table->getError()); - - return false; - } - - // Clear the cache - $this->cleanCache(); - - return true; - } - - /** - * Method to save the reordered nested set tree. - * 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 - * - * @return boolean False on failure or error, True otherwise - * - * @since 3.1 - */ - public function saveorder($idArray = null, $lft_array = null) - { - // Get an instance of the table object. - $table = $this->getTable(); - - if (!$table->saveorder($idArray, $lft_array)) - { - $this->setError($table->getError()); - - return false; - } - - // Clear the cache - $this->cleanCache(); - - return true; - } - - /** - * 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. - * - * @return array Contains the modified title and alias. - * - * @since 3.1 - */ - protected function generateNewTitle($parent_id, $alias, $title) - { - // Alter the title & alias - $table = $this->getTable(); - - while ($table->load(array('alias' => $alias, 'parent_id' => $parent_id))) - { - $title = ($table->title != $title) ? $title : StringHelper::increment($title); - $alias = StringHelper::increment($alias, 'dash'); - } - - return array($title, $alias); - } -} diff --git a/administrator/components/com_tags/models/tags.php b/administrator/components/com_tags/models/tags.php deleted file mode 100644 index 38472621d4b11..0000000000000 --- a/administrator/components/com_tags/models/tags.php +++ /dev/null @@ -1,385 +0,0 @@ -getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); - $this->setState('filter.search', $search); - - $level = $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', ''); - $this->setState('filter.level', $level); - - $access = $this->getUserStateFromRequest($this->context . '.filter.access', 'filter_access', ''); - $this->setState('filter.access', $access); - - $published = $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', ''); - $this->setState('filter.published', $published); - - $language = $this->getUserStateFromRequest($this->context . '.filter.language', 'filter_language', ''); - $this->setState('filter.language', $language); - - $extension = $this->getUserStateFromRequest($this->context . '.filter.extension', 'extension', 'com_content', 'cmd'); - - $this->setState('filter.extension', $extension); - $parts = explode('.', $extension); - - // Extract the component name - $this->setState('filter.component', $parts[0]); - - // Extract the optional section name - $this->setState('filter.section', (count($parts) > 1) ? $parts[1] : null); - - // Load the parameters. - $params = JComponentHelper::getParams('com_tags'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - * - * @since 3.1 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.extension'); - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.level'); - $id .= ':' . $this->getState('filter.access'); - $id .= ':' . $this->getState('filter.published'); - $id .= ':' . $this->getState('filter.language'); - - return parent::getStoreId($id); - } - - /** - * Method to create a query for a list of items. - * - * @return string - * - * @since 3.1 - */ - protected function getListQuery() - { - // Create a new query object. - $db = $this->getDbo(); - $query = $db->getQuery(true); - $user = JFactory::getUser(); - - // Select the required fields from the table. - $query->select( - $this->getState( - 'list.select', - 'a.id, a.title, a.alias, a.note, a.published, a.access' . - ', a.checked_out, a.checked_out_time, a.created_user_id' . - ', a.path, a.parent_id, a.level, a.lft, a.rgt' . - ', a.language' - ) - ); - $query->from('#__tags AS a') - ->where('a.alias <> ' . $db->quote('root')); - - // Join over the language - $query->select('l.title AS language_title, l.image AS language_image') - ->join('LEFT', $db->quoteName('#__languages') . ' AS l ON l.lang_code = a.language'); - - // Join over the users for the checked out user. - $query->select('uc.name AS editor') - ->join('LEFT', '#__users AS uc ON uc.id=a.checked_out'); - - // Join over the users for the author. - $query->select('ua.name AS author_name') - ->join('LEFT', '#__users AS ua ON ua.id = a.created_user_id') - - ->select('ug.title AS access_title') - ->join('LEFT', '#__viewlevels AS ug on ug.id = a.access'); - - // Filter on the level. - if ($level = $this->getState('filter.level')) - { - $query->where('a.level <= ' . (int) $level); - } - - // Filter by access level. - if ($access = $this->getState('filter.access')) - { - $query->where('a.access = ' . (int) $access); - } - - // Implement View Level Access - if (!$user->authorise('core.admin')) - { - $groups = implode(',', $user->getAuthorisedViewLevels()); - $query->where('a.access IN (' . $groups . ')'); - } - - // Filter by published state - $published = $this->getState('filter.published'); - - if (is_numeric($published)) - { - $query->where('a.published = ' . (int) $published); - } - elseif ($published === '') - { - $query->where('(a.published IN (0, 1))'); - } - - // Filter by search in title - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('(a.title LIKE ' . $search . ' OR a.alias LIKE ' . $search . ' OR a.note LIKE ' . $search . ')'); - } - } - - // Filter on the language. - if ($language = $this->getState('filter.language')) - { - $query->where('a.language = ' . $db->quote($language)); - } - - // Add the list ordering clause - $listOrdering = $this->getState('list.ordering', 'a.lft'); - $listDirn = $db->escape($this->getState('list.direction', 'ASC')); - - if ($listOrdering == 'a.access') - { - $query->order('a.access ' . $listDirn . ', a.lft ' . $listDirn); - } - else - { - $query->order($db->escape($listOrdering) . ' ' . $listDirn); - } - - return $query; - } - - /** - * Method override to check-in a record or an array of record - * - * @param mixed $pks The ID of the primary key or an array of IDs - * - * @return mixed Boolean false if there is an error, otherwise the count of records checked in. - * - * @since 12.2 - */ - public function checkin($pks = array()) - { - $pks = (array) $pks; - $table = $this->getTable(); - $count = 0; - - if (empty($pks)) - { - $pks = array((int) $this->getState($this->getName() . '.id')); - } - - // Check in all items. - foreach ($pks as $pk) - { - if ($table->load($pk)) - { - if ($table->checked_out > 0) - { - // Only attempt to check the row in if it exists. - if ($pk) - { - $user = JFactory::getUser(); - - // Get an instance of the row to checkin. - $table = $this->getTable(); - - if (!$table->load($pk)) - { - $this->setError($table->getError()); - - return false; - } - - // Check if this is the user having previously checked out the row. - if ($table->checked_out > 0 && $table->checked_out != $user->get('id') && !$user->authorise('core.admin', 'com_checkin')) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_CHECKIN_USER_MISMATCH')); - - return false; - } - - // Attempt to check the row in. - if (!$table->checkin($pk)) - { - $this->setError($table->getError()); - - return false; - } - } - - $count++; - } - } - else - { - $this->setError($table->getError()); - - return false; - } - } - - return $count; - } - - /** - * Method to get a table object, load it if necessary. - * - * @param string $type The table name. Optional. - * @param string $prefix The class prefix. Optional. - * @param array $config Configuration array for model. Optional. - * - * @return JTable A JTable object - * - * @since 3.1 - */ - public function getTable($type = 'Tag', $prefix = 'TagsTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Method to get an array of data items. - * - * @return mixed An array of data items on success, false on failure. - * - * @since 12.2 - */ - public function getItems() - { - $items = parent::getItems(); - - if ($items != false) - { - $extension = $this->getState('filter.extension'); - - $this->countItems($items, $extension); - } - - return $items; - } - - /** - * Method to load the countItems method from the extensions - * - * @param stdClass[] &$items The category items - * @param string $extension The category extension - * - * @return void - * - * @since 3.5 - */ - public function countItems(&$items, $extension) - { - $parts = explode('.', $extension); - $component = $parts[0]; - $section = null; - - if (count($parts) < 2) - { - return; - } - - // Try to find the component helper. - $eName = str_replace('com_', '', $component); - $file = JPath::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, 'countTagItems'))) - { - $cName::countTagItems($items, $extension); - } - } - } -} diff --git a/administrator/components/com_tags/services/provider.php b/administrator/components/com_tags/services/provider.php new file mode 100644 index 0000000000000..3b695086d673b --- /dev/null +++ b/administrator/components/com_tags/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Tags')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Tags')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_tags/tables/tag.php b/administrator/components/com_tags/tables/tag.php deleted file mode 100644 index c1ae9af06f049..0000000000000 --- a/administrator/components/com_tags/tables/tag.php +++ /dev/null @@ -1,277 +0,0 @@ - 'com_tags.tag')); - } - - /** - * Overloaded bind function - * - * @param array $array Named array - * @param mixed $ignore An optional array or space separated list of properties - * to ignore while binding. - * - * @return mixed Null if operation was satisfactory, otherwise returns an error string - * - * @see JTable::bind - * @since 3.1 - */ - public function bind($array, $ignore = '') - { - if (isset($array['params']) && is_array($array['params'])) - { - $registry = new Registry($array['params']); - $array['params'] = (string) $registry; - } - - if (isset($array['metadata']) && is_array($array['metadata'])) - { - $registry = new Registry($array['metadata']); - $array['metadata'] = (string) $registry; - } - - if (isset($array['urls']) && is_array($array['urls'])) - { - $registry = new Registry($array['urls']); - $array['urls'] = (string) $registry; - } - - if (isset($array['images']) && is_array($array['images'])) - { - $registry = new Registry($array['images']); - $array['images'] = (string) $registry; - } - - return parent::bind($array, $ignore); - } - - /** - * Overloaded check method to ensure data integrity. - * - * @return boolean True on success. - * - * @since 3.1 - * @throws UnexpectedValueException - */ - public function check() - { - // Check for valid name. - if (trim($this->title) == '') - { - throw new UnexpectedValueException(sprintf('The title is empty')); - } - - if (empty($this->alias)) - { - $this->alias = $this->title; - } - - $this->alias = JApplicationHelper::stringURLSafe($this->alias, $this->language); - - if (trim(str_replace('-', '', $this->alias)) == '') - { - $this->alias = JFactory::getDate()->format('Y-m-d-H-i-s'); - } - - // Check the publish down date is not earlier than publish up. - if ((int) $this->publish_down > 0 && $this->publish_down < $this->publish_up) - { - throw new UnexpectedValueException(sprintf('End publish date is before start publish date.')); - } - - // Clean up keywords -- eliminate extra spaces between phrases - // and cr (\r) and lf (\n) characters from string - if (!empty($this->metakey)) - { - // Only process if not empty - // Define array of characters to remove - $bad_characters = array("\n", "\r", "\"", '<', '>'); - - // Remove bad characters - $after_clean = StringHelper::str_ireplace($bad_characters, '', $this->metakey); - - // Create array using commas as delimiter - $keys = explode(',', $after_clean); - $clean_keys = array(); - - foreach ($keys as $key) - { - if (trim($key)) - { - // Ignore blank keywords - $clean_keys[] = trim($key); - } - } - - // Put array back together delimited by ", " - $this->metakey = implode(', ', $clean_keys); - } - - // Clean up description -- eliminate quotes and <> brackets - if (!empty($this->metadesc)) - { - // Only process if not empty - $bad_characters = array("\"", '<', '>'); - $this->metadesc = StringHelper::str_ireplace($bad_characters, '', $this->metadesc); - } - - // Not Null sanity check - $date = JFactory::getDate(); - - if (empty($this->params)) - { - $this->params = '{}'; - } - - if (empty($this->metadesc)) - { - $this->metadesc = ''; - } - - if (empty($this->metakey)) - { - $this->metakey = ''; - } - - if (empty($this->metadata)) - { - $this->metadata = '{}'; - } - - if (empty($this->urls)) - { - $this->urls = '{}'; - } - - if (empty($this->images)) - { - $this->images = '{}'; - } - - if (!(int) $this->checked_out_time) - { - $this->checked_out_time = $date->toSql(); - } - - if (!(int) $this->modified_time) - { - $this->modified_time = $date->toSql(); - } - - if (!(int) $this->modified_time) - { - $this->modified_time = $date->toSql(); - } - - if (!(int) $this->publish_up) - { - $this->publish_up = $date->toSql(); - } - - if (!(int) $this->publish_down) - { - $this->publish_down = $date->toSql(); - } - - return true; - } - - /** - * Overriden JTable::store to set modified data and user id. - * - * @param boolean $updateNulls True to update fields even if they are null. - * - * @return boolean True on success. - * - * @since 3.1 - */ - public function store($updateNulls = false) - { - $date = JFactory::getDate(); - $user = JFactory::getUser(); - - $this->modified_time = $date->toSql(); - - if ($this->id) - { - // Existing item - $this->modified_user_id = $user->get('id'); - } - else - { - // New tag. A tag created and created_by field can be set by the user, - // so we don't touch either of these if they are set. - if (!(int) $this->created_time) - { - $this->created_time = $date->toSql(); - } - - if (empty($this->created_user_id)) - { - $this->created_user_id = $user->get('id'); - } - } - - // Verify that the alias is unique - $table = JTable::getInstance('Tag', 'TagsTable', array('dbo' => $this->_db)); - - if ($table->load(array('alias' => $this->alias)) && ($table->id != $this->id || $this->id == 0)) - { - $this->setError(JText::_('COM_TAGS_ERROR_UNIQUE_ALIAS')); - - return false; - } - - return parent::store($updateNulls); - } - - /** - * Method to delete a node and, optionally, its child nodes from the table. - * - * @param integer $pk The primary key of the node to delete. - * @param boolean $children True to delete child nodes, false to move them up a level. - * - * @return boolean True on success. - * - * @since 3.1 - */ - public function delete($pk = null, $children = false) - { - $return = parent::delete($pk, $children); - - if ($return) - { - $helper = new JHelperTags; - $helper->tagDeleteInstances($pk); - } - - return $return; - } -} diff --git a/administrator/components/com_tags/tags.php b/administrator/components/com_tags/tags.php deleted file mode 100644 index 76d7890bd5b68..0000000000000 --- a/administrator/components/com_tags/tags.php +++ /dev/null @@ -1,20 +0,0 @@ -authorise('core.manage', 'com_tags')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -$controller = JControllerLegacy::getInstance('Tags'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_tags/tags.xml b/administrator/components/com_tags/tags.xml index 2ceb149ae4730..0843325155128 100644 --- a/administrator/components/com_tags/tags.xml +++ b/administrator/components/com_tags/tags.xml @@ -9,6 +9,7 @@ www.joomla.org 3.1.0 COM_TAGS_XML_DESCRIPTION + Joomla\Component\Tags controller.php @@ -36,7 +37,7 @@ language/en-GB.com_tags.ini language/en-GB.com_tags.sys.ini - com_tags + com_tags diff --git a/administrator/components/com_tags/tmpl/tag/edit.php b/administrator/components/com_tags/tmpl/tag/edit.php new file mode 100644 index 0000000000000..00a11bf6b5e73 --- /dev/null +++ b/administrator/components/com_tags/tmpl/tag/edit.php @@ -0,0 +1,68 @@ +ignore_fieldsets = array('jmetadata'); +$this->useCoreUI = true; + +?> + +
    + + + +
    + 'details')); ?> + + +
    +
    +
    + form->renderField('description'); ?> +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + +
    +
    + +
    +
    + +
    +
    + + + +
    + + +
    diff --git a/administrator/components/com_tags/views/tag/tmpl/edit_metadata.php b/administrator/components/com_tags/tmpl/tag/edit_metadata.php similarity index 100% rename from administrator/components/com_tags/views/tag/tmpl/edit_metadata.php rename to administrator/components/com_tags/tmpl/tag/edit_metadata.php diff --git a/administrator/components/com_tags/tmpl/tag/edit_options.php b/administrator/components/com_tags/tmpl/tag/edit_options.php new file mode 100644 index 0000000000000..34751313aebae --- /dev/null +++ b/administrator/components/com_tags/tmpl/tag/edit_options.php @@ -0,0 +1,67 @@ + + 'collapse0')); + $fieldSets = $this->form->getFieldsets('params'); + $i = 0; + + foreach ($fieldSets as $name => $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_TAGS_' . $name . '_FIELDSET_LABEL'; + echo HTMLHelper::_('bootstrap.addSlide', 'categoryOptions', Text::_($label), 'collapse' . ($i++)); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

    ' . $this->escape(Text::_($fieldSet->description)) . '

    '; + endif; + ?> + form->getFieldset($name) as $field) : ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + + + +
    +
    + form->getLabel('note'); ?> +
    +
    + form->getInput('note'); ?> +
    +
    +
    +
    + form->getLabel('tag_layout'); ?> +
    +
    + form->getInput('tag_layout'); ?> +
    +
    +
    +
    + form->getLabel('tag_link_class'); ?> +
    +
    + form->getInput('tag_link_class'); ?> +
    +
    + get('id'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); +$extension = $this->escape($this->state->get('filter.extension')); +$parts = explode('.', $extension); +$component = $parts[0]; +$section = null; +$mode = false; + +if (count($parts) > 1) +{ + $section = $parts[1]; + $inflector = Inflector::getInstance(); + + if (!$inflector->isPlural($section)) + { + $section = $inflector->toPlural($section); + } +} + +if ($section === 'categories') +{ + $mode = true; + $section = $component; + $component = 'com_categories'; +} + +if ($saveOrder && !empty($this->items)) +{ + $saveOrderingUrl = 'index.php?option=com_tags&task=tags.saveOrderAjax&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} +?> +
    +
    + $this)); + ?> + items)) : ?> + + + + + + + + + + + items[0]) && property_exists($this->items[0], 'count_published')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_archived')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> + + + + + + + + + + + class="js-draggable" data-url="" data-direction="" data-nested="true"> + items as $i => $item) : + $orderkey = array_search($item->id, $this->ordering[$item->parent_id]); + $canCreate = $user->authorise('core.create', 'com_tags'); + $canEdit = $user->authorise('core.edit', 'com_tags'); + $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_tags') && $canCheckin; + + // Get the parents of item for sorting + if ($item->level > 1) + { + $parentsStr = ''; + $_currentParentId = $item->parent_id; + $parentsStr = ' ' . $_currentParentId; + for ($j = 0; $j < $item->level; $j++) + { + foreach ($this->ordering as $k => $v) + { + $v = implode('-', $v); + $v = '-' . $v . '-'; + if (strpos($v, '-' . $_currentParentId . '-') !== false) + { + $parentsStr .= ' ' . $k; + $_currentParentId = $k; + break; + } + } + } + } + else + { + $parentsStr = ''; + } + ?> + + + + + + + items[0]) && property_exists($this->items[0], 'count_published')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_archived')) : ?> + + + items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + state->get('list.direction'), $this->state->get('list.ordering')); ?> + + +
    + + + + + + + + + id); ?> + +
    + published, $i, 'tags.', $canChange); ?> +
    +
    + $item->level)); ?> + checked_out) : ?> + editor, $item->checked_out_time, 'tags.', $canCheckin); ?> + + + checked_out ? '' : ''; ?> + + escape($item->title); ?> + + escape($item->title); ?> + + + note)) : ?> + escape($item->alias)); ?> + + escape($item->alias), $this->escape($item->note)); ?> + + + + + count_published; ?> + + + count_unpublished; ?> + + + count_archived; ?> + + + count_trashed; ?> + + escape($item->access_title); ?> + + + + id; ?> +
    + + + pagination->getListFooter(); ?> + + + authorise('core.create', 'com_tags') + && $user->authorise('core.edit', 'com_tags') + && $user->authorise('core.edit.state', 'com_tags')) : ?> + Text::_('COM_TAGS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + +
    +
    diff --git a/administrator/components/com_tags/tmpl/tags/default_batch_body.php b/administrator/components/com_tags/tmpl/tags/default_batch_body.php new file mode 100644 index 0000000000000..51ef5862af0d0 --- /dev/null +++ b/administrator/components/com_tags/tmpl/tags/default_batch_body.php @@ -0,0 +1,29 @@ +state->get('filter.published'); +?> + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/administrator/components/com_tags/tmpl/tags/default_batch_footer.php b/administrator/components/com_tags/tmpl/tags/default_batch_footer.php new file mode 100644 index 0000000000000..8952a5005a713 --- /dev/null +++ b/administrator/components/com_tags/tmpl/tags/default_batch_footer.php @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/administrator/components/com_tags/views/tag/tmpl/edit.php b/administrator/components/com_tags/views/tag/tmpl/edit.php deleted file mode 100644 index d7b7d835b002f..0000000000000 --- a/administrator/components/com_tags/views/tag/tmpl/edit.php +++ /dev/null @@ -1,67 +0,0 @@ -addScriptDeclaration(" - Joomla.submitbutton = function(task) - { - if (task == 'tag.cancel' || document.formvalidator.isValid(document.getElementById('item-form'))) { - " . $this->form->getField('description')->save() . " - Joomla.submitform(task, document.getElementById('item-form')); - } - }; -"); - -// Fieldsets to not automatically render by /layouts/joomla/edit/params.php -$this->ignore_fieldsets = array('jmetadata'); -?> - -
    - - - -
    - 'details')); ?> - - -
    -
    -
    - form->renderField('description'); ?> -
    -
    -
    - -
    -
    - - - - - -
    -
    - -
    -
    - -
    -
    - - - -
    - - -
    diff --git a/administrator/components/com_tags/views/tag/tmpl/edit_options.php b/administrator/components/com_tags/views/tag/tmpl/edit_options.php deleted file mode 100644 index 1cefcdccb78a1..0000000000000 --- a/administrator/components/com_tags/views/tag/tmpl/edit_options.php +++ /dev/null @@ -1,63 +0,0 @@ - - 'collapse0')); - $fieldSets = $this->form->getFieldsets('params'); - $i = 0; - - foreach ($fieldSets as $name => $fieldSet) : - $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_TAGS_' . $name . '_FIELDSET_LABEL'; - echo JHtml::_('bootstrap.addSlide', 'categoryOptions', JText::_($label), 'collapse' . ($i++)); - if (isset($fieldSet->description) && trim($fieldSet->description)) : - echo '

    ' . $this->escape(JText::_($fieldSet->description)) . '

    '; - endif; - ?> - form->getFieldset($name) as $field) : ?> -
    -
    - label; ?> -
    -
    - input; ?> -
    -
    - - - -
    -
    - form->getLabel('note'); ?> -
    -
    - form->getInput('note'); ?> -
    -
    -
    -
    - form->getLabel('tag_layout'); ?> -
    -
    - form->getInput('tag_layout'); ?> -
    -
    -
    -
    - form->getLabel('tag_link_class'); ?> -
    -
    - form->getInput('tag_link_class'); ?> -
    -
    - form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - $this->canDo = JHelperContent::getActions('com_tags'); - $this->assoc = $this->get('Assoc'); - - $input = JFactory::getApplication()->input; - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $input->set('hidemainmenu', true); - $this->addToolbar(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @since 3.1 - * - * @return void - */ - protected function addToolbar() - { - $user = JFactory::getUser(); - $userId = $user->get('id'); - $isNew = ($this->item->id == 0); - $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $userId); - - // Need to load the menu language file as mod_menu hasn't been loaded yet. - $lang = JFactory::getLanguage(); - $lang->load('com_tags', JPATH_BASE, null, false, true) - || $lang->load('com_tags', JPATH_ADMINISTRATOR . '/components/com_tags', null, false, true); - - // Get the results for each action. - $canDo = $this->canDo; - $title = JText::_('COM_TAGS_BASE_' . ($isNew ? 'ADD' : 'EDIT') . '_TITLE'); - - /** - * Prepare the toolbar. - * If it is new we get: `tag tag-add add` - * else we get `tag tag-edit edit` - */ - JToolbarHelper::title($title, 'tag tag-' . ($isNew ? 'add add' : 'edit edit')); - - // For new records, check the create permission. - if ($isNew) - { - JToolbarHelper::apply('tag.apply'); - JToolbarHelper::save('tag.save'); - JToolbarHelper::save2new('tag.save2new'); - JToolbarHelper::cancel('tag.cancel'); - } - - // If not checked out, can save the item. - else - { - // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. - $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_user_id == $userId); - - // Can't save the record if it's checked out and editable - if (!$checkedOut && $itemEditable) - { - JToolbarHelper::apply('tag.apply'); - JToolbarHelper::save('tag.save'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::save2new('tag.save2new'); - } - } - - // If an existing item, can save to a copy. - if ($canDo->get('core.create')) - { - JToolbarHelper::save2copy('tag.save2copy'); - } - - if (JComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $itemEditable) - { - JToolbarHelper::versions('com_tags.tag', $this->item->id); - } - - JToolbarHelper::cancel('tag.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_COMPONENTS_TAGS_MANAGER_EDIT'); - JToolbarHelper::divider(); - } -} diff --git a/administrator/components/com_tags/views/tags/tmpl/default.php b/administrator/components/com_tags/views/tags/tmpl/default.php deleted file mode 100644 index 36e04661a1182..0000000000000 --- a/administrator/components/com_tags/views/tags/tmpl/default.php +++ /dev/null @@ -1,287 +0,0 @@ -get('id'); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$saveOrder = ($listOrder == 'a.lft' && strtolower($listDirn) == 'asc'); -$extension = $this->escape($this->state->get('filter.extension')); -$parts = explode('.', $extension); -$component = $parts[0]; -$section = null; -$mode = false; -$columns = 7; - -if (count($parts) > 1) -{ - $section = $parts[1]; - $inflector = Inflector::getInstance(); - - if (!$inflector->isPlural($section)) - { - $section = $inflector->toPlural($section); - } -} - -if ($section === 'categories') -{ - $mode = true; - $section = $component; - $component = 'com_categories'; -} - -if ($saveOrder) -{ - $saveOrderingUrl = 'index.php?option=com_tags&task=tags.saveOrderAjax'; - JHtml::_('sortablelist.sortable', 'categoryList', 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true); -} -?> -
    -sidebar)) : ?> -
    - sidebar; ?> -
    -
    - -
    - - $this)); - ?> - items)) : ?> -
    - -
    - - - - - - - - - - items[0]) && property_exists($this->items[0], 'count_published')) : ?> - - - - items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> - - - - items[0]) && property_exists($this->items[0], 'count_archived')) : ?> - - - - items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> - - - - - - - - - - - - - - - - items as $i => $item) : - $orderkey = array_search($item->id, $this->ordering[$item->parent_id]); - $canCreate = $user->authorise('core.create', 'com_tags'); - $canEdit = $user->authorise('core.edit', 'com_tags'); - $canCheckin = $user->authorise('core.manage', 'com_checkin') || $item->checked_out == $user->get('id')|| $item->checked_out == 0; - $canChange = $user->authorise('core.edit.state', 'com_tags') && $canCheckin; - - // Get the parents of item for sorting - if ($item->level > 1) - { - $parentsStr = ''; - $_currentParentId = $item->parent_id; - $parentsStr = ' ' . $_currentParentId; - for ($j = 0; $j < $item->level; $j++) - { - foreach ($this->ordering as $k => $v) - { - $v = implode('-', $v); - $v = '-' . $v . '-'; - if (strpos($v, '-' . $_currentParentId . '-') !== false) - { - $parentsStr .= ' ' . $k; - $_currentParentId = $k; - break; - } - } - } - } - else - { - $parentsStr = ''; - } - ?> - - - - - - - items[0]) && property_exists($this->items[0], 'count_published')) : ?> - - - items[0]) && property_exists($this->items[0], 'count_unpublished')) : ?> - - - items[0]) && property_exists($this->items[0], 'count_archived')) : ?> - - - items[0]) && property_exists($this->items[0], 'count_trashed')) : ?> - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - state->get('list.direction'), $this->state->get('list.ordering')); ?> - - -
    - pagination->getListFooter(); ?> -
    - - - - - - - - - id); ?> - -
    - published, $i, 'tags.', $canChange); ?> - published === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'tags'); - JHtml::_('actionsdropdown.' . ((int) $item->published === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'tags'); - echo JHtml::_('actionsdropdown.render', $this->escape($item->title)); - } - ?> -
    -
    - $item->level)); ?> - checked_out) : ?> - editor, $item->checked_out_time, 'tags.', $canCheckin); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - - note)) : ?> - escape($item->alias)); ?> - - escape($item->alias), $this->escape($item->note)); ?> - - - - - count_published; ?> - - - count_unpublished; ?> - - - count_archived; ?> - - - count_trashed; ?> - - escape($item->access_title); ?> - - - - - id; ?> -
    - - authorise('core.create', 'com_tags') - && $user->authorise('core.edit', 'com_tags') - && $user->authorise('core.edit.state', 'com_tags')) : ?> - JText::_('COM_TAGS_BATCH_OPTIONS'), - 'footer' => $this->loadTemplate('batch_footer'), - ), - $this->loadTemplate('batch_body') - ); ?> - - - - - - -
    - 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 deleted file mode 100644 index e01ab9653387c..0000000000000 --- a/administrator/components/com_tags/views/tags/tmpl/default_batch_body.php +++ /dev/null @@ -1,26 +0,0 @@ -state->get('filter.published'); -?> - -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    -
    -
    \ No newline at end of file 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 deleted file mode 100644 index 014201891eb65..0000000000000 --- a/administrator/components/com_tags/views/tags/tmpl/default_batch_footer.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ 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 deleted file mode 100644 index b2d0b39e1a97c..0000000000000 --- a/administrator/components/com_tags/views/tags/view.html.php +++ /dev/null @@ -1,165 +0,0 @@ -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); - } - - // Preprocess the list of items to find ordering divisions. - foreach ($this->items as &$item) - { - $this->ordering[$item->parent_id][] = $item->id; - } - - // Levels filter. - $options = array(); - $options[] = JHtml::_('select.option', '1', JText::_('J1')); - $options[] = JHtml::_('select.option', '2', JText::_('J2')); - $options[] = JHtml::_('select.option', '3', JText::_('J3')); - $options[] = JHtml::_('select.option', '4', JText::_('J4')); - $options[] = JHtml::_('select.option', '5', JText::_('J5')); - $options[] = JHtml::_('select.option', '6', JText::_('J6')); - $options[] = JHtml::_('select.option', '7', JText::_('J7')); - $options[] = JHtml::_('select.option', '8', JText::_('J8')); - $options[] = JHtml::_('select.option', '9', JText::_('J9')); - $options[] = JHtml::_('select.option', '10', JText::_('J10')); - - $this->f_levels = $options; - - // We don't need toolbar in the modal window. - if ($this->getLayout() !== 'modal') - { - $this->addToolbar(); - } - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 3.1 - */ - protected function addToolbar() - { - $state = $this->get('State'); - $canDo = JHelperContent::getActions('com_tags'); - $user = JFactory::getUser(); - - // Get the toolbar object instance - $bar = JToolbar::getInstance('toolbar'); - - JToolbarHelper::title(JText::_('COM_TAGS_MANAGER_TAGS'), 'tags'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('tag.add'); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('tag.edit'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::publish('tags.publish', 'JTOOLBAR_PUBLISH', true); - JToolbarHelper::unpublish('tags.unpublish', 'JTOOLBAR_UNPUBLISH', true); - JToolbarHelper::archiveList('tags.archive'); - } - - if ($canDo->get('core.admin')) - { - JToolbarHelper::checkin('tags.checkin'); - } - - // Add a batch button - if ($user->authorise('core.create', 'com_tags') - && $user->authorise('core.edit', 'com_tags') - && $user->authorise('core.edit.state', 'com_tags')) - { - $title = JText::_('JTOOLBAR_BATCH'); - - // Instantiate a new JLayoutFile instance and render the batch button - $layout = new JLayoutFile('joomla.toolbar.batch'); - - $dhtml = $layout->render(array('title' => $title)); - $bar->appendButton('Custom', $dhtml, 'batch'); - } - - if ($state->get('filter.published') == -2 && $canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'tags.delete', 'JTOOLBAR_EMPTY_TRASH'); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('tags.trash'); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_tags'); - } - - JToolbarHelper::help('JHELP_COMPONENTS_TAGS_MANAGER'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'a.lft' => JText::_('JGRID_HEADING_ORDERING'), - 'a.state' => JText::_('JSTATUS'), - 'a.title' => JText::_('JGLOBAL_TITLE'), - 'a.access' => JText::_('JGRID_HEADING_ACCESS'), - 'a.language' => JText::_('JGRID_HEADING_LANGUAGE'), - 'a.id' => JText::_('JGRID_HEADING_ID') - ); - } -} diff --git a/administrator/components/com_templates/Controller/DisplayController.php b/administrator/components/com_templates/Controller/DisplayController.php new file mode 100644 index 0000000000000..2a38aab192d85 --- /dev/null +++ b/administrator/components/com_templates/Controller/DisplayController.php @@ -0,0 +1,79 @@ +input->get('view', 'styles'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + $document = Factory::getDocument(); + + // For JSON requests + if ($document->getType() == 'json') + { + /*$view = new \Joomla\Component\Templates\Administrator\View\Style\Json; + + // Get/Create the model + $model = new Style; + $view->setModel($model, true); + + $view->document = $document; + + return $view->display(); + */ + + return parent::display(); + } + + // Check for edit form. + if ($view == 'style' && $layout == 'edit' && !$this->checkEditId('com_templates.edit.style', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_templates&view=styles', false)); + + return false; + } + + return parent::display(); + } +} diff --git a/administrator/components/com_templates/Controller/StyleController.php b/administrator/components/com_templates/Controller/StyleController.php new file mode 100644 index 0000000000000..3f6803588554d --- /dev/null +++ b/administrator/components/com_templates/Controller/StyleController.php @@ -0,0 +1,164 @@ +redirect('index.php', Text::_('JINVALID_TOKEN')); + } + + $document = Factory::getDocument(); + + if ($document->getType() === 'json') + { + $app = Factory::getApplication(); + $model = $this->getModel('Style', 'Administrator'); + $table = $model->getTable(); + $data = $this->input->post->get('params', array(), 'array'); + $checkin = $table->hasField('checked_out'); + $context = $this->option . '.edit.' . $this->context; + + $item = $model->getItem($app->getTemplate(true)->id); + + // Setting received params + $item->set('params', $data); + + $data = $item->getProperties(); + unset($data['xml']); + + $key = $table->getKeyName(); + + // Access check. + if (!$this->allowSave($data, $key)) + { + $app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + \JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_templates/forms'); + + // Validate the posted data. + // Sometimes the form needs some posted data, such as for plugins and modules. + $form = $model->getForm($data, false); + + if (!$form) + { + $app->enqueueMessage($model->getError(), 'error'); + + return false; + } + + // Test whether the data is valid. + $validData = $model->validate($form, $data); + + if ($validData === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // 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) + { + $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Save the data in the session. + $app->setUserState($context . '.data', $data); + + return false; + } + + if (!isset($validData['tags'])) + { + $validData['tags'] = null; + } + + // Attempt to save the data. + if (!$model->save($validData)) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + $app->enqueueMessage(Text::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); + + return false; + } + + // Save succeeded, so check-in the record. + if ($checkin && $model->checkin($validData[$key]) === false) + { + // Save the data in the session. + $app->setUserState($context . '.data', $validData); + + // Check-in failed, so go back to the record and display a notice. + $app->enqueueMessage(Text::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'error'); + + return false; + } + + // Redirect the user and adjust session state + // Set the record data in the session. + $recordId = $model->getState($this->context . '.id'); + $this->holdEditId($context, $recordId); + $app->setUserState($context . '.data', null); + $model->checkout($recordId); + + // Invoke the postSave method to allow for the child class to access the model. + $this->postSaveHook($model, $validData); + + return true; + } + else + { + parent::save($key, $urlVar); + } + } +} diff --git a/administrator/components/com_templates/Controller/StylesController.php b/administrator/components/com_templates/Controller/StylesController.php new file mode 100644 index 0000000000000..d949b0c14793f --- /dev/null +++ b/administrator/components/com_templates/Controller/StylesController.php @@ -0,0 +1,153 @@ +input->post->get('cid', array(), 'array'); + + try + { + if (empty($pks)) + { + throw new \Exception(Text::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED')); + } + + $pks = ArrayHelper::toInteger($pks); + + $model = $this->getModel(); + $model->duplicate($pks); + $this->setMessage(Text::_('COM_TEMPLATES_SUCCESS_DUPLICATED')); + } + catch (\Exception $e) + { + Factory::getApplication()->enqueueMessage($e->getMessage(), 'error'); + } + + $this->setRedirect('index.php?option=com_templates&view=styles'); + } + + /** + * Proxy for getModel. + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return Model + * + * @since 1.6 + */ + public function getModel($name = 'Style', $prefix = 'Administrator', $config = array()) + { + return parent::getModel($name, $prefix, array('ignore_request' => true)); + } + + /** + * Method to set the home template for a client. + * + * @return void + * + * @since 1.6 + */ + public function setDefault() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $pks = $this->input->post->get('cid', array(), 'array'); + + try + { + if (empty($pks)) + { + throw new \Exception(Text::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED')); + } + + $pks = ArrayHelper::toInteger($pks); + + // Pop off the first element. + $id = array_shift($pks); + + /* @var \Joomla\Component\Templates\Administrator\Model\StyleModel $model */ + $model = $this->getModel(); + $model->setHome($id); + $this->setMessage(Text::_('COM_TEMPLATES_SUCCESS_HOME_SET')); + } + catch (\Exception $e) + { + $this->setMessage($e->getMessage(), 'warning'); + } + + $this->setRedirect('index.php?option=com_templates&view=styles'); + } + + /** + * Method to unset the default template for a client and for a language + * + * @return void + * + * @since 1.6 + */ + public function unsetDefault() + { + // Check for request forgeries + Session::checkToken('request') or jexit(Text::_('JINVALID_TOKEN')); + + $pks = $this->input->get->get('cid', array(), 'array'); + $pks = ArrayHelper::toInteger($pks); + + try + { + if (empty($pks)) + { + throw new \Exception(Text::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED')); + } + + // Pop off the first element. + $id = array_shift($pks); + + /* @var \Joomla\Component\Templates\Administrator\Model\StyleModel $model */ + $model = $this->getModel(); + $model->unsetHome($id); + $this->setMessage(Text::_('COM_TEMPLATES_SUCCESS_HOME_UNSET')); + } + catch (\Exception $e) + { + $this->setMessage($e->getMessage(), 'warning'); + } + + $this->setRedirect('index.php?option=com_templates&view=styles'); + } +} diff --git a/administrator/components/com_templates/Controller/TemplateController.php b/administrator/components/com_templates/Controller/TemplateController.php new file mode 100644 index 0000000000000..dbe92b27489b6 --- /dev/null +++ b/administrator/components/com_templates/Controller/TemplateController.php @@ -0,0 +1,741 @@ +registerTask('apply', 'save'); + } + + /** + * Method for closing the template. + * + * @return void + * + * @since 3.2 + */ + public function cancel() + { + $this->setRedirect(Route::_('index.php?option=com_templates&view=templates', false)); + } + + /** + * Method for closing a file. + * + * @return void + * + * @since 3.2 + */ + public function close() + { + $app = Factory::getApplication(); + $file = base64_encode('home'); + $id = $this->input->get('id'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + + /** + * Method for copying the template. + * + * @return boolean true on success, false otherwise + * + * @since 3.2 + */ + public function copy() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $app = $this->app; + $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'); + + $this->setRedirect('index.php?option=com_templates&view=template&id=' . $templateID . '&file=' . $file); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel('Template', 'Administrator'); + $model->setState('new_name', $newName); + $model->setState('tmp_prefix', uniqid('template_copy_')); + $model->setState('to_path', Factory::getConfig()->get('tmp_path') . '/' . $model->getState('tmp_prefix')); + + // Process only if we have a new name entered + if (strlen($newName) > 0) + { + if (!$this->app->getIdentity()->authorise('core.create', 'com_templates')) + { + // User is not authorised to delete + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED'), 'error'); + + return false; + } + + // Set FTP credentials, if given + ClientHelper::setCredentialsFromRequest('ftp'); + + // Check that new name is valid + if (($newNameRaw !== null) && ($newName !== $newNameRaw)) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error'); + + return false; + } + + // Check that new name doesn't already exist + if (!$model->checkNewName()) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_DUPLICATE_TEMPLATE_NAME'), 'error'); + + return false; + } + + // Check that from name does exist and get the folder name + $fromName = $model->getFromName(); + + if (!$fromName) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); + + return false; + } + + // Call model's copy method + if (!$model->copy()) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_COPY'), 'error'); + + return false; + } + + // Call installation model + $this->input->set('install_directory', Factory::getConfig()->get('tmp_path') . '/' . $model->getState('tmp_prefix')); + $installModel = new InstallModel; + Factory::getLanguage()->load('com_installer'); + + if (!$installModel->install()) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_INSTALL'), 'error'); + + return false; + } + + $this->setMessage(Text::sprintf('COM_TEMPLATES_COPY_SUCCESS', $newName)); + $model->cleanup(); + + return true; + } + } + + /** + * 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 (note, the empty array is atypical compared to other models). + * + * @return \Joomla\CMS\MVC\Model\BaseDatabaseModel The model. + * + * @since 3.2 + */ + public function getModel($name = 'Template', $prefix = 'Administrator', $config = array()) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to check if you can add a new record. + * + * @return boolean + * + * @since 3.2 + */ + protected function allowEdit() + { + return Factory::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(); + } + + /** + * Saves a template source file. + * + * @return void + * + * @since 3.2 + */ + public function save() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $data = $this->input->post->get('jform', array(), 'array'); + $task = $this->getTask(); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + $fileName = $this->input->get('file'); + $explodeArray = explode(':', base64_decode($fileName)); + + // Access check. + if (!$this->allowSave()) + { + $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + // Match the stored id's with the submitted. + if (empty($data['extension_id']) || empty($data['filename'])) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); + + return false; + } + elseif ($data['extension_id'] != $model->getState('extension.id')) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); + + return false; + } + elseif ($data['filename'] != end($explodeArray)) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); + + return false; + } + + // Validate the posted data. + $form = $model->getForm(); + + if (!$form) + { + $this->setMessage($model->getError(), 'error'); + + return false; + } + + $data = $model->validate($form, $data); + + // Check for validation errors. + if ($data === false) + { + // Get the validation messages. + $errors = $model->getErrors(); + + // 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) + { + $this->app->enqueueMessage($errors[$i]->getMessage(), 'warning'); + } + else + { + $this->app->enqueueMessage($errors[$i], 'warning'); + } + } + + // Redirect back to the edit screen. + $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName; + $this->setRedirect(Route::_($url, false)); + + return false; + } + + // Attempt to save the data. + if (!$model->save($data)) + { + // Redirect back to the edit screen. + $this->setMessage(Text::sprintf('JERROR_SAVE_FAILED', $model->getError()), 'warning'); + $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName; + $this->setRedirect(Route::_($url, false)); + + return false; + } + + $this->setMessage(Text::_('COM_TEMPLATES_FILE_SAVE_SUCCESS')); + + // 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(Route::_($url, false)); + break; + + default: + // Redirect to the list screen. + $file = base64_encode('home'); + $id = $this->input->get('id'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + break; + } + } + + /** + * Method for creating override. + * + * @return void + * + * @since 3.2 + */ + public function overrides() + { + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + $file = $this->input->get('file'); + $override = base64_decode($this->input->get('folder')); + $id = $this->input->get('id'); + + if ($model->createOverride($override)) + { + $this->setMessage(Text::_('COM_TEMPLATES_OVERRIDE_SUCCESS')); + } + + // Redirect back to the edit screen. + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + + /** + * Method for deleting a file. + * + * @return void + * + * @since 3.2 + */ + public function delete() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + $id = $this->input->get('id'); + $file = $this->input->get('file'); + + if (base64_decode(urldecode($file)) == 'index.php') + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INDEX_DELETE'), 'warning'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + + elseif ($model->deleteFile($file)) + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_DELETE_SUCCESS')); + $file = base64_encode('home'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_DELETE'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } + + /** + * Method for creating a new file. + * + * @return void + * + * @since 3.2 + */ + public function createFile() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + $id = $this->input->get('id'); + $file = $this->input->get('file'); + $name = $this->input->get('name'); + $location = base64_decode($this->input->get('address')); + $type = $this->input->get('type'); + + if ($type == 'null') + { + $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_TYPE'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + elseif (!preg_match('/^[a-zA-Z0-9-_]+$/', $name)) + { + $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + elseif ($model->createFile($name, $type, $location)) + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_CREATE_SUCCESS')); + $file = urlencode(base64_encode($location . '/' . $name . '.' . $type)); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_CREATE'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } + + /** + * Method for uploading a file. + * + * @return void + * + * @since 3.2 + */ + public function uploadFile() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + $id = $this->input->get('id'); + $file = $this->input->get('file'); + $upload = $this->input->files->get('files'); + $location = base64_decode($this->input->get('address')); + + if ($return = $model->uploadFile($upload, $location)) + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_UPLOAD_SUCCESS') . $upload['name']); + $redirect = base64_encode($return); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $redirect; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_UPLOAD'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } + + /** + * Method for creating a new folder. + * + * @return void + * + * @since 3.2 + */ + public function createFolder() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + $id = $this->input->get('id'); + $file = $this->input->get('file'); + $name = $this->input->get('name'); + $location = base64_decode($this->input->get('address')); + + if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $name)) + { + $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FOLDER_NAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + elseif ($model->createFolder($name, $location)) + { + $this->setMessage(Text::_('COM_TEMPLATES_FOLDER_CREATE_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FOLDER_CREATE'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } + + /** + * Method for deleting a folder. + * + * @return void + * + * @since 3.2 + */ + public function deleteFolder() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + $id = $this->input->get('id'); + $file = $this->input->get('file'); + $location = base64_decode($this->input->get('address')); + + if (empty($location)) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_ROOT_DELETE'), 'warning'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + elseif ($model->deleteFolder($location)) + { + $this->setMessage(Text::_('COM_TEMPLATES_FOLDER_DELETE_SUCCESS')); + + if (stristr(base64_decode($file), $location) != false) + { + $file = base64_encode('home'); + } + + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_FOLDER_DELETE_ERROR'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } + + /** + * Method for renaming a file. + * + * @return void + * + * @since 3.2 + */ + public function renameFile() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + $id = $this->input->get('id'); + $file = $this->input->get('file'); + $newName = $this->input->get('new_name'); + + if (base64_decode(urldecode($file)) == 'index.php') + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_RENAME_INDEX'), 'warning'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + elseif (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) + { + $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + elseif ($rename = $model->renameFile($file, $newName)) + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_RENAME_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $rename; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_FILE_RENAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } + + /** + * Method for cropping an image. + * + * @return void + * + * @since 3.2 + */ + public function cropImage() + { + $id = $this->input->get('id'); + $file = $this->input->get('file'); + $x = $this->input->get('x'); + $y = $this->input->get('y'); + $w = $this->input->get('w'); + $h = $this->input->get('h'); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + + if (empty($w) && empty($h) && empty($x) && empty($y)) + { + $this->setMessage(Text::_('COM_TEMPLATES_CROP_AREA_ERROR'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + elseif ($model->cropImage($file, $w, $h, $x, $y)) + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_CROP_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_CROP_ERROR'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } + + /** + * Method for resizing an image. + * + * @return void + * + * @since 3.2 + */ + public function resizeImage() + { + $id = $this->input->get('id'); + $file = $this->input->get('file'); + $width = $this->input->get('width'); + $height = $this->input->get('height'); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + + if ($model->resizeImage($file, $width, $height)) + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_RESIZE_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_RESIZE_ERROR'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } + + /** + * Method for copying a file. + * + * @return void + * + * @since 3.2 + */ + public function copyFile() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $id = $this->input->get('id'); + $file = $this->input->get('file'); + $newName = $this->input->get('new_name'); + $location = base64_decode($this->input->get('address')); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + + if (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) + { + $this->setMessage(Text::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + elseif ($model->copyFile($newName, $location, $file)) + { + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_COPY_FAIL'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } + + /** + * Method for extracting an archive file. + * + * @return void + * + * @since 3.2 + */ + public function extractArchive() + { + // Check for request forgeries + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $id = $this->input->get('id'); + $file = $this->input->get('file'); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel(); + + if ($model->extractArchive($file)) + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_SUCCESS')); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + else + { + $this->setMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_FAIL'), 'error'); + $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; + $this->setRedirect(Route::_($url, false)); + } + } +} diff --git a/administrator/components/com_templates/Extension/TemplatesComponent.php b/administrator/components/com_templates/Extension/TemplatesComponent.php new file mode 100644 index 0000000000000..3095e34d0bf30 --- /dev/null +++ b/administrator/components/com_templates/Extension/TemplatesComponent.php @@ -0,0 +1,46 @@ +getRegistry()->register('templates', new Templates); + } +} diff --git a/administrator/components/com_templates/Field/TemplatelocationField.php b/administrator/components/com_templates/Field/TemplatelocationField.php new file mode 100644 index 0000000000000..53555ba4d8fb8 --- /dev/null +++ b/administrator/components/com_templates/Field/TemplatelocationField.php @@ -0,0 +1,47 @@ +getUserStateFromRequest('com_templates.styles.client_id', 'client_id', '0', 'string'); + + // Get the templates for the selected client_id. + $options = TemplatesHelper::getTemplateOptions($clientId); + + // Merge into the parent options. + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_templates/Helper/TemplateHelper.php b/administrator/components/com_templates/Helper/TemplateHelper.php new file mode 100644 index 0000000000000..7787bef857fca --- /dev/null +++ b/administrator/components/com_templates/Helper/TemplateHelper.php @@ -0,0 +1,183 @@ +enqueueMessage(Text::_('COM_TEMPLATES_ERROR_UPLOAD_INPUT'), 'error'); + + return false; + } + + // Media file names should never have executable extensions buried in them. + $executable = array( + 'exe', 'phtml','java', 'perl', 'py', 'asp','dll', 'go', 'jar', + 'ade', 'adp', 'bat', 'chm', 'cmd', 'com', 'cpl', 'hta', 'ins', 'isp', + 'jse', 'lib', 'mde', 'msc', 'msp', 'mst', 'pif', 'scr', 'sct', 'shb', + 'sys', 'vb', 'vbe', 'vbs', 'vxd', 'wsc', 'wsf', 'wsh' + ); + $explodedFileName = explode('.', $file['name']); + + if (count($explodedFileName) > 2) + { + foreach ($executable as $extensionName) + { + if (in_array($extensionName, $explodedFileName)) + { + $app = Factory::getApplication(); + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_EXECUTABLE'), 'error'); + + return false; + } + } + } + + if ($file['name'] !== File::makeSafe($file['name']) || preg_match('/\s/', File::makeSafe($file['name']))) + { + $app = Factory::getApplication(); + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_WARNFILENAME'), 'error'); + + return false; + } + + $format = strtolower(File::getExt($file['name'])); + + $imageTypes = explode(',', $params->get('image_formats')); + $sourceTypes = explode(',', $params->get('source_formats')); + $fontTypes = explode(',', $params->get('font_formats')); + $archiveTypes = explode(',', $params->get('compressed_formats')); + + $allowable = array_merge($imageTypes, $sourceTypes, $fontTypes, $archiveTypes); + + if ($format == '' || $format == false || (!in_array($format, $allowable))) + { + $app = Factory::getApplication(); + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_WARNFILETYPE'), 'error'); + + return false; + } + + if (in_array($format, $archiveTypes)) + { + $zip = new \ZipArchive; + + if ($zip->open($file['tmp_name']) === true) + { + for ($i = 0; $i < $zip->numFiles; $i++) + { + $entry = $zip->getNameIndex($i); + $endString = substr($entry, -1); + + if ($endString != DIRECTORY_SEPARATOR) + { + $explodeArray = explode('.', $entry); + $ext = end($explodeArray); + + if (!in_array($ext, $allowable)) + { + $app = Factory::getApplication(); + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_UNSUPPORTED_ARCHIVE'), 'error'); + + return false; + } + } + } + } + else + { + $app = Factory::getApplication(); + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error'); + + return false; + } + } + + // Max upload size set to 2 MB for Template Manager + $maxSize = (int) ($params->get('upload_limit') * 1024 * 1024); + + if ($maxSize > 0 && (int) $file['size'] > $maxSize) + { + $app = Factory::getApplication(); + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_WARNFILETOOLARGE'), 'error'); + + return false; + } + + $xss_check = file_get_contents($file['tmp_name'], false, null, -1, 256); + $html_tags = array( + 'abbr', 'acronym', 'address', 'applet', 'area', 'audioscope', 'base', 'basefont', 'bdo', 'bgsound', 'big', 'blackface', 'blink', 'blockquote', + 'body', 'bq', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'comment', 'custom', 'dd', 'del', 'dfn', 'dir', 'div', + 'dl', 'dt', 'em', 'embed', 'fieldset', 'fn', 'font', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', + 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'keygen', 'kbd', 'label', 'layer', 'legend', 'li', 'limittext', 'link', 'listing', + 'map', 'marquee', 'menu', 'meta', 'multicol', 'nobr', 'noembed', 'noframes', 'noscript', 'nosmartquotes', 'object', 'ol', 'optgroup', 'option', + 'param', 'plaintext', 'pre', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'server', 'shadow', 'sidebar', 'small', 'spacer', 'span', 'strike', + 'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt', 'ul', 'var', 'wbr', 'xml', + 'xmp', '!DOCTYPE', '!--' + ); + + foreach ($html_tags as $tag) + { + // A tag is '' + if (stristr($xss_check, '<' . $tag . ' ') || stristr($xss_check, '<' . $tag . '>')) + { + $app = Factory::getApplication(); + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_WARNIEXSS'), 'error'); + + return false; + } + } + + return true; + } +} diff --git a/administrator/components/com_templates/Helper/TemplatesHelper.php b/administrator/components/com_templates/Helper/TemplatesHelper.php new file mode 100644 index 0000000000000..a58cb88ee5ceb --- /dev/null +++ b/administrator/components/com_templates/Helper/TemplatesHelper.php @@ -0,0 +1,181 @@ +getQuery(true); + + $query->select($db->quoteName('element', 'value')) + ->select($db->quoteName('name', 'text')) + ->select($db->quoteName('extension_id', 'e_id')) + ->from($db->quoteName('#__extensions')) + ->where($db->quoteName('type') . ' = ' . $db->quote('template')) + ->where($db->quoteName('enabled') . ' = 1') + ->order($db->quoteName('client_id') . ' ASC') + ->order($db->quoteName('name') . ' ASC'); + + if ($clientId != '*') + { + $query->where($db->quoteName('client_id') . ' = ' . (int) $clientId); + } + + $db->setQuery($query); + $options = $db->loadObjectList(); + + return $options; + } + + /** + * TODO + * + * @param string $templateBaseDir TODO + * @param string $templateDir TODO + * + * @return boolean|\JObject + */ + public static function parseXMLTemplateFile($templateBaseDir, $templateDir) + { + $data = new \JObject; + + // Check of the xml file exists + $filePath = Path::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml'); + + if (is_file($filePath)) + { + $xml = Installer::parseXMLInstallFile($filePath); + + if ($xml['type'] != 'template') + { + return false; + } + + foreach ($xml as $key => $value) + { + $data->set($key, $value); + } + } + + return $data; + } + + /** + * TODO + * + * @param integer $clientId TODO + * @param string $templateDir TODO + * + * @return boolean|array + * + * @since 3.0 + */ + public static function getPositions($clientId, $templateDir) + { + $positions = array(); + + $templateBaseDir = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; + $filePath = Path::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml'); + + if (is_file($filePath)) + { + // Read the file to see if it's a valid component XML file + $xml = simplexml_load_file($filePath); + + if (!$xml) + { + return false; + } + + // Check for a valid XML root tag. + + // Extensions use 'extension' as the root tag. Languages use 'metafile' instead + + if ($xml->getName() != 'extension' && $xml->getName() != 'metafile') + { + unset($xml); + + return false; + } + + $positions = (array) $xml->positions; + + if (isset($positions['position'])) + { + $positions = (array) $positions['position']; + } + else + { + $positions = array(); + } + } + + return $positions; + } +} diff --git a/administrator/components/com_templates/Model/StyleModel.php b/administrator/components/com_templates/Model/StyleModel.php new file mode 100644 index 0000000000000..c07f4d98fbac2 --- /dev/null +++ b/administrator/components/com_templates/Model/StyleModel.php @@ -0,0 +1,726 @@ + 'onExtensionBeforeDelete', + 'event_after_delete' => 'onExtensionAfterDelete', + 'event_before_save' => 'onExtensionBeforeSave', + 'event_after_save' => 'onExtensionAfterSave', + 'events_map' => array('delete' => 'extension', 'save' => 'extension') + ), $config + ); + + parent::__construct($config, $factory); + } + + /** + * Method to auto-populate the model state. + * + * @note Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = Factory::getApplication(); + + // Load the User state. + $pk = $app->input->getInt('id'); + $this->setState('style.id', $pk); + + // Load the parameters. + $params = ComponentHelper::getParams('com_templates'); + $this->setState('params', $params); + } + + /** + * Method to delete rows. + * + * @param array &$pks An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + * @throws \Exception + */ + public function delete(&$pks) + { + $pks = (array) $pks; + $user = Factory::getUser(); + $table = $this->getTable(); + $context = $this->option . '.' . $this->name; + + PluginHelper::importPlugin($this->events_map['delete']); + + // Iterate the items to delete each one. + foreach ($pks as $pk) + { + if ($table->load($pk)) + { + // Access checks. + if (!$user->authorise('core.delete', 'com_templates')) + { + throw new \Exception(Text::_('JERROR_CORE_DELETE_NOT_PERMITTED')); + } + + // You should not delete a default style + if ($table->home != '0') + { + Factory::getApplication()->enqueueMessage(Text::_('COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE'), 'error'); + + return false; + } + + // Trigger the before delete event. + $result = Factory::getApplication()->triggerEvent($this->event_before_delete, array($context, $table)); + + if (in_array(false, $result, true) || !$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after delete event. + Factory::getApplication()->triggerEvent($this->event_after_delete, array($context, $table)); + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + // Clean cache + $this->cleanCache(); + + return true; + } + + /** + * Method to duplicate styles. + * + * @param array &$pks An array of primary key IDs. + * + * @return boolean True if successful. + * + * @throws \Exception + */ + public function duplicate(&$pks) + { + $user = Factory::getUser(); + + // Access checks. + if (!$user->authorise('core.create', 'com_templates')) + { + throw new \Exception(Text::_('JERROR_CORE_CREATE_NOT_PERMITTED')); + } + + $context = $this->option . '.' . $this->name; + + // Include the plugins for the save events. + PluginHelper::importPlugin($this->events_map['save']); + + $table = $this->getTable(); + + foreach ($pks as $pk) + { + if ($table->load($pk, true)) + { + // Reset the id to create a new record. + $table->id = 0; + + // Reset the home (don't want dupes of that field). + $table->home = 0; + + // Alter the title. + $m = null; + $table->title = $this->generateNewTitle(null, null, $table->title); + + if (!$table->check()) + { + throw new \Exception($table->getError()); + } + + // Trigger the before save event. + $result = Factory::getApplication()->triggerEvent($this->event_before_save, array($context, &$table, true)); + + if (in_array(false, $result, true) || !$table->store()) + { + throw new \Exception($table->getError()); + } + + // Trigger the after save event. + Factory::getApplication()->triggerEvent($this->event_after_save, array($context, &$table, true)); + } + else + { + throw new \Exception($table->getError()); + } + } + + // Clean cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the title. + * + * @param integer $category_id 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) + { + // Alter the title + $table = $this->getTable(); + + while ($table->load(array('title' => $title))) + { + $title = StringHelper::increment($title); + } + + return $title; + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return Form A Form object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // The folder and element vars are passed when saving the form. + if (empty($data)) + { + $item = $this->getItem(); + $clientId = $item->client_id; + $template = $item->template; + } + else + { + $clientId = ArrayHelper::getValue($data, 'client_id'); + $template = ArrayHelper::getValue($data, 'template'); + } + + // Add the default fields directory + $baseFolder = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; + Form::addFieldPath($baseFolder . '/templates/' . $template . '/field'); + + // These variables are used to add data from the plugin XML files. + $this->setState('item.client_id', $clientId); + $this->setState('item.template', $template); + + // Get the form. + $form = $this->loadForm('com_templates.style', 'style', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('home', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('home', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_templates.edit.style.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_templates.style', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + */ + public function getItem($pk = null) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('style.id'); + + if (!isset($this->_cache[$pk])) + { + // Get a row instance. + $table = $this->getTable(); + + // Attempt to load the row. + $return = $table->load($pk); + + // Check for a table object error. + if ($return === false && $table->getError()) + { + $this->setError($table->getError()); + + return false; + } + + // Convert to the \JObject before adding other data. + $properties = $table->getProperties(1); + $this->_cache[$pk] = ArrayHelper::toObject($properties, 'JObject'); + + // Convert the params field to an array. + $registry = new Registry($table->params); + $this->_cache[$pk]->params = $registry->toArray(); + + // Get the template XML. + $client = ApplicationHelper::getClientInfo($table->client_id); + $path = Path::clean($client->path . '/templates/' . $table->template . '/templateDetails.xml'); + + if (file_exists($path)) + { + $this->_cache[$pk]->xml = simplexml_load_file($path); + } + else + { + $this->_cache[$pk]->xml = null; + } + } + + return $this->_cache[$pk]; + } + + /** + * Method to allow derived classes to preprocess the form. + * + * @param Form $form A Form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws \Exception if there is an error in the form event. + */ + protected function preprocessForm(Form $form, $data, $group = 'content') + { + $clientId = $this->getState('item.client_id'); + $template = $this->getState('item.template'); + $lang = Factory::getLanguage(); + $client = ApplicationHelper::getClientInfo($clientId); + + if (!$form->loadFile('style_' . $client->name, true)) + { + throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); + } + + $formFile = Path::clean($client->path . '/templates/' . $template . '/templateDetails.xml'); + + // Load the core and/or local language file(s). + $lang->load('tpl_' . $template, $client->path, null, false, true) + || $lang->load('tpl_' . $template, $client->path . '/templates/' . $template, null, false, true); + + if (file_exists($formFile)) + { + // Get the template form. + if (!$form->loadFile($formFile, false, '//config')) + { + throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); + } + } + + // 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')) + { + $form->setFieldAttribute('home', 'readonly', 'true'); + } + + // Attempt to load the xml file. + if (!$xml = simplexml_load_file($formFile)) + { + throw new \Exception(Text::_('JERROR_LOADFILE_FAILED')); + } + + // Get the help data from the XML file if present. + $help = $xml->xpath('/extension/help'); + + if (!empty($help)) + { + $helpKey = trim((string) $help[0]['key']); + $helpURL = trim((string) $help[0]['url']); + + $this->helpKey = $helpKey ?: $this->helpKey; + $this->helpURL = $helpURL ?: $this->helpURL; + } + + // Trigger the default form events. + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + */ + public function save($data) + { + // Detect disabled extension + $extension = Table::getInstance('Extension', 'Joomla\\CMS\\Table\\'); + + if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $data['template'], 'client_id' => $data['client_id']))) + { + $this->setError(Text::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE')); + + return false; + } + + $app = Factory::getApplication(); + $table = $this->getTable(); + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('style.id'); + $isNew = true; + + // Include the extension plugins for the save events. + PluginHelper::importPlugin($this->events_map['save']); + + // Load the row if saving an existing record. + if ($pk > 0) + { + $table->load($pk); + $isNew = false; + } + + if ($app->input->get('task') == 'save2copy') + { + $data['title'] = $this->generateNewTitle(null, null, $data['title']); + $data['home'] = 0; + $data['assigned'] = ''; + } + + // Bind the data. + if (!$table->bind($data)) + { + $this->setError($table->getError()); + + return false; + } + + // Prepare the row for saving + $this->prepareTable($table); + + // Check the data. + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = Factory::getApplication()->triggerEvent($this->event_before_save, array('com_templates.style', &$table, $isNew)); + + // Store the data. + if (in_array(false, $result, true) || !$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + $user = Factory::getUser(); + + if ($user->authorise('core.edit', 'com_menus') && $table->client_id == 0) + { + $n = 0; + $db = $this->getDbo(); + $user = Factory::getUser(); + + if (!empty($data['assigned']) && is_array($data['assigned'])) + { + $data['assigned'] = ArrayHelper::toInteger($data['assigned']); + + // Update the mapping for menu items that this style IS assigned to. + $query = $db->getQuery(true) + ->update('#__menu') + ->set('template_style_id = ' . (int) $table->id) + ->where('id IN (' . implode(',', $data['assigned']) . ')') + ->where('template_style_id != ' . (int) $table->id) + ->where('checked_out IN (0,' . (int) $user->id . ')'); + $db->setQuery($query); + $db->execute(); + $n += $db->getAffectedRows(); + } + + // Remove style mappings for menu items this style is NOT assigned to. + // If unassigned then all existing maps will be removed. + $query = $db->getQuery(true) + ->update('#__menu') + ->set('template_style_id = 0'); + + if (!empty($data['assigned'])) + { + $query->where('id NOT IN (' . implode(',', $data['assigned']) . ')'); + } + + $query->where('template_style_id = ' . (int) $table->id) + ->where('checked_out IN (0,' . (int) $user->id . ')'); + $db->setQuery($query); + $db->execute(); + + $n += $db->getAffectedRows(); + + if ($n > 0) + { + $app->enqueueMessage(Text::plural('COM_TEMPLATES_MENU_CHANGED', $n)); + } + } + + // Clean the cache. + $this->cleanCache(); + + // Trigger the after save event. + Factory::getApplication()->triggerEvent($this->event_after_save, array('com_templates.style', &$table, $isNew)); + + $this->setState('style.id', $table->id); + + return true; + } + + /** + * Method to set a template style as home. + * + * @param integer $id The primary key ID for the style. + * + * @return boolean True if successful. + * + * @throws \Exception + */ + public function setHome($id = 0) + { + $user = Factory::getUser(); + $db = $this->getDbo(); + + // Access checks. + if (!$user->authorise('core.edit.state', 'com_templates')) + { + throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + } + + $style = $this->getTable(); + + if (!$style->load((int) $id)) + { + throw new \Exception(Text::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND')); + } + + // Detect disabled extension + $extension = Table::getInstance('Extension', 'Joomla\\CMS\\Table\\'); + + if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $style->template, 'client_id' => $style->client_id))) + { + throw new \Exception(Text::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE')); + } + + // Reset the home fields for the client_id. + $query = $db->getQuery(true) + ->update('#__template_styles') + ->set('home = ' . $db->quote('0')) + ->where('client_id = ' . (int) $style->client_id) + ->where('home = ' . $db->quote('1')); + $db->setQuery($query); + $db->execute(); + + // Set the new home style. + $query = $db->getQuery(true) + ->update('#__template_styles') + ->set('home = ' . $db->quote('1')) + ->where('id = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + // Clean the cache. + $this->cleanCache(); + + return true; + } + + /** + * Method to unset a template style as default for a language. + * + * @param integer $id The primary key ID for the style. + * + * @return boolean True if successful. + * + * @throws \Exception + */ + public function unsetHome($id = 0) + { + $user = Factory::getUser(); + $db = $this->getDbo(); + + // Access checks. + if (!$user->authorise('core.edit.state', 'com_templates')) + { + throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + } + + // Lookup the client_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)) + { + throw new \Exception(Text::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND')); + } + elseif ($style->home == '1') + { + throw new \Exception(Text::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE')); + } + + // Set the new home style. + $query = $db->getQuery(true) + ->update('#__template_styles') + ->set('home = ' . $db->quote('0')) + ->where('id = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + + // Clean the cache. + $this->cleanCache(); + + return true; + } + + /** + * Get the necessary data to load an item help screen. + * + * @return object An object with key, url, and local properties for loading the item help screen. + * + * @since 1.6 + */ + public function getHelp() + { + return (object) array('key' => $this->helpKey, 'url' => $this->helpURL); + } + + /** + * Custom clean cache method + * + * @param string $group The cache group + * @param integer $client_id The ID of the client + * + * @return void + * + * @since 1.6 + */ + protected function cleanCache($group = null, $client_id = 0) + { + parent::cleanCache('com_templates'); + parent::cleanCache('_system'); + } +} diff --git a/administrator/components/com_templates/Model/StylesModel.php b/administrator/components/com_templates/Model/StylesModel.php new file mode 100644 index 0000000000000..f1a8ce355e170 --- /dev/null +++ b/administrator/components/com_templates/Model/StylesModel.php @@ -0,0 +1,206 @@ +setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('filter.template', $this->getUserStateFromRequest($this->context . '.filter.template', 'filter_template', '', 'string')); + $this->setState('filter.menuitem', $this->getUserStateFromRequest($this->context . '.filter.menuitem', 'filter_menuitem', '', 'cmd')); + + // Special case for the client id. + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; + $this->setState('client_id', $clientId); + + // Load the parameters. + $params = ComponentHelper::getParams('com_templates'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('client_id'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.template'); + $id .= ':' . $this->getState('filter.menuitem'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery + */ + protected function getListQuery() + { + $clientId = (int) $this->getState('client_id'); + + // 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.id, a.template, a.title, a.home, a.client_id, l.title AS language_title, l.image as image, l.sef AS language_sef' + ) + ); + $query->from($db->quoteName('#__template_styles', 'a')) + ->where($db->quoteName('a.client_id') . ' = ' . $clientId); + + // Join on menus. + $query->select('COUNT(m.template_style_id) AS assigned') + ->join('LEFT', $db->quoteName('#__menu', 'm') . ' ON ' . $db->quoteName('m.template_style_id') . ' = ' . $db->quoteName('a.id')) + ->group($db->quoteName(array('a.id', 'a.template', 'a.title', 'a.home', 'a.client_id', 'l.title', 'l.image', 'l.sef', 'e.extension_id'))); + + // Join over the language. + $query->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.home')); + + // Filter by extension enabled. + $query->select($db->quoteName('extension_id', 'e_id')) + ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON e.element = a.template AND e.client_id = a.client_id') + ->where($db->quoteName('e.enabled') . ' = 1') + ->where($db->quoteName('e.type') . ' = ' . $db->quote('template')); + + // Filter by template. + if ($template = $this->getState('filter.template')) + { + $query->where($db->quoteName('a.template') . ' = ' . $db->quote($template)); + } + + // Filter by menuitem. + $menuItemId = $this->getState('filter.menuitem'); + + if ($clientId === 0 && is_numeric($menuItemId)) + { + // If user selected the templates styles that are not assigned to any page. + if ((int) $menuItemId === -1) + { + // Only custom template styles overrides not assigned to any menu item. + $query->where($db->quoteName('a.home') . ' = ' . $db->quote(0)) + ->where($db->quoteName('m.id') . ' IS NULL'); + } + // If user selected the templates styles assigned to particular pages. + else + { + // Subquery to get the language of the selected menu item. + $menuItemLanguageSubQuery = $db->getQuery(true); + $menuItemLanguageSubQuery->select($db->quoteName('language')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('id') . ' = ' . $menuItemId); + + // Subquery to get the language of the selected menu item. + $templateStylesMenuItemsSubQuery = $db->getQuery(true); + $templateStylesMenuItemsSubQuery->select($db->quoteName('id')) + ->from($db->quoteName('#__menu')) + ->where($db->quoteName('template_style_id') . ' = ' . $db->quoteName('a.id')); + + // Main query where clause. + $query->where('(' . + // Default template style (fallback template style to all menu items). + $db->quoteName('a.home') . ' = ' . $db->quote(1) . ' OR ' . + // Default template style for specific language (fallback template style to the selected menu item language). + $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 . '))' . + ')' + ); + } + } + + // Filter by search in title. + if ($search = $this->getState('filter.search')) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . strtolower($search) . '%'); + $query->where('(' . ' LOWER(a.template) LIKE ' . $search . ' OR LOWER(a.title) LIKE ' . $search . ')'); + } + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.template')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } +} diff --git a/administrator/components/com_templates/Model/TemplateModel.php b/administrator/components/com_templates/Model/TemplateModel.php new file mode 100644 index 0000000000000..fe80d7005cfd4 --- /dev/null +++ b/administrator/components/com_templates/Model/TemplateModel.php @@ -0,0 +1,1427 @@ +getTemplate()) + { + $temp->name = $name; + $temp->id = urlencode(base64_encode($path . $name)); + + return $temp; + } + } + + /** + * Method to get a list of all the files to edit in a template. + * + * @return array A nested array of relevant files. + * + * @since 1.6 + */ + public function getFiles() + { + $result = array(); + + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $path = Path::clean($client->path . '/templates/' . $template->element . '/'); + $lang = Factory::getLanguage(); + + // Load the core and/or local language file(s). + $lang->load('tpl_' . $template->element, $client->path, null, false, true) || + $lang->load('tpl_' . $template->element, $client->path . '/templates/' . $template->element, null, false, true); + $this->element = $path; + + if (!is_writable($path)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_DIRECTORY_NOT_WRITABLE'), 'error'); + } + + if (is_dir($path)) + { + $result = $this->getDirectoryTree($path); + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_TEMPLATE_FOLDER_NOT_FOUND'), 'error'); + + return false; + } + } + + return $result; + } + + /** + * Get the directory tree. + * + * @param string $dir The path of the directory to scan + * + * @return array + * + * @since 3.2 + */ + public function getDirectoryTree($dir) + { + $result = array(); + + $dirFiles = scandir($dir); + + foreach ($dirFiles as $key => $value) + { + if (!in_array($value, array('.', '..', 'node_modules'))) + { + if (is_dir($dir . $value)) + { + $relativePath = str_replace($this->element, '', $dir . $value); + $result['/' . $relativePath] = $this->getDirectoryTree($dir . $value . '/'); + } + else + { + $ext = pathinfo($dir . $value, PATHINFO_EXTENSION); + $allowedFormat = $this->checkFormat($ext); + + if ($allowedFormat == true) + { + $relativePath = str_replace($this->element, '', $dir); + $info = $this->getFile('/' . $relativePath, $value); + $result[] = $info; + } + } + } + } + + return $result; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 1.6 + */ + protected function populateState() + { + $app = Factory::getApplication(); + + // Load the User state. + $pk = $app->input->getInt('id'); + $this->setState('extension.id', $pk); + + // Load the parameters. + $params = ComponentHelper::getParams('com_templates'); + $this->setState('params', $params); + } + + /** + * Method to get the template information. + * + * @return mixed Object if successful, false if not and internal error is set. + * + * @since 1.6 + */ + public function &getTemplate() + { + if (empty($this->template)) + { + $pk = $this->getState('extension.id'); + $db = $this->getDbo(); + $app = Factory::getApplication(); + + // Get the template information. + $query = $db->getQuery(true) + ->select('extension_id, client_id, element, name, manifest_cache') + ->from('#__extensions') + ->where($db->quoteName('extension_id') . ' = ' . (int) $pk) + ->where($db->quoteName('type') . ' = ' . $db->quote('template')); + $db->setQuery($query); + + try + { + $result = $db->loadObject(); + } + catch (\RuntimeException $e) + { + $app->enqueueMessage($e->getMessage(), 'warning'); + $this->template = false; + + return false; + } + + if (empty($result)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND'), 'error'); + $this->template = false; + } + else + { + $this->template = $result; + } + } + + return $this->template; + } + + /** + * Method to check if new template name already exists + * + * @return boolean true if name is not used, false otherwise + * + * @since 2.5 + */ + public function checkNewName() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from('#__extensions') + ->where('name = ' . $db->quote($this->getState('new_name'))); + $db->setQuery($query); + + return ($db->loadResult() == 0); + } + + /** + * Method to check if new template name already exists + * + * @return string name of current template + * + * @since 2.5 + */ + public function getFromName() + { + return $this->getTemplate()->element; + } + + /** + * Method to check if new template name already exists + * + * @return boolean true if name is not used, false otherwise + * + * @since 2.5 + */ + public function copy() + { + $app = Factory::getApplication(); + + if ($template = $this->getTemplate()) + { + $client = ApplicationHelper::getClientInfo($template->client_id); + $fromPath = Path::clean($client->path . '/templates/' . $template->element . '/'); + + // Delete new folder if it exists + $toPath = $this->getState('to_path'); + + if (Folder::exists($toPath)) + { + if (!Folder::delete($toPath)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_WRITE'), 'error'); + + return false; + } + } + + // Copy all files from $fromName template to $newName folder + if (!Folder::copy($fromPath, $toPath) || !$this->fixTemplateName()) + { + return false; + } + + return true; + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); + + return false; + } + } + + /** + * Method to delete tmp folder + * + * @return boolean true if delete successful, false otherwise + * + * @since 2.5 + */ + public function cleanup() + { + // Clear installation messages + $app = Factory::getApplication(); + $app->setUserState('com_installer.message', ''); + $app->setUserState('com_installer.extension_message', ''); + + // Delete temporary directory + return Folder::delete($this->getState('to_path')); + } + + /** + * Method to rename the template in the XML files and rename the language files + * + * @return boolean true if successful, false otherwise + * + * @since 2.5 + */ + protected function fixTemplateName() + { + // Rename Language files + // Get list of language files + $result = true; + $files = Folder::files($this->getState('to_path'), '.ini', true, true); + $newName = strtolower($this->getState('new_name')); + $template = $this->getTemplate(); + $oldName = $template->element; + $manifest = json_decode($template->manifest_cache); + + foreach ($files as $file) + { + $newFile = str_replace($oldName, $newName, $file); + $result = File::move($file, $newFile) && $result; + } + + // Edit XML file + $xmlFile = $this->getState('to_path') . '/templateDetails.xml'; + + if (File::exists($xmlFile)) + { + $contents = file_get_contents($xmlFile); + $pattern[] = '#\s*' . $manifest->name . '\s*#i'; + $replace[] = '' . $newName . ''; + $pattern[] = '##'; + $replace[] = ''; + $contents = preg_replace($pattern, $replace, $contents); + $result = File::write($xmlFile, $contents) && $result; + } + + return $result; + } + + /** + * Method to get the record form. + * + * @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 A \JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + $app = Factory::getApplication(); + + // Codemirror or Editor None should be enabled + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('COUNT(*)') + ->from('#__extensions as a') + ->where( + '(a.name =' . $db->quote('plg_editors_codemirror') . + ' AND a.enabled = 1) OR (a.name =' . + $db->quote('plg_editors_none') . + ' AND a.enabled = 1)' + ); + $db->setQuery($query); + $state = $db->loadResult(); + + if ((int) $state < 1) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_EDITOR_DISABLED'), 'warning'); + } + + // Get the form. + $form = $this->loadForm('com_templates.source', 'source', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + */ + protected function loadFormData() + { + $data = $this->getSource(); + + $this->preprocessData('com_templates.source', $data); + + return $data; + } + + /** + * Method to get a single record. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function &getSource() + { + $app = Factory::getApplication(); + $item = new \stdClass; + + if (!$this->template) + { + $this->getTemplate(); + } + + if ($this->template) + { + $input = Factory::getApplication()->input; + $fileName = base64_decode($input->get('file')); + $client = ApplicationHelper::getClientInfo($this->template->client_id); + + try + { + $filePath = Path::check($client->path . '/templates/' . $this->template->element . '/' . $fileName); + } + catch (\Exception $e) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_FOUND'), 'error'); + + return; + } + + if (file_exists($filePath)) + { + $item->extension_id = $this->getState('extension.id'); + $item->filename = $fileName; + $item->source = file_get_contents($filePath); + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_FOUND'), 'error'); + } + } + + return $item; + } + + /** + * Method to store the source file contents. + * + * @param array $data The source data to save. + * + * @return boolean True on success, false otherwise and internal error set. + * + * @since 1.6 + */ + public function save($data) + { + // Get the template. + $template = $this->getTemplate(); + + if (empty($template)) + { + return false; + } + + $app = Factory::getApplication(); + $fileName = base64_decode($app->input->get('file')); + $client = ApplicationHelper::getClientInfo($template->client_id); + $filePath = Path::clean($client->path . '/templates/' . $template->element . '/' . $fileName); + + // Include the extension plugins for the save events. + PluginHelper::importPlugin('extension'); + + $user = get_current_user(); + chown($filePath, $user); + Path::setPermissions($filePath, '0644'); + + // Try to make the template file writable. + if (!is_writable($filePath)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_WRITABLE'), 'warning'); + $app->enqueueMessage(Text::sprintf('COM_TEMPLATES_FILE_PERMISSIONS', Path::getPermissions($filePath)), 'warning'); + + if (!Path::isOwner($filePath)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_CHECK_FILE_OWNERSHIP'), 'warning'); + } + + return false; + } + + // Make sure EOL is Unix + $data['source'] = str_replace(array("\r\n", "\r"), "\n", $data['source']); + + $return = File::write($filePath, $data['source']); + + if (!$return) + { + $app->enqueueMessage(Text::sprintf('COM_TEMPLATES_ERROR_FAILED_TO_SAVE_FILENAME', $fileName), 'error'); + + return false; + } + + // Get the extension of the changed file. + $explodeArray = explode('.', $fileName); + $ext = end($explodeArray); + + if ($ext == 'less') + { + $app->enqueueMessage(Text::sprintf('COM_TEMPLATES_COMPILE_LESS', $fileName)); + } + + return true; + } + + /** + * Get overrides folder. + * + * @param string $name The name of override. + * @param string $path Location of override. + * + * @return object containing override name and path. + * + * @since 3.2 + */ + public function getOverridesFolder($name,$path) + { + $folder = new \stdClass; + $folder->name = $name; + $folder->path = base64_encode($path . $name); + + return $folder; + } + + /** + * Get a list of overrides. + * + * @return array containing overrides. + * + * @since 3.2 + */ + public function getOverridesList() + { + if ($template = $this->getTemplate()) + { + $client = ApplicationHelper::getClientInfo($template->client_id); + $componentPath = Path::clean($client->path . '/components/'); + $modulePath = Path::clean($client->path . '/modules/'); + $layoutPath = Path::clean(JPATH_ROOT . '/layouts/'); + $components = Folder::folders($componentPath); + + foreach ($components as $component) + { + // Collect the folders with views + $folders = Folder::folders($componentPath . '/' . $component, '^view[s]?$', false, true); + $folders = array_merge($folders, Folder::folders($componentPath . '/' . $component, '^tmpl?$', false, true)); + + if (!$folders) + { + continue; + } + + foreach ($folders as $folder) + { + // The subfolders are views + $views = Folder::folders($folder); + + foreach ($views as $view) + { + // The old scheme, if a view has a tmpl folder + $path = $folder . '/' . $view . '/tmpl'; + + // The new scheme, the views are directly in the component/tmpl folder + if (!is_dir($path) && substr($folder, -4) == 'tmpl') + { + $path = $folder . '/' . $view; + } + + // Check if the folder exists + if (!is_dir($path)) + { + continue; + } + + $result['components'][$component][] = $this->getOverridesFolder($view, Path::clean($folder . '/')); + } + } + } + + $modules = Folder::folders($modulePath); + + foreach ($modules as $module) + { + $result['modules'][] = $this->getOverridesFolder($module, $modulePath); + } + + $layoutFolders = Folder::folders($layoutPath); + + foreach ($layoutFolders as $layoutFolder) + { + $layoutFolderPath = Path::clean($layoutPath . '/' . $layoutFolder . '/'); + $layouts = Folder::folders($layoutFolderPath); + + foreach ($layouts as $layout) + { + $result['layouts'][$layoutFolder][] = $this->getOverridesFolder($layout, $layoutFolderPath); + } + } + + // Check for layouts in component folders + foreach ($components as $component) + { + if (file_exists($componentPath . '/' . $component . '/layouts/')) + { + $componentLayoutPath = Path::clean($componentPath . '/' . $component . '/layouts/'); + + if ($componentLayoutPath) + { + $layouts = Folder::folders($componentLayoutPath); + + foreach ($layouts as $layout) + { + $result['layouts'][$component][] = $this->getOverridesFolder($layout, $componentLayoutPath); + } + } + } + } + } + + if (!empty($result)) + { + return $result; + } + } + + /** + * Create overrides. + * + * @param string $override The override location. + * + * @return boolean true if override creation is successful, false otherwise + * + * @since 3.2 + */ + public function createOverride($override) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $explodeArray = explode(DIRECTORY_SEPARATOR, $override); + $name = end($explodeArray); + $client = ApplicationHelper::getClientInfo($template->client_id); + + if (stristr($name, 'mod_') != false) + { + $htmlPath = Path::clean($client->path . '/templates/' . $template->element . '/html/' . $name); + } + elseif (stristr($override, 'com_') != false) + { + $size = count($explodeArray); + + $url = Path::clean($explodeArray[$size - 3] . '/' . $explodeArray[$size - 1]); + + if ($explodeArray[$size - 2] == 'layouts') + { + $htmlPath = Path::clean($client->path . '/templates/' . $template->element . '/html/layouts/' . $url); + } + else + { + $htmlPath = Path::clean($client->path . '/templates/' . $template->element . '/html/' . $url); + } + } + else + { + $layoutPath = implode('/', array_slice($explodeArray, -2)); + $htmlPath = Path::clean($client->path . '/templates/' . $template->element . '/html/layouts/' . $layoutPath); + } + + // Check Html folder, create if not exist + if (!Folder::exists($htmlPath)) + { + if (!Folder::create($htmlPath)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FOLDER_ERROR'), 'error'); + + return false; + } + } + + if (stristr($name, 'mod_') != false) + { + $return = $this->createTemplateOverride(Path::clean($override . '/tmpl'), $htmlPath); + } + elseif (stristr($override, 'com_') != false && stristr($override, 'layouts') == false) + { + $path = $override . '/tmpl'; + + // View can also be in the top level folder + if (!is_dir($path)) + { + $path = $override; + } + + $return = $this->createTemplateOverride(Path::clean($path), $htmlPath); + } + else + { + $return = $this->createTemplateOverride($override, $htmlPath); + } + + if ($return) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_OVERRIDE_CREATED') . str_replace(JPATH_ROOT, '', $htmlPath)); + + return true; + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_OVERRIDE_FAILED'), 'error'); + + return false; + } + } + } + + /** + * Create override folder & file + * + * @param string $overridePath The override location + * @param string $htmlPath The html location + * + * @return boolean True on success. False otherwise. + */ + public function createTemplateOverride($overridePath, $htmlPath) + { + $return = false; + + if (empty($overridePath) || empty($htmlPath)) + { + return $return; + } + + // Get list of template folders + $folders = Folder::folders($overridePath, null, true, true); + + if (!empty($folders)) + { + foreach ($folders as $folder) + { + $htmlFolder = $htmlPath . str_replace($overridePath, '', $folder); + + if (!Folder::exists($htmlFolder)) + { + Folder::create($htmlFolder); + } + } + } + + // Get list of template files (Only get *.php file for template file) + $files = Folder::files($overridePath, '.php', true, true); + + if (empty($files)) + { + return true; + } + + foreach ($files as $file) + { + $overrideFilePath = str_replace($overridePath, '', $file); + $htmlFilePath = $htmlPath . $overrideFilePath; + + if (File::exists($htmlFilePath)) + { + // Generate new unique file name base on current time + $today = Factory::getDate(); + $htmlFilePath = File::stripExt($htmlFilePath) . '-' . $today->format('Ymd-His') . '.' . File::getExt($htmlFilePath); + } + + $return = File::copy($file, $htmlFilePath, '', true); + } + + return $return; + } + + /** + * Delete a particular file. + * + * @param string $file The relative location of the file. + * + * @return boolean True if file deletion is successful, false otherwise + * + * @since 3.2 + */ + public function deleteFile($file) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $path = Path::clean($client->path . '/templates/' . $template->element . '/'); + $filePath = $path . urldecode(base64_decode($file)); + + $return = File::delete($filePath); + + if (!$return) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_DELETE_FAIL'), 'error'); + + return false; + } + + return true; + } + } + + /** + * Create new file. + * + * @param string $name The name of file. + * @param string $type The extension of the file. + * @param string $location Location for the new file. + * + * @return boolean true if file created successfully, false otherwise + * + * @since 3.2 + */ + public function createFile($name, $type, $location) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $path = Path::clean($client->path . '/templates/' . $template->element . '/'); + + if (file_exists(Path::clean($path . '/' . $location . '/' . $name . '.' . $type))) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); + + return false; + } + + if (!fopen(Path::clean($path . '/' . $location . '/' . $name . '.' . $type), 'x')) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_CREATE_ERROR'), 'error'); + + return false; + } + + // Check if the format is allowed and will be showed in the backend + $check = $this->checkFormat($type); + + // Add a message if we are not allowed to show this file in the backend. + if (!$check) + { + $app->enqueueMessage(Text::sprintf('COM_TEMPLATES_WARNING_FORMAT_WILL_NOT_BE_VISIBLE', $type), 'warning'); + } + + return true; + } + } + + /** + * Upload new file. + * + * @param string $file The name of the file. + * @param string $location Location for the new file. + * + * @return boolean True if file uploaded successfully, false otherwise + * + * @since 3.2 + */ + public function uploadFile($file, $location) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $path = Path::clean($client->path . '/templates/' . $template->element . '/'); + $fileName = File::makeSafe($file['name']); + + $err = null; + + if (!TemplateHelper::canUpload($file, $err)) + { + // Can't upload the file + return false; + } + + if (file_exists(Path::clean($path . '/' . $location . '/' . $file['name']))) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); + + return false; + } + + if (!File::upload($file['tmp_name'], Path::clean($path . '/' . $location . '/' . $fileName))) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_UPLOAD_ERROR'), 'error'); + + return false; + } + + $url = Path::clean($location . '/' . $fileName); + + return $url; + } + } + + /** + * Create new folder. + * + * @param string $name The name of the new folder. + * @param string $location Location for the new folder. + * + * @return boolean True if override folder is created successfully, false otherwise + * + * @since 3.2 + */ + public function createFolder($name, $location) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $path = Path::clean($client->path . '/templates/' . $template->element . '/'); + + if (file_exists(Path::clean($path . '/' . $location . '/' . $name . '/'))) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FOLDER_EXISTS'), 'error'); + + return false; + } + + if (!Folder::create(Path::clean($path . '/' . $location . '/' . $name))) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FOLDER_CREATE_ERROR'), 'error'); + + return false; + } + + return true; + } + } + + /** + * Delete a folder. + * + * @param string $location The name and location of the folder. + * + * @return boolean True if override folder is deleted successfully, false otherwise + * + * @since 3.2 + */ + public function deleteFolder($location) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $path = Path::clean($client->path . '/templates/' . $template->element . '/' . $location); + + if (!file_exists($path)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FOLDER_NOT_EXISTS'), 'error'); + + return false; + } + + $return = Folder::delete($path); + + if (!$return) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_DELETE_ERROR'), 'error'); + + return false; + } + + return true; + } + } + + /** + * Rename a file. + * + * @param string $file The name and location of the old file + * @param string $name The new name of the file. + * + * @return string Encoded string containing the new file location. + * + * @since 3.2 + */ + public function renameFile($file, $name) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $path = Path::clean($client->path . '/templates/' . $template->element . '/'); + $fileName = base64_decode($file); + $explodeArray = explode('.', $fileName); + $type = end($explodeArray); + $explodeArray = explode('/', $fileName); + $newName = str_replace(end($explodeArray), $name . '.' . $type, $fileName); + + if (file_exists($path . $newName)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); + + return false; + } + + if (!rename($path . $fileName, $path . $newName)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_RENAME_ERROR'), 'error'); + + return false; + } + + return base64_encode($newName); + } + } + + /** + * Get an image address, height and width. + * + * @return array an associative array containing image address, height and width. + * + * @since 3.2 + */ + public function getImage() + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $fileName = base64_decode($app->input->get('file')); + $path = Path::clean($client->path . '/templates/' . $template->element . '/'); + + if (stristr($client->path, 'administrator') == false) + { + $folder = '/templates/'; + } + else + { + $folder = '/administrator/templates/'; + } + + $uri = Uri::root(true) . $folder . $template->element; + + if (file_exists(Path::clean($path . $fileName))) + { + $JImage = new \JImage(Path::clean($path . $fileName)); + $image['address'] = $uri . $fileName; + $image['path'] = $fileName; + $image['height'] = $JImage->getHeight(); + $image['width'] = $JImage->getWidth(); + } + + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_IMAGE_FILE_NOT_FOUND'), 'error'); + + return false; + } + + return $image; + } + } + + /** + * Crop an image. + * + * @param string $file The name and location of the file + * @param string $w width. + * @param string $h height. + * @param string $x x-coordinate. + * @param string $y y-coordinate. + * + * @return boolean true if image cropped successfully, false otherwise. + * + * @since 3.2 + */ + public function cropImage($file, $w, $h, $x, $y) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($file); + $path = Path::clean($client->path . '/templates/' . $template->element . '/' . $relPath); + $JImage = new \JImage($path); + + try + { + $image = $JImage->crop($w, $h, $x, $y, true); + $image->toFile($path); + + return true; + } + catch (\Exception $e) + { + $app->enqueueMessage($e->getMessage(), 'error'); + } + } + } + + /** + * Resize an image. + * + * @param string $file The name and location of the file + * @param string $width The new width of the image. + * @param string $height The new height of the image. + * + * @return boolean true if image resize successful, false otherwise. + * + * @since 3.2 + */ + public function resizeImage($file, $width, $height) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($file); + $path = Path::clean($client->path . '/templates/' . $template->element . '/' . $relPath); + + $JImage = new \JImage($path); + + try + { + $image = $JImage->resize($width, $height, true, 1); + $image->toFile($path); + + return true; + } + catch (\Exception $e) + { + $app->enqueueMessage($e->getMessage(), 'error'); + } + } + } + + /** + * Template preview. + * + * @return object object containing the id of the template. + * + * @since 3.2 + */ + public function getPreview() + { + $app = Factory::getApplication(); + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query->select('id, client_id'); + $query->from('#__template_styles'); + $query->where($db->quoteName('template') . ' = ' . $db->quote($this->template->element)); + + $db->setQuery($query); + + try + { + $result = $db->loadObject(); + } + catch (\RuntimeException $e) + { + $app->enqueueMessage($e->getMessage(), 'warning'); + } + + if (empty($result)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND'), 'warning'); + } + else + { + return $result; + } + } + + /** + * Rename a file. + * + * @return mixed array on success, false on failure + * + * @since 3.2 + */ + public function getFont() + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($app->input->get('file')); + $explodeArray = explode('/', $relPath); + $fileName = end($explodeArray); + $path = Path::clean($client->path . '/templates/' . $template->element . '/' . $relPath); + + if (stristr($client->path, 'administrator') == false) + { + $folder = '/templates/'; + } + else + { + $folder = '/administrator/templates/'; + } + + $uri = Uri::root(true) . $folder . $template->element; + + if (file_exists(Path::clean($path))) + { + $font['address'] = $uri . $relPath; + + $font['rel_path'] = $relPath; + + $font['name'] = $fileName; + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_FONT_FILE_NOT_FOUND'), 'error'); + + return false; + } + + return $font; + } + } + + /** + * Copy a file. + * + * @param string $newName The name of the copied file + * @param string $location The final location where the file is to be copied + * @param string $file The name and location of the file + * + * @return boolean true if image resize successful, false otherwise. + * + * @since 3.2 + */ + public function copyFile($newName, $location, $file) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($file); + $explodeArray = explode('.', $relPath); + $ext = end($explodeArray); + $path = Path::clean($client->path . '/templates/' . $template->element . '/'); + $newPath = Path::clean($path . '/' . $location . '/' . $newName . '.' . $ext); + + if (file_exists($newPath)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); + + return false; + } + + if (File::copy($path . $relPath, $newPath)) + { + $app->enqueueMessage(Text::sprintf('COM_TEMPLATES_FILE_COPY_SUCCESS', $newName . '.' . $ext)); + + return true; + } + else + { + return false; + } + } + } + + /** + * Get the compressed files. + * + * @return array if file exists, false otherwise + * + * @since 3.2 + */ + public function getArchive() + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($app->input->get('file')); + $path = Path::clean($client->path . '/templates/' . $template->element . '/' . $relPath); + + if (file_exists(Path::clean($path))) + { + $files = array(); + $zip = new \ZipArchive; + + if ($zip->open($path) === true) + { + for ($i = 0; $i < $zip->numFiles; $i++) + { + $entry = $zip->getNameIndex($i); + $files[] = $entry; + } + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error'); + + return false; + } + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_FONT_FILE_NOT_FOUND'), 'error'); + + return false; + } + + return $files; + } + } + + /** + * Extract contents of an archive file. + * + * @param string $file The name and location of the file + * + * @return boolean true if image extraction is successful, false otherwise. + * + * @since 3.2 + */ + public function extractArchive($file) + { + if ($template = $this->getTemplate()) + { + $app = Factory::getApplication(); + $client = ApplicationHelper::getClientInfo($template->client_id); + $relPath = base64_decode($file); + $explodeArray = explode('/', $relPath); + $fileName = end($explodeArray); + $folderPath = stristr($relPath, $fileName, true); + $path = Path::clean($client->path . '/templates/' . $template->element . '/' . $folderPath . '/'); + + if (file_exists(Path::clean($path . '/' . $fileName))) + { + $zip = new \ZipArchive; + + if ($zip->open(Path::clean($path . '/' . $fileName)) === true) + { + for ($i = 0; $i < $zip->numFiles; $i++) + { + $entry = $zip->getNameIndex($i); + + if (file_exists(Path::clean($path . '/' . $entry))) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_EXISTS'), 'error'); + + return false; + } + } + + $zip->extractTo($path); + + return true; + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error'); + + return false; + } + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_FILE_ARCHIVE_NOT_FOUND'), 'error'); + + return false; + } + } + } + + /** + * 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)) + { + $params = ComponentHelper::getParams('com_templates'); + $imageTypes = explode(',', $params->get('image_formats')); + $sourceTypes = explode(',', $params->get('source_formats')); + $fontTypes = explode(',', $params->get('font_formats')); + $archiveTypes = explode(',', $params->get('compressed_formats')); + + $this->allowedFormats = array_merge($imageTypes, $sourceTypes, $fontTypes, $archiveTypes); + } + + return in_array($ext, $this->allowedFormats); + } +} diff --git a/administrator/components/com_templates/Model/TemplatesModel.php b/administrator/components/com_templates/Model/TemplatesModel.php new file mode 100644 index 0000000000000..da83eaea09512 --- /dev/null +++ b/administrator/components/com_templates/Model/TemplatesModel.php @@ -0,0 +1,172 @@ +client_id); + $item->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $item->element); + } + + return $items; + } + + /** + * Build an SQL query to load the list data. + * + * @return \JDatabaseQuery + * + * @since 1.6 + */ + 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.extension_id, a.name, a.element, a.client_id' + ) + ); + $query->from($db->quoteName('#__extensions', 'a')) + ->where($db->quoteName('a.client_id') . ' = ' . (int) $this->getState('client_id')) + ->where($db->quoteName('a.enabled') . ' = 1') + ->where($db->quoteName('a.type') . ' = ' . $db->quote('template')); + + // Filter by search in title. + if ($search = $this->getState('filter.search')) + { + if (stripos($search, 'id:') === 0) + { + $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . strtolower($search) . '%'); + $query->where('(' . ' LOWER(a.element) LIKE ' . $search . ' OR LOWER(a.name) LIKE ' . $search . ')'); + } + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.element')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + 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 A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('client_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 1.6 + */ + protected function populateState($ordering = 'a.element', $direction = 'asc') + { + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + + // Special case for the client id. + $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); + $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; + $this->setState('client_id', $clientId); + + // Load the parameters. + $params = ComponentHelper::getParams('com_templates'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } +} diff --git a/administrator/components/com_templates/Service/HTML/Templates.php b/administrator/components/com_templates/Service/HTML/Templates.php new file mode 100644 index 0000000000000..3f5bf0924418b --- /dev/null +++ b/administrator/components/com_templates/Service/HTML/Templates.php @@ -0,0 +1,100 @@ +path . '/templates/' . $template; + $thumb = $basePath . '/template_thumbnail.png'; + $preview = $basePath . '/template_preview.png'; + $html = ''; + + if (file_exists($thumb)) + { + $clientPath = ($clientId == 0) ? '' : 'administrator/'; + $thumb = $clientPath . 'templates/' . $template . '/template_thumbnail.png'; + $html = HTMLHelper::_('image', $thumb, Text::_('COM_TEMPLATES_PREVIEW')); + + if (file_exists($preview)) + { + $html = '' . $html . ''; + } + } + + return $html; + } + + /** + * Renders the html for the modal linked to thumb. + * + * @param string $template The name of the template. + * @param integer $clientId The application client ID the template applies to + * + * @return string The html string + * + * @since 3.4 + */ + public function thumbModal($template, $clientId = 0) + { + $client = ApplicationHelper::getClientInfo($clientId); + $basePath = $client->path . '/templates/' . $template; + $baseUrl = ($clientId == 0) ? Uri::root(true) : Uri::root(true) . '/administrator'; + $thumb = $basePath . '/template_thumbnail.png'; + $preview = $basePath . '/template_preview.png'; + $html = ''; + + if (file_exists($thumb) && file_exists($preview)) + { + $preview = $baseUrl . '/templates/' . $template . '/template_preview.png'; + $footer = ''; + + $html .= HTMLHelper::_( + 'bootstrap.renderModal', + $template . '-Modal', + array( + 'title' => Text::_('COM_TEMPLATES_BUTTON_PREVIEW'), + 'height' => '500px', + 'width' => '800px', + 'footer' => $footer, + ), + $body = '
    ' . $template . '
    ' + ); + } + + return $html; + } +} diff --git a/administrator/components/com_templates/Table/StyleTable.php b/administrator/components/com_templates/Table/StyleTable.php new file mode 100644 index 0000000000000..6f62445e56efd --- /dev/null +++ b/administrator/components/com_templates/Table/StyleTable.php @@ -0,0 +1,156 @@ +home == '1') + { + $this->setError(Text::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE')); + + return false; + } + + return parent::bind($array, $ignore); + } + + /** + * Overloaded check method to ensure data integrity. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function check() + { + try + { + parent::check(); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (empty($this->title)) + { + $this->setError(Text::_('COM_TEMPLATES_ERROR_STYLE_REQUIRES_TITLE')); + + return false; + } + + return true; + } + + /** + * Overloaded store method to ensure unicity of default style. + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function store($updateNulls = false) + { + if ($this->home != '0') + { + $query = $this->_db->getQuery(true) + ->update('#__template_styles') + ->set('home=\'0\'') + ->where('client_id=' . (int) $this->client_id) + ->where('home=' . $this->_db->quote($this->home)); + $this->_db->setQuery($query); + $this->_db->execute(); + } + + return parent::store($updateNulls); + } + + /** + * Overloaded store method to unsure existence of a default style for a template. + * + * @param mixed $pk An optional primary key value to delete. If not set the instance property value is used. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function delete($pk = null) + { + $k = $this->_tbl_key; + $pk = is_null($pk) ? $this->$k : $pk; + + if (!is_null($pk)) + { + $query = $this->_db->getQuery(true) + ->from('#__template_styles') + ->select('id') + ->where('client_id=' . (int) $this->client_id) + ->where('template=' . $this->_db->quote($this->template)); + $this->_db->setQuery($query); + $results = $this->_db->loadColumn(); + + if (count($results) == 1 && $results[0] == $pk) + { + $this->setError(Text::_('COM_TEMPLATES_ERROR_CANNOT_DELETE_LAST_STYLE')); + + return false; + } + } + + return parent::delete($pk); + } +} diff --git a/administrator/components/com_templates/View/Style/HtmlView.php b/administrator/components/com_templates/View/Style/HtmlView.php new file mode 100644 index 0000000000000..02a7c58779886 --- /dev/null +++ b/administrator/components/com_templates/View/Style/HtmlView.php @@ -0,0 +1,157 @@ +item = $this->get('Item'); + $this->state = $this->get('State'); + $this->form = $this->get('Form'); + $this->canDo = ContentHelper::getActions('com_templates'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + if ((!Multilanguage::isEnabled()) && ($this->item->client_id == 0)) + { + $this->form->setFieldAttribute('home', 'type', 'radio'); + $this->form->setFieldAttribute('home', 'class', 'switcher'); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $isNew = ($this->item->id == 0); + $canDo = $this->canDo; + + ToolbarHelper::title( + $isNew ? Text::_('COM_TEMPLATES_MANAGER_ADD_STYLE') + : Text::_('COM_TEMPLATES_MANAGER_EDIT_STYLE'), 'eye thememanager' + ); + + $toolbarButtons = []; + + // If not checked out, can save the item. + if ($canDo->get('core.edit')) + { + $toolbarButtons[] = ['apply', 'style.apply']; + $toolbarButtons[] = ['save', 'style.save']; + } + + // If an existing item, can save to a copy. + if (!$isNew && $canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'style.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (empty($this->item->id)) + { + ToolbarHelper::cancel('style.cancel'); + } + else + { + ToolbarHelper::cancel('style.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + + // Get the help information for the template item. + $lang = Factory::getLanguage(); + $help = $this->get('Help'); + + if ($lang->hasKey($help->url)) + { + $debug = $lang->setDebug(false); + $url = Text::_($help->url); + $lang->setDebug($debug); + } + else + { + $url = null; + } + + ToolbarHelper::help($help->key, false, $url); + } +} diff --git a/administrator/components/com_templates/View/Style/JsonView.php b/administrator/components/com_templates/View/Style/JsonView.php new file mode 100644 index 0000000000000..7ff7116d052f5 --- /dev/null +++ b/administrator/components/com_templates/View/Style/JsonView.php @@ -0,0 +1,76 @@ +item = $this->get('Item'); + } + catch (\Exception $e) + { + $app = Factory::getApplication(); + $app->enqueueMessage($e->getMessage(), 'error'); + + return false; + } + + $paramsList = $this->item->getProperties(); + + unset($paramsList['xml']); + + $paramsList = json_encode($paramsList); + + return $paramsList; + } +} diff --git a/administrator/components/com_templates/View/Styles/HtmlView.php b/administrator/components/com_templates/View/Styles/HtmlView.php new file mode 100644 index 0000000000000..6e75274c99512 --- /dev/null +++ b/administrator/components/com_templates/View/Styles/HtmlView.php @@ -0,0 +1,153 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->total = $this->get('Total'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->preview = ComponentHelper::getParams('com_templates')->get('template_positions_display'); + + TemplatesHelper::addSubmenu('styles'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = \JHtmlSidebar::render(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_templates'); + + // Set the title. + if ((int) $this->get('State')->get('client_id') === 1) + { + ToolbarHelper::title(Text::_('COM_TEMPLATES_MANAGER_STYLES_ADMIN'), 'eye thememanager'); + } + else + { + ToolbarHelper::title(Text::_('COM_TEMPLATES_MANAGER_STYLES_SITE'), 'eye thememanager'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::makeDefault('styles.setDefault', 'COM_TEMPLATES_TOOLBAR_SET_HOME'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.create')) + { + ToolbarHelper::custom('styles.duplicate', 'copy.png', 'copy_f2.png', 'JTOOLBAR_DUPLICATE', true); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'styles.delete', 'JTOOLBAR_DELETE'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_templates'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES'); + + \JHtmlSidebar::setAction('index.php?option=com_templates&view=styles'); + } +} diff --git a/administrator/components/com_templates/View/Template/HtmlView.php b/administrator/components/com_templates/View/Template/HtmlView.php new file mode 100644 index 0000000000000..ee7339b2e5ac2 --- /dev/null +++ b/administrator/components/com_templates/View/Template/HtmlView.php @@ -0,0 +1,332 @@ +file = $app->input->get('file'); + $this->fileName = InputFilter::getInstance()->clean(base64_decode($this->file), 'string'); + $explodeArray = explode('.', $this->fileName); + $ext = end($explodeArray); + $this->files = $this->get('Files'); + $this->state = $this->get('State'); + $this->template = $this->get('Template'); + $this->preview = $this->get('Preview'); + + $params = ComponentHelper::getParams('com_templates'); + $imageTypes = explode(',', $params->get('image_formats')); + $sourceTypes = explode(',', $params->get('source_formats')); + $fontTypes = explode(',', $params->get('font_formats')); + $archiveTypes = explode(',', $params->get('compressed_formats')); + + if (in_array($ext, $sourceTypes)) + { + $this->form = $this->get('Form'); + $this->form->setFieldAttribute('source', 'syntax', $ext); + $this->source = $this->get('Source'); + $this->type = 'file'; + } + elseif (in_array($ext, $imageTypes)) + { + $this->image = $this->get('Image'); + $this->type = 'image'; + } + elseif (in_array($ext, $fontTypes)) + { + $this->font = $this->get('Font'); + $this->type = 'font'; + } + elseif (in_array($ext, $archiveTypes)) + { + $this->archive = $this->get('Archive'); + $this->type = 'archive'; + } + else + { + $this->type = 'home'; + } + + $this->overridesList = $this->get('OverridesList'); + $this->id = $this->state->get('extension.id'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + $app->enqueueMessage(implode("\n", $errors)); + + return false; + } + + $this->addToolbar(); + + if (!Factory::getUser()->authorise('core.admin')) + { + $this->setLayout('readonly'); + } + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @since 1.6 + * + * @return void + */ + protected function addToolbar() + { + $app = Factory::getApplication(); + $user = Factory::getUser(); + $app->input->set('hidemainmenu', true); + + // User is global SuperUser + $isSuperUser = $user->authorise('core.admin'); + + // Get the toolbar object instance + $bar = Toolbar::getInstance('toolbar'); + $explodeArray = explode('.', $this->fileName); + $ext = end($explodeArray); + + ToolbarHelper::title(Text::sprintf('COM_TEMPLATES_MANAGER_VIEW_TEMPLATE', ucfirst($this->template->name)), 'eye thememanager'); + + // Only show file edit buttons for global SuperUser + if ($isSuperUser) + { + // Add an Apply and save button + if ($this->type == 'file') + { + ToolbarHelper::saveGroup( + [ + ['apply', 'template.apply'], + ['save', 'template.save'] + ], + 'btn-success' + ); + } + // Add a Crop and Resize button + elseif ($this->type == 'image') + { + ToolbarHelper::custom('template.cropImage', 'crop', 'move', 'COM_TEMPLATES_BUTTON_CROP', false); + ToolbarHelper::modal('resizeModal', 'icon-expand', 'COM_TEMPLATES_BUTTON_RESIZE'); + } + // Add an extract button + elseif ($this->type == 'archive') + { + ToolbarHelper::custom('template.extractArchive', 'arrow-down', 'arrow-down', 'COM_TEMPLATES_BUTTON_EXTRACT_ARCHIVE', false); + } + + // Add a copy template button + ToolbarHelper::modal('copyModal', 'icon-copy', 'COM_TEMPLATES_BUTTON_COPY_TEMPLATE'); + } + + // Add a Template preview button + if ($this->preview->client_id == 0) + { + $bar->appendButton('Popup', 'picture', 'COM_TEMPLATES_BUTTON_PREVIEW', Uri::root() . 'index.php?tp=1&templateStyle=' . $this->preview->id, 800, 520); + } + + // Only show file manage buttons for global SuperUser + if ($isSuperUser) + { + // Add Manage folders button + ToolbarHelper::modal('folderModal', 'icon-folder icon white', 'COM_TEMPLATES_BUTTON_FOLDERS'); + + // Add a new file button + ToolbarHelper::modal('fileModal', 'icon-file', 'COM_TEMPLATES_BUTTON_FILE'); + + // Add a Rename file Button + if ($this->type != 'home') + { + ToolbarHelper::modal('renameModal', 'icon-refresh', 'COM_TEMPLATES_BUTTON_RENAME_FILE'); + } + + // Add a Delete file Button + if ($this->type != 'home') + { + ToolbarHelper::modal('deleteModal', 'icon-remove', 'COM_TEMPLATES_BUTTON_DELETE_FILE'); + } + } + + if ($this->type == 'home') + { + ToolbarHelper::cancel('template.cancel', 'JTOOLBAR_CLOSE'); + } + else + { + ToolbarHelper::cancel('template.close', 'COM_TEMPLATES_BUTTON_CLOSE_FILE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT'); + } + + /** + * Method for creating the collapsible tree. + * + * @param array $array The value of the present node for recursion + * + * @return string + * + * @note Uses recursion + * @since 3.2 + */ + protected function directoryTree($array) + { + $temp = $this->files; + $this->files = $array; + $txt = $this->loadTemplate('tree'); + $this->files = $temp; + + return $txt; + } + + /** + * Method for listing the folder tree in modals. + * + * @param array $array The value of the present node for recursion + * + * @return string + * + * @note Uses recursion + * @since 3.2 + */ + protected function folderTree($array) + { + $temp = $this->files; + $this->files = $array; + $txt = $this->loadTemplate('folders'); + $this->files = $temp; + + return $txt; + } +} diff --git a/administrator/components/com_templates/View/Templates/HtmlView.php b/administrator/components/com_templates/View/Templates/HtmlView.php new file mode 100644 index 0000000000000..6cbe943572c22 --- /dev/null +++ b/administrator/components/com_templates/View/Templates/HtmlView.php @@ -0,0 +1,148 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->total = $this->get('Total'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + $this->preview = ComponentHelper::getParams('com_templates')->get('template_positions_display'); + $this->file = base64_encode('home'); + + TemplatesHelper::addSubmenu('templates'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_templates'); + + // Set the title. + if ((int) $this->get('State')->get('client_id') === 1) + { + ToolbarHelper::title(Text::_('COM_TEMPLATES_MANAGER_TEMPLATES_ADMIN'), 'eye thememanager'); + } + else + { + ToolbarHelper::title(Text::_('COM_TEMPLATES_MANAGER_TEMPLATES_SITE'), 'eye thememanager'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_templates'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES'); + + \JHtmlSidebar::setAction('index.php?option=com_templates&view=templates'); + + $this->sidebar = \JHtmlSidebar::render(); + } +} diff --git a/administrator/components/com_templates/access.xml b/administrator/components/com_templates/access.xml index 085a53d701b5d..d75ace4004f7a 100644 --- a/administrator/components/com_templates/access.xml +++ b/administrator/components/com_templates/access.xml @@ -1,12 +1,12 @@
    - - - - - - - + + + + + + +
    diff --git a/administrator/components/com_templates/config.xml b/administrator/components/com_templates/config.xml index dbf6c01629694..a977f69f9baf4 100644 --- a/administrator/components/com_templates/config.xml +++ b/administrator/components/com_templates/config.xml @@ -9,19 +9,17 @@ name="template_positions_display" type="radio" label="COM_TEMPLATES_CONFIG_POSITIONS_LABEL" - description="COM_TEMPLATES_CONFIG_POSITIONS_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="0" > - + @@ -30,7 +28,6 @@ name="warning" type="note" label="COM_TEMPLATES_CONFIG_SUPPORTED_LABEL" - description="COM_TEMPLATES_CONFIG_SUPPORTED_DESC" default="zip" extension="com_templates" /> @@ -39,7 +36,6 @@ name="image_formats" type="text" label="COM_TEMPLATES_CONFIG_IMAGE_LABEL" - description="COM_TEMPLATES_CONFIG_IMAGE_DESC" default="gif,bmp,jpg,jpeg" extension="com_templates" /> @@ -48,7 +44,6 @@ name="source_formats" type="text" label="COM_TEMPLATES_CONFIG_SOURCE_LABEL" - description="COM_TEMPLATES_CONFIG_SOURCE_DESC" default="txt,less,ini,xml,js,php,css,sass,scss" extension="com_templates" /> @@ -57,7 +52,6 @@ name="font_formats" type="text" label="COM_TEMPLATES_CONFIG_FONT_LABEL" - description="COM_TEMPLATES_CONFIG_FONT_DESC" default="woff,ttf,otf" extension="com_templates" /> diff --git a/administrator/components/com_templates/controller.php b/administrator/components/com_templates/controller.php deleted file mode 100644 index a8cc5f7d5a3b3..0000000000000 --- a/administrator/components/com_templates/controller.php +++ /dev/null @@ -1,75 +0,0 @@ -input->get('view', 'styles'); - $layout = $this->input->get('layout', 'default'); - $id = $this->input->getInt('id'); - - $document = JFactory::getDocument(); - - // For JSON requests - if ($document->getType() == 'json') - { - $view = new TemplatesViewStyle; - - // Get/Create the model - if ($model = new TemplatesModelStyle) - { - $model->addTablePath(JPATH_ADMINISTRATOR . '/components/com_templates/tables'); - - // Push the model into the view (as default) - $view->setModel($model, true); - } - - $view->document = $document; - - return $view->display(); - } - - // Check for edit form. - if ($view == 'style' && $layout == 'edit' && !$this->checkEditId('com_templates.edit.style', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_templates&view=styles', false)); - - return false; - } - - return parent::display(); - } -} diff --git a/administrator/components/com_templates/controllers/style.php b/administrator/components/com_templates/controllers/style.php deleted file mode 100644 index e114480fdead9..0000000000000 --- a/administrator/components/com_templates/controllers/style.php +++ /dev/null @@ -1,160 +0,0 @@ -redirect('index.php', JText::_('JINVALID_TOKEN')); - } - - $document = JFactory::getDocument(); - - if ($document->getType() === 'json') - { - $app = JFactory::getApplication(); - $lang = JFactory::getLanguage(); - $model = $this->getModel(); - $table = $model->getTable(); - $data = $this->input->post->get('params', array(), 'array'); - $checkin = property_exists($table, 'checked_out'); - $context = $this->option . '.edit.' . $this->context; - $task = $this->getTask(); - - $item = $model->getItem($app->getTemplate(true)->id); - - // Setting received params - $item->set('params', $data); - - $data = $item->getProperties(); - unset($data['xml']); - - $key = $table->getKeyName(); - - // Access check. - if (!$this->allowSave($data, $key)) - { - $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); - - return false; - } - - JForm::addFormPath(JPATH_ADMINISTRATOR . '/components/com_templates/models/forms'); - - // Validate the posted data. - // Sometimes the form needs some posted data, such as for plugins and modules. - $form = $model->getForm($data, false); - - if (!$form) - { - $app->enqueueMessage($model->getError(), 'error'); - - return false; - } - - // Test whether the data is valid. - $validData = $model->validate($form, $data); - - if ($validData === false) - { - // Get the validation messages. - $errors = $model->getErrors(); - - // 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) - { - $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); - } - else - { - $app->enqueueMessage($errors[$i], 'warning'); - } - } - - // Save the data in the session. - $app->setUserState($context . '.data', $data); - - return false; - } - - if (!isset($validData['tags'])) - { - $validData['tags'] = null; - } - - // Attempt to save the data. - if (!$model->save($validData)) - { - // Save the data in the session. - $app->setUserState($context . '.data', $validData); - - $app->enqueueMessage(JText::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); - - return false; - } - - // Save succeeded, so check-in the record. - if ($checkin && $model->checkin($validData[$key]) === false) - { - // Save the data in the session. - $app->setUserState($context . '.data', $validData); - - // Check-in failed, so go back to the record and display a notice. - $app->enqueueMessage(JText::sprintf('JLIB_APPLICATION_ERROR_CHECKIN_FAILED', $model->getError()), 'error'); - - return false; - } - - // Redirect the user and adjust session state - // Set the record data in the session. - $recordId = $model->getState($this->context . '.id'); - $this->holdEditId($context, $recordId); - $app->setUserState($context . '.data', null); - $model->checkout($recordId); - - // Invoke the postSave method to allow for the child class to access the model. - $this->postSaveHook($model, $validData); - - return true; - } - else - { - parent::save($key, $urlVar); - } - } -} diff --git a/administrator/components/com_templates/controllers/styles.php b/administrator/components/com_templates/controllers/styles.php deleted file mode 100644 index eca41c9731921..0000000000000 --- a/administrator/components/com_templates/controllers/styles.php +++ /dev/null @@ -1,142 +0,0 @@ -input->post->get('cid', array(), 'array'); - - try - { - if (empty($pks)) - { - throw new Exception(JText::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED')); - } - - $pks = ArrayHelper::toInteger($pks); - - $model = $this->getModel(); - $model->duplicate($pks); - $this->setMessage(JText::_('COM_TEMPLATES_SUCCESS_DUPLICATED')); - } - catch (Exception $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - $this->setRedirect('index.php?option=com_templates&view=styles'); - } - - /** - * Proxy for getModel. - * - * @param string $name The model name. Optional. - * @param string $prefix The class prefix. Optional. - * @param array $config Configuration array for model. Optional. - * - * @return JModelLegacy - * - * @since 1.6 - */ - public function getModel($name = 'Style', $prefix = 'TemplatesModel', $config = array()) - { - return parent::getModel($name, $prefix, array('ignore_request' => true)); - } - - /** - * Method to set the home template for a client. - * - * @return void - * - * @since 1.6 - */ - public function setDefault() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $pks = $this->input->post->get('cid', array(), 'array'); - - try - { - if (empty($pks)) - { - throw new Exception(JText::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED')); - } - - $pks = ArrayHelper::toInteger($pks); - - // Pop off the first element. - $id = array_shift($pks); - $model = $this->getModel(); - $model->setHome($id); - $this->setMessage(JText::_('COM_TEMPLATES_SUCCESS_HOME_SET')); - } - catch (Exception $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - $this->setRedirect('index.php?option=com_templates&view=styles'); - } - - /** - * Method to unset the default template for a client and for a language - * - * @return void - * - * @since 1.6 - */ - public function unsetDefault() - { - // Check for request forgeries - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); - - $pks = $this->input->get->get('cid', array(), 'array'); - $pks = ArrayHelper::toInteger($pks); - - try - { - if (empty($pks)) - { - throw new Exception(JText::_('COM_TEMPLATES_NO_TEMPLATE_SELECTED')); - } - - // Pop off the first element. - $id = array_shift($pks); - $model = $this->getModel(); - $model->unsetHome($id); - $this->setMessage(JText::_('COM_TEMPLATES_SUCCESS_HOME_UNSET')); - } - catch (Exception $e) - { - JError::raiseWarning(500, $e->getMessage()); - } - - $this->setRedirect('index.php?option=com_templates&view=styles'); - } -} diff --git a/administrator/components/com_templates/controllers/template.php b/administrator/components/com_templates/controllers/template.php deleted file mode 100644 index ed6951178b0d0..0000000000000 --- a/administrator/components/com_templates/controllers/template.php +++ /dev/null @@ -1,749 +0,0 @@ -registerTask('apply', 'save'); - } - - /** - * Method for closing the template. - * - * @return void - * - * @since 3.2 - */ - public function cancel() - { - $this->setRedirect(JRoute::_('index.php?option=com_templates&view=templates', false)); - } - - /** - * Method for closing a file. - * - * @return void - * - * @since 3.2 - */ - public function close() - { - $app = JFactory::getApplication(); - $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)); - } - - /** - * Method for copying the template. - * - * @return boolean true on success, false otherwise - * - * @since 3.2 - */ - public function copy() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $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'); - - $this->setRedirect('index.php?option=com_templates&view=template&id=' . $templateID . '&file=' . $file); - $model = $this->getModel('Template', 'TemplatesModel'); - $model->setState('new_name', $newName); - $model->setState('tmp_prefix', uniqid('template_copy_')); - $model->setState('to_path', JFactory::getConfig()->get('tmp_path') . '/' . $model->getState('tmp_prefix')); - - // Process only if we have a new name entered - if (strlen($newName) > 0) - { - if (!JFactory::getUser()->authorise('core.create', 'com_templates')) - { - // User is not authorised to delete - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED'), 'error'); - - return false; - } - - // Set FTP credentials, if given - JClientHelper::setCredentialsFromRequest('ftp'); - - // Check that new name is valid - if (($newNameRaw !== null) && ($newName !== $newNameRaw)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error'); - - return false; - } - - // Check that new name doesn't already exist - if (!$model->checkNewName()) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_DUPLICATE_TEMPLATE_NAME'), 'error'); - - return false; - } - - // Check that from name does exist and get the folder name - $fromName = $model->getFromName(); - - if (!$fromName) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); - - return false; - } - - // Call model's copy method - if (!$model->copy()) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_COULD_NOT_COPY'), 'error'); - - return false; - } - - // Call installation model - $this->input->set('install_directory', JFactory::getConfig()->get('tmp_path') . '/' . $model->getState('tmp_prefix')); - $installModel = $this->getModel('Install', 'InstallerModel'); - JFactory::getLanguage()->load('com_installer'); - - if (!$installModel->install()) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_COULD_NOT_INSTALL'), 'error'); - - return false; - } - - $this->setMessage(JText::sprintf('COM_TEMPLATES_COPY_SUCCESS', $newName)); - $model->cleanup(); - - return true; - } - } - - /** - * 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 (note, the empty array is atypical compared to other models). - * - * @return JModelLegacy The model. - * - * @since 3.2 - */ - public function getModel($name = 'Template', $prefix = 'TemplatesModel', $config = array()) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Method to check if you can add a new record. - * - * @return boolean - * - * @since 3.2 - */ - 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(); - } - - /** - * Saves a template source file. - * - * @return void - * - * @since 3.2 - */ - public function save() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $data = $this->input->post->get('jform', array(), 'array'); - $task = $this->getTask(); - $model = $this->getModel(); - $fileName = $app->input->get('file'); - $explodeArray = explode(':', base64_decode($fileName)); - - // Access check. - if (!$this->allowSave()) - { - $app->enqueueMessage(JText::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); - - return false; - } - - // Match the stored id's with the submitted. - if (empty($data['extension_id']) || empty($data['filename'])) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); - - return false; - } - elseif ($data['extension_id'] != $model->getState('extension.id')) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); - - return false; - } - elseif ($data['filename'] != end($explodeArray)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_ID_FILENAME_MISMATCH'), 'error'); - - return false; - } - - // Validate the posted data. - $form = $model->getForm(); - - if (!$form) - { - $app->enqueueMessage($model->getError(), 'error'); - - return false; - } - - $data = $model->validate($form, $data); - - // Check for validation errors. - if ($data === false) - { - // Get the validation messages. - $errors = $model->getErrors(); - - // 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) - { - $app->enqueueMessage($errors[$i]->getMessage(), 'warning'); - } - else - { - $app->enqueueMessage($errors[$i], 'warning'); - } - } - - // 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)); - - return false; - } - - // Attempt to save the data. - if (!$model->save($data)) - { - // Redirect back to the edit screen. - $this->setMessage(JText::sprintf('JERROR_SAVE_FAILED', $model->getError()), 'warning'); - $url = 'index.php?option=com_templates&view=template&id=' . $model->getState('extension.id') . '&file=' . $fileName; - $this->setRedirect(JRoute::_($url, false)); - - return false; - } - - $this->setMessage(JText::_('COM_TEMPLATES_FILE_SAVE_SUCCESS')); - - // 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; - - 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; - } - } - - /** - * Method for creating override. - * - * @return void - * - * @since 3.2 - */ - public function overrides() - { - $app = JFactory::getApplication(); - $model = $this->getModel(); - $file = $app->input->get('file'); - $override = base64_decode($app->input->get('folder')); - $id = $app->input->get('id'); - - if ($model->createOverride($override)) - { - $this->setMessage(JText::_('COM_TEMPLATES_OVERRIDE_SUCCESS')); - } - - // Redirect back to the edit screen. - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - - /** - * Method for compiling LESS. - * - * @return void - * - * @since 3.2 - */ - public function less() - { - $app = JFactory::getApplication(); - $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - - if ($model->compileLess($file)) - { - $this->setMessage(JText::_('COM_TEMPLATES_COMPILE_SUCCESS')); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_COMPILE_ERROR'), 'error'); - } - - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - - /** - * Method for deleting a file. - * - * @return void - * - * @since 3.2 - */ - public function delete() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - - 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; - $this->setRedirect(JRoute::_($url, false)); - } - - elseif ($model->deleteFile($file)) - { - $this->setMessage(JText::_('COM_TEMPLATES_FILE_DELETE_SUCCESS')); - $file = base64_encode('home'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FILE_DELETE'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } - - /** - * Method for creating a new file. - * - * @return void - * - * @since 3.2 - */ - public function createFile() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $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'); - - if ($type == 'null') - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FILE_TYPE'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - elseif (!preg_match('/^[a-zA-Z0-9-_]+$/', $name)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - elseif ($model->createFile($name, $type, $location)) - { - $this->setMessage(JText::_('COM_TEMPLATES_FILE_CREATE_SUCCESS')); - $file = urlencode(base64_encode($location . '/' . $name . '.' . $type)); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FILE_CREATE'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } - - /** - * Method for uploading a file. - * - * @return void - * - * @since 3.2 - */ - public function uploadFile() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - $upload = $app->input->files->get('files'); - $location = base64_decode($app->input->get('address')); - - if ($return = $model->uploadFile($upload, $location)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_UPLOAD_SUCCESS') . $upload['name']); - $redirect = base64_encode($return); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $redirect; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FILE_UPLOAD'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } - - /** - * Method for creating a new folder. - * - * @return void - * - * @since 3.2 - */ - public function createFolder() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $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')); - - if (!preg_match('/^[a-zA-Z0-9-_.]+$/', $name)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FOLDER_NAME'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - elseif ($model->createFolder($name, $location)) - { - $this->setMessage(JText::_('COM_TEMPLATES_FOLDER_CREATE_SUCCESS')); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FOLDER_CREATE'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } - - /** - * Method for deleting a folder. - * - * @return void - * - * @since 3.2 - */ - public function deleteFolder() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - $location = base64_decode($app->input->get('address')); - - if (empty($location)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_ROOT_DELETE'), 'warning'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - elseif ($model->deleteFolder($location)) - { - $this->setMessage(JText::_('COM_TEMPLATES_FOLDER_DELETE_SUCCESS')); - - if (stristr(base64_decode($file), $location) != false) - { - $file = base64_encode('home'); - } - - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_DELETE_ERROR'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } - - /** - * Method for renaming a file. - * - * @return void - * - * @since 3.2 - */ - public function renameFile() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $model = $this->getModel(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - $newName = $app->input->get('new_name'); - - 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; - $this->setRedirect(JRoute::_($url, false)); - } - elseif (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - elseif ($rename = $model->renameFile($file, $newName)) - { - $this->setMessage(JText::_('COM_TEMPLATES_FILE_RENAME_SUCCESS')); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $rename; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FILE_RENAME'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } - - /** - * Method for cropping an image. - * - * @return void - * - * @since 3.2 - */ - public function cropImage() - { - $app = JFactory::getApplication(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - $x = $app->input->get('x'); - $y = $app->input->get('y'); - $w = $app->input->get('w'); - $h = $app->input->get('h'); - $model = $this->getModel(); - - if (empty($w) && empty($h) && empty($x) && empty($y)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_CROP_AREA_ERROR'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - elseif ($model->cropImage($file, $w, $h, $x, $y)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_CROP_SUCCESS')); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_CROP_ERROR'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } - - /** - * Method for resizing an image. - * - * @return void - * - * @since 3.2 - */ - public function resizeImage() - { - $app = JFactory::getApplication(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - $width = $app->input->get('width'); - $height = $app->input->get('height'); - $model = $this->getModel(); - - if ($model->resizeImage($file, $width, $height)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_RESIZE_SUCCESS')); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_RESIZE_ERROR'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } - - /** - * Method for copying a file. - * - * @return void - * - * @since 3.2 - */ - public function copyFile() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - $newName = $app->input->get('new_name'); - $location = base64_decode($app->input->get('address')); - $model = $this->getModel(); - - if (!preg_match('/^[a-zA-Z0-9-_]+$/', $newName)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_INVALID_FILE_NAME'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - elseif ($model->copyFile($newName, $location, $file)) - { - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_COPY_FAIL'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } - - /** - * Method for extracting an archive file. - * - * @return void - * - * @since 3.2 - */ - public function extractArchive() - { - // Check for request forgeries - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $app = JFactory::getApplication(); - $id = $app->input->get('id'); - $file = $app->input->get('file'); - $model = $this->getModel(); - - if ($model->extractArchive($file)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_SUCCESS')); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_EXTRACT_FAIL'), 'error'); - $url = 'index.php?option=com_templates&view=template&id=' . $id . '&file=' . $file; - $this->setRedirect(JRoute::_($url, false)); - } - } -} diff --git a/administrator/components/com_templates/models/forms/filter_styles.xml b/administrator/components/com_templates/forms/filter_styles.xml similarity index 87% rename from administrator/components/com_templates/models/forms/filter_styles.xml rename to administrator/components/com_templates/forms/filter_styles.xml index 1578ff8020dc2..159b9158a2d3c 100644 --- a/administrator/components/com_templates/models/forms/filter_styles.xml +++ b/administrator/components/com_templates/forms/filter_styles.xml @@ -1,6 +1,5 @@ -
    -
    + @@ -60,9 +56,6 @@ diff --git a/administrator/components/com_templates/models/forms/filter_templates.xml b/administrator/components/com_templates/forms/filter_templates.xml similarity index 82% rename from administrator/components/com_templates/models/forms/filter_templates.xml rename to administrator/components/com_templates/forms/filter_templates.xml index 7a4c190b0afac..dbbe0af1398a5 100644 --- a/administrator/components/com_templates/models/forms/filter_templates.xml +++ b/administrator/components/com_templates/forms/filter_templates.xml @@ -1,6 +1,5 @@ -
    @@ -36,9 +33,6 @@ diff --git a/administrator/components/com_templates/models/forms/source.xml b/administrator/components/com_templates/forms/source.xml similarity index 89% rename from administrator/components/com_templates/models/forms/source.xml rename to administrator/components/com_templates/forms/source.xml index 5aadea8d7d2ef..823841544041f 100644 --- a/administrator/components/com_templates/models/forms/source.xml +++ b/administrator/components/com_templates/forms/source.xml @@ -15,7 +15,6 @@ name="source" type="editor" label="COM_TEMPLATES_FIELD_SOURCE_LABEL" - description="COM_TEMPLATES_FIELD_SOURCE_DESC" editor="codemirror|none" buttons="no" height="500px" diff --git a/administrator/components/com_templates/models/forms/style.xml b/administrator/components/com_templates/forms/style.xml similarity index 75% rename from administrator/components/com_templates/models/forms/style.xml rename to administrator/components/com_templates/forms/style.xml index 897efc18dcd74..c8a3f158040ef 100644 --- a/administrator/components/com_templates/models/forms/style.xml +++ b/administrator/components/com_templates/forms/style.xml @@ -5,7 +5,6 @@ name="id" type="number" label="JGLOBAL_FIELD_ID_LABEL" - description="JGLOBAL_FIELD_ID_DESC" id="id" default="0" readonly="true" @@ -16,7 +15,6 @@ name="template" type="text" label="COM_TEMPLATES_FIELD_TEMPLATE_LABEL" - description="COM_TEMPLATES_FIELD_TEMPLATE_DESC" class="readonly" size="30" readonly="true" @@ -26,7 +24,6 @@ name="client_id" type="hidden" label="COM_TEMPLATES_FIELD_CLIENT_LABEL" - description="COM_TEMPLATES_FIELD_CLIENT_DESC" class="readonly" default="0" readonly="true" @@ -36,8 +33,7 @@ name="title" type="text" label="COM_TEMPLATES_FIELD_TITLE_LABEL" - description="COM_TEMPLATES_FIELD_TITLE_DESC" - class="input-xxlarge input-large-text" + class="input-xxlarge" size="50" required="true" /> diff --git a/administrator/components/com_templates/forms/style_administrator.xml b/administrator/components/com_templates/forms/style_administrator.xml new file mode 100644 index 0000000000000..14391b21bbd38 --- /dev/null +++ b/administrator/components/com_templates/forms/style_administrator.xml @@ -0,0 +1,15 @@ + + +
    + + + + +
    + diff --git a/administrator/components/com_templates/models/forms/style_site.xml b/administrator/components/com_templates/forms/style_site.xml similarity index 83% rename from administrator/components/com_templates/models/forms/style_site.xml rename to administrator/components/com_templates/forms/style_site.xml index d30c7809e4224..a2945d6474019 100644 --- a/administrator/components/com_templates/models/forms/style_site.xml +++ b/administrator/components/com_templates/forms/style_site.xml @@ -5,7 +5,6 @@ name="home" type="contentlanguage" label="COM_TEMPLATES_FIELD_HOME_LABEL" - description="COM_TEMPLATES_FIELD_HOME_SITE_DESC" default="0" > diff --git a/administrator/components/com_templates/helpers/html/templates.php b/administrator/components/com_templates/helpers/html/templates.php deleted file mode 100644 index 97a7e251a7309..0000000000000 --- a/administrator/components/com_templates/helpers/html/templates.php +++ /dev/null @@ -1,98 +0,0 @@ -path . '/templates/' . $template; - $thumb = $basePath . '/template_thumbnail.png'; - $preview = $basePath . '/template_preview.png'; - $html = ''; - - if (file_exists($thumb)) - { - JHtml::_('bootstrap.tooltip'); - - $clientPath = ($clientId == 0) ? '' : 'administrator/'; - $thumb = $clientPath . 'templates/' . $template . '/template_thumbnail.png'; - $html = JHtml::_('image', $thumb, JText::_('COM_TEMPLATES_PREVIEW')); - - if (file_exists($preview)) - { - $html = '' . $html . ''; - } - } - - return $html; - } - - /** - * Renders the html for the modal linked to thumb. - * - * @param string $template The name of the template. - * @param integer $clientId The application client ID the template applies to - * - * @return string The html string - * - * @since 3.4 - */ - public static function thumbModal($template, $clientId = 0) - { - $client = JApplicationHelper::getClientInfo($clientId); - $basePath = $client->path . '/templates/' . $template; - $baseUrl = ($clientId == 0) ? JUri::root(true) : JUri::root(true) . '/administrator'; - $thumb = $basePath . '/template_thumbnail.png'; - $preview = $basePath . '/template_preview.png'; - $html = ''; - - if (file_exists($thumb)) - { - if (file_exists($preview)) - { - $preview = $baseUrl . '/templates/' . $template . '/template_preview.png'; - $footer = ''; - - $html .= JHtml::_( - 'bootstrap.renderModal', - $template . '-Modal', - array( - 'title' => JText::_('COM_TEMPLATES_BUTTON_PREVIEW'), - 'height' => '500px', - 'width' => '800px', - 'footer' => $footer, - ), - $body = '
    ' . $template . '
    ' - ); - } - } - - return $html; - } -} diff --git a/administrator/components/com_templates/helpers/template.php b/administrator/components/com_templates/helpers/template.php index 89b98753aab5b..9fc818fc9e784 100644 --- a/administrator/components/com_templates/helpers/template.php +++ b/administrator/components/com_templates/helpers/template.php @@ -12,167 +12,10 @@ /** * Template Helper class. * - * @since 3.2 + * @since 3.2 + * + * @deprecated 5.0 Use \Joomla\Component\Templates\Administrator\Helper\TemplateHelper instead */ -abstract class TemplateHelper +abstract class TemplateHelper extends \Joomla\Component\Templates\Administrator\Helper\TemplateHelper { - /** - * Checks if the file is an image - * - * @param string $fileName The filename - * - * @return boolean - * - * @since 3.2 - */ - public static function getTypeIcon($fileName) - { - // Get file extension - return strtolower(substr($fileName, strrpos($fileName, '.') + 1)); - } - - /** - * Checks if the file can be uploaded - * - * @param array $file File information - * @param string $err An error message to be returned - * - * @return boolean - * - * @since 3.2 - */ - public static function canUpload($file, $err = '') - { - $params = JComponentHelper::getParams('com_templates'); - - if (empty($file['name'])) - { - $app = JFactory::getApplication(); - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_UPLOAD_INPUT'), 'error'); - - return false; - } - - // Media file names should never have executable extensions buried in them. - $executable = array( - 'exe', 'phtml','java', 'perl', 'py', 'asp','dll', 'go', 'jar', - 'ade', 'adp', 'bat', 'chm', 'cmd', 'com', 'cpl', 'hta', 'ins', 'isp', - 'jse', 'lib', 'mde', 'msc', 'msp', 'mst', 'pif', 'scr', 'sct', 'shb', - 'sys', 'vb', 'vbe', 'vbs', 'vxd', 'wsc', 'wsf', 'wsh' - ); - $explodedFileName = explode('.', $file['name']); - - if (count($explodedFileName) > 2) - { - foreach ($executable as $extensionName) - { - if (in_array($extensionName, $explodedFileName)) - { - $app = JFactory::getApplication(); - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EXECUTABLE'), 'error'); - - return false; - } - } - } - - jimport('joomla.filesystem.file'); - - if ($file['name'] !== JFile::makeSafe($file['name']) || preg_match('/\s/', JFile::makeSafe($file['name']))) - { - $app = JFactory::getApplication(); - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNFILENAME'), 'error'); - - return false; - } - - $format = strtolower(JFile::getExt($file['name'])); - - $imageTypes = explode(',', $params->get('image_formats')); - $sourceTypes = explode(',', $params->get('source_formats')); - $fontTypes = explode(',', $params->get('font_formats')); - $archiveTypes = explode(',', $params->get('compressed_formats')); - - $allowable = array_merge($imageTypes, $sourceTypes, $fontTypes, $archiveTypes); - - if ($format == '' || $format == false || (!in_array($format, $allowable))) - { - $app = JFactory::getApplication(); - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNFILETYPE'), 'error'); - - return false; - } - - if (in_array($format, $archiveTypes)) - { - $zip = new ZipArchive; - - if ($zip->open($file['tmp_name']) === true) - { - for ($i = 0; $i < $zip->numFiles; $i++) - { - $entry = $zip->getNameIndex($i); - $endString = substr($entry, -1); - - if ($endString != DIRECTORY_SEPARATOR) - { - $explodeArray = explode('.', $entry); - $ext = end($explodeArray); - - if (!in_array($ext, $allowable)) - { - $app = JFactory::getApplication(); - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_UNSUPPORTED_ARCHIVE'), 'error'); - - return false; - } - } - } - } - else - { - $app = JFactory::getApplication(); - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error'); - - return false; - } - } - - // Max upload size set to 2 MB for Template Manager - $maxSize = (int) ($params->get('upload_limit') * 1024 * 1024); - - if ($maxSize > 0 && (int) $file['size'] > $maxSize) - { - $app = JFactory::getApplication(); - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNFILETOOLARGE'), 'error'); - - return false; - } - - $xss_check = file_get_contents($file['tmp_name'], false, null, -1, 256); - $html_tags = array( - 'abbr', 'acronym', 'address', 'applet', 'area', 'audioscope', 'base', 'basefont', 'bdo', 'bgsound', 'big', 'blackface', 'blink', 'blockquote', - 'body', 'bq', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'comment', 'custom', 'dd', 'del', 'dfn', 'dir', 'div', - 'dl', 'dt', 'em', 'embed', 'fieldset', 'fn', 'font', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', - 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'keygen', 'kbd', 'label', 'layer', 'legend', 'li', 'limittext', 'link', 'listing', - 'map', 'marquee', 'menu', 'meta', 'multicol', 'nobr', 'noembed', 'noframes', 'noscript', 'nosmartquotes', 'object', 'ol', 'optgroup', 'option', - 'param', 'plaintext', 'pre', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'server', 'shadow', 'sidebar', 'small', 'spacer', 'span', 'strike', - 'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt', 'ul', 'var', 'wbr', 'xml', - 'xmp', '!DOCTYPE', '!--' - ); - - foreach ($html_tags as $tag) - { - // A tag is '' - if (stristr($xss_check, '<' . $tag . ' ') || stristr($xss_check, '<' . $tag . '>')) - { - $app = JFactory::getApplication(); - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_WARNIEXSS'), 'error'); - - return false; - } - } - - return true; - } } diff --git a/administrator/components/com_templates/helpers/templates.php b/administrator/components/com_templates/helpers/templates.php index e24bb662bd230..8bd618a2d5b52 100644 --- a/administrator/components/com_templates/helpers/templates.php +++ b/administrator/components/com_templates/helpers/templates.php @@ -12,189 +12,10 @@ /** * Templates component helper. * - * @since 1.6 + * @since 1.6 + * + * @deprecated 5.0 Use \Joomla\Component\Templates\Administrator\Helper\TemplatesHelper instead */ -class TemplatesHelper +class TemplatesHelper extends \Joomla\Component\Templates\Administrator\Helper\TemplatesHelper { - /** - * Configure the Linkbar. - * - * @param string $vName The name of the active view. - * - * @return void - */ - public static function addSubmenu($vName) - { - JHtmlSidebar::addEntry( - JText::_('COM_TEMPLATES_SUBMENU_STYLES'), - 'index.php?option=com_templates&view=styles', - $vName == 'styles' - ); - JHtmlSidebar::addEntry( - JText::_('COM_TEMPLATES_SUBMENU_TEMPLATES'), - 'index.php?option=com_templates&view=templates', - $vName == 'templates' - ); - } - - /** - * Gets a list of the actions that can be performed. - * - * @return JObject - * - * @deprecated 3.2 Use JHelperContent::getActions() instead - */ - public static function getActions() - { - // Log usage of deprecated function - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Get list of actions - return JHelperContent::getActions('com_templates'); - } - - /** - * Get a list of filter options for the application clients. - * - * @return array An array of JHtmlOption elements. - */ - public static function getClientOptions() - { - // Build the filter options. - $options = array(); - $options[] = JHtml::_('select.option', '0', JText::_('JSITE')); - $options[] = JHtml::_('select.option', '1', JText::_('JADMINISTRATOR')); - - return $options; - } - - /** - * Get a list of filter options for the templates with styles. - * - * @param mixed $clientId The CMS client id (0:site | 1:administrator) or '*' for all. - * - * @return array An array of JHtmlOption elements. - */ - public static function getTemplateOptions($clientId = '*') - { - // Build the filter options. - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - $query->select($db->quoteName('element', 'value')) - ->select($db->quoteName('name', 'text')) - ->select($db->quoteName('extension_id', 'e_id')) - ->from($db->quoteName('#__extensions')) - ->where($db->quoteName('type') . ' = ' . $db->quote('template')) - ->where($db->quoteName('enabled') . ' = 1') - ->order($db->quoteName('client_id') . ' ASC') - ->order($db->quoteName('name') . ' ASC'); - - if ($clientId != '*') - { - $query->where($db->quoteName('client_id') . ' = ' . (int) $clientId); - } - - $db->setQuery($query); - $options = $db->loadObjectList(); - - return $options; - } - - /** - * TODO - * - * @param string $templateBaseDir TODO - * @param string $templateDir TODO - * - * @return boolean|JObject - */ - public static function parseXMLTemplateFile($templateBaseDir, $templateDir) - { - $data = new JObject; - - // Check of the xml file exists - $filePath = JPath::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml'); - - if (is_file($filePath)) - { - $xml = JInstaller::parseXMLInstallFile($filePath); - - if ($xml['type'] != 'template') - { - return false; - } - - foreach ($xml as $key => $value) - { - $data->set($key, $value); - } - } - - return $data; - } - - /** - * TODO - * - * @param integer $clientId TODO - * @param string $templateDir TODO - * - * @return boolean|array - * - * @since 3.0 - */ - public static function getPositions($clientId, $templateDir) - { - $positions = array(); - - $templateBaseDir = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; - $filePath = JPath::clean($templateBaseDir . '/templates/' . $templateDir . '/templateDetails.xml'); - - if (is_file($filePath)) - { - // Read the file to see if it's a valid component XML file - $xml = simplexml_load_file($filePath); - - if (!$xml) - { - return false; - } - - // Check for a valid XML root tag. - - // Extensions use 'extension' as the root tag. Languages use 'metafile' instead - - if ($xml->getName() != 'extension' && $xml->getName() != 'metafile') - { - unset($xml); - - return false; - } - - $positions = (array) $xml->positions; - - if (isset($positions['position'])) - { - $positions = (array) $positions['position']; - } - else - { - $positions = array(); - } - } - - return $positions; - } } diff --git a/administrator/components/com_templates/models/fields/templatelocation.php b/administrator/components/com_templates/models/fields/templatelocation.php deleted file mode 100644 index 8db12707af91e..0000000000000 --- a/administrator/components/com_templates/models/fields/templatelocation.php +++ /dev/null @@ -1,44 +0,0 @@ -getUserStateFromRequest('com_templates.styles.client_id', 'client_id', '0', 'string'); - - // Get the templates for the selected client_id. - $options = TemplatesHelper::getTemplateOptions($clientId); - - // Merge into the parent options. - return array_merge(parent::getOptions(), $options); - } -} diff --git a/administrator/components/com_templates/models/forms/style_administrator.xml b/administrator/components/com_templates/models/forms/style_administrator.xml deleted file mode 100644 index 219d381b90673..0000000000000 --- a/administrator/components/com_templates/models/forms/style_administrator.xml +++ /dev/null @@ -1,16 +0,0 @@ - -
    -
    - - - - -
    -
    diff --git a/administrator/components/com_templates/models/style.php b/administrator/components/com_templates/models/style.php deleted file mode 100644 index ff12a70470f49..0000000000000 --- a/administrator/components/com_templates/models/style.php +++ /dev/null @@ -1,729 +0,0 @@ - 'onExtensionBeforeDelete', - 'event_after_delete' => 'onExtensionAfterDelete', - 'event_before_save' => 'onExtensionBeforeSave', - 'event_after_save' => 'onExtensionAfterSave', - 'events_map' => array('delete' => 'extension', 'save' => 'extension') - ), $config - ); - - parent::__construct($config); - } - - /** - * Method to auto-populate the model state. - * - * @note Calling getState in this method will result in recursion. - * - * @return void - * - * @since 1.6 - */ - protected function populateState() - { - $app = JFactory::getApplication('administrator'); - - // Load the User state. - $pk = $app->input->getInt('id'); - $this->setState('style.id', $pk); - - // Load the parameters. - $params = JComponentHelper::getParams('com_templates'); - $this->setState('params', $params); - } - - /** - * Method to delete rows. - * - * @param array &$pks An array of item ids. - * - * @return boolean Returns true on success, false on failure. - * - * @since 1.6 - * @throws Exception - */ - public function delete(&$pks) - { - $pks = (array) $pks; - $user = JFactory::getUser(); - $table = $this->getTable(); - $dispatcher = JEventDispatcher::getInstance(); - $context = $this->option . '.' . $this->name; - - JPluginHelper::importPlugin($this->events_map['delete']); - - // Iterate the items to delete each one. - foreach ($pks as $pk) - { - if ($table->load($pk)) - { - // Access checks. - if (!$user->authorise('core.delete', 'com_templates')) - { - throw new Exception(JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); - } - - // You should not delete a default style - if ($table->home != '0') - { - JError::raiseWarning(500, JText::_('COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE')); - - return false; - } - - // Trigger the before delete event. - $result = $dispatcher->trigger($this->event_before_delete, array($context, $table)); - - if (in_array(false, $result, true) || !$table->delete($pk)) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the after delete event. - $dispatcher->trigger($this->event_after_delete, array($context, $table)); - } - else - { - $this->setError($table->getError()); - - return false; - } - } - - // Clean cache - $this->cleanCache(); - - return true; - } - - /** - * Method to duplicate styles. - * - * @param array &$pks An array of primary key IDs. - * - * @return boolean True if successful. - * - * @throws Exception - */ - public function duplicate(&$pks) - { - $user = JFactory::getUser(); - - // Access checks. - if (!$user->authorise('core.create', 'com_templates')) - { - throw new Exception(JText::_('JERROR_CORE_CREATE_NOT_PERMITTED')); - } - - $dispatcher = JEventDispatcher::getInstance(); - $context = $this->option . '.' . $this->name; - - // Include the plugins for the save events. - JPluginHelper::importPlugin($this->events_map['save']); - - $table = $this->getTable(); - - foreach ($pks as $pk) - { - if ($table->load($pk, true)) - { - // Reset the id to create a new record. - $table->id = 0; - - // Reset the home (don't want dupes of that field). - $table->home = 0; - - // Alter the title. - $m = null; - $table->title = $this->generateNewTitle(null, null, $table->title); - - if (!$table->check()) - { - throw new Exception($table->getError()); - } - - // Trigger the before save event. - $result = $dispatcher->trigger($this->event_before_save, array($context, &$table, true)); - - if (in_array(false, $result, true) || !$table->store()) - { - throw new Exception($table->getError()); - } - - // Trigger the after save event. - $dispatcher->trigger($this->event_after_save, array($context, &$table, true)); - } - else - { - throw new Exception($table->getError()); - } - } - - // Clean cache - $this->cleanCache(); - - return true; - } - - /** - * Method to change the title. - * - * @param integer $category_id 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) - { - // Alter the title - $table = $this->getTable(); - - while ($table->load(array('title' => $title))) - { - $title = StringHelper::increment($title); - } - - return $title; - } - - /** - * Method to get the record form. - * - * @param array $data An optional array of data for the form to interogate. - * @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 - * - * @since 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - // The folder and element vars are passed when saving the form. - if (empty($data)) - { - $item = $this->getItem(); - $clientId = $item->client_id; - $template = $item->template; - } - else - { - $clientId = ArrayHelper::getValue($data, 'client_id'); - $template = ArrayHelper::getValue($data, 'template'); - } - - // Add the default fields directory - $baseFolder = $clientId ? JPATH_ADMINISTRATOR : JPATH_SITE; - JForm::addFieldPath($baseFolder . '/templates/' . $template . '/field'); - - // These variables are used to add data from the plugin XML files. - $this->setState('item.client_id', $clientId); - $this->setState('item.template', $template); - - // Get the form. - $form = $this->loadForm('com_templates.style', 'style', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - // Modify the form based on access controls. - if (!$this->canEditState((object) $data)) - { - // Disable fields for display. - $form->setFieldAttribute('home', 'disabled', 'true'); - - // Disable fields while saving. - // The controller has already verified this is a record you can edit. - $form->setFieldAttribute('home', 'filter', 'unset'); - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_templates.edit.style.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - $this->preprocessData('com_templates.style', $data); - - return $data; - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - */ - public function getItem($pk = null) - { - $pk = (!empty($pk)) ? $pk : (int) $this->getState('style.id'); - - if (!isset($this->_cache[$pk])) - { - // Get a row instance. - $table = $this->getTable(); - - // Attempt to load the row. - $return = $table->load($pk); - - // Check for a table object error. - if ($return === false && $table->getError()) - { - $this->setError($table->getError()); - - return false; - } - - // Convert to the JObject before adding other data. - $properties = $table->getProperties(1); - $this->_cache[$pk] = ArrayHelper::toObject($properties, 'JObject'); - - // Convert the params field to an array. - $registry = new Registry($table->params); - $this->_cache[$pk]->params = $registry->toArray(); - - // Get the template XML. - $client = JApplicationHelper::getClientInfo($table->client_id); - $path = JPath::clean($client->path . '/templates/' . $table->template . '/templateDetails.xml'); - - if (file_exists($path)) - { - $this->_cache[$pk]->xml = simplexml_load_file($path); - } - else - { - $this->_cache[$pk]->xml = null; - } - } - - return $this->_cache[$pk]; - } - - /** - * Returns a reference to the a Table object, always creating it. - * - * @param type $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 - */ - public function getTable($type = 'Style', $prefix = 'TemplatesTable', $config = array()) - { - return JTable::getInstance($type, $prefix, $config); - } - - /** - * Method to allow derived classes to preprocess the form. - * - * @param JForm $form A JForm object. - * @param mixed $data The data expected for the form. - * @param string $group The name of the plugin group to import (defaults to "content"). - * - * @return void - * - * @since 1.6 - * @throws Exception if there is an error in the form event. - */ - protected function preprocessForm(JForm $form, $data, $group = 'content') - { - $clientId = $this->getState('item.client_id'); - $template = $this->getState('item.template'); - $lang = JFactory::getLanguage(); - $client = JApplicationHelper::getClientInfo($clientId); - - if (!$form->loadFile('style_' . $client->name, true)) - { - throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); - } - - jimport('joomla.filesystem.path'); - - $formFile = JPath::clean($client->path . '/templates/' . $template . '/templateDetails.xml'); - - // Load the core and/or local language file(s). - $lang->load('tpl_' . $template, $client->path, null, false, true) - || $lang->load('tpl_' . $template, $client->path . '/templates/' . $template, null, false, true); - - if (file_exists($formFile)) - { - // Get the template form. - if (!$form->loadFile($formFile, false, '//config')) - { - throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); - } - } - - // 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')) - { - $form->setFieldAttribute('home', 'readonly', 'true'); - } - - // Attempt to load the xml file. - if (!$xml = simplexml_load_file($formFile)) - { - throw new Exception(JText::_('JERROR_LOADFILE_FAILED')); - } - - // Get the help data from the XML file if present. - $help = $xml->xpath('/extension/help'); - - if (!empty($help)) - { - $helpKey = trim((string) $help[0]['key']); - $helpURL = trim((string) $help[0]['url']); - - $this->helpKey = $helpKey ?: $this->helpKey; - $this->helpURL = $helpURL ?: $this->helpURL; - } - - // Trigger the default form events. - parent::preprocessForm($form, $data, $group); - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - */ - public function save($data) - { - // Detect disabled extension - $extension = JTable::getInstance('Extension'); - - if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $data['template'], 'client_id' => $data['client_id']))) - { - $this->setError(JText::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE')); - - return false; - } - - $app = JFactory::getApplication(); - $dispatcher = JEventDispatcher::getInstance(); - $table = $this->getTable(); - $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('style.id'); - $isNew = true; - - // Include the extension plugins for the save events. - JPluginHelper::importPlugin($this->events_map['save']); - - // Load the row if saving an existing record. - if ($pk > 0) - { - $table->load($pk); - $isNew = false; - } - - if ($app->input->get('task') == 'save2copy') - { - $data['title'] = $this->generateNewTitle(null, null, $data['title']); - $data['home'] = 0; - $data['assigned'] = ''; - } - - // Bind the data. - if (!$table->bind($data)) - { - $this->setError($table->getError()); - - return false; - } - - // Prepare the row for saving - $this->prepareTable($table); - - // Check the data. - if (!$table->check()) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the before save event. - $result = $dispatcher->trigger($this->event_before_save, array('com_templates.style', &$table, $isNew)); - - // Store the data. - if (in_array(false, $result, true) || !$table->store()) - { - $this->setError($table->getError()); - - return false; - } - - $user = JFactory::getUser(); - - if ($user->authorise('core.edit', 'com_menus') && $table->client_id == 0) - { - $n = 0; - $db = $this->getDbo(); - $user = JFactory::getUser(); - - if (!empty($data['assigned']) && is_array($data['assigned'])) - { - $data['assigned'] = ArrayHelper::toInteger($data['assigned']); - - // Update the mapping for menu items that this style IS assigned to. - $query = $db->getQuery(true) - ->update('#__menu') - ->set('template_style_id = ' . (int) $table->id) - ->where('id IN (' . implode(',', $data['assigned']) . ')') - ->where('template_style_id != ' . (int) $table->id) - ->where('checked_out IN (0,' . (int) $user->id . ')'); - $db->setQuery($query); - $db->execute(); - $n += $db->getAffectedRows(); - } - - // Remove style mappings for menu items this style is NOT assigned to. - // If unassigned then all existing maps will be removed. - $query = $db->getQuery(true) - ->update('#__menu') - ->set('template_style_id = 0'); - - if (!empty($data['assigned'])) - { - $query->where('id NOT IN (' . implode(',', $data['assigned']) . ')'); - } - - $query->where('template_style_id = ' . (int) $table->id) - ->where('checked_out IN (0,' . (int) $user->id . ')'); - $db->setQuery($query); - $db->execute(); - - $n += $db->getAffectedRows(); - - if ($n > 0) - { - $app->enqueueMessage(JText::plural('COM_TEMPLATES_MENU_CHANGED', $n)); - } - } - - // Clean the cache. - $this->cleanCache(); - - // Trigger the after save event. - $dispatcher->trigger($this->event_after_save, array('com_templates.style', &$table, $isNew)); - - $this->setState('style.id', $table->id); - - return true; - } - - /** - * Method to set a template style as home. - * - * @param integer $id The primary key ID for the style. - * - * @return boolean True if successful. - * - * @throws Exception - */ - public function setHome($id = 0) - { - $user = JFactory::getUser(); - $db = $this->getDbo(); - - // Access checks. - if (!$user->authorise('core.edit.state', 'com_templates')) - { - throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - } - - $style = JTable::getInstance('Style', 'TemplatesTable'); - - if (!$style->load((int) $id)) - { - throw new Exception(JText::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND')); - } - - // Detect disabled extension - $extension = JTable::getInstance('Extension'); - - if ($extension->load(array('enabled' => 0, 'type' => 'template', 'element' => $style->template, 'client_id' => $style->client_id))) - { - throw new Exception(JText::_('COM_TEMPLATES_ERROR_SAVE_DISABLED_TEMPLATE')); - } - - // Reset the home fields for the client_id. - $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. - $query = $db->getQuery(true) - ->update('#__template_styles') - ->set('home = ' . $db->q('1')) - ->where('id = ' . (int) $id); - $db->setQuery($query); - $db->execute(); - - // Clean the cache. - $this->cleanCache(); - - return true; - } - - /** - * Method to unset a template style as default for a language. - * - * @param integer $id The primary key ID for the style. - * - * @return boolean True if successful. - * - * @throws Exception - */ - public function unsetHome($id = 0) - { - $user = JFactory::getUser(); - $db = $this->getDbo(); - - // Access checks. - if (!$user->authorise('core.edit.state', 'com_templates')) - { - throw new Exception(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - } - - // Lookup the client_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)) - { - throw new Exception(JText::_('COM_TEMPLATES_ERROR_STYLE_NOT_FOUND')); - } - elseif ($style->home == '1') - { - throw new Exception(JText::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE')); - } - - // Set the new home style. - $query = $db->getQuery(true) - ->update('#__template_styles') - ->set('home = ' . $db->q('0')) - ->where('id = ' . (int) $id); - $db->setQuery($query); - $db->execute(); - - // Clean the cache. - $this->cleanCache(); - - return true; - } - - /** - * Get the necessary data to load an item help screen. - * - * @return object An object with key, url, and local properties for loading the item help screen. - * - * @since 1.6 - */ - public function getHelp() - { - return (object) array('key' => $this->helpKey, 'url' => $this->helpURL); - } - - /** - * Custom clean cache method - * - * @param string $group The cache group - * @param integer $client_id The ID of the client - * - * @return void - * - * @since 1.6 - */ - protected function cleanCache($group = null, $client_id = 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 deleted file mode 100644 index e00b16792adea..0000000000000 --- a/administrator/components/com_templates/models/styles.php +++ /dev/null @@ -1,199 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.template', $this->getUserStateFromRequest($this->context . '.filter.template', 'filter_template', '', 'string')); - $this->setState('filter.menuitem', $this->getUserStateFromRequest($this->context . '.filter.menuitem', 'filter_menuitem', '', 'cmd')); - - // Special case for the client id. - $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); - $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; - $this->setState('client_id', $clientId); - - // Load the parameters. - $params = JComponentHelper::getParams('com_templates'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('client_id'); - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.template'); - $id .= ':' . $this->getState('filter.menuitem'); - - return parent::getStoreId($id); - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - */ - protected function getListQuery() - { - $clientId = (int) $this->getState('client_id'); - - // 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.id, a.template, a.title, a.home, a.client_id, l.title AS language_title, l.image as image, l.sef AS language_sef' - ) - ); - $query->from($db->quoteName('#__template_styles', 'a')) - ->where($db->quoteName('a.client_id') . ' = ' . $clientId); - - // Join on menus. - $query->select('COUNT(m.template_style_id) AS assigned') - ->join('LEFT', $db->quoteName('#__menu', 'm') . ' ON ' . $db->quoteName('m.template_style_id') . ' = ' . $db->quoteName('a.id')) - ->group('a.id, a.template, a.title, a.home, a.client_id, l.title, l.image, e.extension_id, l.sef'); - - // Join over the language. - $query->join('LEFT', $db->quoteName('#__languages', 'l') . ' ON ' . $db->quoteName('l.lang_code') . ' = ' . $db->quoteName('a.home')); - - // Filter by extension enabled. - $query->select($db->quoteName('extension_id', 'e_id')) - ->join('LEFT', $db->quoteName('#__extensions', 'e') . ' ON e.element = a.template AND e.client_id = a.client_id') - ->where($db->quoteName('e.enabled') . ' = 1') - ->where($db->quoteName('e.type') . ' = ' . $db->quote('template')); - - // Filter by template. - if ($template = $this->getState('filter.template')) - { - $query->where($db->quoteName('a.template') . ' = ' . $db->quote($template)); - } - - // Filter by menuitem. - $menuItemId = $this->getState('filter.menuitem'); - - if ($clientId === 0 && is_numeric($menuItemId)) - { - // If user selected the templates styles that are not assigned to any page. - if ((int) $menuItemId === -1) - { - // Only custom template styles overrides not assigned to any menu item. - $query->where($db->quoteName('a.home') . ' = ' . $db->quote(0)) - ->where($db->quoteName('m.id') . ' IS NULL'); - } - // If user selected the templates styles assigned to particular pages. - else - { - // Subquery to get the language of the selected menu item. - $menuItemLanguageSubQuery = $db->getQuery(true); - $menuItemLanguageSubQuery->select($db->quoteName('language')) - ->from($db->quoteName('#__menu')) - ->where($db->quoteName('id') . ' = ' . $menuItemId); - - // Subquery to get the language of the selected menu item. - $templateStylesMenuItemsSubQuery = $db->getQuery(true); - $templateStylesMenuItemsSubQuery->select($db->quoteName('id')) - ->from($db->quoteName('#__menu')) - ->where($db->quoteName('template_style_id') . ' = ' . $db->quoteName('a.id')); - - // Main query where clause. - $query->where('(' . - // Default template style (fallback template style to all menu items). - $db->quoteName('a.home') . ' = ' . $db->quote(1) . ' OR ' . - // Default template style for specific language (fallback template style to the selected menu item language). - $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 . '))' . - ')' - ); - } - } - - // Filter by search in title. - if ($search = $this->getState('filter.search')) - { - if (stripos($search, 'id:') === 0) - { - $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); - } - else - { - $search = $db->quote('%' . strtolower($search) . '%'); - $query->where('(' . ' LOWER(a.template) LIKE ' . $search . ' OR LOWER(a.title) LIKE ' . $search . ')'); - } - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.template')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - return $query; - } -} diff --git a/administrator/components/com_templates/models/template.php b/administrator/components/com_templates/models/template.php deleted file mode 100644 index 3a7c36bf6b271..0000000000000 --- a/administrator/components/com_templates/models/template.php +++ /dev/null @@ -1,1451 +0,0 @@ -getTemplate()) - { - $temp->name = $name; - $temp->id = urlencode(base64_encode($path . $name)); - - return $temp; - } - } - - /** - * Method to get a list of all the files to edit in a template. - * - * @return array A nested array of relevant files. - * - * @since 1.6 - */ - public function getFiles() - { - $result = array(); - - if ($template = $this->getTemplate()) - { - jimport('joomla.filesystem.folder'); - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); - $lang = JFactory::getLanguage(); - - // Load the core and/or local language file(s). - $lang->load('tpl_' . $template->element, $client->path, null, false, true) || - $lang->load('tpl_' . $template->element, $client->path . '/templates/' . $template->element, null, false, true); - $this->element = $path; - - if (!is_writable($path)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_DIRECTORY_NOT_WRITABLE'), 'error'); - } - - if (is_dir($path)) - { - $result = $this->getDirectoryTree($path); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_TEMPLATE_FOLDER_NOT_FOUND'), 'error'); - - return false; - } - } - - return $result; - } - - /** - * Get the directory tree. - * - * @param string $dir The path of the directory to scan - * - * @return array - * - * @since 3.2 - */ - public function getDirectoryTree($dir) - { - $result = array(); - - $dirFiles = scandir($dir); - - foreach ($dirFiles as $key => $value) - { - if (!in_array($value, array('.', '..'))) - { - if (is_dir($dir . $value)) - { - $relativePath = str_replace($this->element, '', $dir . $value); - $result['/' . $relativePath] = $this->getDirectoryTree($dir . $value . '/'); - } - else - { - $ext = pathinfo($dir . $value, PATHINFO_EXTENSION); - $allowedFormat = $this->checkFormat($ext); - - if ($allowedFormat == true) - { - $relativePath = str_replace($this->element, '', $dir); - $info = $this->getFile('/' . $relativePath, $value); - $result[] = $info; - } - } - } - } - - return $result; - } - - /** - * Method to auto-populate the model state. - * - * Note. Calling getState in this method will result in recursion. - * - * @return void - * - * @since 1.6 - */ - protected function populateState() - { - jimport('joomla.filesystem.file'); - $app = JFactory::getApplication('administrator'); - - // Load the User state. - $pk = $app->input->getInt('id'); - $this->setState('extension.id', $pk); - - // Load the parameters. - $params = JComponentHelper::getParams('com_templates'); - $this->setState('params', $params); - } - - /** - * Method to get the template information. - * - * @return mixed Object if successful, false if not and internal error is set. - * - * @since 1.6 - */ - public function &getTemplate() - { - if (empty($this->template)) - { - $pk = $this->getState('extension.id'); - $db = $this->getDbo(); - $app = JFactory::getApplication(); - - // Get the template information. - $query = $db->getQuery(true) - ->select('extension_id, client_id, element, name, manifest_cache') - ->from('#__extensions') - ->where($db->quoteName('extension_id') . ' = ' . (int) $pk) - ->where($db->quoteName('type') . ' = ' . $db->quote('template')); - $db->setQuery($query); - - try - { - $result = $db->loadObject(); - } - catch (RuntimeException $e) - { - $app->enqueueMessage($e->getMessage(), 'warning'); - $this->template = false; - - return false; - } - - if (empty($result)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND'), 'error'); - $this->template = false; - } - else - { - $this->template = $result; - } - } - - return $this->template; - } - - /** - * Method to check if new template name already exists - * - * @return boolean true if name is not used, false otherwise - * - * @since 2.5 - */ - public function checkNewName() - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('COUNT(*)') - ->from('#__extensions') - ->where('name = ' . $db->quote($this->getState('new_name'))); - $db->setQuery($query); - - return ($db->loadResult() == 0); - } - - /** - * Method to check if new template name already exists - * - * @return string name of current template - * - * @since 2.5 - */ - public function getFromName() - { - return $this->getTemplate()->element; - } - - /** - * Method to check if new template name already exists - * - * @return boolean true if name is not used, false otherwise - * - * @since 2.5 - */ - public function copy() - { - $app = JFactory::getApplication(); - - if ($template = $this->getTemplate()) - { - jimport('joomla.filesystem.folder'); - $client = JApplicationHelper::getClientInfo($template->client_id); - $fromPath = JPath::clean($client->path . '/templates/' . $template->element . '/'); - - // Delete new folder if it exists - $toPath = $this->getState('to_path'); - - if (JFolder::exists($toPath)) - { - if (!JFolder::delete($toPath)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_COULD_NOT_WRITE'), 'error'); - - return false; - } - } - - // Copy all files from $fromName template to $newName folder - if (!JFolder::copy($fromPath, $toPath) || !$this->fixTemplateName()) - { - return false; - } - - return true; - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); - - return false; - } - } - - /** - * Method to delete tmp folder - * - * @return boolean true if delete successful, false otherwise - * - * @since 2.5 - */ - public function cleanup() - { - // Clear installation messages - $app = JFactory::getApplication(); - $app->setUserState('com_installer.message', ''); - $app->setUserState('com_installer.extension_message', ''); - - // Delete temporary directory - return JFolder::delete($this->getState('to_path')); - } - - /** - * Method to rename the template in the XML files and rename the language files - * - * @return boolean true if successful, false otherwise - * - * @since 2.5 - */ - protected function fixTemplateName() - { - // Rename Language files - // Get list of language files - $result = true; - $files = JFolder::files($this->getState('to_path'), '.ini', true, true); - $newName = strtolower($this->getState('new_name')); - $template = $this->getTemplate(); - $oldName = $template->element; - $manifest = json_decode($template->manifest_cache); - - jimport('joomla.filesystem.file'); - - foreach ($files as $file) - { - $newFile = str_replace($oldName, $newName, $file); - $result = JFile::move($file, $newFile) && $result; - } - - // Edit XML file - $xmlFile = $this->getState('to_path') . '/templateDetails.xml'; - - if (JFile::exists($xmlFile)) - { - $contents = file_get_contents($xmlFile); - $pattern[] = '#\s*' . $manifest->name . '\s*#i'; - $replace[] = '' . $newName . ''; - $pattern[] = '##'; - $replace[] = ''; - $contents = preg_replace($pattern, $replace, $contents); - $result = JFile::write($xmlFile, $contents) && $result; - } - - return $result; - } - - /** - * Method to get the record form. - * - * @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 A JForm object on success, false on failure - * - * @since 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - $app = JFactory::getApplication(); - - // Codemirror or Editor None should be enabled - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('COUNT(*)') - ->from('#__extensions as a') - ->where( - '(a.name =' . $db->quote('plg_editors_codemirror') . - ' AND a.enabled = 1) OR (a.name =' . - $db->quote('plg_editors_none') . - ' AND a.enabled = 1)' - ); - $db->setQuery($query); - $state = $db->loadResult(); - - if ((int) $state < 1) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EDITOR_DISABLED'), 'warning'); - } - - // Get the form. - $form = $this->loadForm('com_templates.source', 'source', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - $data = $this->getSource(); - - $this->preprocessData('com_templates.source', $data); - - return $data; - } - - /** - * Method to get a single record. - * - * @return mixed Object on success, false on failure. - * - * @since 1.6 - */ - public function &getSource() - { - $app = JFactory::getApplication(); - $item = new stdClass; - - if (!$this->template) - { - $this->getTemplate(); - } - - if ($this->template) - { - $input = JFactory::getApplication()->input; - $fileName = base64_decode($input->get('file')); - $client = JApplicationHelper::getClientInfo($this->template->client_id); - - try - { - $filePath = JPath::check($client->path . '/templates/' . $this->template->element . '/' . $fileName); - } - catch (Exception $e) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_FOUND'), 'error'); - - return; - } - - if (file_exists($filePath)) - { - $item->extension_id = $this->getState('extension.id'); - $item->filename = $fileName; - $item->source = file_get_contents($filePath); - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_FOUND'), 'error'); - } - } - - return $item; - } - - /** - * Method to store the source file contents. - * - * @param array $data The source data to save. - * - * @return boolean True on success, false otherwise and internal error set. - * - * @since 1.6 - */ - public function save($data) - { - jimport('joomla.filesystem.file'); - - // Get the template. - $template = $this->getTemplate(); - - if (empty($template)) - { - return false; - } - - $app = JFactory::getApplication(); - $fileName = base64_decode($app->input->get('file')); - $client = JApplicationHelper::getClientInfo($template->client_id); - $filePath = JPath::clean($client->path . '/templates/' . $template->element . '/' . $fileName); - - // Include the extension plugins for the save events. - JPluginHelper::importPlugin('extension'); - - $user = get_current_user(); - chown($filePath, $user); - JPath::setPermissions($filePath, '0644'); - - // Try to make the template file writable. - if (!is_writable($filePath)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_WRITABLE'), 'warning'); - $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_FILE_PERMISSIONS', JPath::getPermissions($filePath)), 'warning'); - - if (!JPath::isOwner($filePath)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_CHECK_FILE_OWNERSHIP'), 'warning'); - } - - return false; - } - - // Make sure EOL is Unix - $data['source'] = str_replace(array("\r\n", "\r"), "\n", $data['source']); - - $return = JFile::write($filePath, $data['source']); - - if (!$return) - { - $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_ERROR_FAILED_TO_SAVE_FILENAME', $fileName), 'error'); - - return false; - } - - // Get the extension of the changed file. - $explodeArray = explode('.', $fileName); - $ext = end($explodeArray); - - if ($ext == 'less') - { - $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_COMPILE_LESS', $fileName)); - } - - return true; - } - - /** - * Get overrides folder. - * - * @param string $name The name of override. - * @param string $path Location of override. - * - * @return object containing override name and path. - * - * @since 3.2 - */ - public function getOverridesFolder($name,$path) - { - $folder = new stdClass; - $folder->name = $name; - $folder->path = base64_encode($path . $name); - - return $folder; - } - - /** - * Get a list of overrides. - * - * @return array containing overrides. - * - * @since 3.2 - */ - public function getOverridesList() - { - if ($template = $this->getTemplate()) - { - $client = JApplicationHelper::getClientInfo($template->client_id); - $componentPath = JPath::clean($client->path . '/components/'); - $modulePath = JPath::clean($client->path . '/modules/'); - $layoutPath = JPath::clean(JPATH_ROOT . '/layouts/'); - $components = JFolder::folders($componentPath); - - foreach ($components as $component) - { - if (file_exists($componentPath . '/' . $component . '/views/')) - { - $viewPath = JPath::clean($componentPath . '/' . $component . '/views/'); - } - elseif (file_exists($componentPath . '/' . $component . '/view/')) - { - $viewPath = JPath::clean($componentPath . '/' . $component . '/view/'); - } - else - { - $viewPath = ''; - } - - if ($viewPath) - { - $views = JFolder::folders($viewPath); - - foreach ($views as $view) - { - // Only show the view has layout inside it - if (file_exists($viewPath . $view . '/tmpl')) - { - $result['components'][$component][] = $this->getOverridesFolder($view, $viewPath); - } - } - } - } - - $modules = JFolder::folders($modulePath); - - foreach ($modules as $module) - { - $result['modules'][] = $this->getOverridesFolder($module, $modulePath); - } - - $layoutFolders = JFolder::folders($layoutPath); - - foreach ($layoutFolders as $layoutFolder) - { - $layoutFolderPath = JPath::clean($layoutPath . '/' . $layoutFolder . '/'); - $layouts = JFolder::folders($layoutFolderPath); - - foreach ($layouts as $layout) - { - $result['layouts'][$layoutFolder][] = $this->getOverridesFolder($layout, $layoutFolderPath); - } - } - - // Check for layouts in component folders - foreach ($components as $component) - { - if (file_exists($componentPath . '/' . $component . '/layouts/')) - { - $componentLayoutPath = JPath::clean($componentPath . '/' . $component . '/layouts/'); - - if ($componentLayoutPath) - { - $layouts = JFolder::folders($componentLayoutPath); - - foreach ($layouts as $layout) - { - $result['layouts'][$component][] = $this->getOverridesFolder($layout, $componentLayoutPath); - } - } - } - } - } - - if (!empty($result)) - { - return $result; - } - } - - /** - * Create overrides. - * - * @param string $override The override location. - * - * @return boolean true if override creation is successful, false otherwise - * - * @since 3.2 - */ - public function createOverride($override) - { - jimport('joomla.filesystem.folder'); - - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $explodeArray = explode(DIRECTORY_SEPARATOR, $override); - $name = end($explodeArray); - $client = JApplicationHelper::getClientInfo($template->client_id); - - if (stristr($name, 'mod_') != false) - { - $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/' . $name); - } - elseif (stristr($override, 'com_') != false) - { - $size = count($explodeArray); - - $url = JPath::clean($explodeArray[$size - 3] . '/' . $explodeArray[$size - 1]); - - if ($explodeArray[$size - 2] == 'layouts') - { - $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/layouts/' . $url); - } - else - { - $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/' . $url); - } - } - else - { - $layoutPath = implode('/', array_slice($explodeArray, -2)); - $htmlPath = JPath::clean($client->path . '/templates/' . $template->element . '/html/layouts/' . $layoutPath); - } - - // Check Html folder, create if not exist - if (!JFolder::exists($htmlPath)) - { - if (!JFolder::create($htmlPath)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_ERROR'), 'error'); - - return false; - } - } - - if (stristr($name, 'mod_') != false) - { - $return = $this->createTemplateOverride(JPath::clean($override . '/tmpl'), $htmlPath); - } - elseif (stristr($override, 'com_') != false && stristr($override, 'layouts') == false) - { - $return = $this->createTemplateOverride(JPath::clean($override . '/tmpl'), $htmlPath); - } - else - { - $return = $this->createTemplateOverride($override, $htmlPath); - } - - if ($return) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_OVERRIDE_CREATED') . str_replace(JPATH_ROOT, '', $htmlPath)); - - return true; - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_OVERRIDE_FAILED'), 'error'); - - return false; - } - } - } - - /** - * Create override folder & file - * - * @param string $overridePath The override location - * @param string $htmlPath The html location - * - * @return boolean True on success. False otherwise. - */ - public function createTemplateOverride($overridePath, $htmlPath) - { - $return = false; - - if (empty($overridePath) || empty($htmlPath)) - { - return $return; - } - - // Get list of template folders - $folders = JFolder::folders($overridePath, null, true, true); - - if (!empty($folders)) - { - foreach ($folders as $folder) - { - $htmlFolder = $htmlPath . str_replace($overridePath, '', $folder); - - if (!JFolder::exists($htmlFolder)) - { - JFolder::create($htmlFolder); - } - } - } - - // Get list of template files (Only get *.php file for template file) - $files = JFolder::files($overridePath, '.php', true, true); - - if (empty($files)) - { - return true; - } - - foreach ($files as $file) - { - $overrideFilePath = str_replace($overridePath, '', $file); - $htmlFilePath = $htmlPath . $overrideFilePath; - - if (JFile::exists($htmlFilePath)) - { - // Generate new unique file name base on current time - $today = JFactory::getDate(); - $htmlFilePath = JFile::stripExt($htmlFilePath) . '-' . $today->format('Ymd-His') . '.' . JFile::getExt($htmlFilePath); - } - - $return = JFile::copy($file, $htmlFilePath, '', true); - } - - return $return; - } - - /** - * Compile less using the less compiler under /build. - * - * @param string $input The relative location of the less file. - * - * @return boolean true if compilation is successful, false otherwise - * - * @since 3.2 - */ - public function compileLess($input) - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); - $inFile = urldecode(base64_decode($input)); - $explodeArray = explode('/', $inFile); - $fileName = end($explodeArray); - $outFile = reset(explode('.', $fileName)); - - $less = new JLess; - $less->setFormatter(new JLessFormatterJoomla); - - try - { - $less->compileFile($path . $inFile, $path . 'css/' . $outFile . '.css'); - - return true; - } - catch (Exception $e) - { - $app->enqueueMessage($e->getMessage(), 'error'); - } - } - } - - /** - * Delete a particular file. - * - * @param string $file The relative location of the file. - * - * @return boolean True if file deletion is successful, false otherwise - * - * @since 3.2 - */ - public function deleteFile($file) - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); - $filePath = $path . urldecode(base64_decode($file)); - - $return = JFile::delete($filePath); - - if (!$return) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_DELETE_FAIL'), 'error'); - - return false; - } - - return true; - } - } - - /** - * Create new file. - * - * @param string $name The name of file. - * @param string $type The extension of the file. - * @param string $location Location for the new file. - * - * @return boolean true if file created successfully, false otherwise - * - * @since 3.2 - */ - public function createFile($name, $type, $location) - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); - - if (file_exists(JPath::clean($path . '/' . $location . '/' . $name . '.' . $type))) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); - - return false; - } - - if (!fopen(JPath::clean($path . '/' . $location . '/' . $name . '.' . $type), 'x')) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_CREATE_ERROR'), 'error'); - - return false; - } - - // Check if the format is allowed and will be showed in the backend - $check = $this->checkFormat($type); - - // Add a message if we are not allowed to show this file in the backend. - if (!$check) - { - $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_WARNING_FORMAT_WILL_NOT_BE_VISIBLE', $type), 'warning'); - } - - return true; - } - } - - /** - * Upload new file. - * - * @param string $file The name of the file. - * @param string $location Location for the new file. - * - * @return boolean True if file uploaded successfully, false otherwise - * - * @since 3.2 - */ - public function uploadFile($file, $location) - { - jimport('joomla.filesystem.folder'); - - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); - $fileName = JFile::makeSafe($file['name']); - - $err = null; - JLoader::register('TemplateHelper', JPATH_ADMINISTRATOR . '/components/com_templates/helpers/template.php'); - - if (!TemplateHelper::canUpload($file, $err)) - { - // Can't upload the file - return false; - } - - if (file_exists(JPath::clean($path . '/' . $location . '/' . $file['name']))) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); - - return false; - } - - if (!JFile::upload($file['tmp_name'], JPath::clean($path . '/' . $location . '/' . $fileName))) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_UPLOAD_ERROR'), 'error'); - - return false; - } - - $url = JPath::clean($location . '/' . $fileName); - - return $url; - } - } - - /** - * Create new folder. - * - * @param string $name The name of the new folder. - * @param string $location Location for the new folder. - * - * @return boolean True if override folder is created successfully, false otherwise - * - * @since 3.2 - */ - public function createFolder($name, $location) - { - jimport('joomla.filesystem.folder'); - - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); - - if (file_exists(JPath::clean($path . '/' . $location . '/' . $name . '/'))) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_EXISTS'), 'error'); - - return false; - } - - if (!JFolder::create(JPath::clean($path . '/' . $location . '/' . $name))) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_CREATE_ERROR'), 'error'); - - return false; - } - - return true; - } - } - - /** - * Delete a folder. - * - * @param string $location The name and location of the folder. - * - * @return boolean True if override folder is deleted successfully, false otherwise - * - * @since 3.2 - */ - public function deleteFolder($location) - { - jimport('joomla.filesystem.folder'); - - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $location); - - if (!file_exists($path)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FOLDER_NOT_EXISTS'), 'error'); - - return false; - } - - $return = JFolder::delete($path); - - if (!$return) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_DELETE_ERROR'), 'error'); - - return false; - } - - return true; - } - } - - /** - * Rename a file. - * - * @param string $file The name and location of the old file - * @param string $name The new name of the file. - * - * @return string Encoded string containing the new file location. - * - * @since 3.2 - */ - public function renameFile($file, $name) - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); - $fileName = base64_decode($file); - $explodeArray = explode('.', $fileName); - $type = end($explodeArray); - $explodeArray = explode('/', $fileName); - $newName = str_replace(end($explodeArray), $name . '.' . $type, $fileName); - - if (file_exists($path . $newName)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); - - return false; - } - - if (!rename($path . $fileName, $path . $newName)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_RENAME_ERROR'), 'error'); - - return false; - } - - return base64_encode($newName); - } - } - - /** - * Get an image address, height and width. - * - * @return array an associative array containing image address, height and width. - * - * @since 3.2 - */ - public function getImage() - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $fileName = base64_decode($app->input->get('file')); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); - - if (stristr($client->path, 'administrator') == false) - { - $folder = '/templates/'; - } - else - { - $folder = '/administrator/templates/'; - } - - $uri = JUri::root(true) . $folder . $template->element; - - if (file_exists(JPath::clean($path . $fileName))) - { - $JImage = new JImage(JPath::clean($path . $fileName)); - $image['address'] = $uri . $fileName; - $image['path'] = $fileName; - $image['height'] = $JImage->getHeight(); - $image['width'] = $JImage->getWidth(); - } - - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_IMAGE_FILE_NOT_FOUND'), 'error'); - - return false; - } - - return $image; - } - } - - /** - * Crop an image. - * - * @param string $file The name and location of the file - * @param string $w width. - * @param string $h height. - * @param string $x x-coordinate. - * @param string $y y-coordinate. - * - * @return boolean true if image cropped successfully, false otherwise. - * - * @since 3.2 - */ - public function cropImage($file, $w, $h, $x, $y) - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $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); - - return true; - } - catch (Exception $e) - { - $app->enqueueMessage($e->getMessage(), 'error'); - } - } - } - - /** - * Resize an image. - * - * @param string $file The name and location of the file - * @param string $width The new width of the image. - * @param string $height The new height of the image. - * - * @return boolean true if image resize successful, false otherwise. - * - * @since 3.2 - */ - public function resizeImage($file, $width, $height) - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $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->resize($width, $height, true, 1); - $image->toFile($path); - - return true; - } - catch (Exception $e) - { - $app->enqueueMessage($e->getMessage(), 'error'); - } - } - } - - /** - * Template preview. - * - * @return object object containing the id of the template. - * - * @since 3.2 - */ - public function getPreview() - { - $app = JFactory::getApplication(); - $db = $this->getDbo(); - $query = $db->getQuery(true); - - $query->select('id, client_id'); - $query->from('#__template_styles'); - $query->where($db->quoteName('template') . ' = ' . $db->quote($this->template->element)); - - $db->setQuery($query); - - try - { - $result = $db->loadObject(); - } - catch (RuntimeException $e) - { - $app->enqueueMessage($e->getMessage(), 'warning'); - } - - if (empty($result)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND'), 'warning'); - } - else - { - return $result; - } - } - - /** - * Rename a file. - * - * @return mixed array on success, false on failure - * - * @since 3.2 - */ - public function getFont() - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $relPath = base64_decode($app->input->get('file')); - $explodeArray = explode('/', $relPath); - $fileName = end($explodeArray); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $relPath); - - if (stristr($client->path, 'administrator') == false) - { - $folder = '/templates/'; - } - else - { - $folder = '/administrator/templates/'; - } - - $uri = JUri::root(true) . $folder . $template->element; - - if (file_exists(JPath::clean($path))) - { - $font['address'] = $uri . $relPath; - - $font['rel_path'] = $relPath; - - $font['name'] = $fileName; - } - - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FONT_FILE_NOT_FOUND'), 'error'); - - return false; - } - - return $font; - } - } - - /** - * Copy a file. - * - * @param string $newName The name of the copied file - * @param string $location The final location where the file is to be copied - * @param string $file The name and location of the file - * - * @return boolean true if image resize successful, false otherwise. - * - * @since 3.2 - */ - public function copyFile($newName, $location, $file) - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $relPath = base64_decode($file); - $explodeArray = explode('.', $relPath); - $ext = end($explodeArray); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/'); - $newPath = JPath::clean($path . '/' . $location . '/' . $newName . '.' . $ext); - - if (file_exists($newPath)) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_EXISTS'), 'error'); - - return false; - } - - if (JFile::copy($path . $relPath, $newPath)) - { - $app->enqueueMessage(JText::sprintf('COM_TEMPLATES_FILE_COPY_SUCCESS', $newName . '.' . $ext)); - - return true; - } - else - { - return false; - } - } - } - - /** - * Get the compressed files. - * - * @return array if file exists, false otherwise - * - * @since 3.2 - */ - public function getArchive() - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $relPath = base64_decode($app->input->get('file')); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $relPath); - - if (file_exists(JPath::clean($path))) - { - $files = array(); - $zip = new ZipArchive; - - if ($zip->open($path) === true) - { - for ($i = 0; $i < $zip->numFiles; $i++) - { - $entry = $zip->getNameIndex($i); - $files[] = $entry; - } - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error'); - - return false; - } - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_ERROR_FONT_FILE_NOT_FOUND'), 'error'); - - return false; - } - - return $files; - } - } - - /** - * Extract contents of an archive file. - * - * @param string $file The name and location of the file - * - * @return boolean true if image extraction is successful, false otherwise. - * - * @since 3.2 - */ - public function extractArchive($file) - { - if ($template = $this->getTemplate()) - { - $app = JFactory::getApplication(); - $client = JApplicationHelper::getClientInfo($template->client_id); - $relPath = base64_decode($file); - $explodeArray = explode('/', $relPath); - $fileName = end($explodeArray); - $folderPath = stristr($relPath, $fileName, true); - $path = JPath::clean($client->path . '/templates/' . $template->element . '/' . $folderPath . '/'); - - if (file_exists(JPath::clean($path . '/' . $fileName))) - { - $zip = new ZipArchive; - - if ($zip->open(JPath::clean($path . '/' . $fileName)) === true) - { - for ($i = 0; $i < $zip->numFiles; $i++) - { - $entry = $zip->getNameIndex($i); - - if (file_exists(JPath::clean($path . '/' . $entry))) - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_EXISTS'), 'error'); - - return false; - } - } - - $zip->extractTo($path); - - return true; - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL'), 'error'); - - return false; - } - } - else - { - $app->enqueueMessage(JText::_('COM_TEMPLATES_FILE_ARCHIVE_NOT_FOUND'), 'error'); - - return false; - } - } - } - - /** - * 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)) - { - $params = JComponentHelper::getParams('com_templates'); - $imageTypes = explode(',', $params->get('image_formats')); - $sourceTypes = explode(',', $params->get('source_formats')); - $fontTypes = explode(',', $params->get('font_formats')); - $archiveTypes = explode(',', $params->get('compressed_formats')); - - $this->allowedFormats = array_merge($imageTypes, $sourceTypes, $fontTypes, $archiveTypes); - } - - return in_array($ext, $this->allowedFormats); - } -} diff --git a/administrator/components/com_templates/models/templates.php b/administrator/components/com_templates/models/templates.php deleted file mode 100644 index 77e2e1b25968c..0000000000000 --- a/administrator/components/com_templates/models/templates.php +++ /dev/null @@ -1,163 +0,0 @@ -client_id); - $item->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $item->element); - } - - return $items; - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - * - * @since 1.6 - */ - 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.extension_id, a.name, a.element, a.client_id' - ) - ); - $query->from($db->quoteName('#__extensions', 'a')) - ->where($db->quoteName('a.client_id') . ' = ' . (int) $this->getState('client_id')) - ->where($db->quoteName('a.enabled') . ' = 1') - ->where($db->quoteName('a.type') . ' = ' . $db->quote('template')); - - // Filter by search in title. - if ($search = $this->getState('filter.search')) - { - if (stripos($search, 'id:') === 0) - { - $query->where($db->quoteName('a.id') . ' = ' . (int) substr($search, 3)); - } - else - { - $search = $db->quote('%' . strtolower($search) . '%'); - $query->where('(' . ' LOWER(a.element) LIKE ' . $search . ' OR LOWER(a.name) LIKE ' . $search . ')'); - } - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.element')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - 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 A store id. - * - * @since 1.6 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('client_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 1.6 - */ - protected function populateState($ordering = 'a.element', $direction = 'asc') - { - // Load the filter state. - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - - // Special case for the client id. - $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); - $clientId = (!in_array($clientId, array (0, 1))) ? 0 : $clientId; - $this->setState('client_id', $clientId); - - // Load the parameters. - $params = JComponentHelper::getParams('com_templates'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } -} diff --git a/administrator/components/com_templates/services/provider.php b/administrator/components/com_templates/services/provider.php new file mode 100644 index 0000000000000..80f7bc73cdb42 --- /dev/null +++ b/administrator/components/com_templates/services/provider.php @@ -0,0 +1,56 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Templates')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Templates')); + + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new TemplatesComponent($container->get(DispatcherFactoryInterface::class)); + + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + $component->setRegistry($container->get(Registry::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_templates/tables/style.php b/administrator/components/com_templates/tables/style.php deleted file mode 100644 index 08bec641347d1..0000000000000 --- a/administrator/components/com_templates/tables/style.php +++ /dev/null @@ -1,140 +0,0 @@ -home == '1') - { - $this->setError(JText::_('COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE')); - - return false; - } - - return parent::bind($array, $ignore); - } - - /** - * Overloaded check method to ensure data integrity. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function check() - { - if (empty($this->title)) - { - $this->setError(JText::_('COM_TEMPLATES_ERROR_STYLE_REQUIRES_TITLE')); - - return false; - } - - return true; - } - - /** - * Overloaded store method to ensure unicity of default style. - * - * @param boolean $updateNulls True to update fields even if they are null. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function store($updateNulls = false) - { - if ($this->home != '0') - { - $query = $this->_db->getQuery(true) - ->update('#__template_styles') - ->set('home=\'0\'') - ->where('client_id=' . (int) $this->client_id) - ->where('home=' . $this->_db->quote($this->home)); - $this->_db->setQuery($query); - $this->_db->execute(); - } - - return parent::store($updateNulls); - } - - /** - * Overloaded store method to unsure existence of a default style for a template. - * - * @param mixed $pk An optional primary key value to delete. If not set the instance property value is used. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function delete($pk = null) - { - $k = $this->_tbl_key; - $pk = is_null($pk) ? $this->$k : $pk; - - if (!is_null($pk)) - { - $query = $this->_db->getQuery(true) - ->from('#__template_styles') - ->select('id') - ->where('client_id=' . (int) $this->client_id) - ->where('template=' . $this->_db->quote($this->template)); - $this->_db->setQuery($query); - $results = $this->_db->loadColumn(); - - if (count($results) == 1 && $results[0] == $pk) - { - $this->setError(JText::_('COM_TEMPLATES_ERROR_CANNOT_DELETE_LAST_STYLE')); - - return false; - } - } - - return parent::delete($pk); - } -} diff --git a/administrator/components/com_templates/templates.php b/administrator/components/com_templates/templates.php deleted file mode 100644 index 0e902ffbf6989..0000000000000 --- a/administrator/components/com_templates/templates.php +++ /dev/null @@ -1,22 +0,0 @@ -authorise('core.manage', 'com_templates')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -JLoader::register('TemplatesHelper', __DIR__ . '/helpers/templates.php'); - -$controller = JControllerLegacy::getInstance('Templates'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_templates/templates.xml b/administrator/components/com_templates/templates.xml index 4335da1ee756c..aa5863dea7339 100644 --- a/administrator/components/com_templates/templates.xml +++ b/administrator/components/com_templates/templates.xml @@ -9,15 +9,19 @@ www.joomla.org 3.0.0 COM_TEMPLATES_XML_DESCRIPTION + Joomla\Component\Templates config.xml - controller.php - templates.php - controllers + access.xml + dispatcher.php + Controller + Helper helpers + Model models - tables + Table + View views diff --git a/administrator/components/com_templates/tmpl/style/edit.php b/administrator/components/com_templates/tmpl/style/edit.php new file mode 100644 index 0000000000000..0608acdb86977 --- /dev/null +++ b/administrator/components/com_templates/tmpl/style/edit.php @@ -0,0 +1,109 @@ +useCoreUI = true; + +$user = Factory::getUser(); +?> + +
    + + + +
    + 'details')); ?> + + + +
    +
    +

    + item->template); ?> +

    +
    + + item->client_id == 0 ? Text::_('JSITE') : Text::_('JADMINISTRATOR'); ?> + +
    +
    +

    item->xml->description); ?>

    + fieldset = 'description'; + $description = LayoutHelper::render('joomla.edit.fieldset', $this); + ?> + +

    + + + +

    + +
    + fieldset = 'basic'; + $html = LayoutHelper::render('joomla.edit.fieldset', $this); + echo $html ? '
    ' . $html : ''; + ?> +
    +
    +
    +
    + fields = array( + 'home', + 'client_id', + 'template' + ); + ?> + +
    +
    +
    +
    + + + + + + + + + fieldsets = array(); + $this->ignore_fieldsets = array('basic', 'description'); + echo LayoutHelper::render('joomla.edit.params', $this); + ?> + + authorise('core.edit', 'com_menus') && $this->item->client_id == 0 && $this->canDo->get('core.edit.state')) : ?> + + loadTemplate('assignment'); ?> + + + + + + + +
    +
    diff --git a/administrator/components/com_templates/tmpl/style/edit_assignment.php b/administrator/components/com_templates/tmpl/style/edit_assignment.php new file mode 100644 index 0000000000000..c0bc5731c23be --- /dev/null +++ b/administrator/components/com_templates/tmpl/style/edit_assignment.php @@ -0,0 +1,50 @@ + + +
    + +
    + diff --git a/administrator/components/com_templates/tmpl/style/edit_options.php b/administrator/components/com_templates/tmpl/style/edit_options.php new file mode 100644 index 0000000000000..e049d487fd598 --- /dev/null +++ b/administrator/components/com_templates/tmpl/style/edit_options.php @@ -0,0 +1,43 @@ + + 'collapse0')); + $fieldSets = $this->form->getFieldsets('params'); + $i = 0; + + foreach ($fieldSets as $name => $fieldSet) : + $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_TEMPLATES_' . $name . '_FIELDSET_LABEL'; + echo HTMLHelper::_('bootstrap.addSlide', 'templatestyleOptions', Text::_($label), 'collapse' . ($i++)); + if (isset($fieldSet->description) && trim($fieldSet->description)) : + echo '

    ' . $this->escape(Text::_($fieldSet->description)) . '

    '; + endif; + ?> + form->getFieldset($name) as $field) : ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + state->get('client_id', 0); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
    +
    +
    + sidebar; ?> +
    +
    +
    + $this, 'options' => array('selectorFieldName' => 'client_id'))); ?> + total > 0) : ?> + + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_templates'); + $canEdit = $user->authorise('core.edit', 'com_templates'); + $canChange = $user->authorise('core.edit.state', 'com_templates'); + ?> + + + + + + + + + + + + +
    +   + + + + + + + + + + +
    + id); ?> + + preview && $item->client_id == '0') : ?> + + + + client_id == '1') : ?> + + + + + + + + + escape($item->title); ?> + + escape($item->title); ?> + + + home == '0' || $item->home == '1') : ?> + home != '0', $i, 'styles.', $canChange && $item->home != '1'); ?> + + + image) : ?> + image . '.gif', $item->language_title, array('title' => Text::sprintf('COM_TEMPLATES_GRID_UNSET_LANGUAGE', $item->language_title)), true); ?> + + language_sef; ?> + + + + image) : ?> + image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> + + language_sef; ?> + + + + home == '1') : ?> + + home != '0' && $item->home != '1') : ?> + escape($item->language_title)); ?> + assigned > 0) : ?> + escape($item->assigned)); ?> + + + + + + + id; ?> +
    + + + pagination->getListFooter(); ?> + + + + + + +
    +
    +
    +
    diff --git a/administrator/components/com_templates/views/styles/tmpl/default.xml b/administrator/components/com_templates/tmpl/styles/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_templates/views/styles/tmpl/default.xml rename to administrator/components/com_templates/tmpl/styles/default.xml diff --git a/administrator/components/com_templates/tmpl/template/default.php b/administrator/components/com_templates/tmpl/template/default.php new file mode 100644 index 0000000000000..dbe6b92e8556a --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default.php @@ -0,0 +1,362 @@ +input; + +// No access if not global SuperUser +if (!Factory::getUser()->authorise('core.admin')) +{ + Factory::getApplication()->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'danger'); +} + +if ($this->type == 'image') +{ + HTMLHelper::_('script', 'vendor/cropperjs/cropper.min.js', array('version' => 'auto', 'relative' => true)); + HTMLHelper::_('stylesheet', 'vendor/cropperjs/cropper.min.css', array('version' => 'auto', 'relative' => true)); +} + +HTMLHelper::_('script', 'com_templates/admin-templates-default.min.js', array('version' => 'auto', 'relative' => true)); +HTMLHelper::_('stylesheet', 'com_templates/admin-templates-default.css', array('version' => 'auto', 'relative' => true)); + +if ($this->type == 'font') +{ + Factory::getDocument()->addStyleDeclaration(" + @font-face { + font-family: previewFont; + src: url('" . $this->font['address'] . "') + } + .font-preview { + font-family: previewFont !important; + } + "); +} +?> + 'editor')); ?> + +
    +
    + type == 'file') : ?> +

    source->filename, $this->template->element); ?>

    + + + type == 'image') : ?> +

    image['path'], $this->template->element); ?>

    + + + type == 'font') : ?> +

    font['rel_path'], $this->template->element); ?>

    + + +
    +
    +
    +
    + loadTemplate('tree'); ?> +
    +
    + type == 'home') : ?> +
    + + +

    +

    +

    + + + +

    +
    + + type == 'file') : ?> +
    +
    + form->getInput('source'); ?> +
    + + + form->getInput('extension_id'); ?> + form->getInput('filename'); ?> +
    + + type == 'archive') : ?> + +
    + + + +
    + + type == 'image') : ?> + +
    +
    + + + + + + + + +
    +
    + + type == 'font') : ?> +
    +
    +
    +

    H1. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +

    H2. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +

    H3. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +

    H4. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +
    H5. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML
    +
    H6. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML
    +

    Bold. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +

    Italics. Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    +

    Unordered List

    +
      +
    • Item
    • +
    • Item
    • +
    • Item
      +
        +
      • Item
      • +
      • Item
      • +
      • Item
        +
          +
        • Item
        • +
        • Item
        • +
        • Item
        • +
        +
      • +
      +
    • +
    +

    Ordered List

    +
      +
    1. Item
    2. +
    3. Item
    4. +
    5. Item
      +
        +
      • Item
      • +
      • Item
      • +
      • Item
        +
          +
        • Item
        • +
        • Item
        • +
        • Item
        • +
        +
      • +
      +
    6. +
    + + +
    +
    +
    + +
    +
    + + + +
    +
    + +
      + + overridesList['modules'] as $module) : ?> +
    • + path + . '&id=' . $input->getInt('id') . '&file=' . $this->file . '&' . $token; + ?> + +  name; ?> + +
    • + +
    +
    +
    + +
      + + overridesList['components'] as $key => $value) : ?> +
    • + +   + +
        + +
      • + path + . '&id=' . $input->getInt('id') . '&file=' . $this->file . '&' . $token; + ?> + +  name; ?> + +
      • + +
      +
    • + +
    +
    +
    + +
      + + overridesList['layouts'] as $key => $value) : ?> +
    • + +   + +
        + +
      • + path + . '&id=' . $input->getInt('id') . '&file=' . $this->file . '&' . $token; + ?> + +  name; ?> + +
      • + +
      +
    • + +
    +
    +
    + + + +loadTemplate('description'); ?> + + + + 'copyModal', + 'params' => array( + 'title' => Text::_('COM_TEMPLATES_TEMPLATE_COPY'), + 'footer' => $this->loadTemplate('modal_copy_footer') + ), + 'body' => $this->loadTemplate('modal_copy_body') +); +?> +
    + + +
    +type != 'home') : ?> + 'renameModal', + 'params' => array( + 'title' => Text::sprintf('COM_TEMPLATES_RENAME_FILE', $this->fileName), + 'footer' => $this->loadTemplate('modal_rename_footer') + ), + 'body' => $this->loadTemplate('modal_rename_body') + ); + ?> +
    + + +
    + +type != 'home') : ?> + 'deleteModal', + 'params' => array( + 'title' => Text::_('COM_TEMPLATES_ARE_YOU_SURE'), + 'footer' => $this->loadTemplate('modal_delete_footer') + ), + 'body' => $this->loadTemplate('modal_delete_body') + ); + ?> + + + 'fileModal', + 'params' => array( + 'title' => Text::_('COM_TEMPLATES_NEW_FILE_HEADER'), + 'footer' => $this->loadTemplate('modal_file_footer'), + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 50, + 'modalWidth' => 60, + ), + 'body' => $this->loadTemplate('modal_file_body') +); +?> + + 'folderModal', + 'params' => array( + 'title' => Text::_('COM_TEMPLATES_MANAGE_FOLDERS'), + 'footer' => $this->loadTemplate('modal_folder_footer'), + 'height' => '400px', + 'width' => '800px', + 'bodyHeight' => 50, + 'modalWidth' => 60, + ), + 'body' => $this->loadTemplate('modal_folder_body') +); +?> + +type != 'home') : ?> + 'resizeModal', + 'params' => array( + 'title' => Text::_('COM_TEMPLATES_RESIZE_IMAGE'), + 'footer' => $this->loadTemplate('modal_resize_footer') + ), + 'body' => $this->loadTemplate('modal_resize_body') + ); + ?> +
    + + +
    + \ No newline at end of file diff --git a/administrator/components/com_templates/tmpl/template/default_description.php b/administrator/components/com_templates/tmpl/template/default_description.php new file mode 100644 index 0000000000000..e77cfd974604f --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_description.php @@ -0,0 +1,28 @@ + + +
    +
    + template->element, $this->template->client_id); ?> + template->element, $this->template->client_id); ?> +
    +

    template->element); ?>

    + template->client_id); ?> +

    template->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $this->template->element); ?>

    +

    template->xmldata->description); ?>

    +
    diff --git a/administrator/components/com_templates/tmpl/template/default_folders.php b/administrator/components/com_templates/tmpl/template/default_folders.php new file mode 100644 index 0000000000000..c5aad05c0dd55 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_folders.php @@ -0,0 +1,26 @@ +files, SORT_STRING); +?> + + diff --git a/administrator/components/com_templates/tmpl/template/default_modal_copy_body.php b/administrator/components/com_templates/tmpl/template/default_modal_copy_body.php new file mode 100644 index 0000000000000..6767b9d44f86c --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_copy_body.php @@ -0,0 +1,31 @@ + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    diff --git a/administrator/components/com_templates/tmpl/template/default_modal_copy_footer.php b/administrator/components/com_templates/tmpl/template/default_modal_copy_footer.php new file mode 100644 index 0000000000000..d573553cee930 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_copy_footer.php @@ -0,0 +1,16 @@ + + + diff --git a/administrator/components/com_templates/tmpl/template/default_modal_delete_body.php b/administrator/components/com_templates/tmpl/template/default_modal_delete_body.php new file mode 100644 index 0000000000000..d1be1658b1686 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_delete_body.php @@ -0,0 +1,21 @@ + +
    +
    +
    +

    fileName); ?>

    +
    +
    +
    \ No newline at end of file diff --git a/administrator/components/com_templates/tmpl/template/default_modal_delete_footer.php b/administrator/components/com_templates/tmpl/template/default_modal_delete_footer.php new file mode 100644 index 0000000000000..8e45b62c73b51 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_delete_footer.php @@ -0,0 +1,26 @@ +input; +?> +
    + + + + + + + +
    diff --git a/administrator/components/com_templates/tmpl/template/default_modal_file_body.php b/administrator/components/com_templates/tmpl/template/default_modal_file_body.php new file mode 100644 index 0000000000000..4436f4c5354c2 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_file_body.php @@ -0,0 +1,95 @@ +input; +?> +
    +
    +
    +
    +
    + loadTemplate('folders'); ?> +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + +
    + state->get('params')->get('upload_limit'); ?> + + +
    +
    +
    + type != 'home') : ?> +
    +
    +
    +
    + + + + +
    + +
    +
    +
    + +
    +
    +
    +
    diff --git a/administrator/components/com_templates/tmpl/template/default_modal_file_footer.php b/administrator/components/com_templates/tmpl/template/default_modal_file_footer.php new file mode 100644 index 0000000000000..81fe765ca0575 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_file_footer.php @@ -0,0 +1,15 @@ + + diff --git a/administrator/components/com_templates/tmpl/template/default_modal_folder_body.php b/administrator/components/com_templates/tmpl/template/default_modal_folder_body.php new file mode 100644 index 0000000000000..5f9f61feb2ace --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_folder_body.php @@ -0,0 +1,44 @@ +input; +?> +
    +
    +
    +
    +
    + loadTemplate('folders'); ?> +
    +
    +
    +
    +
    +
    +
    + + + + +
    + +
    +
    +
    +
    +
    +
    +
    diff --git a/administrator/components/com_templates/tmpl/template/default_modal_folder_footer.php b/administrator/components/com_templates/tmpl/template/default_modal_folder_footer.php new file mode 100644 index 0000000000000..d03cffa1a9eee --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_folder_footer.php @@ -0,0 +1,26 @@ +input; +?> +
    +
    + + + + +
    +
    diff --git a/administrator/components/com_templates/tmpl/template/default_modal_rename_body.php b/administrator/components/com_templates/tmpl/template/default_modal_rename_body.php new file mode 100644 index 0000000000000..7806c88a5d8f9 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_rename_body.php @@ -0,0 +1,37 @@ + +
    +
    +
    +
    +
    + +
    +
    +
    + + + .fileName); ?> + +
    +
    +
    +
    +
    +
    diff --git a/administrator/components/com_templates/tmpl/template/default_modal_rename_footer.php b/administrator/components/com_templates/tmpl/template/default_modal_rename_footer.php new file mode 100644 index 0000000000000..fff1e64b05e9c --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_rename_footer.php @@ -0,0 +1,16 @@ + + + diff --git a/administrator/components/com_templates/tmpl/template/default_modal_resize_body.php b/administrator/components/com_templates/tmpl/template/default_modal_resize_body.php new file mode 100644 index 0000000000000..64f2f71145a78 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_resize_body.php @@ -0,0 +1,41 @@ + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    diff --git a/administrator/components/com_templates/tmpl/template/default_modal_resize_footer.php b/administrator/components/com_templates/tmpl/template/default_modal_resize_footer.php new file mode 100644 index 0000000000000..0a2a54693a8a5 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_modal_resize_footer.php @@ -0,0 +1,16 @@ + + + diff --git a/administrator/components/com_templates/tmpl/template/default_tree.php b/administrator/components/com_templates/tmpl/template/default_tree.php new file mode 100644 index 0000000000000..7971b4005ac55 --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/default_tree.php @@ -0,0 +1,67 @@ +files, SORT_STRING); +?> + +
      + files as $key => $value) : ?> + + fileName); + $count = 0; + + $keyArrayCount = count($keyArray); + + if (count($fileArray) >= $keyArrayCount) + { + for ($i = 0; $i < $keyArrayCount; $i++) + { + if ($keyArray[$i] === $fileArray[$i]) + { + $count++; + } + } + + if ($count === $keyArrayCount) + { + $class = 'folder show'; + } + else + { + $class = 'folder'; + } + } + else + { + $class = 'folder'; + } + + ?> +
    • + +  escape(end($explodeArray)); ?> + + directoryTree($value); ?> +
    • + + +
    • + id . '&file=' . $value->id); ?>'> +  escape($value->name); ?> + +
    • + + +
    diff --git a/administrator/components/com_templates/tmpl/template/readonly.php b/administrator/components/com_templates/tmpl/template/readonly.php new file mode 100644 index 0000000000000..7890e051cd1cc --- /dev/null +++ b/administrator/components/com_templates/tmpl/template/readonly.php @@ -0,0 +1,30 @@ +input; +?> +
    + 'description')); ?> + + loadTemplate('description'); ?> + + + + +
    diff --git a/administrator/components/com_templates/tmpl/templates/default.php b/administrator/components/com_templates/tmpl/templates/default.php new file mode 100644 index 0000000000000..cf4684ecd5480 --- /dev/null +++ b/administrator/components/com_templates/tmpl/templates/default.php @@ -0,0 +1,108 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> + +
    +
    +
    + sidebar; ?> +
    +
    +
    + $this, 'options' => array('selectorFieldName' => 'client_id'))); ?> + total > 0) : ?> + + + + + + + + + + + + items as $i => $item) : ?> + + + + + + + + + +
    + + + + + + + + + +
    + element, $item->client_id); ?> + element, $item->client_id); ?> + + + name)); ?> +
    + preview && $item->client_id == '0') : ?> + + + + client_id == '1') : ?> + + + + +
    +
    + escape($item->xmldata->get('version')); ?> + + escape($item->xmldata->get('creationDate')); ?> + + xmldata->get('author')) : ?> +
    escape($author); ?>
    + + — + + xmldata->get('authorEmail')) : ?> +
    escape($email); ?>
    + + xmldata->get('authorUrl')) : ?> + + +
    + + + pagination->getListFooter(); ?> + + + + + + +
    +
    +
    +
    diff --git a/administrator/components/com_templates/views/templates/tmpl/default.xml b/administrator/components/com_templates/tmpl/templates/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_templates/views/templates/tmpl/default.xml rename to administrator/components/com_templates/tmpl/templates/default.xml diff --git a/administrator/components/com_templates/views/style/tmpl/edit.php b/administrator/components/com_templates/views/style/tmpl/edit.php deleted file mode 100644 index ef5bc0c902e73..0000000000000 --- a/administrator/components/com_templates/views/style/tmpl/edit.php +++ /dev/null @@ -1,105 +0,0 @@ -addScriptDeclaration(" - Joomla.submitbutton = function(task) - { - if (task == 'style.cancel' || document.formvalidator.isValid(document.getElementById('style-form'))) { - Joomla.submitform(task, document.getElementById('style-form')); - } - }; -"); -?> - -
    - - - -
    - 'details')); ?> - - - -
    -
    -

    - item->template); ?> -

    -
    - - item->client_id == 0 ? JText::_('JSITE') : JText::_('JADMINISTRATOR'); ?> - -
    -
    -

    item->xml->description); ?>

    - fieldset = 'description'; - $description = JLayoutHelper::render('joomla.edit.fieldset', $this); - ?> - -

    - - - -

    - -
    - fieldset = 'basic'; - $html = JLayoutHelper::render('joomla.edit.fieldset', $this); - echo $html ? '
    ' . $html : ''; - ?> -
    -
    - fields = array( - 'home', - 'client_id', - 'template' - ); - ?> - -
    -
    - - - - - - - - - fieldsets = array(); - $this->ignore_fieldsets = array('basic', 'description'); - echo JLayoutHelper::render('joomla.edit.params', $this); - ?> - - authorise('core.edit', 'com_menus') && $this->item->client_id == 0 && $this->canDo->get('core.edit.state')) : ?> - - loadTemplate('assignment'); ?> - - - - - - - -
    -
    diff --git a/administrator/components/com_templates/views/style/tmpl/edit_assignment.php b/administrator/components/com_templates/views/style/tmpl/edit_assignment.php deleted file mode 100644 index e3467788c7084..0000000000000 --- a/administrator/components/com_templates/views/style/tmpl/edit_assignment.php +++ /dev/null @@ -1,46 +0,0 @@ - - -
    - -
    - diff --git a/administrator/components/com_templates/views/style/tmpl/edit_options.php b/administrator/components/com_templates/views/style/tmpl/edit_options.php deleted file mode 100644 index a68dbfd1993a5..0000000000000 --- a/administrator/components/com_templates/views/style/tmpl/edit_options.php +++ /dev/null @@ -1,40 +0,0 @@ - - 'collapse0')); - $fieldSets = $this->form->getFieldsets('params'); - $i = 0; - - foreach ($fieldSets as $name => $fieldSet) : - $label = !empty($fieldSet->label) ? $fieldSet->label : 'COM_TEMPLATES_' . $name . '_FIELDSET_LABEL'; - echo JHtml::_('bootstrap.addSlide', 'templatestyleOptions', JText::_($label), 'collapse' . ($i++)); - if (isset($fieldSet->description) && trim($fieldSet->description)) : - echo '

    ' . $this->escape(JText::_($fieldSet->description)) . '

    '; - endif; - ?> - form->getFieldset($name) as $field) : ?> -
    -
    - label; ?> -
    -
    - input; ?> -
    -
    - item = $this->get('Item'); - $this->state = $this->get('State'); - $this->form = $this->get('Form'); - $this->canDo = JHelperContent::getActions('com_templates'); - - // 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 1.6 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - - $isNew = ($this->item->id == 0); - $canDo = $this->canDo; - - JToolbarHelper::title( - $isNew ? JText::_('COM_TEMPLATES_MANAGER_ADD_STYLE') - : JText::_('COM_TEMPLATES_MANAGER_EDIT_STYLE'), 'eye thememanager' - ); - - // If not checked out, can save the item. - if ($canDo->get('core.edit')) - { - JToolbarHelper::apply('style.apply'); - JToolbarHelper::save('style.save'); - } - - // If an existing item, can save to a copy. - if (!$isNew && $canDo->get('core.create')) - { - JToolbarHelper::save2copy('style.save2copy'); - } - - if (empty($this->item->id)) - { - JToolbarHelper::cancel('style.cancel'); - } - else - { - JToolbarHelper::cancel('style.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - - // Get the help information for the template item. - $lang = JFactory::getLanguage(); - $help = $this->get('Help'); - - if ($lang->hasKey($help->url)) - { - $debug = $lang->setDebug(false); - $url = JText::_($help->url); - $lang->setDebug($debug); - } - else - { - $url = null; - } - - JToolbarHelper::help($help->key, false, $url); - } -} diff --git a/administrator/components/com_templates/views/style/view.json.php b/administrator/components/com_templates/views/style/view.json.php deleted file mode 100644 index fdc2d73b78f02..0000000000000 --- a/administrator/components/com_templates/views/style/view.json.php +++ /dev/null @@ -1,72 +0,0 @@ -item = $this->get('Item'); - } - catch (Exception $e) - { - $app = JFactory::getApplication(); - $app->enqueueMessage($e->getMessage(), 'error'); - - return false; - } - - $paramsList = $this->item->getProperties(); - - unset($paramsList['xml']); - - $paramsList = json_encode($paramsList); - - return $paramsList; - - } -} diff --git a/administrator/components/com_templates/views/styles/tmpl/default.php b/administrator/components/com_templates/views/styles/tmpl/default.php deleted file mode 100644 index 9e76138fcbd63..0000000000000 --- a/administrator/components/com_templates/views/styles/tmpl/default.php +++ /dev/null @@ -1,150 +0,0 @@ -state->get('client_id', 0); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$colSpan = $clientId === 1 ? 5 : 6; -?> -
    -sidebar)) : ?> -
    - sidebar; ?> -
    -
    - -
    - - $this, 'options' => array('selectorFieldName' => 'client_id'))); ?> - total > 0) : ?> - - - - - - - - - - - - - - - - - - - - items as $i => $item) : - $canCreate = $user->authorise('core.create', 'com_templates'); - $canEdit = $user->authorise('core.edit', 'com_templates'); - $canChange = $user->authorise('core.edit.state', 'com_templates'); - ?> - - - - - - - - - - - - -
    -   - - - - - - - - - - -
    - pagination->getListFooter(); ?> -
    - id); ?> - - preview && $item->client_id == '0') : ?> - - - - - client_id == '1') : ?> - - - - - - - - - escape($item->title); ?> - - escape($item->title); ?> - - - home == '0' || $item->home == '1') : ?> - home != '0', $i, 'styles.', $canChange && $item->home != '1'); ?> - - - image) : ?> - image . '.gif', $item->language_title, array('title' => JText::sprintf('COM_TEMPLATES_GRID_UNSET_LANGUAGE', $item->language_title)), true); ?> - - language_sef; ?> - - - - image) : ?> - image . '.gif', $item->language_title, array('title' => $item->language_title), true); ?> - - language_sef; ?> - - - - home == '1') : ?> - - home != '0' && $item->home != '1') : ?> - escape($item->language_title)); ?> - assigned > 0) : ?> - escape($item->assigned)); ?> - - - - - - - id; ?> -
    - - - - - -
    - diff --git a/administrator/components/com_templates/views/styles/view.html.php b/administrator/components/com_templates/views/styles/view.html.php deleted file mode 100644 index 937f940c856b2..0000000000000 --- a/administrator/components/com_templates/views/styles/view.html.php +++ /dev/null @@ -1,111 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->total = $this->get('Total'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - $this->preview = JComponentHelper::getParams('com_templates')->get('template_positions_display'); - - TemplatesHelper::addSubmenu('styles'); - - // 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 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_templates'); - - // Set the title. - if ((int) $this->get('State')->get('client_id') === 1) - { - JToolbarHelper::title(JText::_('COM_TEMPLATES_MANAGER_STYLES_ADMIN'), 'eye thememanager'); - } - else - { - JToolbarHelper::title(JText::_('COM_TEMPLATES_MANAGER_STYLES_SITE'), 'eye thememanager'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::makeDefault('styles.setDefault', 'COM_TEMPLATES_TOOLBAR_SET_HOME'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('style.edit'); - } - - if ($canDo->get('core.create')) - { - JToolbarHelper::custom('styles.duplicate', 'copy.png', 'copy_f2.png', 'JTOOLBAR_DUPLICATE', true); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'styles.delete', 'JTOOLBAR_DELETE'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_templates'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_EXTENSIONS_TEMPLATE_MANAGER_STYLES'); - - JHtmlSidebar::setAction('index.php?option=com_templates&view=styles'); - - } -} diff --git a/administrator/components/com_templates/views/template/tmpl/default.php b/administrator/components/com_templates/views/template/tmpl/default.php deleted file mode 100644 index b6fa01ec36b5d..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default.php +++ /dev/null @@ -1,504 +0,0 @@ -input; - -// No access if not global SuperUser -if (!JFactory::getUser()->authorise('core.admin')) -{ - JFactory::getApplication()->enqueueMessage(JText::_('JERROR_ALERTNOAUTHOR'), 'error'); -} - -if ($this->type == 'image') -{ - JHtml::_('script', 'system/jquery.Jcrop.min.js', array('version' => 'auto', 'relative' => true)); - JHtml::_('stylesheet', 'system/jquery.Jcrop.min.css', array('version' => 'auto', 'relative' => true)); -} - -JFactory::getDocument()->addScriptDeclaration(" -jQuery(document).ready(function($){ - - // Hide all the folder when the page loads - $('.folder ul, .component-folder ul, .layout-folder ul').hide(); - - // Display the tree after loading - $('.directory-tree').removeClass('directory-tree'); - - // Show all the lists in the path of an open file - $('.show > ul').show(); - - // Stop the default action of anchor tag on a click event - $('.folder-url, .component-folder-url, .layout-folder-url').click(function(event){ - event.preventDefault(); - }); - - // Prevent the click event from proliferating - $('.file, .component-file-url').bind('click',function(e){ - e.stopPropagation(); - }); - - // Toggle the child indented list on a click event - $('.folder, .component-folder, .layout-folder').bind('click',function(e){ - $(this).children('ul').toggle(); - e.stopPropagation(); - }); - - // New file tree - $('#fileModal .folder-url').bind('click',function(e){ - $('.folder-url').removeClass('selected'); - e.stopPropagation(); - $('#fileModal input.address').val($(this).attr('data-id')); - $(this).addClass('selected'); - }); - - // Folder manager tree - $('#folderModal .folder-url').bind('click',function(e){ - $('.folder-url').removeClass('selected'); - e.stopPropagation(); - $('#folderModal input.address').val($(this).attr('data-id')); - $(this).addClass('selected'); - }); - - var containerDiv = document.querySelector('.span3.tree-holder'), - treeContainer = containerDiv.querySelector('.nav.nav-list'), - liEls = treeContainer.querySelectorAll('.folder.show'), - filePathEl = document.querySelector('p.lead.hidden.path'); - - if(filePathEl) - var filePathTmp = document.querySelector('p.lead.hidden.path').innerText; - - if(filePathTmp && filePathTmp.charAt( 0 ) === '/' ) { - filePathTmp = filePathTmp.slice( 1 ); - filePathTmp = filePathTmp.split('/'); - filePathTmp = filePathTmp[filePathTmp.length - 1]; - var re = new RegExp( filePathTmp ); - - for (var i = 0, l = liEls.length; i < l; i++) { - liEls[i].querySelector('a').classList.add('active'); - if (i === liEls.length - 1) { - var parentUl = liEls[i].querySelector('ul'), - allLi = parentUl.querySelectorAll('li'); - - for (var i = 0, l = allLi.length; i < l; i++) { - aEl = allLi[i].querySelector('a'), - spanEl = aEl.querySelector('span'); - - if (spanEl && re.test(spanEl.innerText)) { - aEl.classList.add('active'); - } - } - } - } - } -});"); - -if ($this->type == 'image') -{ - JFactory::getDocument()->addScriptDeclaration(" - jQuery(document).ready(function($) { - var jcrop_api; - - // Configuration for image cropping - $('#image-crop').Jcrop({ - onChange: showCoords, - onSelect: showCoords, - onRelease: clearCoords, - trueSize: [" . $this->image['width'] . ',' . $this->image['height'] . "] - },function(){ - jcrop_api = this; - }); - - // Function for calculating the crop coordinates - function showCoords(c) - { - $('#x').val(c.x); - $('#y').val(c.y); - $('#w').val(c.w); - $('#h').val(c.h); - }; - - // Function for clearing the coordinates - function clearCoords() - { - $('#adminForm input').val(''); - }; - });"); -} - -JFactory::getDocument()->addStyleDeclaration(' - /* Styles for modals */ - .selected{ - background: #08c; - color: #fff; - } - .selected:hover{ - background: #08c !important; - color: #fff; - } - .modal-body .column-left { - float: left; max-height: 70vh; overflow-y: auto; - } - .modal-body .column-right { - float: right; - } - @media (max-width: 767px) { - .modal-body .column-right { - float: left; - } - } - #deleteFolder{ - margin: 0; - } - - #image-crop{ - max-width: 100% !important; - width: auto; - height: auto; - } - - .directory-tree{ - display: none; - } - - .tree-holder{ - overflow-x: auto; - } -'); - -if ($this->type == 'font') -{ - JFactory::getDocument()->addStyleDeclaration( - "/* Styles for font preview */ - @font-face - { - font-family: previewFont; - src: url('" . $this->font['address'] . "') - } - - .font-preview{ - font-family: previewFont !important; - }" - ); -} -?> - 'editor')); ?> - -
    -
    - type == 'file') : ?> -

    source->filename, $this->template->element); ?>

    - - - type == 'image') : ?> -

    image['path'], $this->template->element); ?>

    - - - - type == 'font') : ?> -

    font['rel_path'], $this->template->element); ?>

    - - - -
    -
    -
    -
    - loadTemplate('tree'); ?> -
    -
    - type == 'home') : ?> -
    - - -
    -

    -

    -

    - - - -

    -
    -
    - - type == 'file') : ?> -
    - -
    - form->getInput('source'); ?> -
    - - - form->getInput('extension_id'); ?> - form->getInput('filename'); ?> - -
    - - type == 'archive') : ?> - -
    - - - - -
    - - type == 'image') : ?> - -
    -
    - - - - - - -
    -
    - - type == 'font') : ?> -
    -
    -
    -

    H1

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    -

    H2

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    -

    H3

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    -

    H4

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML

    -

    H5

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML
    -

    H6

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML
    -

    Bold

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML -

    Italics

    Quickly gaze at Joomla! views from HTML, CSS, JavaScript and XML -

    Unordered List

    -
      -
    • Item
    • -
    • Item
    • -
    • Item
      -
        -
      • Item
      • -
      • Item
      • -
      • Item
        -
          -
        • Item
        • -
        • Item
        • -
        • Item
        • -
        -
      • -
      -
    • -
    -

    Ordered List

    -
      -
    1. Item
    2. -
    3. Item
    4. -
    5. Item
      -
        -
      • Item
      • -
      • Item
      • -
      • Item
        -
          -
        • Item
        • -
        • Item
        • -
        • Item
        • -
        -
      • -
      -
    6. -
    - - -
    -
    -
    - -
    -
    - - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - - -loadTemplate('description'); ?> - - - - 'copyModal', - 'params' => array( - 'title' => JText::_('COM_TEMPLATES_TEMPLATE_COPY'), - 'footer' => $this->loadTemplate('modal_copy_footer'), - ), - 'body' => $this->loadTemplate('modal_copy_body'), -); -?> -
    - - -
    -type != 'home') : ?> - 'renameModal', - 'params' => array( - 'title' => JText::sprintf('COM_TEMPLATES_RENAME_FILE', $this->fileName), - 'footer' => $this->loadTemplate('modal_rename_footer'), - ), - 'body' => $this->loadTemplate('modal_rename_body'), - ); - ?> -
    - - -
    - -type != 'home') : ?> - 'deleteModal', - 'params' => array( - 'title' => JText::_('COM_TEMPLATES_ARE_YOU_SURE'), - 'footer' => $this->loadTemplate('modal_delete_footer'), - ), - 'body' => $this->loadTemplate('modal_delete_body'), - ); - ?> - - - 'fileModal', - 'params' => array( - 'title' => JText::_('COM_TEMPLATES_NEW_FILE_HEADER'), - 'footer' => $this->loadTemplate('modal_file_footer'), - ), - 'body' => $this->loadTemplate('modal_file_body'), -); -?> - - 'folderModal', - 'params' => array( - 'title' => JText::_('COM_TEMPLATES_MANAGE_FOLDERS'), - 'footer' => $this->loadTemplate('modal_folder_footer'), - ), - 'body' => $this->loadTemplate('modal_folder_body'), -); -?> - -type != 'home') : ?> - 'resizeModal', - 'params' => array( - 'title' => JText::_('COM_TEMPLATES_RESIZE_IMAGE'), - 'footer' => $this->loadTemplate('modal_resize_footer'), - ), - 'body' => $this->loadTemplate('modal_resize_body'), - ); - ?> -
    - - -
    - \ No newline at end of file diff --git a/administrator/components/com_templates/views/template/tmpl/default_description.php b/administrator/components/com_templates/views/template/tmpl/default_description.php deleted file mode 100644 index 40b3ce7712710..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_description.php +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - template->element, $this->template->client_id); ?> - template->element, $this->template->client_id); ?> -
    -

    template->element); ?>

    -template->client_id); ?> -

    template->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $this->template->element); ?>

    -

    template->xmldata->description); ?>

    \ No newline at end of file diff --git a/administrator/components/com_templates/views/template/tmpl/default_folders.php b/administrator/components/com_templates/views/template/tmpl/default_folders.php deleted file mode 100644 index 7d6738079c98c..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_folders.php +++ /dev/null @@ -1,25 +0,0 @@ -files, SORT_STRING); -?> - - diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_copy_body.php b/administrator/components/com_templates/views/template/tmpl/default_modal_copy_body.php deleted file mode 100644 index e733508a88eb1..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_copy_body.php +++ /dev/null @@ -1,27 +0,0 @@ - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_copy_footer.php b/administrator/components/com_templates/views/template/tmpl/default_modal_copy_footer.php deleted file mode 100644 index cdc26f3ff8621..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_copy_footer.php +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_delete_body.php b/administrator/components/com_templates/views/template/tmpl/default_modal_delete_body.php deleted file mode 100644 index d8d8f59d0005f..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_delete_body.php +++ /dev/null @@ -1,16 +0,0 @@ - -
    -
    -

    fileName); ?>

    -
    -
    \ No newline at end of file diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_delete_footer.php b/administrator/components/com_templates/views/template/tmpl/default_modal_delete_footer.php deleted file mode 100644 index a98ecf24fd9c4..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_delete_footer.php +++ /dev/null @@ -1,22 +0,0 @@ -input; -?> -
    - - - - - - - -
    diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_file_body.php b/administrator/components/com_templates/views/template/tmpl/default_modal_file_body.php deleted file mode 100644 index 7b41a19708099..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_file_body.php +++ /dev/null @@ -1,70 +0,0 @@ -input; -?> -
    -
    -
    -
    -
    -
    - - - - - - -
    -
    -
    -
    - - - -
    - state->get('params')->get('upload_limit'); ?> - - -
    -
    - type != 'home') : ?> -
    -
    - - - - - -
    -
    - -
    -
    - loadTemplate('folders'); ?> -
    -
    -
    -
    -
    diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_file_footer.php b/administrator/components/com_templates/views/template/tmpl/default_modal_file_footer.php deleted file mode 100644 index e13f4a7365855..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_file_footer.php +++ /dev/null @@ -1,12 +0,0 @@ - - diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_folder_body.php b/administrator/components/com_templates/views/template/tmpl/default_modal_folder_body.php deleted file mode 100644 index 105488d5fb224..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_folder_body.php +++ /dev/null @@ -1,34 +0,0 @@ -input; -?> -
    -
    -
    -
    -
    -
    - - - - - -
    -
    -
    -
    - loadTemplate('folders'); ?> -
    -
    -
    -
    -
    diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_folder_footer.php b/administrator/components/com_templates/views/template/tmpl/default_modal_folder_footer.php deleted file mode 100644 index d27a623248731..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_folder_footer.php +++ /dev/null @@ -1,21 +0,0 @@ -input; -?> -
    -
    - - - - -
    -
    diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_rename_body.php b/administrator/components/com_templates/views/template/tmpl/default_modal_rename_body.php deleted file mode 100644 index 83402a0c02707..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_rename_body.php +++ /dev/null @@ -1,31 +0,0 @@ - -
    -
    -
    -
    -
    - -
    -
    -
    - - .fileName); ?> -
    -
    -
    -
    -
    -
    diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_rename_footer.php b/administrator/components/com_templates/views/template/tmpl/default_modal_rename_footer.php deleted file mode 100644 index c37c1eb4cdbfd..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_rename_footer.php +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_resize_body.php b/administrator/components/com_templates/views/template/tmpl/default_modal_resize_body.php deleted file mode 100644 index b53b6f71768c5..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_resize_body.php +++ /dev/null @@ -1,35 +0,0 @@ - -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    diff --git a/administrator/components/com_templates/views/template/tmpl/default_modal_resize_footer.php b/administrator/components/com_templates/views/template/tmpl/default_modal_resize_footer.php deleted file mode 100644 index 9430bba8d81de..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_modal_resize_footer.php +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/administrator/components/com_templates/views/template/tmpl/default_tree.php b/administrator/components/com_templates/views/template/tmpl/default_tree.php deleted file mode 100644 index f00e38768fde3..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/default_tree.php +++ /dev/null @@ -1,64 +0,0 @@ -files, SORT_STRING); -?> - - diff --git a/administrator/components/com_templates/views/template/tmpl/readonly.php b/administrator/components/com_templates/views/template/tmpl/readonly.php deleted file mode 100644 index 06bf02ded3ab7..0000000000000 --- a/administrator/components/com_templates/views/template/tmpl/readonly.php +++ /dev/null @@ -1,27 +0,0 @@ -input; -?> -
    - 'description')); ?> - - loadTemplate('description'); ?> - - - - -
    diff --git a/administrator/components/com_templates/views/template/view.html.php b/administrator/components/com_templates/views/template/view.html.php deleted file mode 100644 index 681ec0f034d50..0000000000000 --- a/administrator/components/com_templates/views/template/view.html.php +++ /dev/null @@ -1,299 +0,0 @@ -file = $app->input->get('file'); - $this->fileName = JFilterInput::getInstance()->clean(base64_decode($this->file), 'string'); - $explodeArray = explode('.', $this->fileName); - $ext = end($explodeArray); - $this->files = $this->get('Files'); - $this->state = $this->get('State'); - $this->template = $this->get('Template'); - $this->preview = $this->get('Preview'); - - $params = JComponentHelper::getParams('com_templates'); - $imageTypes = explode(',', $params->get('image_formats')); - $sourceTypes = explode(',', $params->get('source_formats')); - $fontTypes = explode(',', $params->get('font_formats')); - $archiveTypes = explode(',', $params->get('compressed_formats')); - - if (in_array($ext, $sourceTypes)) - { - $this->form = $this->get('Form'); - $this->form->setFieldAttribute('source', 'syntax', $ext); - $this->source = $this->get('Source'); - $this->type = 'file'; - } - elseif (in_array($ext, $imageTypes)) - { - $this->image = $this->get('Image'); - $this->type = 'image'; - } - elseif (in_array($ext, $fontTypes)) - { - $this->font = $this->get('Font'); - $this->type = 'font'; - } - elseif (in_array($ext, $archiveTypes)) - { - $this->archive = $this->get('Archive'); - $this->type = 'archive'; - } - else - { - $this->type = 'home'; - } - - $this->overridesList = $this->get('OverridesList'); - $this->id = $this->state->get('extension.id'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - $app->enqueueMessage(implode("\n", $errors)); - - return false; - } - - $this->addToolbar(); - - if (!JFactory::getUser()->authorise('core.admin')) - { - $this->setLayout('readonly'); - } - - return parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @since 1.6 - * - * @return void - */ - protected function addToolbar() - { - $app = JFactory::getApplication(); - $user = JFactory::getUser(); - $app->input->set('hidemainmenu', true); - - // User is global SuperUser - $isSuperUser = $user->authorise('core.admin'); - - // Get the toolbar object instance - $bar = JToolbar::getInstance('toolbar'); - $explodeArray = explode('.', $this->fileName); - $ext = end($explodeArray); - - JToolbarHelper::title(JText::sprintf('COM_TEMPLATES_MANAGER_VIEW_TEMPLATE', ucfirst($this->template->name)), 'eye thememanager'); - - // Only show file edit buttons for global SuperUser - if ($isSuperUser) - { - // Add an Apply and save button - if ($this->type == 'file') - { - JToolbarHelper::apply('template.apply'); - JToolbarHelper::save('template.save'); - } - // Add a Crop and Resize button - elseif ($this->type == 'image') - { - JToolbarHelper::custom('template.cropImage', 'move', 'move', 'COM_TEMPLATES_BUTTON_CROP', false); - JToolbarHelper::modal('resizeModal', 'icon-refresh', 'COM_TEMPLATES_BUTTON_RESIZE'); - } - // Add an extract button - elseif ($this->type == 'archive') - { - JToolbarHelper::custom('template.extractArchive', 'arrow-down', 'arrow-down', 'COM_TEMPLATES_BUTTON_EXTRACT_ARCHIVE', false); - } - - // Add a copy template button (Hathor override doesn't need the button) - if ($app->getTemplate() != 'hathor') - { - JToolbarHelper::modal('copyModal', 'icon-copy', 'COM_TEMPLATES_BUTTON_COPY_TEMPLATE'); - } - } - - // Add a Template preview button - if ($this->preview->client_id == 0) - { - $bar->appendButton('Popup', 'picture', 'COM_TEMPLATES_BUTTON_PREVIEW', JUri::root() . 'index.php?tp=1&templateStyle=' . $this->preview->id, 800, 520); - } - - // Only show file manage buttons for global SuperUser - if ($isSuperUser) - { - // Add Manage folders button - JToolbarHelper::modal('folderModal', 'icon-folder icon white', 'COM_TEMPLATES_BUTTON_FOLDERS'); - - // Add a new file button - JToolbarHelper::modal('fileModal', 'icon-file', 'COM_TEMPLATES_BUTTON_FILE'); - - // Add a Rename file Button (Hathor override doesn't need the button) - if ($app->getTemplate() != 'hathor' && $this->type != 'home') - { - JToolbarHelper::modal('renameModal', 'icon-refresh', 'COM_TEMPLATES_BUTTON_RENAME_FILE'); - } - - // Add a Delete file Button - if ($this->type != 'home') - { - JToolbarHelper::modal('deleteModal', 'icon-remove', 'COM_TEMPLATES_BUTTON_DELETE_FILE'); - } - - // Add a Compile Button - if ($ext == 'less') - { - JToolbarHelper::custom('template.less', 'play', 'play', 'COM_TEMPLATES_BUTTON_LESS', false); - } - } - - if ($this->type == 'home') - { - JToolbarHelper::cancel('template.cancel', 'JTOOLBAR_CLOSE'); - } - else - { - JToolbarHelper::cancel('template.close', 'COM_TEMPLATES_BUTTON_CLOSE_FILE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT'); - } - - /** - * Method for creating the collapsible tree. - * - * @param array $array The value of the present node for recursion - * - * @return string - * - * @note Uses recursion - * @since 3.2 - */ - protected function directoryTree($array) - { - $temp = $this->files; - $this->files = $array; - $txt = $this->loadTemplate('tree'); - $this->files = $temp; - - return $txt; - } - - /** - * Method for listing the folder tree in modals. - * - * @param array $array The value of the present node for recursion - * - * @return string - * - * @note Uses recursion - * @since 3.2 - */ - protected function folderTree($array) - { - $temp = $this->files; - $this->files = $array; - $txt = $this->loadTemplate('folders'); - $this->files = $temp; - - return $txt; - } -} diff --git a/administrator/components/com_templates/views/templates/tmpl/default.php b/administrator/components/com_templates/views/templates/tmpl/default.php deleted file mode 100644 index 784ed2d7e2a82..0000000000000 --- a/administrator/components/com_templates/views/templates/tmpl/default.php +++ /dev/null @@ -1,113 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> - -
    -sidebar)) : ?> -
    - sidebar; ?> -
    -
    - -
    - - $this, 'options' => array('selectorFieldName' => 'client_id'))); ?> - total > 0) : ?> - - - - - - - - - - - - - - - - - items as $i => $item) : ?> - - - - - - - - - -
    - - - - - - - - - -
    - pagination->getListFooter(); ?> -
    - element, $item->client_id); ?> - element, $item->client_id); ?> - - - name)); ?> -
    - preview && $item->client_id == '0') : ?> - - - - client_id == '1') : ?> - - - - -
    -
    - escape($item->xmldata->get('version')); ?> - - escape($item->xmldata->get('creationDate')); ?> - - xmldata->get('author')) : ?> -
    escape($author); ?>
    - - — - - xmldata->get('authorEmail')) : ?> -
    escape($email); ?>
    - - xmldata->get('authorUrl')) : ?> - - -
    - - - - - -
    - diff --git a/administrator/components/com_templates/views/templates/view.html.php b/administrator/components/com_templates/views/templates/view.html.php deleted file mode 100644 index 57dddc6679cce..0000000000000 --- a/administrator/components/com_templates/views/templates/view.html.php +++ /dev/null @@ -1,109 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->total = $this->get('Total'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - $this->preview = JComponentHelper::getParams('com_templates')->get('template_positions_display'); - $this->file = base64_encode('home'); - - TemplatesHelper::addSubmenu('templates'); - - // 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 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_templates'); - - // Set the title. - if ((int) $this->get('State')->get('client_id') === 1) - { - JToolbarHelper::title(JText::_('COM_TEMPLATES_MANAGER_TEMPLATES_ADMIN'), 'eye thememanager'); - } - else - { - JToolbarHelper::title(JText::_('COM_TEMPLATES_MANAGER_TEMPLATES_SITE'), 'eye thememanager'); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_templates'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES'); - - JHtmlSidebar::setAction('index.php?option=com_templates&view=templates'); - - $this->sidebar = JHtmlSidebar::render(); - } -} diff --git a/administrator/components/com_users/Controller/DisplayController.php b/administrator/components/com_users/Controller/DisplayController.php new file mode 100644 index 0000000000000..cf135a0ec0360 --- /dev/null +++ b/administrator/components/com_users/Controller/DisplayController.php @@ -0,0 +1,122 @@ +get('core.admin'); + break; + + // Default permissions. + default: + return true; + } + } + + /** + * 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 Joomla\CMS\Filter\InputFilter::clean()}. + * + * @return BaseController This object to support chaining. + * + * @since 1.5 + */ + public function display($cachable = false, $urlparams = array()) + { + $view = $this->input->get('view', 'users'); + $layout = $this->input->get('layout', 'default'); + $id = $this->input->getInt('id'); + + if (!$this->canView($view)) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + // Check for edit form. + if ($view == 'user' && $layout == 'edit' && !$this->checkEditId('com_users.edit.user', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_users&view=users', false)); + + return false; + } + elseif ($view == 'group' && $layout == 'edit' && !$this->checkEditId('com_users.edit.group', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_users&view=groups', false)); + + return false; + } + elseif ($view == 'level' && $layout == 'edit' && !$this->checkEditId('com_users.edit.level', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_users&view=levels', false)); + + return false; + } + elseif ($view == 'note' && $layout == 'edit' && !$this->checkEditId('com_users.edit.note', $id)) + { + // Somehow the person just went to the form - we don't allow that. + $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); + $this->setRedirect(Route::_('index.php?option=com_users&view=notes', false)); + + return false; + } + + return parent::display($cachable, $urlparams); + } +} diff --git a/administrator/components/com_users/Controller/GroupController.php b/administrator/components/com_users/Controller/GroupController.php new file mode 100644 index 0000000000000..dbe864a95a44e --- /dev/null +++ b/administrator/components/com_users/Controller/GroupController.php @@ -0,0 +1,73 @@ +app->getIdentity()->authorise('core.admin', $this->option) && parent::allowSave($data, $key)); + } + + /** + * Overrides Joomla\CMS\MVC\Controller\FormController::allowEdit + * + * Checks that non-Super Admins are not editing Super Admins. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since 1.6 + */ + protected function allowEdit($data = array(), $key = 'id') + { + // Check if this group is a Super Admin + if (Access::checkGroup($data[$key], 'core.admin')) + { + // If I'm not a Super Admin, then disallow the edit. + if (!$this->app->getIdentity()->authorise('core.admin')) + { + return false; + } + } + + return parent::allowEdit($data, $key); + } +} diff --git a/administrator/components/com_users/Controller/GroupsController.php b/administrator/components/com_users/Controller/GroupsController.php new file mode 100644 index 0000000000000..c0be8b80ba658 --- /dev/null +++ b/administrator/components/com_users/Controller/GroupsController.php @@ -0,0 +1,140 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Removes an item. + * + * Overrides Joomla\CMS\MVC\Controller\AdminController::delete to check the core.admin permission. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function delete() + { + if (!$this->app->getIdentity()->authorise('core.admin', $this->option)) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + return parent::delete(); + } + + /** + * Method to publish a list of records. + * + * Overrides Joomla\CMS\MVC\Controller\AdminController::publish to check the core.admin permission. + * + * @return void + * + * @since 1.6 + */ + public function publish() + { + if (!$this->app->getIdentity()->authorise('core.admin', $this->option)) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + return parent::publish(); + } + + /** + * Changes the order of one or more records. + * + * Overrides Joomla\CMS\MVC\Controller\AdminController::reorder to check the core.admin permission. + * + * @return boolean True on success + * + * @since 1.6 + */ + public function reorder() + { + if (!$this->app->getIdentity()->authorise('core.admin', $this->option)) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + return parent::reorder(); + } + + /** + * Method to save the submitted ordering values for records. + * + * Overrides Joomla\CMS\MVC\Controller\AdminController::saveorder to check the core.admin permission. + * + * @return boolean True on success + * + * @since 1.6 + */ + public function saveorder() + { + if (!$this->app->getIdentity()->authorise('core.admin', $this->option)) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + return parent::saveorder(); + } + + /** + * Check in of one or more records. + * + * Overrides Joomla\CMS\MVC\Controller\AdminController::checkin to check the core.admin permission. + * + * @return boolean True on success + * + * @since 1.6 + */ + public function checkin() + { + if (!$this->app->getIdentity()->authorise('core.admin', $this->option)) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + return parent::checkin(); + } +} diff --git a/administrator/components/com_users/Controller/LevelController.php b/administrator/components/com_users/Controller/LevelController.php new file mode 100644 index 0000000000000..e73432dfc7fb7 --- /dev/null +++ b/administrator/components/com_users/Controller/LevelController.php @@ -0,0 +1,94 @@ +app->getIdentity()->authorise('core.admin', $this->option) && parent::allowSave($data, $key)); + } + + /** + * Removes an item. + * + * Overrides Joomla\CMS\MVC\Controller\FormController::delete to check the core.admin permission. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + */ + public function delete() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + + if (!$this->app->getIdentity()->authorise('core.admin', $this->option)) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + elseif (empty($ids)) + { + $this->setMessage(Text::_('COM_USERS_NO_LEVELS_SELECTED'), 'warning'); + } + else + { + // Get the model. + $model = $this->getModel(); + + $ids = ArrayHelper::toInteger($ids); + + // Remove the items. + if (!$model->delete($ids)) + { + $this->setMessage($model->getError(), 'error'); + } + else + { + $this->setMessage(Text::plural('COM_USERS_N_LEVELS_DELETED', count($ids))); + } + } + + $this->setRedirect('index.php?option=com_users&view=levels'); + } +} diff --git a/administrator/components/com_users/Controller/LevelsController.php b/administrator/components/com_users/Controller/LevelsController.php new file mode 100644 index 0000000000000..6558079407d5c --- /dev/null +++ b/administrator/components/com_users/Controller/LevelsController.php @@ -0,0 +1,43 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_users/Controller/MailController.php b/administrator/components/com_users/Controller/MailController.php new file mode 100644 index 0000000000000..4687e48fcc856 --- /dev/null +++ b/administrator/components/com_users/Controller/MailController.php @@ -0,0 +1,72 @@ +app->get('massmailoff', 0) == 1) + { + $this->app->redirect(Route::_('index.php', false)); + } + + // Check for request forgeries. + Session::checkToken('request') or jexit(Text::_('JINVALID_TOKEN')); + + $model = $this->getModel('Mail'); + + if ($model->send()) + { + $type = 'message'; + } + else + { + $type = 'error'; + } + + $msg = $model->getError(); + $this->setRedirect('index.php?option=com_users&view=mail', $msg, $type); + } + + /** + * Cancel the mail + * + * @return void + * + * @since 1.6 + */ + public function cancel() + { + // Check for request forgeries. + Session::checkToken('request') or jexit(Text::_('JINVALID_TOKEN')); + $this->setRedirect('index.php'); + } +} diff --git a/administrator/components/com_users/Controller/NoteController.php b/administrator/components/com_users/Controller/NoteController.php new file mode 100644 index 0000000000000..184c94386c8cd --- /dev/null +++ b/administrator/components/com_users/Controller/NoteController.php @@ -0,0 +1,54 @@ +input->get('u_id', 0, 'int'); + + if ($userId) + { + $append .= '&u_id=' . $userId; + } + + return $append; + } +} diff --git a/administrator/components/com_users/Controller/NotesController.php b/administrator/components/com_users/Controller/NotesController.php new file mode 100644 index 0000000000000..cb5518c19f48e --- /dev/null +++ b/administrator/components/com_users/Controller/NotesController.php @@ -0,0 +1,46 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } +} diff --git a/administrator/components/com_users/Controller/ProfileController.php b/administrator/components/com_users/Controller/ProfileController.php new file mode 100644 index 0000000000000..e48b863ed2b30 --- /dev/null +++ b/administrator/components/com_users/Controller/ProfileController.php @@ -0,0 +1,62 @@ +app->close(); + } +} diff --git a/administrator/components/com_users/Controller/UserController.php b/administrator/components/com_users/Controller/UserController.php new file mode 100644 index 0000000000000..428233837c989 --- /dev/null +++ b/administrator/components/com_users/Controller/UserController.php @@ -0,0 +1,96 @@ +app->getIdentity()->authorise('core.admin')) + { + return false; + } + } + + return parent::allowEdit($data, $key); + } + + /** + * Method to run batch operations. + * + * @param object $model The model. + * + * @return boolean True on success, false on failure + * + * @since 2.5 + */ + public function batch($model = null) + { + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + // Set the model + $model = $this->getModel('User', 'Administrator', array()); + + // Preset the redirect + $this->setRedirect(Route::_('index.php?option=com_users&view=users' . $this->getRedirectToListAppend(), false)); + + return parent::batch($model); + } + + /** + * Function that allows child controller access to model data after the data has been saved. + * + * @param BaseDatabaseModel $model The data model object. + * @param array $validData The validated data. + * + * @return void + * + * @since 3.1 + */ + protected function postSaveHook(BaseDatabaseModel $model, $validData = array()) + { + return; + } +} diff --git a/administrator/components/com_users/Controller/UsersController.php b/administrator/components/com_users/Controller/UsersController.php new file mode 100644 index 0000000000000..25a5a7bf0a1e6 --- /dev/null +++ b/administrator/components/com_users/Controller/UsersController.php @@ -0,0 +1,155 @@ +registerTask('block', 'changeBlock'); + $this->registerTask('unblock', 'changeBlock'); + } + + /** + * Proxy for getModel. + * + * @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 1.6 + */ + public function getModel($name = 'User', $prefix = 'Administrator', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to change the block status on a record. + * + * @return void + * + * @since 1.6 + */ + public function changeBlock() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + $values = array('block' => 1, 'unblock' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($values, $task, 0, 'int'); + + if (empty($ids)) + { + $this->setMessage(Text::_('COM_USERS_USERS_NO_ITEM_SELECTED'), 'warning'); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Change the state of the records. + if (!$model->block($ids, $value)) + { + $this->setMessage($model->getError(), 'error'); + } + else + { + if ($value == 1) + { + $this->setMessage(Text::plural('COM_USERS_N_USERS_BLOCKED', count($ids))); + } + elseif ($value == 0) + { + $this->setMessage(Text::plural('COM_USERS_N_USERS_UNBLOCKED', count($ids))); + } + } + } + + $this->setRedirect('index.php?option=com_users&view=users'); + } + + /** + * Method to activate a record. + * + * @return void + * + * @since 1.6 + */ + public function activate() + { + // Check for request forgeries. + Session::checkToken() or jexit(Text::_('JINVALID_TOKEN')); + + $ids = $this->input->get('cid', array(), 'array'); + + if (empty($ids)) + { + $this->setMessage(Text::_('COM_USERS_USERS_NO_ITEM_SELECTED'), 'error'); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Change the state of the records. + if (!$model->activate($ids)) + { + $this->setMessage($model->getError(), 'error'); + } + else + { + $this->setMessage(Text::plural('COM_USERS_N_USERS_ACTIVATED', count($ids))); + } + } + + $this->setRedirect('index.php?option=com_users&view=users'); + } +} diff --git a/administrator/components/com_users/Field/GroupparentField.php b/administrator/components/com_users/Field/GroupparentField.php new file mode 100644 index 0000000000000..f03f52262e27b --- /dev/null +++ b/administrator/components/com_users/Field/GroupparentField.php @@ -0,0 +1,75 @@ +getAll(); + + // Prevent parenting to children of this item. + if ($id = $this->form->getValue('id')) + { + unset($options[$id]); + } + + $options = array_values($options); + $isSuperAdmin = Factory::getUser()->authorise('core.admin'); + + // Pad the option text with spaces using depth level as a multiplier. + for ($i = 0, $n = count($options); $i < $n; $i++) + { + // Show groups only if user is super admin or group is not super admin + if ($isSuperAdmin || !Access::checkGroup($options[$i]->id, 'core.admin')) + { + $options[$i]->value = $options[$i]->id; + $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->title; + } + else + { + unset($options[$i]); + } + } + + // Merge any additional options in the XML definition. + return array_merge(parent::getOptions(), $options); + } +} diff --git a/administrator/components/com_users/Field/LevelsField.php b/administrator/components/com_users/Field/LevelsField.php new file mode 100644 index 0000000000000..9e266c307e2ba --- /dev/null +++ b/administrator/components/com_users/Field/LevelsField.php @@ -0,0 +1,47 @@ +get('core.admin')) + { + HTMLHelper::_('sidebar.addEntry', + Text::_('COM_USERS_SUBMENU_GROUPS'), + 'index.php?option=com_users&view=groups', + $vName == 'groups' + ); + HTMLHelper::_('sidebar.addEntry', + Text::_('COM_USERS_SUBMENU_LEVELS'), + 'index.php?option=com_users&view=levels', + $vName == 'levels' + ); + } + + if (ComponentHelper::isEnabled('com_fields') && ComponentHelper::getParams('com_users')->get('custom_fields_enable', '1')) + { + HTMLHelper::_('sidebar.addEntry', + Text::_('JGLOBAL_FIELDS'), + 'index.php?option=com_fields&context=com_users.user', + $vName == 'fields.fields' + ); + HTMLHelper::_('sidebar.addEntry', + Text::_('JGLOBAL_FIELD_GROUPS'), + 'index.php?option=com_fields&view=groups&context=com_users.user', + $vName == 'fields.groups' + ); + } + + HTMLHelper::_('sidebar.addEntry', + Text::_('COM_USERS_SUBMENU_NOTES'), + 'index.php?option=com_users&view=notes', + $vName == 'notes' + ); + HTMLHelper::_('sidebar.addEntry', + Text::_('COM_USERS_SUBMENU_NOTE_CATEGORIES'), + 'index.php?option=com_categories&extension=com_users', + $vName == 'categories' + ); + } + + /** + * Get a list of filter options for the blocked state of a user. + * + * @return array An array of \JHtmlOption elements. + * + * @since 1.6 + */ + public static function getStateOptions() + { + // Build the filter options. + $options = array(); + $options[] = HTMLHelper::_('select.option', '0', Text::_('JENABLED')); + $options[] = HTMLHelper::_('select.option', '1', Text::_('JDISABLED')); + + return $options; + } + + /** + * Get a list of filter options for the activated state of a user. + * + * @return array An array of \JHtmlOption elements. + * + * @since 1.6 + */ + public static function getActiveOptions() + { + // Build the filter options. + $options = array(); + $options[] = HTMLHelper::_('select.option', '0', Text::_('COM_USERS_ACTIVATED')); + $options[] = HTMLHelper::_('select.option', '1', Text::_('COM_USERS_UNACTIVATED')); + + return $options; + } + + /** + * Get a list of the user groups for filtering. + * + * @return array An array of \JHtmlOption elements. + * + * @since 1.6 + */ + public static function getGroups() + { + $options = UserGroupsHelper::getInstance()->getAll(); + + foreach ($options as &$option) + { + $option->value = $option->id; + $option->text = str_repeat('- ', $option->level) . $option->title; + } + + return $options; + } + + /** + * Creates a list of range options used in filter select list + * used in com_users on users view + * + * @return array + * + * @since 2.5 + */ + public static function getRangeOptions() + { + $options = array( + HTMLHelper::_('select.option', 'today', Text::_('COM_USERS_OPTION_RANGE_TODAY')), + HTMLHelper::_('select.option', 'past_week', Text::_('COM_USERS_OPTION_RANGE_PAST_WEEK')), + HTMLHelper::_('select.option', 'past_1month', Text::_('COM_USERS_OPTION_RANGE_PAST_1MONTH')), + HTMLHelper::_('select.option', 'past_3month', Text::_('COM_USERS_OPTION_RANGE_PAST_3MONTH')), + HTMLHelper::_('select.option', 'past_6month', Text::_('COM_USERS_OPTION_RANGE_PAST_6MONTH')), + HTMLHelper::_('select.option', 'past_year', Text::_('COM_USERS_OPTION_RANGE_PAST_YEAR')), + HTMLHelper::_('select.option', 'post_year', Text::_('COM_USERS_OPTION_RANGE_POST_YEAR')), + ); + + return $options; + } + + /** + * Creates a list of two factor authentication methods used in com_users + * on user view + * + * @return array + * + * @since 3.2.0 + * @throws \Exception + */ + public static function getTwoFactorMethods() + { + PluginHelper::importPlugin('twofactorauth'); + $identities = Factory::getApplication()->triggerEvent('onUserTwofactorIdentify', array()); + + $options = array( + HTMLHelper::_('select.option', 'none', Text::_('JGLOBAL_OTPMETHOD_NONE'), 'value', 'text'), + ); + + if (!empty($identities)) + { + foreach ($identities as $identity) + { + if (!is_object($identity)) + { + continue; + } + + $options[] = HTMLHelper::_('select.option', $identity->method, $identity->title, 'value', 'text'); + } + } + + return $options; + } + + /** + * Get a list of the User Groups for Viewing Access Levels + * + * @param string $rules User Groups in JSON format + * + * @return string $groups Comma separated list of User Groups + * + * @since 3.6 + */ + public static function getVisibleByGroups($rules) + { + $rules = json_decode($rules); + + if (!$rules) + { + return false; + } + + $rules = implode(',', $rules); + + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('a.title AS text') + ->from('#__usergroups as a') + ->where('a.id IN (' . $rules . ')'); + $db->setQuery($query); + + $groups = $db->loadColumn(); + $groups = implode(', ', $groups); + + return $groups; + } + + /** + * Adds Count Items for Tag Manager. + * + * @param \stdClass[] &$items The user note tag objects + * @param string $extension The name of the active view. + * + * @return \stdClass[] + * + * @since 3.6 + */ + public static function countTagItems(&$items, $extension) + { + $db = Factory::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->quoteName('#__contentitem_tag_map') . 'AS ct ') + ->where('ct.tag_id = ' . (int) $item->id) + ->where('ct.type_alias =' . $db->quote($extension)) + ->join('LEFT', $db->quoteName('#__categories') . ' AS c ON ct.content_item_id=c.id') + ->group('c.published'); + + $db->setQuery($query); + $users = $db->loadObjectList(); + + foreach ($users as $user) + { + if ($user->state == 1) + { + $item->count_published = $user->count; + } + + if ($user->state == 0) + { + $item->count_unpublished = $user->count; + } + + if ($user->state == 2) + { + $item->count_archived = $user->count; + } + + if ($user->state == -2) + { + $item->count_trashed = $user->count; + } + } + } + + return $items; + } + + /** + * Returns a valid section for users. If it is not valid then null + * is returned. + * + * @param string $section The section to get the mapping for + * + * @return string|null The new section + * + * @since 3.7.0 + * @throws \Exception + */ + public static function validateSection($section) + { + if (Factory::getApplication()->isClient('site')) + { + switch ($section) + { + case 'registration': + case 'profile': + $section = 'user'; + } + } + + if ($section != 'user') + { + // We don't know other sections + return null; + } + + return $section; + } + + /** + * Returns valid contexts + * + * @return array + * + * @since 3.7.0 + */ + public static function getContexts() + { + Factory::getLanguage()->load('com_users', JPATH_ADMINISTRATOR); + + $contexts = array( + 'com_users.user' => Text::_('COM_USERS'), + ); + + return $contexts; + } +} diff --git a/administrator/components/com_users/Helper/UsersHelperDebug.php b/administrator/components/com_users/Helper/UsersHelperDebug.php new file mode 100644 index 0000000000000..a9acc7d4bc7c9 --- /dev/null +++ b/administrator/components/com_users/Helper/UsersHelperDebug.php @@ -0,0 +1,160 @@ +getQuery(true) + ->select('name AS text, element AS value') + ->from('#__extensions') + ->where('enabled >= 1') + ->where('type =' . $db->quote('component')); + + $items = $db->setQuery($query)->loadObjectList(); + + if (count($items)) + { + $lang = Factory::getLanguage(); + + foreach ($items as &$item) + { + // Load language + $extension = $item->value; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) + || $lang->load("$extension.sys", $source, null, false, true); + + // Translate component name + $item->text = Text::_($item->text); + } + + // Sort by component name + $items = ArrayHelper::sortObjects($items, 'text', 1, true, true); + } + + return $items; + } + + /** + * Get a list of the actions for the component or code actions. + * + * @param string $component The name of the component. + * + * @return array + * + * @since 1.6 + */ + public static function getDebugActions($component = null) + { + $actions = array(); + + // Try to get actions for the component + if (!empty($component)) + { + $component_actions = Access::getActionsFromFile(JPATH_ADMINISTRATOR . '/components/' . $component . '/access.xml'); + + if (!empty($component_actions)) + { + foreach ($component_actions as &$action) + { + $actions[$action->title] = array($action->name, $action->description); + } + } + } + + // Use default actions from configuration if no component selected or component doesn't have actions + if (empty($actions)) + { + $filename = JPATH_ADMINISTRATOR . '/components/com_config/forms/application.xml'; + + if (is_file($filename)) + { + $xml = simplexml_load_file($filename); + + foreach ($xml->children()->fieldset as $fieldset) + { + if ('permissions' == (string) $fieldset['name']) + { + foreach ($fieldset->children() as $field) + { + if ('rules' == (string) $field['name']) + { + foreach ($field->children() as $action) + { + $actions[(string) $action['title']] = array( + (string) $action['name'], + (string) $action['description'] + ); + } + + break; + } + } + } + } + + // Load language + $lang = Factory::getLanguage(); + $extension = 'com_config'; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + + $lang->load($extension, JPATH_ADMINISTRATOR, null, false, false) + || $lang->load($extension, $source, null, false, false) + || $lang->load($extension, JPATH_ADMINISTRATOR, $lang->getDefault(), false, false) + || $lang->load($extension, $source, $lang->getDefault(), false, false); + } + } + + return $actions; + } + + /** + * Get a list of filter options for the levels. + * + * @return array An array of \JHtmlOption elements. + */ + public static function getLevelsOptions() + { + // Build the filter options. + $options = array(); + $options[] = HTMLHelper::_('select.option', '1', Text::sprintf('COM_USERS_OPTION_LEVEL_COMPONENT', 1)); + $options[] = HTMLHelper::_('select.option', '2', Text::sprintf('COM_USERS_OPTION_LEVEL_CATEGORY', 2)); + $options[] = HTMLHelper::_('select.option', '3', Text::sprintf('COM_USERS_OPTION_LEVEL_DEEPER', 3)); + $options[] = HTMLHelper::_('select.option', '4', '4'); + $options[] = HTMLHelper::_('select.option', '5', '5'); + $options[] = HTMLHelper::_('select.option', '6', '6'); + + return $options; + } +} diff --git a/administrator/components/com_users/Model/DebuggroupModel.php b/administrator/components/com_users/Model/DebuggroupModel.php new file mode 100644 index 0000000000000..ce322612b1326 --- /dev/null +++ b/administrator/components/com_users/Model/DebuggroupModel.php @@ -0,0 +1,285 @@ +getState('filter.component'); + + return UsersHelperDebug::getDebugActions($component); + } + + /** + * Override getItems method. + * + * @return array + * + * @since 1.6 + */ + public function getItems() + { + $groupId = $this->getState('group_id'); + + if (($assets = parent::getItems()) && $groupId) + { + $actions = $this->getDebugActions(); + + foreach ($assets as &$asset) + { + $asset->checks = array(); + + foreach ($actions as $action) + { + $name = $action[0]; + $level = $action[1]; + + // Check that we check this action for the level of the asset. + if ($level === null || $level >= $asset->level) + { + // We need to test this action. + $asset->checks[$name] = Access::checkGroup($groupId, $name, $asset->name); + } + else + { + // We ignore this action. + $asset->checks[$name] = 'skip'; + } + } + } + } + + return $assets; + } + + /** + * 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 1.6 + */ + protected function populateState($ordering = 'a.lft', $direction = 'asc') + { + $app = Factory::getApplication(); + + // Adjust the context to support modal layouts. + $layout = $app->input->get('layout', 'default'); + + if ($layout) + { + $this->context .= '.' . $layout; + } + + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('group_id', $this->getUserStateFromRequest($this->context . '.group_id', 'group_id', 0, 'int', false)); + + $levelStart = $this->getUserStateFromRequest($this->context . '.filter.level_start', 'filter_level_start', '', 'cmd'); + $this->setState('filter.level_start', $levelStart); + + $value = $this->getUserStateFromRequest($this->context . '.filter.level_end', 'filter_level_end', '', 'cmd'); + + if ($value > 0 && $value < $levelStart) + { + $value = $levelStart; + } + + $this->setState('filter.level_end', $value); + + $this->setState('filter.component', $this->getUserStateFromRequest($this->context . '.filter.component', 'filter_component', '', 'string')); + + // Load the parameters. + $params = ComponentHelper::getParams('com_users'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('group_id'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.level_start'); + $id .= ':' . $this->getState('filter.level_end'); + $id .= ':' . $this->getState('filter.component'); + + return parent::getStoreId($id); + } + + /** + * Get the group being debugged. + * + * @return CMSObject + * + * @since 1.6 + */ + public function getGroup() + { + $groupId = (int) $this->getState('group_id'); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('id, title') + ->from('#__usergroups') + ->where('id = ' . $groupId); + + $db->setQuery($query); + + try + { + $group = $db->loadObject(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return $group; + } + + /** + * Build an SQL query to load the list data. + * + * @return DatabaseQuery + * + * @since 1.6 + */ + 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.id, a.name, a.title, a.level, a.lft, a.rgt' + ) + ); + $query->from($db->quoteName('#__assets', 'a')); + + // Filter the items over the search string if set. + if ($this->getState('filter.search')) + { + // Escape the search token. + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($this->getState('filter.search')), true) . '%')); + + // Compile the different search clauses. + $searches = array(); + $searches[] = 'a.name LIKE ' . $search; + $searches[] = 'a.title LIKE ' . $search; + + // Add the clauses to the query. + $query->where('(' . implode(' OR ', $searches) . ')'); + } + + // Filter on the start and end levels. + $levelStart = (int) $this->getState('filter.level_start'); + $levelEnd = (int) $this->getState('filter.level_end'); + + if ($levelEnd > 0 && $levelEnd < $levelStart) + { + $levelEnd = $levelStart; + } + + if ($levelStart > 0) + { + $query->where('a.level >= ' . $levelStart); + } + + if ($levelEnd > 0) + { + $query->where('a.level <= ' . $levelEnd); + } + + // Filter the items over the component if set. + if ($this->getState('filter.component')) + { + $component = $this->getState('filter.component'); + $query->where('(a.name = ' . $db->quote($component) . ' OR a.name LIKE ' . $db->quote($component . '.%') . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } +} diff --git a/administrator/components/com_users/Model/DebuguserModel.php b/administrator/components/com_users/Model/DebuguserModel.php new file mode 100644 index 0000000000000..c2e82c9403f5e --- /dev/null +++ b/administrator/components/com_users/Model/DebuguserModel.php @@ -0,0 +1,267 @@ +getState('filter.component'); + + return UsersHelperDebug::getDebugActions($component); + } + + /** + * Override getItems method. + * + * @return array + * + * @since 1.6 + */ + public function getItems() + { + $userId = $this->getState('user_id'); + $user = Factory::getUser($userId); + + if (($assets = parent::getItems()) && $userId) + { + $actions = $this->getDebugActions(); + + foreach ($assets as &$asset) + { + $asset->checks = array(); + + foreach ($actions as $action) + { + $name = $action[0]; + $level = $action[1]; + + // Check that we check this action for the level of the asset. + if ($level === null || $level >= $asset->level) + { + // We need to test this action. + $asset->checks[$name] = $user->authorise($name, $asset->name); + } + else + { + // We ignore this action. + $asset->checks[$name] = 'skip'; + } + } + } + } + + return $assets; + } + + /** + * 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 1.6 + * @throws \Exception + */ + protected function populateState($ordering = 'a.lft', $direction = 'asc') + { + $app = Factory::getApplication(); + + // Adjust the context to support modal layouts. + $layout = $app->input->get('layout', 'default'); + + if ($layout) + { + $this->context .= '.' . $layout; + } + + // Load the filter state. + $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); + $this->setState('user_id', $this->getUserStateFromRequest($this->context . '.user_id', 'user_id', 0, 'int', false)); + + $levelStart = $this->getUserStateFromRequest($this->context . '.filter.level_start', 'filter_level_start', '', 'cmd'); + $this->setState('filter.level_start', $levelStart); + + $value = $this->getUserStateFromRequest($this->context . '.filter.level_end', 'filter_level_end', '', 'cmd'); + + if ($value > 0 && $value < $levelStart) + { + $value = $levelStart; + } + + $this->setState('filter.level_end', $value); + + $this->setState('filter.component', $this->getUserStateFromRequest($this->context . '.filter.component', 'filter_component', '', 'string')); + + // Load the parameters. + $params = ComponentHelper::getParams('com_users'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('user_id'); + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.level_start'); + $id .= ':' . $this->getState('filter.level_end'); + $id .= ':' . $this->getState('filter.component'); + + return parent::getStoreId($id); + } + + /** + * Get the user being debugged. + * + * @return User + * + * @since 1.6 + */ + public function getUser() + { + $userId = $this->getState('user_id'); + + return Factory::getUser($userId); + } + + /** + * Build an SQL query to load the list data. + * + * @return DatabaseQuery + * + * @since 1.6 + */ + 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.id, a.name, a.title, a.level, a.lft, a.rgt' + ) + ); + $query->from($db->quoteName('#__assets', 'a')); + + // Filter the items over the search string if set. + if ($this->getState('filter.search')) + { + // Escape the search token. + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($this->getState('filter.search')), true) . '%')); + + // Compile the different search clauses. + $searches = array(); + $searches[] = 'a.name LIKE ' . $search; + $searches[] = 'a.title LIKE ' . $search; + + // Add the clauses to the query. + $query->where('(' . implode(' OR ', $searches) . ')'); + } + + // Filter on the start and end levels. + $levelStart = (int) $this->getState('filter.level_start'); + $levelEnd = (int) $this->getState('filter.level_end'); + + if ($levelEnd > 0 && $levelEnd < $levelStart) + { + $levelEnd = $levelStart; + } + + if ($levelStart > 0) + { + $query->where('a.level >= ' . $levelStart); + } + + if ($levelEnd > 0) + { + $query->where('a.level <= ' . $levelEnd); + } + + // Filter the items over the component if set. + if ($this->getState('filter.component')) + { + $component = $this->getState('filter.component'); + $query->where('(a.name = ' . $db->quote($component) . ' OR a.name LIKE ' . $db->quote($component . '.%') . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } +} diff --git a/administrator/components/com_users/Model/GroupModel.php b/administrator/components/com_users/Model/GroupModel.php new file mode 100644 index 0000000000000..859461514b282 --- /dev/null +++ b/administrator/components/com_users/Model/GroupModel.php @@ -0,0 +1,343 @@ + 'onUserAfterDeleteGroup', + 'event_after_save' => 'onUserAfterSaveGroup', + 'event_before_delete' => 'onUserBeforeDeleteGroup', + 'event_before_save' => 'onUserBeforeSaveGroup', + 'events_map' => array('delete' => 'user', 'save' => 'user') + ), $config + ); + + parent::__construct($config, $factory); + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @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 Table A database object + * + * @since 1.6 + */ + public function getTable($type = 'Usergroup', $prefix = 'Joomla\\CMS\\Table\\', $config = array()) + { + $return = Table::getInstance($type, $prefix, $config); + + return $return; + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interogate. + * @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 + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_users.group', 'group', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + * @throws \Exception + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_users.edit.group.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_users.group', $data); + + return $data; + } + + /** + * Override preprocessForm to load the user plugin group instead of content. + * + * @param \JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws \Exception if there is an error loading the form. + */ + protected function preprocessForm(\JForm $form, $data, $group = '') + { + $obj = is_array($data) ? ArrayHelper::toObject($data, 'JObject') : $data; + + if (isset($obj->parent_id) && $obj->parent_id == 0 && $obj->id > 0) + { + $form->setFieldAttribute('parent_id', 'type', 'hidden'); + $form->setFieldAttribute('parent_id', 'hidden', 'true'); + } + + parent::preprocessForm($form, $data, 'user'); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + // Include the user plugins for events. + PluginHelper::importPlugin($this->events_map['save']); + + /** + * Check the super admin permissions for group + * We get the parent group permissions and then check the group permissions manually + * We have to calculate the group permissions manually because we haven't saved the group yet + */ + $parentSuperAdmin = Access::checkGroup($data['parent_id'], 'core.admin'); + + // Get core.admin rules from the root asset + $rules = Access::getAssetRules('root.1')->getData('core.admin'); + + // Get the value for the current group (will be true (allowed), false (denied), or null (inherit) + $groupSuperAdmin = $rules['core.admin']->allow($data['id']); + + // We only need to change the $groupSuperAdmin if the parent is true or false. Otherwise, the value set in the rule takes effect. + if ($parentSuperAdmin === false) + { + // If parent is false (Denied), effective value will always be false + $groupSuperAdmin = false; + } + elseif ($parentSuperAdmin === true) + { + // If parent is true (allowed), group is true unless explicitly set to false + $groupSuperAdmin = ($groupSuperAdmin === false) ? false : true; + } + + // Check for non-super admin trying to save with super admin group + $iAmSuperAdmin = Factory::getUser()->authorise('core.admin'); + + if (!$iAmSuperAdmin && $groupSuperAdmin) + { + $this->setError(Text::_('JLIB_USER_ERROR_NOT_SUPERADMIN')); + + return false; + } + + /** + * Check for super-admin changing self to be non-super-admin + * First, are we a super admin + */ + if ($iAmSuperAdmin) + { + // Next, are we a member of the current group? + $myGroups = Access::getGroupsByUser(Factory::getUser()->get('id'), false); + + if (in_array($data['id'], $myGroups)) + { + // Now, would we have super admin permissions without the current group? + $otherGroups = array_diff($myGroups, array($data['id'])); + $otherSuperAdmin = false; + + foreach ($otherGroups as $otherGroup) + { + $otherSuperAdmin = $otherSuperAdmin ?: Access::checkGroup($otherGroup, 'core.admin'); + } + + /** + * If we would not otherwise have super admin permissions + * and the current group does not have super admin permissions, throw an exception + */ + if ((!$otherSuperAdmin) && (!$groupSuperAdmin)) + { + $this->setError(Text::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF')); + + return false; + } + } + } + + if (Factory::getApplication()->input->get('task') == 'save2copy') + { + $data['title'] = $this->generateGroupTitle($data['parent_id'], $data['title']); + } + + // Proceed with the save + return parent::save($data); + } + + /** + * Method to delete rows. + * + * @param array &$pks An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + * @throws \Exception + */ + public function delete(&$pks) + { + // Typecast variable. + $pks = (array) $pks; + $user = Factory::getUser(); + $groups = Access::getGroupsByUser($user->get('id')); + + // Get a row instance. + $table = $this->getTable(); + + // Load plugins. + PluginHelper::importPlugin($this->events_map['delete']); + + // Check if I am a Super Admin + $iAmSuperAdmin = $user->authorise('core.admin'); + + // Do not allow to delete groups to which the current user belongs + foreach ($pks as $pk) + { + if (in_array($pk, $groups)) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_USERS_DELETE_ERROR_INVALID_GROUP'), 'error'); + + return false; + } + } + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + // Access checks. + $allow = $user->authorise('core.edit.state', 'com_users'); + + // Don't allow non-super-admin to delete a super admin + $allow = (!$iAmSuperAdmin && Access::checkGroup($pk, 'core.admin')) ? false : $allow; + + if ($allow) + { + // Fire the before delete event. + Factory::getApplication()->triggerEvent($this->event_before_delete, array($table->getProperties())); + + if (!$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + else + { + // Trigger the after delete event. + Factory::getApplication()->triggerEvent($this->event_after_delete, array($table->getProperties(), true, $this->getError())); + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('JERROR_CORE_DELETE_NOT_PERMITTED'), 'error'); + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + return true; + } + + /** + * Method to generate the title of group on Save as Copy action + * + * @param integer $parentId The id of the parent. + * @param string $title The title of group + * + * @return string Contains the modified title. + * + * @since 3.3.7 + */ + protected function generateGroupTitle($parentId, $title) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('title' => $title, 'parent_id' => $parentId))) + { + if ($title == $table->title) + { + $title = StringHelper::increment($title); + } + } + + return $title; + } +} diff --git a/administrator/components/com_users/Model/GroupsModel.php b/administrator/components/com_users/Model/GroupsModel.php new file mode 100644 index 0000000000000..9fe23a541027a --- /dev/null +++ b/administrator/components/com_users/Model/GroupsModel.php @@ -0,0 +1,252 @@ +setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Gets the list of groups and adds expensive joins to the result set. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 1.6 + */ + public function getItems() + { + // Get a storage key. + $store = $this->getStoreId(); + + // Try to load the data from internal storage. + if (empty($this->cache[$store])) + { + $items = parent::getItems(); + + // Bail out on an error or empty list. + if (empty($items)) + { + $this->cache[$store] = $items; + + return $items; + } + + try + { + $items = $this->populateExtraData($items); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Add the items to the internal cache. + $this->cache[$store] = $items; + } + + return $this->cache[$store]; + } + + /** + * Build an SQL query to load the list data. + * + * @return DatabaseQuery + */ + 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('#__usergroups') . ' AS a'); + + // Filter the comments over the search string if set. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.title LIKE ' . $search); + } + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Populate level & path for items. + * + * @param array $items Array of \stdClass objects + * + * @return array + * + * @since 3.6.3 + */ + private function populateExtraData(array $items) + { + // First pass: get list of the group id's and reset the counts. + $groupsByKey = array(); + + foreach ($items as $item) + { + $groupsByKey[(int) $item->id] = $item; + } + + $groupIds = array_keys($groupsByKey); + + $db = $this->getDbo(); + + // Get total enabled users in group. + $query = $db->getQuery(true); + + // Count the objects in the user group. + $query->select('map.group_id, COUNT(DISTINCT map.user_id) AS user_count') + ->from($db->quoteName('#__user_usergroup_map', 'map')) + ->join('LEFT', $db->quoteName('#__users', 'u') . ' ON ' . $db->quoteName('u.id') . ' = ' . $db->quoteName('map.user_id')) + ->where($db->quoteName('map.group_id') . ' IN (' . implode(',', $groupIds) . ')') + ->where($db->quoteName('u.block') . ' = 0') + ->group($db->quoteName('map.group_id')); + $db->setQuery($query); + + try + { + $countEnabled = $db->loadAssocList('group_id', 'count_enabled'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Get total disabled users in group. + $query->clear('where') + ->where('map.group_id IN (' . implode(',', $groupIds) . ')') + ->where('u.block = 1'); + $db->setQuery($query); + + try + { + $countDisabled = $db->loadAssocList('group_id', 'count_disabled'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Inject the values back into the array. + foreach ($groupsByKey as &$item) + { + $item->count_enabled = isset($countEnabled[$item->id]) ? (int) $countEnabled[$item->id]['user_count'] : 0; + $item->count_disabled = isset($countDisabled[$item->id]) ? (int) $countDisabled[$item->id]['user_count'] : 0; + $item->user_count = $item->count_enabled + $item->count_disabled; + } + + $groups = new UserGroupsHelper($groupsByKey); + + return array_values($groups->getAll()); + } +} diff --git a/administrator/components/com_users/Model/LevelModel.php b/administrator/components/com_users/Model/LevelModel.php new file mode 100644 index 0000000000000..6e07b80d8ed96 --- /dev/null +++ b/administrator/components/com_users/Model/LevelModel.php @@ -0,0 +1,230 @@ +levelsInUse === null) + { + // Populate the list once. + $this->levelsInUse = array(); + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('DISTINCT access'); + + // Get all the tables and the prefix + $tables = $db->getTableList(); + $prefix = $db->getPrefix(); + + foreach ($tables as $table) + { + // Get all of the columns in the table + $fields = $db->getTableColumns($table); + + /** + * We are looking for the access field. If custom tables are using something other + * than the 'access' field they are on their own unfortunately. + * Also make sure the table prefix matches the live db prefix (eg, it is not a "bak_" table) + */ + if (strpos($table, $prefix) === 0 && isset($fields['access'])) + { + // Lookup the distinct values of the field. + $query->clear('from') + ->from($db->quoteName($table)); + $db->setQuery($query); + + try + { + $values = $db->loadColumn(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + $this->levelsInUse = array_merge($this->levelsInUse, $values); + + // TODO Could assemble an array of the tables used by each view level list those, + // giving the user a clue in the error where to look. + } + } + + // Get uniques. + $this->levelsInUse = array_unique($this->levelsInUse); + + // Ok, after all that we are ready to check the record :) + } + + if (in_array($record->id, $this->levelsInUse)) + { + $this->setError(Text::sprintf('COM_USERS_ERROR_VIEW_LEVEL_IN_USE', $record->id, $record->title)); + + return false; + } + + return parent::canDelete($record); + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @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 Table A database object + * + * @since 1.6 + */ + public function getTable($type = 'ViewLevel', $prefix = 'Joomla\\CMS\\Table\\', $config = array()) + { + $return = Table::getInstance($type, $prefix, $config); + + return $return; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + $result = parent::getItem($pk); + + // Convert the params field to an array. + $result->rules = json_decode($result->rules); + + return $result; + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interogate. + * @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 + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm('com_users.level', 'level', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + * @throws \Exception + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_users.edit.level.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_users.level', $data); + + return $data; + } + + /** + * Method to preprocess the form + * + * @param \JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws \Exception if there is an error loading the form. + */ + protected function preprocessForm(\JForm $form, $data, $group = '') + { + // TO DO warning! + parent::preprocessForm($form, $data, 'user'); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + */ + public function save($data) + { + if (!isset($data['rules'])) + { + $data['rules'] = array(); + } + + $data['title'] = InputFilter::getInstance()->clean($data['title'], 'TRIM'); + + return parent::save($data); + } +} diff --git a/administrator/components/com_users/Model/LevelsModel.php b/administrator/components/com_users/Model/LevelsModel.php new file mode 100644 index 0000000000000..d7bcf1e1b0794 --- /dev/null +++ b/administrator/components/com_users/Model/LevelsModel.php @@ -0,0 +1,241 @@ +setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + + return parent::getStoreId($id); + } + + /** + * Build an SQL query to load the list data. + * + * @return DatabaseQuery + */ + 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('#__viewlevels') . ' AS a'); + + // Add the level in the tree. + $query->group('a.id, a.title, a.ordering, a.rules'); + + // Filter the items over the search string if set. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('a.title LIKE ' . $search); + } + } + + $query->group('a.id'); + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } + + /** + * Method to adjust the ordering of a row. + * + * @param integer $pk The ID of the primary key to move. + * @param integer $direction Increment, usually +1 or -1 + * + * @return boolean False on failure or error, true otherwise. + */ + public function reorder($pk, $direction = 0) + { + // Sanitize the id and adjustment. + $pk = (!empty($pk)) ? $pk : (int) $this->getState('level.id'); + $user = Factory::getUser(); + + // Get an instance of the record's table. + $table = Table::getInstance('viewlevel', 'Joomla\\CMS\Table\\'); + + // Load the row. + if (!$table->load($pk)) + { + $this->setError($table->getError()); + + return false; + } + + // Access checks. + $allow = $user->authorise('core.edit.state', 'com_users'); + + if (!$allow) + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); + + return false; + } + + // Move the row. + // TODO: Where clause to restrict category. + $table->move($pk); + + return true; + } + + /** + * Saves the manually set order of records. + * + * @param array $pks An array of primary key ids. + * @param integer $order Order position + * + * @return boolean Boolean true on success, boolean false + * + * @throws \Exception + */ + public function saveorder($pks, $order) + { + $table = Table::getInstance('viewlevel', 'Joomla\\CMS\Table\\'); + $user = Factory::getUser(); + $conditions = array(); + + if (empty($pks)) + { + Factory::getApplication()->enqueueMessage(Text::_('COM_USERS_ERROR_LEVELS_NOLEVELS_SELECTED'), 'error'); + + return false; + } + + // Update ordering values + foreach ($pks as $i => $pk) + { + $table->load((int) $pk); + + // Access checks. + $allow = $user->authorise('core.edit.state', 'com_users'); + + if (!$allow) + { + // Prune items that you can't change. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'error'); + } + elseif ($table->ordering != $order[$i]) + { + $table->ordering = $order[$i]; + + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + } + } + + // Execute reorder for each category. + foreach ($conditions as $cond) + { + $table->load($cond[0]); + $table->reorder($cond[1]); + } + + return true; + } +} diff --git a/administrator/components/com_users/Model/MailModel.php b/administrator/components/com_users/Model/MailModel.php new file mode 100644 index 0000000000000..bbd2b7a8a2046 --- /dev/null +++ b/administrator/components/com_users/Model/MailModel.php @@ -0,0 +1,248 @@ +loadForm('com_users.mail', 'mail', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + * @throws \Exception + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_users.display.mail.data', array()); + + $this->preprocessData('com_users.mail', $data); + + return $data; + } + + /** + * Method to preprocess the form + * + * @param \JForm $form A form object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws \Exception if there is an error loading the form. + */ + protected function preprocessForm(\JForm $form, $data, $group = 'user') + { + parent::preprocessForm($form, $data, $group); + } + + /** + * Send the email + * + * @return boolean + * + * @throws \Exception + */ + public function send() + { + $app = Factory::getApplication(); + $data = $app->input->post->get('jform', array(), 'array'); + $user = Factory::getUser(); + $access = new Access; + $db = $this->getDbo(); + + $mode = array_key_exists('mode', $data) ? (int) $data['mode'] : 0; + $subject = array_key_exists('subject', $data) ? $data['subject'] : ''; + $grp = array_key_exists('group', $data) ? (int) $data['group'] : 0; + $recurse = array_key_exists('recurse', $data) ? (int) $data['recurse'] : 0; + $bcc = array_key_exists('bcc', $data) ? (int) $data['bcc'] : 0; + $disabled = array_key_exists('disabled', $data) ? (int) $data['disabled'] : 0; + $message_body = array_key_exists('message', $data) ? $data['message'] : ''; + + // Automatically removes html formatting + if (!$mode) + { + $message_body = InputFilter::getInstance()->clean($message_body, 'string'); + } + + // Check for a message body and subject + if (!$message_body || !$subject) + { + $app->setUserState('com_users.display.mail.data', $data); + $this->setError(Text::_('COM_USERS_MAIL_PLEASE_FILL_IN_THE_FORM_CORRECTLY')); + + return false; + } + + // Get users in the group out of the ACL + $to = $access->getUsersByGroup($grp, $recurse); + + // Get all users email and group except for senders + $query = $db->getQuery(true) + ->select('email') + ->from('#__users') + ->where('id != ' . (int) $user->get('id')); + + if ($grp !== 0) + { + if (empty($to)) + { + $query->where('0'); + } + else + { + $query->where('id IN (' . implode(',', $to) . ')'); + } + } + + if ($disabled == 0) + { + $query->where('block = 0'); + } + + $db->setQuery($query); + $rows = $db->loadColumn(); + + // Check to see if there are any users in this group before we continue + if (!count($rows)) + { + $app->setUserState('com_users.display.mail.data', $data); + + if (in_array($user->id, $to)) + { + $this->setError(Text::_('COM_USERS_MAIL_ONLY_YOU_COULD_BE_FOUND_IN_THIS_GROUP')); + } + else + { + $this->setError(Text::_('COM_USERS_MAIL_NO_USERS_COULD_BE_FOUND_IN_THIS_GROUP')); + } + + return false; + } + + // Get the Mailer + $mailer = Factory::getMailer(); + $params = ComponentHelper::getParams('com_users'); + + try + { + // Build email message format. + $mailer->setSender(array($app->get('mailfrom'), $app->get('fromname'))); + $mailer->setSubject($params->get('mailSubjectPrefix') . stripslashes($subject)); + $mailer->setBody($message_body . $params->get('mailBodySuffix')); + $mailer->IsHtml($mode); + + // Add recipients + if ($bcc) + { + $mailer->addBcc($rows); + $mailer->addRecipient($app->get('mailfrom')); + } + else + { + $mailer->addRecipient($rows); + } + + // Send the Mail + $rs = $mailer->Send(); + } + catch (\Exception $exception) + { + try + { + Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror'); + + $rs = false; + } + catch (\RuntimeException $exception) + { + Factory::getApplication()->enqueueMessage(Text::_($exception->errorMessage()), 'warning'); + + $rs = false; + } + } + + + // Check for an error + if ($rs !== true) + { + $app->setUserState('com_users.display.mail.data', $data); + $this->setError($rs->getError()); + + return false; + } + elseif (empty($rs)) + { + $app->setUserState('com_users.display.mail.data', $data); + $this->setError(Text::_('COM_USERS_MAIL_THE_MAIL_COULD_NOT_BE_SENT')); + + return false; + } + else + { + /** + * Fill the data (specially for the 'mode', 'group' and 'bcc': they could not exist in the array + * when the box is not checked and in this case, the default value would be used instead of the '0' + * one) + */ + $data['mode'] = $mode; + $data['subject'] = $subject; + $data['group'] = $grp; + $data['recurse'] = $recurse; + $data['bcc'] = $bcc; + $data['message'] = $message_body; + $app->setUserState('com_users.display.mail.data', array()); + $app->enqueueMessage(Text::plural('COM_USERS_MAIL_EMAIL_SENT_TO_N_USERS', count($rows)), 'message'); + + return true; + } + } +} diff --git a/administrator/components/com_users/Model/NoteModel.php b/administrator/components/com_users/Model/NoteModel.php new file mode 100644 index 0000000000000..9bfb0c8afd1df --- /dev/null +++ b/administrator/components/com_users/Model/NoteModel.php @@ -0,0 +1,138 @@ +loadForm('com_users.note', 'note', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + return $form; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 2.5 + * @throws \Exception + */ + public function getItem($pk = null) + { + $result = parent::getItem($pk); + + // Get the dispatcher and load the content plugins. + PluginHelper::importPlugin('content'); + + // Load the user plugins for backward compatibility (v3.3.3 and earlier). + PluginHelper::importPlugin('user'); + + // Trigger the data preparation event. + Factory::getApplication()->triggerEvent('onContentPrepareData', array('com_users.note', $result)); + + return $result; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + * @throws \Exception + */ + protected function loadFormData() + { + // Get the application + $app = Factory::getApplication(); + + // Check the session for previously entered form data. + $data = $app->getUserState('com_users.edit.note.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + + // Prime some default values. + if ($this->getState('note.id') == 0) + { + $data->set('catid', $app->input->get('catid', $app->getUserState('com_users.notes.filter.category_id'), 'int')); + } + + $userId = $app->input->get('u_id', 0, 'int'); + + if ($userId != 0) + { + $data->user_id = $userId; + } + } + + $this->preprocessData('com_users.note', $data); + + return $data; + } + + /** + * Method to auto-populate the model state. + * + * Note. Calling getState in this method will result in recursion. + * + * @return void + * + * @since 2.5 + * @throws \Exception + */ + protected function populateState() + { + parent::populateState(); + + $userId = Factory::getApplication()->input->get('u_id', 0, 'int'); + $this->setState('note.user_id', $userId); + } +} diff --git a/administrator/components/com_users/Model/NotesModel.php b/administrator/components/com_users/Model/NotesModel.php new file mode 100644 index 0000000000000..9ad6267098d57 --- /dev/null +++ b/administrator/components/com_users/Model/NotesModel.php @@ -0,0 +1,225 @@ +getDbo(); + $query = $db->getQuery(true); + + // Select the required fields from the table. + $query->select( + $this->getState('list.select', + 'a.id, a.subject, a.checked_out, a.checked_out_time,' . + 'a.catid, a.created_time, a.review_time,' . + 'a.state, a.publish_up, a.publish_down' + ) + ); + $query->from('#__user_notes AS a'); + + // Join over the category + $query->select('c.title AS category_title, c.params AS category_params') + ->join('LEFT', '#__categories AS c ON c.id = a.catid'); + + // Join over the users for the note user. + $query->select('u.name AS user_name') + ->join('LEFT', '#__users AS u ON u.id = a.user_id'); + + // Join over the users for the checked out user. + $query->select('uc.name AS editor') + ->join('LEFT', '#__users AS uc ON uc.id = a.checked_out'); + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'uid:') === 0) + { + $query->where('a.user_id = ' . (int) substr($search, 4)); + } + else + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('((a.subject LIKE ' . $search . ') OR (u.name LIKE ' . $search . ') OR (u.username LIKE ' . $search . '))'); + } + } + + // Filter by published state + $published = $this->getState('filter.published'); + + if (is_numeric($published)) + { + $query->where('a.state = ' . (int) $published); + } + elseif ($published === '') + { + $query->where('(a.state IN (0, 1))'); + } + + // Filter by a single category. + $categoryId = (int) $this->getState('filter.category_id'); + + if ($categoryId) + { + $query->where('a.catid = ' . $categoryId); + } + + // Filter by a single user. + $userId = (int) $this->getState('filter.user_id'); + + if ($userId) + { + // Add the body and where filter. + $query->select('a.body') + ->where('a.user_id = ' . $userId); + } + + // Filter on the level. + if ($level = $this->getState('filter.level')) + { + $query->where($db->quoteName('c.level') . ' <= ' . (int) $level); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 'a.review_time')) . ' ' . $db->escape($this->getState('list.direction', 'DESC'))); + + 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 A store id. + * + * @since 2.5 + */ + 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 .= ':' . $this->getState('filter.user_id'); + $id .= ':' . $this->getState('filter.level'); + + return parent::getStoreId($id); + } + + /** + * Gets a user object if the user filter is set. + * + * @return User The User object + * + * @since 2.5 + */ + public function getUser() + { + $user = new User; + + // Filter by search in title + $search = (int) $this->getState('filter.user_id'); + + if ($search != 0) + { + $user->load((int) $search); + } + + return $user; + } + + /** + * 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 1.6 + * @throws \Exception + */ + protected function populateState($ordering = 'a.review_time', $direction = 'desc') + { + // Adjust the context to support modal layouts. + if ($layout = Factory::getApplication()->input->get('layout')) + { + $this->context .= '.' . $layout; + } + + parent::populateState($ordering, $direction); + } +} diff --git a/administrator/components/com_users/Model/UserModel.php b/administrator/components/com_users/Model/UserModel.php new file mode 100644 index 0000000000000..a7d14c7487c88 --- /dev/null +++ b/administrator/components/com_users/Model/UserModel.php @@ -0,0 +1,1418 @@ + 'onUserAfterDelete', + 'event_after_save' => 'onUserAfterSave', + 'event_before_delete' => 'onUserBeforeDelete', + 'event_before_save' => 'onUserBeforeSave', + 'events_map' => array('save' => 'user', 'delete' => 'user', 'validate' => 'user') + ), $config + ); + + parent::__construct($config, $factory); + } + + /** + * Returns a reference to the a Table object, always creating it. + * + * @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 Table A database object + * + * @since 1.6 + */ + public function getTable($type = 'User', $prefix = 'Joomla\\CMS\\Table\\', $config = array()) + { + $table = Table::getInstance($type, $prefix, $config); + + return $table; + } + + /** + * Method to get a single record. + * + * @param integer $pk The id of the primary key. + * + * @return mixed Object on success, false on failure. + * + * @since 1.6 + */ + public function getItem($pk = null) + { + $pk = (!empty($pk)) ? $pk : (int) $this->getState('user.id'); + + if ($this->_item === null) + { + $this->_item = array(); + } + + if (!isset($this->_item[$pk])) + { + $result = parent::getItem($pk); + + if ($result) + { + $result->tags = new TagsHelper; + $result->tags->getTagIds($result->id, 'com_users.user'); + } + + $this->_item[$pk] = $result; + } + + return $this->_item[$pk]; + } + + /** + * Method to get the record form. + * + * @param array $data An optional array of data for the form to interogate. + * @param boolean $loadData True if the form is to load its own data (default case), false if not. + * + * @return mixed A \JForm object on success, false on failure + * + * @since 1.6 + */ + public function getForm($data = array(), $loadData = true) + { + $pluginParams = new Registry; + + if (PluginHelper::isEnabled('user', 'joomla')) + { + $plugin = PluginHelper::getPlugin('user', 'joomla'); + $pluginParams->loadString($plugin->params); + } + + // Get the form. + $form = $this->loadForm('com_users.user', 'user', array('control' => 'jform', 'load_data' => $loadData)); + + if (empty($form)) + { + return false; + } + + // Passwords fields are required when mail to user is set to No in joomla user plugin + $userId = $form->getValue('id'); + + if ($userId === 0 && $pluginParams->get('mail_to_user', '1') === '0') + { + $form->setFieldAttribute('password', 'required', 'true'); + $form->setFieldAttribute('password2', 'required', 'true'); + } + + // If the user needs to change their password, mark the password fields as required + if (Factory::getUser()->requireReset) + { + $form->setFieldAttribute('password', 'required', 'true'); + $form->setFieldAttribute('password2', 'required', 'true'); + } + + // When multilanguage is set, a user's default site language should also be a Content Language + if (Multilanguage::isEnabled()) + { + $form->setFieldAttribute('language', 'type', 'frontend_language', 'params'); + } + + // The user should not be able to set the requireReset value on their own account + if ((int) $userId === (int) Factory::getUser()->id) + { + $form->removeField('requireReset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since 1.6 + * @throws \Exception + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState('com_users.edit.user.data', array()); + + if (empty($data)) + { + $data = $this->getItem(); + } + + $this->preprocessData('com_users.profile', $data, 'user'); + + return $data; + } + + /** + * Override Joomla\CMS\MVC\Model\AdminModel::preprocessForm to ensure the correct plugin group is loaded. + * + * @param \JForm $form A \JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since 1.6 + * @throws \Exception if there is an error in the form event. + */ + protected function preprocessForm(\JForm $form, $data, $group = 'user') + { + parent::preprocessForm($form, $data, $group); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since 1.6 + * @throws \Exception + */ + public function save($data) + { + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('user.id'); + $user = User::getInstance($pk); + + $my = Factory::getUser(); + $iAmSuperAdmin = $my->authorise('core.admin'); + + // User cannot modify own user groups + if ((int) $user->id == (int) $my->id && !$iAmSuperAdmin && isset($data['groups'])) + { + // Form was probably tampered with + Factory::getApplication()->enqueueMessage(Text::_('COM_USERS_USERS_ERROR_CANNOT_EDIT_OWN_GROUP'), 'warning'); + + $data['groups'] = null; + } + + if ($data['block'] && $pk == $my->id && !$my->block) + { + $this->setError(Text::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); + + return false; + } + + // Make sure user groups is selected when add/edit an account + if (empty($data['groups']) && ((int) $user->id != (int) $my->id || $iAmSuperAdmin)) + { + $this->setError(Text::_('COM_USERS_USERS_ERROR_CANNOT_SAVE_ACCOUNT_WITHOUT_GROUPS')); + + return false; + } + + // Make sure that we are not removing ourself from Super Admin group + if ($iAmSuperAdmin && $my->get('id') == $pk) + { + // Check that at least one of our new groups is Super Admin + $stillSuperAdmin = false; + $myNewGroups = $data['groups']; + + foreach ($myNewGroups as $group) + { + $stillSuperAdmin = $stillSuperAdmin ?: Access::checkGroup($group, 'core.admin'); + } + + if (!$stillSuperAdmin) + { + $this->setError(Text::_('COM_USERS_USERS_ERROR_CANNOT_DEMOTE_SELF')); + + return false; + } + } + + // Handle the two factor authentication setup + if (array_key_exists('twofactor', $data)) + { + $twoFactorMethod = $data['twofactor']['method']; + + // Get the current One Time Password (two factor auth) configuration + $otpConfig = $this->getOtpConfig($pk); + + if ($twoFactorMethod != 'none') + { + // Run the plugins + PluginHelper::importPlugin('twofactorauth'); + $otpConfigReplies = Factory::getApplication()->triggerEvent('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($pk, $otpConfig); + + // Generate one time emergency passwords if required (depleted or not set) + if (empty($otpConfig->otep)) + { + $oteps = $this->generateOteps($pk); + } + } + else + { + $otpConfig->method = 'none'; + $otpConfig->config = array(); + $this->setOtpConfig($pk, $otpConfig); + } + + // Unset the raw data + unset($data['twofactor']); + + // Reload the user record with the updated OTP configuration + $user->load($pk); + } + + // Bind the data. + if (!$user->bind($data)) + { + $this->setError($user->getError()); + + return false; + } + + // Store the data. + if (!$user->save()) + { + $this->setError($user->getError()); + + return false; + } + + $this->setState('user.id', $user->id); + + return true; + } + + /** + * Method to delete rows. + * + * @param array &$pks An array of item ids. + * + * @return boolean Returns true on success, false on failure. + * + * @since 1.6 + * @throws \Exception + */ + public function delete(&$pks) + { + $user = Factory::getUser(); + $table = $this->getTable(); + $pks = (array) $pks; + + // Check if I am a Super Admin + $iAmSuperAdmin = $user->authorise('core.admin'); + + PluginHelper::importPlugin($this->events_map['delete']); + + if (in_array($user->id, $pks)) + { + $this->setError(Text::_('COM_USERS_USERS_ERROR_CANNOT_DELETE_SELF')); + + return false; + } + + // Iterate the items to delete each one. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + // Access checks. + $allow = $user->authorise('core.delete', 'com_users'); + + // Don't allow non-super-admin to delete a super admin + $allow = (!$iAmSuperAdmin && Access::check($pk, 'core.admin')) ? false : $allow; + + if ($allow) + { + // Get users data for the users to delete. + $user_to_delete = Factory::getUser($pk); + + // Fire the before delete event. + Factory::getApplication()->triggerEvent($this->event_before_delete, array($table->getProperties())); + + if (!$table->delete($pk)) + { + $this->setError($table->getError()); + + return false; + } + else + { + // Trigger the after delete event. + Factory::getApplication()->triggerEvent($this->event_after_delete, array($user_to_delete->getProperties(), true, $this->getError())); + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('JERROR_CORE_DELETE_NOT_PERMITTED'), 'error'); + } + } + else + { + $this->setError($table->getError()); + + return false; + } + } + + return true; + } + + /** + * Method to block user records. + * + * @param array &$pks The ids of the items to publish. + * @param integer $value The value of the published state + * + * @return boolean True on success. + * + * @since 1.6 + * @throws \Exception + */ + public function block(&$pks, $value = 1) + { + $app = Factory::getApplication(); + $user = Factory::getUser(); + + // Check if I am a Super Admin + $iAmSuperAdmin = $user->authorise('core.admin'); + $table = $this->getTable(); + $pks = (array) $pks; + + PluginHelper::importPlugin($this->events_map['save']); + + // Prepare the logout options. + $options = array( + 'clientid' => $app->get('shared_session', '0') ? null : 0, + ); + + // Access checks. + foreach ($pks as $i => $pk) + { + if ($value == 1 && $pk == $user->get('id')) + { + // Cannot block yourself. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF'), 'error'); + } + elseif ($table->load($pk)) + { + $old = $table->getProperties(); + $allow = $user->authorise('core.edit.state', 'com_users'); + + // Don't allow non-super-admin to delete a super admin + $allow = (!$iAmSuperAdmin && Access::check($pk, 'core.admin')) ? false : $allow; + + if ($allow) + { + // Skip changing of same state + if ($table->block == $value) + { + unset($pks[$i]); + continue; + } + + $table->block = (int) $value; + + // If unblocking, also change password reset count to zero to unblock reset + if ($table->block === 0) + { + $table->resetCount = 0; + } + + // Allow an exception to be thrown. + try + { + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = Factory::getApplication()->triggerEvent($this->event_before_save, array($old, false, $table->getProperties())); + + if (in_array(false, $result, true)) + { + // Plugin will have to raise its own error or throw an exception. + return false; + } + + // Store the table. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the after save event + Factory::getApplication()->triggerEvent($this->event_after_save, array($table->getProperties(), false, true, null)); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Log the user out. + if ($value) + { + $app->logout($table->id, $options); + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'error'); + } + } + } + + return true; + } + + /** + * Method to activate user records. + * + * @param array &$pks The ids of the items to activate. + * + * @return boolean True on success. + * + * @since 1.6 + * @throws \Exception + */ + public function activate(&$pks) + { + $user = Factory::getUser(); + + // Check if I am a Super Admin + $iAmSuperAdmin = $user->authorise('core.admin'); + $table = $this->getTable(); + $pks = (array) $pks; + + PluginHelper::importPlugin($this->events_map['save']); + + // Access checks. + foreach ($pks as $i => $pk) + { + if ($table->load($pk)) + { + $old = $table->getProperties(); + $allow = $user->authorise('core.edit.state', 'com_users'); + + // Don't allow non-super-admin to delete a super admin + $allow = (!$iAmSuperAdmin && Access::check($pk, 'core.admin')) ? false : $allow; + + if (empty($table->activation)) + { + // Ignore activated accounts. + unset($pks[$i]); + } + elseif ($allow) + { + $table->block = 0; + $table->activation = ''; + + // Allow an exception to be thrown. + try + { + if (!$table->check()) + { + $this->setError($table->getError()); + + return false; + } + + // Trigger the before save event. + $result = Factory::getApplication()->triggerEvent($this->event_before_save, array($old, false, $table->getProperties())); + + if (in_array(false, $result, true)) + { + // Plugin will have to raise it's own error or throw an exception. + return false; + } + + // Store the table. + if (!$table->store()) + { + $this->setError($table->getError()); + + return false; + } + + // Fire the after save event + Factory::getApplication()->triggerEvent($this->event_after_save, array($table->getProperties(), false, true, null)); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + else + { + // Prune items that you can't change. + unset($pks[$i]); + Factory::getApplication()->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED'), 'error'); + } + } + } + + return true; + } + + /** + * Method to perform batch operations on an item or a set of items. + * + * @param array $commands An array of commands to perform. + * @param array $pks An array of item ids. + * @param array $contexts An array of item contexts. + * + * @return boolean Returns true on success, false on failure. + * + * @since 2.5 + */ + public function batch($commands, $pks, $contexts) + { + // Sanitize user ids. + $pks = array_unique($pks); + $pks = ArrayHelper::toInteger($pks); + + // Remove any values of zero. + if (array_search(0, $pks, true)) + { + unset($pks[array_search(0, $pks, true)]); + } + + if (empty($pks)) + { + $this->setError(Text::_('COM_USERS_USERS_NO_ITEM_SELECTED')); + + return false; + } + + $done = false; + + if (!empty($commands['group_id'])) + { + $cmd = ArrayHelper::getValue($commands, 'group_action', 'add'); + + if (!$this->batchUser((int) $commands['group_id'], $pks, $cmd)) + { + return false; + } + + $done = true; + } + + if (!empty($commands['reset_id'])) + { + if (!$this->batchReset($pks, $commands['reset_id'])) + { + return false; + } + + $done = true; + } + + if (!$done) + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); + + return false; + } + + // Clear the cache + $this->cleanCache(); + + return true; + } + + /** + * Batch flag users as being required to reset their passwords + * + * @param array $user_ids An array of user IDs on which to operate + * @param string $action The action to perform + * + * @return boolean True on success, false on failure + * + * @since 3.2 + */ + public function batchReset($user_ids, $action) + { + $user_ids = ArrayHelper::toInteger($user_ids); + + // Check if I am a Super Admin + $iAmSuperAdmin = Factory::getUser()->authorise('core.admin'); + + // Non-super super user cannot work with super-admin user. + if (!$iAmSuperAdmin && UserHelper::checkSuperUserInUsers($user_ids)) + { + $this->setError(Text::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER')); + + return false; + } + + // Set the action to perform + if ($action === 'yes') + { + $value = 1; + } + else + { + $value = 0; + } + + // Prune out the current user if they are in the supplied user ID array + $user_ids = array_diff($user_ids, array(Factory::getUser()->id)); + + if (empty($user_ids)) + { + $this->setError(Text::_('COM_USERS_USERS_ERROR_CANNOT_REQUIRERESET_SELF')); + + return false; + } + + // Get the DB object + $db = $this->getDbo(); + + $user_ids = ArrayHelper::toInteger($user_ids); + + $query = $db->getQuery(true); + + // Update the reset flag + $query->update($db->quoteName('#__users')) + ->set($db->quoteName('requireReset') . ' = ' . $value) + ->where($db->quoteName('id') . ' IN (' . implode(',', $user_ids) . ')'); + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + return true; + } + + /** + * Perform batch operations + * + * @param integer $group_id The group ID which assignments are being edited + * @param array $user_ids An array of user IDs on which to operate + * @param string $action The action to perform + * + * @return boolean True on success, false on failure + * + * @since 1.6 + */ + public function batchUser($group_id, $user_ids, $action) + { + $user_ids = ArrayHelper::toInteger($user_ids); + + // Check if I am a Super Admin + $iAmSuperAdmin = Factory::getUser()->authorise('core.admin'); + + // Non-super super user cannot work with super-admin user. + if (!$iAmSuperAdmin && UserHelper::checkSuperUserInUsers($user_ids)) + { + $this->setError(Text::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER')); + + return false; + } + + // Non-super admin cannot work with super-admin group. + if ((!$iAmSuperAdmin && Access::checkGroup($group_id, 'core.admin')) || $group_id < 1) + { + $this->setError(Text::_('COM_USERS_ERROR_INVALID_GROUP')); + + return false; + } + + // Get the DB object + $db = $this->getDbo(); + + switch ($action) + { + // Sets users to a selected group + case 'set': + $doDelete = 'all'; + $doAssign = true; + break; + + // Remove users from a selected group + case 'del': + $doDelete = 'group'; + break; + + // Add users to a selected group + case 'add': + default: + $doAssign = true; + break; + } + + // Remove the users from the group if requested. + if (isset($doDelete)) + { + $query = $db->getQuery(true); + + // Remove users from the group + $query->delete($db->quoteName('#__user_usergroup_map')) + ->where($db->quoteName('user_id') . ' IN (' . implode(',', $user_ids) . ')'); + + // Only remove users from selected group + if ($doDelete == 'group') + { + $query->where($db->quoteName('group_id') . ' = ' . (int) $group_id); + } + + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + // Assign the users to the group if requested. + if (isset($doAssign)) + { + $query = $db->getQuery(true); + + // First, we need to check if the user is already assigned to a group + $query->select($db->quoteName('user_id')) + ->from($db->quoteName('#__user_usergroup_map')) + ->where($db->quoteName('group_id') . ' = ' . (int) $group_id); + $db->setQuery($query); + $users = $db->loadColumn(); + + // Build the values clause for the assignment query. + $query->clear(); + $groups = false; + + foreach ($user_ids as $id) + { + if (!in_array($id, $users)) + { + $query->values($id . ',' . $group_id); + $groups = true; + } + } + + // If we have no users to process, throw an error to notify the user + if (!$groups) + { + $this->setError(Text::_('COM_USERS_ERROR_NO_ADDITIONS')); + + return false; + } + + $query->insert($db->quoteName('#__user_usergroup_map')) + ->columns(array($db->quoteName('user_id'), $db->quoteName('group_id'))); + $db->setQuery($query); + + try + { + $db->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + } + + return true; + } + + /** + * Gets the available groups. + * + * @return array An array of groups + * + * @since 1.6 + */ + public function getGroups() + { + $user = Factory::getUser(); + + if ($user->authorise('core.edit', 'com_users') && $user->authorise('core.manage', 'com_users')) + { + $model = new GroupsModel(array('ignore_request' => true)); + + return $model->getItems(); + } + else + { + return null; + } + } + + /** + * Gets the groups this object is assigned to + * + * @param integer $userId The user ID to retrieve the groups for + * + * @return array An array of assigned groups + * + * @since 1.6 + */ + public function getAssignedGroups($userId = null) + { + $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); + + if (empty($userId)) + { + $result = array(); + $form = $this->getForm(); + + if ($form) + { + $groupsIDs = $form->getValue('groups'); + } + + if (!empty($groupsIDs)) + { + $result = $groupsIDs; + } + else + { + $config = ComponentHelper::getParams('com_users'); + + if ($groupId = $config->get('new_usertype')) + { + $result[] = $groupId; + } + } + } + else + { + $result = UserHelper::getUserGroups($userId); + } + + return $result; + } + + /** + * Returns the one time password (OTP) – a.k.a. two factor authentication – + * configuration for a particular user. + * + * @param integer $user_id The numeric ID of the user + * + * @return \stdClass An object holding the OTP configuration for this user + * + * @since 3.2 + */ + public function getOtpConfig($user_id = null) + { + $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); + + // Initialise + $otpConfig = (object) array( + 'method' => 'none', + 'config' => array(), + 'otep' => array() + ); + + /** + * Get the raw data, without going through User (required in order to + * be able to modify the user record before logging in the user). + */ + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select('*') + ->from($db->quoteName('#__users')) + ->where($db->quoteName('id') . ' = ' . (int) $user_id); + $db->setQuery($query); + $item = $db->loadObject(); + + // Make sure this user does have OTP enabled + if (empty($item->otpKey)) + { + return $otpConfig; + } + + // Get the encrypted data + list($method, $config) = explode(':', $item->otpKey, 2); + $encryptedOtep = $item->otep; + + // Get the secret key, yes the thing that is saved in the configuration file + $key = $this->getOtpConfigEncryptionKey(); + + if (strpos($config, '{') === false) + { + $openssl = new Aes($key, 256); + $mcrypt = new Aes($key, 256, 'cbc', null, 'mcrypt'); + + $decryptedConfig = $mcrypt->decryptString($config); + + if (strpos($decryptedConfig, '{') !== false) + { + // Data encrypted with mcrypt + $decryptedOtep = $mcrypt->decryptString($encryptedOtep); + $encryptedOtep = $openssl->encryptString($decryptedOtep); + } + else + { + // Config data seems to be save encrypted, this can happen with 3.6.3 and openssl, lets get the data + $decryptedConfig = $openssl->decryptString($config); + } + + $otpKey = $method . ':' . $decryptedConfig; + + $query = $db->getQuery(true) + ->update($db->quoteName('#__users')) + ->set($db->quoteName('otep') . '=' . $db->quote($encryptedOtep)) + ->set($db->quoteName('otpKey') . '=' . $db->quote($otpKey)) + ->where($db->quoteName('id') . ' = ' . $db->quote($user_id)); + $db->setQuery($query); + $db->execute(); + } + else + { + $decryptedConfig = $config; + } + + // Create an encryptor class + $aes = new Aes($key, 256); + + // Decrypt the data + $decryptedOtep = $aes->decryptString($encryptedOtep); + + // Remove the null padding added during encryption + $decryptedConfig = rtrim($decryptedConfig, "\0"); + $decryptedOtep = rtrim($decryptedOtep, "\0"); + + // Update the configuration object + $otpConfig->method = $method; + $otpConfig->config = @json_decode($decryptedConfig); + $otpConfig->otep = @json_decode($decryptedOtep); + + /* + * If the decryption failed for any reason we essentially disable the + * two-factor authentication. This prevents impossible to log in sites + * if the site admin changes the site secret for any reason. + */ + if (is_null($otpConfig->config)) + { + $otpConfig->config = array(); + } + + if (is_object($otpConfig->config)) + { + $otpConfig->config = (array) $otpConfig->config; + } + + if (is_null($otpConfig->otep)) + { + $otpConfig->otep = array(); + } + + if (is_object($otpConfig->otep)) + { + $otpConfig->otep = (array) $otpConfig->otep; + } + + // Return the configuration object + return $otpConfig; + } + + /** + * 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 $user_id The numeric ID of the user + * @param \stdClass $otpConfig The OTP configuration object + * + * @return boolean True on success + * + * @since 3.2 + */ + public function setOtpConfig($user_id, $otpConfig) + { + $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); + + $updates = (object) array( + 'id' => $user_id, + 'otpKey' => '', + 'otep' => '' + ); + + // Create an encryptor class + $key = $this->getOtpConfigEncryptionKey(); + $aes = new Aes($key, 256); + + // Create the encrypted option strings + if (!empty($otpConfig->method) && ($otpConfig->method != 'none')) + { + $decryptedConfig = json_encode($otpConfig->config); + $decryptedOtep = json_encode($otpConfig->otep); + $updates->otpKey = $otpConfig->method . ':' . $decryptedConfig; + $updates->otep = $aes->encryptString($decryptedOtep); + } + + $db = $this->getDbo(); + $result = $db->updateObject('#__users', $updates, 'id'); + + return $result; + } + + /** + * Gets the symmetric encryption key for the OTP configuration data. It + * currently returns the site's secret. + * + * @return string The encryption key + * + * @since 3.2 + */ + public function getOtpConfigEncryptionKey() + { + return Factory::getConfig()->get('secret'); + } + + /** + * Gets the configuration forms for all two-factor authentication methods + * in an array. + * + * @param integer $user_id The user ID to load the forms for (optional) + * + * @return array + * + * @since 3.2 + * @throws \Exception + */ + public function getTwofactorform($user_id = null) + { + $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); + + $otpConfig = $this->getOtpConfig($user_id); + + PluginHelper::importPlugin('twofactorauth'); + + return Factory::getApplication()->triggerEvent('onUserTwofactorShowConfiguration', array($otpConfig, $user_id)); + } + + /** + * Generates a new set of One Time Emergency Passwords (OTEPs) for a given user. + * + * @param integer $user_id The user ID + * @param integer $count How many OTEPs to generate? Default: 10 + * + * @return array The generated OTEPs + * + * @since 3.2 + */ + public function generateOteps($user_id, $count = 10) + { + $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); + + // Initialise + $oteps = array(); + + // Get the OTP configuration for the user + $otpConfig = $this->getOtpConfig($user_id); + + // If two factor authentication is not enabled, abort + if (empty($otpConfig->method) || ($otpConfig->method == 'none')) + { + return $oteps; + } + + $salt = '0123456789'; + $base = strlen($salt); + $length = 16; + + for ($i = 0; $i < $count; $i++) + { + $makepass = ''; + $random = Crypt::genRandomBytes($length + 1); + $shift = ord($random[0]); + + for ($j = 1; $j <= $length; ++$j) + { + $makepass .= $salt[($shift + ord($random[$j])) % $base]; + $shift += ord($random[$j]); + } + + $oteps[] = $makepass; + } + + $otpConfig->otep = $oteps; + + // Save the now modified OTP configuration + $this->setOtpConfig($user_id, $otpConfig); + + return $oteps; + } + + /** + * Checks if the provided secret key is a valid two factor authentication + * secret key. If not, it will check it against the list of one time + * emergency passwords (OTEPs). If it's a valid OTEP it will also remove it + * from the user's list of OTEPs. + * + * This method will return true in the following conditions: + * - The two factor authentication is not enabled + * - You have provided a valid secret key for + * - You have provided a valid OTEP + * + * You can define the following options in the $options array: + * otp_config The OTP (one time password, a.k.a. two factor auth) + * configuration object. If not set we'll load it automatically. + * warn_if_not_req Issue a warning if you are checking a secret key against + * a user account which doesn't have any two factor + * authentication method enabled. + * warn_irq_msg The string to use for the warn_if_not_req warning + * + * @param integer $user_id The user's numeric ID + * @param string $secretkey The secret key you want to check + * @param array $options Options; see above + * + * @return boolean True if it's a valid secret key for this user. + * + * @since 3.2 + * @throws \Exception + */ + public function isValidSecretKey($user_id, $secretkey, $options = array()) + { + // Load the user's OTP (one time password, a.k.a. two factor auth) configuration + if (!array_key_exists('otp_config', $options)) + { + $otpConfig = $this->getOtpConfig($user_id); + $options['otp_config'] = $otpConfig; + } + else + { + $otpConfig = $options['otp_config']; + } + + // Check if the user has enabled two factor authentication + if (empty($otpConfig->method) || ($otpConfig->method == 'none')) + { + // Load language + $lang = Factory::getLanguage(); + $extension = 'com_users'; + $source = JPATH_ADMINISTRATOR . '/components/' . $extension; + + $lang->load($extension, JPATH_ADMINISTRATOR, null, false, true) + || $lang->load($extension, $source, null, false, true); + + $warn = true; + $warnMessage = Text::_('COM_USERS_ERROR_SECRET_CODE_WITHOUT_TFA'); + + if (array_key_exists('warn_if_not_req', $options)) + { + $warn = $options['warn_if_not_req']; + } + + if (array_key_exists('warn_irq_msg', $options)) + { + $warnMessage = $options['warn_irq_msg']; + } + + // Warn the user if they are using a secret code but they have not + // enabled two factor auth in their account. + if (!empty($secretkey) && $warn) + { + try + { + $app = Factory::getApplication(); + $app->enqueueMessage($warnMessage, 'warning'); + } + catch (\Exception $exc) + { + // This happens when we are in CLI mode. In this case + // no warning is issued + return true; + } + } + + return true; + } + + $credentials = array( + 'secretkey' => $secretkey, + ); + + // Try to validate the OTP + PluginHelper::importPlugin('twofactorauth'); + + $otpAuthReplies = Factory::getApplication()->triggerEvent('onUserTwofactorAuthenticate', array($credentials, $options)); + + $check = false; + + /* + * This looks like noob code but DO NOT TOUCH IT and do not convert + * to in_array(). During testing in_array() inexplicably returned + * null when the OTEP begins with a zero! o_O + */ + if (!empty($otpAuthReplies)) + { + foreach ($otpAuthReplies as $authReply) + { + $check = $check || $authReply; + } + } + + // Fall back to one time emergency passwords + if (!$check) + { + $check = $this->isValidOtep($user_id, $secretkey, $otpConfig); + } + + return $check; + } + + /** + * Checks if the supplied string is a valid one time emergency password + * (OTEP) for this user. If it is it will be automatically removed from the + * user's list of OTEPs. + * + * @param integer $user_id The user ID against which you are checking + * @param string $otep The string you want to test for validity + * @param object $otpConfig Optional; the two factor authentication configuration (automatically fetched if not set) + * + * @return boolean True if it's a valid OTEP or if two factor auth is not + * enabled in this user's account. + * + * @since 3.2 + */ + public function isValidOtep($user_id, $otep, $otpConfig = null) + { + if (is_null($otpConfig)) + { + $otpConfig = $this->getOtpConfig($user_id); + } + + // Did the user use an OTEP instead? + if (empty($otpConfig->otep)) + { + if (empty($otpConfig->method) || ($otpConfig->method == 'none')) + { + // Two factor authentication is not enabled on this account. + // Any string is assumed to be a valid OTEP. + return true; + } + else + { + /** + * Two factor authentication enabled and no OTEPs defined. The + * user has used them all up. Therefore anything they enter is + * an invalid OTEP. + */ + return false; + } + } + + // Clean up the OTEP (remove dashes, spaces and other funny stuff + // our beloved users may have unwittingly stuffed in it) + $otep = filter_var($otep, FILTER_SANITIZE_NUMBER_INT); + $otep = str_replace('-', '', $otep); + + $check = false; + + // Did we find a valid OTEP? + if (in_array($otep, $otpConfig->otep)) + { + // Remove the OTEP from the array + $otpConfig->otep = array_diff($otpConfig->otep, array($otep)); + + $this->setOtpConfig($user_id, $otpConfig); + + // Return true; the OTEP was a valid one + $check = true; + } + + return $check; + } +} diff --git a/administrator/components/com_users/Model/UsersModel.php b/administrator/components/com_users/Model/UsersModel.php new file mode 100644 index 0000000000000..b944ffb5bd367 --- /dev/null +++ b/administrator/components/com_users/Model/UsersModel.php @@ -0,0 +1,532 @@ +input->get('layout', 'default', 'cmd')) + { + $this->context .= '.' . $layout; + } + + $groups = json_decode(base64_decode($app->input->get('groups', '', 'BASE64'))); + + if (isset($groups)) + { + $groups = ArrayHelper::toInteger($groups); + } + + $this->setState('filter.groups', $groups); + + $excluded = json_decode(base64_decode($app->input->get('excluded', '', 'BASE64'))); + + if (isset($excluded)) + { + $excluded = ArrayHelper::toInteger($excluded); + } + + $this->setState('filter.excluded', $excluded); + + // Load the parameters. + $params = ComponentHelper::getParams('com_users'); + $this->setState('params', $params); + + // List state information. + parent::populateState($ordering, $direction); + } + + /** + * 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 A store id. + * + * @since 1.6 + */ + protected function getStoreId($id = '') + { + // Compile the store id. + $id .= ':' . $this->getState('filter.search'); + $id .= ':' . $this->getState('filter.active'); + $id .= ':' . $this->getState('filter.state'); + $id .= ':' . $this->getState('filter.group_id'); + $id .= ':' . $this->getState('filter.range'); + + return parent::getStoreId($id); + } + + /** + * Gets the list of users and adds expensive joins to the result set. + * + * @return mixed An array of data items on success, false on failure. + * + * @since 1.6 + */ + public function getItems() + { + // Get a storage key. + $store = $this->getStoreId(); + + // Try to load the data from internal storage. + if (empty($this->cache[$store])) + { + $groups = $this->getState('filter.groups'); + $groupId = $this->getState('filter.group_id'); + + if (isset($groups) && (empty($groups) || $groupId && !in_array($groupId, $groups))) + { + $items = array(); + } + else + { + $items = parent::getItems(); + } + + // Bail out on an error or empty list. + if (empty($items)) + { + $this->cache[$store] = $items; + + return $items; + } + + // Joining the groups with the main query is a performance hog. + // Find the information only on the result set. + + // First pass: get list of the user id's and reset the counts. + $userIds = array(); + + foreach ($items as $item) + { + $userIds[] = (int) $item->id; + $item->group_count = 0; + $item->group_names = ''; + $item->note_count = 0; + } + + // Get the counts from the database only for the users in the list. + $db = $this->getDbo(); + $query = $db->getQuery(true); + + // Join over the group mapping table. + $query->select('map.user_id, COUNT(map.group_id) AS group_count') + ->from('#__user_usergroup_map AS map') + ->where('map.user_id IN (' . implode(',', $userIds) . ')') + ->group('map.user_id') + // Join over the user groups table. + ->join('LEFT', '#__usergroups AS g2 ON g2.id = map.group_id'); + + $db->setQuery($query); + + // Load the counts into an array indexed on the user id field. + try + { + $userGroups = $db->loadObjectList('user_id'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + $query->clear() + ->select('n.user_id, COUNT(n.id) As note_count') + ->from('#__user_notes AS n') + ->where('n.user_id IN (' . implode(',', $userIds) . ')') + ->where('n.state >= 0') + ->group('n.user_id'); + + $db->setQuery($query); + + // Load the counts into an array indexed on the aro.value field (the user id). + try + { + $userNotes = $db->loadObjectList('user_id'); + } + catch (\RuntimeException $e) + { + $this->setError($e->getMessage()); + + return false; + } + + // Second pass: collect the group counts into the master items array. + foreach ($items as &$item) + { + if (isset($userGroups[$item->id])) + { + $item->group_count = $userGroups[$item->id]->group_count; + + // Group_concat in other databases is not supported + $item->group_names = $this->_getUserDisplayedGroups($item->id); + } + + if (isset($userNotes[$item->id])) + { + $item->note_count = $userNotes[$item->id]->note_count; + } + } + + // Add the items to the internal cache. + $this->cache[$store] = $items; + } + + return $this->cache[$store]; + } + + /** + * Build an SQL query to load the list data. + * + * @return DatabaseQuery + * + * @since 1.6 + */ + 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('#__users') . ' AS a'); + + // If the model is set to check item state, add to the query. + $state = $this->getState('filter.state'); + + if (is_numeric($state)) + { + $query->where('a.block = ' . (int) $state); + } + + // If the model is set to check the activated state, add to the query. + $active = $this->getState('filter.active'); + + if (is_numeric($active)) + { + if ($active == '0') + { + $query->where('a.activation IN (' . $db->quote('') . ', ' . $db->quote('0') . ')'); + } + elseif ($active == '1') + { + $query->where($query->length('a.activation') . ' > 1'); + } + } + + // Filter the items over the group id if set. + $groupId = $this->getState('filter.group_id'); + $groups = $this->getState('filter.groups'); + + if ($groupId || isset($groups)) + { + $query->join('LEFT', '#__user_usergroup_map AS map2 ON map2.user_id = a.id') + ->group( + $db->quoteName( + array( + 'a.id', + 'a.name', + 'a.username', + 'a.password', + 'a.block', + 'a.sendEmail', + 'a.registerDate', + 'a.lastvisitDate', + 'a.activation', + 'a.params', + 'a.email', + 'a.lastResetTime', + 'a.resetCount', + 'a.otpKey', + 'a.otep', + 'a.requireReset' + ) + ) + ); + + if ($groupId) + { + $query->where('map2.group_id = ' . (int) $groupId); + } + + if (isset($groups)) + { + $query->where('map2.group_id IN (' . implode(',', $groups) . ')'); + } + } + + // Filter the items over the search string if set. + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + if (stripos($search, 'id:') === 0) + { + $query->where('a.id = ' . (int) substr($search, 3)); + } + elseif (stripos($search, 'username:') === 0) + { + $search = $db->quote('%' . $db->escape(substr($search, 9), true) . '%'); + $query->where('a.username LIKE ' . $search); + } + else + { + // Escape the search token. + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + + // Compile the different search clauses. + $searches = array(); + $searches[] = 'a.name LIKE ' . $search; + $searches[] = 'a.username LIKE ' . $search; + $searches[] = 'a.email LIKE ' . $search; + + // Add the clauses to the query. + $query->where('(' . implode(' OR ', $searches) . ')'); + } + } + + // Add filter for registration ranges select list + $range = $this->getState('filter.range'); + + // Apply the range filter. + if ($range) + { + $dates = $this->buildDateRange($range); + + if ($dates['dNow'] === false) + { + $query->where( + $db->quoteName('a.registerDate') . ' < ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) + ); + } + else + { + $query->where( + $db->quoteName('a.registerDate') . ' >= ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) . + ' AND ' . $db->quoteName('a.registerDate') . ' <= ' . $db->quote($dates['dNow']->format('Y-m-d H:i:s')) + ); + } + } + + // Add filter for registration ranges select list + $lastvisitrange = $this->getState('filter.lastvisitrange'); + + // Apply the range filter. + if ($lastvisitrange) + { + $dates = $this->buildDateRange($lastvisitrange); + + if (is_string($dates['dStart'])) + { + $query->where( + $db->quoteName('a.lastvisitDate') . ' = ' . $db->quote($dates['dStart']) + ); + } + elseif ($dates['dNow'] === false) + { + $query->where( + $db->quoteName('a.lastvisitDate') . ' < ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) + ); + } + else + { + $query->where( + $db->quoteName('a.lastvisitDate') . ' >= ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) . + ' AND ' . $db->quoteName('a.lastvisitDate') . ' <= ' . $db->quote($dates['dNow']->format('Y-m-d H:i:s')) + ); + } + } + + // Filter by excluded users + $excluded = $this->getState('filter.excluded'); + + if (!empty($excluded)) + { + $query->where('id NOT IN (' . implode(',', $excluded) . ')'); + } + + // Add the list ordering clause. + $query->order( + $db->quoteName($db->escape($this->getState('list.ordering', 'a.name'))) . ' ' . $db->escape($this->getState('list.direction', 'ASC')) + ); + + return $query; + } + + /** + * Construct the date range to filter on. + * + * @param string $range The textual range to construct the filter for. + * + * @return string The date range to filter on. + * + * @since 3.6.0 + * @throws \Exception + */ + 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'); + $arr = []; + break; + + case 'post_year': + $dNow = false; + case 'past_year': + $dStart->modify('-1 year'); + break; + + case 'today': + // Ranges that need to align with local 'days' need special treatment. + $app = Factory::getApplication(); + $offset = $app->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; + case 'never': + $dNow = false; + $dStart = $this->_db->getNullDate(); + break; + } + + return array('dNow' => $dNow, 'dStart' => $dStart); + } + + /** + * SQL server change + * + * @param integer $user_id User identifier + * + * @return string Groups titles imploded :$ + */ + protected function _getUserDisplayedGroups($user_id) + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('title')) + ->from($db->quoteName('#__usergroups', 'ug')) + ->join('LEFT', $db->quoteName('#__user_usergroup_map', 'map') . ' ON (ug.id = map.group_id)') + ->where($db->quoteName('map.user_id') . ' = ' . (int) $user_id); + + try + { + $result = $db->setQuery($query)->loadColumn(); + } + catch (\RunTimeException $e) + { + $result = array(); + } + + return implode("\n", $result); + } +} diff --git a/administrator/components/com_users/Table/NoteTable.php b/administrator/components/com_users/Table/NoteTable.php new file mode 100644 index 0000000000000..10da370b46d36 --- /dev/null +++ b/administrator/components/com_users/Table/NoteTable.php @@ -0,0 +1,195 @@ +typeAlias = 'com_users.note'; + parent::__construct('#__user_notes', 'id', $db); + } + + /** + * Overloaded store method for the notes table. + * + * @param boolean $updateNulls Toggle whether null values should be updated. + * + * @return boolean True on success, false on failure. + * + * @since 2.5 + */ + public function store($updateNulls = false) + { + $date = Factory::getDate()->toSql(); + $userId = Factory::getUser()->get('id'); + + if (!((int) $this->review_time)) + { + // Null date. + $this->review_time = $this->getDbo()->getNullDate(); + } + + if ($this->id) + { + // Existing item + $this->modified_time = $date; + $this->modified_user_id = $userId; + } + else + { + // New record. + $this->created_time = $date; + $this->created_user_id = $userId; + } + + // Attempt to store the data. + return parent::store($updateNulls); + } + + /** + * Method to set the publishing state for a row or list of rows in the database + * table. The method respects checked out rows by other users and will attempt + * to check-in rows that it can after adjustments are made. + * + * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. + * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] + * @param integer $userId The user id of the user performing the operation. + * + * @return boolean True on success. + * + * @since 2.5 + */ + public function publish($pks = null, $state = 1, $userId = 0) + { + $k = $this->getPrimaryKey(); + + // Sanitize input. + $pks = ArrayHelper::toInteger($pks); + $userId = (int) $userId; + $state = (int) $state; + + // If there are no primary keys set check to see if the instance key is set. + if (empty($pks)) + { + if ($this->$k) + { + $pks = array($this->$k); + } + // Nothing to set publishing state on, return false. + else + { + $this->setError(Text::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); + + return false; + } + } + + $query = $this->getDbo()->getQuery(true) + ->update($this->getDbo()->quoteName($this->_tbl)) + ->set($this->getDbo()->quoteName('state') . ' = ' . (int) $state); + + // Build the WHERE clause for the primary keys. + $query->where($k . '=' . implode(' OR ' . $k . '=', $pks)); + + // Determine if there is checkin support for the table. + if (!$this->hasField('checked_out') || !$this->hasField('checked_out_time')) + { + $checkin = false; + } + else + { + $query->where('(checked_out = 0 OR checked_out = ' . (int) $userId . ')'); + $checkin = true; + } + + // Update the publishing state for rows with the given primary keys. + $this->getDbo()->setQuery($query); + + try + { + $this->getDbo()->execute(); + } + catch (\RuntimeException $e) + { + $this->setError($this->getDbo()->getMessage()); + + return false; + } + + // If checkin is supported and all rows were adjusted, check them in. + if ($checkin && (count($pks) == $this->getDbo()->getAffectedRows())) + { + // Checkin the rows. + foreach ($pks as $pk) + { + $this->checkin($pk); + } + } + + // If the \JTable instance value is in the list of primary keys that were set, set the instance. + if (in_array($this->$k, $pks)) + { + $this->state = $state; + } + + $this->setError(''); + + return true; + } + + /** + * Method to perform sanity checks on the Table instance properties to ensure they are safe to store in the database. + * + * @return boolean True if the instance is sane and able to be stored in the database. + * + * @since 4.0.0 + */ + public function check() + { + try + { + parent::check(); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (empty($this->modified_time)) + { + $this->modified_time = $this->getDbo()->getNullDate(); + } + + return true; + } +} diff --git a/administrator/components/com_users/View/Debuggroup/HtmlView.php b/administrator/components/com_users/View/Debuggroup/HtmlView.php new file mode 100644 index 0000000000000..f0d4182c2add4 --- /dev/null +++ b/administrator/components/com_users/View/Debuggroup/HtmlView.php @@ -0,0 +1,138 @@ +authorise('core.manage', 'com_users')) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + $this->actions = $this->get('DebugActions'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->group = $this->get('Group'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_users'); + + ToolbarHelper::title(Text::sprintf('COM_USERS_VIEW_DEBUG_GROUP_TITLE', $this->group->id, $this->group->title), 'users groups'); + ToolbarHelper::cancel('group.cancel', 'JTOOLBAR_CLOSE'); + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_users'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_USERS_DEBUG_GROUPS'); + } +} diff --git a/administrator/components/com_users/View/Debuguser/HtmlView.php b/administrator/components/com_users/View/Debuguser/HtmlView.php new file mode 100644 index 0000000000000..a0d88f19d8fcc --- /dev/null +++ b/administrator/components/com_users/View/Debuguser/HtmlView.php @@ -0,0 +1,138 @@ +authorise('core.manage', 'com_users')) + { + throw new Notallowed(Text::_('JERROR_ALERTNOAUTHOR'), 403); + } + + $this->actions = $this->get('DebugActions'); + $this->items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->user = $this->get('User'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_users'); + + ToolbarHelper::title(Text::sprintf('COM_USERS_VIEW_DEBUG_USER_TITLE', $this->user->id, $this->user->name), 'users user'); + ToolbarHelper::cancel('user.cancel', 'JTOOLBAR_CLOSE'); + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_users'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_USERS_DEBUG_USERS'); + } +} diff --git a/administrator/components/com_users/View/Group/HtmlView.php b/administrator/components/com_users/View/Group/HtmlView.php new file mode 100644 index 0000000000000..0c3e53065c057 --- /dev/null +++ b/administrator/components/com_users/View/Group/HtmlView.php @@ -0,0 +1,127 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + * @throws \Exception + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $isNew = ($this->item->id == 0); + $canDo = ContentHelper::getActions('com_users'); + + ToolbarHelper::title(Text::_($isNew ? 'COM_USERS_VIEW_NEW_GROUP_TITLE' : 'COM_USERS_VIEW_EDIT_GROUP_TITLE'), 'users groups-add'); + + $toolbarButtons = []; + + if ($canDo->get('core.edit') || $canDo->get('core.create')) + { + $toolbarButtons[] = ['apply', 'group.apply']; + $toolbarButtons[] = ['save', 'group.save']; + } + + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2new', 'group.save2new']; + } + + // If an existing item, can save to a copy. + if (!$isNew && $canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'group.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (empty($this->item->id)) + { + ToolbarHelper::cancel('group.cancel'); + } + else + { + ToolbarHelper::cancel('group.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_USERS_GROUPS_EDIT'); + } +} diff --git a/administrator/components/com_users/View/Groups/HtmlView.php b/administrator/components/com_users/View/Groups/HtmlView.php new file mode 100644 index 0000000000000..686fe124115bc --- /dev/null +++ b/administrator/components/com_users/View/Groups/HtmlView.php @@ -0,0 +1,152 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + UsersHelper::addSubmenu('groups'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = HTMLHelper::_('sidebar.render'); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_users'); + + ToolbarHelper::title(Text::_('COM_USERS_VIEW_GROUPS_TITLE'), 'users groups'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('group.add'); + } + + if ($canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'groups.delete', 'JTOOLBAR_DELETE'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_users'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_USERS_GROUPS'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.title' => Text::_('COM_USERS_HEADING_GROUP_TITLE'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_users/View/Level/HtmlView.php b/administrator/components/com_users/View/Level/HtmlView.php new file mode 100644 index 0000000000000..bfe166c5c95a1 --- /dev/null +++ b/administrator/components/com_users/View/Level/HtmlView.php @@ -0,0 +1,127 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + * @throws \Exception + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $isNew = ($this->item->id == 0); + $canDo = ContentHelper::getActions('com_users'); + + ToolbarHelper::title(Text::_($isNew ? 'COM_USERS_VIEW_NEW_LEVEL_TITLE' : 'COM_USERS_VIEW_EDIT_LEVEL_TITLE'), 'users levels-add'); + + $toolbarButtons = []; + + if ($canDo->get('core.edit') || $canDo->get('core.create')) + { + $toolbarButtons[] = ['apply', 'level.apply']; + $toolbarButtons[] = ['save', 'level.save']; + } + + if ($canDo->get('core.create')) + { + $toolbarButtons[] = ['save2new', 'level.save2new']; + } + + // If an existing item, can save to a copy. + if (!$isNew && $canDo->get('core.create')) + { + $toolbarButtons[] = ['save2copy', 'level.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (empty($this->item->id)) + { + ToolbarHelper::cancel('level.cancel'); + } + else + { + ToolbarHelper::cancel('level.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS_EDIT'); + } +} diff --git a/administrator/components/com_users/View/Levels/HtmlView.php b/administrator/components/com_users/View/Levels/HtmlView.php new file mode 100644 index 0000000000000..9f96bd3b931c9 --- /dev/null +++ b/administrator/components/com_users/View/Levels/HtmlView.php @@ -0,0 +1,153 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + UsersHelper::addSubmenu('levels'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->addToolbar(); + $this->sidebar = HTMLHelper::_('sidebar.render'); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_users'); + + ToolbarHelper::title(Text::_('COM_USERS_VIEW_LEVELS_TITLE'), 'users levels'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('level.add'); + } + + if ($canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'level.delete', 'JTOOLBAR_DELETE'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_users'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.ordering' => Text::_('JGRID_HEADING_ORDERING'), + 'a.title' => Text::_('COM_USERS_HEADING_LEVEL_NAME'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_users/View/Mail/HtmlView.php b/administrator/components/com_users/View/Mail/HtmlView.php new file mode 100644 index 0000000000000..9dc5103f1156a --- /dev/null +++ b/administrator/components/com_users/View/Mail/HtmlView.php @@ -0,0 +1,78 @@ +get('massmailoff', 0) == 1) + { + Factory::getApplication()->redirect(Route::_('index.php', false)); + } + + // Get data from the model + $this->form = $this->get('Form'); + + $this->addToolbar(); + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + * @throws \Exception + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + ToolbarHelper::title(Text::_('COM_USERS_MASS_MAIL'), 'users massmail'); + ToolbarHelper::custom('mail.send', 'envelope.png', 'send_f2.png', 'COM_USERS_TOOLBAR_MAIL_SEND_MAIL', false); + ToolbarHelper::cancel('mail.cancel'); + ToolbarHelper::divider(); + ToolbarHelper::preferences('com_users'); + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_USERS_MASS_MAIL_USERS'); + } +} diff --git a/administrator/components/com_users/View/Note/HtmlView.php b/administrator/components/com_users/View/Note/HtmlView.php new file mode 100644 index 0000000000000..a610772427cca --- /dev/null +++ b/administrator/components/com_users/View/Note/HtmlView.php @@ -0,0 +1,148 @@ +state = $this->get('State'); + $this->item = $this->get('Item'); + $this->form = $this->get('Form'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Get the component HTML helpers + HTMLHelper::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + parent::display($tpl); + $this->addToolbar(); + } + + /** + * Display the toolbar. + * + * @return void + * + * @since 2.5 + * @throws \Exception + */ + protected function addToolbar() + { + $input = Factory::getApplication()->input; + $input->set('hidemainmenu', 1); + + $user = Factory::getUser(); + $isNew = ($this->item->id == 0); + $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); + + // Since we don't track these assets at the item level, use the category id. + $canDo = ContentHelper::getActions('com_users', 'category', $this->item->catid); + + ToolbarHelper::title(Text::_('COM_USERS_NOTES'), 'users user'); + + $toolbarButtons = []; + + // If not checked out, can save the item. + if (!$checkedOut && ($canDo->get('core.edit') || count($user->getAuthorisedCategories('com_users', 'core.create')))) + { + $toolbarButtons[] = ['apply', 'note.apply']; + $toolbarButtons[] = ['save', 'note.save']; + } + + if (!$checkedOut && count($user->getAuthorisedCategories('com_users', 'core.create'))) + { + $toolbarButtons[] = ['save2new', 'note.save2new']; + } + + // If an existing item, can save to a copy. + if (!$isNew && (count($user->getAuthorisedCategories('com_users', 'core.create')) > 0)) + { + $toolbarButtons[] = ['save2copy', 'note.save2copy']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (empty($this->item->id)) + { + ToolbarHelper::cancel('note.cancel'); + } + else + { + if (ComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $canDo->get('core.edit')) + { + ToolbarHelper::versions('com_users.note', $this->item->id); + } + + ToolbarHelper::cancel('note.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_USERS_USER_NOTES_EDIT'); + } +} diff --git a/administrator/components/com_users/View/Notes/HtmlView.php b/administrator/components/com_users/View/Notes/HtmlView.php new file mode 100644 index 0000000000000..8f5393cd835bf --- /dev/null +++ b/administrator/components/com_users/View/Notes/HtmlView.php @@ -0,0 +1,197 @@ +items = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->state = $this->get('State'); + $this->user = $this->get('User'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + UsersHelper::addSubmenu('notes'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Get the component HTML helpers + HTMLHelper::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + // Turn parameters into registry objects + foreach ($this->items as $item) + { + $item->cparams = new Registry($item->category_params); + } + + $this->addToolbar(); + $this->sidebar = HTMLHelper::_('sidebar.render'); + parent::display($tpl); + } + + /** + * Display the toolbar. + * + * @return void + * + * @since 2.5 + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions('com_users', 'category', $this->state->get('filter.category_id')); + + ToolbarHelper::title(Text::_('COM_USERS_VIEW_NOTES_TITLE'), 'users user'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('note.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::divider(); + ToolbarHelper::publish('notes.publish', 'JTOOLBAR_PUBLISH', true); + ToolbarHelper::unpublish('notes.unpublish', 'JTOOLBAR_UNPUBLISH', true); + + ToolbarHelper::divider(); + ToolbarHelper::archiveList('notes.archive'); + ToolbarHelper::checkin('notes.checkin'); + } + + if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'notes.delete', 'JTOOLBAR_EMPTY_TRASH'); + ToolbarHelper::divider(); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('notes.trash'); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_users'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_USERS_USER_NOTES'); + + HTMLHelper::_('sidebar.setAction', 'index.php?option=com_users&view=notes'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'u.name' => Text::_('COM_USERS_USER_HEADING'), + 'a.subject' => Text::_('COM_USERS_SUBJECT_HEADING'), + 'c.title' => Text::_('COM_USERS_CATEGORY_HEADING'), + 'a.state' => Text::_('JSTATUS'), + 'a.review_time' => Text::_('COM_USERS_REVIEW_HEADING'), + 'a.id' => Text::_('JGRID_HEADING_ID') + ); + } +} diff --git a/administrator/components/com_users/View/User/HtmlView.php b/administrator/components/com_users/View/User/HtmlView.php new file mode 100644 index 0000000000000..71df8a6fb6502 --- /dev/null +++ b/administrator/components/com_users/View/User/HtmlView.php @@ -0,0 +1,174 @@ +form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->state = $this->get('State'); + $this->tfaform = $this->get('Twofactorform'); + $this->otpConfig = $this->get('otpConfig'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Prevent user from modifying own group(s) + $user = Factory::getUser(); + + if ((int) $user->id != (int) $this->item->id || $user->authorise('core.admin')) + { + $this->grouplist = $this->get('Groups'); + $this->groups = $this->get('AssignedGroups'); + } + + $this->form->setValue('password', null); + $this->form->setValue('password2', null); + + parent::display($tpl); + $this->addToolbar(); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + * @throws \Exception + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $user = Factory::getUser(); + $canDo = ContentHelper::getActions('com_users'); + $isNew = ($this->item->id == 0); + $isProfile = $this->item->id == $user->id; + + ToolbarHelper::title( + Text::_( + $isNew ? 'COM_USERS_VIEW_NEW_USER_TITLE' : ($isProfile ? 'COM_USERS_VIEW_EDIT_PROFILE_TITLE' : 'COM_USERS_VIEW_EDIT_USER_TITLE') + ), + 'user ' . ($isNew ? 'user-add' : ($isProfile ? 'user-profile' : 'user-edit')) + ); + + $toolbarButtons = []; + + if ($canDo->get('core.edit') || $canDo->get('core.create')) + { + $toolbarButtons[] = ['apply', 'user.apply']; + $toolbarButtons[] = ['save', 'user.save']; + } + + if ($canDo->get('core.create') && $canDo->get('core.manage')) + { + $toolbarButtons[] = ['save2new', 'user.save2new']; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + + if (empty($this->item->id)) + { + ToolbarHelper::cancel('user.cancel'); + } + else + { + ToolbarHelper::cancel('user.cancel', 'JTOOLBAR_CLOSE'); + } + + ToolbarHelper::divider(); + ToolbarHelper::help('JHELP_USERS_USER_MANAGER_EDIT'); + } +} diff --git a/administrator/components/com_users/View/Users/HtmlView.php b/administrator/components/com_users/View/Users/HtmlView.php new file mode 100644 index 0000000000000..3b17c45cc70c7 --- /dev/null +++ b/administrator/components/com_users/View/Users/HtmlView.php @@ -0,0 +1,211 @@ +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->canDo = ContentHelper::getActions('com_users'); + $this->db = Factory::getDbo(); + + UsersHelper::addSubmenu('users'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Include the component HTML helpers. + HTMLHelper::addIncludePath(JPATH_COMPONENT . '/helpers/html'); + + $this->addToolbar(); + $this->sidebar = HTMLHelper::_('sidebar.render'); + + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since 1.6 + */ + protected function addToolbar() + { + $canDo = $this->canDo; + $user = Factory::getUser(); + + // Get the toolbar object instance + $bar = Toolbar::getInstance('toolbar'); + + ToolbarHelper::title(Text::_('COM_USERS_VIEW_USERS_TITLE'), 'users user'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('user.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::divider(); + ToolbarHelper::publish('users.activate', 'COM_USERS_TOOLBAR_ACTIVATE', true); + ToolbarHelper::unpublish('users.block', 'COM_USERS_TOOLBAR_BLOCK', true); + ToolbarHelper::custom('users.unblock', 'unblock.png', 'unblock_f2.png', 'COM_USERS_TOOLBAR_UNBLOCK', true); + ToolbarHelper::divider(); + } + + if ($canDo->get('core.delete')) + { + ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'users.delete', 'JTOOLBAR_DELETE'); + ToolbarHelper::divider(); + } + + // Add a batch button + if ($user->authorise('core.create', 'com_users') + && $user->authorise('core.edit', 'com_users') + && $user->authorise('core.edit.state', 'com_users')) + { + $title = Text::_('JTOOLBAR_BATCH'); + + // Instantiate a new LayoutFile instance and render the batch button + $layout = new FileLayout('joomla.toolbar.batch'); + + $dhtml = $layout->render(array('title' => $title)); + $bar->appendButton('Custom', $dhtml, 'batch'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences('com_users'); + ToolbarHelper::divider(); + } + + ToolbarHelper::help('JHELP_USERS_USER_MANAGER'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since 3.0 + */ + protected function getSortFields() + { + return array( + 'a.name' => Text::_('COM_USERS_HEADING_NAME'), + 'a.username' => Text::_('JGLOBAL_USERNAME'), + 'a.block' => Text::_('COM_USERS_HEADING_ENABLED'), + 'a.activation' => Text::_('COM_USERS_HEADING_ACTIVATED'), + 'a.email' => Text::_('JGLOBAL_EMAIL'), + 'a.lastvisitDate' => Text::_('COM_USERS_HEADING_LAST_VISIT_DATE'), + 'a.registerDate' => Text::_('COM_USERS_HEADING_REGISTRATION_DATE'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_users/access.xml b/administrator/components/com_users/access.xml index 01051d5e50fe5..77a301f0174cb 100644 --- a/administrator/components/com_users/access.xml +++ b/administrator/components/com_users/access.xml @@ -1,34 +1,34 @@
    - - - - - - - - + + + + + + + +
    - - - - - + + + + +
    - - - - - - + + + + + +
    - - - - + + + +
    diff --git a/administrator/components/com_users/config.xml b/administrator/components/com_users/config.xml index a0a03011b5037..a5a7b3d8e41dc 100644 --- a/administrator/components/com_users/config.xml +++ b/administrator/components/com_users/config.xml @@ -1,25 +1,23 @@ -
    - + @@ -28,7 +26,6 @@ name="guest_usergroup" type="usergrouplist" label="COM_USERS_CONFIG_FIELD_GUEST_USER_GROUP_LABEL" - description="COM_USERS_CONFIG_FIELD_GUEST_USER_GROUP_DESC" default="1" checksuperusergroup="1" /> @@ -37,19 +34,17 @@ name="sendpassword" type="radio" label="COM_USERS_CONFIG_FIELD_SENDPASSWORD_LABEL" - description="COM_USERS_CONFIG_FIELD_SENDPASSWORD_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" > - + @@ -61,19 +56,17 @@ name="mail_to_admin" type="radio" label="COM_USERS_CONFIG_FIELD_MAILTOADMIN_LABEL" - description="COM_USERS_CONFIG_FIELD_MAILTOADMIN_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" > - + - + - + - +
    @@ -127,7 +117,6 @@ name="reset_count" type="integer" label="COM_USERS_CONFIG_FIELD_FRONTEND_RESET_COUNT_LABEL" - description="COM_USERS_CONFIG_FIELD_FRONTEND_RESET_COUNT_DESC" first="0" last="20" step="1" @@ -138,7 +127,6 @@ name="reset_time" type="integer" label="COM_USERS_CONFIG_FIELD_FRONTEND_RESET_TIME_LABEL" - description="COM_USERS_CONFIG_FIELD_FRONTEND_RESET_TIME_DESC" first="1" last="24" step="1" @@ -149,7 +137,6 @@ name="minimum_length" type="integer" label="COM_USERS_CONFIG_FIELD_MINIMUM_PASSWORD_LENGTH" - description="COM_USERS_CONFIG_FIELD_MINIMUM_PASSWORD_LENGTH_DESC" first="4" last="99" step="1" @@ -160,7 +147,6 @@ name="minimum_integers" type="integer" label="COM_USERS_CONFIG_FIELD_MINIMUM_INTEGERS" - description="COM_USERS_CONFIG_FIELD_MINIMUM_INTEGERS_DESC" first="0" last="98" step="1" @@ -171,7 +157,6 @@ name="minimum_symbols" type="integer" label="COM_USERS_CONFIG_FIELD_MINIMUM_SYMBOLS" - description="COM_USERS_CONFIG_FIELD_MINIMUM_SYMBOLS_DESC" first="0" last="98" step="1" @@ -182,13 +167,21 @@ name="minimum_uppercase" type="integer" label="COM_USERS_CONFIG_FIELD_MINIMUM_UPPERCASE" - description="COM_USERS_CONFIG_FIELD_MINIMUM_UPPERCASE_DESC" first="0" last="98" step="1" default="0" /> +
    - + @@ -251,24 +240,22 @@ name="debugUsers" type="radio" label="COM_USERS_DEBUG_USERS_LABEL" - description="COM_USERS_DEBUG_USERS_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" > - - + + - - + +
    @@ -278,29 +265,15 @@ description="COM_USERS_CONFIG_INTEGRATION_SETTINGS_DESC" > - - - - - - +
    diff --git a/administrator/components/com_users/controller.php b/administrator/components/com_users/controller.php deleted file mode 100644 index 8e64e70ee7753..0000000000000 --- a/administrator/components/com_users/controller.php +++ /dev/null @@ -1,109 +0,0 @@ -get('core.admin'); - break; - - // Default permissions. - default: - return true; - } - } - - /** - * 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 JController This object to support chaining. - * - * @since 1.5 - */ - public function display($cachable = false, $urlparams = false) - { - $view = $this->input->get('view', 'users'); - $layout = $this->input->get('layout', 'default'); - $id = $this->input->getInt('id'); - - if (!$this->canView($view)) - { - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); - } - - // Check for edit form. - if ($view == 'user' && $layout == 'edit' && !$this->checkEditId('com_users.edit.user', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_users&view=users', false)); - - return false; - } - elseif ($view == 'group' && $layout == 'edit' && !$this->checkEditId('com_users.edit.group', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_users&view=groups', false)); - - return false; - } - elseif ($view == 'level' && $layout == 'edit' && !$this->checkEditId('com_users.edit.level', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_users&view=levels', false)); - - return false; - } - elseif ($view == 'note' && $layout == 'edit' && !$this->checkEditId('com_users.edit.note', $id)) - { - // Somehow the person just went to the form - we don't allow that. - $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); - $this->setMessage($this->getError(), 'error'); - $this->setRedirect(JRoute::_('index.php?option=com_users&view=notes', false)); - - return false; - } - - return parent::display(); - } -} diff --git a/administrator/components/com_users/controllers/group.php b/administrator/components/com_users/controllers/group.php deleted file mode 100644 index e0ea7e35b4ff5..0000000000000 --- a/administrator/components/com_users/controllers/group.php +++ /dev/null @@ -1,68 +0,0 @@ -authorise('core.admin', $this->option) && parent::allowSave($data, $key)); - } - - /** - * Overrides JControllerForm::allowEdit - * - * Checks that non-Super Admins are not editing Super Admins. - * - * @param array $data An array of input data. - * @param string $key The name of the key for the primary key. - * - * @return boolean - * - * @since 1.6 - */ - protected function allowEdit($data = array(), $key = 'id') - { - // Check if this group is a Super Admin - if (JAccess::checkGroup($data[$key], 'core.admin')) - { - // If I'm not a Super Admin, then disallow the edit. - if (!JFactory::getUser()->authorise('core.admin')) - { - return false; - } - } - - return parent::allowEdit($data, $key); - } -} diff --git a/administrator/components/com_users/controllers/groups.php b/administrator/components/com_users/controllers/groups.php deleted file mode 100644 index 7992a518f199b..0000000000000 --- a/administrator/components/com_users/controllers/groups.php +++ /dev/null @@ -1,140 +0,0 @@ - true)); - } - - /** - * Removes an item. - * - * Overrides JControllerAdmin::delete to check the core.admin permission. - * - * @return boolean Returns true on success, false on failure. - * - * @since 1.6 - */ - public function delete() - { - if (!JFactory::getUser()->authorise('core.admin', $this->option)) - { - JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); - jexit(); - } - - return parent::delete(); - } - - /** - * Method to publish a list of records. - * - * Overrides JControllerAdmin::publish to check the core.admin permission. - * - * @return void - * - * @since 1.6 - */ - public function publish() - { - if (!JFactory::getUser()->authorise('core.admin', $this->option)) - { - JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); - jexit(); - } - - return parent::publish(); - } - - /** - * Changes the order of one or more records. - * - * Overrides JControllerAdmin::reorder to check the core.admin permission. - * - * @return boolean True on success - * - * @since 1.6 - */ - public function reorder() - { - if (!JFactory::getUser()->authorise('core.admin', $this->option)) - { - JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); - jexit(); - } - - return parent::reorder(); - } - - /** - * Method to save the submitted ordering values for records. - * - * Overrides JControllerAdmin::saveorder to check the core.admin permission. - * - * @return boolean True on success - * - * @since 1.6 - */ - public function saveorder() - { - if (!JFactory::getUser()->authorise('core.admin', $this->option)) - { - JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); - jexit(); - } - - return parent::saveorder(); - } - - /** - * Check in of one or more records. - * - * Overrides JControllerAdmin::checkin to check the core.admin permission. - * - * @return boolean True on success - * - * @since 1.6 - */ - public function checkin() - { - if (!JFactory::getUser()->authorise('core.admin', $this->option)) - { - JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); - jexit(); - } - - return parent::checkin(); - } -} diff --git a/administrator/components/com_users/controllers/level.php b/administrator/components/com_users/controllers/level.php deleted file mode 100644 index 7f1fb6a48c70f..0000000000000 --- a/administrator/components/com_users/controllers/level.php +++ /dev/null @@ -1,89 +0,0 @@ -authorise('core.admin', $this->option) && parent::allowSave($data, $key)); - } - - /** - * Removes an item. - * - * Overrides JControllerAdmin::delete to check the core.admin permission. - * - * @return boolean Returns true on success, false on failure. - * - * @since 1.6 - */ - public function delete() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = $this->input->get('cid', array(), 'array'); - - if (!JFactory::getUser()->authorise('core.admin', $this->option)) - { - JError::raiseError(500, JText::_('JERROR_ALERTNOAUTHOR')); - jexit(); - } - elseif (empty($ids)) - { - JError::raiseWarning(500, JText::_('COM_USERS_NO_LEVELS_SELECTED')); - } - else - { - // Get the model. - $model = $this->getModel(); - - $ids = ArrayHelper::toInteger($ids); - - // Remove the items. - if (!$model->delete($ids)) - { - JError::raiseWarning(500, $model->getError()); - } - else - { - $this->setMessage(JText::plural('COM_USERS_N_LEVELS_DELETED', count($ids))); - } - } - - $this->setRedirect('index.php?option=com_users&view=levels'); - } -} diff --git a/administrator/components/com_users/controllers/levels.php b/administrator/components/com_users/controllers/levels.php deleted file mode 100644 index 1744575e8daf1..0000000000000 --- a/administrator/components/com_users/controllers/levels.php +++ /dev/null @@ -1,40 +0,0 @@ - true)); - } -} diff --git a/administrator/components/com_users/controllers/mail.php b/administrator/components/com_users/controllers/mail.php deleted file mode 100644 index 759186b28f249..0000000000000 --- a/administrator/components/com_users/controllers/mail.php +++ /dev/null @@ -1,65 +0,0 @@ -get('massmailoff', 0) == 1) - { - JFactory::getApplication()->redirect(JRoute::_('index.php', false)); - } - - // Check for request forgeries. - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); - - $model = $this->getModel('Mail'); - - if ($model->send()) - { - $type = 'message'; - } - else - { - $type = 'error'; - } - - $msg = $model->getError(); - $this->setredirect('index.php?option=com_users&view=mail', $msg, $type); - } - - /** - * Cancel the mail - * - * @return void - * - * @since 1.6 - */ - public function cancel() - { - // Check for request forgeries. - JSession::checkToken('request') or jexit(JText::_('JINVALID_TOKEN')); - $this->setRedirect('index.php'); - } -} diff --git a/administrator/components/com_users/controllers/note.php b/administrator/components/com_users/controllers/note.php deleted file mode 100644 index 2136f7dae9d8f..0000000000000 --- a/administrator/components/com_users/controllers/note.php +++ /dev/null @@ -1,50 +0,0 @@ -input->get('u_id', 0, 'int'); - - if ($userId) - { - $append .= '&u_id=' . $userId; - } - - return $append; - } -} diff --git a/administrator/components/com_users/controllers/notes.php b/administrator/components/com_users/controllers/notes.php deleted file mode 100644 index ba42bd85f3b4a..0000000000000 --- a/administrator/components/com_users/controllers/notes.php +++ /dev/null @@ -1,42 +0,0 @@ - true)) - { - return parent::getModel($name, $prefix, $config); - } -} diff --git a/administrator/components/com_users/controllers/profile.json.php b/administrator/components/com_users/controllers/profile.json.php deleted file mode 100644 index 2b7fade24e126..0000000000000 --- a/administrator/components/com_users/controllers/profile.json.php +++ /dev/null @@ -1,21 +0,0 @@ -authorise('core.admin')) - { - return false; - } - } - - return parent::allowEdit($data, $key); - } - - /** - * Method to run batch operations. - * - * @param object $model The model. - * - * @return boolean True on success, false on failure - * - * @since 2.5 - */ - public function batch($model = null) - { - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - // Set the model - $model = $this->getModel('User', '', array()); - - // Preset the redirect - $this->setRedirect(JRoute::_('index.php?option=com_users&view=users' . $this->getRedirectToListAppend(), false)); - - return parent::batch($model); - } - - /** - * 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.1 - */ - protected function postSaveHook(JModelLegacy $model, $validData = array()) - { - return; - } -} diff --git a/administrator/components/com_users/controllers/users.php b/administrator/components/com_users/controllers/users.php deleted file mode 100644 index 607ce59230cde..0000000000000 --- a/administrator/components/com_users/controllers/users.php +++ /dev/null @@ -1,142 +0,0 @@ -registerTask('block', 'changeBlock'); - $this->registerTask('unblock', 'changeBlock'); - } - - /** - * Proxy for getModel. - * - * @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 1.6 - */ - public function getModel($name = 'User', $prefix = 'UsersModel', $config = array('ignore_request' => true)) - { - return parent::getModel($name, $prefix, $config); - } - - /** - * Method to change the block status on a record. - * - * @return void - * - * @since 1.6 - */ - public function changeBlock() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = $this->input->get('cid', array(), 'array'); - $values = array('block' => 1, 'unblock' => 0); - $task = $this->getTask(); - $value = ArrayHelper::getValue($values, $task, 0, 'int'); - - if (empty($ids)) - { - JError::raiseWarning(500, JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); - } - else - { - // Get the model. - $model = $this->getModel(); - - // Change the state of the records. - if (!$model->block($ids, $value)) - { - JError::raiseWarning(500, $model->getError()); - } - else - { - if ($value == 1) - { - $this->setMessage(JText::plural('COM_USERS_N_USERS_BLOCKED', count($ids))); - } - elseif ($value == 0) - { - $this->setMessage(JText::plural('COM_USERS_N_USERS_UNBLOCKED', count($ids))); - } - } - } - - $this->setRedirect('index.php?option=com_users&view=users'); - } - - /** - * Method to activate a record. - * - * @return void - * - * @since 1.6 - */ - public function activate() - { - // Check for request forgeries. - JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); - - $ids = $this->input->get('cid', array(), 'array'); - - if (empty($ids)) - { - JError::raiseWarning(500, JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); - } - else - { - // Get the model. - $model = $this->getModel(); - - // Change the state of the records. - if (!$model->activate($ids)) - { - JError::raiseWarning(500, $model->getError()); - } - else - { - $this->setMessage(JText::plural('COM_USERS_N_USERS_ACTIVATED', count($ids))); - } - } - - $this->setRedirect('index.php?option=com_users&view=users'); - } -} diff --git a/administrator/components/com_users/models/forms/fields/user.xml b/administrator/components/com_users/forms/fields/user.xml similarity index 100% rename from administrator/components/com_users/models/forms/fields/user.xml rename to administrator/components/com_users/forms/fields/user.xml diff --git a/administrator/components/com_users/models/forms/filter_debuggroup.xml b/administrator/components/com_users/forms/filter_debuggroup.xml similarity index 83% rename from administrator/components/com_users/models/forms/filter_debuggroup.xml rename to administrator/components/com_users/forms/filter_debuggroup.xml index 72eb8deb0e034..f72f788d1a5e6 100644 --- a/administrator/components/com_users/models/forms/filter_debuggroup.xml +++ b/administrator/components/com_users/forms/filter_debuggroup.xml @@ -1,5 +1,5 @@ -
    + @@ -22,8 +20,6 @@ @@ -32,8 +28,6 @@ @@ -61,7 +55,6 @@ diff --git a/administrator/components/com_users/models/forms/filter_debuguser.xml b/administrator/components/com_users/forms/filter_debuguser.xml similarity index 83% rename from administrator/components/com_users/models/forms/filter_debuguser.xml rename to administrator/components/com_users/forms/filter_debuguser.xml index f09569a9e947f..22b98bbeaec1c 100644 --- a/administrator/components/com_users/models/forms/filter_debuguser.xml +++ b/administrator/components/com_users/forms/filter_debuguser.xml @@ -1,5 +1,5 @@ - + @@ -20,8 +18,6 @@ @@ -29,8 +25,6 @@ @@ -56,7 +50,6 @@ diff --git a/administrator/components/com_users/forms/filter_groups.xml b/administrator/components/com_users/forms/filter_groups.xml new file mode 100644 index 0000000000000..c430ddbd23628 --- /dev/null +++ b/administrator/components/com_users/forms/filter_groups.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + diff --git a/administrator/components/com_users/models/forms/filter_levels.xml b/administrator/components/com_users/forms/filter_levels.xml similarity index 92% rename from administrator/components/com_users/models/forms/filter_levels.xml rename to administrator/components/com_users/forms/filter_levels.xml index 081189f1068f5..0bc8afb4cca64 100644 --- a/administrator/components/com_users/models/forms/filter_levels.xml +++ b/administrator/components/com_users/forms/filter_levels.xml @@ -13,8 +13,6 @@ @@ -31,7 +29,6 @@ type="limitbox" label="JGLOBAL_LIMIT" description="JGLOBAL_LIMIT" - class="input-mini" default="25" onchange="this.form.submit();" /> diff --git a/administrator/components/com_users/models/forms/filter_notes.xml b/administrator/components/com_users/forms/filter_notes.xml similarity index 86% rename from administrator/components/com_users/models/forms/filter_notes.xml rename to administrator/components/com_users/forms/filter_notes.xml index b4895e2e1a271..6a5eadf55bc16 100644 --- a/administrator/components/com_users/models/forms/filter_notes.xml +++ b/administrator/components/com_users/forms/filter_notes.xml @@ -18,8 +18,6 @@ @@ -28,8 +26,6 @@ @@ -65,9 +59,6 @@ diff --git a/administrator/components/com_users/models/forms/filter_users.xml b/administrator/components/com_users/forms/filter_users.xml similarity index 80% rename from administrator/components/com_users/models/forms/filter_users.xml rename to administrator/components/com_users/forms/filter_users.xml index af0a88b65b691..b6e60fca437e3 100644 --- a/administrator/components/com_users/models/forms/filter_users.xml +++ b/administrator/components/com_users/forms/filter_users.xml @@ -11,8 +11,6 @@ @@ -20,8 +18,6 @@ @@ -29,8 +25,6 @@ @@ -38,8 +32,6 @@ @@ -47,8 +39,6 @@ @@ -58,8 +48,6 @@ @@ -84,8 +72,6 @@ +
    +
    + + + + + + + + + + + +
    +
    diff --git a/administrator/components/com_users/models/forms/level.xml b/administrator/components/com_users/forms/level.xml similarity index 91% rename from administrator/components/com_users/models/forms/level.xml rename to administrator/components/com_users/forms/level.xml index 0651cacbcccea..67703f4abf3d4 100644 --- a/administrator/components/com_users/models/forms/level.xml +++ b/administrator/components/com_users/forms/level.xml @@ -13,7 +13,6 @@ name="title" type="text" label="COM_USERS_LEVEL_FIELD_TITLE_LABEL" - description="COM_USERS_LEVEL_FIELD_TITLE_DESC" required="true" size="50" /> diff --git a/administrator/components/com_users/forms/mail.xml b/administrator/components/com_users/forms/mail.xml new file mode 100644 index 0000000000000..126e2e94a511e --- /dev/null +++ b/administrator/components/com_users/forms/mail.xml @@ -0,0 +1,63 @@ + +
    +
    + + + + + + + + + + + + + + + + +
    +
    diff --git a/administrator/components/com_users/models/forms/note.xml b/administrator/components/com_users/forms/note.xml similarity index 82% rename from administrator/components/com_users/models/forms/note.xml rename to administrator/components/com_users/forms/note.xml index 13cd9379dea0c..fd9b585b35c5e 100644 --- a/administrator/components/com_users/models/forms/note.xml +++ b/administrator/components/com_users/forms/note.xml @@ -1,8 +1,6 @@
    -
    +
    @@ -48,7 +43,6 @@ name="body" type="editor" label="COM_USERS_FIELD_NOTEBODY_LABEL" - description="COM_USERS_FIELD_NOTEBODY_DESC" rows="10" cols="80" filter="safehtml" @@ -58,7 +52,6 @@ name="state" type="list" label="JSTATUS" - description="COM_USERS_FIELD_STATE_DESC" size="1" default="1" > @@ -72,7 +65,6 @@ name="review_time" type="calendar" label="COM_USERS_FIELD_REVIEW_TIME_LABEL" - description="COM_USERS_FIELD_REVIEW_TIME_DESC" default="NOW" translateformat="true" /> @@ -121,7 +113,6 @@ name="publish_up" type="calendar" label="JGLOBAL_FIELD_PUBLISH_UP_LABEL" - description="JGLOBAL_FIELD_PUBLISH_UP_DESC" translateformat="true" showtime="true" size="22" @@ -132,7 +123,6 @@ name="publish_down" type="calendar" label="JGLOBAL_FIELD_PUBLISH_DOWN_LABEL" - description="JGLOBAL_FIELD_PUBLISH_DOWN_DESC" translateformat="true" showtime="true" size="22" @@ -143,7 +133,6 @@ name="version_note" type="text" label="JGLOBAL_FIELD_VERSION_NOTE_LABEL" - description="JGLOBAL_FIELD_VERSION_NOTE_DESC" maxlength="255" size="45" labelclass="control-label" diff --git a/administrator/components/com_users/models/forms/user.xml b/administrator/components/com_users/forms/user.xml similarity index 75% rename from administrator/components/com_users/models/forms/user.xml rename to administrator/components/com_users/forms/user.xml index 0ec33fc941364..11de26f71648d 100644 --- a/administrator/components/com_users/models/forms/user.xml +++ b/administrator/components/com_users/forms/user.xml @@ -5,7 +5,6 @@ name="name" type="text" label="COM_USERS_USER_FIELD_NAME_LABEL" - description="COM_USERS_USER_FIELD_NAME_DESC" required="true" size="30" /> @@ -14,20 +13,20 @@ name="username" type="text" label="COM_USERS_USER_FIELD_USERNAME_LABEL" - description="COM_USERS_USER_FIELD_USERNAME_DESC" required="true" size="30" /> - @@ -35,9 +34,8 @@ name="password2" type="password" label="COM_USERS_USER_FIELD_PASSWORD2_LABEL" - description="COM_USERS_USER_FIELD_PASSWORD2_DESC" autocomplete="off" - class="validate-password" + class="validate-passwordExtra" filter="raw" message="COM_USERS_USER_FIELD_PASSWORD1_MESSAGE" size="30" @@ -45,11 +43,10 @@ field="password" /> - - + - + - + @@ -174,7 +162,6 @@ name="admin_language" type="language" label="COM_USERS_USER_FIELD_BACKEND_LANGUAGE_LABEL" - description="COM_USERS_USER_FIELD_BACKEND_LANGUAGE_DESC" client="administrator" > @@ -184,7 +171,6 @@ name="language" type="language" label="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL" - description="COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_DESC" client="site" > @@ -194,7 +180,6 @@ name="editor" type="plugins" label="COM_USERS_USER_FIELD_EDITOR_LABEL" - description="COM_USERS_USER_FIELD_EDITOR_DESC" folder="editors" > @@ -204,7 +189,6 @@ name="helpsite" type="helpsite" label="COM_USERS_USER_FIELD_HELPSITE_LABEL" - description="COM_USERS_USER_FIELD_HELPSITE_DESC" > @@ -213,7 +197,6 @@ name="timezone" type="timezone" label="COM_USERS_USER_FIELD_TIMEZONE_LABEL" - description="COM_USERS_USER_FIELD_TIMEZONE_DESC" > diff --git a/administrator/components/com_users/helpers/debug.php b/administrator/components/com_users/helpers/debug.php index 4a938950a4935..f8fbd6d0e372a 100644 --- a/administrator/components/com_users/helpers/debug.php +++ b/administrator/components/com_users/helpers/debug.php @@ -9,146 +9,14 @@ defined('_JEXEC') or die; -use Joomla\Utilities\ArrayHelper; - /** * Users component debugging helper. * - * @since 1.6 + * @since 1.6 + * + * @deprecated 5.0 Use \Joomla\Component\Users\Administrator\Helper\UsersHelperDebug instead */ -class UsersHelperDebug +class UsersHelperDebug extends \Joomla\Component\Users\Administrator\Helper\UsersHelperDebug { - /** - * Get a list of the components. - * - * @return array - * - * @since 1.6 - */ - public static function getComponents() - { - // Initialise variable. - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('name AS text, element AS value') - ->from('#__extensions') - ->where('enabled >= 1') - ->where('type =' . $db->quote('component')); - - $items = $db->setQuery($query)->loadObjectList(); - - if (count($items)) - { - $lang = JFactory::getLanguage(); - - foreach ($items as &$item) - { - // Load language - $extension = $item->value; - $source = JPATH_ADMINISTRATOR . '/components/' . $extension; - $lang->load("$extension.sys", JPATH_ADMINISTRATOR, null, false, true) - || $lang->load("$extension.sys", $source, null, false, true); - - // Translate component name - $item->text = JText::_($item->text); - } - - // Sort by component name - $items = ArrayHelper::sortObjects($items, 'text', 1, true, true); - } - - return $items; - } - - /** - * Get a list of the actions for the component or code actions. - * - * @param string $component The name of the component. - * - * @return array - * - * @since 1.6 - */ - public static function getDebugActions($component = null) - { - $actions = array(); - - // Try to get actions for the component - if (!empty($component)) - { - $component_actions = JAccess::getActions($component); - - if (!empty($component_actions)) - { - foreach ($component_actions as &$action) - { - $actions[$action->title] = array($action->name, $action->description); - } - } - } - - // Use default actions from configuration if no component selected or component doesn't have actions - if (empty($actions)) - { - $filename = JPATH_ADMINISTRATOR . '/components/com_config/model/form/application.xml'; - - if (is_file($filename)) - { - $xml = simplexml_load_file($filename); - - foreach ($xml->children()->fieldset as $fieldset) - { - if ('permissions' == (string) $fieldset['name']) - { - foreach ($fieldset->children() as $field) - { - if ('rules' == (string) $field['name']) - { - foreach ($field->children() as $action) - { - $actions[(string) $action['title']] = array( - (string) $action['name'], - (string) $action['description'] - ); - } - - break; - } - } - } - } - - // Load language - $lang = JFactory::getLanguage(); - $extension = 'com_config'; - $source = JPATH_ADMINISTRATOR . '/components/' . $extension; - - $lang->load($extension, JPATH_ADMINISTRATOR, null, false, false) - || $lang->load($extension, $source, null, false, false) - || $lang->load($extension, JPATH_ADMINISTRATOR, $lang->getDefault(), false, false) - || $lang->load($extension, $source, $lang->getDefault(), false, false); - } - } - - return $actions; - } - - /** - * Get a list of filter options for the levels. - * - * @return array An array of JHtmlOption elements. - */ - public static function getLevelsOptions() - { - // Build the filter options. - $options = array(); - $options[] = JHtml::_('select.option', '1', JText::sprintf('COM_USERS_OPTION_LEVEL_COMPONENT', 1)); - $options[] = JHtml::_('select.option', '2', JText::sprintf('COM_USERS_OPTION_LEVEL_CATEGORY', 2)); - $options[] = JHtml::_('select.option', '3', JText::sprintf('COM_USERS_OPTION_LEVEL_DEEPER', 3)); - $options[] = JHtml::_('select.option', '4', '4'); - $options[] = JHtml::_('select.option', '5', '5'); - $options[] = JHtml::_('select.option', '6', '6'); - return $options; - } } diff --git a/administrator/components/com_users/helpers/html/users.php b/administrator/components/com_users/helpers/html/users.php index e1a81604ba41b..c9cf8d8dbedc1 100644 --- a/administrator/components/com_users/helpers/html/users.php +++ b/administrator/components/com_users/helpers/html/users.php @@ -9,6 +9,12 @@ defined('_JEXEC') or die; +use Joomla\CMS\Filesystem\Path; +use Joomla\CMS\Uri\Uri; +use Joomla\CMS\Router\Route; +use Joomla\CMS\Language\Text; +use Joomla\CMS\HTML\HTMLHelper; + /** * Extended Utility class for the Users component. * @@ -24,21 +30,21 @@ class JHtmlUsers * @return string A element if the specified file exists, otherwise, a null string * * @since 2.5 + * @throws \Exception */ public static function image($src) { $src = preg_replace('#[^A-Z0-9\-_\./]#i', '', $src); $file = JPATH_SITE . '/' . $src; - jimport('joomla.filesystem.path'); - JPath::check($file); + Path::check($file); if (!file_exists($file)) { return ''; } - return ''; + return ''; } /** @@ -52,10 +58,11 @@ public static function image($src) */ public static function addNote($userId) { - $title = JText::_('COM_USERS_ADD_NOTE'); + $title = Text::_('COM_USERS_ADD_NOTE'); - return '' . $title . ''; + return ' ' . $title . ''; } /** @@ -75,10 +82,10 @@ public static function filterNotes($count, $userId) return ''; } - $title = JText::_('COM_USERS_FILTER_NOTES'); + $title = Text::_('COM_USERS_FILTER_NOTES'); - return ''; + return ' ' . $title . ''; } /** @@ -98,10 +105,10 @@ public static function notes($count, $userId) return ''; } - $title = JText::plural('COM_USERS_N_USER_NOTES', $count); + $title = Text::plural('COM_USERS_N_USER_NOTES', $count); - return '' . $title . ''; + return ' ' . $title . ''; } /** @@ -121,11 +128,11 @@ public static function notesModal($count, $userId) return ''; } - $title = JText::plural('COM_USERS_N_USER_NOTES', $count); - $footer = ''; + $title = Text::plural('COM_USERS_N_USER_NOTES', $count); + $footer = ''; - return JHtml::_( + return HTMLHelper::_( 'bootstrap.renderModal', 'userModal_' . (int) $userId, array( @@ -134,7 +141,7 @@ public static function notesModal($count, $userId) 'keyboard' => true, 'closeButton' => true, 'footer' => $footer, - 'url' => JRoute::_('index.php?option=com_users&view=notes&tmpl=component&layout=modal&filter[user_id]=' . (int) $userId), + 'url' => Route::_('index.php?option=com_users&view=notes&tmpl=component&layout=modal&filter[user_id]=' . (int) $userId), 'height' => '300px', 'width' => '800px', ) diff --git a/administrator/components/com_users/helpers/users.php b/administrator/components/com_users/helpers/users.php index 78bbc4965c80e..1197d214e3440 100644 --- a/administrator/components/com_users/helpers/users.php +++ b/administrator/components/com_users/helpers/users.php @@ -12,351 +12,10 @@ /** * Users component helper. * - * @since 1.6 + * @since 1.6 + * + * @deprecated 5.0 Use \Joomla\Component\Users\Administrator\Helper\UsersHelper instead */ -class UsersHelper +class UsersHelper extends \Joomla\Component\Users\Administrator\Helper\UsersHelper { - /** - * @var JObject A cache for the available actions. - * @since 1.6 - */ - protected static $actions; - - /** - * Configure the Linkbar. - * - * @param string $vName The name of the active view. - * - * @return void - * - * @since 1.6 - */ - public static function addSubmenu($vName) - { - JHtmlSidebar::addEntry( - JText::_('COM_USERS_SUBMENU_USERS'), - 'index.php?option=com_users&view=users', - $vName == 'users' - ); - - // Groups and Levels are restricted to core.admin - $canDo = JHelperContent::getActions('com_users'); - - if ($canDo->get('core.admin')) - { - JHtmlSidebar::addEntry( - JText::_('COM_USERS_SUBMENU_GROUPS'), - 'index.php?option=com_users&view=groups', - $vName == 'groups' - ); - JHtmlSidebar::addEntry( - JText::_('COM_USERS_SUBMENU_LEVELS'), - 'index.php?option=com_users&view=levels', - $vName == 'levels' - ); - } - - if (JComponentHelper::isEnabled('com_fields') && JComponentHelper::getParams('com_users')->get('custom_fields_enable', '1')) - { - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_FIELDS'), - 'index.php?option=com_fields&context=com_users.user', - $vName == 'fields.fields' - ); - JHtmlSidebar::addEntry( - JText::_('JGLOBAL_FIELD_GROUPS'), - 'index.php?option=com_fields&view=groups&context=com_users.user', - $vName == 'fields.groups' - ); - } - - JHtmlSidebar::addEntry( - JText::_('COM_USERS_SUBMENU_NOTES'), - 'index.php?option=com_users&view=notes', - $vName == 'notes' - ); - - JHtmlSidebar::addEntry( - JText::_('COM_USERS_SUBMENU_NOTE_CATEGORIES'), - 'index.php?option=com_categories&extension=com_users', - $vName == 'categories' - ); - } - - /** - * Gets a list of the actions that can be performed. - * - * @return JObject - * - * @deprecated 3.2 Use JHelperContent::getActions() instead - */ - public static function getActions() - { - // Log usage of deprecated function - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHelperContent::getActions() with new arguments order instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - // Get list of actions - return JHelperContent::getActions('com_users'); - } - - /** - * Get a list of filter options for the blocked state of a user. - * - * @return array An array of JHtmlOption elements. - * - * @since 1.6 - */ - public static function getStateOptions() - { - // Build the filter options. - $options = array(); - $options[] = JHtml::_('select.option', '0', JText::_('JENABLED')); - $options[] = JHtml::_('select.option', '1', JText::_('JDISABLED')); - - return $options; - } - - /** - * Get a list of filter options for the activated state of a user. - * - * @return array An array of JHtmlOption elements. - * - * @since 1.6 - */ - public static function getActiveOptions() - { - // Build the filter options. - $options = array(); - $options[] = JHtml::_('select.option', '0', JText::_('COM_USERS_ACTIVATED')); - $options[] = JHtml::_('select.option', '1', JText::_('COM_USERS_UNACTIVATED')); - - return $options; - } - - /** - * Get a list of the user groups for filtering. - * - * @return array An array of JHtmlOption elements. - * - * @since 1.6 - */ - public static function getGroups() - { - $options = JHelperUsergroups::getInstance()->getAll(); - - foreach ($options as &$option) - { - $option->value = $option->id; - $option->text = str_repeat('- ', $option->level) . $option->title; - } - - return $options; - } - - /** - * Creates a list of range options used in filter select list - * used in com_users on users view - * - * @return array - * - * @since 2.5 - */ - public static function getRangeOptions() - { - $options = array( - JHtml::_('select.option', 'today', JText::_('COM_USERS_OPTION_RANGE_TODAY')), - JHtml::_('select.option', 'past_week', JText::_('COM_USERS_OPTION_RANGE_PAST_WEEK')), - JHtml::_('select.option', 'past_1month', JText::_('COM_USERS_OPTION_RANGE_PAST_1MONTH')), - JHtml::_('select.option', 'past_3month', JText::_('COM_USERS_OPTION_RANGE_PAST_3MONTH')), - JHtml::_('select.option', 'past_6month', JText::_('COM_USERS_OPTION_RANGE_PAST_6MONTH')), - JHtml::_('select.option', 'past_year', JText::_('COM_USERS_OPTION_RANGE_PAST_YEAR')), - JHtml::_('select.option', 'post_year', JText::_('COM_USERS_OPTION_RANGE_POST_YEAR')), - ); - - return $options; - } - - /** - * Creates a list of two factor authentication methods used in com_users - * on user view - * - * @return array - * - * @since 3.2.0 - */ - public static function getTwoFactorMethods() - { - FOFPlatform::getInstance()->importPlugin('twofactorauth'); - $identities = FOFPlatform::getInstance()->runPlugins('onUserTwofactorIdentify', array()); - - $options = array( - JHtml::_('select.option', 'none', JText::_('JGLOBAL_OTPMETHOD_NONE'), 'value', 'text'), - ); - - if (!empty($identities)) - { - foreach ($identities as $identity) - { - if (!is_object($identity)) - { - continue; - } - - $options[] = JHtml::_('select.option', $identity->method, $identity->title, 'value', 'text'); - } - } - - return $options; - } - - /** - * Get a list of the User Groups for Viewing Access Levels - * - * @param string $rules User Groups in JSON format - * - * @return string $groups Comma separated list of User Groups - * - * @since 3.6 - */ - public static function getVisibleByGroups($rules) - { - $rules = json_decode($rules); - - if (!$rules) - { - return false; - } - - $rules = implode(',', $rules); - - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select('a.title AS text') - ->from('#__usergroups as a') - ->where('a.id IN (' . $rules . ')'); - $db->setQuery($query); - - $groups = $db->loadColumn(); - $groups = implode(', ', $groups); - - return $groups; - } - - /** - * Adds Count Items for Tag Manager. - * - * @param stdClass[] &$items The user note 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('c.published'); - - $db->setQuery($query); - $users = $db->loadObjectList(); - - foreach ($users as $user) - { - if ($user->state == 1) - { - $item->count_published = $user->count; - } - - if ($user->state == 0) - { - $item->count_unpublished = $user->count; - } - - if ($user->state == 2) - { - $item->count_archived = $user->count; - } - - if ($user->state == -2) - { - $item->count_trashed = $user->count; - } - } - } - - return $items; - } - - /** - * Returns a valid section for users. If it is not valid then null - * is returned. - * - * @param string $section The section to get the mapping for - * - * @return string|null The new section - * - * @since 3.7.0 - */ - public static function validateSection($section) - { - if (JFactory::getApplication()->isClient('site')) - { - switch ($section) - { - case 'registration': - case 'profile': - $section = 'user'; - } - } - - if ($section != 'user') - { - // We don't know other sections - return null; - } - - return $section; - } - - /** - * Returns valid contexts - * - * @return array - * - * @since 3.7.0 - */ - public static function getContexts() - { - JFactory::getLanguage()->load('com_users', JPATH_ADMINISTRATOR); - - $contexts = array( - 'com_users.user' => JText::_('COM_USERS'), - ); - - return $contexts; - } } diff --git a/administrator/components/com_users/models/debuggroup.php b/administrator/components/com_users/models/debuggroup.php deleted file mode 100644 index 70617eb49785c..0000000000000 --- a/administrator/components/com_users/models/debuggroup.php +++ /dev/null @@ -1,275 +0,0 @@ -getState('filter.component'); - - return UsersHelperDebug::getDebugActions($component); - } - - /** - * Override getItems method. - * - * @return array - * - * @since 1.6 - */ - public function getItems() - { - $groupId = $this->getState('group_id'); - - if (($assets = parent::getItems()) && $groupId) - { - $actions = $this->getDebugActions(); - - foreach ($assets as &$asset) - { - $asset->checks = array(); - - foreach ($actions as $action) - { - $name = $action[0]; - $level = $action[1]; - - // Check that we check this action for the level of the asset. - if ($level === null || $level >= $asset->level) - { - // We need to test this action. - $asset->checks[$name] = JAccess::checkGroup($groupId, $name, $asset->name); - } - else - { - // We ignore this action. - $asset->checks[$name] = 'skip'; - } - } - } - } - - return $assets; - } - - /** - * 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 1.6 - */ - protected function populateState($ordering = 'a.lft', $direction = 'asc') - { - $app = JFactory::getApplication('administrator'); - - // Adjust the context to support modal layouts. - $layout = $app->input->get('layout', 'default'); - - if ($layout) - { - $this->context .= '.' . $layout; - } - - // Load the filter state. - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('group_id', $this->getUserStateFromRequest($this->context . '.group_id', 'group_id', 0, 'int', false)); - - $levelStart = $this->getUserStateFromRequest($this->context . '.filter.level_start', 'filter_level_start', '', 'cmd'); - $this->setState('filter.level_start', $levelStart); - - $value = $this->getUserStateFromRequest($this->context . '.filter.level_end', 'filter_level_end', '', 'cmd'); - - if ($value > 0 && $value < $levelStart) - { - $value = $levelStart; - } - - $this->setState('filter.level_end', $value); - - $this->setState('filter.component', $this->getUserStateFromRequest($this->context . '.filter.component', 'filter_component', '', 'string')); - - // Load the parameters. - $params = JComponentHelper::getParams('com_users'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('group_id'); - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.level_start'); - $id .= ':' . $this->getState('filter.level_end'); - $id .= ':' . $this->getState('filter.component'); - - return parent::getStoreId($id); - } - - /** - * Get the group being debugged. - * - * @return JObject - * - * @since 1.6 - */ - public function getGroup() - { - $groupId = (int) $this->getState('group_id'); - - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('id, title') - ->from('#__usergroups') - ->where('id = ' . $groupId); - - $db->setQuery($query); - - try - { - $group = $db->loadObject(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - return $group; - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - * - * @since 1.6 - */ - 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.id, a.name, a.title, a.level, a.lft, a.rgt' - ) - ); - $query->from($db->quoteName('#__assets', 'a')); - - // Filter the items over the search string if set. - if ($this->getState('filter.search')) - { - // Escape the search token. - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($this->getState('filter.search')), true) . '%')); - - // Compile the different search clauses. - $searches = array(); - $searches[] = 'a.name LIKE ' . $search; - $searches[] = 'a.title LIKE ' . $search; - - // Add the clauses to the query. - $query->where('(' . implode(' OR ', $searches) . ')'); - } - - // Filter on the start and end levels. - $levelStart = (int) $this->getState('filter.level_start'); - $levelEnd = (int) $this->getState('filter.level_end'); - - if ($levelEnd > 0 && $levelEnd < $levelStart) - { - $levelEnd = $levelStart; - } - - if ($levelStart > 0) - { - $query->where('a.level >= ' . $levelStart); - } - - if ($levelEnd > 0) - { - $query->where('a.level <= ' . $levelEnd); - } - - // Filter the items over the component if set. - if ($this->getState('filter.component')) - { - $component = $this->getState('filter.component'); - $query->where('(a.name = ' . $db->quote($component) . ' OR a.name LIKE ' . $db->quote($component . '.%') . ')'); - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - return $query; - } -} diff --git a/administrator/components/com_users/models/debuguser.php b/administrator/components/com_users/models/debuguser.php deleted file mode 100644 index 584a4b825253a..0000000000000 --- a/administrator/components/com_users/models/debuguser.php +++ /dev/null @@ -1,257 +0,0 @@ -getState('filter.component'); - - return UsersHelperDebug::getDebugActions($component); - } - - /** - * Override getItems method. - * - * @return array - * - * @since 1.6 - */ - public function getItems() - { - $userId = $this->getState('user_id'); - $user = JFactory::getUser($userId); - - if (($assets = parent::getItems()) && $userId) - { - $actions = $this->getDebugActions(); - - foreach ($assets as &$asset) - { - $asset->checks = array(); - - foreach ($actions as $action) - { - $name = $action[0]; - $level = $action[1]; - - // Check that we check this action for the level of the asset. - if ($level === null || $level >= $asset->level) - { - // We need to test this action. - $asset->checks[$name] = $user->authorise($name, $asset->name); - } - else - { - // We ignore this action. - $asset->checks[$name] = 'skip'; - } - } - } - } - - return $assets; - } - - /** - * 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 1.6 - */ - protected function populateState($ordering = 'a.lft', $direction = 'asc') - { - $app = JFactory::getApplication('administrator'); - - // Adjust the context to support modal layouts. - $layout = $app->input->get('layout', 'default'); - - if ($layout) - { - $this->context .= '.' . $layout; - } - - // Load the filter state. - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('user_id', $this->getUserStateFromRequest($this->context . '.user_id', 'user_id', 0, 'int', false)); - - $levelStart = $this->getUserStateFromRequest($this->context . '.filter.level_start', 'filter_level_start', '', 'cmd'); - $this->setState('filter.level_start', $levelStart); - - $value = $this->getUserStateFromRequest($this->context . '.filter.level_end', 'filter_level_end', '', 'cmd'); - - if ($value > 0 && $value < $levelStart) - { - $value = $levelStart; - } - - $this->setState('filter.level_end', $value); - - $this->setState('filter.component', $this->getUserStateFromRequest($this->context . '.filter.component', 'filter_component', '', 'string')); - - // Load the parameters. - $params = JComponentHelper::getParams('com_users'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('user_id'); - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.level_start'); - $id .= ':' . $this->getState('filter.level_end'); - $id .= ':' . $this->getState('filter.component'); - - return parent::getStoreId($id); - } - - /** - * Get the user being debugged. - * - * @return JUser - * - * @since 1.6 - */ - public function getUser() - { - $userId = $this->getState('user_id'); - - return JFactory::getUser($userId); - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - * - * @since 1.6 - */ - 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.id, a.name, a.title, a.level, a.lft, a.rgt' - ) - ); - $query->from($db->quoteName('#__assets', 'a')); - - // Filter the items over the search string if set. - if ($this->getState('filter.search')) - { - // Escape the search token. - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($this->getState('filter.search')), true) . '%')); - - // Compile the different search clauses. - $searches = array(); - $searches[] = 'a.name LIKE ' . $search; - $searches[] = 'a.title LIKE ' . $search; - - // Add the clauses to the query. - $query->where('(' . implode(' OR ', $searches) . ')'); - } - - // Filter on the start and end levels. - $levelStart = (int) $this->getState('filter.level_start'); - $levelEnd = (int) $this->getState('filter.level_end'); - - if ($levelEnd > 0 && $levelEnd < $levelStart) - { - $levelEnd = $levelStart; - } - - if ($levelStart > 0) - { - $query->where('a.level >= ' . $levelStart); - } - - if ($levelEnd > 0) - { - $query->where('a.level <= ' . $levelEnd); - } - - // Filter the items over the component if set. - if ($this->getState('filter.component')) - { - $component = $this->getState('filter.component'); - $query->where('(a.name = ' . $db->quote($component) . ' OR a.name LIKE ' . $db->quote($component . '.%') . ')'); - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - return $query; - } -} diff --git a/administrator/components/com_users/models/fields/groupparent.php b/administrator/components/com_users/models/fields/groupparent.php deleted file mode 100644 index 479a0f42e5622..0000000000000 --- a/administrator/components/com_users/models/fields/groupparent.php +++ /dev/null @@ -1,67 +0,0 @@ -getAll(); - - // Prevent parenting to children of this item. - if ($id = $this->form->getValue('id')) - { - unset($options[$id]); - } - - $options = array_values($options); - $isSuperAdmin = JFactory::getUser()->authorise('core.admin'); - - // Pad the option text with spaces using depth level as a multiplier. - for ($i = 0, $n = count($options); $i < $n; $i++) - { - // Show groups only if user is super admin or group is not super admin - if ($isSuperAdmin || !JAccess::checkGroup($options[$i]->id, 'core.admin')) - { - $options[$i]->value = $options[$i]->id; - $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->title; - } - else - { - unset($options[$i]); - } - } - - // Merge any additional options in the XML definition. - return array_merge(parent::getOptions(), $options); - } -} diff --git a/administrator/components/com_users/models/fields/levels.php b/administrator/components/com_users/models/fields/levels.php deleted file mode 100644 index 6c55ed0959390..0000000000000 --- a/administrator/components/com_users/models/fields/levels.php +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/administrator/components/com_users/models/forms/group.xml b/administrator/components/com_users/models/forms/group.xml deleted file mode 100644 index d56950c38ae64..0000000000000 --- a/administrator/components/com_users/models/forms/group.xml +++ /dev/null @@ -1,46 +0,0 @@ - -
    -
    - - - - - - - - - - - -
    -
    diff --git a/administrator/components/com_users/models/forms/mail.xml b/administrator/components/com_users/models/forms/mail.xml deleted file mode 100644 index c1e8d5b65c285..0000000000000 --- a/administrator/components/com_users/models/forms/mail.xml +++ /dev/null @@ -1,70 +0,0 @@ - -
    -
    - - - - - - - - - - - - - - - - -
    -
    diff --git a/administrator/components/com_users/models/group.php b/administrator/components/com_users/models/group.php deleted file mode 100644 index decedb93f6cac..0000000000000 --- a/administrator/components/com_users/models/group.php +++ /dev/null @@ -1,330 +0,0 @@ - 'onUserAfterDeleteGroup', - 'event_after_save' => 'onUserAfterSaveGroup', - 'event_before_delete' => 'onUserBeforeDeleteGroup', - 'event_before_save' => 'onUserBeforeSaveGroup', - 'events_map' => array('delete' => 'user', 'save' => 'user') - ), $config - ); - - parent::__construct($config); - } - - /** - * Returns a reference to the a Table object, always creating it. - * - * @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 - * - * @since 1.6 - */ - public function getTable($type = 'Usergroup', $prefix = 'JTable', $config = array()) - { - $return = JTable::getInstance($type, $prefix, $config); - - return $return; - } - - /** - * Method to get the record form. - * - * @param array $data An optional array of data for the form to interogate. - * @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 - * - * @since 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - // Get the form. - $form = $this->loadForm('com_users.group', 'group', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_users.edit.group.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - $this->preprocessData('com_users.group', $data); - - return $data; - } - - /** - * Override preprocessForm to load the user plugin group instead of content. - * - * @param JForm $form A form object. - * @param mixed $data The data expected for the form. - * @param string $group The name of the plugin group to import (defaults to "content"). - * - * @return void - * - * @since 1.6 - * @throws Exception if there is an error loading the form. - */ - protected function preprocessForm(JForm $form, $data, $group = '') - { - $obj = is_array($data) ? ArrayHelper::toObject($data, 'JObject') : $data; - - if (isset($obj->parent_id) && $obj->parent_id == 0 && $obj->id > 0) - { - $form->setFieldAttribute('parent_id', 'type', 'hidden'); - $form->setFieldAttribute('parent_id', 'hidden', 'true'); - } - - parent::preprocessForm($form, $data, 'user'); - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function save($data) - { - // Include the user plugins for events. - JPluginHelper::importPlugin($this->events_map['save']); - - /** - * Check the super admin permissions for group - * We get the parent group permissions and then check the group permissions manually - * We have to calculate the group permissions manually because we haven't saved the group yet - */ - $parentSuperAdmin = JAccess::checkGroup($data['parent_id'], 'core.admin'); - - // Get core.admin rules from the root asset - $rules = JAccess::getAssetRules('root.1')->getData('core.admin'); - - // Get the value for the current group (will be true (allowed), false (denied), or null (inherit) - $groupSuperAdmin = $rules['core.admin']->allow($data['id']); - - // We only need to change the $groupSuperAdmin if the parent is true or false. Otherwise, the value set in the rule takes effect. - if ($parentSuperAdmin === false) - { - // If parent is false (Denied), effective value will always be false - $groupSuperAdmin = false; - } - elseif ($parentSuperAdmin === true) - { - // If parent is true (allowed), group is true unless explicitly set to false - $groupSuperAdmin = ($groupSuperAdmin === false) ? false : true; - } - - // Check for non-super admin trying to save with super admin group - $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin'); - - if (!$iAmSuperAdmin && $groupSuperAdmin) - { - $this->setError(JText::_('JLIB_USER_ERROR_NOT_SUPERADMIN')); - - return false; - } - - /** - * Check for super-admin changing self to be non-super-admin - * First, are we a super admin - */ - if ($iAmSuperAdmin) - { - // Next, are we a member of the current group? - $myGroups = JAccess::getGroupsByUser(JFactory::getUser()->get('id'), false); - - if (in_array($data['id'], $myGroups)) - { - // Now, would we have super admin permissions without the current group? - $otherGroups = array_diff($myGroups, array($data['id'])); - $otherSuperAdmin = false; - - foreach ($otherGroups as $otherGroup) - { - $otherSuperAdmin = $otherSuperAdmin ?: JAccess::checkGroup($otherGroup, 'core.admin'); - } - - /** - * If we would not otherwise have super admin permissions - * and the current group does not have super admin permissions, throw an exception - */ - if ((!$otherSuperAdmin) && (!$groupSuperAdmin)) - { - $this->setError(JText::_('JLIB_USER_ERROR_CANNOT_DEMOTE_SELF')); - - return false; - } - } - } - - if (JFactory::getApplication()->input->get('task') == 'save2copy') - { - $data['title'] = $this->generateGroupTitle($data['parent_id'], $data['title']); - } - - // Proceed with the save - return parent::save($data); - } - - /** - * Method to delete rows. - * - * @param array &$pks An array of item ids. - * - * @return boolean Returns true on success, false on failure. - * - * @since 1.6 - * @throws Exception - */ - public function delete(&$pks) - { - // Typecast variable. - $pks = (array) $pks; - $user = JFactory::getUser(); - $groups = JAccess::getGroupsByUser($user->get('id')); - - // Get a row instance. - $table = $this->getTable(); - - // Load plugins. - JPluginHelper::importPlugin($this->events_map['delete']); - $dispatcher = JEventDispatcher::getInstance(); - - // Check if I am a Super Admin - $iAmSuperAdmin = $user->authorise('core.admin'); - - // Do not allow to delete groups to which the current user belongs - foreach ($pks as $pk) - { - if (in_array($pk, $groups)) - { - JError::raiseWarning(403, JText::_('COM_USERS_DELETE_ERROR_INVALID_GROUP')); - - return false; - } - } - - // Iterate the items to delete each one. - foreach ($pks as $i => $pk) - { - if ($table->load($pk)) - { - // Access checks. - $allow = $user->authorise('core.edit.state', 'com_users'); - - // Don't allow non-super-admin to delete a super admin - $allow = (!$iAmSuperAdmin && JAccess::checkGroup($pk, 'core.admin')) ? false : $allow; - - if ($allow) - { - // Fire the before delete event. - $dispatcher->trigger($this->event_before_delete, array($table->getProperties())); - - if (!$table->delete($pk)) - { - $this->setError($table->getError()); - - return false; - } - else - { - // Trigger the after delete event. - $dispatcher->trigger($this->event_after_delete, array($table->getProperties(), true, $this->getError())); - } - } - else - { - // Prune items that you can't change. - unset($pks[$i]); - JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); - } - } - else - { - $this->setError($table->getError()); - - return false; - } - } - - return true; - } - - /** - * Method to generate the title of group on Save as Copy action - * - * @param integer $parentId The id of the parent. - * @param string $title The title of group - * - * @return string Contains the modified title. - * - * @since 3.3.7 - */ - protected function generateGroupTitle($parentId, $title) - { - // Alter the title & alias - $table = $this->getTable(); - - while ($table->load(array('title' => $title, 'parent_id' => $parentId))) - { - if ($title == $table->title) - { - $title = StringHelper::increment($title); - } - } - - return $title; - } -} diff --git a/administrator/components/com_users/models/groups.php b/administrator/components/com_users/models/groups.php deleted file mode 100644 index 6c2167f7ccf73..0000000000000 --- a/administrator/components/com_users/models/groups.php +++ /dev/null @@ -1,247 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - - // Load the parameters. - $params = JComponentHelper::getParams('com_users'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - - return parent::getStoreId($id); - } - - /** - * Gets the list of groups and adds expensive joins to the result set. - * - * @return mixed An array of data items on success, false on failure. - * - * @since 1.6 - */ - public function getItems() - { - // Get a storage key. - $store = $this->getStoreId(); - - // Try to load the data from internal storage. - if (empty($this->cache[$store])) - { - $items = parent::getItems(); - - // Bail out on an error or empty list. - if (empty($items)) - { - $this->cache[$store] = $items; - - return $items; - } - - try - { - $items = $this->populateExtraData($items); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Add the items to the internal cache. - $this->cache[$store] = $items; - } - - return $this->cache[$store]; - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - */ - 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('#__usergroups') . ' AS a'); - - // Filter the comments over the search string if set. - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('a.title LIKE ' . $search); - } - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.lft')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - return $query; - } - - /** - * Populate level & path for items. - * - * @param array $items Array of stdClass objects - * - * @return array - * - * @since 3.6.3 - */ - private function populateExtraData(array $items) - { - // First pass: get list of the group id's and reset the counts. - $groupsByKey = array(); - - foreach ($items as $item) - { - $groupsByKey[(int) $item->id] = $item; - } - - $groupIds = array_keys($groupsByKey); - - $db = $this->getDbo(); - - // Get total enabled users in group. - $query = $db->getQuery(true); - - // Count the objects in the user group. - $query->select('map.group_id, COUNT(DISTINCT map.user_id) AS user_count') - ->from($db->quoteName('#__user_usergroup_map', 'map')) - ->join('LEFT', $db->quoteName('#__users', 'u') . ' ON ' . $db->quoteName('u.id') . ' = ' . $db->quoteName('map.user_id')) - ->where($db->quoteName('map.group_id') . ' IN (' . implode(',', $groupIds) . ')') - ->where($db->quoteName('u.block') . ' = 0') - ->group($db->quoteName('map.group_id')); - $db->setQuery($query); - - try - { - $countEnabled = $db->loadAssocList('group_id', 'count_enabled'); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Get total disabled users in group. - $query->clear('where') - ->where('map.group_id IN (' . implode(',', $groupIds) . ')') - ->where('u.block = 1'); - $db->setQuery($query); - - try - { - $countDisabled = $db->loadAssocList('group_id', 'count_disabled'); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Inject the values back into the array. - foreach ($groupsByKey as &$item) - { - $item->count_enabled = isset($countEnabled[$item->id]) ? (int) $countEnabled[$item->id]['user_count'] : 0; - $item->count_disabled = isset($countDisabled[$item->id]) ? (int) $countDisabled[$item->id]['user_count'] : 0; - $item->user_count = $item->count_enabled + $item->count_disabled; - } - - $groups = new JHelperUsergroups($groupsByKey); - - return array_values($groups->getAll()); - } -} diff --git a/administrator/components/com_users/models/level.php b/administrator/components/com_users/models/level.php deleted file mode 100644 index 5bcdb8860e6bf..0000000000000 --- a/administrator/components/com_users/models/level.php +++ /dev/null @@ -1,220 +0,0 @@ -levelsInUse === null) - { - // Populate the list once. - $this->levelsInUse = array(); - - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('DISTINCT access'); - - // Get all the tables and the prefix - $tables = $db->getTableList(); - $prefix = $db->getPrefix(); - - foreach ($tables as $table) - { - // Get all of the columns in the table - $fields = $db->getTableColumns($table); - - /** - * We are looking for the access field. If custom tables are using something other - * than the 'access' field they are on their own unfortunately. - * Also make sure the table prefix matches the live db prefix (eg, it is not a "bak_" table) - */ - if (strpos($table, $prefix) === 0 && isset($fields['access'])) - { - // Lookup the distinct values of the field. - $query->clear('from') - ->from($db->quoteName($table)); - $db->setQuery($query); - - try - { - $values = $db->loadColumn(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - $this->levelsInUse = array_merge($this->levelsInUse, $values); - - // TODO Could assemble an array of the tables used by each view level list those, - // giving the user a clue in the error where to look. - } - } - - // Get uniques. - $this->levelsInUse = array_unique($this->levelsInUse); - - // Ok, after all that we are ready to check the record :) - } - - if (in_array($record->id, $this->levelsInUse)) - { - $this->setError(JText::sprintf('COM_USERS_ERROR_VIEW_LEVEL_IN_USE', $record->id, $record->title)); - - return false; - } - - return parent::canDelete($record); - } - - /** - * Returns a reference to the a Table object, always creating it. - * - * @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 - * - * @since 1.6 - */ - public function getTable($type = 'Viewlevel', $prefix = 'JTable', $config = array()) - { - $return = JTable::getInstance($type, $prefix, $config); - - return $return; - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - * - * @since 1.6 - */ - public function getItem($pk = null) - { - $result = parent::getItem($pk); - - // Convert the params field to an array. - $result->rules = json_decode($result->rules); - - return $result; - } - - /** - * Method to get the record form. - * - * @param array $data An optional array of data for the form to interogate. - * @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 - * - * @since 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - // Get the form. - $form = $this->loadForm('com_users.level', 'level', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_users.edit.level.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - $this->preprocessData('com_users.level', $data); - - return $data; - } - - /** - * Method to preprocess the form - * - * @param JForm $form A form object. - * @param mixed $data The data expected for the form. - * @param string $group The name of the plugin group to import (defaults to "content"). - * - * @return void - * - * @since 1.6 - * @throws Exception if there is an error loading the form. - */ - protected function preprocessForm(JForm $form, $data, $group = '') - { - parent::preprocessForm($form, $data, 'user'); - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function save($data) - { - if (!isset($data['rules'])) - { - $data['rules'] = array(); - } - - $data['title'] = JFilterInput::getInstance()->clean($data['title'], 'TRIM'); - - return parent::save($data); - } -} diff --git a/administrator/components/com_users/models/levels.php b/administrator/components/com_users/models/levels.php deleted file mode 100644 index 896cdbe8c0a6b..0000000000000 --- a/administrator/components/com_users/models/levels.php +++ /dev/null @@ -1,229 +0,0 @@ -setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search')); - - // Load the parameters. - $params = JComponentHelper::getParams('com_users'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - - return parent::getStoreId($id); - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - */ - 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('#__viewlevels') . ' AS a'); - - // Add the level in the tree. - $query->group('a.id, a.title, a.ordering, a.rules'); - - // Filter the items over the search string if set. - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('a.title LIKE ' . $search); - } - } - - $query->group('a.id'); - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - return $query; - } - - /** - * Method to adjust the ordering of a row. - * - * @param integer $pk The ID of the primary key to move. - * @param integer $direction Increment, usually +1 or -1 - * - * @return boolean False on failure or error, true otherwise. - */ - public function reorder($pk, $direction = 0) - { - // Sanitize the id and adjustment. - $pk = (!empty($pk)) ? $pk : (int) $this->getState('level.id'); - $user = JFactory::getUser(); - - // Get an instance of the record's table. - $table = JTable::getInstance('viewlevel'); - - // Load the row. - if (!$table->load($pk)) - { - $this->setError($table->getError()); - - return false; - } - - // Access checks. - $allow = $user->authorise('core.edit.state', 'com_users'); - - if (!$allow) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - - return false; - } - - // Move the row. - // TODO: Where clause to restrict category. - $table->move($pk); - - return true; - } - - /** - * Saves the manually set order of records. - * - * @param array $pks An array of primary key ids. - * @param integer $order Order position - * - * @return boolean|JException Boolean true on success, boolean false or JException instance on error - */ - public function saveorder($pks, $order) - { - $table = JTable::getInstance('viewlevel'); - $user = JFactory::getUser(); - $conditions = array(); - - if (empty($pks)) - { - return JError::raiseWarning(500, JText::_('COM_USERS_ERROR_LEVELS_NOLEVELS_SELECTED')); - } - - // Update ordering values - foreach ($pks as $i => $pk) - { - $table->load((int) $pk); - - // Access checks. - $allow = $user->authorise('core.edit.state', 'com_users'); - - if (!$allow) - { - // Prune items that you can't change. - unset($pks[$i]); - JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - } - elseif ($table->ordering != $order[$i]) - { - $table->ordering = $order[$i]; - - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - } - } - - // Execute reorder for each category. - foreach ($conditions as $cond) - { - $table->load($cond[0]); - $table->reorder($cond[1]); - } - - return true; - } -} diff --git a/administrator/components/com_users/models/mail.php b/administrator/components/com_users/models/mail.php deleted file mode 100644 index 274fb616fa621..0000000000000 --- a/administrator/components/com_users/models/mail.php +++ /dev/null @@ -1,216 +0,0 @@ -loadForm('com_users.mail', 'mail', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_users.display.mail.data', array()); - - $this->preprocessData('com_users.mail', $data); - - return $data; - } - - /** - * Method to preprocess the form - * - * @param JForm $form A form object. - * @param mixed $data The data expected for the form. - * @param string $group The name of the plugin group to import (defaults to "content"). - * - * @return void - * - * @since 1.6 - * @throws Exception if there is an error loading the form. - */ - protected function preprocessForm(JForm $form, $data, $group = 'user') - { - parent::preprocessForm($form, $data, $group); - } - - /** - * Send the email - * - * @return boolean - */ - public function send() - { - $app = JFactory::getApplication(); - $data = $app->input->post->get('jform', array(), 'array'); - $user = JFactory::getUser(); - $access = new JAccess; - $db = $this->getDbo(); - - $mode = array_key_exists('mode', $data) ? (int) $data['mode'] : 0; - $subject = array_key_exists('subject', $data) ? $data['subject'] : ''; - $grp = array_key_exists('group', $data) ? (int) $data['group'] : 0; - $recurse = array_key_exists('recurse', $data) ? (int) $data['recurse'] : 0; - $bcc = array_key_exists('bcc', $data) ? (int) $data['bcc'] : 0; - $disabled = array_key_exists('disabled', $data) ? (int) $data['disabled'] : 0; - $message_body = array_key_exists('message', $data) ? $data['message'] : ''; - - // Automatically removes html formatting - if (!$mode) - { - $message_body = JFilterInput::getInstance()->clean($message_body, 'string'); - } - - // Check for a message body and subject - if (!$message_body || !$subject) - { - $app->setUserState('com_users.display.mail.data', $data); - $this->setError(JText::_('COM_USERS_MAIL_PLEASE_FILL_IN_THE_FORM_CORRECTLY')); - - return false; - } - - // Get users in the group out of the ACL - $to = $access->getUsersByGroup($grp, $recurse); - - // Get all users email and group except for senders - $query = $db->getQuery(true) - ->select('email') - ->from('#__users') - ->where('id != ' . (int) $user->get('id')); - - if ($grp !== 0) - { - if (empty($to)) - { - $query->where('0'); - } - else - { - $query->where('id IN (' . implode(',', $to) . ')'); - } - } - - if ($disabled == 0) - { - $query->where('block = 0'); - } - - $db->setQuery($query); - $rows = $db->loadColumn(); - - // Check to see if there are any users in this group before we continue - if (!count($rows)) - { - $app->setUserState('com_users.display.mail.data', $data); - - if (in_array($user->id, $to)) - { - $this->setError(JText::_('COM_USERS_MAIL_ONLY_YOU_COULD_BE_FOUND_IN_THIS_GROUP')); - } - else - { - $this->setError(JText::_('COM_USERS_MAIL_NO_USERS_COULD_BE_FOUND_IN_THIS_GROUP')); - } - - return false; - } - - // Get the Mailer - $mailer = JFactory::getMailer(); - $params = JComponentHelper::getParams('com_users'); - - // Build email message format. - $mailer->setSender(array($app->get('mailfrom'), $app->get('fromname'))); - $mailer->setSubject($params->get('mailSubjectPrefix') . stripslashes($subject)); - $mailer->setBody($message_body . $params->get('mailBodySuffix')); - $mailer->IsHtml($mode); - - // Add recipients - if ($bcc) - { - $mailer->addBcc($rows); - $mailer->addRecipient($app->get('mailfrom')); - } - else - { - $mailer->addRecipient($rows); - } - - // Send the Mail - $rs = $mailer->Send(); - - // Check for an error - if ($rs instanceof Exception) - { - $app->setUserState('com_users.display.mail.data', $data); - $this->setError($rs->getError()); - - return false; - } - elseif (empty($rs)) - { - $app->setUserState('com_users.display.mail.data', $data); - $this->setError(JText::_('COM_USERS_MAIL_THE_MAIL_COULD_NOT_BE_SENT')); - - return false; - } - else - { - /** - * Fill the data (specially for the 'mode', 'group' and 'bcc': they could not exist in the array - * when the box is not checked and in this case, the default value would be used instead of the '0' - * one) - */ - $data['mode'] = $mode; - $data['subject'] = $subject; - $data['group'] = $grp; - $data['recurse'] = $recurse; - $data['bcc'] = $bcc; - $data['message'] = $message_body; - $app->setUserState('com_users.display.mail.data', array()); - $app->enqueueMessage(JText::plural('COM_USERS_MAIL_EMAIL_SENT_TO_N_USERS', count($rows)), 'message'); - - return true; - } - } -} diff --git a/administrator/components/com_users/models/note.php b/administrator/components/com_users/models/note.php deleted file mode 100644 index 123961edb7104..0000000000000 --- a/administrator/components/com_users/models/note.php +++ /dev/null @@ -1,146 +0,0 @@ -loadForm('com_users.note', 'note', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - return $form; - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - * - * @since 2.5 - */ - public function getItem($pk = null) - { - $result = parent::getItem($pk); - - // Get the dispatcher and load the content plugins. - $dispatcher = JEventDispatcher::getInstance(); - JPluginHelper::importPlugin('content'); - - // Load the user plugins for backward compatibility (v3.3.3 and earlier). - JPluginHelper::importPlugin('user'); - - // Trigger the data preparation event. - $dispatcher->trigger('onContentPrepareData', array('com_users.note', $result)); - - return $result; - } - - /** - * 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 The table object - * - * @since 2.5 - */ - public function getTable($name = 'Note', $prefix = 'UsersTable', $options = array()) - { - return JTable::getInstance($name, $prefix, $options); - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Get the application - $app = JFactory::getApplication(); - - // Check the session for previously entered form data. - $data = $app->getUserState('com_users.edit.note.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - - // Prime some default values. - if ($this->getState('note.id') == 0) - { - $data->set('catid', $app->input->get('catid', $app->getUserState('com_users.notes.filter.category_id'), 'int')); - } - - $userId = $app->input->get('u_id', 0, 'int'); - - if ($userId != 0) - { - $data->user_id = $userId; - } - } - - $this->preprocessData('com_users.note', $data); - - return $data; - } - - /** - * Method to auto-populate the model state. - * - * Note. Calling getState in this method will result in recursion. - * - * @return void - * - * @since 2.5 - */ - protected function populateState() - { - parent::populateState(); - - $userId = JFactory::getApplication()->input->get('u_id', 0, 'int'); - $this->setState('note.user_id', $userId); - } -} diff --git a/administrator/components/com_users/models/notes.php b/administrator/components/com_users/models/notes.php deleted file mode 100644 index 4bb9b247912f4..0000000000000 --- a/administrator/components/com_users/models/notes.php +++ /dev/null @@ -1,220 +0,0 @@ -getDbo(); - $query = $db->getQuery(true); - - // Select the required fields from the table. - $query->select( - $this->getState('list.select', - 'a.id, a.subject, a.checked_out, a.checked_out_time,' . - 'a.catid, a.created_time, a.review_time,' . - 'a.state, a.publish_up, a.publish_down' - ) - ); - $query->from('#__user_notes AS a'); - - // Join over the category - $query->select('c.title AS category_title, c.params AS category_params') - ->join('LEFT', '#__categories AS c ON c.id = a.catid'); - - // Join over the users for the note user. - $query->select('u.name AS user_name') - ->join('LEFT', '#__users AS u ON u.id = a.user_id'); - - // Join over the users for the checked out user. - $query->select('uc.name AS editor') - ->join('LEFT', '#__users AS uc ON uc.id = a.checked_out'); - - // Filter by search in title - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - elseif (stripos($search, 'uid:') === 0) - { - $query->where('a.user_id = ' . (int) substr($search, 4)); - } - else - { - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - $query->where('((a.subject LIKE ' . $search . ') OR (u.name LIKE ' . $search . ') OR (u.username LIKE ' . $search . '))'); - } - } - - // Filter by published state - $published = $this->getState('filter.published'); - - if (is_numeric($published)) - { - $query->where('a.state = ' . (int) $published); - } - elseif ($published === '') - { - $query->where('(a.state IN (0, 1))'); - } - - // Filter by a single category. - $categoryId = (int) $this->getState('filter.category_id'); - - if ($categoryId) - { - $query->where('a.catid = ' . $categoryId); - } - - // Filter by a single user. - $userId = (int) $this->getState('filter.user_id'); - - if ($userId) - { - // Add the body and where filter. - $query->select('a.body') - ->where('a.user_id = ' . $userId); - } - - // Filter on the level. - if ($level = $this->getState('filter.level')) - { - $query->where($db->quoteName('c.level') . ' <= ' . (int) $level); - } - - // Add the list ordering clause. - $query->order($db->escape($this->getState('list.ordering', 'a.review_time')) . ' ' . $db->escape($this->getState('list.direction', 'DESC'))); - - 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 A store id. - * - * @since 2.5 - */ - 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 .= ':' . $this->getState('filter.user_id'); - $id .= ':' . $this->getState('filter.level'); - - return parent::getStoreId($id); - } - - /** - * Gets a user object if the user filter is set. - * - * @return JUser The JUser object - * - * @since 2.5 - */ - public function getUser() - { - $user = new JUser; - - // Filter by search in title - $search = (int) $this->getState('filter.user_id'); - - if ($search != 0) - { - $user->load((int) $search); - } - - return $user; - } - - /** - * 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 1.6 - */ - protected function populateState($ordering = 'a.review_time', $direction = 'desc') - { - // Adjust the context to support modal layouts. - if ($layout = JFactory::getApplication()->input->get('layout')) - { - $this->context .= '.' . $layout; - } - - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search')); - $this->setState('filter.published', $this->getUserStateFromRequest($this->context . '.filter.published', 'filter_published', '', 'string')); - $this->setState('filter.category_id', $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id')); - $this->setState('filter.user_id', $this->getUserStateFromRequest($this->context . '.filter.user_id', 'filter_user_id')); - $this->setState('filter.level', $this->getUserStateFromRequest($this->context . '.filter.level', 'filter_level', '', 'cmd')); - - parent::populateState($ordering, $direction); - } -} diff --git a/administrator/components/com_users/models/user.php b/administrator/components/com_users/models/user.php deleted file mode 100644 index 458efaaa3fd71..0000000000000 --- a/administrator/components/com_users/models/user.php +++ /dev/null @@ -1,1396 +0,0 @@ - 'onUserAfterDelete', - 'event_after_save' => 'onUserAfterSave', - 'event_before_delete' => 'onUserBeforeDelete', - 'event_before_save' => 'onUserBeforeSave', - 'events_map' => array('save' => 'user', 'delete' => 'user', 'validate' => 'user') - ), $config - ); - - parent::__construct($config); - } - - /** - * Returns a reference to the a Table object, always creating it. - * - * @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 - * - * @since 1.6 - */ - public function getTable($type = 'User', $prefix = 'JTable', $config = array()) - { - $table = JTable::getInstance($type, $prefix, $config); - - return $table; - } - - /** - * Method to get a single record. - * - * @param integer $pk The id of the primary key. - * - * @return mixed Object on success, false on failure. - * - * @since 1.6 - */ - public function getItem($pk = null) - { - $pk = (!empty($pk)) ? $pk : (int) $this->getState('user.id'); - - if ($this->_item === null) - { - $this->_item = array(); - } - - if (!isset($this->_item[$pk])) - { - $result = parent::getItem($pk); - - if ($result) - { - $result->tags = new JHelperTags; - $result->tags->getTagIds($result->id, 'com_users.user'); - } - - $this->_item[$pk] = $result; - } - - return $this->_item[$pk]; - } - - /** - * Method to get the record form. - * - * @param array $data An optional array of data for the form to interogate. - * @param boolean $loadData True if the form is to load its own data (default case), false if not. - * - * @return mixed A JForm object on success, false on failure - * - * @since 1.6 - */ - public function getForm($data = array(), $loadData = true) - { - $pluginParams = new Registry; - - if (JPluginHelper::isEnabled('user', 'joomla')) - { - $plugin = JPluginHelper::getPlugin('user', 'joomla'); - $pluginParams->loadString($plugin->params); - } - - // Get the form. - $form = $this->loadForm('com_users.user', 'user', array('control' => 'jform', 'load_data' => $loadData)); - - if (empty($form)) - { - return false; - } - - // Passwords fields are required when mail to user is set to No in joomla user plugin - $userId = $form->getValue('id'); - - if ($userId === 0 && $pluginParams->get('mail_to_user', '1') === '0') - { - $form->setFieldAttribute('password', 'required', 'true'); - $form->setFieldAttribute('password2', 'required', 'true'); - } - - // If the user needs to change their password, mark the password fields as required - if (JFactory::getUser()->requireReset) - { - $form->setFieldAttribute('password', 'required', 'true'); - $form->setFieldAttribute('password2', 'required', 'true'); - } - - // When multilanguage is set, a user's default site language should also be a Content Language - if (JLanguageMultilang::isEnabled()) - { - $form->setFieldAttribute('language', 'type', 'frontend_language', 'params'); - } - - // The user should not be able to set the requireReset value on their own account - if ((int) $userId === (int) JFactory::getUser()->id) - { - $form->removeField('requireReset'); - } - - return $form; - } - - /** - * Method to get the data that should be injected in the form. - * - * @return mixed The data for the form. - * - * @since 1.6 - */ - protected function loadFormData() - { - // Check the session for previously entered form data. - $data = JFactory::getApplication()->getUserState('com_users.edit.user.data', array()); - - if (empty($data)) - { - $data = $this->getItem(); - } - - $this->preprocessData('com_users.profile', $data, 'user'); - - return $data; - } - - /** - * Override JModelAdmin::preprocessForm to ensure the correct plugin group is loaded. - * - * @param JForm $form A JForm object. - * @param mixed $data The data expected for the form. - * @param string $group The name of the plugin group to import (defaults to "content"). - * - * @return void - * - * @since 1.6 - * @throws Exception if there is an error in the form event. - */ - protected function preprocessForm(JForm $form, $data, $group = 'user') - { - parent::preprocessForm($form, $data, $group); - } - - /** - * Method to save the form data. - * - * @param array $data The form data. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function save($data) - { - $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('user.id'); - $user = JUser::getInstance($pk); - - $my = JFactory::getUser(); - $iAmSuperAdmin = $my->authorise('core.admin'); - - // User cannot modify own user groups - if ((int) $user->id == (int) $my->id && !$iAmSuperAdmin && isset($data['groups'])) - { - // Form was probably tampered with - JFactory::getApplication()->enqueueMessage(JText::_('COM_USERS_USERS_ERROR_CANNOT_EDIT_OWN_GROUP'), 'warning'); - - $data['groups'] = null; - } - - if ($data['block'] && $pk == $my->id && !$my->block) - { - $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); - - return false; - } - - // Make sure user groups is selected when add/edit an account - if (empty($data['groups']) && ((int) $user->id != (int) $my->id || $iAmSuperAdmin)) - { - $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_SAVE_ACCOUNT_WITHOUT_GROUPS')); - - return false; - } - - // Make sure that we are not removing ourself from Super Admin group - if ($iAmSuperAdmin && $my->get('id') == $pk) - { - // Check that at least one of our new groups is Super Admin - $stillSuperAdmin = false; - $myNewGroups = $data['groups']; - - foreach ($myNewGroups as $group) - { - $stillSuperAdmin = $stillSuperAdmin ?: JAccess::checkGroup($group, 'core.admin'); - } - - if (!$stillSuperAdmin) - { - $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DEMOTE_SELF')); - - return false; - } - } - - // Handle the two factor authentication setup - if (array_key_exists('twofactor', $data)) - { - $twoFactorMethod = $data['twofactor']['method']; - - // Get the current One Time Password (two factor auth) configuration - $otpConfig = $this->getOtpConfig($pk); - - 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($pk, $otpConfig); - - // Generate one time emergency passwords if required (depleted or not set) - if (empty($otpConfig->otep)) - { - $oteps = $this->generateOteps($pk); - } - } - else - { - $otpConfig->method = 'none'; - $otpConfig->config = array(); - $this->setOtpConfig($pk, $otpConfig); - } - - // Unset the raw data - unset($data['twofactor']); - - // Reload the user record with the updated OTP configuration - $user->load($pk); - } - - // Bind the data. - if (!$user->bind($data)) - { - $this->setError($user->getError()); - - return false; - } - - // Store the data. - if (!$user->save()) - { - $this->setError($user->getError()); - - return false; - } - - $this->setState('user.id', $user->id); - - return true; - } - - /** - * Method to delete rows. - * - * @param array &$pks An array of item ids. - * - * @return boolean Returns true on success, false on failure. - * - * @since 1.6 - */ - public function delete(&$pks) - { - $user = JFactory::getUser(); - $table = $this->getTable(); - $pks = (array) $pks; - - // Check if I am a Super Admin - $iAmSuperAdmin = $user->authorise('core.admin'); - - JPluginHelper::importPlugin($this->events_map['delete']); - $dispatcher = JEventDispatcher::getInstance(); - - if (in_array($user->id, $pks)) - { - $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_DELETE_SELF')); - - return false; - } - - // Iterate the items to delete each one. - foreach ($pks as $i => $pk) - { - if ($table->load($pk)) - { - // Access checks. - $allow = $user->authorise('core.delete', 'com_users'); - - // Don't allow non-super-admin to delete a super admin - $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; - - if ($allow) - { - // Get users data for the users to delete. - $user_to_delete = JFactory::getUser($pk); - - // Fire the before delete event. - $dispatcher->trigger($this->event_before_delete, array($table->getProperties())); - - if (!$table->delete($pk)) - { - $this->setError($table->getError()); - - return false; - } - else - { - // Trigger the after delete event. - $dispatcher->trigger($this->event_after_delete, array($user_to_delete->getProperties(), true, $this->getError())); - } - } - else - { - // Prune items that you can't change. - unset($pks[$i]); - JError::raiseWarning(403, JText::_('JERROR_CORE_DELETE_NOT_PERMITTED')); - } - } - else - { - $this->setError($table->getError()); - - return false; - } - } - - return true; - } - - /** - * Method to block user records. - * - * @param array &$pks The ids of the items to publish. - * @param integer $value The value of the published state - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function block(&$pks, $value = 1) - { - $app = JFactory::getApplication(); - $dispatcher = JEventDispatcher::getInstance(); - $user = JFactory::getUser(); - - // Check if I am a Super Admin - $iAmSuperAdmin = $user->authorise('core.admin'); - $table = $this->getTable(); - $pks = (array) $pks; - - JPluginHelper::importPlugin($this->events_map['save']); - - // Prepare the logout options. - $options = array( - 'clientid' => $app->get('shared_session', '0') ? null : 0, - ); - - // Access checks. - foreach ($pks as $i => $pk) - { - if ($value == 1 && $pk == $user->get('id')) - { - // Cannot block yourself. - unset($pks[$i]); - JError::raiseWarning(403, JText::_('COM_USERS_USERS_ERROR_CANNOT_BLOCK_SELF')); - } - elseif ($table->load($pk)) - { - $old = $table->getProperties(); - $allow = $user->authorise('core.edit.state', 'com_users'); - - // Don't allow non-super-admin to delete a super admin - $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; - - if ($allow) - { - // Skip changing of same state - if ($table->block == $value) - { - unset($pks[$i]); - continue; - } - - $table->block = (int) $value; - - // If unblocking, also change password reset count to zero to unblock reset - if ($table->block === 0) - { - $table->resetCount = 0; - } - - // Allow an exception to be thrown. - try - { - if (!$table->check()) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the before save event. - $result = $dispatcher->trigger($this->event_before_save, array($old, false, $table->getProperties())); - - if (in_array(false, $result, true)) - { - // Plugin will have to raise its own error or throw an exception. - return false; - } - - // Store the table. - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the after save event - $dispatcher->trigger($this->event_after_save, array($table->getProperties(), false, true, null)); - } - catch (Exception $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Log the user out. - if ($value) - { - $app->logout($table->id, $options); - } - } - else - { - // Prune items that you can't change. - unset($pks[$i]); - JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - } - } - } - - return true; - } - - /** - * Method to activate user records. - * - * @param array &$pks The ids of the items to activate. - * - * @return boolean True on success. - * - * @since 1.6 - */ - public function activate(&$pks) - { - $dispatcher = JEventDispatcher::getInstance(); - $user = JFactory::getUser(); - - // Check if I am a Super Admin - $iAmSuperAdmin = $user->authorise('core.admin'); - $table = $this->getTable(); - $pks = (array) $pks; - - JPluginHelper::importPlugin($this->events_map['save']); - - // Access checks. - foreach ($pks as $i => $pk) - { - if ($table->load($pk)) - { - $old = $table->getProperties(); - $allow = $user->authorise('core.edit.state', 'com_users'); - - // Don't allow non-super-admin to delete a super admin - $allow = (!$iAmSuperAdmin && JAccess::check($pk, 'core.admin')) ? false : $allow; - - if (empty($table->activation)) - { - // Ignore activated accounts. - unset($pks[$i]); - } - elseif ($allow) - { - $table->block = 0; - $table->activation = ''; - - // Allow an exception to be thrown. - try - { - if (!$table->check()) - { - $this->setError($table->getError()); - - return false; - } - - // Trigger the before save event. - $result = $dispatcher->trigger($this->event_before_save, array($old, false, $table->getProperties())); - - if (in_array(false, $result, true)) - { - // Plugin will have to raise it's own error or throw an exception. - return false; - } - - // Store the table. - if (!$table->store()) - { - $this->setError($table->getError()); - - return false; - } - - // Fire the after save event - $dispatcher->trigger($this->event_after_save, array($table->getProperties(), false, true, null)); - } - catch (Exception $e) - { - $this->setError($e->getMessage()); - - return false; - } - } - else - { - // Prune items that you can't change. - unset($pks[$i]); - JError::raiseWarning(403, JText::_('JLIB_APPLICATION_ERROR_EDITSTATE_NOT_PERMITTED')); - } - } - } - - return true; - } - - /** - * Method to perform batch operations on an item or a set of items. - * - * @param array $commands An array of commands to perform. - * @param array $pks An array of item ids. - * @param array $contexts An array of item contexts. - * - * @return boolean Returns true on success, false on failure. - * - * @since 2.5 - */ - public function batch($commands, $pks, $contexts) - { - // Sanitize user ids. - $pks = array_unique($pks); - $pks = ArrayHelper::toInteger($pks); - - // Remove any values of zero. - if (array_search(0, $pks, true)) - { - unset($pks[array_search(0, $pks, true)]); - } - - if (empty($pks)) - { - $this->setError(JText::_('COM_USERS_USERS_NO_ITEM_SELECTED')); - - return false; - } - - $done = false; - - if (!empty($commands['group_id'])) - { - $cmd = ArrayHelper::getValue($commands, 'group_action', 'add'); - - if (!$this->batchUser((int) $commands['group_id'], $pks, $cmd)) - { - return false; - } - - $done = true; - } - - if (!empty($commands['reset_id'])) - { - if (!$this->batchReset($pks, $commands['reset_id'])) - { - return false; - } - - $done = true; - } - - if (!$done) - { - $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); - - return false; - } - - // Clear the cache - $this->cleanCache(); - - return true; - } - - /** - * Batch flag users as being required to reset their passwords - * - * @param array $user_ids An array of user IDs on which to operate - * @param string $action The action to perform - * - * @return boolean True on success, false on failure - * - * @since 3.2 - */ - public function batchReset($user_ids, $action) - { - $user_ids = ArrayHelper::toInteger($user_ids); - - // Check if I am a Super Admin - $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin'); - - // Non-super super user cannot work with super-admin user. - if (!$iAmSuperAdmin && JUserHelper::checkSuperUserInUsers($user_ids)) - { - $this->setError(JText::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER')); - - return false; - } - - // Set the action to perform - if ($action === 'yes') - { - $value = 1; - } - else - { - $value = 0; - } - - // Prune out the current user if they are in the supplied user ID array - $user_ids = array_diff($user_ids, array(JFactory::getUser()->id)); - - if (empty($user_ids)) - { - $this->setError(JText::_('COM_USERS_USERS_ERROR_CANNOT_REQUIRERESET_SELF')); - - return false; - } - - // Get the DB object - $db = $this->getDbo(); - - $user_ids = ArrayHelper::toInteger($user_ids); - - $query = $db->getQuery(true); - - // Update the reset flag - $query->update($db->quoteName('#__users')) - ->set($db->quoteName('requireReset') . ' = ' . $value) - ->where($db->quoteName('id') . ' IN (' . implode(',', $user_ids) . ')'); - - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - return true; - } - - /** - * Perform batch operations - * - * @param integer $group_id The group ID which assignments are being edited - * @param array $user_ids An array of user IDs on which to operate - * @param string $action The action to perform - * - * @return boolean True on success, false on failure - * - * @since 1.6 - */ - public function batchUser($group_id, $user_ids, $action) - { - $user_ids = ArrayHelper::toInteger($user_ids); - - // Check if I am a Super Admin - $iAmSuperAdmin = JFactory::getUser()->authorise('core.admin'); - - // Non-super super user cannot work with super-admin user. - if (!$iAmSuperAdmin && JUserHelper::checkSuperUserInUsers($user_ids)) - { - $this->setError(JText::_('COM_USERS_ERROR_CANNOT_BATCH_SUPERUSER')); - - return false; - } - - // Non-super admin cannot work with super-admin group. - if ((!$iAmSuperAdmin && JAccess::checkGroup($group_id, 'core.admin')) || $group_id < 1) - { - $this->setError(JText::_('COM_USERS_ERROR_INVALID_GROUP')); - - return false; - } - - // Get the DB object - $db = $this->getDbo(); - - switch ($action) - { - // Sets users to a selected group - case 'set': - $doDelete = 'all'; - $doAssign = true; - break; - - // Remove users from a selected group - case 'del': - $doDelete = 'group'; - break; - - // Add users to a selected group - case 'add': - default: - $doAssign = true; - break; - } - - // Remove the users from the group if requested. - if (isset($doDelete)) - { - $query = $db->getQuery(true); - - // Remove users from the group - $query->delete($db->quoteName('#__user_usergroup_map')) - ->where($db->quoteName('user_id') . ' IN (' . implode(',', $user_ids) . ')'); - - // Only remove users from selected group - if ($doDelete == 'group') - { - $query->where($db->quoteName('group_id') . ' = ' . (int) $group_id); - } - - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - } - - // Assign the users to the group if requested. - if (isset($doAssign)) - { - $query = $db->getQuery(true); - - // First, we need to check if the user is already assigned to a group - $query->select($db->quoteName('user_id')) - ->from($db->quoteName('#__user_usergroup_map')) - ->where($db->quoteName('group_id') . ' = ' . (int) $group_id); - $db->setQuery($query); - $users = $db->loadColumn(); - - // Build the values clause for the assignment query. - $query->clear(); - $groups = false; - - foreach ($user_ids as $id) - { - if (!in_array($id, $users)) - { - $query->values($id . ',' . $group_id); - $groups = true; - } - } - - // If we have no users to process, throw an error to notify the user - if (!$groups) - { - $this->setError(JText::_('COM_USERS_ERROR_NO_ADDITIONS')); - - return false; - } - - $query->insert($db->quoteName('#__user_usergroup_map')) - ->columns(array($db->quoteName('user_id'), $db->quoteName('group_id'))); - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - } - - return true; - } - - /** - * Gets the available groups. - * - * @return array An array of groups - * - * @since 1.6 - */ - public function getGroups() - { - $user = JFactory::getUser(); - - if ($user->authorise('core.edit', 'com_users') && $user->authorise('core.manage', 'com_users')) - { - $model = JModelLegacy::getInstance('Groups', 'UsersModel', array('ignore_request' => true)); - - return $model->getItems(); - } - else - { - return null; - } - } - - /** - * Gets the groups this object is assigned to - * - * @param integer $userId The user ID to retrieve the groups for - * - * @return array An array of assigned groups - * - * @since 1.6 - */ - public function getAssignedGroups($userId = null) - { - $userId = (!empty($userId)) ? $userId : (int) $this->getState('user.id'); - - if (empty($userId)) - { - $result = array(); - $form = $this->getForm(); - - if ($form) - { - $groupsIDs = $form->getValue('groups'); - } - - if (!empty($groupsIDs)) - { - $result = $groupsIDs; - } - else - { - $config = JComponentHelper::getParams('com_users'); - - if ($groupId = $config->get('new_usertype')) - { - $result[] = $groupId; - } - } - } - else - { - $result = JUserHelper::getUserGroups($userId); - } - - return $result; - } - - /** - * Returns the one time password (OTP) – a.k.a. two factor authentication – - * configuration for a particular user. - * - * @param integer $user_id The numeric ID of the user - * - * @return stdClass An object holding the OTP configuration for this user - * - * @since 3.2 - */ - public function getOtpConfig($user_id = null) - { - $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); - - // Initialise - $otpConfig = (object) array( - 'method' => 'none', - 'config' => array(), - 'otep' => array() - ); - - /** - * Get the raw data, without going through JUser (required in order to - * be able to modify the user record before logging in the user). - */ - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select('*') - ->from($db->qn('#__users')) - ->where($db->qn('id') . ' = ' . (int) $user_id); - $db->setQuery($query); - $item = $db->loadObject(); - - // Make sure this user does have OTP enabled - if (empty($item->otpKey)) - { - return $otpConfig; - } - - // Get the encrypted data - list($method, $config) = explode(':', $item->otpKey, 2); - $encryptedOtep = $item->otep; - - // Get the secret key, yes the thing that is saved in the configuration file - $key = $this->getOtpConfigEncryptionKey(); - - if (strpos($config, '{') === false) - { - $openssl = new FOFEncryptAes($key, 256); - $mcrypt = new FOFEncryptAes($key, 256, 'cbc', null, 'mcrypt'); - - $decryptedConfig = $mcrypt->decryptString($config); - - if (strpos($decryptedConfig, '{') !== false) - { - // Data encrypted with mcrypt - $decryptedOtep = $mcrypt->decryptString($encryptedOtep); - $encryptedOtep = $openssl->encryptString($decryptedOtep); - } - else - { - // Config data seems to be save encrypted, this can happen with 3.6.3 and openssl, lets get the data - $decryptedConfig = $openssl->decryptString($config); - } - - $otpKey = $method . ':' . $decryptedConfig; - - $query = $db->getQuery(true) - ->update($db->qn('#__users')) - ->set($db->qn('otep') . '=' . $db->q($encryptedOtep)) - ->set($db->qn('otpKey') . '=' . $db->q($otpKey)) - ->where($db->qn('id') . ' = ' . $db->q($user_id)); - $db->setQuery($query); - $db->execute(); - } - else - { - $decryptedConfig = $config; - } - - // Create an encryptor class - $aes = new FOFEncryptAes($key, 256); - - // Decrypt the data - $decryptedOtep = $aes->decryptString($encryptedOtep); - - // Remove the null padding added during encryption - $decryptedConfig = rtrim($decryptedConfig, "\0"); - $decryptedOtep = rtrim($decryptedOtep, "\0"); - - // Update the configuration object - $otpConfig->method = $method; - $otpConfig->config = @json_decode($decryptedConfig); - $otpConfig->otep = @json_decode($decryptedOtep); - - /* - * If the decryption failed for any reason we essentially disable the - * two-factor authentication. This prevents impossible to log in sites - * if the site admin changes the site secret for any reason. - */ - if (is_null($otpConfig->config)) - { - $otpConfig->config = array(); - } - - if (is_object($otpConfig->config)) - { - $otpConfig->config = (array) $otpConfig->config; - } - - if (is_null($otpConfig->otep)) - { - $otpConfig->otep = array(); - } - - if (is_object($otpConfig->otep)) - { - $otpConfig->otep = (array) $otpConfig->otep; - } - - // Return the configuration object - return $otpConfig; - } - - /** - * 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 $user_id The numeric ID of the user - * @param stdClass $otpConfig The OTP configuration object - * - * @return boolean True on success - * - * @since 3.2 - */ - public function setOtpConfig($user_id, $otpConfig) - { - $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); - - $updates = (object) array( - 'id' => $user_id, - 'otpKey' => '', - 'otep' => '' - ); - - // Create an encryptor class - $key = $this->getOtpConfigEncryptionKey(); - $aes = new FOFEncryptAes($key, 256); - - // Create the encrypted option strings - if (!empty($otpConfig->method) && ($otpConfig->method != 'none')) - { - $decryptedConfig = json_encode($otpConfig->config); - $decryptedOtep = json_encode($otpConfig->otep); - $updates->otpKey = $otpConfig->method . ':' . $decryptedConfig; - $updates->otep = $aes->encryptString($decryptedOtep); - } - - $db = $this->getDbo(); - $result = $db->updateObject('#__users', $updates, 'id'); - - return $result; - } - - /** - * Gets the symmetric encryption key for the OTP configuration data. It - * currently returns the site's secret. - * - * @return string The encryption key - * - * @since 3.2 - */ - public function getOtpConfigEncryptionKey() - { - return JFactory::getConfig()->get('secret'); - } - - /** - * Gets the configuration forms for all two-factor authentication methods - * in an array. - * - * @param integer $user_id The user ID to load the forms for (optional) - * - * @return array - * - * @since 3.2 - */ - public function getTwofactorform($user_id = null) - { - $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); - - $otpConfig = $this->getOtpConfig($user_id); - - FOFPlatform::getInstance()->importPlugin('twofactorauth'); - - return FOFPlatform::getInstance()->runPlugins('onUserTwofactorShowConfiguration', array($otpConfig, $user_id)); - } - - /** - * Generates a new set of One Time Emergency Passwords (OTEPs) for a given user. - * - * @param integer $user_id The user ID - * @param integer $count How many OTEPs to generate? Default: 10 - * - * @return array The generated OTEPs - * - * @since 3.2 - */ - public function generateOteps($user_id, $count = 10) - { - $user_id = (!empty($user_id)) ? $user_id : (int) $this->getState('user.id'); - - // Initialise - $oteps = array(); - - // Get the OTP configuration for the user - $otpConfig = $this->getOtpConfig($user_id); - - // If two factor authentication is not enabled, abort - if (empty($otpConfig->method) || ($otpConfig->method == 'none')) - { - return $oteps; - } - - $salt = '0123456789'; - $base = strlen($salt); - $length = 16; - - for ($i = 0; $i < $count; $i++) - { - $makepass = ''; - $random = JCrypt::genRandomBytes($length + 1); - $shift = ord($random[0]); - - for ($j = 1; $j <= $length; ++$j) - { - $makepass .= $salt[($shift + ord($random[$j])) % $base]; - $shift += ord($random[$j]); - } - - $oteps[] = $makepass; - } - - $otpConfig->otep = $oteps; - - // Save the now modified OTP configuration - $this->setOtpConfig($user_id, $otpConfig); - - return $oteps; - } - - /** - * Checks if the provided secret key is a valid two factor authentication - * secret key. If not, it will check it against the list of one time - * emergency passwords (OTEPs). If it's a valid OTEP it will also remove it - * from the user's list of OTEPs. - * - * This method will return true in the following conditions: - * - The two factor authentication is not enabled - * - You have provided a valid secret key for - * - You have provided a valid OTEP - * - * You can define the following options in the $options array: - * otp_config The OTP (one time password, a.k.a. two factor auth) - * configuration object. If not set we'll load it automatically. - * warn_if_not_req Issue a warning if you are checking a secret key against - * a user account which doesn't have any two factor - * authentication method enabled. - * warn_irq_msg The string to use for the warn_if_not_req warning - * - * @param integer $user_id The user's numeric ID - * @param string $secretkey The secret key you want to check - * @param array $options Options; see above - * - * @return boolean True if it's a valid secret key for this user. - * - * @since 3.2 - */ - public function isValidSecretKey($user_id, $secretkey, $options = array()) - { - // Load the user's OTP (one time password, a.k.a. two factor auth) configuration - if (!array_key_exists('otp_config', $options)) - { - $otpConfig = $this->getOtpConfig($user_id); - $options['otp_config'] = $otpConfig; - } - else - { - $otpConfig = $options['otp_config']; - } - - // Check if the user has enabled two factor authentication - if (empty($otpConfig->method) || ($otpConfig->method == 'none')) - { - // Load language - $lang = JFactory::getLanguage(); - $extension = 'com_users'; - $source = JPATH_ADMINISTRATOR . '/components/' . $extension; - - $lang->load($extension, JPATH_ADMINISTRATOR, null, false, true) - || $lang->load($extension, $source, null, false, true); - - $warn = true; - $warnMessage = JText::_('COM_USERS_ERROR_SECRET_CODE_WITHOUT_TFA'); - - if (array_key_exists('warn_if_not_req', $options)) - { - $warn = $options['warn_if_not_req']; - } - - if (array_key_exists('warn_irq_msg', $options)) - { - $warnMessage = $options['warn_irq_msg']; - } - - // Warn the user if they are using a secret code but they have not - // enabled two factor auth in their account. - if (!empty($secretkey) && $warn) - { - try - { - $app = JFactory::getApplication(); - $app->enqueueMessage($warnMessage, 'warning'); - } - catch (Exception $exc) - { - // This happens when we are in CLI mode. In this case - // no warning is issued - return true; - } - } - - return true; - } - - $credentials = array( - 'secretkey' => $secretkey, - ); - - // Try to validate the OTP - FOFPlatform::getInstance()->importPlugin('twofactorauth'); - - $otpAuthReplies = FOFPlatform::getInstance()->runPlugins('onUserTwofactorAuthenticate', array($credentials, $options)); - - $check = false; - - /* - * This looks like noob code but DO NOT TOUCH IT and do not convert - * to in_array(). During testing in_array() inexplicably returned - * null when the OTEP begins with a zero! o_O - */ - if (!empty($otpAuthReplies)) - { - foreach ($otpAuthReplies as $authReply) - { - $check = $check || $authReply; - } - } - - // Fall back to one time emergency passwords - if (!$check) - { - $check = $this->isValidOtep($user_id, $secretkey, $otpConfig); - } - - return $check; - } - - /** - * Checks if the supplied string is a valid one time emergency password - * (OTEP) for this user. If it is it will be automatically removed from the - * user's list of OTEPs. - * - * @param integer $user_id The user ID against which you are checking - * @param string $otep The string you want to test for validity - * @param object $otpConfig Optional; the two factor authentication configuration (automatically fetched if not set) - * - * @return boolean True if it's a valid OTEP or if two factor auth is not - * enabled in this user's account. - * - * @since 3.2 - */ - public function isValidOtep($user_id, $otep, $otpConfig = null) - { - if (is_null($otpConfig)) - { - $otpConfig = $this->getOtpConfig($user_id); - } - - // Did the user use an OTEP instead? - if (empty($otpConfig->otep)) - { - if (empty($otpConfig->method) || ($otpConfig->method == 'none')) - { - // Two factor authentication is not enabled on this account. - // Any string is assumed to be a valid OTEP. - return true; - } - else - { - /** - * Two factor authentication enabled and no OTEPs defined. The - * user has used them all up. Therefore anything they enter is - * an invalid OTEP. - */ - return false; - } - } - - // Clean up the OTEP (remove dashes, spaces and other funny stuff - // our beloved users may have unwittingly stuffed in it) - $otep = filter_var($otep, FILTER_SANITIZE_NUMBER_INT); - $otep = str_replace('-', '', $otep); - - $check = false; - - // Did we find a valid OTEP? - if (in_array($otep, $otpConfig->otep)) - { - // Remove the OTEP from the array - $otpConfig->otep = array_diff($otpConfig->otep, array($otep)); - - $this->setOtpConfig($user_id, $otpConfig); - - // Return true; the OTEP was a valid one - $check = true; - } - - return $check; - } -} diff --git a/administrator/components/com_users/models/users.php b/administrator/components/com_users/models/users.php deleted file mode 100644 index c3e99c67aa8da..0000000000000 --- a/administrator/components/com_users/models/users.php +++ /dev/null @@ -1,523 +0,0 @@ -input->get('layout', 'default', 'cmd')) - { - $this->context .= '.' . $layout; - } - - // Load the filter state. - $this->setState('filter.search', $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '', 'string')); - $this->setState('filter.active', $this->getUserStateFromRequest($this->context . '.filter.active', 'filter_active', '', 'cmd')); - $this->setState('filter.state', $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'cmd')); - $this->setState('filter.group_id', $this->getUserStateFromRequest($this->context . '.filter.group_id', 'filter_group_id', null, 'int')); - $this->setState('filter.range', $this->getUserStateFromRequest($this->context . '.filter.range', 'filter_range', '', 'cmd')); - $this->setState( - 'filter.lastvisitrange', $this->getUserStateFromRequest($this->context . '.filter.lastvisitrange', 'filter_lastvisitrange', '', 'cmd') - ); - - $groups = json_decode(base64_decode($app->input->get('groups', '', 'BASE64'))); - - if (isset($groups)) - { - $groups = ArrayHelper::toInteger($groups); - } - - $this->setState('filter.groups', $groups); - - $excluded = json_decode(base64_decode($app->input->get('excluded', '', 'BASE64'))); - - if (isset($excluded)) - { - $excluded = ArrayHelper::toInteger($excluded); - } - - $this->setState('filter.excluded', $excluded); - - // Load the parameters. - $params = JComponentHelper::getParams('com_users'); - $this->setState('params', $params); - - // List state information. - parent::populateState($ordering, $direction); - } - - /** - * 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 A store id. - * - * @since 1.6 - */ - protected function getStoreId($id = '') - { - // Compile the store id. - $id .= ':' . $this->getState('filter.search'); - $id .= ':' . $this->getState('filter.active'); - $id .= ':' . $this->getState('filter.state'); - $id .= ':' . $this->getState('filter.group_id'); - $id .= ':' . $this->getState('filter.range'); - - return parent::getStoreId($id); - } - - /** - * Gets the list of users and adds expensive joins to the result set. - * - * @return mixed An array of data items on success, false on failure. - * - * @since 1.6 - */ - public function getItems() - { - // Get a storage key. - $store = $this->getStoreId(); - - // Try to load the data from internal storage. - if (empty($this->cache[$store])) - { - $groups = $this->getState('filter.groups'); - $groupId = $this->getState('filter.group_id'); - - if (isset($groups) && (empty($groups) || $groupId && !in_array($groupId, $groups))) - { - $items = array(); - } - else - { - $items = parent::getItems(); - } - - // Bail out on an error or empty list. - if (empty($items)) - { - $this->cache[$store] = $items; - - return $items; - } - - // Joining the groups with the main query is a performance hog. - // Find the information only on the result set. - - // First pass: get list of the user id's and reset the counts. - $userIds = array(); - - foreach ($items as $item) - { - $userIds[] = (int) $item->id; - $item->group_count = 0; - $item->group_names = ''; - $item->note_count = 0; - } - - // Get the counts from the database only for the users in the list. - $db = $this->getDbo(); - $query = $db->getQuery(true); - - // Join over the group mapping table. - $query->select('map.user_id, COUNT(map.group_id) AS group_count') - ->from('#__user_usergroup_map AS map') - ->where('map.user_id IN (' . implode(',', $userIds) . ')') - ->group('map.user_id') - // Join over the user groups table. - ->join('LEFT', '#__usergroups AS g2 ON g2.id = map.group_id'); - - $db->setQuery($query); - - // Load the counts into an array indexed on the user id field. - try - { - $userGroups = $db->loadObjectList('user_id'); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - $query->clear() - ->select('n.user_id, COUNT(n.id) As note_count') - ->from('#__user_notes AS n') - ->where('n.user_id IN (' . implode(',', $userIds) . ')') - ->where('n.state >= 0') - ->group('n.user_id'); - - $db->setQuery($query); - - // Load the counts into an array indexed on the aro.value field (the user id). - try - { - $userNotes = $db->loadObjectList('user_id'); - } - catch (RuntimeException $e) - { - $this->setError($e->getMessage()); - - return false; - } - - // Second pass: collect the group counts into the master items array. - foreach ($items as &$item) - { - if (isset($userGroups[$item->id])) - { - $item->group_count = $userGroups[$item->id]->group_count; - - // Group_concat in other databases is not supported - $item->group_names = $this->_getUserDisplayedGroups($item->id); - } - - if (isset($userNotes[$item->id])) - { - $item->note_count = $userNotes[$item->id]->note_count; - } - } - - // Add the items to the internal cache. - $this->cache[$store] = $items; - } - - return $this->cache[$store]; - } - - /** - * Build an SQL query to load the list data. - * - * @return JDatabaseQuery - * - * @since 1.6 - */ - 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('#__users') . ' AS a'); - - // If the model is set to check item state, add to the query. - $state = $this->getState('filter.state'); - - if (is_numeric($state)) - { - $query->where('a.block = ' . (int) $state); - } - - // If the model is set to check the activated state, add to the query. - $active = $this->getState('filter.active'); - - if (is_numeric($active)) - { - if ($active == '0') - { - $query->where('a.activation IN (' . $db->quote('') . ', ' . $db->quote('0') . ')'); - } - elseif ($active == '1') - { - $query->where($query->length('a.activation') . ' > 1'); - } - } - - // Filter the items over the group id if set. - $groupId = $this->getState('filter.group_id'); - $groups = $this->getState('filter.groups'); - - if ($groupId || isset($groups)) - { - $query->join('LEFT', '#__user_usergroup_map AS map2 ON map2.user_id = a.id') - ->group( - $db->quoteName( - array( - 'a.id', - 'a.name', - 'a.username', - 'a.password', - 'a.block', - 'a.sendEmail', - 'a.registerDate', - 'a.lastvisitDate', - 'a.activation', - 'a.params', - 'a.email' - ) - ) - ); - - if ($groupId) - { - $query->where('map2.group_id = ' . (int) $groupId); - } - - if (isset($groups)) - { - $query->where('map2.group_id IN (' . implode(',', $groups) . ')'); - } - } - - // Filter the items over the search string if set. - $search = $this->getState('filter.search'); - - if (!empty($search)) - { - if (stripos($search, 'id:') === 0) - { - $query->where('a.id = ' . (int) substr($search, 3)); - } - elseif (stripos($search, 'username:') === 0) - { - $search = $db->quote('%' . $db->escape(substr($search, 9), true) . '%'); - $query->where('a.username LIKE ' . $search); - } - else - { - // Escape the search token. - $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); - - // Compile the different search clauses. - $searches = array(); - $searches[] = 'a.name LIKE ' . $search; - $searches[] = 'a.username LIKE ' . $search; - $searches[] = 'a.email LIKE ' . $search; - - // Add the clauses to the query. - $query->where('(' . implode(' OR ', $searches) . ')'); - } - } - - // Add filter for registration ranges select list - $range = $this->getState('filter.range'); - - // Apply the range filter. - if ($range) - { - $dates = $this->buildDateRange($range); - - if ($dates['dNow'] === false) - { - $query->where( - $db->qn('a.registerDate') . ' < ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) - ); - } - else - { - $query->where( - $db->qn('a.registerDate') . ' >= ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) . - ' AND ' . $db->qn('a.registerDate') . ' <= ' . $db->quote($dates['dNow']->format('Y-m-d H:i:s')) - ); - } - } - - // Add filter for registration ranges select list - $lastvisitrange = $this->getState('filter.lastvisitrange'); - - // Apply the range filter. - if ($lastvisitrange) - { - $dates = $this->buildDateRange($lastvisitrange); - - if (is_string($dates['dStart'])) - { - $query->where( - $db->qn('a.lastvisitDate') . ' = ' . $db->quote($dates['dStart']) - ); - } - elseif ($dates['dNow'] === false) - { - $query->where( - $db->qn('a.lastvisitDate') . ' < ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) - ); - } - else - { - $query->where( - $db->qn('a.lastvisitDate') . ' >= ' . $db->quote($dates['dStart']->format('Y-m-d H:i:s')) . - ' AND ' . $db->qn('a.lastvisitDate') . ' <= ' . $db->quote($dates['dNow']->format('Y-m-d H:i:s')) - ); - } - } - - // Filter by excluded users - $excluded = $this->getState('filter.excluded'); - - if (!empty($excluded)) - { - $query->where('id NOT IN (' . implode(',', $excluded) . ')'); - } - - // Add the list ordering clause. - $query->order($db->qn($db->escape($this->getState('list.ordering', 'a.name'))) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); - - return $query; - } - - /** - * Construct the date range to filter on. - * - * @param string $range The textual range to construct the filter for. - * - * @return string The date range to filter on. - * - * @since 3.6.0 - */ - private function buildDateRange($range) - { - // Get UTC for now. - $dNow = new JDate; - $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 'post_year': - $dNow = false; - case 'past_year': - $dStart->modify('-1 year'); - break; - - case 'today': - // Ranges that need to align with local 'days' need special treatment. - $app = JFactory::getApplication(); - $offset = $app->get('offset'); - - // Reset the start time to be the beginning of today, local time. - $dStart = new JDate('now', $offset); - $dStart->setTime(0, 0, 0); - - // Now change the timezone back to UTC. - $tz = new DateTimeZone('GMT'); - $dStart->setTimezone($tz); - break; - case 'never': - $dNow = false; - $dStart = $this->_db->getNullDate(); - break; - } - - return array('dNow' => $dNow, 'dStart' => $dStart); - } - - /** - * SQL server change - * - * @param integer $user_id User identifier - * - * @return string Groups titles imploded :$ - */ - protected function _getUserDisplayedGroups($user_id) - { - $db = $this->getDbo(); - $query = $db->getQuery(true) - ->select($db->qn('title')) - ->from($db->qn('#__usergroups', 'ug')) - ->join('LEFT', $db->qn('#__user_usergroup_map', 'map') . ' ON (ug.id = map.group_id)') - ->where($db->qn('map.user_id') . ' = ' . (int) $user_id); - - try - { - $result = $db->setQuery($query)->loadColumn(); - } - catch (RunTimeException $e) - { - $result = array(); - } - - return implode("\n", $result); - } -} diff --git a/administrator/components/com_users/services/provider.php b/administrator/components/com_users/services/provider.php new file mode 100644 index 0000000000000..97c0f38fccfe7 --- /dev/null +++ b/administrator/components/com_users/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Users')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Users')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_users/tables/note.php b/administrator/components/com_users/tables/note.php deleted file mode 100644 index e8a644d4a2563..0000000000000 --- a/administrator/components/com_users/tables/note.php +++ /dev/null @@ -1,159 +0,0 @@ - 'com_users.note')); - } - - /** - * Overloaded store method for the notes table. - * - * @param boolean $updateNulls Toggle whether null values should be updated. - * - * @return boolean True on success, false on failure. - * - * @since 2.5 - */ - public function store($updateNulls = false) - { - $date = JFactory::getDate()->toSql(); - $userId = JFactory::getUser()->get('id'); - - $this->modified_time = $date; - $this->modified_user_id = $userId; - - if (!((int) $this->review_time)) - { - // Null date. - $this->review_time = $this->_db->getNullDate(); - } - - if (empty($this->id)) - { - // New record. - $this->created_time = $date; - $this->created_user_id = $userId; - } - - // Attempt to store the data. - return parent::store($updateNulls); - } - - /** - * Method to set the publishing state for a row or list of rows in the database - * table. The method respects checked out rows by other users and will attempt - * to check-in rows that it can after adjustments are made. - * - * @param mixed $pks An optional array of primary key values to update. If not set the instance property value is used. - * @param integer $state The publishing state. eg. [0 = unpublished, 1 = published] - * @param integer $userId The user id of the user performing the operation. - * - * @return boolean True on success. - * - * @since 2.5 - */ - public function publish($pks = null, $state = 1, $userId = 0) - { - $k = $this->_tbl_key; - - // Sanitize input. - $pks = ArrayHelper::toInteger($pks); - $userId = (int) $userId; - $state = (int) $state; - - // If there are no primary keys set check to see if the instance key is set. - if (empty($pks)) - { - if ($this->$k) - { - $pks = array($this->$k); - } - // Nothing to set publishing state on, return false. - else - { - $this->setError(JText::_('JLIB_DATABASE_ERROR_NO_ROWS_SELECTED')); - - return false; - } - } - - $query = $this->_db->getQuery(true) - ->update($this->_db->quoteName($this->_tbl)) - ->set($this->_db->quoteName('state') . ' = ' . (int) $state); - - // Build the WHERE clause for the primary keys. - $query->where($k . '=' . implode(' OR ' . $k . '=', $pks)); - - // Determine if there is checkin support for the table. - if (!property_exists($this, 'checked_out') || !property_exists($this, 'checked_out_time')) - { - $checkin = false; - } - else - { - $query->where('(checked_out = 0 OR checked_out = ' . (int) $userId . ')'); - $checkin = true; - } - - // Update the publishing state for rows with the given primary keys. - $this->_db->setQuery($query); - - try - { - $this->_db->execute(); - } - catch (RuntimeException $e) - { - $this->setError($this->_db->getMessage()); - - return false; - } - - // If checkin is supported and all rows were adjusted, check them in. - if ($checkin && (count($pks) == $this->_db->getAffectedRows())) - { - // Checkin the rows. - foreach ($pks as $pk) - { - $this->checkin($pk); - } - } - - // If the JTable instance value is in the list of primary keys that were set, set the instance. - if (in_array($this->$k, $pks)) - { - $this->state = $state; - } - - $this->setError(''); - - return true; - } -} diff --git a/administrator/components/com_users/tmpl/debuggroup/default.php b/administrator/components/com_users/tmpl/debuggroup/default.php new file mode 100644 index 0000000000000..d660dbf9a00e2 --- /dev/null +++ b/administrator/components/com_users/tmpl/debuggroup/default.php @@ -0,0 +1,106 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
    +
    + $this)); ?> +
    + + + + + + actions as $key => $action) : ?> + + + + + + + + items as $i => $item) : ?> + + + + actions as $action) : ?> + checks[$name]; + if ($check === true) : + $class = 'text-success icon-ok'; + $button = 'btn-success'; + elseif ($check === false) : + $class = 'icon-remove'; + $button = 'btn-danger'; + elseif ($check === null) : + $class = 'text-danger icon-ban-circle'; + $button = 'btn-warning'; + else : + $class = ''; + $button = ''; + endif; + ?> + + + + + + + +
    + + + + + + + + + +
    + escape($item->title); ?> + + $item->level + 1)) . $this->escape($item->name); ?> + + + + lft; ?> + - rgt; ?> + + id; ?> +
    +
    + +   +   + +
    + + + pagination->getListFooter(); ?> + +
    + + + +
    +
    diff --git a/administrator/components/com_users/tmpl/debuguser/default.php b/administrator/components/com_users/tmpl/debuguser/default.php new file mode 100644 index 0000000000000..a1f2cc0ee4eea --- /dev/null +++ b/administrator/components/com_users/tmpl/debuguser/default.php @@ -0,0 +1,106 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +?> +
    +
    + $this)); ?> +
    + + + + + + actions as $key => $action) : ?> + + + + + + + + items as $i => $item) : ?> + + + + actions as $action) : ?> + checks[$name]; + if ($check === true) : + $class = 'text-success icon-ok'; + $button = 'btn-success'; + elseif ($check === false) : + $class = 'icon-remove'; + $button = 'btn-danger'; + elseif ($check === null) : + $class = 'text-danger icon-ban-circle'; + $button = 'btn-warning'; + else : + $class = ''; + $button = ''; + endif; + ?> + + + + + + + +
    + + + + + + + + + +
    + escape($item->title); ?> + + $item->level + 1)) . $this->escape($item->name); ?> + + + + lft; ?> + - rgt; ?> + + id; ?> +
    +
    + +   +   + +
    + + + pagination->getListFooter(); ?> + +
    + + + +
    +
    diff --git a/administrator/components/com_users/tmpl/group/edit.php b/administrator/components/com_users/tmpl/group/edit.php new file mode 100644 index 0000000000000..6b9be581806ea --- /dev/null +++ b/administrator/components/com_users/tmpl/group/edit.php @@ -0,0 +1,47 @@ + + +
    +
    + +
    +
    + form->getLabel('title'); ?> +
    +
    + form->getInput('title'); ?> +
    +
    +
    + form->getField('parent_id'); ?> + hidden) : ?> +
    + label; ?> +
    + +
    + input; ?> +
    +
    +
    + + +
    diff --git a/administrator/components/com_users/views/group/tmpl/edit.xml b/administrator/components/com_users/tmpl/group/edit.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_users/views/group/tmpl/edit.xml rename to administrator/components/com_users/tmpl/group/edit.xml diff --git a/administrator/components/com_users/tmpl/groups/default.php b/administrator/components/com_users/tmpl/groups/default.php new file mode 100644 index 0000000000000..b0c8a2f990015 --- /dev/null +++ b/administrator/components/com_users/tmpl/groups/default.php @@ -0,0 +1,124 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$debugGroups = $this->state->get('params')->get('debugGroups', 1); + +Text::script('COM_USERS_GROUPS_CONFIRM_DELETE', true); + +HTMLHelper::_('script', 'com_users/admin-users-groups.min.js', array('version' => 'auto', 'relative' => true)); +?> +
    +
    +
    + sidebar; ?> +
    +
    +
    + $this, 'options' => array('filterButton' => false))); ?> + items)) : ?> + + + + + + + + + + + + + + items as $i => $item) : + $canCreate = $user->authorise('core.create', 'com_users'); + $canEdit = $user->authorise('core.edit', 'com_users'); + + // If this group is super admin and this user is not super admin, $canEdit is false + if (!$user->authorise('core.admin') && Access::checkGroup($item->id, 'core.admin')) + { + $canEdit = false; + } + $canChange = $user->authorise('core.edit.state', 'com_users'); + ?> + + + + + + + + + +
    + + + + + + + + + + + +
    + + id); ?> + + + $item->level + 1)); ?> + + + escape($item->title); ?> + + escape($item->title); ?> + + + + + + + count_enabled; ?> + + + count_disabled; ?> + + id; ?> +
    + + + pagination->getListFooter(); ?> + + + + + + +
    +
    +
    +
    diff --git a/administrator/components/com_users/views/groups/tmpl/default.xml b/administrator/components/com_users/tmpl/groups/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_users/views/groups/tmpl/default.xml rename to administrator/components/com_users/tmpl/groups/default.xml diff --git a/administrator/components/com_users/tmpl/level/edit.php b/administrator/components/com_users/tmpl/level/edit.php new file mode 100644 index 0000000000000..86a3dbe367ee8 --- /dev/null +++ b/administrator/components/com_users/tmpl/level/edit.php @@ -0,0 +1,41 @@ + + +
    +
    + +
    +
    + form->getLabel('title'); ?> +
    +
    + form->getInput('title'); ?> +
    +
    +
    + +
    + + item->rules); ?> +
    + + +
    diff --git a/administrator/components/com_users/views/level/tmpl/edit.xml b/administrator/components/com_users/tmpl/level/edit.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_users/views/level/tmpl/edit.xml rename to administrator/components/com_users/tmpl/level/edit.xml diff --git a/administrator/components/com_users/tmpl/levels/default.php b/administrator/components/com_users/tmpl/levels/default.php new file mode 100644 index 0000000000000..4e44ab1f6e47e --- /dev/null +++ b/administrator/components/com_users/tmpl/levels/default.php @@ -0,0 +1,129 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrder = $listOrder == 'a.ordering'; + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_users&task=levels.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('sortablelist.sortable', 'levelList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); +} + +?> +
    +
    +
    + sidebar; ?> +
    +
    +
    + $this, 'options' => array('filterButton' => false))); ?> + + items)) : ?> + + + + + + + + + + + + + + items); ?> + items as $i => $item) : + $ordering = ($listOrder == 'a.ordering'); + $canCreate = $user->authorise('core.create', 'com_users'); + $canEdit = $user->authorise('core.edit', 'com_users'); + $canChange = $user->authorise('core.edit.state', 'com_users'); + ?> + + + + + + + + + +
    + + + + + + + + + +
    + + + + + + + + + id); ?> + + + + escape($item->title); ?> + + escape($item->title); ?> + + + rules); ?> + + id; ?> +
    + + + pagination->getListFooter(); ?> + + + + + +
    +
    +
    +
    diff --git a/administrator/components/com_users/views/levels/tmpl/default.xml b/administrator/components/com_users/tmpl/levels/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_users/views/levels/tmpl/default.xml rename to administrator/components/com_users/tmpl/levels/default.xml diff --git a/administrator/components/com_users/tmpl/mail/default.php b/administrator/components/com_users/tmpl/mail/default.php new file mode 100644 index 0000000000000..87c206f317138 --- /dev/null +++ b/administrator/components/com_users/tmpl/mail/default.php @@ -0,0 +1,89 @@ + 'auto', 'relative' => true)); + +$comUserParams = ComponentHelper::getParams('com_users'); +?> + +
    +
    +
    +
    +
    +
    form->getLabel('subject'); ?>
    +
    +
    + get('mailSubjectPrefix'))) : ?> + + get('mailSubjectPrefix'); ?> + + + form->getInput('subject'); ?> +
    +
    +
    +
    +
    form->getLabel('message'); ?>
    +
    + form->getInput('message'); ?> + get('mailBodySuffix'))) : ?> +
    +
    + get('mailBodySuffix'); ?> +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    +
    + form->getInput('recurse'); ?> + form->getLabel('recurse'); ?> +
    +
    + form->getInput('mode'); ?> + form->getLabel('mode'); ?> +
    +
    + form->getInput('disabled'); ?> + form->getLabel('disabled'); ?> +
    +
    + form->getInput('bcc'); ?> + form->getLabel('bcc'); ?> +
    +
    + form->getLabel('group'); ?> + form->getInput('group'); ?> +
    +
    +
    +
    +
    +
    diff --git a/administrator/components/com_users/views/mail/tmpl/default.xml b/administrator/components/com_users/tmpl/mail/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_users/views/mail/tmpl/default.xml rename to administrator/components/com_users/tmpl/mail/default.xml diff --git a/administrator/components/com_users/tmpl/note/edit.php b/administrator/components/com_users/tmpl/note/edit.php new file mode 100644 index 0000000000000..5e31fdce155a7 --- /dev/null +++ b/administrator/components/com_users/tmpl/note/edit.php @@ -0,0 +1,79 @@ + +
    +
    +
    +
    + form->getLabel('subject'); ?> +
    +
    + form->getInput('subject'); ?> +
    +
    +
    +
    + form->getLabel('user_id'); ?> +
    +
    + form->getInput('user_id'); ?> +
    +
    +
    +
    + form->getLabel('catid'); ?> +
    +
    + form->getInput('catid'); ?> +
    +
    +
    +
    + form->getLabel('state'); ?> +
    +
    + form->getInput('state'); ?> +
    +
    +
    +
    + form->getLabel('review_time'); ?> +
    +
    + form->getInput('review_time'); ?> +
    +
    +
    +
    + form->getLabel('version_note'); ?> +
    +
    + form->getInput('version_note'); ?> +
    +
    +
    +
    + form->getLabel('body'); ?> +
    +
    + form->getInput('body'); ?> +
    +
    + + + +
    +
    diff --git a/administrator/components/com_users/views/note/tmpl/edit.xml b/administrator/components/com_users/tmpl/note/edit.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_users/views/note/tmpl/edit.xml rename to administrator/components/com_users/tmpl/note/edit.xml diff --git a/administrator/components/com_users/tmpl/notes/default.php b/administrator/components/com_users/tmpl/notes/default.php new file mode 100644 index 0000000000000..848c19154062b --- /dev/null +++ b/administrator/components/com_users/tmpl/notes/default.php @@ -0,0 +1,123 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +?> +
    +
    +
    + sidebar; ?> +
    +
    +
    + $this)); ?> + + items)) : ?> + + + + + + + + + + + + + + + items as $i => $item) : + $canEdit = $user->authorise('core.edit', 'com_users.category.' . $item->catid); + $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', 'com_users.category.' . $item->catid) && $canCheckin; + $subject = $item->subject ?: Text::_('COM_USERS_EMPTY_SUBJECT'); + ?> + + + + + + + + + + +
    + + + + + + + + + + + +
    + id); ?> + +
    + state, $i, 'notes.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> +
    +
    + checked_out) : ?> + editor, $item->checked_out_time, 'notes.', $canCheckin); ?> + + subject ?: Text::_('COM_USERS_EMPTY_SUBJECT'); ?> + + checked_out ? '' : ''; ?> + + escape($subject); ?> + + escape($subject); ?> + +
    + escape($item->category_title); ?> +
    +
    + escape($item->user_name); ?> + + review_time !== Factory::getDbo()->getNullDate()) : ?> + review_time, Text::_('DATE_FORMAT_LC4')); ?> + + + + + id; ?> +
    + + + pagination->getListFooter(); ?> + + + +
    + + + +
    +
    +
    +
    +
    diff --git a/administrator/components/com_users/views/notes/tmpl/default.xml b/administrator/components/com_users/tmpl/notes/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_users/views/notes/tmpl/default.xml rename to administrator/components/com_users/tmpl/notes/default.xml diff --git a/administrator/components/com_users/tmpl/notes/modal.php b/administrator/components/com_users/tmpl/notes/modal.php new file mode 100644 index 0000000000000..265a3e7bf755f --- /dev/null +++ b/administrator/components/com_users/tmpl/notes/modal.php @@ -0,0 +1,57 @@ + +
    +

    user->name, $this->user->id); ?>

    +items)) : ?> + + +
      + items as $item) : ?> +
    • +
      + subject) : ?> +

      id, $this->escape($item->subject)); ?>

      + +

      id, Text::_('COM_USERS_EMPTY_SUBJECT')); ?>

      + +
      + +
      + created_time, Text::_('DATE_FORMAT_LC2')); ?> +
      + + cparams->get('image'); ?> + + catid && isset($category_image)) : ?> +
      + +
      + +
      + escape($item->category_title); ?> +
      + + +
      +
      + body) ? HTMLHelper::_('content.prepare', $item->body) : ''); ?> +
      +
    • + +
    + +
    diff --git a/administrator/components/com_users/tmpl/user/edit.php b/administrator/components/com_users/tmpl/user/edit.php new file mode 100644 index 0000000000000..144f4e6e87ee5 --- /dev/null +++ b/administrator/components/com_users/tmpl/user/edit.php @@ -0,0 +1,109 @@ + 'auto', 'relative' => true)); + +// Get the form fieldsets. +$fieldsets = $this->form->getFieldsets(); +$settings = array(); + +$this->useCoreUI = true; + +?> + +
    + + + +
    + 'details')); ?> + + + form->getFieldset('user_details') as $field) : ?> +
    +
    + label; ?> +
    +
    + input; ?> +
    +
    + + + + grouplist) : ?> + + loadTemplate('groups'); ?> + + + + ignore_fieldsets = array('user_details'); + echo LayoutHelper::render('joomla.edit.params', $this); + ?> + + tfaform) && $this->item->id) : ?> + +
    +
    + +
    +
    + 'Joomla.twoFactorMethodChange()', 'class' => 'custom-select'), 'value', 'text', $this->otpConfig->method, 'jform_twofactor_method', false); ?> +
    +
    +
    + tfaform as $form) : ?> + otpConfig->method ? 'display: block' : 'display: none'; ?> +
    + +
    + +
    + +
    + + + + + otpConfig->otep)) : ?> + + + otpConfig->otep as $otep) : ?> + + --- + + + +
    + + + + + +
    + + + +
    diff --git a/administrator/components/com_users/views/user/tmpl/edit.xml b/administrator/components/com_users/tmpl/user/edit.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_users/views/user/tmpl/edit.xml rename to administrator/components/com_users/tmpl/user/edit.xml diff --git a/administrator/components/com_users/tmpl/user/edit_groups.php b/administrator/components/com_users/tmpl/user/edit_groups.php new file mode 100644 index 0000000000000..71d5c42c391f5 --- /dev/null +++ b/administrator/components/com_users/tmpl/user/edit_groups.php @@ -0,0 +1,17 @@ + +groups, true); ?> diff --git a/administrator/components/com_users/tmpl/users/default.php b/administrator/components/com_users/tmpl/users/default.php new file mode 100644 index 0000000000000..e55f6463171e1 --- /dev/null +++ b/administrator/components/com_users/tmpl/users/default.php @@ -0,0 +1,195 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$loggeduser = Factory::getUser(); +$debugUsers = $this->state->get('params')->get('debugUsers', 1); +?> +
    +
    +
    + sidebar; ?> +
    +
    +
    + $this)); + ?> + items)) : ?> + + + + + + + + + + + + + + + + + + + items as $i => $item) : + $canEdit = $this->canDo->get('core.edit'); + $canChange = $loggeduser->authorise('core.edit.state', 'com_users'); + + // If this group is super admin and this user is not super admin, $canEdit is false + if ((!$loggeduser->authorise('core.admin')) && Access::check($item->id, 'core.admin')) + { + $canEdit = false; + $canChange = false; + } + ?> + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + id); ?> + + +
    + + + escape($item->name); ?> + + escape($item->name); ?> + +
    +
    + id); ?> + note_count > 0) : ?> + + + +
    + note_count, $item->id); ?> + requireReset == '1') : ?> + + + + + +
    + escape($item->username); ?> + + id == $item->id; ?> + + block, $i, 'users.', !$self); ?> + + block, $i, 'users.', false);; ?> + + + activation) ? 0 : 1; + echo HTMLHelper::_('jgrid.state', JHtmlUsers::activateStates(), $activated, $i, 'users.', (boolean) $activated); + ?> + + group_names, "\n") > 1) : ?> + + + group_names); ?> + + + escape($item->email)); ?> + + lastvisitDate != $this->db->getNullDate()) : ?> + lastvisitDate, Text::_('DATE_FORMAT_LC6')); ?> + + + + + registerDate, Text::_('DATE_FORMAT_LC6')); ?> + + id; ?> +
    + + + pagination->getListFooter(); ?> + + + authorise('core.create', 'com_users') + && $loggeduser->authorise('core.edit', 'com_users') + && $loggeduser->authorise('core.edit.state', 'com_users')) : ?> + Text::_('COM_USERS_BATCH_OPTIONS'), + 'footer' => $this->loadTemplate('batch_footer'), + ), + $this->loadTemplate('batch_body') + ); ?> + + + + + + +
    +
    +
    +
    diff --git a/administrator/components/com_users/views/users/tmpl/default.xml b/administrator/components/com_users/tmpl/users/default.xml old mode 100755 new mode 100644 similarity index 100% rename from administrator/components/com_users/views/users/tmpl/default.xml rename to administrator/components/com_users/tmpl/users/default.xml diff --git a/administrator/components/com_users/tmpl/users/default_batch_body.php b/administrator/components/com_users/tmpl/users/default_batch_body.php new file mode 100644 index 0000000000000..442f32240d0aa --- /dev/null +++ b/administrator/components/com_users/tmpl/users/default_batch_body.php @@ -0,0 +1,48 @@ + + +
    +
    +
    + +
    + +
    +
    +
    + + +
    +
    +
    diff --git a/administrator/components/com_users/tmpl/users/default_batch_footer.php b/administrator/components/com_users/tmpl/users/default_batch_footer.php new file mode 100644 index 0000000000000..102e53bc44ded --- /dev/null +++ b/administrator/components/com_users/tmpl/users/default_batch_footer.php @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/administrator/components/com_users/tmpl/users/modal.php b/administrator/components/com_users/tmpl/users/modal.php new file mode 100644 index 0000000000000..ce5f60dc47ac5 --- /dev/null +++ b/administrator/components/com_users/tmpl/users/modal.php @@ -0,0 +1,108 @@ + 'bottom')); + +$input = Factory::getApplication()->input; +$field = $input->getCmd('field'); +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$enabledStates = array(0 => 'icon-publish', 1 => 'icon-unpublish'); +$activatedStates = array(0 => 'icon-publish', 1 => 'icon-unpublish'); +$userRequired = (int) $input->get('required', 0, 'int'); +$onClick = "window.parent.jSelectUser(this);window.parent.Joomla.Modal.getCurrent().close()"; + +?> +
    +
    + +
    +   +
    + + $this)); ?> + items)) : ?> + + + + + + + + + + + + + + + + items as $item) : ?> + + + + + + + + + + +
    + + + + + + + + + + + +
    + + escape($item->name); ?> + + + escape($item->username); ?> + + + + + + group_names); ?> + + id; ?> +
    + + + pagination->getListFooter(); ?> + + + + + + + +
    +
    diff --git a/administrator/components/com_users/users.php b/administrator/components/com_users/users.php deleted file mode 100644 index 48bdfbbc77d66..0000000000000 --- a/administrator/components/com_users/users.php +++ /dev/null @@ -1,22 +0,0 @@ -authorise('core.manage', 'com_users')) -{ - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); -} - -JLoader::register('UsersHelper', __DIR__ . '/helpers/users.php'); - -$controller = JControllerLegacy::getInstance('Users'); -$controller->execute(JFactory::getApplication()->input->get('task')); -$controller->redirect(); diff --git a/administrator/components/com_users/users.xml b/administrator/components/com_users/users.xml index 0eafa9845ac5b..9b69dcba71bb0 100644 --- a/administrator/components/com_users/users.xml +++ b/administrator/components/com_users/users.xml @@ -9,14 +9,16 @@ www.joomla.org 3.0.0 COM_USERS_XML_DESCRIPTION + Joomla\Component\Users - controller.php router.php - users.php - controllers + dispatcher.php + Controller helpers + Model models + View views @@ -25,11 +27,15 @@ config.xml - controller.php - users.php - controllers + access.xml + dispatcher.php + Controller + Helper helpers + Model models + Table + View views diff --git a/administrator/components/com_users/views/debuggroup/tmpl/default.php b/administrator/components/com_users/views/debuggroup/tmpl/default.php deleted file mode 100644 index 532db349dfe5c..0000000000000 --- a/administrator/components/com_users/views/debuggroup/tmpl/default.php +++ /dev/null @@ -1,115 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$colSpan = 4 + count($this->actions); -?> -
    -sidebar)) : ?> -
    - sidebar; ?> -
    -
    - -
    - - $this)); ?> -
    - - - - - - actions as $key => $action) : ?> - - - - - - - - - - - - - items as $i => $item) : ?> - - - - actions as $action) : ?> - checks[$name]; - if ($check === true) : - $class = 'icon-ok'; - $button = 'btn-success'; - elseif ($check === false) : - $class = 'icon-remove'; - $button = 'btn-danger'; - elseif ($check === null) : - $class = 'icon-ban-circle'; - $button = 'btn-warning'; - else : - $class = ''; - $button = ''; - endif; - ?> - - - - - - - -
    - - - - - - - - - -
    - pagination->getListFooter(); ?> -
    - escape($item->title); ?> - - $item->level + 1)) . $this->escape($item->name); ?> - - - - lft; ?> - - rgt; ?> - - id; ?> -
    - - - -
    - -   -   - -

    -
    -
    - diff --git a/administrator/components/com_users/views/debuggroup/view.html.php b/administrator/components/com_users/views/debuggroup/view.html.php deleted file mode 100644 index c0e7fd8c2e907..0000000000000 --- a/administrator/components/com_users/views/debuggroup/view.html.php +++ /dev/null @@ -1,106 +0,0 @@ -authorise('core.manage', 'com_users')) - { - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); - } - - $this->actions = $this->get('DebugActions'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->group = $this->get('Group'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - // Vars only used in hathor. - // @deprecated 4.0 To be removed with Hathor - $this->levels = UsersHelperDebug::getLevelsOptions(); - $this->components = UsersHelperDebug::getComponents(); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->addToolbar(); - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_users'); - - JToolbarHelper::title(JText::sprintf('COM_USERS_VIEW_DEBUG_GROUP_TITLE', $this->group->id, $this->group->title), 'users groups'); - JToolbarHelper::cancel('group.cancel', 'JTOOLBAR_CLOSE'); - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_users'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_USERS_DEBUG_GROUPS'); - } -} diff --git a/administrator/components/com_users/views/debuguser/tmpl/default.php b/administrator/components/com_users/views/debuguser/tmpl/default.php deleted file mode 100644 index e2b366ca6ddc1..0000000000000 --- a/administrator/components/com_users/views/debuguser/tmpl/default.php +++ /dev/null @@ -1,115 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$colSpan = 4 + count($this->actions); -?> -
    -sidebar)) : ?> -
    - sidebar; ?> -
    -
    - -
    - - $this)); ?> -
    - - - - - - actions as $key => $action) : ?> - - - - - - - - - - - - - items as $i => $item) : ?> - - - - actions as $action) : ?> - checks[$name]; - if ($check === true) : - $class = 'icon-ok'; - $button = 'btn-success'; - elseif ($check === false) : - $class = 'icon-remove'; - $button = 'btn-danger'; - elseif ($check === null) : - $class = 'icon-ban-circle'; - $button = 'btn-warning'; - else : - $class = ''; - $button = ''; - endif; - ?> - - - - - - - -
    - - - - - - - - - -
    - pagination->getListFooter(); ?> -
    - escape($item->title); ?> - - $item->level + 1)) . $this->escape($item->name); ?> - - - - lft; ?> - - rgt; ?> - - id; ?> -
    - - - -
    - -   -   - -

    -
    -
    - diff --git a/administrator/components/com_users/views/debuguser/view.html.php b/administrator/components/com_users/views/debuguser/view.html.php deleted file mode 100644 index 7a68dd46ab3b5..0000000000000 --- a/administrator/components/com_users/views/debuguser/view.html.php +++ /dev/null @@ -1,106 +0,0 @@ -authorise('core.manage', 'com_users')) - { - throw new JAccessExceptionNotallowed(JText::_('JERROR_ALERTNOAUTHOR'), 403); - } - - $this->actions = $this->get('DebugActions'); - $this->items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->user = $this->get('User'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - // Vars only used in hathor. - // @deprecated 4.0 To be removed with Hathor - $this->levels = UsersHelperDebug::getLevelsOptions(); - $this->components = UsersHelperDebug::getComponents(); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->addToolbar(); - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_users'); - - JToolbarHelper::title(JText::sprintf('COM_USERS_VIEW_DEBUG_USER_TITLE', $this->user->id, $this->user->name), 'users user'); - JToolbarHelper::cancel('user.cancel', 'JTOOLBAR_CLOSE'); - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_users'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_USERS_DEBUG_USERS'); - } -} diff --git a/administrator/components/com_users/views/group/tmpl/edit.php b/administrator/components/com_users/views/group/tmpl/edit.php deleted file mode 100644 index d2303520dfaa2..0000000000000 --- a/administrator/components/com_users/views/group/tmpl/edit.php +++ /dev/null @@ -1,54 +0,0 @@ -addScriptDeclaration(" - Joomla.submitbutton = function(task) - { - if (task == 'group.cancel' || document.formvalidator.isValid(document.getElementById('group-form'))) - { - Joomla.submitform(task, document.getElementById('group-form')); - } - }; -"); -?> - -
    -
    - -
    -
    - form->getLabel('title'); ?> -
    -
    - form->getInput('title'); ?> -
    -
    -
    - form->getField('parent_id'); ?> - hidden) : ?> -
    - label; ?> -
    - -
    - input; ?> -
    -
    -
    - - -
    diff --git a/administrator/components/com_users/views/group/view.html.php b/administrator/components/com_users/views/group/view.html.php deleted file mode 100644 index baf3b31114331..0000000000000 --- a/administrator/components/com_users/views/group/view.html.php +++ /dev/null @@ -1,105 +0,0 @@ -state = $this->get('State'); - $this->item = $this->get('Item'); - $this->form = $this->get('Form'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->addToolbar(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - - $isNew = ($this->item->id == 0); - $canDo = JHelperContent::getActions('com_users'); - - JToolbarHelper::title(JText::_($isNew ? 'COM_USERS_VIEW_NEW_GROUP_TITLE' : 'COM_USERS_VIEW_EDIT_GROUP_TITLE'), 'users groups-add'); - - if ($canDo->get('core.edit') || $canDo->get('core.create')) - { - JToolbarHelper::apply('group.apply'); - JToolbarHelper::save('group.save'); - } - - if ($canDo->get('core.create')) - { - JToolbarHelper::save2new('group.save2new'); - } - - // If an existing item, can save to a copy. - if (!$isNew && $canDo->get('core.create')) - { - JToolbarHelper::save2copy('group.save2copy'); - } - - if (empty($this->item->id)) - { - JToolbarHelper::cancel('group.cancel'); - } - else - { - JToolbarHelper::cancel('group.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_USERS_GROUPS_EDIT'); - } -} diff --git a/administrator/components/com_users/views/groups/tmpl/default.php b/administrator/components/com_users/views/groups/tmpl/default.php deleted file mode 100644 index 09f7d64fe20b5..0000000000000 --- a/administrator/components/com_users/views/groups/tmpl/default.php +++ /dev/null @@ -1,142 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$debugGroups = $this->state->get('params')->get('debugGroups', 1); - -JText::script('COM_USERS_GROUPS_CONFIRM_DELETE'); - -JFactory::getDocument()->addScriptDeclaration(' - Joomla.submitbutton = function(task) { - if (task == "groups.delete") { - var i, cids = document.getElementsByName("cid[]"); - for (i = 0; i < cids.length; i++) { - if (cids[i].checked && cids[i].parentNode.getAttribute("data-usercount") != 0) { - if (confirm(Joomla.JText._("COM_USERS_GROUPS_CONFIRM_DELETE"))) { - Joomla.submitform(task); - } - return false; - } - } - } - - Joomla.submitform(task); - return false; - }; -'); -?> -
    -sidebar)) : ?> -
    - sidebar; ?> -
    -
    - -
    - - $this, 'options' => array('filterButton' => false))); ?> -
    - items)) : ?> -
    - -
    - - - - - - - - - - - - - - - - - - items as $i => $item) : - $canCreate = $user->authorise('core.create', 'com_users'); - $canEdit = $user->authorise('core.edit', 'com_users'); - - // If this group is super admin and this user is not super admin, $canEdit is false - if (!$user->authorise('core.admin') && JAccess::checkGroup($item->id, 'core.admin')) - { - $canEdit = false; - } - $canChange = $user->authorise('core.edit.state', 'com_users'); - ?> - - - - - - - - - -
    - - - - - - - - - - - -
    - pagination->getListFooter(); ?> -
    - - id); ?> - - - $item->level + 1)); ?> - - - escape($item->title); ?> - - escape($item->title); ?> - - - - - - - count_enabled; ?> - - - count_disabled; ?> - - id; ?> -
    - - - - - -
    - diff --git a/administrator/components/com_users/views/groups/view.html.php b/administrator/components/com_users/views/groups/view.html.php deleted file mode 100644 index c9fe97410f243..0000000000000 --- a/administrator/components/com_users/views/groups/view.html.php +++ /dev/null @@ -1,124 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - UsersHelper::addSubmenu('groups'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_users'); - - JToolbarHelper::title(JText::_('COM_USERS_VIEW_GROUPS_TITLE'), 'users groups'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('group.add'); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('group.edit'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'groups.delete', 'JTOOLBAR_DELETE'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_users'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_USERS_GROUPS'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'a.title' => JText::_('COM_USERS_HEADING_GROUP_TITLE'), - 'a.id' => JText::_('JGRID_HEADING_ID'), - ); - } -} diff --git a/administrator/components/com_users/views/level/tmpl/edit.php b/administrator/components/com_users/views/level/tmpl/edit.php deleted file mode 100644 index 61aec7df4b292..0000000000000 --- a/administrator/components/com_users/views/level/tmpl/edit.php +++ /dev/null @@ -1,47 +0,0 @@ -addScriptDeclaration(" - Joomla.submitbutton = function(task) - { - if (task == 'level.cancel' || document.formvalidator.isValid(document.getElementById('level-form'))) - { - Joomla.submitform(task, document.getElementById('level-form')); - } - }; -"); -?> - -
    -
    - -
    -
    - form->getLabel('title'); ?> -
    -
    - form->getInput('title'); ?> -
    -
    -
    - -
    - - item->rules); ?> -
    - - -
    diff --git a/administrator/components/com_users/views/level/view.html.php b/administrator/components/com_users/views/level/view.html.php deleted file mode 100644 index 5638941b40cab..0000000000000 --- a/administrator/components/com_users/views/level/view.html.php +++ /dev/null @@ -1,105 +0,0 @@ -form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->addToolbar(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - - $isNew = ($this->item->id == 0); - $canDo = JHelperContent::getActions('com_users'); - - JToolbarHelper::title(JText::_($isNew ? 'COM_USERS_VIEW_NEW_LEVEL_TITLE' : 'COM_USERS_VIEW_EDIT_LEVEL_TITLE'), 'users levels-add'); - - if ($canDo->get('core.edit') || $canDo->get('core.create')) - { - JToolbarHelper::apply('level.apply'); - JToolbarHelper::save('level.save'); - } - - if ($canDo->get('core.create')) - { - JToolbarHelper::save2new('level.save2new'); - } - - // If an existing item, can save to a copy. - if (!$isNew && $canDo->get('core.create')) - { - JToolbarHelper::save2copy('level.save2copy'); - } - - if (empty($this->item->id)) - { - JToolbarHelper::cancel('level.cancel'); - } - else - { - JToolbarHelper::cancel('level.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS_EDIT'); - } -} diff --git a/administrator/components/com_users/views/levels/tmpl/default.php b/administrator/components/com_users/views/levels/tmpl/default.php deleted file mode 100644 index 14b6e6d60bb36..0000000000000 --- a/administrator/components/com_users/views/levels/tmpl/default.php +++ /dev/null @@ -1,128 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$saveOrder = $listOrder == 'a.ordering'; - -if ($saveOrder) -{ - $saveOrderingUrl = 'index.php?option=com_users&task=levels.saveOrderAjax&tmpl=component'; - JHtml::_('sortablelist.sortable', 'levelList', 'adminForm', strtolower($listDirn), $saveOrderingUrl); -} - -?> -
    -sidebar)) : ?> -
    - sidebar; ?> -
    -
    - -
    - - $this, 'options' => array('filterButton' => false))); ?> -
    - items)) : ?> -
    - -
    - - - - - - - - - - - - - - - - - - items); ?> - items as $i => $item) : - $ordering = ($listOrder == 'a.ordering'); - $canCreate = $user->authorise('core.create', 'com_users'); - $canEdit = $user->authorise('core.edit', 'com_users'); - $canChange = $user->authorise('core.edit.state', 'com_users'); - ?> - - - - - - - - - -
    - - - - - - - - - -
    - pagination->getListFooter(); ?> -
    - - - - - - - - - id); ?> - - - - escape($item->title); ?> - - escape($item->title); ?> - - - rules); ?> - - id; ?> -
    - - - - -
    - diff --git a/administrator/components/com_users/views/levels/view.html.php b/administrator/components/com_users/views/levels/view.html.php deleted file mode 100644 index ff439227abc72..0000000000000 --- a/administrator/components/com_users/views/levels/view.html.php +++ /dev/null @@ -1,125 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - UsersHelper::addSubmenu('levels'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_users'); - - JToolbarHelper::title(JText::_('COM_USERS_VIEW_LEVELS_TITLE'), 'users levels'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('level.add'); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('level.edit'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'level.delete', 'JTOOLBAR_DELETE'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_users'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_USERS_ACCESS_LEVELS'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'a.ordering' => JText::_('JGRID_HEADING_ORDERING'), - 'a.title' => JText::_('COM_USERS_HEADING_LEVEL_NAME'), - 'a.id' => JText::_('JGRID_HEADING_ID'), - ); - } -} diff --git a/administrator/components/com_users/views/mail/tmpl/default.php b/administrator/components/com_users/views/mail/tmpl/default.php deleted file mode 100644 index 671f7f8ead9f5..0000000000000 --- a/administrator/components/com_users/views/mail/tmpl/default.php +++ /dev/null @@ -1,75 +0,0 @@ -addScriptDeclaration($script); -?> - -
    -
    -
    -
    -
    -
    form->getLabel('subject'); ?>
    -
    get('mailSubjectPrefix'); ?> - form->getInput('subject'); ?>
    -
    -
    -
    form->getLabel('message'); ?>
    -
    form->getInput('message'); ?>
    - get('mailBodySuffix'); ?>
    -
    -
    - - -
    -
    -
    -
    -
    form->getInput('recurse'); ?> form->getLabel('recurse'); ?>
    -
    -
    -
    form->getInput('mode'); ?> form->getLabel('mode'); ?>
    -
    -
    -
    form->getInput('disabled'); ?> form->getLabel('disabled'); ?>
    -
    -
    -
    form->getInput('bcc'); ?> form->getLabel('bcc'); ?>
    -
    -
    -
    form->getLabel('group'); ?>
    -
    form->getInput('group'); ?>
    -
    -
    -
    -
    -
    diff --git a/administrator/components/com_users/views/mail/view.html.php b/administrator/components/com_users/views/mail/view.html.php deleted file mode 100644 index ae4f2831da4d5..0000000000000 --- a/administrator/components/com_users/views/mail/view.html.php +++ /dev/null @@ -1,65 +0,0 @@ -get('massmailoff', 0) == 1) - { - JFactory::getApplication()->redirect(JRoute::_('index.php', false)); - } - - // Get data from the model - $this->form = $this->get('Form'); - - $this->addToolbar(); - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - - JToolbarHelper::title(JText::_('COM_USERS_MASS_MAIL'), 'users massmail'); - JToolbarHelper::custom('mail.send', 'envelope.png', 'send_f2.png', 'COM_USERS_TOOLBAR_MAIL_SEND_MAIL', false); - JToolbarHelper::cancel('mail.cancel'); - JToolbarHelper::divider(); - JToolbarHelper::preferences('com_users'); - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_USERS_MASS_MAIL_USERS'); - } -} diff --git a/administrator/components/com_users/views/note/tmpl/edit.php b/administrator/components/com_users/views/note/tmpl/edit.php deleted file mode 100644 index 3b448113241d9..0000000000000 --- a/administrator/components/com_users/views/note/tmpl/edit.php +++ /dev/null @@ -1,90 +0,0 @@ -addScriptDeclaration(' -jQuery(document).ready(function() { - Joomla.submitbutton = function(task) - { - if (task == "note.cancel" || document.formvalidator.isValid(document.getElementById("note-form"))) - { - ' . $this->form->getField('body')->save() . ' - Joomla.submitform(task, document.getElementById("note-form")); - } - } -});'); -?> -
    -
    -
    -
    - form->getLabel('subject'); ?> -
    -
    - form->getInput('subject'); ?> -
    -
    -
    -
    - form->getLabel('user_id'); ?> -
    -
    - form->getInput('user_id'); ?> -
    -
    -
    -
    - form->getLabel('catid'); ?> -
    -
    - form->getInput('catid'); ?> -
    -
    -
    -
    - form->getLabel('state'); ?> -
    -
    - form->getInput('state'); ?> -
    -
    -
    -
    - form->getLabel('review_time'); ?> -
    -
    - form->getInput('review_time'); ?> -
    -
    -
    -
    - form->getLabel('version_note'); ?> -
    -
    - form->getInput('version_note'); ?> -
    -
    - -
    -
    - form->getLabel('body'); ?> -
    -
    - form->getInput('body'); ?> -
    -
    - - - -
    -
    diff --git a/administrator/components/com_users/views/note/view.html.php b/administrator/components/com_users/views/note/view.html.php deleted file mode 100644 index 2b6e97be49b1f..0000000000000 --- a/administrator/components/com_users/views/note/view.html.php +++ /dev/null @@ -1,128 +0,0 @@ -state = $this->get('State'); - $this->item = $this->get('Item'); - $this->form = $this->get('Form'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - // Get the component HTML helpers - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - - parent::display($tpl); - $this->addToolbar(); - } - - /** - * Display the toolbar. - * - * @return void - * - * @since 2.5 - */ - protected function addToolbar() - { - $input = JFactory::getApplication()->input; - $input->set('hidemainmenu', 1); - - $user = JFactory::getUser(); - $isNew = ($this->item->id == 0); - $checkedOut = !($this->item->checked_out == 0 || $this->item->checked_out == $user->get('id')); - - // Since we don't track these assets at the item level, use the category id. - $canDo = JHelperContent::getActions('com_users', 'category', $this->item->catid); - - JToolbarHelper::title(JText::_('COM_USERS_NOTES'), 'users user'); - - // If not checked out, can save the item. - if (!$checkedOut && ($canDo->get('core.edit') || count($user->getAuthorisedCategories('com_users', 'core.create')))) - { - JToolbarHelper::apply('note.apply'); - JToolbarHelper::save('note.save'); - } - - if (!$checkedOut && count($user->getAuthorisedCategories('com_users', 'core.create'))) - { - JToolbarHelper::save2new('note.save2new'); - } - - // If an existing item, can save to a copy. - if (!$isNew && (count($user->getAuthorisedCategories('com_users', 'core.create')) > 0)) - { - JToolbarHelper::save2copy('note.save2copy'); - } - - if (empty($this->item->id)) - { - JToolbarHelper::cancel('note.cancel'); - } - else - { - if (JComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $canDo->get('core.edit')) - { - JToolbarHelper::versions('com_users.note', $this->item->id); - } - - JToolbarHelper::cancel('note.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_USERS_USER_NOTES_EDIT'); - } -} diff --git a/administrator/components/com_users/views/notes/tmpl/default.php b/administrator/components/com_users/views/notes/tmpl/default.php deleted file mode 100644 index 0882e6d1f70c2..0000000000000 --- a/administrator/components/com_users/views/notes/tmpl/default.php +++ /dev/null @@ -1,129 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -?> -
    -sidebar)) : ?> -
    - sidebar; ?> -
    -
    - -
    - - $this)); ?> - - items)) : ?> -
    - -
    - - - - - - - - - - - - - - - - - - - items as $i => $item) : - $canEdit = $user->authorise('core.edit', 'com_users.category.' . $item->catid); - $canCheckin = $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $user->get('id') || $item->checked_out == 0; - $canChange = $user->authorise('core.edit.state', 'com_users.category.' . $item->catid) && $canCheckin; - $subject = $item->subject ?: JText::_('COM_USERS_EMPTY_SUBJECT'); - ?> - - - - - - - - - - -
    - - - - - - - - - - - -
    - pagination->getListFooter(); ?> -
    - id); ?> - -
    - state, $i, 'notes.', $canChange, 'cb', $item->publish_up, $item->publish_down); ?> - state === 2 ? 'un' : '') . 'archive', 'cb' . $i, 'notes'); - JHtml::_('actionsdropdown.' . ((int) $item->state === -2 ? 'un' : '') . 'trash', 'cb' . $i, 'notes'); - echo JHtml::_('actionsdropdown.render', $this->escape($subject)); - } - ?> -
    -
    - checked_out) : ?> - editor, $item->checked_out_time, 'notes.', $canCheckin); ?> - - subject ?: JText::_('COM_USERS_EMPTY_SUBJECT'); ?> - - escape($subject); ?> - - escape($subject); ?> - -
    - escape($item->category_title); ?> -
    -
    - escape($item->user_name); ?> - - review_time !== JFactory::getDbo()->getNullDate()) : ?> - review_time, JText::_('DATE_FORMAT_LC4')); ?> - - - - - id; ?> -
    - - -
    - - - -
    -
    - diff --git a/administrator/components/com_users/views/notes/tmpl/modal.php b/administrator/components/com_users/views/notes/tmpl/modal.php deleted file mode 100644 index b810c3ed9da4b..0000000000000 --- a/administrator/components/com_users/views/notes/tmpl/modal.php +++ /dev/null @@ -1,54 +0,0 @@ - -
    -

    user->name, $this->user->id); ?>

    -items)) : ?> - - -
      - items as $item) : ?> -
    • -
      - subject) : ?> -

      id, $this->escape($item->subject)); ?>

      - -

      id, JText::_('COM_USERS_EMPTY_SUBJECT')); ?>

      - -
      - -
      - created_time, JText::_('DATE_FORMAT_LC2')); ?> -
      - - cparams->get('image'); ?> - - catid && isset($category_image)) : ?> -
      - -
      - -
      - escape($item->category_title); ?> -
      - - -
      -
      - body) ? JHtml::_('content.prepare', $item->body) : ''); ?> -
      -
    • - -
    - -
    diff --git a/administrator/components/com_users/views/notes/view.html.php b/administrator/components/com_users/views/notes/view.html.php deleted file mode 100644 index e01db127335e3..0000000000000 --- a/administrator/components/com_users/views/notes/view.html.php +++ /dev/null @@ -1,168 +0,0 @@ -items = $this->get('Items'); - $this->pagination = $this->get('Pagination'); - $this->state = $this->get('State'); - $this->user = $this->get('User'); - $this->filterForm = $this->get('FilterForm'); - $this->activeFilters = $this->get('ActiveFilters'); - - UsersHelper::addSubmenu('notes'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - // Get the component HTML helpers - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - - // Turn parameters into registry objects - foreach ($this->items as $item) - { - $item->cparams = new Registry($item->category_params); - } - - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - parent::display($tpl); - } - - /** - * Display the toolbar. - * - * @return void - * - * @since 2.5 - */ - protected function addToolbar() - { - $canDo = JHelperContent::getActions('com_users', 'category', $this->state->get('filter.category_id')); - - JToolbarHelper::title(JText::_('COM_USERS_VIEW_NOTES_TITLE'), 'users user'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('note.add'); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('note.edit'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::divider(); - JToolbarHelper::publish('notes.publish', 'JTOOLBAR_PUBLISH', true); - JToolbarHelper::unpublish('notes.unpublish', 'JTOOLBAR_UNPUBLISH', true); - - JToolbarHelper::divider(); - JToolbarHelper::archiveList('notes.archive'); - JToolbarHelper::checkin('notes.checkin'); - } - - if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'notes.delete', 'JTOOLBAR_EMPTY_TRASH'); - JToolbarHelper::divider(); - } - elseif ($canDo->get('core.edit.state')) - { - JToolbarHelper::trash('notes.trash'); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_users'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_USERS_USER_NOTES'); - - JHtmlSidebar::setAction('index.php?option=com_users&view=notes'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'u.name' => JText::_('COM_USERS_USER_HEADING'), - 'a.subject' => JText::_('COM_USERS_SUBJECT_HEADING'), - 'c.title' => JText::_('COM_USERS_CATEGORY_HEADING'), - 'a.state' => JText::_('JSTATUS'), - 'a.review_time' => JText::_('COM_USERS_REVIEW_HEADING'), - 'a.id' => JText::_('JGRID_HEADING_ID') - ); - } -} diff --git a/administrator/components/com_users/views/user/tmpl/edit.php b/administrator/components/com_users/views/user/tmpl/edit.php deleted file mode 100644 index 0ee07452c686c..0000000000000 --- a/administrator/components/com_users/views/user/tmpl/edit.php +++ /dev/null @@ -1,133 +0,0 @@ -addScriptDeclaration(" - Joomla.submitbutton = function(task) - { - if (task == 'user.cancel' || document.formvalidator.isValid(document.getElementById('user-form'))) - { - Joomla.submitform(task, document.getElementById('user-form')); - } - }; - - Joomla.twoFactorMethodChange = function(e) - { - var selectedPane = 'com_users_twofactor_' + jQuery('#jform_twofactor_method').val(); - - jQuery.each(jQuery('#com_users_twofactor_forms_container>div'), function(i, el) { - if (el.id != selectedPane) - { - jQuery('#' + el.id).hide(0); - } - else - { - jQuery('#' + el.id).show(0); - } - }); - }; -"); - -// Get the form fieldsets. -$fieldsets = $this->form->getFieldsets(); -?> - -
    - - - -
    - 'details')); ?> - - - form->getFieldset('user_details') as $field) : ?> -
    -
    - label; ?> -
    -
    - fieldname == 'password') : ?> - - - input; ?> -
    -
    - - - - grouplist) : ?> - - loadTemplate('groups'); ?> - - - - ignore_fieldsets = array('user_details'); - echo JLayoutHelper::render('joomla.edit.params', $this); - ?> - - tfaform) && $this->item->id) : ?> - -
    -
    - -
    -
    - 'Joomla.twoFactorMethodChange()'), 'value', 'text', $this->otpConfig->method, 'jform_twofactor_method', false); ?> -
    -
    -
    - tfaform as $form) : ?> - otpConfig->method ? 'display: block' : 'display: none'; ?> -
    - -
    - -
    - -
    - - - -
    - -
    - otpConfig->otep)) : ?> -
    - -
    - - otpConfig->otep as $otep) : ?> - - --- - - -
    - -
    - - - - - -
    - - - -
    diff --git a/administrator/components/com_users/views/user/tmpl/edit_groups.php b/administrator/components/com_users/views/user/tmpl/edit_groups.php deleted file mode 100644 index 0dab8f7d5f38f..0000000000000 --- a/administrator/components/com_users/views/user/tmpl/edit_groups.php +++ /dev/null @@ -1,15 +0,0 @@ - -groups, true); ?> diff --git a/administrator/components/com_users/views/user/view.html.php b/administrator/components/com_users/views/user/view.html.php deleted file mode 100644 index 511403dd2fdf7..0000000000000 --- a/administrator/components/com_users/views/user/view.html.php +++ /dev/null @@ -1,114 +0,0 @@ -form = $this->get('Form'); - $this->item = $this->get('Item'); - $this->state = $this->get('State'); - $this->tfaform = $this->get('Twofactorform'); - $this->otpConfig = $this->get('otpConfig'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - // Prevent user from modifying own group(s) - $user = JFactory::getUser(); - - if ((int) $user->id != (int) $this->item->id || $user->authorise('core.admin')) - { - $this->grouplist = $this->get('Groups'); - $this->groups = $this->get('AssignedGroups'); - } - - $this->form->setValue('password', null); - $this->form->setValue('password2', null); - - parent::display($tpl); - $this->addToolbar(); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - JFactory::getApplication()->input->set('hidemainmenu', true); - - $user = JFactory::getUser(); - $canDo = JHelperContent::getActions('com_users'); - $isNew = ($this->item->id == 0); - $isProfile = $this->item->id == $user->id; - - JToolbarHelper::title( - JText::_( - $isNew ? 'COM_USERS_VIEW_NEW_USER_TITLE' : ($isProfile ? 'COM_USERS_VIEW_EDIT_PROFILE_TITLE' : 'COM_USERS_VIEW_EDIT_USER_TITLE') - ), - 'user ' . ($isNew ? 'user-add' : ($isProfile ? 'user-profile' : 'user-edit')) - ); - - if ($canDo->get('core.edit') || $canDo->get('core.create')) - { - JToolbarHelper::apply('user.apply'); - JToolbarHelper::save('user.save'); - } - - if ($canDo->get('core.create') && $canDo->get('core.manage')) - { - JToolbarHelper::save2new('user.save2new'); - } - - if (empty($this->item->id)) - { - JToolbarHelper::cancel('user.cancel'); - } - else - { - JToolbarHelper::cancel('user.cancel', 'JTOOLBAR_CLOSE'); - } - - JToolbarHelper::divider(); - JToolbarHelper::help('JHELP_USERS_USER_MANAGER_EDIT'); - } -} diff --git a/administrator/components/com_users/views/users/tmpl/default.php b/administrator/components/com_users/views/users/tmpl/default.php deleted file mode 100644 index 7b949f8079b0e..0000000000000 --- a/administrator/components/com_users/views/users/tmpl/default.php +++ /dev/null @@ -1,188 +0,0 @@ -escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$loggeduser = JFactory::getUser(); -$debugUsers = $this->state->get('params')->get('debugUsers', 1); -?> -
    - sidebar)) : ?> -
    - sidebar; ?> -
    -
    - -
    - - $this)); - ?> - items)) : ?> -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - items as $i => $item) : - $canEdit = $this->canDo->get('core.edit'); - $canChange = $loggeduser->authorise('core.edit.state', 'com_users'); - - // If this group is super admin and this user is not super admin, $canEdit is false - if ((!$loggeduser->authorise('core.admin')) && JAccess::check($item->id, 'core.admin')) - { - $canEdit = false; - $canChange = false; - } - ?> - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    - pagination->getListFooter(); ?> -
    - - id); ?> - - -
    - - - escape($item->name); ?> - - escape($item->name); ?> - -
    -
    - note_count, $item->id); ?> - note_count, $item->id); ?> - id); ?> -
    - note_count, $item->id); ?> - requireReset == '1') : ?> - - - - - -
    - escape($item->username); ?> - - id == $item->id; - - if ($canChange) : - echo JHtml::_('jgrid.state', JHtmlUsers::blockStates($self), $item->block, $i, 'users.', !$self); - else : - echo JHtml::_('jgrid.state', JHtmlUsers::blockStates($self), $item->block, $i, 'users.', false); - endif; ?> - - activation) ? 0 : 1; - echo JHtml::_('jgrid.state', JHtmlUsers::activateStates(), $activated, $i, 'users.', (boolean) $activated); - ?> - - group_names, "\n") > 1) : ?> - - - group_names); ?> - - - escape($item->email)); ?> - - lastvisitDate != $this->db->getNullDate()) : ?> - lastvisitDate, JText::_('DATE_FORMAT_LC6')); ?> - - - - - registerDate, JText::_('DATE_FORMAT_LC6')); ?> - - id; ?> -
    - - authorise('core.create', 'com_users') - && $loggeduser->authorise('core.edit', 'com_users') - && $loggeduser->authorise('core.edit.state', 'com_users')) : ?> - JText::_('COM_USERS_BATCH_OPTIONS'), - 'footer' => $this->loadTemplate('batch_footer'), - ), - $this->loadTemplate('batch_body') - ); ?> - - - - - - -
    - diff --git a/administrator/components/com_users/views/users/tmpl/default_batch_body.php b/administrator/components/com_users/views/users/tmpl/default_batch_body.php deleted file mode 100644 index 38bc4a7691e9a..0000000000000 --- a/administrator/components/com_users/views/users/tmpl/default_batch_body.php +++ /dev/null @@ -1,50 +0,0 @@ - - -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    - -
    - -
    -
    diff --git a/administrator/components/com_users/views/users/tmpl/default_batch_footer.php b/administrator/components/com_users/views/users/tmpl/default_batch_footer.php deleted file mode 100644 index 1da0d37095bbb..0000000000000 --- a/administrator/components/com_users/views/users/tmpl/default_batch_footer.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - - \ No newline at end of file diff --git a/administrator/components/com_users/views/users/tmpl/modal.php b/administrator/components/com_users/views/users/tmpl/modal.php deleted file mode 100644 index f9991fd2a7b91..0000000000000 --- a/administrator/components/com_users/views/users/tmpl/modal.php +++ /dev/null @@ -1,128 +0,0 @@ - 'bottom')); -JHtml::_('bootstrap.popover', '.hasPopover', array('placement' => 'bottom')); -JHtml::_('formbehavior.chosen', 'select'); -JHtml::_('behavior.multiselect'); - -// Special case for the search field tooltip. -$searchFilterDesc = $this->filterForm->getFieldAttribute('search', 'description', null, 'filter'); -JHtml::_('bootstrap.tooltip', '#filter_search', array('title' => JText::_($searchFilterDesc), 'placement' => 'bottom')); - -$input = JFactory::getApplication()->input; -$field = $input->getCmd('field'); -$listOrder = $this->escape($this->state->get('list.ordering')); -$listDirn = $this->escape($this->state->get('list.direction')); -$enabledStates = array(0 => 'icon-publish', 1 => 'icon-unpublish'); -$activatedStates = array(0 => 'icon-publish', 1 => 'icon-unpublish'); -$userRequired = (int) $input->get('required', 0, 'int'); - -/** - * Mootools compatibility - * - * There is an extra option passed in the URL for the iframe &ismoo=0 for the bootstraped field. - * By default the value will be 1 or defaults to mootools behaviour using function jSelectUser() - * - * This should be removed when mootools won't be shipped by Joomla. - */ -$isMoo = $input->getInt('ismoo', 1); - -if ($isMoo) -{ - $onClick = "window.parent.jSelectUser(this);window.parent.jQuery('.modal.in').modal('hide');"; -} - -?> -
    -
    - -
    -   -
    - - $this)); ?> - items)) : ?> -
    - -
    - - - - - - - - - - - - - - - - - - - - items as $item) : ?> - - - - - - - - - - -
    - - - - - - - - - - - -
    - pagination->getListFooter(); ?> -
    - onclick=""> - escape($item->name); ?> - - - escape($item->username); ?> - - - - - - group_names); ?> - - id; ?> -
    - - - - - - - -
    -
    diff --git a/administrator/components/com_users/views/users/view.html.php b/administrator/components/com_users/views/users/view.html.php deleted file mode 100644 index 91824550d74d1..0000000000000 --- a/administrator/components/com_users/views/users/view.html.php +++ /dev/null @@ -1,194 +0,0 @@ -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->canDo = JHelperContent::getActions('com_users'); - $this->db = JFactory::getDbo(); - - UsersHelper::addSubmenu('users'); - - // Check for errors. - if (count($errors = $this->get('Errors'))) - { - throw new Exception(implode("\n", $errors), 500); - } - - // Include the component HTML helpers. - JHtml::addIncludePath(JPATH_COMPONENT . '/helpers/html'); - - $this->addToolbar(); - $this->sidebar = JHtmlSidebar::render(); - - parent::display($tpl); - } - - /** - * Add the page title and toolbar. - * - * @return void - * - * @since 1.6 - */ - protected function addToolbar() - { - $canDo = $this->canDo; - $user = JFactory::getUser(); - - // Get the toolbar object instance - $bar = JToolbar::getInstance('toolbar'); - - JToolbarHelper::title(JText::_('COM_USERS_VIEW_USERS_TITLE'), 'users user'); - - if ($canDo->get('core.create')) - { - JToolbarHelper::addNew('user.add'); - } - - if ($canDo->get('core.edit')) - { - JToolbarHelper::editList('user.edit'); - } - - if ($canDo->get('core.edit.state')) - { - JToolbarHelper::divider(); - JToolbarHelper::publish('users.activate', 'COM_USERS_TOOLBAR_ACTIVATE', true); - JToolbarHelper::unpublish('users.block', 'COM_USERS_TOOLBAR_BLOCK', true); - JToolbarHelper::custom('users.unblock', 'unblock.png', 'unblock_f2.png', 'COM_USERS_TOOLBAR_UNBLOCK', true); - JToolbarHelper::divider(); - } - - if ($canDo->get('core.delete')) - { - JToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'users.delete', 'JTOOLBAR_DELETE'); - JToolbarHelper::divider(); - } - - // Add a batch button - if ($user->authorise('core.create', 'com_users') - && $user->authorise('core.edit', 'com_users') - && $user->authorise('core.edit.state', 'com_users')) - { - $title = JText::_('JTOOLBAR_BATCH'); - - // Instantiate a new JLayoutFile instance and render the batch button - $layout = new JLayoutFile('joomla.toolbar.batch'); - - $dhtml = $layout->render(array('title' => $title)); - $bar->appendButton('Custom', $dhtml, 'batch'); - } - - if ($canDo->get('core.admin') || $canDo->get('core.options')) - { - JToolbarHelper::preferences('com_users'); - JToolbarHelper::divider(); - } - - JToolbarHelper::help('JHELP_USERS_USER_MANAGER'); - } - - /** - * Returns an array of fields the table can be sorted by - * - * @return array Array containing the field name to sort by as the key and display text as value - * - * @since 3.0 - */ - protected function getSortFields() - { - return array( - 'a.name' => JText::_('COM_USERS_HEADING_NAME'), - 'a.username' => JText::_('JGLOBAL_USERNAME'), - 'a.block' => JText::_('COM_USERS_HEADING_ENABLED'), - 'a.activation' => JText::_('COM_USERS_HEADING_ACTIVATED'), - 'a.email' => JText::_('JGLOBAL_EMAIL'), - 'a.lastvisitDate' => JText::_('COM_USERS_HEADING_LAST_VISIT_DATE'), - 'a.registerDate' => JText::_('COM_USERS_HEADING_REGISTRATION_DATE'), - 'a.id' => JText::_('JGRID_HEADING_ID'), - ); - } -} diff --git a/administrator/components/com_workflow/Controller/DisplayController.php b/administrator/components/com_workflow/Controller/DisplayController.php new file mode 100644 index 0000000000000..b44e7c31238f8 --- /dev/null +++ b/administrator/components/com_workflow/Controller/DisplayController.php @@ -0,0 +1,61 @@ +extension)) + { + $this->extension = $this->input->get('extension', 'com_content'); + } + } +} diff --git a/administrator/components/com_workflow/Controller/StageController.php b/administrator/components/com_workflow/Controller/StageController.php new file mode 100644 index 0000000000000..88548bacbb0e1 --- /dev/null +++ b/administrator/components/com_workflow/Controller/StageController.php @@ -0,0 +1,149 @@ +workflowID)) + { + $this->workflowID = $this->input->get('workflow_id'); + } + + if (empty($this->extension)) + { + $this->extension = $this->input->get('extension'); + } + } + + /** + * Method to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function allowAdd($data = array()) + { + $user = Factory::getUser(); + + return $user->authorise('core.create', $this->extension); + } + + /** + * Method to check if you can edit a record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function allowEdit($data = array(), $key = 'id') + { + $recordId = isset($data[$key]) ? (int) $data[$key] : 0; + $user = Factory::getUser(); + + // Check "edit" permission on record asset (explicit or inherited) + if ($user->authorise('core.edit', $this->extension . '.stage.' . $recordId)) + { + return true; + } + + // Check "edit own" permission on record asset (explicit or inherited) + if ($user->authorise('core.edit.own', $this->extension . '.stage.' . $recordId)) + { + // Need to do a lookup from the model to get the owner + $record = $this->getModel()->getItem($recordId); + + return !empty($record) && $record->created_by == $user->id; + } + + return false; + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since __DEPLOY_VERSION__ + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') + { + $append = parent::getRedirectToItemAppend($recordId); + + $append .= '&workflow_id=' . $this->workflowID . '&extension=' . $this->extension; + + return $append; + } + + /** + * Gets the URL arguments to append to a list redirect. + * + * @return string The arguments to append to the redirect URL. + * + * @since __DEPLOY_VERSION__ + */ + protected function getRedirectToListAppend() + { + $append = parent::getRedirectToListAppend(); + $append .= '&workflow_id=' . $this->workflowID . '&extension=' . $this->extension; + + return $append; + } +} diff --git a/administrator/components/com_workflow/Controller/StagesController.php b/administrator/components/com_workflow/Controller/StagesController.php new file mode 100644 index 0000000000000..9998d100021e5 --- /dev/null +++ b/administrator/components/com_workflow/Controller/StagesController.php @@ -0,0 +1,192 @@ +registerTask('unsetDefault', 'setDefault'); + } + + /** + * Proxy for getModel + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config The array of possible config values. Optional. + * + * @return \Joomla\CMS\Model\Model The model. + * + * @since __DEPLOY_VERSION__ + */ + public function getModel($name = 'Stage', $prefix = 'Administrator', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to set the home property for a list of items + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function setDefault() + { + // Check for request forgeries + Session::checkToken('request') or die(Text::_('JINVALID_TOKEN')); + + // Get items to publish from the request. + $cid = $this->input->get('cid', array(), 'array'); + $data = array('setDefault' => 1, 'unsetDefault' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($data, $task, 0, 'int'); + + if (!$value) + { + $this->setMessage(Text::_('COM_WORKFLOW_DISABLE_DEFAULT'), 'warning'); + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&extension=' . $this->input->getCmd("extension"), false + ) + ); + + return; + } + + if (empty($cid) || !is_array($cid)) + { + $this->setMessage(Text::_('COM_WORKFLOW_NO_ITEM_SELECTED'), 'warning'); + } + elseif (count($cid) > 1) + { + $this->setMessage(Text::_('COM_WORKFLOW_TOO_MANY_ITEMS'), 'error'); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $id = (int) reset($cid); + + // Publish the items. + if (!$model->setDefault($id, $value)) + { + $this->setMessage($model->getError(), 'warning'); + } + else + { + $this->setMessage(Text::_('COM_WORKFLOW_ITEM_SET_DEFAULT')); + } + } + + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&extension=' . $this->input->getCmd("extension") + . '&workflow_id=' . $this->input->getCmd("workflow_id"), false + ) + ); + } + + /** + * Check in of one or more records. + * + * @return boolean True on success + * + * @since __DEPLOY_VERSION__ + */ + public function checkin() + { + parent::checkin(); + + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&extension=' . $this->input->getCmd('extension') + . '&workflow_id=' . $this->input->getCmd('workflow_id'), false + ) + ); + } + + /** + * Deletes and returns correctly. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function delete() + { + parent::delete(); + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&extension=' . $this->input->getCmd("extension") + . '&workflow_id=' . $this->input->getCmd("workflow_id"), false + ) + ); + } + + /** + * Method to publish a list of items + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function publish() + { + parent::publish(); + + $extension = $this->input->get('extension'); + $extensionURL = $extension ? '&extension=' . $extension : ''; + + $workflow_id = $this->input->getInt('workflow_id'); + + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . $extensionURL . '&workflow_id=' . $workflow_id, false + ) + ); + } +} diff --git a/administrator/components/com_workflow/Controller/TransitionController.php b/administrator/components/com_workflow/Controller/TransitionController.php new file mode 100644 index 0000000000000..375f1b09013a7 --- /dev/null +++ b/administrator/components/com_workflow/Controller/TransitionController.php @@ -0,0 +1,148 @@ +workflowID)) + { + $this->workflowID = $this->input->get('workflow_id'); + } + + if (empty($this->extension)) + { + $this->extension = $this->input->get('extension'); + } + } + + /** + * Method to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function allowAdd($data = array()) + { + $user = Factory::getUser(); + + return $user->authorise('core.create', $this->extension); + } + + /** + * Method to check if you can edit a record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function allowEdit($data = array(), $key = 'id') + { + $recordId = isset($data[$key]) ? (int) $data[$key] : 0; + $user = Factory::getUser(); + + // Check "edit" permission on record asset (explicit or inherited) + if ($user->authorise('core.edit', $this->extension . '.transition.' . $recordId)) + { + return true; + } + + // Check "edit own" permission on record asset (explicit or inherited) + if ($user->authorise('core.edit.own', $this->extension . '.transition.' . $recordId)) + { + // Need to do a lookup from the model to get the owner + $record = $this->getModel()->getItem($recordId); + + return !empty($record) && $record->created_by == $user->id; + } + + return false; + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since __DEPLOY_VERSION__ + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') + { + $append = parent::getRedirectToItemAppend($recordId); + $append .= '&workflow_id=' . $this->workflowID . '&extension=' . $this->extension; + + return $append; + } + + /** + * Gets the URL arguments to append to a list redirect. + * + * @return string The arguments to append to the redirect URL. + * + * @since __DEPLOY_VERSION__ + */ + protected function getRedirectToListAppend() + { + $append = parent::getRedirectToListAppend(); + $append .= '&workflow_id=' . $this->workflowID . '&extension=' . $this->extension; + + return $append; + } +} diff --git a/administrator/components/com_workflow/Controller/TransitionsController.php b/administrator/components/com_workflow/Controller/TransitionsController.php new file mode 100644 index 0000000000000..e72f237090d28 --- /dev/null +++ b/administrator/components/com_workflow/Controller/TransitionsController.php @@ -0,0 +1,81 @@ + true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Deletes and returns correctly. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function delete() + { + parent::delete(); + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&extension=' . $this->input->getCmd("extension") + . '&workflow_id=' . $this->input->getCmd("workflow_id"), false + ) + ); + } + + /** + * Method to publish a list of items + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function publish() + { + parent::publish(); + + $extension = $this->input->get('extension'); + $extensionURL = $extension ? '&extension=' . $extension : ''; + + $workflow_id = $this->input->getInt('workflow_id'); + + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . $extensionURL . '&workflow_id=' . $workflow_id, false + ) + ); + } +} diff --git a/administrator/components/com_workflow/Controller/WorkflowController.php b/administrator/components/com_workflow/Controller/WorkflowController.php new file mode 100644 index 0000000000000..528f25259aff4 --- /dev/null +++ b/administrator/components/com_workflow/Controller/WorkflowController.php @@ -0,0 +1,243 @@ +extension)) + { + $this->extension = $this->input->get('extension', 'com_content'); + } + } + + /** + * Method to check if you can add a new record. + * + * @param array $data An array of input data. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function allowAdd($data = array()) + { + $user = Factory::getUser(); + + return $user->authorise('core.create', $this->extension); + } + + /** + * Method to check if you can edit a record. + * + * @param array $data An array of input data. + * @param string $key The name of the key for the primary key. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + */ + protected function allowEdit($data = array(), $key = 'id') + { + $recordId = isset($data[$key]) ? (int) $data[$key] : 0; + $user = Factory::getUser(); + + // Check "edit" permission on record asset (explicit or inherited) + if ($user->authorise('core.edit', $this->extension . '.workflow.' . $recordId)) + { + return true; + } + + // Check "edit own" permission on record asset (explicit or inherited) + if ($user->authorise('core.edit.own', $this->extension . '.workflow.' . $recordId)) + { + // Need to do a lookup from the model to get the owner + $record = $this->getModel()->getItem($recordId); + + return !empty($record) && $record->created_by == $user->id; + } + + return false; + } + + /** + * Gets the URL arguments to append to an item redirect. + * + * @param integer $recordId The primary key id for the item. + * @param string $urlVar The name of the URL variable for the id. + * + * @return string The arguments to append to the redirect URL. + * + * @since __DEPLOY_VERSION__ + */ + protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') + { + $append = parent::getRedirectToItemAppend($recordId); + $append .= '&extension=' . $this->extension; + + return $append; + } + + /** + * Gets the URL arguments to append to a list redirect. + * + * @return string The arguments to append to the redirect URL. + * + * @since __DEPLOY_VERSION__ + */ + protected function getRedirectToListAppend() + { + $append = parent::getRedirectToListAppend(); + $append .= '&extension=' . $this->extension; + + return $append; + } + + /** + * 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 __DEPLOY_VERSION__ + */ + public function postSaveHook(\JModelLegacy $model, $validData = array()) + { + $task = $this->getTask(); + + // The save2copy task needs to be handled slightly differently. + if ($task === 'save2copy') + { + $table = $model->getTable(); + + $key = $table->getKeyName(); + + $recordId = $this->input->getInt($key); + + $db = $model->getDbo(); + $query = $db->getQuery(true); + + $query->select('*') + ->from($db->quoteName('#__workflow_stages')) + ->where($db->quoteName('workflow_id') . ' = ' . (int) $recordId); + + $statuses = $db->setQuery($query)->loadAssocList(); + + $smodel = $this->getModel('State'); + + $workflowID = (int) $model->getState($model->getName() . '.id'); + + $mapping = []; + + foreach ($statuses as $status) + { + $table = $smodel->getTable(); + + $oldID = $status['id']; + + $status['workflow_id'] = $workflowID; + $status['id'] = 0; + unset($status['asset_id']); + + $table->save($status); + + $mapping[$oldID] = (int) $table->id; + } + + $query->clear(); + + $query->select('*') + ->from($db->quoteName('#__workflow_transitions')) + ->where($db->quoteName('workflow_id') . ' = ' . (int) $recordId); + + $transitions = $db->setQuery($query)->loadAssocList(); + + $tmodel = $this->getModel('Transition'); + + foreach ($transitions as $transition) + { + $table = $tmodel->getTable(); + + $transition['from_stage_id'] = $mapping[$transition['from_stage_id']]; + $transition['to_stage_id'] = $mapping[$transition['to_stage_id']]; + + $transition['workflow_id'] = $workflowID; + $transition['id'] = 0; + unset($transition['asset_id']); + + $table->save($transition); + } + } + } + + /** + * Method to save a workflow. + * + * @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 __DEPLOY_VERSION__ + */ + public function save($key = null, $urlVar = null) + { + $task = $this->getTask(); + + // The save2copy task needs to be handled slightly differently. + if ($task === 'save2copy') + { + $data = $this->input->post->get('jform', array(), 'array'); + + // Prevent default + $data['default'] = 0; + + $this->input->post->set('jform', $data); + } + + parent::save($key, $urlVar); + } +} diff --git a/administrator/components/com_workflow/Controller/WorkflowsController.php b/administrator/components/com_workflow/Controller/WorkflowsController.php new file mode 100644 index 0000000000000..2264db00265ef --- /dev/null +++ b/administrator/components/com_workflow/Controller/WorkflowsController.php @@ -0,0 +1,154 @@ +registerTask('unsetDefault', 'setDefault'); + } + + /** + * Proxy for getModel + * + * @param string $name The model name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config The array of possible config values. Optional. + * + * @return \Joomla\CMS\MVC\Model\BaseDatabaseModel The model. + * + * @since __DEPLOY_VERSION__ + */ + public function getModel($name = 'Workflow', $prefix = 'Administrator', $config = array('ignore_request' => true)) + { + return parent::getModel($name, $prefix, $config); + } + + /** + * Method to set the home property for a list of items + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function setDefault() + { + // Check for request forgeries + Session::checkToken('request') or die(Text::_('JINVALID_TOKEN')); + + // Get items to publish from the request. + $cid = $this->input->get('cid', array(), 'array'); + $data = array('setDefault' => 1, 'unsetDefault' => 0); + $task = $this->getTask(); + $value = ArrayHelper::getValue($data, $task, 0, 'int'); + + if (!$value) + { + $this->setMessage(Text::_('COM_WORKFLOW_DISABLE_DEFAULT'), 'warning'); + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&extension=' . $this->input->getCmd("extension"), false + ) + ); + + return; + } + + if (empty($cid) || !is_array($cid)) + { + $this->setMessage(Text::_('COM_WORKFLOW_NO_ITEM_SELECTED'), 'warning'); + } + elseif (count($cid) > 1) + { + $this->setMessage(Text::_('COM_WORKFLOW_TOO_MANY_ITEMS'), 'error'); + } + else + { + // Get the model. + $model = $this->getModel(); + + // Make sure the item ids are integers + $id = (int) reset($cid); + + // Publish the items. + if (!$model->setDefault($id, $value)) + { + $this->setMessage($model->getError(), 'warning'); + } + else + { + if ($value === 1) + { + $ntext = 'COM_WORKFLOW_ITEM_SET_DEFAULT'; + } + else + { + $ntext = 'COM_WORKFLOW_ITEM_UNSET_DEFAULT'; + } + + $this->setMessage(Text::_($ntext, count($cid))); + } + } + + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&extension=' . $this->input->getCmd("extension"), false + ) + ); + } + + /** + * Deletes and returns correctly. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function delete() + { + parent::delete(); + $this->setRedirect( + Route::_( + 'index.php?option=' . $this->option . '&view=' . $this->view_list + . '&extension=' . $this->input->getCmd("extension"), false + ) + ); + } +} diff --git a/administrator/components/com_workflow/Helper/StageHelper.php b/administrator/components/com_workflow/Helper/StageHelper.php new file mode 100644 index 0000000000000..9dcc9bf5c41bb --- /dev/null +++ b/administrator/components/com_workflow/Helper/StageHelper.php @@ -0,0 +1,25 @@ +input->getCmd('extension'); + + $parts = explode('.', $extension); + + $component = reset($parts); + + $eName = ucfirst(str_replace('com_', '', $component)); + $cName = $eName . 'Helper'; + + $class = '\\Joomla\\Component\\' . $eName . '\\Administrator\\Helper\\' . $cName; + + if (class_exists($class) && is_callable([$class, 'addSubmenu'])) + { + $lang = Factory::getLanguage(); + + // Loading language file from the administrator/language directory then + // loading language file from the administrator/components/*extension*/language directory + $lang->load($component, JPATH_BASE, null, false, true) + || $lang->load($component, \JPath::clean(JPATH_ADMINISTRATOR . '/components/' . $component), null, false, true); + + call_user_func([$class, 'addSubmenu'], $vName); + } + } +} diff --git a/administrator/components/com_workflow/Model/StageModel.php b/administrator/components/com_workflow/Model/StageModel.php new file mode 100644 index 0000000000000..cc20afada8541 --- /dev/null +++ b/administrator/components/com_workflow/Model/StageModel.php @@ -0,0 +1,327 @@ +option . '.' . $this->name; + $extension = $app->getUserStateFromRequest($context . '.filter.extension', 'extension', 'com_content', 'cmd'); + + $this->setState('filter.extension', $extension); + } + + /** + * Method to change the title + * + * @param integer $category_id The id of the category. + * @param string $alias The alias. + * @param string $title The title. + * + * @return array Contains the modified title and alias. + * + * @since __DEPLOY_VERSION__ + */ + protected function generateNewTitle($category_id, $alias, $title) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('title' => $title))) + { + $title = StringHelper::increment($title); + } + + return array($title, $alias); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function save($data) + { + $context = $this->option . '.' . $this->name; + $app = Factory::getApplication(); + $input = $app->input; + $workflowID = $app->getUserStateFromRequest($context . '.filter.workflow_id', 'workflow_id', 0, 'int'); + + if (empty($data['workflow_id'])) + { + $data['workflow_id'] = $workflowID; + } + + if ($input->get('task') == 'save2copy') + { + $origTable = clone $this->getTable(); + + // Alter the title for save as copy + if ($origTable->load(['title' => $data['title']])) + { + list($title) = $this->generateNewTitle(0, '', $data['title']); + $data['title'] = $title; + } + + $data['published'] = 0; + $data['default'] = 0; + } + + return parent::save($data); + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission for the component. + * + * @since __DEPLOY_VERSION__ + */ + protected function canDelete($record) + { + if (empty($record->id) || $record->published != -2) + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + + return false; + } + + $app = Factory::getApplication(); + $extension = $app->getUserStateFromRequest('com_workflow.stage.filter.extension', 'extension', 'com_content', 'cmd'); + + $parts = explode('.', $extension); + + $component = reset($parts); + + if (!Factory::getUser()->authorise('core.delete', $component . '.state.' . (int) $record->id) || $record->default) + { + $this->setError(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); + + return false; + } + + return true; + } + + /** + * 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 __DEPLOY_VERSION__ + */ + protected function canEditState($record) + { + $user = Factory::getUser(); + $app = Factory::getApplication(); + $extension = $app->getUserStateFromRequest('com_workflow.state.filter.extension', 'extension', 'com_content', 'cmd'); + + // Check for existing workflow. + if (!empty($record->id)) + { + return $user->authorise('core.edit.state', $extension . '.state.' . (int) $record->id); + } + + // Default to component settings if workflow isn't known. + return $user->authorise('core.edit.state', $extension); + } + + /** + * Abstract 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 __DEPLOY_VERSION__ + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm( + 'com_workflow.state', + 'stage', + array( + 'control' => 'jform', + 'load_data' => $loadData + ) + ); + + if (empty($form)) + { + return false; + } + + if ($loadData) + { + $data = $this->loadFormData(); + } + + $item = $this->getItem($form->getValue('id')); + + // Deactivate switcher if default + // Use $item, otherwise we'll be locked when we get the data from the request + if (!empty($item->default)) + { + $form->setValue('default', null, 1); + $form->setFieldAttribute('default', 'readonly', 'true'); + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since __DEPLOY_VERSION__ + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState( + 'com_workflow.edit.state.data', + array() + ); + + if (empty($data)) + { + $data = $this->getItem(); + } + + return $data; + } + + /** + * Method to change the home state of one or more items. + * + * @param array $pk A list of the primary keys to change. + * @param integer $value The value of the home state. + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function setDefault($pk, $value = 1) + { + $table = $this->getTable(); + + if ($table->load(array('id' => $pk))) + { + if (!$table->published) + { + $this->setError(Text::_("COM_WORKFLOW_ITEM_MUST_PUBLISHED")); + + return false; + } + } + + if ($value) + { + // Verify that the home page for this language is unique per client id + if ($table->load(array('default' => '1', 'workflow_id' => $table->workflow_id))) + { + $table->default = 0; + $table->store(); + } + } + + if ($table->load(array('id' => $pk))) + { + $table->default = $value; + $table->store(); + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to change the published state of one or more records. + * + * @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. + * + * @since __DEPLOY_VERSION__ + */ + public function publish(&$pks, $value = 1) + { + $table = $this->getTable(); + $pks = (array) $pks; + $app = Factory::getApplication(); + $extension = $app->getUserStateFromRequest('com_workflow.state.filter.extension', 'extension', 'com_content', 'cmd'); + + // Default item existence checks. + if ($value != 1) + { + foreach ($pks as $i => $pk) + { + if ($table->load(array('id' => $pk)) && $table->default) + { + // Prune items that you can't change. + $app->enqueueMessage(Text::_('COM_WORKFLOW_MSG_DELETE_DEFAULT'), 'error'); + unset($pks[$i]); + } + } + } + + return parent::publish($pks, $value); + } +} diff --git a/administrator/components/com_workflow/Model/StagesModel.php b/administrator/components/com_workflow/Model/StagesModel.php new file mode 100644 index 0000000000000..f144b164ac6ec --- /dev/null +++ b/administrator/components/com_workflow/Model/StagesModel.php @@ -0,0 +1,187 @@ +getUserStateFromRequest($this->context . '.filter.workflow_id', 'workflow_id', 1, 'int'); + $extension = $app->getUserStateFromRequest($this->context . '.filter.extension', 'extension', 'com_content', 'cmd'); + + if ($workflowID) + { + $table = $this->getTable('Workflow', 'Administrator'); + + if ($table->load($workflowID)) + { + $this->setState('active_workflow', $table->title); + } + } + + $this->setState('filter.workflow_id', $workflowID); + $this->setState('filter.extension', $extension); + + parent::populateState($ordering, $direction); + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param object $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since __DEPLOY_VERSION__ + */ + protected function getReorderConditions($table) + { + return [ + 'workflow_id = ' . (int) $table->workflow_id + ]; + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return \Joomla\CMS\Table\Table A JTable object + * + * @since __DEPLOY_VERSION__ + */ + public function getTable($type = 'Stage', $prefix = 'Administrator', $config = array()) + { + return parent::getTable($type, $prefix, $config); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return string The query to database. + * + * @since __DEPLOY_VERSION__ + */ + public function getListQuery() + { + $db = $this->getDbo(); + + $query = parent::getListQuery(); + + $select = $db->quoteName( + array( + 's.id', + 's.title', + 's.ordering', + 's.condition', + 's.default', + 's.published' + ) + ); + + $query + ->select($select) + ->from($db->quoteName('#__workflow_stages', 's')); + + // Filter by extension + if ($workflowID = (int) $this->getState('filter.workflow_id')) + { + $query->where($db->quoteName('s.workflow_id') . ' = ' . $workflowID); + } + + $condition = $this->getState('filter.condition'); + + // Filter by condition + if (is_numeric($condition)) + { + $query->where($db->quoteName('s.condition') . ' = ' . (int) $db->escape($condition)); + } + + $status = (string) $this->getState('filter.published'); + + // Filter by condition + if (is_numeric($status)) + { + $query->where($db->quoteName('s.published') . ' = ' . (int) $status); + } + elseif ($status == '') + { + $query->where($db->quoteName('s.published') . ' IN (0, 1)'); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(' . $db->quoteName('s.title') . ' LIKE ' . $search . ' OR ' . $db->quoteName('s.description') . ' LIKE ' . $search . ')'); + } + + // Add the list ordering clause. + $query->order($db->escape($this->getState('list.ordering', 's.ordering')) . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); + + return $query; + } +} diff --git a/administrator/components/com_workflow/Model/TransitionModel.php b/administrator/components/com_workflow/Model/TransitionModel.php new file mode 100644 index 0000000000000..323167211a190 --- /dev/null +++ b/administrator/components/com_workflow/Model/TransitionModel.php @@ -0,0 +1,268 @@ +option . '.' . $this->name; + $extension = $app->getUserStateFromRequest($context . '.filter.extension', 'extension', 'com_content', 'cmd'); + + $this->setState('filter.extension', $extension); + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission for the component. + * + * @since __DEPLOY_VERSION__ + */ + protected function canDelete($record) + { + if (empty($record->id) || $record->published != -2) + { + return false; + } + + $app = Factory::getApplication(); + $extension = $app->getUserStateFromRequest('com_workflow.transition.filter.extension', 'extension', 'com_content', 'cmd'); + + return Factory::getUser()->authorise('core.delete', $extension . '.transition.' . (int) $record->id); + } + + /** + * 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 __DEPLOY_VERSION__ + */ + protected function canEditState($record) + { + $user = Factory::getUser(); + $app = Factory::getApplication(); + $extension = $app->getUserStateFromRequest('com_workflow.transition.filter.extension', 'extension', 'com_content', 'cmd'); + + // Check for existing workflow. + if (!empty($record->id)) + { + return $user->authorise('core.edit.state', $extension . '.transition.' . (int) $record->id); + } + + // Default to component settings if workflow isn't known. + return $user->authorise('core.edit.state', $extension); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function save($data) + { + $pk = (!empty($data['id'])) ? $data['id'] : (int) $this->getState($this->getName() . '.id'); + $isNew = true; + $context = $this->option . '.' . $this->name; + $app = Factory::getApplication(); + $input = $app->input; + + if ($pk > 0) + { + $isNew = false; + } + + if ($data['to_stage_id'] == $data['from_stage_id']) + { + $this->setError(Text::_('COM_WORKFLOW_MSG_FROM_TO_STAGE')); + + return false; + } + + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__workflow_transitions')) + ->where($db->quoteName('from_stage_id') . ' = ' . (int) $data['from_stage_id']) + ->where($db->quoteName('to_stage_id') . ' = ' . (int) $data['to_stage_id']); + + if (!$isNew) + { + $query->where($db->quoteName('id') . ' <> ' . (int) $data['id']); + } + + $db->setQuery($query); + $duplicate = $db->loadResult(); + + if (!empty($duplicate)) + { + $this->setError(Text::_("COM_WORKFLOW_TRANSITION_DUPLICATE")); + + return false; + } + + $workflowID = $app->getUserStateFromRequest($context . '.filter.workflow_id', 'workflow_id', 0, 'int'); + + if (empty($data['workflow_id'])) + { + $data['workflow_id'] = $workflowID; + } + + if ($input->get('task') == 'save2copy') + { + $origTable = clone $this->getTable(); + + // Alter the title for save as copy + if ($origTable->load(['title' => $data['title']])) + { + list($title) = $this->generateNewTitle(0, '', $data['title']); + $data['title'] = $title; + } + + $data['published'] = 0; + } + + return parent::save($data); + } + + /** + * Method to change the title + * + * @param integer $category_id The id of the category. + * @param string $alias The alias. + * @param string $title The title. + * + * @return array Contains the modified title and alias. + * + * @since __DEPLOY_VERSION__ + */ + protected function generateNewTitle($category_id, $alias, $title) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('title' => $title))) + { + $title = StringHelper::increment($title); + } + + return array($title, $alias); + } + + /** + * Abstract 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 __DEPLOY_VERSION__ + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm( + 'com_workflow.transition', + 'transition', + array( + 'control' => 'jform', + 'load_data' => $loadData + ) + ); + + if (empty($form)) + { + return false; + } + + if ($loadData) + { + $data = (object) $this->loadFormData(); + } + + if (!$this->canEditState($data)) + { + // Disable fields for display. + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + $app = Factory::getApplication(); + + $workflow_id = $app->input->getInt('workflow_id'); + + $where = $this->getDbo()->quoteName('workflow_id') . ' = ' . $workflow_id . ' AND ' . $this->getDbo()->quoteName('published') . ' = 1'; + + $form->setFieldAttribute('from_stage_id', 'sql_where', $where); + $form->setFieldAttribute('to_stage_id', 'sql_where', $where); + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since __DEPLOY_VERSION__ + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState( + 'com_workflow.edit.transition.data', + array() + ); + + if (empty($data)) + { + $data = $this->getItem(); + } + + return $data; + } +} diff --git a/administrator/components/com_workflow/Model/TransitionsModel.php b/administrator/components/com_workflow/Model/TransitionsModel.php new file mode 100644 index 0000000000000..16791b2086aa2 --- /dev/null +++ b/administrator/components/com_workflow/Model/TransitionsModel.php @@ -0,0 +1,231 @@ +getUserStateFromRequest($this->context . '.filter.workflow_id', 'workflow_id', 1, 'int'); + $extension = $app->getUserStateFromRequest($this->context . '.filter.extension', 'extension', 'com_content', 'cmd'); + + if ($workflowID) + { + $table = $this->getTable('Workflow', 'Administrator'); + + if ($table->load($workflowID)) + { + $this->setState('active_workflow', $table->title); + } + } + + $this->setState('filter.workflow_id', $workflowID); + $this->setState('filter.extension', $extension); + + parent::populateState($ordering, $direction); + + // TODO: Change the autogenerated stub + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return \Joomla\CMS\Table\Table A JTable object + * + * @since __DEPLOY_VERSION__ + */ + public function getTable($type = 'Transition', $prefix = 'Administrator', $config = array()) + { + return parent::getTable($type, $prefix, $config); + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param object $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since __DEPLOY_VERSION__ + */ + protected function getReorderConditions($table) + { + return 'workflow_id = ' . $this->getDbo()->quote((int) $table->workflow_id); + } + + /** + * Method to get the data that should be injected in the form. + * + * @return string The query to database. + * + * @since __DEPLOY_VERSION__ + */ + public function getListQuery() + { + $db = $this->getDbo(); + + $query = parent::getListQuery(); + + $select = $db->quoteName( + array( + 't.id', + 't.title', + 't.from_stage_id', + 't.to_stage_id', + 't.published', + 't.ordering', + ) + ); + + $select[] = $db->quoteName('f_stage.title', 'from_stage'); + $select[] = $db->quoteName('t_stage.title', 'to_stage'); + $joinTo = $db->quoteName('#__workflow_stages', 't_stage') . + ' ON ' . $db->quoteName('t_stage.id') . ' = ' . $db->quoteName('t.to_stage_id'); + + $query + ->select($select) + ->from($db->quoteName('#__workflow_transitions', 't')) + ->leftJoin( + $db->quoteName('#__workflow_stages', 'f_stage') . ' ON ' . $db->quoteName('f_stage.id') . ' = ' . $db->quoteName('t.from_stage_id') + ) + ->leftJoin($joinTo); + + // Filter by extension + if ($workflowID = (int) $this->getState('filter.workflow_id')) + { + $query->where($db->quoteName('t.workflow_id') . ' = ' . $workflowID); + } + + $status = $this->getState('filter.published'); + + // Filter by condition + if (is_numeric($status)) + { + $query->where($db->quoteName('t.published') . ' = ' . (int) $status); + } + elseif ($status == '') + { + $query->where($db->quoteName('t.published') . ' IN (0, 1)'); + } + + // Filter by column from_stage_id + if ($fromStage = $this->getState('filter.from_stage')) + { + $query->where($db->quoteName('from_stage_id') . ' = ' . (int) $fromStage); + } + + // Filter by column from_stage_id + if ($toStage = $this->getState('filter.to_stage')) + { + $query->where($db->quoteName('to_stage_id') . ' = ' . (int) $toStage); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(' . $db->quoteName('title') . ' LIKE ' . $search . ' OR ' . $db->quoteName('description') . ' LIKE ' . $search . ')'); + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering', 't.id'); + $orderDirn = strtolower($this->state->get('list.direction', 'asc')); + + $query->order($db->quoteName($orderCol) . ' ' . $db->escape($orderDirn == 'desc' ? 'DESC' : 'ASC')); + + return $query; + } + + /** + * 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 __DEPLOY_VERSION__ + */ + public function getFilterForm($data = array(), $loadData = true) + { + $form = parent::getFilterForm($data, $loadData); + + $id = (int) $this->getState('filter.workflow_id'); + + if ($form) + { + $where = $this->getDbo()->quoteName('workflow_id') . ' = ' . $id . ' AND ' . $this->getDbo()->quoteName('published') . ' = 1'; + + $form->setFieldAttribute('from_stage', 'sql_where', $where, 'filter'); + $form->setFieldAttribute('to_stage', 'sql_where', $where, 'filter'); + } + + return $form; + } +} diff --git a/administrator/components/com_workflow/Model/WorkflowModel.php b/administrator/components/com_workflow/Model/WorkflowModel.php new file mode 100644 index 0000000000000..d75ab057c90dd --- /dev/null +++ b/administrator/components/com_workflow/Model/WorkflowModel.php @@ -0,0 +1,380 @@ +option . '.' . $this->name; + $extension = $app->getUserStateFromRequest($context . '.filter.extension', 'extension', 'com_content', 'cmd'); + + $this->setState('filter.extension', $extension); + } + + /** + * Method to change the title + * + * @param integer $category_id The id of the category. + * @param string $alias The alias. + * @param string $title The title. + * + * @return array Contains the modified title and alias. + * + * @since __DEPLOY_VERSION__ + */ + protected function generateNewTitle($category_id, $alias, $title) + { + // Alter the title & alias + $table = $this->getTable(); + + while ($table->load(array('title' => $title))) + { + $title = StringHelper::increment($title); + } + + return array($title, $alias); + } + + /** + * Method to save the form data. + * + * @param array $data The form data. + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function save($data) + { + $user = Factory::getUser(); + $app = Factory::getApplication(); + $input = $app->input; + $context = $this->option . '.' . $this->name; + $extension = $app->getUserStateFromRequest($context . '.filter.extension', 'extension', 'com_content', 'cmd'); + $data['extension'] = $extension; + $data['asset_id'] = 0; + + if ($input->get('task') == 'save2copy') + { + $origTable = clone $this->getTable(); + + // Alter the title for save as copy + if ($origTable->load(['title' => $data['title']])) + { + list($title) = $this->generateNewTitle(0, '', $data['title']); + $data['title'] = $title; + } + + // Unpublish new copy + $data['published'] = 0; + } + + $result = parent::save($data); + + // Create a default stage + if ($result && $input->getCmd('task') !== 'save2copy' && $this->getState($this->getName() . '.new')) + { + $stage = $this->getTable('Stage'); + + $newstage = new \stdClass; + + $newstage->workflow_id = (int) $this->getState($this->getName() . '.id'); + $newstage->title = Text::_('COM_WORKFLOW_PUBLISHED'); + $newstage->description = ''; + $newstage->published = 1; + $newstage->condition = 1; + $newstage->default = 1; + + $stage->save($newstage); + } + + return $result; + } + + /** + * Abstract 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 __DEPLOY_VERSION__ + */ + public function getForm($data = array(), $loadData = true) + { + // Get the form. + $form = $this->loadForm( + 'com_workflow.workflow', + 'workflow', + array( + 'control' => 'jform', + 'load_data' => $loadData + ) + ); + + if (empty($form)) + { + return false; + } + + if ($loadData) + { + $data = $this->loadFormData(); + } + + $item = $this->getItem($form->getValue('id')); + + // Deactivate switcher if default + // Use $item, otherwise we'll be locked when we get the data from the request + if (!empty($item->default)) + { + $form->setFieldAttribute('default', 'readonly', 'true'); + } + + // Modify the form based on access controls. + if (!$this->canEditState((object) $data)) + { + // Disable fields for display. + $form->setFieldAttribute('published', 'disabled', 'true'); + + // Disable fields while saving. + // The controller has already verified this is a record you can edit. + $form->setFieldAttribute('published', 'filter', 'unset'); + } + + $form->setFieldAttribute('created', 'default', Factory::getDate()->format('Y-m-d H:i:s')); + $form->setFieldAttribute('modified', 'default', Factory::getDate()->format('Y-m-d H:i:s')); + + return $form; + } + + /** + * Method to get the data that should be injected in the form. + * + * @return mixed The data for the form. + * + * @since __DEPLOY_VERSION__ + */ + protected function loadFormData() + { + // Check the session for previously entered form data. + $data = Factory::getApplication()->getUserState( + 'com_workflow.edit.workflow.data', + array() + ); + + if (empty($data)) + { + $data = $this->getItem(); + } + + return $data; + } + + /** + * Method to preprocess the form. + * + * @param \JForm $form A \JForm object. + * @param mixed $data The data expected for the form. + * @param string $group The name of the plugin group to import (defaults to "content"). + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function preprocessForm(\JForm $form, $data, $group = 'content') + { + $extension = Factory::getApplication()->input->get('extension', 'com_content'); + + // Set the access control rules field component value. + $form->setFieldAttribute('rules', 'component', $extension); + $form->setFieldAttribute('rules', 'section', 'workflow'); + + parent::preprocessForm($form, $data, $group); + } + + /** + * A protected method to get a set of ordering conditions. + * + * @param object $table A record object. + * + * @return array An array of conditions to add to add to ordering queries. + * + * @since __DEPLOY_VERSION__ + */ + protected function getReorderConditions($table) + { + return 'extension = ' . $this->getDbo()->quote($table->extension); + } + + /** + * Method to change the default state of one item. + * + * @param array $pk A list of the primary keys to change. + * @param integer $value The value of the home state. + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + */ + public function setDefault($pk, $value = 1) + { + $table = $this->getTable(); + + if ($table->load(array('id' => $pk))) + { + if ($table->published !== 1) + { + $this->setError(Text::_('COM_WORKFLOW_ITEM_MUST_PUBLISHED')); + + return false; + } + } + + $date = Factory::getDate()->toSql(); + + if ($value) + { + // Unset other default item + if ($table->load(array('default' => '1'))) + { + $table->default = 0; + $table->modified = $date; + $table->store(); + } + } + + if ($table->load(array('id' => $pk))) + { + $table->modified = $date; + $table->default = $value; + $table->store(); + } + + // Clean the cache + $this->cleanCache(); + + return true; + } + + /** + * Method to test whether a record can be deleted. + * + * @param object $record A record object. + * + * @return boolean True if allowed to delete the record. Defaults to the permission for the component. + * + * @since __DEPLOY_VERSION__ + */ + protected function canDelete($record) + { + if (empty($record->id) || $record->published != -2) + { + return false; + } + + return Factory::getUser()->authorise('core.delete', $record->extension . '.workflow.' . (int) $record->id); + } + + /** + * 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 __DEPLOY_VERSION__ + */ + protected function canEditState($record) + { + $user = Factory::getUser(); + + // Check for existing workflow. + if (!empty($record->id)) + { + return $user->authorise('core.edit.state', $record->extension . '.workflow.' . (int) $record->id); + } + + // Default to component settings if workflow isn't known. + return $user->authorise('core.edit.state', $record->extension); + } + + /** + * Method to change the published state of one or more records. + * + * @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. + * + * @since __DEPLOY_VERSION__ + */ + public function publish(&$pks, $value = 1) + { + $table = $this->getTable(); + $pks = (array) $pks; + + $date = Factory::getDate()->toSql(); + + // Default workflow item check. + foreach ($pks as $i => $pk) + { + if ($table->load($pk) && $value != 1 && $table->default) + { + // Prune items that you can't change. + Factory::getApplication()->enqueueMessage(Text::_('COM_WORKFLOW_UNPUBLISH_DEFAULT_ERROR'), 'error'); + unset($pks[$i]); + break; + } + } + + // Clean the cache. + $this->cleanCache(); + + // Ensure that previous checks don't empty the array. + if (empty($pks)) + { + return true; + } + + $table->load($pk); + $table->modified = $date; + $table->store(); + + return parent::publish($pks, $value); + } +} diff --git a/administrator/components/com_workflow/Model/WorkflowsModel.php b/administrator/components/com_workflow/Model/WorkflowsModel.php new file mode 100644 index 0000000000000..8c381211ec5d2 --- /dev/null +++ b/administrator/components/com_workflow/Model/WorkflowsModel.php @@ -0,0 +1,264 @@ +getUserStateFromRequest($this->context . '.filter.extension', 'extension', 'com_content', 'cmd'); + + $this->setState('filter.extension', $extension); + $parts = explode('.', $extension); + + // Extract the component name + $this->setState('filter.component', $parts[0]); + + // Extract the optional section name + $this->setState('filter.section', (count($parts) > 1) ? $parts[1] : null); + + parent::populateState($ordering, $direction); + } + + /** + * Method to get a table object, load it if necessary. + * + * @param string $type The table name. Optional. + * @param string $prefix The class prefix. Optional. + * @param array $config Configuration array for model. Optional. + * + * @return \Joomla\CMS\Table\Table A JTable object + * + * @since __DEPLOY_VERSION__ + */ + public function getTable($type = 'Workflow', $prefix = 'Administrator', $config = array()) + { + return parent::getTable($type, $prefix, $config); + } + + /** + * Method to get an array of data items. + * + * @return mixed An array of data items on success, false on failure. + * + * @since __DEPLOY_VERSION__ + */ + public function getItems() + { + $items = parent::getItems(); + + if ($items) + { + $this->countItems($items); + } + + return $items; + } + + /** + * Add the number of transitions and states to all workflow items + * + * @param array $items The workflow items + * + * @return mixed An array of data items on success, false on failure. + * + * @since __DEPLOY_VERSION__ + */ + protected function countItems($items) + { + $db = $this->getDbo(); + + $ids = [0]; + + foreach ($items as $item) + { + $ids[] = (int) $item->id; + + $item->count_states = 0; + $item->count_transitions = 0; + } + + $query = $db->getQuery(true); + + $query ->select('workflow_id, count(*) AS count') + ->from($db->quoteName('#__workflow_stages')) + ->where($db->quoteName('workflow_id') . ' IN(' . implode(',', $ids) . ')') + ->where($db->quoteName('published') . '>= 0') + ->group($db->quoteName('workflow_id')); + + $status = $db->setQuery($query)->loadObjectList('workflow_id'); + + $query = $db->getQuery(true); + + $query->select('workflow_id, count(*) AS count') + ->from($db->quoteName('#__workflow_transitions')) + ->where($db->quoteName('workflow_id') . ' IN(' . implode(',', $ids) . ')') + ->where($db->quoteName('published') . '>= 0') + ->group($db->quoteName('workflow_id')); + + $transitions = $db->setQuery($query)->loadObjectList('workflow_id'); + + foreach ($items as $item) + { + if (isset($status[$item->id])) + { + $item->count_states = (int) $status[$item->id]->count; + } + + if (isset($transitions[$item->id])) + { + $item->count_transitions = (int) $transitions[$item->id]->count; + } + } + } + + /** + * Method to get the data that should be injected in the form. + * + * @return string The query to database. + * + * @since __DEPLOY_VERSION__ + */ + public function getListQuery() + { + $db = $this->getDbo(); + + $query = parent::getListQuery(); + + $select = $db->quoteName( + array( + 'w.id', + 'w.title', + 'w.created', + 'w.modified', + 'w.published', + 'w.ordering', + 'w.default', + 'w.created_by', + 'w.description', + 'u.name' + ) + ); + + $query + ->select($select) + ->from($db->quoteName('#__workflows', 'w')) + ->leftJoin($db->quoteName('#__users', 'u') . ' ON ' . $db->quoteName('u.id') . ' = ' . $db->quoteName('w.created_by')); + + // Filter by extension + if ($extension = $this->getState('filter.extension')) + { + $query->where($db->quoteName('extension') . ' = ' . $db->quote($db->escape($extension))); + } + + $status = (string) $this->getState('filter.published'); + + // Filter by condition + if (is_numeric($status)) + { + $query->where($db->quoteName('w.published') . ' = ' . (int) $status); + } + elseif ($status == '') + { + $query->where($db->quoteName('w.published') . " IN ('0', '1')"); + } + + // Filter by search in title + $search = $this->getState('filter.search'); + + if (!empty($search)) + { + $search = $db->quote('%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%')); + $query->where('(' . $db->quoteName('w.title') . ' LIKE ' . $search . ' OR ' . $db->quoteName('w.description') . ' LIKE ' . $search . ')'); + } + + // Add the list ordering clause. + $orderCol = $this->state->get('list.ordering', 'w.ordering'); + $orderDirn = strtolower($this->state->get('list.direction', 'asc')); + + $query->order($db->quoteName($db->escape($orderCol)) . ' ' . $db->escape($orderDirn == 'desc' ? 'DESC' : 'ASC')); + + return $query; + } + + /** + * Build a list of authors + * + * @return \stdClass[] + * + * @since __DEPLOY_VERSION__ + */ + public function getAuthors() + { + $query = $this->getDbo()->getQuery(true); + + $query->select('u.id AS value, u.name AS text') + ->from('#__users AS u') + ->join('INNER', '#__workflows AS c ON c.created_by = u.id') + ->group('u.id, u.name') + ->order('u.name'); + + return $this->getDbo()->setQuery($query)->loadObjectList(); + } +} diff --git a/administrator/components/com_workflow/Table/StageTable.php b/administrator/components/com_workflow/Table/StageTable.php new file mode 100644 index 0000000000000..c0cec9d6a0211 --- /dev/null +++ b/administrator/components/com_workflow/Table/StageTable.php @@ -0,0 +1,237 @@ +access = (int) Factory::getConfig()->get('access'); + } + + /** + * Deletes workflow with transition and stages. + * + * @param int $pk Extension ids to delete. + * + * @return boolean True on success. + * + * @since __DEPLOY_VERSION__ + * + * @throws \UnexpectedValueException + */ + public function delete($pk = null) + { + // @TODO: correct ACL check should be done in $model->canDelete(...) not here + if (!Factory::getUser()->authorise('core.delete', 'com_workflows')) + { + throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 403); + } + + $db = $this->getDbo(); + $app = Factory::getApplication(); + + // Gets the update site names. + $query = $db->getQuery(true) + ->select($db->quoteName(array('id', 'title'))) + ->from($db->quoteName('#__workflow_stages')) + ->where($db->quoteName('id') . ' = ' . (int) $pk); + $db->setQuery($query); + $stage = $db->loadResult(); + + if ($stage->default) + { + $app->enqueueMessage(Text::sprintf('COM_WORKFLOW_MSG_DELETE_DEFAULT', $stage->title), 'error'); + + return false; + } + + // Delete the update site from all tables. + try + { + $query = $db->getQuery(true) + ->delete($db->quoteName('#__workflow_transitions')) + ->where($db->quoteName('to_stage_id') . ' = ' . (int) $pk, 'OR') + ->where($db->quoteName('from_stage_id') . ' = ' . (int) $pk); + + $db->setQuery($query)->execute(); + + return parent::delete($pk); + } + catch (\RuntimeException $e) + { + $app->enqueueMessage(Text::sprintf('COM_WORKFLOW_MSG_WORKFLOWS_DELETE_ERROR', $stage->title, $e->getMessage()), 'error'); + } + + return false; + } + + /** + * Overloaded check function + * + * @return boolean True on success + * + * @see Table::check() + * @since 4.0 + */ + public function check() + { + try + { + parent::check(); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (trim($this->title) === '') + { + $this->setError(Text::_('JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_STATE')); + + return false; + } + + if (!empty($this->default)) + { + if ((int) $this->published !== 1) + { + $this->setError(Text::_('COM_WORKFLOW_ITEM_MUST_PUBLISHED')); + + return false; + } + } + else + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query + ->select($db->quoteName('id')) + ->from($db->quoteName('#__workflow_stages')) + ->where($db->quoteName('workflow_id') . '=' . $this->workflow_id) + ->where($db->quoteName('default') . '= 1'); + + $stage = $db->setQuery($query)->loadObject(); + + if (empty($stage) || $stage->id === $this->id) + { + $this->default = '1'; + + $this->setError(Text::_('COM_WORKFLOW_DISABLE_DEFAULT')); + + return false; + } + } + + return true; + } + + /** + * Overloaded store function + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return mixed False on failure, positive integer on success. + * + * @see Table::store() + * @since 4.0 + */ + public function store($updateNulls = false) + { + $table = new StageTable($this->getDbo()); + + if ($this->default == '1') + { + // Verify that the default is unique for this workflow + if ($table->load(array('default' => '1', 'workflow_id' => (int) $this->workflow_id))) + { + $table->default = 0; + $table->store(); + } + } + + return parent::store($updateNulls); + } + + /** + * Method to compute the default name of the asset. + * The default name is in the form table_name.id + * where id is the value of the primary key of the table. + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetName() + { + $k = $this->_tbl_key; + $workflow = new WorkflowTable($this->getDbo()); + $workflow->load($this->workflow_id); + + return $workflow->extension . '.stage.' . (int) $this->$k; + } + + /** + * Method to return the title to use for the asset table. + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetTitle() + { + return $this->title; + } + + /** + * Get the parent asset id for the record + * + * @param Table $table A JTable object for the asset parent. + * @param integer $id The id for the asset + * + * @return integer The id of the asset's parent + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetParentId(Table $table = null, $id = null) + { + $asset = self::getInstance('Asset', 'JTable', array('dbo' => $this->getDbo())); + $workflow = new WorkflowTable($this->getDbo()); + $workflow->load($this->workflow_id); + $name = $workflow->extension . '.workflow.' . (int) $workflow->id; + $asset->loadByName($name); + $assetId = $asset->id; + + return !empty($assetId) ? $assetId : parent::_getAssetParentId($table, $id); + } +} diff --git a/administrator/components/com_workflow/Table/TransitionTable.php b/administrator/components/com_workflow/Table/TransitionTable.php new file mode 100644 index 0000000000000..07f537e46cd22 --- /dev/null +++ b/administrator/components/com_workflow/Table/TransitionTable.php @@ -0,0 +1,89 @@ +access = (int) Factory::getConfig()->get('access'); + } + + /** + * Method to compute the default name of the asset. + * The default name is in the form table_name.id + * where id is the value of the primary key of the table. + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetName() + { + $k = $this->_tbl_key; + $workflow = new WorkflowTable($this->getDbo()); + $workflow->load($this->workflow_id); + + return $workflow->extension . '.transition.' . (int) $this->$k; + } + + /** + * Method to return the title to use for the asset table. + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetTitle() + { + return $this->title; + } + + /** + * Get the parent asset id for the record + * + * @param Table $table A JTable object for the asset parent. + * @param integer $id The id for the asset + * + * @return integer The id of the asset's parent + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetParentId(Table $table = null, $id = null) + { + $asset = self::getInstance('Asset', 'JTable', array('dbo' => $this->getDbo())); + $workflow = new WorkflowTable($this->getDbo()); + $workflow->load($this->workflow_id); + $name = $workflow->extension . '.workflow.' . (int) $workflow->id; + $asset->loadByName($name); + $assetId = $asset->id; + + return !empty($assetId) ? $assetId : parent::_getAssetParentId($table, $id); + } +} diff --git a/administrator/components/com_workflow/Table/WorkflowTable.php b/administrator/components/com_workflow/Table/WorkflowTable.php new file mode 100644 index 0000000000000..d67dd5907181f --- /dev/null +++ b/administrator/components/com_workflow/Table/WorkflowTable.php @@ -0,0 +1,281 @@ +typeAlias = '{extension}.workflow'; + + parent::__construct('#__workflows', 'id', $db); + + $this->access = (int) Factory::getConfig()->get('access'); + } + + /** + * Deletes workflow with transition and states. + * + * @param int $pk Extension ids to delete. + * + * @return boolean + * + * @since __DEPLOY_VERSION__ + * + * @throws \Exception on ACL error + */ + public function delete($pk = null) + { + if (!Factory::getUser()->authorise('core.delete', 'com_installer')) + { + throw new \Exception(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED'), 403); + } + + $db = $this->getDbo(); + $app = Factory::getApplication(); + + // Gets the workflow information that is going to be deleted. + $query = $db->getQuery(true) + ->select($db->quoteName(array('id', 'title'))) + ->from($db->quoteName('#__workflows')) + ->where($db->quoteName('id') . ' = ' . (int) $pk); + $db->setQuery($query); + $workflow = $db->loadResult(); + + if ($workflow->default) + { + $app->enqueueMessage(Text::sprintf('COM_WORKFLOW_MSG_DELETE_DEFAULT', $workflow->title), 'error'); + + return false; + } + + // Delete the workflow states, then transitions from all tables. + try + { + $query = $db->getQuery(true) + ->delete($db->quoteName('#__workflow_stages')) + ->where($db->quoteName('workflow_id') . ' = ' . (int) $pk); + $db->setQuery($query); + $db->execute(); + + $query = $db->getQuery(true) + ->delete($db->quoteName('#__workflow_transitions')) + ->where($db->quoteName('workflow_id') . ' = ' . (int) $pk); + $db->setQuery($query); + $db->execute(); + + return parent::delete($pk); + } + catch (\RuntimeException $e) + { + $app->enqueueMessage(Text::sprintf('COM_WORKFLOW_MSG_WORKFLOWS_DELETE_ERROR', $workflow->title, $e->getMessage()), 'error'); + + return false; + } + } + + /** + * Overloaded check function + * + * @return boolean True on success + * + * @see Table::check() + * @since 4.0 + */ + public function check() + { + try + { + parent::check(); + } + catch (\Exception $e) + { + $this->setError($e->getMessage()); + + return false; + } + + if (trim($this->title) === '') + { + $this->setError(Text::_('JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_WORKFLOW')); + + return false; + } + + if (!empty($this->default)) + { + if ((int) $this->published !== 1) + { + $this->setError(Text::_('COM_WORKFLOW_ITEM_MUST_PUBLISHED')); + + return false; + } + } + else + { + $db = $this->getDbo(); + $query = $db->getQuery(true); + + $query + ->select($db->quoteName('id')) + ->from($db->quoteName('#__workflows')) + ->where($db->quoteName('default') . '= 1'); + + $state = $db->setQuery($query)->loadObject(); + + if (empty($state) || $state->id === $this->id) + { + $this->default = '1'; + + $this->setError(Text::_('COM_WORKFLOW_DISABLE_DEFAULT')); + + return false; + } + } + + return true; + } + + /** + * Overloaded store function + * + * @param boolean $updateNulls True to update fields even if they are null. + * + * @return mixed False on failure, positive integer on success. + * + * @see Table::store() + * @since 4.0 + */ + public function store($updateNulls = false) + { + $date = Factory::getDate(); + $user = Factory::getUser(); + + $table = new WorkflowTable($this->getDbo()); + + if ($this->id) + { + // Existing item + $this->modified_by = $user->id; + $this->modified = $date->toSql(); + } + else + { + $this->modified_by = 0; + $this->modified = $this->getDbo()->getNullDate(); + } + + if (!(int) $this->created) + { + $this->created = $date->toSql(); + } + + if (empty($this->created_by)) + { + $this->created_by = $user->id; + } + + if ($this->default == '1') + { + // Verify that the default is unique for this workflow + if ($table->load(array('default' => '1'))) + { + $table->default = 0; + $table->store(); + } + } + + return parent::store($updateNulls); + } + + /** + * Method to compute the default name of the asset. + * The default name is in the form table_name.id + * where id is the value of the primary key of the table. + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetName() + { + $k = $this->_tbl_key; + + return $this->extension . '.workflow.' . (int) $this->$k; + } + + /** + * Method to return the title to use for the asset table. + * + * @return string + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetTitle() + { + return $this->title; + } + + /** + * Get the parent asset id for the record + * + * @param Table $table A JTable object for the asset parent. + * @param integer $id The id for the asset + * + * @return integer The id of the asset's parent + * + * @since __DEPLOY_VERSION__ + */ + protected function _getAssetParentId(Table $table = null, $id = null) + { + $assetId = null; + + // Build the query to get the asset id for the parent category. + $query = $this->getDbo()->getQuery(true) + ->select($this->getDbo()->quoteName('id')) + ->from($this->getDbo()->quoteName('#__assets')) + ->where($this->getDbo()->quoteName('name') . ' = ' . $this->getDbo()->quote($this->extension)); + + // Get the asset id from the database. + $this->getDbo()->setQuery($query); + + if ($result = $this->getDbo()->loadResult()) + { + $assetId = (int) $result; + } + + // Return the asset id. + if ($assetId) + { + return $assetId; + } + else + { + return parent::_getAssetParentId($table, $id); + } + } +} diff --git a/administrator/components/com_workflow/View/Stage/HtmlView.php b/administrator/components/com_workflow/View/Stage/HtmlView.php new file mode 100644 index 0000000000000..994ced1cc019b --- /dev/null +++ b/administrator/components/com_workflow/View/Stage/HtmlView.php @@ -0,0 +1,148 @@ +get('Errors'))) + { + throw new JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Get the Data + $this->state = $this->get('State'); + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->extension = $this->state->get('filter.extension'); + + // Set the toolbar + $this->addToolBar(); + + // Display the template + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $user = Factory::getUser(); + $userId = $user->id; + $isNew = empty($this->item->id); + + $canDo = StageHelper::getActions($this->extension, 'state', $this->item->id); + + ToolbarHelper::title(empty($this->item->id) ? Text::_('COM_WORKFLOW_STAGE_ADD') : Text::_('COM_WORKFLOW_STAGE_EDIT'), 'address'); + + $toolbarButtons = []; + + if ($isNew) + { + // For new records, check the create permission. + if ($canDo->get('core.edit')) + { + $toolbarButtons = [['apply', 'stage.apply'], ['save', 'stage.save'], ['save2new', 'stage.save2new']]; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + } + else + { + // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. + $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId); + + if ($itemEditable) + { + $toolbarButtons = [['apply', 'stage.apply'], ['save', 'stage.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')) + { + $toolbarButtons[] = ['save2new', 'stage.save2new']; + $toolbarButtons[] = ['save2copy', 'stage.save2copy']; + } + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + } + + ToolbarHelper::cancel('stage.cancel'); + ToolbarHelper::divider(); + } +} diff --git a/administrator/components/com_workflow/View/Stages/HtmlView.php b/administrator/components/com_workflow/View/Stages/HtmlView.php new file mode 100644 index 0000000000000..950ebe972ef79 --- /dev/null +++ b/administrator/components/com_workflow/View/Stages/HtmlView.php @@ -0,0 +1,196 @@ +get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->state = $this->get('State'); + $this->stages = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + $this->workflowID = $this->state->get('filter.workflow_id'); + $this->extension = $this->state->get('filter.extension'); + + WorkflowHelper::addSubmenu('stages'); + + $this->sidebar = \JHtmlSidebar::render(); + + if (!empty($this->stages)) + { + $workflow = new Workflow(['extension' => 'com_content']); + + foreach ($this->stages as $i => $item) + { + $item->condition = $workflow->getConditionName($item->condition); + } + } + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions($this->extension, 'workflow', $this->workflowID); + + $workflow = !empty($this->state->get('active_workflow', '')) ? $this->state->get('active_workflow', '') . ': ' : ''; + + ToolbarHelper::title(Text::sprintf('COM_WORKFLOW_STAGES_LIST', $this->escape($workflow)), 'address contact'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('stage.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publishList('stages.publish'); + ToolbarHelper::unpublishList('stages.unpublish'); + ToolbarHelper::makeDefault('stages.setDefault', 'COM_WORKFLOW_TOOLBAR_DEFAULT'); + } + + if ($canDo->get('core.admin')) + { + ToolbarHelper::checkin('stages.checkin', 'JTOOLBAR_CHECKIN', true); + } + + if ($this->state->get('filter.published') === '-2' && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList(Text::_('COM_WORKFLOW_ARE_YOU_SURE'), 'stages.delete'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('stages.trash'); + } + + ToolbarHelper::help('JHELP_WORKFLOW_STAGES_LIST'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since __DEPLOY_VERSION__ + */ + protected function getSortFields() + { + return array( + 'a.published' => Text::_('JSTATUS'), + 'a.title' => Text::_('JGLOBAL_TITLE'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_workflow/View/Transition/HtmlView.php b/administrator/components/com_workflow/View/Transition/HtmlView.php new file mode 100644 index 0000000000000..efbb1dc072359 --- /dev/null +++ b/administrator/components/com_workflow/View/Transition/HtmlView.php @@ -0,0 +1,171 @@ +get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->app = Factory::getApplication(); + $this->input = $this->app->input; + + // Get the Data + $this->state = $this->get('State'); + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->extension = $this->state->get('filter.extension'); + + // Get the ID of workflow + $this->workflowID = $this->input->getCmd("workflow_id"); + + // Set the toolbar + $this->addToolBar(); + + // Display the template + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $user = Factory::getUser(); + $userId = $user->id; + $isNew = empty($this->item->id); + + $canDo = StageHelper::getActions($this->extension, 'transition', $this->item->id); + + ToolbarHelper::title(empty($this->item->id) ? Text::_('COM_WORKFLOW_TRANSITION_ADD') : Text::_('COM_WORKFLOW_TRANSITION_EDIT'), 'address'); + + $toolbarButtons = []; + + if ($isNew) + { + // For new records, check the create permission. + if ($canDo->get('core.edit')) + { + $toolbarButtons = [['apply', 'transition.apply'], ['save', 'transition.save'], ['save2new', 'transition.save2new']]; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + } + else + { + // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. + $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId); + + if ($itemEditable) + { + $toolbarButtons = [['apply', 'transition.apply'], ['save', 'transition.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')) + { + $toolbarButtons[] = ['save2new', 'transition.save2new']; + $toolbarButtons[] = ['save2copy', 'transition.save2copy']; + } + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + } + + ToolbarHelper::cancel('transition.cancel'); + ToolbarHelper::divider(); + } +} diff --git a/administrator/components/com_workflow/View/Transitions/HtmlView.php b/administrator/components/com_workflow/View/Transitions/HtmlView.php new file mode 100644 index 0000000000000..fda9e50944868 --- /dev/null +++ b/administrator/components/com_workflow/View/Transitions/HtmlView.php @@ -0,0 +1,163 @@ +get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->state = $this->get('State'); + $this->transitions = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + $this->workflowID = $this->state->get('filter.workflow_id'); + $this->extension = $this->state->get('filter.extension'); + + WorkflowHelper::addSubmenu('transitions'); + + $this->sidebar = \JHtmlSidebar::render(); + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions($this->extension, 'workflow', $this->workflowID); + + $workflow = !empty($this->state->get('active_workflow', '')) ? $this->state->get('active_workflow', '') . ': ' : ''; + + ToolbarHelper::title(Text::sprintf('COM_WORKFLOW_TRANSITIONS_LIST', $this->escape($workflow)), 'address contact'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('transition.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publishList('transitions.publish'); + ToolbarHelper::unpublishList('transitions.unpublish'); + } + + if ($this->state->get('filter.published') === '-2' && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList(Text::_('COM_WORKFLOW_ARE_YOU_SURE'), 'transitions.delete'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('transitions.trash'); + } + + ToolbarHelper::help('JHELP_WORKFLOW_TRANSITIONS_LIST'); + } +} diff --git a/administrator/components/com_workflow/View/Workflow/HtmlView.php b/administrator/components/com_workflow/View/Workflow/HtmlView.php new file mode 100644 index 0000000000000..662e11404f42a --- /dev/null +++ b/administrator/components/com_workflow/View/Workflow/HtmlView.php @@ -0,0 +1,152 @@ +state = $this->get('State'); + $this->form = $this->get('Form'); + $this->item = $this->get('Item'); + $this->extension = $this->state->get('filter.extension'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + // Set the toolbar + $this->addToolBar(); + + // Display the template + parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + Factory::getApplication()->input->set('hidemainmenu', true); + + $user = Factory::getUser(); + $userId = $user->id; + $isNew = empty($this->item->id); + + $canDo = WorkflowHelper::getActions($this->extension, 'workflow', $this->item->id); + + ToolbarHelper::title(empty($this->item->id) ? Text::_('COM_WORKFLOW_WORKFLOWS_ADD') : Text::_('COM_WORKFLOW_WORKFLOWS_EDIT'), 'address'); + + $toolbarButtons = []; + + if ($isNew) + { + // For new records, check the create permission. + if ($canDo->get('core.edit')) + { + $toolbarButtons = [['apply', 'workflow.apply'], ['save', 'workflow.save'], ['save2new', 'workflow.save2new']]; + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + } + else + { + // Since it's an existing record, check the edit permission, or fall back to edit own if the owner. + $itemEditable = $canDo->get('core.edit') || ($canDo->get('core.edit.own') && $this->item->created_by == $userId); + + if ($itemEditable) + { + $toolbarButtons = [['apply', 'workflow.apply'], ['save', 'workflow.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')) + { + $toolbarButtons[] = ['save2new', 'workflow.save2new']; + } + } + + ToolbarHelper::saveGroup( + $toolbarButtons, + 'btn-success' + ); + } + + ToolbarHelper::cancel('workflow.cancel'); + } +} diff --git a/administrator/components/com_workflow/View/Workflows/HtmlView.php b/administrator/components/com_workflow/View/Workflows/HtmlView.php new file mode 100644 index 0000000000000..56f927e572aa9 --- /dev/null +++ b/administrator/components/com_workflow/View/Workflows/HtmlView.php @@ -0,0 +1,177 @@ +state = $this->get('State'); + $this->workflows = $this->get('Items'); + $this->pagination = $this->get('Pagination'); + $this->filterForm = $this->get('FilterForm'); + $this->activeFilters = $this->get('ActiveFilters'); + + // Check for errors. + if (count($errors = $this->get('Errors'))) + { + throw new \JViewGenericdataexception(implode("\n", $errors), 500); + } + + $this->extension = $this->state->get('filter.extension'); + + WorkflowHelper::addSubmenu($this->state->get('filter.extension')); + $this->sidebar = \JHtmlSidebar::render(); + + $this->addToolbar(); + + return parent::display($tpl); + } + + /** + * Add the page title and toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function addToolbar() + { + $canDo = ContentHelper::getActions($this->extension); + + ToolbarHelper::title(Text::_('COM_WORKFLOW_WORKFLOWS_LIST'), 'address contact'); + + if ($canDo->get('core.create')) + { + ToolbarHelper::addNew('workflow.add'); + } + + if ($canDo->get('core.edit.state')) + { + ToolbarHelper::publishList('workflows.publish'); + ToolbarHelper::unpublishList('workflows.unpublish'); + ToolbarHelper::makeDefault('workflows.setDefault', 'COM_WORKFLOW_TOOLBAR_DEFAULT'); + } + + if ($canDo->get('core.admin')) + { + ToolbarHelper::checkin('workflows.checkin', 'JTOOLBAR_CHECKIN', true); + } + + if ($this->state->get('filter.published') === '-2' && $canDo->get('core.delete')) + { + ToolbarHelper::deleteList(Text::_('COM_WORKFLOW_ARE_YOU_SURE'), 'workflows.delete'); + } + elseif ($canDo->get('core.edit.state')) + { + ToolbarHelper::trash('workflows.trash'); + } + + if ($canDo->get('core.admin') || $canDo->get('core.options')) + { + ToolbarHelper::preferences($this->extension); + } + + ToolbarHelper::help('JHELP_WORKFLOWS_LIST'); + } + + /** + * Returns an array of fields the table can be sorted by + * + * @return array Array containing the field name to sort by as the key and display text as value + * + * @since __DEPLOY_VERSION__ + */ + protected function getSortFields() + { + return array( + 'a.published' => Text::_('JSTATUS'), + 'a.title' => Text::_('JGLOBAL_TITLE'), + 'a.id' => Text::_('JGRID_HEADING_ID'), + ); + } +} diff --git a/administrator/components/com_workflow/access.xml b/administrator/components/com_workflow/access.xml new file mode 100644 index 0000000000000..9d46096118d78 --- /dev/null +++ b/administrator/components/com_workflow/access.xml @@ -0,0 +1,6 @@ + + +
    + +
    +
    diff --git a/administrator/components/com_workflow/forms/filter_stages.xml b/administrator/components/com_workflow/forms/filter_stages.xml new file mode 100644 index 0000000000000..5bef7f2cc0d4b --- /dev/null +++ b/administrator/components/com_workflow/forms/filter_stages.xml @@ -0,0 +1,60 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/administrator/components/com_workflow/forms/filter_transitions.xml b/administrator/components/com_workflow/forms/filter_transitions.xml new file mode 100644 index 0000000000000..c6260988909d8 --- /dev/null +++ b/administrator/components/com_workflow/forms/filter_transitions.xml @@ -0,0 +1,74 @@ + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/administrator/components/com_workflow/forms/filter_workflows.xml b/administrator/components/com_workflow/forms/filter_workflows.xml new file mode 100644 index 0000000000000..c855ff95a396e --- /dev/null +++ b/administrator/components/com_workflow/forms/filter_workflows.xml @@ -0,0 +1,50 @@ + +
    + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/administrator/components/com_workflow/forms/stage.xml b/administrator/components/com_workflow/forms/stage.xml new file mode 100644 index 0000000000000..ffade1903a4f1 --- /dev/null +++ b/administrator/components/com_workflow/forms/stage.xml @@ -0,0 +1,74 @@ + +
    +
    + + + + +
    + +
    + + + + + +
    + +
    + + +
    +
    diff --git a/administrator/components/com_workflow/forms/transition.xml b/administrator/components/com_workflow/forms/transition.xml new file mode 100644 index 0000000000000..9f9bd8375ae5a --- /dev/null +++ b/administrator/components/com_workflow/forms/transition.xml @@ -0,0 +1,77 @@ + +
    +
    + + + + + + + +
    + +
    + +
    + +
    + + +
    +
    diff --git a/administrator/components/com_workflow/forms/workflow.xml b/administrator/components/com_workflow/forms/workflow.xml new file mode 100644 index 0000000000000..d14069c10ea15 --- /dev/null +++ b/administrator/components/com_workflow/forms/workflow.xml @@ -0,0 +1,82 @@ + +
    +
    + + + + +
    + +
    + + + + + + + +
    + +
    + + +
    +
    diff --git a/administrator/components/com_workflow/services/provider.php b/administrator/components/com_workflow/services/provider.php new file mode 100644 index 0000000000000..14287b8f52564 --- /dev/null +++ b/administrator/components/com_workflow/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Workflow')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Workflow')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/components/com_workflow/tmpl/stage/edit.php b/administrator/components/com_workflow/tmpl/stage/edit.php new file mode 100644 index 0000000000000..cc781e83f1079 --- /dev/null +++ b/administrator/components/com_workflow/tmpl/stage/edit.php @@ -0,0 +1,62 @@ + 0)); + +$app = Factory::getApplication(); +$input = $app->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' : ''; + +?> + +
    + + + + 'details')); ?> + + +
    +
    + form->renderField('condition'); ?> + form->getInput('description'); ?> +
    +
    +
    +
    +
    + form->renderField('published'); ?> + form->renderField('default'); ?> +
    +
    +
    +
    +
    + + + + + form->getInput('workflow_id'); ?> + + +
    diff --git a/administrator/components/com_workflow/tmpl/stages/default.php b/administrator/components/com_workflow/tmpl/stages/default.php new file mode 100644 index 0000000000000..3abd99c493d08 --- /dev/null +++ b/administrator/components/com_workflow/tmpl/stages/default.php @@ -0,0 +1,151 @@ +id; + +$listOrder = $this->escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrderingUrl = ''; + +$saveOrder = ($listOrder == 's.ordering'); + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_workflow&task=stages.saveOrderAjax&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} +?> +
    +
    +
    + sidebar; ?> +
    +
    +
    + $this)); + ?> + stages)) : ?> +
    + +
    + + + + + + + + + + + + + + + stages as $i => $item): + $edit = Route::_('index.php?option=com_workflow&task=stage.edit&id=' . $item->id . '&workflow_id=' . (int) $this->workflowID . '&extension=' . $this->extension); + + $canEdit = $user->authorise('core.edit', $this->extension . '.stage.' . $item->id); + // @TODO set proper checkin fields + $canCheckin = true || $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.stage', $this->extension . '.stage.' . $item->id) && $canCheckin; + ?> + + + + + + + + + + + +
    + + + + + + + + + + + + + +
    + + + + + + + + id); ?> + +
    + published, $i, 'stages.', $canChange); ?> +
    +
    + default, $i, 'stages.', $canChange); ?> + + + '; ?> + + escape(Text::_($item->title)); ?> + + + escape(Text::_($item->title)); ?> + + + condition); ?> + + id; ?> +
    + + pagination->getListFooter(); ?> + + + + + + + +
    +
    +
    diff --git a/administrator/components/com_workflow/tmpl/transition/edit.php b/administrator/components/com_workflow/tmpl/transition/edit.php new file mode 100644 index 0000000000000..f4688b0d73237 --- /dev/null +++ b/administrator/components/com_workflow/tmpl/transition/edit.php @@ -0,0 +1,84 @@ + 0 )); + +// In case of modal +$isModal = $this->input->get('layout') == 'modal' ? true : false; +$layout = $isModal ? 'modal' : 'edit'; +$tmpl = $isModal || $this->input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=component' : ''; + +?> + + + + + +
    + 'details')); ?> + + +
    +
    +
    +
    + form->getLabel('from_stage_id'); ?> +
    +
    + form->getInput('from_stage_id'); ?> +
    +
    +
    +
    + form->getLabel('to_stage_id'); ?> +
    +
    + form->getInput('to_stage_id'); ?> +
    +
    + form->getInput('description'); ?> +
    +
    +
    +
    +
    +
    +
    + form->getLabel('published'); ?> +
    +
    + form->getInput('published'); ?> +
    +
    +
    +
    +
    +
    +
    + + + + form->getInput('rules'); ?> + + + +
    + form->getInput('workflow_id'); ?> + + +
    diff --git a/administrator/components/com_workflow/tmpl/transitions/default.php b/administrator/components/com_workflow/tmpl/transitions/default.php new file mode 100644 index 0000000000000..97bfd3f5072a9 --- /dev/null +++ b/administrator/components/com_workflow/tmpl/transitions/default.php @@ -0,0 +1,152 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); +$saveOrderingUrl = ''; + +$saveOrder = ($listOrder == 't.ordering'); + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_workflow&task=transitions.saveOrderAjax&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} +?> +
    +
    +
    + sidebar; ?> +
    +
    +
    + $this)); + ?> + transitions)) : ?> +
    + +
    + + + + + + + + + + + + + + + transitions as $i => $item): + $edit = Route::_('index.php?option=com_workflow&task=transition.edit&id=' . $item->id . '&workflow_id=' . (int) $this->workflowID . '&extension=' . $this->extension); + + $canEdit = $user->authorise('core.edit', $this->extension . '.transition.' . $item->id); + // @TODO set proper checkin fields + $canCheckin = true || $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canChange = $user->authorise('core.edit.state', $this->extension . '.transition.' . $item->id) && $canCheckin; ?> + + + + + + + + + + + +
    + + + + + + + + + + + + + +
    + + + + + + + + id); ?> + +
    + published, $i, 'transitions.', $canChange); ?> +
    +
    + + '; ?> + + title; ?> + + + title; ?> + + + from_stage_id < 0) : ?> + + + escape(Text::_($item->from_stage)); ?> + + + escape(Text::_($item->to_stage)); ?> + + id; ?> +
    + + pagination->getListFooter(); ?> + + + + + + +
    +
    +
    diff --git a/administrator/components/com_workflow/tmpl/workflow/edit.php b/administrator/components/com_workflow/tmpl/workflow/edit.php new file mode 100644 index 0000000000000..05923fa0e5394 --- /dev/null +++ b/administrator/components/com_workflow/tmpl/workflow/edit.php @@ -0,0 +1,80 @@ + 0 )); + +$app = Factory::getApplication(); +$input = $app->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' : ''; + +?> + + + + + +
    + 'general')); ?> + + +
    +
    + form->renderField('description'); ?> +
    +
    +
    +
    +
    +
    +
    + form->getLabel('published'); ?> +
    +
    + form->getInput('published'); ?> +
    +
    +
    +
    + form->getLabel('default'); ?> +
    +
    + form->getInput('default'); ?> +
    +
    +
    +
    +
    +
    +
    + + + + form->getInput('rules'); ?> + + + +
    + form->getInput('extension'); ?> + + +
    diff --git a/administrator/components/com_workflow/tmpl/workflows/default.php b/administrator/components/com_workflow/tmpl/workflows/default.php new file mode 100644 index 0000000000000..cf09dac884771 --- /dev/null +++ b/administrator/components/com_workflow/tmpl/workflows/default.php @@ -0,0 +1,172 @@ +escape($this->state->get('list.ordering')); +$listDirn = $this->escape($this->state->get('list.direction')); + +$saveOrder = $listOrder == 'w.ordering'; + +$orderingColumn = 'created'; + +if (strpos($listOrder, 'modified') !== false) +{ + $orderingColumn = 'modified'; +} + +if ($saveOrder) +{ + $saveOrderingUrl = 'index.php?option=com_workflow&task=workflows.saveOrderAjax&tmpl=component&' . Session::getFormToken() . '=1'; + HTMLHelper::_('draggablelist.draggable'); +} + +$extension = $this->escape($this->state->get('filter.extension')); + +$user = Factory::getUser(); +$userId = $user->id; +?> +
    +
    +
    + sidebar; ?> +
    +
    +
    + $this)); + ?> + workflows)) : ?> +
    + +
    + + + + + + + + + + + + + + + class="js-draggable" data-url="" data-direction="" data-nested="false"> + workflows as $i => $item): + $states = Route::_('index.php?option=com_workflow&view=stages&workflow_id=' . $item->id . '&extension=' . $extension); + $transitions = Route::_('index.php?option=com_workflow&view=transitions&workflow_id=' . $item->id . '&extension=' . $extension); + $edit = Route::_('index.php?option=com_workflow&task=workflow.edit&id=' . $item->id); + + $canEdit = $user->authorise('core.edit', $extension . '.workflow.' . $item->id); + // @TODO set proper checkin fields + $canCheckin = true || $user->authorise('core.admin', 'com_checkin') || $item->checked_out == $userId || $item->checked_out == 0; + $canEditOwn = $user->authorise('core.edit.own', $extension . '.workflow.' . $item->id) && $item->created_by == $userId; + $canChange = $user->authorise('core.edit.state', $extension . '.workflow.' . $item->id) && $canCheckin; + ?> + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + id); ?> + +
    + published, $i, 'workflows.', $canChange); ?> +
    +
    + + '; ?> + + title; ?> + +
    description; ?>
    + + title; ?> +
    description; ?>
    + +
    + default, $i, 'workflows.', $canChange); ?> + + + count_states; ?> + + + count_transitions; ?> + + id; ?> +
    + + pagination->getListFooter(); ?> + + + + + + +
    +
    +
    +
    diff --git a/administrator/components/com_workflow/workflow.xml b/administrator/components/com_workflow/workflow.xml new file mode 100644 index 0000000000000..8209f5bc033b5 --- /dev/null +++ b/administrator/components/com_workflow/workflow.xml @@ -0,0 +1,35 @@ + + + com_workflow + Joomla! Project + June 2017 + (C) 2005 - 2017 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + 4.0.0 + COM_WORKFLOW_XML_DESCRIPTION + Joomla\Component\Workflow + + COM_WORKFLOW + + access.xml + config.xml + workflow.php + dispacher.php + Controller + Field + forms + Helper + helpers + Model + Table + tmpl + View + + + language/en-GB.com_workflow.ini + language/en-GB.com_workflow.sys.ini + + + \ No newline at end of file diff --git a/administrator/components/com_wrapper/services/provider.php b/administrator/components/com_wrapper/services/provider.php new file mode 100644 index 0000000000000..f9b9d2bb07f1b --- /dev/null +++ b/administrator/components/com_wrapper/services/provider.php @@ -0,0 +1,52 @@ +registerServiceProvider(new MVCFactoryFactory('\\Joomla\\Component\\Wrapper')); + $container->registerServiceProvider(new DispatcherFactory('\\Joomla\\Component\\Wrapper')); + $container->set( + ComponentInterface::class, + function (Container $container) + { + $component = new MVCComponent($container->get(DispatcherFactoryInterface::class)); + $component->setMvcFactoryFactory($container->get(MVCFactoryFactoryInterface::class)); + + return $component; + } + ); + } +}; diff --git a/administrator/help/en-GB/toc.json b/administrator/help/en-GB/toc.json index b2cf6954bc995..3012f80984759 100644 --- a/administrator/help/en-GB/toc.json +++ b/administrator/help/en-GB/toc.json @@ -1 +1 @@ -{ "COMPONENTS_ASSOCIATIONS": "COMPONENTS_ASSOCIATIONS", "COMPONENTS_ASSOCIATIONS_EDIT": "COMPONENTS_ASSOCIATIONS_EDIT", "COMPONENTS_BANNERS_BANNERS": "COMPONENTS_BANNERS_BANNERS", "COMPONENTS_BANNERS_BANNERS_EDIT": "COMPONENTS_BANNERS_BANNERS_EDIT", "COMPONENTS_BANNERS_CATEGORIES": "COMPONENTS_BANNERS_CATEGORIES", "COMPONENTS_BANNERS_CATEGORY_EDIT": "COMPONENTS_BANNERS_CATEGORIES_EDIT", "COMPONENTS_BANNERS_CLIENTS": "COMPONENTS_BANNERS_CLIENTS", "COMPONENTS_BANNERS_CLIENTS_EDIT": "COMPONENTS_BANNERS_CLIENTS_EDIT", "COMPONENTS_BANNERS_TRACKS": "COMPONENTS_BANNERS_TRACKS", "COMPONENTS_CONTACTS_CONTACTS": "COMPONENTS_CONTACTS_CONTACTS", "COMPONENTS_CONTACTS_CONTACTS_EDIT": "COMPONENTS_CONTACTS_CONTACTS_EDIT", "COMPONENTS_CONTACT_CATEGORIES": "COMPONENTS_CONTACT_CATEGORIES", "COMPONENTS_CONTACT_CATEGORY_EDIT": "COMPONENTS_CONTACT_CATEGORIES_EDIT", "COMPONENTS_CONTENT_CATEGORIES": "COMPONENTS_CONTENT_CATEGORIES", "COMPONENTS_CONTENT_CATEGORY_EDIT": "COMPONENTS_CONTENT_CATEGORIES_EDIT", "COMPONENTS_FIELDS_FIELDS": "COMPONENTS_FIELDS_FIELDS", "COMPONENTS_FIELDS_FIELDS_EDIT": "COMPONENTS_FIELDS_FIELDS_EDIT", "COMPONENTS_FIELDS_FIELD_GROUPS": "COMPONENTS_FIELDS_FIELD_GROUPS", "COMPONENTS_FIELDS_FIELD_GROUPS_EDIT": "COMPONENTS_FIELDS_FIELD_GROUPS_EDIT", "COMPONENTS_FINDER_MANAGE_CONTENT_MAPS": "COMPONENTS_FINDER_MANAGE_CONTENT_MAPS", "COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT": "COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT", "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS": "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS", "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT": "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT", "COMPONENTS_JOOMLA_UPDATE": "COMPONENTS_JOOMLA_UPDATE", "COMPONENTS_MESSAGING_INBOX": "COMPONENTS_MESSAGING_INBOX", "COMPONENTS_MESSAGING_READ": "COMPONENTS_MESSAGING_READ", "COMPONENTS_MESSAGING_WRITE": "COMPONENTS_MESSAGING_WRITE", "COMPONENTS_NEWSFEEDS_CATEGORIES": "COMPONENTS_NEWSFEEDS_CATEGORIES", "COMPONENTS_NEWSFEEDS_CATEGORY_EDIT": "COMPONENTS_NEWSFEEDS_CATEGORIES_EDIT", "COMPONENTS_NEWSFEEDS_FEEDS": "COMPONENTS_NEWSFEEDS_FEEDS", "COMPONENTS_NEWSFEEDS_FEEDS_EDIT": "COMPONENTS_NEWSFEEDS_FEEDS_EDIT", "COMPONENTS_POST_INSTALLATION_MESSAGES": "COMPONENTS_POST_INSTALLATION_MESSAGES", "COMPONENTS_REDIRECT_MANAGER": "COMPONENTS_REDIRECT_MANAGER", "COMPONENTS_REDIRECT_MANAGER_EDIT": "COMPONENTS_REDIRECT_MANAGER_EDIT", "COMPONENTS_SEARCH": "COMPONENTS_SEARCH", "COMPONENTS_TAGS_MANAGER": "COMPONENTS_TAGS_MANAGER", "COMPONENTS_TAGS_MANAGER_EDIT": "COMPONENTS_TAGS_MANAGER_EDIT", "COMPONENTS_WEBLINKS_CATEGORIES": "COMPONENTS_WEBLINKS_CATEGORIES", "COMPONENTS_WEBLINKS_CATEGORY_EDIT": "COMPONENTS_WEBLINKS_CATEGORIES_EDIT", "COMPONENTS_WEBLINKS_LINKS": "COMPONENTS_WEBLINKS_LINKS", "COMPONENTS_WEBLINKS_LINKS_EDIT": "COMPONENTS_WEBLINKS_LINKS_EDIT", "CONTENT_ARTICLE_MANAGER": "CONTENT_ARTICLE_MANAGER", "CONTENT_ARTICLE_MANAGER_EDIT": "CONTENT_ARTICLE_MANAGER_EDIT", "CONTENT_FEATURED_ARTICLES": "CONTENT_FEATURED_ARTICLES", "CONTENT_MEDIA_MANAGER": "CONTENT_MEDIA_MANAGER", "EXTENSIONS_EXTENSION_MANAGER_DATABASE": "EXTENSIONS_EXTENSION_MANAGER_DATABASE", "EXTENSIONS_EXTENSION_MANAGER_DISCOVER": "EXTENSIONS_EXTENSION_MANAGER_DISCOVER", "EXTENSIONS_EXTENSION_MANAGER_INSTALL": "EXTENSIONS_EXTENSION_MANAGER_INSTALL", "EXTENSIONS_EXTENSION_MANAGER_MANAGE": "EXTENSIONS_EXTENSION_MANAGER_MANAGE", "EXTENSIONS_EXTENSION_MANAGER_UPDATE": "EXTENSIONS_EXTENSION_MANAGER_UPDATE", "EXTENSIONS_EXTENSION_MANAGER_WARNINGS": "EXTENSIONS_EXTENSION_MANAGER_WARNINGS", "EXTENSIONS_LANGUAGE_MANAGER_CONTENT": "EXTENSIONS_LANGUAGE_MANAGER_CONTENT", "EXTENSIONS_LANGUAGE_MANAGER_EDIT": "EXTENSIONS_LANGUAGE_MANAGER_EDIT", "EXTENSIONS_LANGUAGE_MANAGER_INSTALLED": "EXTENSIONS_LANGUAGE_MANAGER_INSTALLED", "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES": "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES", "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT": "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT", "EXTENSIONS_MODULE_MANAGER": "EXTENSIONS_MODULE_MANAGER", "EXTENSIONS_MODULE_MANAGER_EDIT": "EXTENSIONS_MODULE_MANAGER_EDIT", "EXTENSIONS_PLUGIN_MANAGER": "EXTENSIONS_PLUGIN_MANAGER", "EXTENSIONS_PLUGIN_MANAGER_EDIT": "EXTENSIONS_PLUGIN_MANAGER_EDIT", "EXTENSIONS_TEMPLATE_MANAGER_STYLES": "EXTENSIONS_TEMPLATE_MANAGER_STYLES", "EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT": "EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT", "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES": "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES", "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT": "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT", "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE": "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE", "MENUS_MENU_ITEM_MANAGER": "MENUS_MENU_ITEM_MANAGER", "MENUS_MENU_ITEM_MANAGER_EDIT": "MENUS_MENU_ITEM_MANAGER_EDIT", "MENUS_MENU_MANAGER": "MENUS_MENU_MANAGER", "MENUS_MENU_MANAGER_EDIT": "MENUS_MENU_MANAGER_EDIT", "SITE_GLOBAL_CONFIGURATION": "SITE_GLOBAL_CONFIGURATION", "SITE_MAINTENANCE_CLEAR_CACHE": "SITE_MAINTENANCE_CLEAR_CACHE", "SITE_MAINTENANCE_GLOBAL_CHECK-IN": "SITE_MAINTENANCE_GLOBAL_CHECK-IN", "SITE_MAINTENANCE_PURGE_EXPIRED_CACHE": "SITE_MAINTENANCE_PURGE_EXPIRED_CACHE", "SITE_SYSTEM_INFORMATION": "SITE_SYSTEM_INFORMATION", "START_HERE": "START_HERE", "USERS_ACCESS_LEVELS": "USERS_ACCESS_LEVELS", "USERS_ACCESS_LEVELS_EDIT": "USERS_ACCESS_LEVELS_EDIT", "USERS_DEBUG_USERS": "USERS_DEBUG_USER", "USERS_GROUPS": "USERS_GROUPS", "USERS_GROUPS_EDIT": "USERS_GROUPS_EDIT", "USERS_MASS_MAIL_USERS": "USERS_MASS_MAIL_USERS", "USERS_USER_MANAGER": "USERS_USER_MANAGER", "USERS_USER_MANAGER_EDIT": "USERS_USER_MANAGER_EDIT", "USERS_USER_NOTES": "USERS_USER_NOTES", "USERS_USER_NOTES_EDIT": "USERS_USER_NOTES_EDIT" } \ No newline at end of file +{ "COMPONENTS_ASSOCIATIONS": "COMPONENTS_ASSOCIATIONS", "COMPONENTS_ASSOCIATIONS_EDIT": "COMPONENTS_ASSOCIATIONS_EDIT", "COMPONENTS_BANNERS_BANNERS": "COMPONENTS_BANNERS_BANNERS", "COMPONENTS_BANNERS_BANNERS_EDIT": "COMPONENTS_BANNERS_BANNERS_EDIT", "COMPONENTS_BANNERS_CATEGORIES": "COMPONENTS_BANNERS_CATEGORIES", "COMPONENTS_BANNERS_CATEGORY_EDIT": "COMPONENTS_BANNERS_CATEGORIES_EDIT", "COMPONENTS_BANNERS_CLIENTS": "COMPONENTS_BANNERS_CLIENTS", "COMPONENTS_BANNERS_CLIENTS_EDIT": "COMPONENTS_BANNERS_CLIENTS_EDIT", "COMPONENTS_BANNERS_TRACKS": "COMPONENTS_BANNERS_TRACKS", "COMPONENTS_CONTACTS_CONTACTS": "COMPONENTS_CONTACTS_CONTACTS", "COMPONENTS_CONTACTS_CONTACTS_EDIT": "COMPONENTS_CONTACTS_CONTACTS_EDIT", "COMPONENTS_CONTACT_CATEGORIES": "COMPONENTS_CONTACT_CATEGORIES", "COMPONENTS_CONTACT_CATEGORY_EDIT": "COMPONENTS_CONTACT_CATEGORIES_EDIT", "COMPONENTS_CONTENT_CATEGORIES": "COMPONENTS_CONTENT_CATEGORIES", "COMPONENTS_CONTENT_CATEGORY_EDIT": "COMPONENTS_CONTENT_CATEGORIES_EDIT", "COMPONENTS_FIELDS_FIELDS": "COMPONENTS_FIELDS_FIELDS", "COMPONENTS_FIELDS_FIELDS_EDIT": "COMPONENTS_FIELDS_FIELDS_EDIT", "COMPONENTS_FIELDS_FIELD_GROUPS": "COMPONENTS_FIELDS_FIELD_GROUPS", "COMPONENTS_FIELDS_FIELD_GROUPS_EDIT": "COMPONENTS_FIELDS_FIELD_GROUPS_EDIT", "COMPONENTS_FINDER_MANAGE_CONTENT_MAPS": "COMPONENTS_FINDER_MANAGE_CONTENT_MAPS", "COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT": "COMPONENTS_FINDER_MANAGE_INDEXED_CONTENT", "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS": "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS", "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT": "COMPONENTS_FINDER_MANAGE_SEARCH_FILTERS_EDIT", "COMPONENTS_JOOMLA_UPDATE": "COMPONENTS_JOOMLA_UPDATE", "COMPONENTS_MESSAGING_INBOX": "COMPONENTS_MESSAGING_INBOX", "COMPONENTS_MESSAGING_READ": "COMPONENTS_MESSAGING_READ", "COMPONENTS_MESSAGING_WRITE": "COMPONENTS_MESSAGING_WRITE", "COMPONENTS_NEWSFEEDS_CATEGORIES": "COMPONENTS_NEWSFEEDS_CATEGORIES", "COMPONENTS_NEWSFEEDS_CATEGORY_EDIT": "COMPONENTS_NEWSFEEDS_CATEGORIES_EDIT", "COMPONENTS_NEWSFEEDS_FEEDS": "COMPONENTS_NEWSFEEDS_FEEDS", "COMPONENTS_NEWSFEEDS_FEEDS_EDIT": "COMPONENTS_NEWSFEEDS_FEEDS_EDIT", "COMPONENTS_POST_INSTALLATION_MESSAGES": "COMPONENTS_POST_INSTALLATION_MESSAGES", "COMPONENTS_REDIRECT_MANAGER": "COMPONENTS_REDIRECT_MANAGER", "COMPONENTS_REDIRECT_MANAGER_EDIT": "COMPONENTS_REDIRECT_MANAGER_EDIT", "COMPONENTS_SEARCH": "COMPONENTS_SEARCH", "COMPONENTS_TAGS_MANAGER": "COMPONENTS_TAGS_MANAGER", "COMPONENTS_TAGS_MANAGER_EDIT": "COMPONENTS_TAGS_MANAGER_EDIT", "COMPONENTS_WEBLINKS_CATEGORIES": "COMPONENTS_WEBLINKS_CATEGORIES", "COMPONENTS_WEBLINKS_CATEGORY_EDIT": "COMPONENTS_WEBLINKS_CATEGORIES_EDIT", "COMPONENTS_WEBLINKS_LINKS": "COMPONENTS_WEBLINKS_LINKS", "COMPONENTS_WEBLINKS_LINKS_EDIT": "COMPONENTS_WEBLINKS_LINKS_EDIT", "CONTENT_ARTICLE_MANAGER": "CONTENT_ARTICLE_MANAGER", "CONTENT_ARTICLE_MANAGER_EDIT": "CONTENT_ARTICLE_MANAGER_EDIT", "CONTENT_FEATURED_ARTICLES": "CONTENT_FEATURED_ARTICLES", "CONTENT_MEDIA_MANAGER": "CONTENT_MEDIA_MANAGER", "EXTENSIONS_EXTENSION_MANAGER_DATABASE": "EXTENSIONS_EXTENSION_MANAGER_DATABASE", "EXTENSIONS_EXTENSION_MANAGER_DISCOVER": "EXTENSIONS_EXTENSION_MANAGER_DISCOVER", "EXTENSIONS_EXTENSION_MANAGER_INSTALL": "EXTENSIONS_EXTENSION_MANAGER_INSTALL", "EXTENSIONS_EXTENSION_MANAGER_MANAGE": "EXTENSIONS_EXTENSION_MANAGER_MANAGE", "EXTENSIONS_EXTENSION_MANAGER_UPDATE": "EXTENSIONS_EXTENSION_MANAGER_UPDATE", "EXTENSIONS_EXTENSION_MANAGER_WARNINGS": "EXTENSIONS_EXTENSION_MANAGER_WARNINGS", "EXTENSIONS_LANGUAGE_MANAGER_CONTENT": "EXTENSIONS_LANGUAGE_MANAGER_CONTENT", "EXTENSIONS_LANGUAGE_MANAGER_EDIT": "EXTENSIONS_LANGUAGE_MANAGER_EDIT", "EXTENSIONS_LANGUAGE_MANAGER_INSTALLED": "EXTENSIONS_LANGUAGE_MANAGER_INSTALLED", "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES": "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES", "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT": "EXTENSIONS_LANGUAGE_MANAGER_OVERRIDES_EDIT", "EXTENSIONS_MODULE_MANAGER": "EXTENSIONS_MODULE_MANAGER", "EXTENSIONS_MODULE_MANAGER_EDIT": "EXTENSIONS_MODULE_MANAGER_EDIT", "EXTENSIONS_PLUGIN_MANAGER": "EXTENSIONS_PLUGIN_MANAGER", "EXTENSIONS_PLUGIN_MANAGER_EDIT": "EXTENSIONS_PLUGIN_MANAGER_EDIT", "EXTENSIONS_TEMPLATE_MANAGER_STYLES": "EXTENSIONS_TEMPLATE_MANAGER_STYLES", "EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT": "EXTENSIONS_TEMPLATE_MANAGER_STYLES_EDIT", "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES": "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES", "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT": "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT", "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE": "EXTENSIONS_TEMPLATE_MANAGER_TEMPLATES_EDIT_SOURCE", "MENUS_MENU_ITEM_MANAGER": "MENUS_MENU_ITEM_MANAGER", "MENUS_MENU_ITEM_MANAGER_EDIT": "MENUS_MENU_ITEM_MANAGER_EDIT", "MENUS_MENU_MANAGER": "MENUS_MENU_MANAGER", "MENUS_MENU_MANAGER_EDIT": "MENUS_MENU_MANAGER_EDIT", "SITE_GLOBAL_CONFIGURATION": "SITE_GLOBAL_CONFIGURATION", "SITE_MAINTENANCE_CLEAR_CACHE": "SITE_MAINTENANCE_CLEAR_CACHE", "SITE_MAINTENANCE_GLOBAL_CHECK-IN": "SITE_MAINTENANCE_GLOBAL_CHECK-IN", "SITE_MAINTENANCE_PURGE_EXPIRED_CACHE": "SITE_MAINTENANCE_PURGE_EXPIRED_CACHE", "SITE_SYSTEM_INFORMATION": "SITE_SYSTEM_INFORMATION", "START_HERE": "START_HERE", "USERS_ACCESS_LEVELS": "USERS_ACCESS_LEVELS", "USERS_ACCESS_LEVELS_EDIT": "USERS_ACCESS_LEVELS_EDIT", "USERS_DEBUG_USERS": "USERS_DEBUG_USER", "USERS_GROUPS": "USERS_GROUPS", "USERS_GROUPS_EDIT": "USERS_GROUPS_EDIT", "USERS_MASS_MAIL_USERS": "USERS_MASS_MAIL_USERS", "USERS_USER_MANAGER": "USERS_USER_MANAGER", "USERS_USER_MANAGER_EDIT": "USERS_USER_MANAGER_EDIT", "USERS_USER_NOTES": "USERS_USER_NOTES", "USERS_USER_NOTES_EDIT": "USERS_USER_NOTES_EDIT" } diff --git a/administrator/includes/app.php b/administrator/includes/app.php new file mode 100644 index 0000000000000..ea56b1e27f8af --- /dev/null +++ b/administrator/includes/app.php @@ -0,0 +1,63 @@ +setStart($startTime, $startMem)->mark('afterLoad') : null; + +// Boot the DI container +$container = \Joomla\CMS\Factory::getContainer(); + +/* + * Alias the session service keys to the web session service as that is the primary session backend for this application + * + * In addition to aliasing "common" service keys, we also create aliases for the PHP classes to ensure autowiring objects + * is supported. This includes aliases for aliased class names, and the keys for alised class names should be considered + * deprecated to be removed when the class name alias is removed as well. + */ +$container->alias('session.web', 'session.web.administrator') + ->alias('session', 'session.web.administrator') + ->alias('JSession', 'session.web.administrator') + ->alias(\Joomla\CMS\Session\Session::class, 'session.web.administrator') + ->alias(\Joomla\Session\Session::class, 'session.web.administrator') + ->alias(\Joomla\Session\SessionInterface::class, 'session.web.administrator'); + +// Instantiate the application. +$app = $container->get(\Joomla\CMS\Application\AdministratorApplication::class); + +// Set the application as global app +\Joomla\CMS\Factory::$application = $app; + +// Execute the application. +$app->execute(); diff --git a/administrator/includes/defines.php b/administrator/includes/defines.php index cf0c11a6c1566..1e2eb7b80a31a 100644 --- a/administrator/includes/defines.php +++ b/administrator/includes/defines.php @@ -21,5 +21,5 @@ define('JPATH_PLUGINS', JPATH_ROOT . DIRECTORY_SEPARATOR . 'plugins'); define('JPATH_INSTALLATION', JPATH_ROOT . DIRECTORY_SEPARATOR . 'installation'); define('JPATH_THEMES', JPATH_BASE . DIRECTORY_SEPARATOR . 'templates'); -define('JPATH_CACHE', JPATH_BASE . DIRECTORY_SEPARATOR . 'cache'); +define('JPATH_CACHE', JPATH_ADMINISTRATOR . DIRECTORY_SEPARATOR . 'cache'); define('JPATH_MANIFESTS', JPATH_ADMINISTRATOR . DIRECTORY_SEPARATOR . 'manifests'); diff --git a/administrator/includes/framework.php b/administrator/includes/framework.php index 27b22a8bc76e0..b8194d2bf57e7 100644 --- a/administrator/includes/framework.php +++ b/administrator/includes/framework.php @@ -8,26 +8,13 @@ defined('_JEXEC') or die; -// Joomla system checks. -@ini_set('magic_quotes_runtime', 0); - // System includes -require_once JPATH_LIBRARIES . '/import.legacy.php'; - -// Bootstrap the CMS libraries. -require_once JPATH_LIBRARIES . '/cms.php'; - -// Set system error handling -JError::setErrorHandling(E_NOTICE, 'message'); -JError::setErrorHandling(E_WARNING, 'message'); -JError::setErrorHandling(E_ERROR, 'message', array('JError', 'customErrorPage')); - -$version = new JVersion; +require_once JPATH_LIBRARIES . '/bootstrap.php'; // Installation check, and check on removal of the install directory. if (!file_exists(JPATH_CONFIGURATION . '/configuration.php') || (filesize(JPATH_CONFIGURATION . '/configuration.php') < 10) - || (file_exists(JPATH_INSTALLATION . '/index.php') && (false === $version->isInDevelopmentState()))) + || (file_exists(JPATH_INSTALLATION . '/index.php') && (false === (new JVersion)->isInDevelopmentState()))) { if (file_exists(JPATH_INSTALLATION . '/index.php')) { diff --git a/administrator/includes/helper.php b/administrator/includes/helper.php deleted file mode 100644 index 1a7bb7d71a679..0000000000000 --- a/administrator/includes/helper.php +++ /dev/null @@ -1,50 +0,0 @@ -input->get('option')); - - $app->loadIdentity(); - $user = $app->getIdentity(); - - if ($user->get('guest') || !$user->authorise('core.login.admin')) - { - $option = 'com_login'; - } - - if (empty($option)) - { - $option = 'com_cpanel'; - } - - $app->input->set('option', $option); - - return $option; - } -} diff --git a/administrator/includes/subtoolbar.php b/administrator/includes/subtoolbar.php deleted file mode 100644 index 03833f6d533b5..0000000000000 --- a/administrator/includes/subtoolbar.php +++ /dev/null @@ -1,213 +0,0 @@ - $label, 'name' => $name, 'options' => $options, 'noDefault' => $noDefault); - } - - /** - * Returns an array of all filters - * - * @return array - * - * @since 3.0 - * @deprecated 4.0 Use JHtmlSidebar::getFilters() instead. - */ - public static function getFilters() - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHtmlSidebar::getFilters() instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - return self::$filters; - } - - /** - * Set value for the action attribute of the filter form - * - * @param string $action Value for the action attribute of the form - * - * @return void - * - * @since 3.0 - * @deprecated 4.0 Use JHtmlSidebar::setAction() instead. - */ - public static function setAction($action) - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHtmlSidebar::setAction() instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - self::$action = $action; - } - - /** - * Get value for the action attribute of the filter form - * - * @return string Value for the action attribute of the form - * - * @since 3.0 - * @deprecated 4.0 Use JHtmlSidebar::getAction() instead. - */ - public static function getAction() - { - try - { - JLog::add( - sprintf('%s() is deprecated. Use JHtmlSidebar::getAction() instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - return self::$action; - } -} diff --git a/administrator/includes/toolbar.php b/administrator/includes/toolbar.php deleted file mode 100644 index c7c5e84310733..0000000000000 --- a/administrator/includes/toolbar.php +++ /dev/null @@ -1,655 +0,0 @@ -render(array('title' => $title, 'icon' => $icon)); - - $app = JFactory::getApplication(); - $app->JComponentTitle = $html; - JFactory::getDocument()->setTitle(strip_tags($title) . ' - ' . $app->get('sitename') . ' - ' . JText::_('JADMINISTRATION')); - } - - /** - * Writes a spacer cell. - * - * @param string $width The width for the cell - * - * @return void - * - * @since 1.5 - */ - public static function spacer($width = '') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a spacer. - $bar->appendButton('Separator', 'spacer', $width); - } - - /** - * Writes a divider between menu buttons - * - * @return void - * - * @since 1.5 - */ - public static function divider() - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a divider. - $bar->appendButton('Separator', 'divider'); - } - - /** - * Writes a custom option and task button for the button bar. - * - * @param string $task The task to perform (picked up by the switch($task) blocks). - * @param string $icon The image to display. - * @param string $iconOver The image to display when moused over. - * @param string $alt The alt text for the icon image. - * @param bool $listSelect True if required to check that a standard list item is checked. - * - * @return void - * - * @since 1.5 - */ - public static function custom($task = '', $icon = '', $iconOver = '', $alt = '', $listSelect = true) - { - $bar = JToolbar::getInstance('toolbar'); - - // Strip extension. - $icon = preg_replace('#\.[^.]*$#', '', $icon); - - // Add a standard button. - $bar->appendButton('Standard', $icon, $alt, $task, $listSelect); - } - - /** - * Writes a preview button for a given option (opens a popup window). - * - * @param string $url The name of the popup file (excluding the file extension) - * @param bool $updateEditors Unused - * - * @return void - * - * @since 1.5 - */ - public static function preview($url = '', $updateEditors = false) - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a preview button. - $bar->appendButton('Popup', 'preview', 'Preview', $url . '&task=preview'); - } - - /** - * Writes a preview button for a given option (opens a popup window). - * - * @param string $ref The name of the popup file (excluding the file extension for an xml file). - * @param bool $com Use the help file in the component directory. - * @param string $override Use this URL instead of any other - * @param string $component Name of component to get Help (null for current component) - * - * @return void - * - * @since 1.5 - */ - public static function help($ref, $com = false, $override = null, $component = null) - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a help button. - $bar->appendButton('Help', $ref, $com, $override, $component); - } - - /** - * Writes a cancel button that will go back to the previous page without doing - * any other operation. - * - * @param string $alt Alternative text. - * @param string $href URL of the href attribute. - * - * @return void - * - * @since 1.5 - */ - public static function back($alt = 'JTOOLBAR_BACK', $href = 'javascript:history.back();') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a back button. - $bar->appendButton('Link', 'back', $alt, $href); - } - - /** - * Creates a button to redirect to a link - * - * @param string $url The link url - * @param string $text Button text - * @param string $name Name to be used as apart of the id - * - * @return void - * - * @since 3.5 - */ - public static function link($url, $text, $name = 'link') - { - $bar = JToolbar::getInstance('toolbar'); - - $bar->appendButton('Link', $name, $text, $url); - } - - /** - * Writes a media_manager button. - * - * @param string $directory The subdirectory to upload the media to. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function media_manager($directory = '', $alt = 'JTOOLBAR_UPLOAD') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an upload button. - $bar->appendButton('Popup', 'upload', $alt, 'index.php?option=com_media&tmpl=component&task=popupUpload&folder=' . $directory, 800, 520); - } - - /** - * Writes a common 'default' button for a record. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function makeDefault($task = 'default', $alt = 'JTOOLBAR_DEFAULT') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a default button. - $bar->appendButton('Standard', 'default', $alt, $task, true); - } - - /** - * Writes a common 'assign' button for a record. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function assign($task = 'assign', $alt = 'JTOOLBAR_ASSIGN') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an assign button. - $bar->appendButton('Standard', 'assign', $alt, $task, true); - } - - /** - * Writes the common 'new' icon for the button bar. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * @param boolean $check True if required to check that a standard list item is checked. - * - * @return void - * - * @since 1.5 - */ - public static function addNew($task = 'add', $alt = 'JTOOLBAR_NEW', $check = false) - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a new button. - $bar->appendButton('Standard', 'new', $alt, $task, $check); - } - - /** - * Writes a common 'publish' button. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * @param boolean $check True if required to check that a standard list item is checked. - * - * @return void - * - * @since 1.5 - */ - public static function publish($task = 'publish', $alt = 'JTOOLBAR_PUBLISH', $check = false) - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a publish button. - $bar->appendButton('Standard', 'publish', $alt, $task, $check); - } - - /** - * Writes a common 'publish' button for a list of records. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function publishList($task = 'publish', $alt = 'JTOOLBAR_PUBLISH') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a publish button (list). - $bar->appendButton('Standard', 'publish', $alt, $task, true); - } - - /** - * Writes a common 'unpublish' button. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * @param boolean $check True if required to check that a standard list item is checked. - * - * @return void - * - * @since 1.5 - */ - public static function unpublish($task = 'unpublish', $alt = 'JTOOLBAR_UNPUBLISH', $check = false) - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an unpublish button - $bar->appendButton('Standard', 'unpublish', $alt, $task, $check); - } - - /** - * Writes a common 'unpublish' button for a list of records. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function unpublishList($task = 'unpublish', $alt = 'JTOOLBAR_UNPUBLISH') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an unpublish button (list). - $bar->appendButton('Standard', 'unpublish', $alt, $task, true); - } - - /** - * Writes a common 'archive' button for a list of records. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function archiveList($task = 'archive', $alt = 'JTOOLBAR_ARCHIVE') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an archive button. - $bar->appendButton('Standard', 'archive', $alt, $task, true); - } - - /** - * Writes an unarchive button for a list of records. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function unarchiveList($task = 'unarchive', $alt = 'JTOOLBAR_UNARCHIVE') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an unarchive button (list). - $bar->appendButton('Standard', 'unarchive', $alt, $task, true); - } - - /** - * Writes a common 'edit' button for a list of records. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function editList($task = 'edit', $alt = 'JTOOLBAR_EDIT') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an edit button. - $bar->appendButton('Standard', 'edit', $alt, $task, true); - } - - /** - * Writes a common 'edit' button for a template html. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function editHtml($task = 'edit_source', $alt = 'JTOOLBAR_EDIT_HTML') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an edit html button. - $bar->appendButton('Standard', 'edithtml', $alt, $task, true); - } - - /** - * Writes a common 'edit' button for a template css. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function editCss($task = 'edit_css', $alt = 'JTOOLBAR_EDIT_CSS') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an edit css button (hide). - $bar->appendButton('Standard', 'editcss', $alt, $task, true); - } - - /** - * Writes a common 'delete' button for a list of records. - * - * @param string $msg Postscript for the 'are you sure' message. - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function deleteList($msg = '', $task = 'remove', $alt = 'JTOOLBAR_DELETE') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a delete button. - if ($msg) - { - $bar->appendButton('Confirm', $msg, 'delete', $alt, $task, true); - } - else - { - $bar->appendButton('Standard', 'delete', $alt, $task, true); - } - } - - /** - * Writes a common 'trash' button for a list of records. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * @param bool $check True to allow lists. - * - * @return void - * - * @since 1.5 - */ - public static function trash($task = 'remove', $alt = 'JTOOLBAR_TRASH', $check = true) - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a trash button. - $bar->appendButton('Standard', 'trash', $alt, $task, $check, false); - } - - /** - * Writes a save button for a given option. - * Apply operation leads to a save action only (does not leave edit mode). - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function apply($task = 'apply', $alt = 'JTOOLBAR_APPLY') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add an apply button - $bar->appendButton('Standard', 'apply', $alt, $task, false); - } - - /** - * Writes a save button for a given option. - * Save operation leads to a save and then close action. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function save($task = 'save', $alt = 'JTOOLBAR_SAVE') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a save button. - $bar->appendButton('Standard', 'save', $alt, $task, false); - } - - /** - * Writes a save and create new button for a given option. - * Save and create operation leads to a save and then add action. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.6 - */ - public static function save2new($task = 'save2new', $alt = 'JTOOLBAR_SAVE_AND_NEW') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a save and create new button. - $bar->appendButton('Standard', 'save-new', $alt, $task, false); - } - - /** - * Writes a save as copy button for a given option. - * Save as copy operation leads to a save after clearing the key, - * then returns user to edit mode with new key. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.6 - */ - public static function save2copy($task = 'save2copy', $alt = 'JTOOLBAR_SAVE_AS_COPY') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a save and create new button. - $bar->appendButton('Standard', 'save-copy', $alt, $task, false); - } - - /** - * Writes a checkin button for a given option. - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * @param boolean $check True if required to check that a standard list item is checked. - * - * @return void - * - * @since 1.7 - */ - public static function checkin($task = 'checkin', $alt = 'JTOOLBAR_CHECKIN', $check = true) - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a save and create new button. - $bar->appendButton('Standard', 'checkin', $alt, $task, $check); - } - - /** - * Writes a cancel button and invokes a cancel operation (eg a checkin). - * - * @param string $task An override for the task. - * @param string $alt An override for the alt text. - * - * @return void - * - * @since 1.5 - */ - public static function cancel($task = 'cancel', $alt = 'JTOOLBAR_CANCEL') - { - $bar = JToolbar::getInstance('toolbar'); - - // Add a cancel button. - $bar->appendButton('Standard', 'cancel', $alt, $task, false); - } - - /** - * Writes a configuration button and invokes a cancel operation (eg a checkin). - * - * @param string $component The name of the component, eg, com_content. - * @param integer $height The height of the popup. [UNUSED] - * @param integer $width The width of the popup. [UNUSED] - * @param string $alt The name of the button. - * @param string $path An alternative path for the configuation xml relative to JPATH_SITE. - * - * @return void - * - * @since 1.5 - */ - public static function preferences($component, $height = '550', $width = '875', $alt = 'JToolbar_Options', $path = '') - { - $component = urlencode($component); - $path = urlencode($path); - $bar = JToolbar::getInstance('toolbar'); - - $uri = (string) JUri::getInstance(); - $return = urlencode(base64_encode($uri)); - - // Add a button linking to config for component. - $bar->appendButton( - 'Link', - 'options', - $alt, - 'index.php?option=com_config&view=component&component=' . $component . '&path=' . $path . '&return=' . $return - ); - } - - /** - * Writes a version history - * - * @param string $typeAlias The component and type, for example 'com_content.article' - * @param integer $itemId The id of the item, for example the article id. - * @param integer $height The height of the popup. - * @param integer $width The width of the popup. - * @param string $alt The name of the button. - * - * @return void - * - * @since 3.2 - */ - public static function versions($typeAlias, $itemId, $height = 800, $width = 500, $alt = 'JTOOLBAR_VERSIONS') - { - $lang = JFactory::getLanguage(); - $lang->load('com_contenthistory', JPATH_ADMINISTRATOR, $lang->getTag(), true); - $contentTypeTable = JTable::getInstance('Contenttype'); - $typeId = $contentTypeTable->getTypeId($typeAlias); - - // Options array for JLayout - $options = array(); - $options['title'] = JText::_($alt); - $options['height'] = $height; - $options['width'] = $width; - $options['itemId'] = $itemId; - $options['typeId'] = $typeId; - $options['typeAlias'] = $typeAlias; - - $bar = JToolbar::getInstance('toolbar'); - $layout = new JLayoutFile('joomla.toolbar.versions'); - $bar->appendButton('Custom', $layout->render($options), 'versions'); - } - - /** - * Displays a modal button - * - * @param string $targetModalId ID of the target modal box - * @param string $icon Icon class to show on modal button - * @param string $alt Title for the modal button - * - * @return void - * - * @since 3.2 - */ - public static function modal($targetModalId, $icon, $alt) - { - $title = JText::_($alt); - $dhtml = ''; - - $bar = JToolbar::getInstance('toolbar'); - $bar->appendButton('Custom', $dhtml, $alt); - } -} diff --git a/administrator/index.php b/administrator/index.php index ac537b53eb62b..c980d1b8d19dd 100644 --- a/administrator/index.php +++ b/administrator/index.php @@ -6,46 +6,31 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ +/** + * NOTE: This file should remain compatible with PHP 5.2 to allow us to run our PHP minimum check and show a friendly error message + */ + /** * Define the application's minimum supported PHP version as a constant so it can be referenced within the application. */ -define('JOOMLA_MINIMUM_PHP', '5.3.10'); +define('JOOMLA_MINIMUM_PHP', '7.0'); if (version_compare(PHP_VERSION, JOOMLA_MINIMUM_PHP, '<')) { - die('Your host needs to use PHP ' . JOOMLA_MINIMUM_PHP . ' or higher to run this version of Joomla!'); + die( + str_replace( + '{{PHP_VERSION}}', + JOOMLA_MINIMUM_PHP, + file_get_contents(dirname(__FILE__) . '/../templates/system/incompatible.html') + ) + ); } -// Saves the start time and memory usage. -$startTime = microtime(1); -$startMem = memory_get_usage(); - /** * Constant that is checked in included files to prevent direct access. - * define() is used in the installation folder rather than "const" to not error for PHP 5.2 and lower + * define() is used rather than "const" to not error for PHP 5.2 and lower */ define('_JEXEC', 1); -if (file_exists(__DIR__ . '/defines.php')) -{ - include_once __DIR__ . '/defines.php'; -} - -if (!defined('_JDEFINES')) -{ - define('JPATH_BASE', __DIR__); - require_once JPATH_BASE . '/includes/defines.php'; -} - -require_once JPATH_BASE . '/includes/framework.php'; -require_once JPATH_BASE . '/includes/helper.php'; -require_once JPATH_BASE . '/includes/toolbar.php'; - -// Set profiler start time and memory usage and mark afterLoad in the profiler. -JDEBUG ? JProfiler::getInstance('Application')->setStart($startTime, $startMem)->mark('afterLoad') : null; - -// Instantiate the application. -$app = JFactory::getApplication('administrator'); - -// Execute the application. -$app->execute(); +// Run the application - All executable code should be triggered through this file +require_once dirname(__FILE__) . '/includes/app.php'; diff --git a/administrator/language/en-GB/en-GB.com_admin.ini b/administrator/language/en-GB/en-GB.com_admin.ini index 3ff9f0a5be4ad..3c691310375ea 100644 --- a/administrator/language/en-GB/en-GB.com_admin.ini +++ b/administrator/language/en-GB/en-GB.com_admin.ini @@ -60,10 +60,6 @@ COM_ADMIN_HELP_COMPONENTS_REDIRECT_MANAGER_EDIT="Redirect: Links - New/Edit" COM_ADMIN_HELP_COMPONENTS_SEARCH="Search" COM_ADMIN_HELP_COMPONENTS_TAGS_MANAGER="Tags" COM_ADMIN_HELP_COMPONENTS_TAGS_MANAGER_EDIT="Tags: New/Edit" -COM_ADMIN_HELP_COMPONENTS_WEBLINKS_CATEGORIES="Web Links: Categories" -COM_ADMIN_HELP_COMPONENTS_WEBLINKS_CATEGORIES_EDIT="Web Links: Categories - New/Edit" -COM_ADMIN_HELP_COMPONENTS_WEBLINKS_LINKS="Web Links" -COM_ADMIN_HELP_COMPONENTS_WEBLINKS_LINKS_EDIT="Web Links: New/Edit" COM_ADMIN_HELP_CONTENT_ARTICLE_MANAGER="Articles" COM_ADMIN_HELP_CONTENT_ARTICLE_MANAGER_EDIT="Articles: New/Edit" COM_ADMIN_HELP_CONTENT_FEATURED_ARTICLES="Articles: Featured " @@ -120,6 +116,7 @@ COM_ADMIN_MAGIC_QUOTES="Magic Quotes" COM_ADMIN_MAX_INPUT_VARS="Maximum Input Variables" COM_ADMIN_MBSTRING_ENABLED="Multibyte String (mbstring) Enabled" COM_ADMIN_MCRYPT_ENABLED="Mcrypt Enabled" +COM_ADMIN_MEDIA_CACHE_DIRECTORY="Cached Media Directory" COM_ADMIN_NA="n/a" COM_ADMIN_OPEN_BASEDIR="Open basedir" COM_ADMIN_OUTPUT_BUFFERING="Output Buffering" @@ -129,9 +126,7 @@ COM_ADMIN_PHP_SETTINGS="PHP Settings" COM_ADMIN_PHP_VERSION="PHP Version" COM_ADMIN_PHPINFO_DISABLED="The built in phpinfo() function has been disabled by your host." COM_ADMIN_PLATFORM_VERSION="Joomla! Platform Version" -COM_ADMIN_REGISTER_GLOBALS="Register Globals" COM_ADMIN_RELEVANT_PHP_SETTINGS="Relevant PHP Settings" -COM_ADMIN_SAFE_MODE="Safe Mode" COM_ADMIN_SEARCH="Search" COM_ADMIN_SESSION_AUTO_START="Session Auto Start" COM_ADMIN_SESSION_SAVE_PATH="Session Save Path" @@ -145,30 +140,17 @@ COM_ADMIN_TEMP_DIRECTORY="(Temp folder)" COM_ADMIN_UNWRITABLE="Unwritable" COM_ADMIN_USER_ACCOUNT_DETAILS="My Profile Details" COM_ADMIN_USER_AGENT="User Agent" -COM_ADMIN_USER_FIELD_BACKEND_LANGUAGE_DESC="Select the Language for the Administrator Backend interface. This will only affect this User." COM_ADMIN_USER_FIELD_BACKEND_LANGUAGE_LABEL="Backend Language" -COM_ADMIN_USER_FIELD_BACKEND_TEMPLATE_DESC="Select the template style for the Administrator Backend interface. This will only affect this User." COM_ADMIN_USER_FIELD_BACKEND_TEMPLATE_LABEL="Backend Template Style" -COM_ADMIN_USER_FIELD_EDITOR_DESC="Editor for this user." COM_ADMIN_USER_FIELD_EDITOR_LABEL="Editor" -COM_ADMIN_USER_FIELD_EMAIL_DESC="Enter an email address for the user." -COM_ADMIN_USER_FIELD_FRONTEND_LANGUAGE_DESC="Select the Language for the Frontend interface. This will only affect this User." COM_ADMIN_USER_FIELD_FRONTEND_LANGUAGE_LABEL="Frontend Language" -COM_ADMIN_USER_FIELD_HELPSITE_DESC="Help site for this user." COM_ADMIN_USER_FIELD_HELPSITE_LABEL="Help Site" -COM_ADMIN_USER_FIELD_LASTVISIT_DESC="Last visit date." COM_ADMIN_USER_FIELD_LASTVISIT_LABEL="Last Visit Date" -COM_ADMIN_USER_FIELD_NAME_DESC="Enter the name of the user." COM_ADMIN_USER_FIELD_NOCHANGE_USERNAME_DESC="If you want to change your Username, please contact a site administrator." COM_ADMIN_USER_FIELD_PASSWORD1_MESSAGE="The passwords you entered do not match. Please enter your desired password in the password field and confirm your entry by entering it in the confirm password field." -COM_ADMIN_USER_FIELD_PASSWORD2_DESC="Confirm the user's password." COM_ADMIN_USER_FIELD_PASSWORD2_LABEL="Confirm Password" -COM_ADMIN_USER_FIELD_PASSWORD_DESC="Enter the password for the user." -COM_ADMIN_USER_FIELD_REGISTERDATE_DESC="Registration date." COM_ADMIN_USER_FIELD_REGISTERDATE_LABEL="Registration Date" -COM_ADMIN_USER_FIELD_TIMEZONE_DESC="Time zone for this user." COM_ADMIN_USER_FIELD_TIMEZONE_LABEL="Time Zone" -COM_ADMIN_USER_FIELD_USERNAME_DESC="Enter the login name (Username) for the user." COM_ADMIN_USER_FIELD_USERNAME_LABEL="Login Name" COM_ADMIN_USER_HEADING_NAME="Name" COM_ADMIN_USER_SETTINGS_FIELDSET_LABEL="Basic Settings" diff --git a/administrator/language/en-GB/en-GB.com_associations.ini b/administrator/language/en-GB/en-GB.com_associations.ini index e4d06b5829e55..8cf38050cfc87 100644 --- a/administrator/language/en-GB/en-GB.com_associations.ini +++ b/administrator/language/en-GB/en-GB.com_associations.ini @@ -8,8 +8,6 @@ COM_ASSOCIATIONS_ADD_NEW_ASSOCIATION="Add new association" COM_ASSOCIATIONS_ASSOCIATED_ITEM="Target" COM_ASSOCIATIONS_CHANGE_TARGET="Change Target" COM_ASSOCIATIONS_COMPONENT_NOT_SUPPORTED="The extension %s does not support multilingual associations." -COM_ASSOCIATIONS_COMPONENT_SELECTOR_DESC="Select a component from this list" -COM_ASSOCIATIONS_COMPONENT_SELECTOR_LABEL="Select component" COM_ASSOCIATIONS_CONFIGURATION="Multilingual Associations: Options" COM_ASSOCIATIONS_COPY_REFERENCE="Copy Reference to Target" COM_ASSOCIATIONS_DELETE_ORPHANS="Delete Orphans" @@ -19,9 +17,7 @@ COM_ASSOCIATIONS_DELETE_ORPHANS_SUCCESS="All orphans have been deleted." COM_ASSOCIATIONS_EDIT_ASSOCIATION="Edit association" COM_ASSOCIATIONS_EDIT_HIDE_REFERENCE="Hide Reference" COM_ASSOCIATIONS_EDIT_SHOW_REFERENCE="Show Reference" -COM_ASSOCIATIONS_ERROR_NO_ASSOC="The Multilingual Associations component can't be used if the site is not set as multilingual and/or Associations is not enabled in the Language Filter plugin." -COM_ASSOCIATIONS_FILTER_MENUTYPE_DESC="Select a Menu" -COM_ASSOCIATIONS_FILTER_MENUTYPE_LABEL="Menu" +COM_ASSOCIATIONS_ERROR_NO_ASSOC="The Multilingual Associations component can't be used if the site is not set as multilingual and/or Associations is not enabled in the Language Filter plugin." COM_ASSOCIATIONS_FILTER_SEARCH_DESC="Search an item by its title" COM_ASSOCIATIONS_FILTER_SEARCH_LABEL="Search item" COM_ASSOCIATIONS_FILTER_SELECT_ITEM_TYPE="- Select Item Type -" diff --git a/administrator/language/en-GB/en-GB.com_banners.ini b/administrator/language/en-GB/en-GB.com_banners.ini index 24d37881ef0c6..cd60873fecb05 100644 --- a/administrator/language/en-GB/en-GB.com_banners.ini +++ b/administrator/language/en-GB/en-GB.com_banners.ini @@ -12,7 +12,6 @@ COM_BANNERS_BANNERS_HTML_PIN_BANNER="Pinned banner" COM_BANNERS_BANNERS_HTML_UNPIN_BANNER="Unpinned banner" COM_BANNERS_BANNERS_N_ITEMS_ARCHIVED="%d banners archived." COM_BANNERS_BANNERS_N_ITEMS_ARCHIVED_1="%d banner archived." -COM_BANNERS_BANNERS_N_ITEMS_CHECKED_IN_0="No banner checked in." COM_BANNERS_BANNERS_N_ITEMS_CHECKED_IN_1="%d banner checked in." COM_BANNERS_BANNERS_N_ITEMS_CHECKED_IN_MORE="%d banners checked in." COM_BANNERS_BANNERS_N_ITEMS_DELETED="%d banners deleted." @@ -31,7 +30,6 @@ COM_BANNERS_BATCH_CLIENT_LABEL_DESC="Not making a selection will keep the origin COM_BANNERS_BATCH_CLIENT_NOCHANGE="- Keep original Client -" COM_BANNERS_BATCH_OPTIONS="Batch process the selected banners" COM_BANNERS_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved banners. Otherwise, all actions are applied to the selected banners." -COM_BANNERS_BEGIN_DESC="Banner begin date" COM_BANNERS_BEGIN_HINT="Begin date (yyyy-mm-dd)" COM_BANNERS_BEGIN_LABEL="Begin Date" COM_BANNERS_CANCEL="Cancel" @@ -41,7 +39,6 @@ COM_BANNERS_CLIENTS_FILTER_SEARCH_DESC="Search in client name. Prefix with ID: t COM_BANNERS_CLIENTS_FILTER_SEARCH_LABEL="Search Clients" COM_BANNERS_CLIENTS_N_ITEMS_ARCHIVED="%d clients archived." COM_BANNERS_CLIENTS_N_ITEMS_ARCHIVED_1="%d client archived." -COM_BANNERS_CLIENTS_N_ITEMS_CHECKED_IN_0="No client checked in." COM_BANNERS_CLIENTS_N_ITEMS_CHECKED_IN_1="%d client checked in." COM_BANNERS_CLIENTS_N_ITEMS_CHECKED_IN_MORE="%d clients checked in." COM_BANNERS_CLIENTS_N_ITEMS_DELETED="%d clients deleted." @@ -60,9 +57,7 @@ COM_BANNERS_COUNT_TRASHED_ITEMS="Trashed banners" COM_BANNERS_COUNT_UNPUBLISHED_ITEMS="Unpublished banners" COM_BANNERS_DEFAULT="Default (%s)" COM_BANNERS_DELETE_MSG="Are you sure you want to delete all these tracks?" -COM_BANNERS_EDIT_BANNER="Edit Banner" COM_BANNERS_EDIT_CLIENT="Details" -COM_BANNERS_END_DESC="Banner end date" COM_BANNERS_END_HINT="End date (yyyy-mm-dd)" COM_BANNERS_END_LABEL="End Date" COM_BANNERS_ERR_ZIP_ADAPTER_FAILURE="Zip adapter failure" @@ -70,81 +65,39 @@ COM_BANNERS_ERR_ZIP_CREATE_FAILURE="Zip create failure" COM_BANNERS_ERR_ZIP_DELETE_FAILURE="Zip delete failure" COM_BANNERS_ERROR_UNIQUE_ALIAS="Another Banner from this category has the same alias (remember it may be a trashed item)." COM_BANNERS_EXTRA="Additional Information" -COM_BANNERS_FIELD_ALIAS_DESC="The alias is for internal use only. Leave this blank and Joomla will fill in a default value from the title. It has to be unique for each banner in the same category." -COM_BANNERS_FIELD_ALT_DESC="Alternative text used for visitors without access to images." COM_BANNERS_FIELD_ALT_LABEL="Alt Text" -COM_BANNERS_FIELD_BANNEROWNPREFIX_DESC="Use own prefix or the client prefix." COM_BANNERS_FIELD_BANNEROWNPREFIX_LABEL="Use Own Prefix" -COM_BANNERS_FIELD_BASENAME_DESC="File name pattern which can have
    __SITE__ for the site name
    __CATID__ for the category ID
    __CATNAME__ for the category name
    __CLIENTID__ for the client ID
    __CLIENTNAME__ for the client name
    __TYPE__ for the type
    __TYPENAME__ for the type name
    __BEGIN__ for the begin date
    __END__ for the end date." +COM_BANNERS_FIELD_BASENAME_DESC="File name pattern which can have
    __SITE__ for the site name
    __CATID__ for the category ID
    __CATNAME__ for the category name
    __CLIENTID__ for the client ID
    __CLIENTNAME__ for the client name
    __TYPE__ for the type
    __TYPENAME__ for the type name
    __BEGIN__ for the begin date
    __END__ for the end date." COM_BANNERS_FIELD_BASENAME_LABEL="File Name" -COM_BANNERS_FIELD_CATEGORY_DESC="Choose a category for this banner." -COM_BANNERS_FIELD_CLICKS_DESC="Displays the number of clicks on the banner. Select reset if desired." COM_BANNERS_FIELD_CLICKS_LABEL="Total Clicks" -COM_BANNERS_FIELD_CLICKURL_DESC="The URL used when the banner is clicked on." COM_BANNERS_FIELD_CLICKURL_LABEL="Click URL" -COM_BANNERS_FIELD_CLIENT_DESC="Choose a client for this banner." COM_BANNERS_FIELD_CLIENT_LABEL="Client" COM_BANNERS_FIELD_CLIENT_METAKEYWORDPREFIX_DESC="When matching Meta keywords, only search for Meta keywords with this prefix (improves performance)." COM_BANNERS_FIELD_CLIENT_METAKEYWORDPREFIX_LABEL="Meta Keyword Prefix" -COM_BANNERS_FIELD_CLIENT_METAKEYWORDS_DESC="Enter the meta keywords for the clients' banners." -COM_BANNERS_FIELD_CLIENT_NAME_DESC="Enter a name for the client." -COM_BANNERS_FIELD_CLIENT_NAME_LABEL="Client Name" -COM_BANNERS_FIELD_CLIENT_STATE_DESC="Defines the status of the client." -COM_BANNERS_FIELD_CLIENTOWNPREFIX_DESC="Use own prefix or the component prefix." COM_BANNERS_FIELD_CLIENTOWNPREFIX_LABEL="Use Own Prefix" -COM_BANNERS_FIELD_COMPRESSED_DESC="Option to compress file for export." COM_BANNERS_FIELD_COMPRESSED_LABEL="Compressed" -COM_BANNERS_FIELD_CONTACT_DESC="Enter the name of a user as contact." COM_BANNERS_FIELD_CONTACT_LABEL="Contact Name" -COM_BANNERS_FIELD_CREATED_BY_ALIAS_DESC="Enter an alias to be displayed instead of the name of the user who created the banner." COM_BANNERS_FIELD_CREATED_BY_ALIAS_LABEL="Created by Alias" -COM_BANNERS_FIELD_CREATED_BY_DESC="Select the name of the user who created the banner." COM_BANNERS_FIELD_CREATED_BY_LABEL="Created By" -COM_BANNERS_FIELD_CREATED_DESC="Banner created date." COM_BANNERS_FIELD_CREATED_LABEL="Created Date" -COM_BANNERS_FIELD_CUSTOMCODE_DESC="Enter your custom code for the banner." COM_BANNERS_FIELD_CUSTOMCODE_LABEL="Custom Code" -COM_BANNERS_FIELD_DESCRIPTION_DESC="Enter a description for the banner." -COM_BANNERS_FIELD_EMAIL_DESC="Enter a valid Contact email." COM_BANNERS_FIELD_EMAIL_LABEL="Contact Email" -COM_BANNERS_FIELD_EXTRAINFO_DESC="Enter extra information for this client." COM_BANNERS_FIELD_EXTRAINFO_LABEL="Additional Information" -COM_BANNERS_FIELD_HEIGHT_DESC="The height of the banner." COM_BANNERS_FIELD_HEIGHT_LABEL="Height" -COM_BANNERS_FIELD_IMAGE_DESC="Select or upload an image for this banner." COM_BANNERS_FIELD_IMAGE_LABEL="Image" -COM_BANNERS_FIELD_IMPMADE_DESC="Displays the number of impressions made for the banner." COM_BANNERS_FIELD_IMPMADE_LABEL="Total Impressions" -COM_BANNERS_FIELD_IMPTOTAL_DESC="Total limit of impressions defined for the banner." COM_BANNERS_FIELD_IMPTOTAL_LABEL="Max. Impressions" -COM_BANNERS_FIELD_LANGUAGE_DESC="Assign a language to this banner." COM_BANNERS_FIELD_METAKEYWORDPREFIX_DESC="When matching Meta keywords, only search for Meta keywords with this prefix (improves performance)." COM_BANNERS_FIELD_METAKEYWORDPREFIX_LABEL="Meta Keyword Prefix" -COM_BANNERS_FIELD_METAKEYWORDS_DESC="Enter the meta keywords for the banner." -COM_BANNERS_FIELD_MODIFIED_BY_DESC="Name of the user who modified this banner." -COM_BANNERS_FIELD_NAME_DESC="Enter a name for the banner." COM_BANNERS_FIELD_NAME_LABEL="Name" -COM_BANNERS_FIELD_PUBLISH_DOWN_DESC="An optional date to Finish Publishing the banner." COM_BANNERS_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" -COM_BANNERS_FIELD_PUBLISH_UP_DESC="An optional date to Start Publishing the banner." COM_BANNERS_FIELD_PUBLISH_UP_LABEL="Start Publishing" -COM_BANNERS_FIELD_PURCHASETYPE_DESC="Select the type of purchase in the list." COM_BANNERS_FIELD_PURCHASETYPE_LABEL="Purchase Type" -COM_BANNERS_FIELD_STATE_DESC="Defines the status of the banner." COM_BANNERS_FIELD_STICKY_DESC="Whether or not the Banner is 'pinned'. If one or more Banners in a Category are pinned, they will take priority over Banners that are not pinned. For example, if two Banners in a Category are pinned and a third Banner is not pinned, the third Banner will not display if the module setting is 'Pinned, Randomise'. Only the two pinned Banners will display." COM_BANNERS_FIELD_STICKY_LABEL="Pinned" -COM_BANNERS_FIELD_TRACKCLICK_DESC="Record the number of clicks on the banners on a daily basis." COM_BANNERS_FIELD_TRACKCLICK_LABEL="Track Clicks" -COM_BANNERS_FIELD_TRACKIMPRESSION_DESC="Record the impressions (views) of the banners on a daily basis." COM_BANNERS_FIELD_TRACKIMPRESSION_LABEL="Track Impressions" -COM_BANNERS_FIELD_TYPE_DESC="Choose the type of banner. Select Image to display an image. Select Custom to enter your custom code." COM_BANNERS_FIELD_TYPE_LABEL="Type" -; The following five strings are deprecated and will be removed with 4.0. They generate wrong plural detection in Crowdin. -COM_BANNERS_FIELD_VALUE_1="Unlimited" -COM_BANNERS_FIELD_VALUE_2="Yearly" -COM_BANNERS_FIELD_VALUE_3="Monthly" -COM_BANNERS_FIELD_VALUE_4="Weekly" -COM_BANNERS_FIELD_VALUE_5="Daily" COM_BANNERS_FIELD_VALUE_UNLIMITED="Unlimited" COM_BANNERS_FIELD_VALUE_YEARLY="Yearly" COM_BANNERS_FIELD_VALUE_MONTHLY="Monthly" @@ -153,21 +106,15 @@ COM_BANNERS_FIELD_VALUE_DAILY="Daily" COM_BANNERS_FIELD_VALUE_CUSTOM="Custom" COM_BANNERS_FIELD_VALUE_IMAGE="Image" COM_BANNERS_FIELD_VALUE_USECLIENTDEFAULT="-- Use Client Default --" -COM_BANNERS_FIELD_VALUE_USECOMPONENTDEFAULT="-- Use Component Default --" COM_BANNERS_FIELD_VERSION_LABEL="Revision" -COM_BANNERS_FIELD_VERSION_DESC="A count of the number of times this banner has been revised." COM_BANNERS_FIELD_WIDTH_LABEL="Width" -COM_BANNERS_FIELD_WIDTH_DESC="The width of the banner." COM_BANNERS_FIELDSET_CONFIG_BANNER_OPTIONS_DESC="These settings apply to version history for Banners, Banner Categories and Banner Clients." COM_BANNERS_FIELDSET_CONFIG_BANNER_OPTIONS_LABEL="History" COM_BANNERS_FIELDSET_CONFIG_CLIENT_OPTIONS_LABEL="Client" COM_BANNERS_FIELDSET_CONFIG_CLIENT_OPTIONS_DESC="These settings apply for all clients unless they are changed for a specific client." -COM_BANNERS_FILENAME="%1$s-banners-tracks-%2$s" COM_BANNERS_GROUP_LABEL_PUBLISHING_DETAILS="Publishing Options" COM_BANNERS_GROUP_LABEL_BANNER_DETAILS="Banner Details" COM_BANNERS_HEADING_ACTIVE="Active" -COM_BANNERS_HEADING_ACTIVE_ASC="Active ascending" -COM_BANNERS_HEADING_ACTIVE_DESC="Active descending" COM_BANNERS_HEADING_BANNERS="Banners" COM_BANNERS_HEADING_BANNERS_ASC="Banners ascending" COM_BANNERS_HEADING_BANNERS_DESC="Banners descending" @@ -201,7 +148,6 @@ COM_BANNERS_HEADING_TYPE_ASC="Type ascending" COM_BANNERS_HEADING_TYPE_DESC="Type descending" COM_BANNERS_IMPRESSION="Impression" COM_BANNERS_IMPRESSIONS="%1$s of %2$s" -COM_BANNERS_MANAGER="Banners" COM_BANNERS_MANAGER_BANNER_EDIT="Banners: Edit" COM_BANNERS_MANAGER_BANNER_NEW="Banners: New" COM_BANNERS_MANAGER_BANNERS="Banners" @@ -209,8 +155,6 @@ COM_BANNERS_MANAGER_CLIENT_EDIT="Banners: Edit Client" COM_BANNERS_MANAGER_CLIENT_NEW="Banners: New Client" COM_BANNERS_MANAGER_CLIENTS="Banners: Clients" COM_BANNERS_MANAGER_TRACKS="Banners: Tracks" -COM_BANNERS_METADATA="Metadata" -COM_BANNERS_FIELD_MODIFIED_DESC="The date and time that the banner was last modified." COM_BANNERS_N_BANNERS_STUCK="%d banners pinned." COM_BANNERS_N_BANNERS_STUCK_1="%d banner pinned." COM_BANNERS_N_BANNERS_UNSTUCK="%d banners unpinned." @@ -219,7 +163,6 @@ COM_BANNERS_NEW_BANNER="New Banner" COM_BANNERS_NEW_CLIENT="New Client" COM_BANNERS_NO_BANNERS_SELECTED="No banners selected." COM_BANNERS_NO_CLIENT="- No client -" -COM_BANNERS_NO_CLIENTS_SELECTED="No clients selected." COM_BANNERS_NOCATEGORYNAME="No category" COM_BANNERS_NOCLIENTNAME="No client" COM_BANNERS_RESET_CLICKS="Reset clicks" @@ -243,4 +186,4 @@ COM_BANNERS_TYPE1="Impressions" COM_BANNERS_TYPE2="Clicks" COM_BANNERS_UNLIMITED="Unlimited" COM_BANNERS_XML_DESCRIPTION="This component manages banners and banner clients." -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_banners.sys.ini b/administrator/language/en-GB/en-GB.com_banners.sys.ini index 6d6483da797a5..1c17a12a4d4ca 100644 --- a/administrator/language/en-GB/en-GB.com_banners.sys.ini +++ b/administrator/language/en-GB/en-GB.com_banners.sys.ini @@ -5,8 +5,6 @@ COM_BANNERS="Banners" COM_BANNERS_BANNERS="Banners" -COM_BANNERS_CATEGORY_ADD_TITLE="Banners: Add Category" -COM_BANNERS_CATEGORY_EDIT_TITLE="Banners: Edit Category" COM_BANNERS_CATEGORIES="Categories" COM_BANNERS_CONTENT_TYPE_BANNER="Banner" COM_BANNERS_CONTENT_TYPE_CLIENT="Banner Client" diff --git a/administrator/language/en-GB/en-GB.com_cache.ini b/administrator/language/en-GB/en-GB.com_cache.ini index 9bfb89d74301d..36cf2df733336 100644 --- a/administrator/language/en-GB/en-GB.com_cache.ini +++ b/administrator/language/en-GB/en-GB.com_cache.ini @@ -4,11 +4,7 @@ ; Note : All ini files need to be saved as UTF-8 COM_CACHE="Cache" -COM_CACHE_BACK_CACHE_MANAGER="Return to Cache" -COM_CACHE_CLEAR_CACHE_ADMIN="Clear Cache Administrator" COM_CACHE_CLEAR_CACHE="Maintenance: Clear Cache" -COM_CACHE_CLEAR_CACHE_ADMIN_TITLE="Maintenance: Clear Cache (Administrator)" -COM_CACHE_CLEAR_CACHE_SITE_TITLE="Maintenance: Clear Cache (Site)" COM_CACHE_PURGE_EXPIRED_CACHE="Maintenance: Clear Expired Cache" COM_CACHE_CONFIGURATION="Cache: Options" COM_CACHE_ERROR_CACHE_CONNECTION_FAILED="Could not connect to the cache store to fetch the cache data." @@ -26,11 +22,9 @@ COM_CACHE_HEADING_COUNT_ASC="Number of Files ascending" COM_CACHE_HEADING_COUNT_DESC="Number of Files descending" COM_CACHE_HEADING_SIZE_ASC="Size ascending" COM_CACHE_HEADING_SIZE_DESC="Size descending" -COM_CACHE_MANAGER="Cache" COM_CACHE_MSG_ALL_CACHE_GROUPS_CLEARED="All cache group(s) have been cleared." COM_CACHE_MSG_SOME_CACHE_GROUPS_CLEARED="Only some cache group(s) have been cleared." COM_CACHE_NUMBER_OF_FILES="Number of Files" -COM_CACHE_PURGE_CACHE_ADMIN="Clear Cache Administrator" COM_CACHE_PURGE_EXPIRED="Clear Expired Cache" COM_CACHE_PURGE_EXPIRED_ITEMS="Clear expired items" COM_CACHE_PURGE_INSTRUCTIONS="Select the Clear Expired Cache icon in the toolbar to delete all expired cache files. Note: Cache files that are still current will not be deleted." @@ -38,4 +32,4 @@ COM_CACHE_RESOURCE_INTENSIVE_WARNING="This can be resource intensive on sites wi COM_CACHE_SIZE="Size" COM_CACHE_SELECT_CLIENT="- Select Location -" COM_CACHE_XML_DESCRIPTION="Component for cache management." -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_categories.ini b/administrator/language/en-GB/en-GB.com_categories.ini index ad3a570e34112..d5ec6cede2150 100644 --- a/administrator/language/en-GB/en-GB.com_categories.ini +++ b/administrator/language/en-GB/en-GB.com_categories.ini @@ -5,40 +5,22 @@ CATEGORIES_FIELDSET_OPTIONS="Options" COM_CATEGORIES="Categories" -COM_CATEGORIES_ACCESS_CREATE_DESC="New setting for create actions in this category and the calculated setting based on the parent category and group permissions." -COM_CATEGORIES_ACCESS_DELETE_DESC="New setting for delete actions on this category and the calculated setting based on the parent category and group permissions." -COM_CATEGORIES_ACCESS_EDIT_DESC="New setting for edit actions on this category and the calculated setting based on the parent category and group permissions." -COM_CATEGORIES_ACCESS_EDITOWN_DESC="New setting for edit own actions on this category and the calculated setting based on the parent category and group permissions." -COM_CATEGORIES_ACCESS_EDITSTATE_DESC="New setting for edit state actions on this category and the calculated setting based on the parent category and group permissions." -COM_CATEGORIES_BASIC_FIELDSET_LABEL="Options" COM_CATEGORIES_BATCH_CANNOT_CREATE="You are not allowed to create new categories in this category." COM_CATEGORIES_BATCH_CANNOT_EDIT="You are not allowed to edit one or more of these categories." -; COM_CATEGORIES_BATCH_CATEGORY_LABEL is deprecated, use JLIB_HTML_BATCH_MENU_LABEL instead. -COM_CATEGORIES_BATCH_CATEGORY_LABEL="To Move or Copy your selection please select a Category." COM_CATEGORIES_BATCH_OPTIONS="Batch process the selected categories." COM_CATEGORIES_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved categories. Otherwise, all actions are applied to the selected categories." COM_CATEGORIES_CATEGORIES_BASE_TITLE="Categories" COM_CATEGORIES_CATEGORIES_TITLE="%s: Categories" COM_CATEGORIES_CATEGORY_ADD_TITLE="%s: New Category" -COM_CATEGORIES_CATEGORY_BASE_ADD_TITLE="Categories: New Category" -COM_CATEGORIES_CATEGORY_BASE_EDIT_TITLE="Categories: Edit Category" COM_CATEGORIES_CATEGORY_EDIT_TITLE="%s: Edit Category" -COM_CATEGORIES_CATEGORY_OPTIONS="Category" COM_CATEGORIES_CHANGE_CATEGORY="Select or Change Category" COM_CATEGORIES_DELETE_NOT_ALLOWED="Delete not allowed for category %s." -COM_CATEGORIES_DESCRIPTION_DESC="Enter an optional category description in the text area." COM_CATEGORIES_EDIT_CATEGORY="Edit Category" COM_CATEGORIES_ERROR_ALL_LANGUAGE_ASSOCIATED="A category item set to All languages can't be associated. Associations have not been set." COM_CATEGORIES_FIELD_BASIC_LABEL="Options" -COM_CATEGORIES_FIELD_HITS_DESC="Number of hits for this category." COM_CATEGORIES_FIELD_IMAGE_ALT_LABEL="Alt Text" -COM_CATEGORIES_FIELD_IMAGE_ALT_DESC="Alternative text used for visitors without access to images." -COM_CATEGORIES_FIELD_IMAGE_DESC="Select or upload an image for this category." COM_CATEGORIES_FIELD_IMAGE_LABEL="Image" -COM_CATEGORIES_FIELD_LANGUAGE_DESC="Assign a language to this category." -COM_CATEGORIES_FIELD_NOTE_DESC="An optional note to display in the category list." COM_CATEGORIES_FIELD_NOTE_LABEL="Note" -COM_CATEGORIES_FIELD_PARENT_DESC="Select a parent category." COM_CATEGORIES_FIELD_PARENT_LABEL="Parent" COM_CATEGORIES_FIELDSET_DETAILS="Category Details" COM_CATEGORIES_FIELDSET_PUBLISHING="Publishing" @@ -47,15 +29,11 @@ COM_CATEGORIES_FILTER_SEARCH_DESC="Search in title, alias and note. Prefix with COM_CATEGORIES_FILTER_SEARCH_LABEL="Search Categories" COM_CATEGORIES_HAS_SUBCATEGORY_ITEMS="%d items are assigned to this category's subcategories." COM_CATEGORIES_HAS_SUBCATEGORY_ITEMS_1="%d item is assigned to one of this category's subcategories." -; The following 2 strings are deprecated and will be removed with 4.0. -COM_CATEGORIES_ITEM_ASSOCIATIONS_FIELDSET_LABEL="Category Item Associations" -COM_CATEGORIES_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a category item for the target language. This association will let the Language Switcher module redirect to the associated category item in another language. If used, make sure to display the Language switcher module on the relevant pages. A category item set to language 'All' can't be associated." COM_CATEGORIES_ITEMS_SEARCH_FILTER="Search" COM_CATEGORIES_N_ITEMS_ARCHIVED="%d categories archived." COM_CATEGORIES_N_ITEMS_ARCHIVED_1="%d category archived." COM_CATEGORIES_N_ITEMS_ASSIGNED="%d items are assigned to this category." COM_CATEGORIES_N_ITEMS_ASSIGNED_1="%d item is assigned to this category." -COM_CATEGORIES_N_ITEMS_CHECKED_IN_0="No category checked in." COM_CATEGORIES_N_ITEMS_CHECKED_IN_1="%d category checked in." COM_CATEGORIES_N_ITEMS_CHECKED_IN_MORE="%d categories checked in." COM_CATEGORIES_N_ITEMS_DELETED="%d categories deleted." @@ -84,4 +62,4 @@ COM_CATEGORY_COUNT_UNPUBLISHED_ITEMS="Unpublished items" COM_CATEGORY_HEADING_ASSOCIATION="Association" JGLOBAL_NO_ITEM_SELECTED="No categories selected." JLIB_HTML_ACCESS_SUMMARY_DESC="Shown below is an overview of the permission settings for this category. Select the tabs above to customise these settings by action." -JLIB_RULES_SETTING_NOTES_ITEM="Changes apply to this category and all child categories.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES_ITEM="Changes apply to this category and all child categories.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_categories.sys.ini b/administrator/language/en-GB/en-GB.com_categories.sys.ini index 17708ea68bb33..814aea9caa7c2 100644 --- a/administrator/language/en-GB/en-GB.com_categories.sys.ini +++ b/administrator/language/en-GB/en-GB.com_categories.sys.ini @@ -8,6 +8,5 @@ COM_CATEGORIES_CATEGORIES_VIEW_DEFAULT_DESC="Shows a List of All categories in t COM_CATEGORIES_CATEGORIES_VIEW_DEFAULT_TITLE="List All Categories" COM_CATEGORIES_CATEGORY_VIEW_EDIT_DESC="Create a new Category in the selected component." COM_CATEGORIES_CATEGORY_VIEW_EDIT_TITLE="Create New Category" -COM_CATEGORIES_CHOOSE_COMPONENT_DESC="Select a component to which this category should be linked.
    If a component using categories is not shown in the list, please create at least one category for it using the default regular menu." COM_CATEGORIES_CHOOSE_COMPONENT_LABEL="Choose a Component" COM_CATEGORIES_XML_DESCRIPTION="This component manages categories." diff --git a/administrator/language/en-GB/en-GB.com_checkin.ini b/administrator/language/en-GB/en-GB.com_checkin.ini index 3e9ee4292c991..720a5ba476bb6 100644 --- a/administrator/language/en-GB/en-GB.com_checkin.ini +++ b/administrator/language/en-GB/en-GB.com_checkin.ini @@ -14,10 +14,9 @@ COM_CHECKIN_GLOBAL_CHECK_IN="Maintenance: Global Check-in" COM_CHECKIN_ITEMS_TO_CHECK_IN="Items to check-in" COM_CHECKIN_ITEMS_TO_CHECK_IN_ASC="Items to check-in ascending" COM_CHECKIN_ITEMS_TO_CHECK_IN_DESC="Items to check-in descending" -COM_CHECKIN_N_ITEMS_CHECKED_IN_0="No item checked in." COM_CHECKIN_N_ITEMS_CHECKED_IN_1="1 item checked in." COM_CHECKIN_N_ITEMS_CHECKED_IN_MORE="%s items checked in." COM_CHECKIN_NO_ITEMS="There are no tables with checked out items or there are no tables with checked out items that match your search." COM_CHECKIN_TABLE="%s table" COM_CHECKIN_XML_DESCRIPTION="Check-in Component." -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." \ No newline at end of file +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_config.ini b/administrator/language/en-GB/en-GB.com_config.ini index 2c8110a6d10ac..3f063f4e4c14e 100644 --- a/administrator/language/en-GB/en-GB.com_config.ini +++ b/administrator/language/en-GB/en-GB.com_config.ini @@ -4,18 +4,6 @@ ; Note : All ini files need to be saved as UTF-8 COM_CONFIG="Configuration Manager" -COM_CONFIG_ACTION_ADMIN_DESC="Allows users in the group to perform any action over the whole site regardless of any other permission settings." -COM_CONFIG_ACTION_CREATE_DESC="Allows users in the group to create any content in any extension." -COM_CONFIG_ACTION_DELETE_DESC="Allows users in the group to delete any content in any extension." -COM_CONFIG_ACTION_EDIT_DESC="Allows users in the group to edit any content in any extension." -COM_CONFIG_ACTION_EDITOWN_DESC="Allows users in the group to edit any content they own in any extension." -COM_CONFIG_ACTION_EDITVALUE_DESC="Allows users in the group to edit any value of custom fields submitted in any extension." -COM_CONFIG_ACTION_EDITSTATE_DESC="Allows users in the group to edit the state of any content in any extension." -COM_CONFIG_ACTION_LOGIN_ADMIN_DESC="Allows users in the group to login to the Backend Administrator site." -COM_CONFIG_ACTION_LOGIN_OFFLINE_DESC="Allows users in the group to access the Frontend site when site is offline." -COM_CONFIG_ACTION_LOGIN_SITE_DESC="Allows users in the group to login to the Frontend site." -COM_CONFIG_ACTION_MANAGE_DESC="Allows users in the group to access all of the administration interface except Global Configuration." -COM_CONFIG_ACTION_OPTIONS_DESC="Allows users in the group to edit the options except the permissions of any extension." COM_CONFIG_CACHE_SETTINGS="Cache Settings" COM_CONFIG_CACHE_WARNING="Failed to clear cache automatically, you may need to do so manually." COM_CONFIG_COMPONENT_FIELDSET_LABEL="Component" @@ -31,6 +19,7 @@ COM_CONFIG_ERROR_CONFIG_EXTENSION_NOT_FOUND="The Global Configuration extension COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTUNWRITABLE="Could not make configuration.php unwritable." COM_CONFIG_ERROR_CONFIGURATION_PHP_NOTWRITABLE="Could not make configuration.php writable." COM_CONFIG_ERROR_CUSTOM_CACHE_PATH_NOTWRITABLE_USING_DEFAULT="The folder at %1$s is not writable and cannot be used for the cache, using the default %2$s instead." +COM_CONFIG_ERROR_CUSTOM_SESSION_FILESYSTEM_PATH_NOTWRITABLE_USING_DEFAULT="The folder at %s is not writable and cannot be used to store session data, the default PHP path will be used instead." COM_CONFIG_ERROR_HELPREFRESH_ERROR_STORE="The new Help Sites list could not be saved." COM_CONFIG_ERROR_HELPREFRESH_FETCH="The current Help Sites list could not be fetched from the remote server." COM_CONFIG_ERROR_ROOT_ASSET_NOT_FOUND="The asset for global configuration could not be found. Permissions have not been saved." @@ -38,175 +27,98 @@ COM_CONFIG_ERROR_SSL_NOT_AVAILABLE="HTTPS has not been enabled as it is not avai COM_CONFIG_ERROR_SSL_NOT_AVAILABLE_HTTP_CODE="HTTPS version of the site returned an invalid HTTP status code." COM_CONFIG_ERROR_REMOVING_SUPER_ADMIN="You can't remove your own Super User permissions." COM_CONFIG_ERROR_WRITE_FAILED="Could not write to the configuration file" -COM_CONFIG_FIELD_CACHE_HANDLER_DESC="Choose the cache handler. Native caching mechanism is file-based. Please make sure the cache folders are writable." COM_CONFIG_FIELD_CACHE_HANDLER_LABEL="Cache Handler" COM_CONFIG_FIELD_CACHE_PLATFORMPREFIX_LABEL="Platform Specific Caching" -COM_CONFIG_FIELD_CACHE_PLATFORMPREFIX_DESC="Enable or disable platform specific caching. Enable when HTML output on mobile differs from other devices. (Default disabled.)" COM_CONFIG_FIELD_CACHE_LABEL="System Cache" -COM_CONFIG_FIELD_CACHE_DESC="Enable or disable caching and set caching level. Conservative level: smaller system cache, Progressive level (default): faster, bigger system cache, includes module renderers cache. Not appropriate for extremely large sites." -COM_CONFIG_FIELD_CACHE_PATH_DESC="Please specify a writable folder to store cache files if you do not wish to use the default folder." COM_CONFIG_FIELD_CACHE_PATH_LABEL="Path to Cache Folder" -COM_CONFIG_FIELD_CACHE_TIME_DESC="The maximum length of time in minutes for a cache file to be stored before it is refreshed." -COM_CONFIG_FIELD_CACHE_TIME_LABEL="Cache Time" -COM_CONFIG_FIELD_COOKIE_DOMAIN_DESC="Domain to use when setting session cookies. Precede domain with '.' if cookie should be valid for all subdomains." +COM_CONFIG_FIELD_CACHE_TIME_LABEL="Cache Time (minutes)" +COM_CONFIG_FIELD_COOKIE_DOMAIN_DESC="Precede domain with '.' if cookie should be valid for all subdomains." COM_CONFIG_FIELD_COOKIE_DOMAIN_LABEL="Cookie Domain" -COM_CONFIG_FIELD_COOKIE_PATH_DESC="Path the cookie should be valid for." COM_CONFIG_FIELD_COOKIE_PATH_LABEL="Cookie Path" -COM_CONFIG_FIELD_DATABASE_HOST_DESC="The hostname for your database entered during the installation process. Do not edit this field unless absolutely necessary (eg the transfer of the database to a new hosting provider)." COM_CONFIG_FIELD_DATABASE_HOST_LABEL="Host" -COM_CONFIG_FIELD_DATABASE_NAME_DESC="The name for your database entered during the installation process. Do not edit this field unless absolutely necessary (eg the transfer of the database to a new hosting provider)." COM_CONFIG_FIELD_DATABASE_NAME_LABEL="Database Name" -COM_CONFIG_FIELD_DATABASE_PREFIX_DESC="The prefix used for your database tables, created during the installation process. Do not edit this field unless absolutely necessary (eg the transfer of the database to a new hosting provider)." COM_CONFIG_FIELD_DATABASE_PREFIX_LABEL="Database Tables Prefix" -COM_CONFIG_FIELD_DATABASE_TYPE_DESC="The type of database in use, selected during the installation process. Do not edit this field unless you are migrating to a different type of database, perhaps due to changing your hosting provider." COM_CONFIG_FIELD_DATABASE_TYPE_LABEL="Database Type" -COM_CONFIG_FIELD_DATABASE_USERNAME_DESC="The username for access to your database entered during the installation process. Do not edit this field unless absolutely necessary (eg the transfer of the database to a new hosting provider)." COM_CONFIG_FIELD_DATABASE_USERNAME_LABEL="Database Username" -COM_CONFIG_FIELD_DEBUG_LANG_DESC="Select if the debugging indicators (** ... **) or (?? ... ??) for the Joomla Language files will be displayed. Debug Language will work without Debug System being activated, but you will not get the additional detailed references that will help you correct any errors." COM_CONFIG_FIELD_DEBUG_LANG_LABEL="Debug Language" -COM_CONFIG_FIELD_DEBUG_SYSTEM_DESC="If enabled, diagnostic information, language translation and SQL errors (if present) will be displayed. The information will be displayed at the foot of every page you view within the Joomla Backend and Frontend. It is not advisable to leave the debug mode activated when running a live website." COM_CONFIG_FIELD_DEBUG_SYSTEM_LABEL="Debug System" -COM_CONFIG_FIELD_DEFAULT_ACCESS_LEVEL_DESC="Select the default access level for new content, menu items and other items created on your site." COM_CONFIG_FIELD_DEFAULT_ACCESS_LEVEL_LABEL="Default Access Level" -COM_CONFIG_FIELD_DEFAULT_EDITOR_DESC="Select the default text editor for your site. Registered Users will be able to change their preference in their personal details if you allow that option." COM_CONFIG_FIELD_DEFAULT_EDITOR_LABEL="Default Editor" -COM_CONFIG_FIELD_DEFAULT_CAPTCHA_DESC="Select the default captcha for your site. You may need to enter required information for your captcha plugin in the Plugin Manager." COM_CONFIG_FIELD_DEFAULT_CAPTCHA_LABEL="Default Captcha" -COM_CONFIG_FIELD_DEFAULT_FEED_LIMIT_DESC="Select the number of content items to show in the feed(s)." COM_CONFIG_FIELD_DEFAULT_FEED_LIMIT_LABEL="Default Feed Limit" -COM_CONFIG_FIELD_DEFAULT_LIST_LIMIT_DESC="Sets the default length of lists in the Control Panel for all users." COM_CONFIG_FIELD_DEFAULT_LIST_LIMIT_LABEL="Default List Limit" -COM_CONFIG_FIELD_ERROR_REPORTING_DESC="Select the level of reporting. See the Help Screen for full details." COM_CONFIG_FIELD_ERROR_REPORTING_LABEL="Error Reporting" -COM_CONFIG_FIELD_FEED_EMAIL_DESC="The RSS and Atom news feeds include the author's email address. Select Author Email Address to use each author's email address (from the User Manager) in the news feed. Select Site Email Address to include the site 'Mail from' email address for each article." COM_CONFIG_FIELD_FEED_EMAIL_LABEL="Feed Email Address" COM_CONFIG_FIELD_FILTERS_DEFAULT_BLACK_LIST="Default Blacklist" COM_CONFIG_FIELD_FILTERS_CUSTOM_BLACK_LIST="Custom Blacklist" COM_CONFIG_FIELD_FILTERS_NO_HTML="No HTML" COM_CONFIG_FIELD_FILTERS_NO_FILTER="No Filtering" COM_CONFIG_FIELD_FILTERS_WHITE_LIST="Whitelist" -COM_CONFIG_FRONTEDITING_DESC="Select if you want mouse-over edit icons for modules and menu items (support may depend on your template)." COM_CONFIG_FRONTEDITING_LABEL="Mouse-over Edit Icons for" COM_CONFIG_FRONTEDITING_MENUSANDMODULES="Modules & Menus" -COM_CONFIG_FRONTEDITING_MENUSANDMODULES_ADMIN_TOO="Modules & Menus (administrator too)" COM_CONFIG_FRONTEDITING_MODULES="Modules" -COM_CONFIG_FIELD_FORCE_SSL_DESC="Force site access in the selected areas to occur only with HTTPS (encrypted HTTP connections with the https:// protocol prefix) and also force the use of secure cookies. Note, you must have HTTPS enabled on your server to utilise this option." COM_CONFIG_FIELD_FORCE_SSL_LABEL="Force HTTPS" -COM_CONFIG_FIELD_FTP_ENABLE_DESC="Enable the built in FTP (File Transfer Protocol) functionality which is needed, in some server environments, instead of the normal upload functionality of Joomla." COM_CONFIG_FIELD_FTP_ENABLE_LABEL="Enable FTP" -COM_CONFIG_FIELD_FTP_HOST_DESC="Enter the name of the host of your FTP server." COM_CONFIG_FIELD_FTP_HOST_LABEL="FTP Host" -COM_CONFIG_FIELD_FTP_PASSWORD_DESC="Enter your FTP password." COM_CONFIG_FIELD_FTP_PASSWORD_LABEL="FTP Password" -COM_CONFIG_FIELD_FTP_PORT_DESC="Enter the port that FTP should be accessed by. The default is port 21." COM_CONFIG_FIELD_FTP_PORT_LABEL="FTP Port" -COM_CONFIG_FIELD_FTP_ROOT_DESC="The path to the root folder of the FTP server. The root folder is the base folder to which the FTP server is allowed access." COM_CONFIG_FIELD_FTP_ROOT_LABEL="FTP Root" -COM_CONFIG_FIELD_FTP_USERNAME_DESC="The username used to access the FTP server." COM_CONFIG_FIELD_FTP_USERNAME_LABEL="FTP Username" -COM_CONFIG_FIELD_GZIP_COMPRESSION_DESC="Compress buffered output if supported." COM_CONFIG_FIELD_GZIP_COMPRESSION_LABEL="Gzip Page Compression" -COM_CONFIG_FIELD_HELP_SERVER_DESC="Select the name of the help server from which your system will collect the help screen displays." COM_CONFIG_FIELD_HELP_SERVER_LABEL="Help Server" -COM_CONFIG_FIELD_LOG_PATH_DESC="Please specify a folder to store log files." COM_CONFIG_FIELD_LOG_PATH_LABEL="Path to Log Folder" -COM_CONFIG_FIELD_MAIL_FROM_EMAIL_DESC="The email address that will be used to send site email." COM_CONFIG_FIELD_MAIL_FROM_EMAIL_LABEL="From Email" -COM_CONFIG_FIELD_MAIL_FROM_NAME_DESC="Text displayed in the header "From:" field when sending a site email. Usually the site name." COM_CONFIG_FIELD_MAIL_FROM_NAME_LABEL="From Name" COM_CONFIG_FIELD_MAIL_REPLY_TO_EMAIL_LABEL="Reply To email" -COM_CONFIG_FIELD_MAIL_REPLY_TO_EMAIL_DESC="The email address that will be used to receive end user(s) reply" COM_CONFIG_FIELD_MAIL_REPLY_TO_NAME_LABEL="Reply To Name" -COM_CONFIG_FIELD_MAIL_REPLY_TO_NAME_DESC="Text displayed in the header "To:" field when end user(s) replying to received email" -COM_CONFIG_FIELD_MAIL_MAILONLINE_DESC="Select Yes to turn on mail sending, select No to turn off mail sending. Warning: It is recommended to put the site offline when disabling the mail function!" COM_CONFIG_FIELD_MAIL_MAILONLINE_LABEL="Send Mail" -COM_CONFIG_FIELD_MAIL_MASSMAILOFF_DESC="Select Yes to disable the Mass Mail Users function, select No to make it active." COM_CONFIG_FIELD_MAIL_MASSMAILOFF_LABEL="Disable Mass Mail" -COM_CONFIG_FIELD_MAIL_MAILER_DESC="Select which mailer for the delivery of site email." COM_CONFIG_FIELD_MAIL_MAILER_LABEL="Mailer" -COM_CONFIG_FIELD_MAIL_SENDMAIL_PATH_DESC="Enter the path to the sendmail program folder on the host server." COM_CONFIG_FIELD_MAIL_SENDMAIL_PATH_LABEL="Sendmail Path" -COM_CONFIG_FIELD_MAIL_SMTP_AUTH_DESC="Select Yes if your SMTP Host requires SMTP Authentication." COM_CONFIG_FIELD_MAIL_SMTP_AUTH_LABEL="SMTP Authentication" -COM_CONFIG_FIELD_MAIL_SMTP_HOST_DESC="Enter the name of the SMTP host." COM_CONFIG_FIELD_MAIL_SMTP_HOST_LABEL="SMTP Host" -COM_CONFIG_FIELD_MAIL_SMTP_PASSWORD_DESC="Enter the password for the SMTP host." COM_CONFIG_FIELD_MAIL_SMTP_PASSWORD_LABEL="SMTP Password" -COM_CONFIG_FIELD_MAIL_SMTP_PORT_DESC="Enter the port number of the SMTP server Joomla will use to send emails. Usually:
    - 25 when using an unsecure mail server
    - 465 when using a secure server with SMTPS
    - 25 or 587 when using a secure server with SMTP with STARTTLS extension." COM_CONFIG_FIELD_MAIL_SMTP_PORT_LABEL="SMTP Port" -COM_CONFIG_FIELD_MAIL_SMTP_SECURE_DESC="Select the security model of the SMTP server Joomla will use to send emails.
    - None for no encryption
    - SSL/TLS for SMTPS (usually on port 465)
    - STARTTLS for SMTP with STARTTLS extension (usually on port 25 or port 587)" COM_CONFIG_FIELD_MAIL_SMTP_SECURE_LABEL="SMTP Security" -COM_CONFIG_FIELD_MAIL_SMTP_USERNAME_DESC="Enter the username for access to the SMTP host." COM_CONFIG_FIELD_MAIL_SMTP_USERNAME_LABEL="SMTP Username" -COM_CONFIG_FIELD_MEMCACHE_COMPRESSION_DESC="Memcache(d) compression." COM_CONFIG_FIELD_MEMCACHE_COMPRESSION_LABEL="Memcache(d) Compression" -COM_CONFIG_FIELD_MEMCACHE_HOST_DESC="Memcache(d) server host." COM_CONFIG_FIELD_MEMCACHE_HOST_LABEL="Memcache(d) Server Host" -COM_CONFIG_FIELD_MEMCACHE_PERSISTENT_DESC="Persistent Memcache(d)." COM_CONFIG_FIELD_MEMCACHE_PERSISTENT_LABEL="Persistent Memcache(d)" -COM_CONFIG_FIELD_MEMCACHE_PORT_DESC="Memcache(d) server port." COM_CONFIG_FIELD_MEMCACHE_PORT_LABEL="Memcache(d) Server Port" -COM_CONFIG_FIELD_REDIS_AUTH_DESC="Redis server authentication." COM_CONFIG_FIELD_REDIS_AUTH_LABEL="Redis Server Authentication" -COM_CONFIG_FIELD_REDIS_DB_DESC="Redis database." COM_CONFIG_FIELD_REDIS_DB_LABEL="Redis Database" -COM_CONFIG_FIELD_REDIS_HOST_DESC="Redis server host." COM_CONFIG_FIELD_REDIS_HOST_LABEL="Redis Server Host" -COM_CONFIG_FIELD_REDIS_PERSISTENT_DESC="Persistent Redis." COM_CONFIG_FIELD_REDIS_PERSISTENT_LABEL="Persistent Redis" -COM_CONFIG_FIELD_REDIS_PORT_DESC="Redis server port." COM_CONFIG_FIELD_REDIS_PORT_LABEL="Redis Server Port" -COM_CONFIG_FIELD_METAAUTHOR_DESC="Show the author meta tag when viewing articles." -COM_CONFIG_FIELD_METAAUTHOR_LABEL="Show Author Meta Tag" -COM_CONFIG_FIELD_METADESC_DESC="Enter a description of the overall website that may be used by search engines. Generally, a maximum of 20 words is best." +COM_CONFIG_FIELD_METAAUTHOR_LABEL="Author Meta Tag" COM_CONFIG_FIELD_METADESC_LABEL="Site Meta Description" -COM_CONFIG_FIELD_METAKEYS_DESC="Enter the keywords and phrases that best describe your website. Separate keywords and phrases with a comma." COM_CONFIG_FIELD_METAKEYS_LABEL="Site Meta Keywords" -COM_CONFIG_FIELD_METALANGUAGE_DESC="Places the selected language in the metadata for the site." -COM_CONFIG_FIELD_METALANGUAGE_LABEL="Site Meta Language" -COM_CONFIG_FIELD_METAVERSION_LABEL="Show Joomla Version" -COM_CONFIG_FIELD_METAVERSION_DESC="Show the Joomla version number in the generator meta tag." -COM_CONFIG_FIELD_OFFLINE_IMAGE_DESC="Select or upload an optional image to be displayed on the default offline page. Make sure the image is less than 400px wide." +COM_CONFIG_FIELD_METAVERSION_LABEL="Joomla Version" COM_CONFIG_FIELD_OFFLINE_IMAGE_LABEL="Offline Image" -COM_CONFIG_FIELD_OFFLINE_MESSAGE_DESC="The custom offline message will be used if the 'Offline Message' field is set to 'Use Custom Message'." COM_CONFIG_FIELD_OFFLINE_MESSAGE_LABEL="Custom Message" -COM_CONFIG_FIELD_PROXY_ENABLE_DESC="Enable Joomla to use a proxy which is needed in some server environments to fetch URLs like in the Joomla Update component." COM_CONFIG_FIELD_PROXY_ENABLE_LABEL="Enable Proxy" -COM_CONFIG_FIELD_PROXY_HOST_DESC="Enter the name of the host of your Proxy server." COM_CONFIG_FIELD_PROXY_HOST_LABEL="Proxy Host" -COM_CONFIG_FIELD_PROXY_PASSWORD_DESC="Enter your Proxy password." COM_CONFIG_FIELD_PROXY_PASSWORD_LABEL="Proxy Password" -COM_CONFIG_FIELD_PROXY_PORT_DESC="Enter the port that Proxy should be accessed by." COM_CONFIG_FIELD_PROXY_PORT_LABEL="Proxy Port" -COM_CONFIG_FIELD_PROXY_USERNAME_DESC="The username used to access the Proxy server." COM_CONFIG_FIELD_PROXY_USERNAME_LABEL="Proxy Username" -COM_CONFIG_FIELD_SECRET_DESC="This is an auto-generated, unique alphanumeric code for every Joomla installation. It is used for security functions." -COM_CONFIG_FIELD_SECRET_LABEL="Secret" -COM_CONFIG_FIELD_SEF_REWRITE_DESC="Select to use a server's rewrite engine to catch URLs that meet specific conditions and rewrite them as directed. Available for IIS 7 and Apache.
    Apache users only!
    Rename htaccess.txt to .htaccess before activating.
    IIS 7 users only!
    Rename web.config.txt to web.config and install IIS URL Rewrite Module before activating.
    " +COM_CONFIG_FIELD_SEF_REWRITE_DESC="Available for IIS 7 and Apache.
    Apache users only!
    Rename htaccess.txt to .htaccess before activating.
    IIS 7 users only!
    Rename web.config.txt to web.config and install IIS URL Rewrite Module before activating.
    " COM_CONFIG_FIELD_SEF_REWRITE_LABEL="Use URL Rewriting" -COM_CONFIG_FIELD_SEF_SUFFIX_DESC="If yes, the system will add a suffix to the URL based on the document type." COM_CONFIG_FIELD_SEF_SUFFIX_LABEL="Add Suffix to URL" -COM_CONFIG_FIELD_SEF_URL_DESC="Select if the URLs are optimised for Search Engines." COM_CONFIG_FIELD_SEF_URL_LABEL="Search Engine Friendly URLs" -COM_CONFIG_FIELD_SERVER_TIMEZONE_DESC="Choose a city in the list to configure the date and time for display." COM_CONFIG_FIELD_SERVER_TIMEZONE_LABEL="Server Time Zone" -COM_CONFIG_FIELD_SESSION_HANDLER_DESC="The mechanism by which Joomla identifies a User once they are connected to the website using non-persistent cookies.
    If 'PHP' is selected, the session.save_handler value from the PHP configuration will be used." +COM_CONFIG_FIELD_FILESYSTEM_PATH_DESC="The filesystem path where session data will be stored.
    If empty, the system's temporary directory will be used." +COM_CONFIG_FIELD_FILESYSTEM_PATH_LABEL="Session Save Path" COM_CONFIG_FIELD_SESSION_HANDLER_LABEL="Session Handler" -COM_CONFIG_FIELD_SESSION_TIME_DESC="Auto log out a User after they have been inactive for the entered number of minutes. Do not set too high." -COM_CONFIG_FIELD_SESSION_TIME_LABEL="Session Lifetime" +COM_CONFIG_FIELD_SESSION_METADATA_DESC="If enabled, additional metadata about a user's session (including their username, user ID, and which application they are logged into) will be logged to the session database table.
    If disabled, features dependent on this data will be unavailable." +COM_CONFIG_FIELD_SESSION_METADATA_LABEL="Track Session Metadata" +COM_CONFIG_FIELD_SESSION_TIME_LABEL="Session Lifetime (minutes)" COM_CONFIG_FIELD_SHARED_SESSION_DESC="When enabled, a user's session is shared between the frontend and administrator sections of the site. Note that changing this value will invalidate all existing sessions on the site. This is not available when the \"Force HTTPS\" option is set to \"Administrator Only\"." COM_CONFIG_FIELD_SHARED_SESSION_LABEL="Shared Sessions" -COM_CONFIG_FIELD_SITE_DISPLAY_MESSAGE_DESC="Display or not a Frontend message when the site is offline. The custom offline message uses the value defined in the 'Custom message' field. The language offline message uses the value defined in the site language ini file." COM_CONFIG_FIELD_SITE_DISPLAY_MESSAGE_LABEL="Offline Message" -COM_CONFIG_FIELD_SITE_NAME_DESC="Enter the name of your website. This will be used in various locations (eg the Backend browser title bar and Site Offline pages)." COM_CONFIG_FIELD_SITE_NAME_LABEL="Site Name" -COM_CONFIG_FIELD_SITE_OFFLINE_DESC="Select if access to the Site Frontend is available. If Yes, the Frontend will display or not a message depending on the settings below." COM_CONFIG_FIELD_SITE_OFFLINE_LABEL="Site Offline" -COM_CONFIG_FIELD_SITENAME_PAGETITLES_DESC="Begin or end all Page Titles with the site name (for example, My Site Name - My Article Name)." COM_CONFIG_FIELD_SITENAME_PAGETITLES_LABEL="Site Name in Page Titles" -COM_CONFIG_FIELD_TEMP_PATH_DESC="Please specify a writable folder to store temporary files." COM_CONFIG_FIELD_TEMP_PATH_LABEL="Path to Temp Folder" -COM_CONFIG_FIELD_UNICODESLUGS_DESC="Choose between transliteration and unicode aliases. Transliteration is the default." COM_CONFIG_FIELD_UNICODESLUGS_LABEL="Unicode Aliases" COM_CONFIG_FIELD_VALUE_ADMINISTRATOR_ONLY="Administrator Only" COM_CONFIG_FIELD_VALUE_AFTER="After" @@ -234,7 +146,6 @@ COM_CONFIG_FTP_DETAILS="FTP Login Details" COM_CONFIG_FTP_DETAILS_TIP="For updating your configuration.php file, Joomla will most likely need your FTP account details. Please enter them in the form fields below." COM_CONFIG_FTP_SETTINGS="FTP Settings" COM_CONFIG_GLOBAL_CONFIGURATION="Global Configuration" -COM_CONFIG_HELPREFRESH_SUCCESS="The Help Sites list has been refreshed." COM_CONFIG_LOCATION_SETTINGS="Location Settings" COM_CONFIG_MAIL_SETTINGS="Mail Settings" COM_CONFIG_METADATA_SETTINGS="Metadata Settings" @@ -243,11 +154,8 @@ COM_CONFIG_PERMISSIONS="Permissions" COM_CONFIG_PROXY_SETTINGS="Proxy Settings" COM_CONFIG_SAVE_SUCCESS="Configuration saved." COM_CONFIG_SENDMAIL_ACTION_BUTTON="Send Test Mail" -COM_CONFIG_SENDMAIL_BODY="This is a test mail sent using "_QQ_"%s"_QQ_". Your email settings are correct!" +COM_CONFIG_SENDMAIL_BODY="This is a test mail sent using \"%s\". Your email settings are correct!" COM_CONFIG_SENDMAIL_ERROR="Test mail could not be sent." -COM_CONFIG_SENDMAIL_METHOD_MAIL="PHP Mail" -COM_CONFIG_SENDMAIL_METHOD_SENDMAIL="Sendmail" -COM_CONFIG_SENDMAIL_METHOD_SMTP="SMTP" COM_CONFIG_SENDMAIL_SUBJECT="Test mail from %s" COM_CONFIG_SENDMAIL_SUCCESS="The email was sent to %s using %s. You should check that you've received the test email." COM_CONFIG_SENDMAIL_SUCCESS_FALLBACK="The email was sent to %s but using %s as fallback. You should check that you've received the test email." @@ -260,6 +168,6 @@ COM_CONFIG_SYSTEM="System" COM_CONFIG_SYSTEM_SETTINGS="System Settings" COM_CONFIG_TEXT_FILTER_SETTINGS="Text Filter Settings" COM_CONFIG_TEXT_FILTERS="Text Filters" -COM_CONFIG_TEXT_FILTERS_DESC="These text filter settings will be applied to all text editor fields in the selected groups.
    These filtering options give more control over the HTML your content providers submit. You can be as strict or as liberal as you require to suit your site's needs. The filtering is opt-in and the default settings provide good protection against markup commonly associated with website attacks." +COM_CONFIG_TEXT_FILTERS_DESC="These text filter settings will be applied to all text editor fields in the selected groups.
    These filtering options give more control over the HTML your content providers submit. You can be as strict or as liberal as you require to suit your site's needs. The filtering is opt-in and the default settings provide good protection against markup commonly associated with website attacks." COM_CONFIG_XML_DESCRIPTION="Configuration Manager" -JLIB_RULES_SETTING_NOTES="If you change the setting, it will apply to this and all child groups, components and content. Note that:
    Inherited means that the permissions from the parent group will be used.
    Denied means that no matter what the parent group's setting is, the group being edited can't take this action.
    Allowed means that the group being edited will be able to take this action (but if this is in conflict with the parent group it will have no impact; a conflict will be indicated by Not Allowed (Locked) under Calculated Settings).
    Not Set is used only for the Public group in global configuration. The Public group is the parent of all other groups. If a permission is not set, it is treated as deny but can be changed for child groups, components, categories and items." +JLIB_RULES_SETTING_NOTES="If you change the setting, it will apply to this and all child groups, components and content. Note that:
    Inherited means that the permissions from the parent group will be used.
    Denied means that no matter what the parent group's setting is, the group being edited can't take this action.
    Allowed means that the group being edited will be able to take this action (but if this is in conflict with the parent group it will have no impact; a conflict will be indicated by Not Allowed (Locked) under Calculated Settings).
    Not Set is used only for the Public group in global configuration. The Public group is the parent of all other groups. If a permission is not set, it is treated as deny but can be changed for child groups, components, categories and items." diff --git a/administrator/language/en-GB/en-GB.com_contact.ini b/administrator/language/en-GB/en-GB.com_contact.ini index b9e861fddc559..d04409f611a63 100644 --- a/administrator/language/en-GB/en-GB.com_contact.ini +++ b/administrator/language/en-GB/en-GB.com_contact.ini @@ -5,20 +5,14 @@ COM_CONTACT="Contacts" COM_CONTACT_BASIC_OPTIONS_FIELDSET_LABEL="Contact Display Options" -; COM_CONTACT_BATCH_MENU_LABEL is deprecated, use JLIB_HTML_BATCH_MENU_LABEL instead. -COM_CONTACT_BATCH_MENU_LABEL="To Move or Copy your selection please select a Category." COM_CONTACT_BATCH_OPTIONS="Batch process the selected contacts" COM_CONTACT_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved contacts. Otherwise, all actions are applied to the selected contacts." COM_CONTACT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of contact categories within a category." COM_CONTACT_CATEGORY_VIEW_DEFAULT_DESC="This view lists the contacts in a category." COM_CONTACT_CHANGE_CONTACT="Select or Change Contact" -; COM_CONTACT_CHANGE_CONTACT_BUTTON deprecated, use COM_CONTACT_CHANGE_CONTACT instead. -COM_CONTACT_CHANGE_CONTACT_BUTTON="Change Contact" COM_CONTACT_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Contact Component will integrate with other extensions." COM_CONTACT_CONFIGURATION="Contacts: Options" COM_CONTACT_CONTACT_DETAILS="Details" -COM_CONTACT_CONTACT_DISPLAY_DETAILS="Display options for the individual contact page." -COM_CONTACT_CONTACT_SETTINGS_LABEL="Contact Options" COM_CONTACT_CONTACT_VIEW_DEFAULT_DESC="This links to the contact information for one contact." COM_CONTACT_CONTACTS="Contacts" COM_CONTACT_DETAILS="Contact Information" @@ -26,65 +20,37 @@ COM_CONTACT_EDIT_CONTACT="Edit Contact" COM_CONTACT_EDIT_DETAILS="Edit contact information displayed on an individual page." COM_CONTACT_ERROR_UNIQUE_ALIAS="Another Contact from this category has the same alias (remember it may be a trashed item)." COM_CONTACT_ERROR_ALL_LANGUAGE_ASSOCIATED="A contact item set to All languages can't be associated. Associations have not been set." -COM_CONTACT_FIELD_ARTICLES_DISPLAY_NUM_DESC="Number of articles to list." COM_CONTACT_FIELD_ARTICLES_DISPLAY_NUM_LABEL="# Articles to List" -COM_CONTACT_FIELD_ARTICLES_SHOW_DESC="If this contact is mapped to a user, and if this is set to Show, then a list of articles created by this user will show." -COM_CONTACT_FIELD_ARTICLES_SHOW_LABEL="Show User Articles" -COM_CONTACT_FIELD_BREADCRUMBS_DESC="Show or hide category breadcrumbs." -COM_CONTACT_FIELD_BREADCRUMBS_LABEL="Show Category Breadcrumbs" -COM_CONTACT_FIELD_CAPTCHA_DESC="Select the captcha plugin that will be used in the contact form. You may need to enter required information for your captcha plugin in the Plugin Manager.
    If 'Use Global' is selected, make sure a captcha plugin is selected in Global Configuration." +COM_CONTACT_FIELD_ARTICLES_SHOW_LABEL="User Articles" COM_CONTACT_FIELD_CAPTCHA_LABEL="Allow Captcha on Contact" -COM_CONTACT_FIELD_CATEGORIES_DESC="Displays a list of contact categories within a category." -COM_CONTACT_FIELD_CATEGORIES_LABEL="Choose a Parent Category" -COM_CONTACT_FIELD_CATEGORY_DESC="Select a contact category to display." COM_CONTACT_FIELD_CATEGORY_LABEL="Select a Category" -COM_CONTACT_FIELD_CONFIG_ALLOW_VCARD_DESC="Allow vCard to be displayed." -COM_CONTACT_FIELD_CONFIG_ALLOW_VCARD_LABEL="Allow vCard" -COM_CONTACT_FIELD_CONFIG_BANNED_EMAIL_DESC="Email addresses not allowed to submit contact form. Separate multiple email addresses with a semicolon." -COM_CONTACT_FIELD_CONFIG_BANNED_EMAIL_LABEL="Banned Email" -COM_CONTACT_FIELD_CONFIG_BANNED_SUBJECT_DESC="Subjects not allowed in contact form. Separate multiple subjects with a semicolon." +COM_CONTACT_FIELD_CONFIG_BANNED_EMAIL_DESC="Separate multiple email addresses with a semicolon." +COM_CONTACT_FIELD_CONFIG_BANNED_EMAIL_LABEL="Banned Email Address" +COM_CONTACT_FIELD_CONFIG_BANNED_SUBJECT_DESC=" Separate multiple subjects with a semicolon." COM_CONTACT_FIELD_CONFIG_BANNED_SUBJECT_LABEL="Banned Subject" -COM_CONTACT_FIELD_CONFIG_BANNED_TEXT_DESC="Text not allowed in contact form body. Separate multiple words with a semicolon." +COM_CONTACT_FIELD_CONFIG_BANNED_TEXT_DESC="Separate multiple words with a semicolon." COM_CONTACT_FIELD_CONFIG_BANNED_TEXT_LABEL="Banned Text" COM_CONTACT_FIELD_CONFIG_CATEGORIES_DESC="These settings apply for Contact Categories Options unless they are changed for a specific menu item." COM_CONTACT_FIELD_CONFIG_CATEGORY_DESC="These settings apply for Contact Category Options unless they are changed for a specific menu item." COM_CONTACT_FIELD_CONFIG_CONTACT_FORM="Form" -COM_CONTACT_FIELD_CONFIG_COUNTRY_DESC="Show or hide a Country column in the list of Contacts." COM_CONTACT_FIELD_CONFIG_COUNTRY_LABEL="Country" -COM_CONTACT_FIELD_CONFIG_CUSTOM_REPLY_DESC="Turns off the automated reply, allowing for Plugins to handle integration with other systems." COM_CONTACT_FIELD_CONFIG_CUSTOM_REPLY_LABEL="Custom Reply" -COM_CONTACT_FIELD_CONFIG_EMAIL_DESC="Show or hide an Email column in the list of Contacts." -COM_CONTACT_FIELD_CONFIG_FAX_DESC="Show or hide a Fax column in the list of Contacts." COM_CONTACT_FIELD_CONFIG_FAX_LABEL="Fax" COM_CONTACT_FIELD_CONFIG_INDIVIDUAL_CONTACT_DESC="These settings apply for single Contact unless they are changed for a specific menu item or Contact." COM_CONTACT_FIELD_CONFIG_INDIVIDUAL_CONTACT_DISPLAY="Contact" COM_CONTACT_FIELD_CONFIG_SHOW_IMAGE_LABEL="Image" -COM_CONTACT_FIELD_CONFIG_SHOW_IMAGE_DESC="Show or hide an Image column in the list of Contacts." -COM_CONTACT_FIELD_CONFIG_MOBILE_DESC="Show or hide show a Mobile column in the list of Contacts." COM_CONTACT_FIELD_CONFIG_MOBILE_LABEL="Mobile" -COM_CONTACT_FIELD_CONFIG_PHONE_DESC="Show or hide a Phone column in the list of Contacts." COM_CONTACT_FIELD_CONFIG_PHONE_LABEL="Phone" -COM_CONTACT_FIELD_CONFIG_POSITION_DESC="Show or hide a Position column in the list of Contacts." COM_CONTACT_FIELD_CONFIG_POSITION_LABEL="Position" -COM_CONTACT_FIELD_CONFIG_REDIRECT_DESC="Enter an alternative URL where the user will be redirected to after mail is sent." -COM_CONTACT_FIELD_CONFIG_REDIRECT_LABEL="Contact Redirect" -COM_CONTACT_FIELD_CONFIG_SESSION_CHECK_DESC="Check for the existence of session cookie. This means that users without cookies enabled will not be able to send emails." +COM_CONTACT_FIELD_CONFIG_REDIRECT_LABEL="Contact Redirect URL" COM_CONTACT_FIELD_CONFIG_SESSION_CHECK_LABEL="Session Check" COM_CONTACT_FIELD_CONFIG_STATE_LABEL="State or County" -COM_CONTACT_FIELD_CONFIG_STATE_DESC="Show or hide a State or County column in the list of Contacts." -COM_CONTACT_FIELD_CONFIG_SUBURB_DESC="Show or hide a City or Suburb column in the list of Contacts." COM_CONTACT_FIELD_CONFIG_SUBURB_LABEL="City or Suburb" COM_CONTACT_FIELD_CONFIG_TABLE_OF_CONTACTS_DESC="These settings apply for Contact List Options unless they are changed for a specific menu item." -COM_CONTACT_FIELD_CONFIG_VCARD_DESC="Show or hide a vCard column in the list of Contacts." COM_CONTACT_FIELD_CONFIG_VCARD_LABEL="vCard" -COM_CONTACT_FIELD_CONTACT_SHOW_CATEGORY_DESC="If "Hide", the Contact Category will not show. If "Show Without Link", Category will show as text. If "Show With Link", Category will show as a link to a Single Category Menu Item." COM_CONTACT_FIELD_CONTACT_SHOW_CATEGORY_LABEL="Contact Category" -COM_CONTACT_FIELD_CONTACT_SHOW_LIST_DESC="If Show, the user will be able to change which contact is shown by selecting a contact from a dropdown list of all contacts in the current contact category." -COM_CONTACT_FIELD_CONTACT_SHOW_LIST_LABEL="Show Contact List" -COM_CONTACT_FIELD_CREATED_BY_ALIAS_DESC="Enter an alias to be displayed instead of the name of the user who created the contact." +COM_CONTACT_FIELD_CONTACT_SHOW_LIST_LABEL="Contact Select List" COM_CONTACT_FIELD_CREATED_BY_ALIAS_LABEL="Created By Alias" -COM_CONTACT_FIELD_CREATED_BY_DESC="Select the name of the user who created the contact." -COM_CONTACT_FIELD_CREATED_DESC="Date when the contact was created." COM_CONTACT_FIELD_CREATED_LABEL="Created Date" COM_CONTACT_FIELD_EMAIL_BANNED_EMAIL_DESC="Email addresses not allowed to submit contact form. Separate multiple email addresses with a semicolon." COM_CONTACT_FIELD_EMAIL_BANNED_EMAIL_LABEL="Banned Email" @@ -92,143 +58,70 @@ COM_CONTACT_FIELD_EMAIL_BANNED_SUBJECT_DESC="Subjects not allowed in contact for COM_CONTACT_FIELD_EMAIL_BANNED_SUBJECT_LABEL="Banned Subject" COM_CONTACT_FIELD_EMAIL_BANNED_TEXT_DESC="Text not allowed in contact form body. Separate multiple words with a semicolon." COM_CONTACT_FIELD_EMAIL_BANNED_TEXT_LABEL="Banned Text" -COM_CONTACT_FIELD_EMAIL_EMAIL_COPY_DESC="Hide or Show checkbox to allow copy of email to be sent to submitter." COM_CONTACT_FIELD_EMAIL_EMAIL_COPY_LABEL="Send Copy to Submitter" -COM_CONTACT_FIELD_EMAIL_SHOW_FORM_DESC="Show or hide the contact form." COM_CONTACT_FIELD_EMAIL_SHOW_FORM_LABEL="Contact Form" -COM_CONTACT_FIELD_FEATURED_DESC="If marked yes, will be displayed in featured view." -COM_CONTACT_FIELD_FEEDLINK_DESC="Show or hide a feed link for this contact category." -COM_CONTACT_FIELD_FEEDLINK_LABEL="Feed Link" -COM_CONTACT_FIELD_ICONS_ADDRESS_DESC="Select or upload an image for the Address icon. If none selected, the default icon will be displayed." -COM_CONTACT_FIELD_ICONS_ADDRESS_LABEL="Address Icon" -COM_CONTACT_FIELD_ICONS_EMAIL_DESC="Select or upload an image for the Email icon. If none selected, the default icon will be displayed." -COM_CONTACT_FIELD_ICONS_EMAIL_LABEL="Email Icon" -COM_CONTACT_FIELD_ICONS_FAX_DESC="Select or upload an image for the Fax icon. If none selected, the default icon will be displayed." -COM_CONTACT_FIELD_ICONS_FAX_LABEL="Fax Icon" -COM_CONTACT_FIELD_ICONS_MISC_DESC="Select or upload an image for the Misc icon. If none selected, the default icon will be displayed." -COM_CONTACT_FIELD_ICONS_MISC_LABEL="Misc Icon" -COM_CONTACT_FIELD_ICONS_MOBILE_DESC="Select or upload an image for the Mobile icon. If none selected, the default icon will be displayed." -COM_CONTACT_FIELD_ICONS_MOBILE_LABEL="Mobile Icon" -COM_CONTACT_FIELD_ICONS_SETTINGS_DESC="Show icons, text or nothing next to the information." +COM_CONTACT_FIELD_ICONS_ADDRESS_LABEL="Custom Address Icon" +COM_CONTACT_FIELD_ICONS_EMAIL_LABEL="Custom Email Icon" +COM_CONTACT_FIELD_ICONS_FAX_LABEL="Custom Fax Icon" +COM_CONTACT_FIELD_ICONS_MISC_LABEL="Custom Misc Icon" +COM_CONTACT_FIELD_ICONS_MOBILE_LABEL="Custom Mobile Icon" COM_CONTACT_FIELD_ICONS_SETTINGS_LABEL="Settings" -COM_CONTACT_FIELD_ICONS_TELEPHONE_DESC="Select or upload an image for the Telephone icon. If none selected, the default icon will be displayed." -COM_CONTACT_FIELD_ICONS_TELEPHONE_LABEL="Telephone Icon" -COM_CONTACT_FIELD_IMAGE_ALIGN_DESC="Alignment of the image." -COM_CONTACT_FIELD_IMAGE_ALIGN_LABEL="Image Alignment" -COM_CONTACT_FIELD_INFORMATION_ADDRESS_DESC="Contact's address." +COM_CONTACT_FIELD_ICONS_TELEPHONE_LABEL="Custom Telephone Icon" COM_CONTACT_FIELD_INFORMATION_ADDRESS_LABEL="Address" -COM_CONTACT_FIELD_INFORMATION_COUNTRY_DESC="Contact's country." COM_CONTACT_FIELD_INFORMATION_COUNTRY_LABEL="Country" -COM_CONTACT_FIELD_INFORMATION_EMAIL_DESC="Contact's email." -COM_CONTACT_FIELD_INFORMATION_FAX_DESC="Contact's fax." COM_CONTACT_FIELD_INFORMATION_FAX_LABEL="Fax" -COM_CONTACT_FIELD_INFORMATION_MISC_DESC="Contact's miscellaneous information." COM_CONTACT_FIELD_INFORMATION_MISC_LABEL="Miscellaneous Information" -COM_CONTACT_FIELD_INFORMATION_MOBILE_DESC="Contact's mobile phone." COM_CONTACT_FIELD_INFORMATION_MOBILE_LABEL="Mobile" -COM_CONTACT_FIELD_INFORMATION_POSITION_DESC="Contact's position." COM_CONTACT_FIELD_INFORMATION_POSITION_LABEL="Position" -COM_CONTACT_FIELD_INFORMATION_POSTCODE_DESC="Contact's Postal/ZIP code." COM_CONTACT_FIELD_INFORMATION_POSTCODE_LABEL="Postal/ZIP Code" -COM_CONTACT_FIELD_INFORMATION_STATE_DESC="Contact's state or province." COM_CONTACT_FIELD_INFORMATION_STATE_LABEL="State or Province" -COM_CONTACT_FIELD_INFORMATION_SUBURB_DESC="Contact's city or suburb." COM_CONTACT_FIELD_INFORMATION_SUBURB_LABEL="City or Suburb" -COM_CONTACT_FIELD_INFORMATION_TELEPHONE_DESC="Contact's telephone." COM_CONTACT_FIELD_INFORMATION_TELEPHONE_LABEL="Telephone" -COM_CONTACT_FIELD_INFORMATION_WEBPAGE_DESC="Contact's Website. IDN (International) Links are converted to punycode when they are saved." COM_CONTACT_FIELD_INFORMATION_WEBPAGE_LABEL="Website" -COM_CONTACT_FIELD_INITIAL_SORT_DESC="Choose the field or fields by which contacts will be sorted." COM_CONTACT_FIELD_INITIAL_SORT_LABEL="Sort By" -COM_CONTACT_FIELD_LANGUAGE_DESC="Assign a language for this contact." -COM_CONTACT_FIELD_LIMIT_BOX_DESC="Show or hide limit box." -COM_CONTACT_FIELD_LIMIT_BOX_LABEL="Limit box" -COM_CONTACT_FIELD_LINK_NAME_DESC="An additional link for this contact." -COM_CONTACT_FIELD_LINKA_DESC="Enter a URL for Link A." COM_CONTACT_FIELD_LINKA_LABEL="Link A URL" COM_CONTACT_FIELD_LINKA_NAME_LABEL="Link A Label" -COM_CONTACT_FIELD_LINKB_DESC="Enter a URL for Link B." COM_CONTACT_FIELD_LINKB_LABEL="Link B URL" COM_CONTACT_FIELD_LINKB_NAME_LABEL="Link B Label" -COM_CONTACT_FIELD_LINKC_DESC="Enter a URL for Link C." COM_CONTACT_FIELD_LINKC_LABEL="Link C URL" COM_CONTACT_FIELD_LINKC_NAME_LABEL="Link C Label" -COM_CONTACT_FIELD_LINKD_DESC="Enter a URL for Link D." COM_CONTACT_FIELD_LINKD_LABEL="Link D URL" COM_CONTACT_FIELD_LINKD_NAME_LABEL="Link D Label" -COM_CONTACT_FIELD_LINKE_DESC="Enter a URL for Link E." COM_CONTACT_FIELD_LINKE_LABEL="Link E URL" COM_CONTACT_FIELD_LINKE_NAME_LABEL="Link E Label" -COM_CONTACT_FIELD_LINKED_USER_DESC="Linked Joomla User." COM_CONTACT_FIELD_LINKED_USER_LABEL="Linked User" COM_CONTACT_FIELD_LINKED_USER_LABEL_ASC="Linked User ascending" COM_CONTACT_FIELD_LINKED_USER_LABEL_DESC="Linked User descending" -COM_CONTACT_FIELD_MODIFIED_BY_DESC="Name of the user who modified this contact." -COM_CONTACT_FIELD_MODIFIED_DESC="The date and time that the contact was last modified." -COM_CONTACT_FIELD_NAME_DESC="Contact name." COM_CONTACT_FIELD_NAME_LABEL="Name" -COM_CONTACT_FIELD_NUM_CONTACTS_DESC="Number of Contacts to display as list." -COM_CONTACT_FIELD_NUM_CONTACTS_LABEL="Number of Contacts" -COM_CONTACT_FIELD_PARAMS_ADD_MAILTO_LINK_DESC="Adds a mailto: link to the displayed email address." COM_CONTACT_FIELD_PARAMS_ADD_MAILTO_LINK_LABEL="Add Mailto: Link" -COM_CONTACT_FIELD_PARAMS_CONTACT_E_MAIL_DESC="Show or hide contact email." -COM_CONTACT_FIELD_PARAMS_CONTACT_POSITION_DESC="Show or hide position." COM_CONTACT_FIELD_PARAMS_CONTACT_POSITION_LABEL="Contact's Position" -COM_CONTACT_FIELD_PARAMS_COUNTRY_DESC="Show or hide country." COM_CONTACT_FIELD_PARAMS_COUNTRY_LABEL="Country" -COM_CONTACT_FIELD_PARAMS_FAX_DESC="Show or hide fax number." COM_CONTACT_FIELD_PARAMS_FAX_LABEL="Fax" -COM_CONTACT_FIELD_PARAMS_IMAGE_DESC="Select or upload the contact image." COM_CONTACT_FIELD_PARAMS_IMAGE_LABEL="Image" -COM_CONTACT_FIELD_PARAMS_MISC_INFO_DESC="Show or hide miscellaneous information." COM_CONTACT_FIELD_PARAMS_MISC_INFO_LABEL="Miscellaneous Information" -COM_CONTACT_FIELD_PARAMS_MOBILE_DESC="Show or hide mobile number." COM_CONTACT_FIELD_PARAMS_MOBILE_LABEL="Mobile Phone" -COM_CONTACT_FIELD_PARAMS_NAME_DESC="Show or hide name of the contact." COM_CONTACT_FIELD_PARAMS_NAME_LABEL="Name" -COM_CONTACT_FIELD_PARAMS_POST-ZIP_CODE_DESC="Show or hide the Postal/ZIP code." COM_CONTACT_FIELD_PARAMS_POST-ZIP_CODE_LABEL="Postal/ZIP Code" -COM_CONTACT_FIELD_PARAMS_SHOW_IMAGE_DESC="Show or hide image." COM_CONTACT_FIELD_PARAMS_SHOW_IMAGE_LABEL="Image" -COM_CONTACT_FIELD_PARAMS_STATE-COUNTY_DESC="Show or hide state or county." COM_CONTACT_FIELD_PARAMS_STATE-COUNTY_LABEL="State or County" -COM_CONTACT_FIELD_PARAMS_STREET_ADDRESS_DESC="Show or hide street address." COM_CONTACT_FIELD_PARAMS_STREET_ADDRESS_LABEL="Street Address" -COM_CONTACT_FIELD_PARAMS_TELEPHONE_DESC="Show or hide telephone number." COM_CONTACT_FIELD_PARAMS_TELEPHONE_LABEL="Telephone" -COM_CONTACT_FIELD_PARAMS_TOWN-SUBURB_DESC="Show or hide city or suburb." COM_CONTACT_FIELD_PARAMS_TOWN-SUBURB_LABEL="City or Suburb" -COM_CONTACT_FIELD_PARAMS_VCARD_DESC="Show or hide a link to allow export to vCard format." COM_CONTACT_FIELD_PARAMS_VCARD_LABEL="vCard" -COM_CONTACT_FIELD_PARAMS_WEBPAGE_DESC="Show or hide webpage." COM_CONTACT_FIELD_PARAMS_WEBPAGE_LABEL="Webpage" -COM_CONTACT_FIELD_PRESENTATION_DESC="Determines the style used to display sections of the contact form." COM_CONTACT_FIELD_PRESENTATION_LABEL="Display Format" -COM_CONTACT_FIELD_PROFILE_SHOW_DESC="If the contact is mapped to a user and this option is set to Show, then the profile of the user will be shown in the contact details." COM_CONTACT_FIELD_PROFILE_SHOW_LABEL="User Profile" -COM_CONTACT_FIELD_PUBLISH_DOWN_DESC="An optional date to Finish Publishing the contact." COM_CONTACT_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" -COM_CONTACT_FIELD_PUBLISH_UP_DESC="An optional date to Start Publishing the contact." COM_CONTACT_FIELD_PUBLISH_UP_LABEL="Start Publishing" -COM_CONTACT_FIELD_SHOW_CAT_ITEMS_DESC="Show or hide the number of contacts in category." COM_CONTACT_FIELD_SHOW_CAT_ITEMS_LABEL="# Contacts in Category" -COM_CONTACT_FIELD_SHOW_CATEGORY_DESC="Displays the category." -COM_CONTACT_FIELD_SHOW_LINKS_DESC="Show or hide the contact links." COM_CONTACT_FIELD_SHOW_LINKS_LABEL="Contact Links" -COM_CONTACT_FIELD_SHOW_CAT_TAGS_DESC="Show or hide the tags for a contact category." COM_CONTACT_FIELD_SHOW_CAT_TAGS_LABEL="Category Tags" -COM_CONTACT_FIELD_SHOW_TAGS_DESC="Show or hide the tags for a contact." COM_CONTACT_FIELD_SHOW_TAGS_LABEL="Tags" COM_CONTACT_FIELD_SHOW_INFO_LABEL="Contact Information" -COM_CONTACT_FIELD_SHOW_INFO_DESC="Show or hide the contact information." -COM_CONTACT_FIELD_SORTNAME1_DESC="The part of the name to use as the first sort field." COM_CONTACT_FIELD_SORTNAME1_LABEL="First Sort Field" -COM_CONTACT_FIELD_SORTNAME2_DESC="The part of the name to use as the second sort field." COM_CONTACT_FIELD_SORTNAME2_LABEL="Second Sort Field" -COM_CONTACT_FIELD_SORTNAME3_DESC="The part of the name to use as the third sort field." COM_CONTACT_FIELD_SORTNAME3_LABEL="Third Sort Field" -COM_CONTACT_FIELD_USER_CUSTOM_FIELDS_SHOW_LABEL="Show User Custom Fields" -COM_CONTACT_FIELD_USER_CUSTOM_FIELDS_SHOW_DESC="Show user custom fields which belong to all or only selected field groups." +COM_CONTACT_FIELD_USER_CUSTOM_FIELDS_SHOW_LABEL="User Custom Fields" COM_CONTACT_FIELD_VALUE_ICONS="Icons" COM_CONTACT_FIELD_VALUE_NAME="Name" COM_CONTACT_FIELD_VALUE_NO_LINK="Show Without Link" @@ -242,7 +135,6 @@ COM_CONTACT_FIELD_VALUE_TEXT="Text" COM_CONTACT_FIELD_VALUE_USE_CONTACT_SETTINGS="Use Contact Settings" COM_CONTACT_FIELD_VALUE_WITH_LINK="Show With Link" COM_CONTACT_FIELD_VERSION_LABEL="Revision" -COM_CONTACT_FIELD_VERSION_DESC="A count of the number of times this contact has been revised." COM_CONTACT_FIELDS_CONTACT_FIELDS_TITLE="Contacts: Fields" COM_CONTACT_FIELDS_CONTACT_FIELD_ADD_TITLE="Contacts: New Field" COM_CONTACT_FIELDS_CONTACT_FIELD_EDIT_TITLE="Contacts: Edit Field" @@ -251,26 +143,18 @@ COM_CONTACT_FIELDS_CONTEXT_MAIL="Mail" COM_CONTACT_FIELDSET_CONTACT_FORM="Contact form" COM_CONTACT_FIELDSET_CONTACT_LABEL="Form" COM_CONTACT_FIELDSET_CONTACTFORM_LABEL="Mail Options" -COM_CONTACT_FIELDSET_OPTIONS="Display Options" -COM_CONTACT_FILTER_DESC="Choose the type of filter to display per default." COM_CONTACT_FILTER_LABEL="Filter field" COM_CONTACT_FILTER_SEARCH_DESC="Search in contact name and alias. Prefix with ID: to search for a contact ID." COM_CONTACT_FILTER_SEARCH_LABEL="Search Contacts" COM_CONTACT_ICONS_SETTINGS="Icons" COM_CONTACT_HEADING_ASSOCIATION="Association" -COM_CONTACT_HITS_DESC="Number of hits for this contact." COM_CONTACT_ID_LABEL="ID" -; The following 2 strings are deprecated and will be removed with 4.0. -COM_CONTACT_ITEM_ASSOCIATIONS_FIELDSET_LABEL="Contact Item Associations" -COM_CONTACT_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a contact item for the target language. This association will let the Language Switcher module redirect to the associated contact item in another language. If used, make sure to display the Language switcher module on the relevant pages. A contact item set to language 'All' can't be associated." COM_CONTACT_MAIL_FIELDSET_LABEL="Mail Options" -COM_CONTACT_MANAGER_CONTACT="Contacts: New/Edit" COM_CONTACT_MANAGER_CONTACT_EDIT="Contacts: Edit" COM_CONTACT_MANAGER_CONTACT_NEW="Contacts: New" COM_CONTACT_MANAGER_CONTACTS="Contacts" COM_CONTACT_N_ITEMS_ARCHIVED="%d contacts archived." COM_CONTACT_N_ITEMS_ARCHIVED_1="%d contact archived." -COM_CONTACT_N_ITEMS_CHECKED_IN_0="No contact checked in." COM_CONTACT_N_ITEMS_CHECKED_IN_1="%d contact checked in." COM_CONTACT_N_ITEMS_CHECKED_IN_MORE="%d contacts checked in." COM_CONTACT_N_ITEMS_DELETED="%d contacts deleted." @@ -285,31 +169,23 @@ COM_CONTACT_N_ITEMS_UNFEATURED="%d contacts unfeatured." COM_CONTACT_N_ITEMS_UNFEATURED_1="%d contact unfeatured." COM_CONTACT_N_ITEMS_UNPUBLISHED="%d contacts unpublished." COM_CONTACT_N_ITEMS_UNPUBLISHED_1="%d contact unpublished." -COM_CONTACT_NAME_DESC="Contact name." COM_CONTACT_NEW_CONTACT="New Contact" COM_CONTACT_NO_ITEM_SELECTED="No contacts selected." -COM_CONTACT_OPTIONS="Options" COM_CONTACT_SAVE_SUCCESS="Contact saved." COM_CONTACT_SEARCH_IN_NAME="Search contacts by name" COM_CONTACT_SELECT_A_CONTACT="Select a Contact" -COM_CONTACT_SELECT_CONTACT_DESC="Select or create a contact to be displayed." COM_CONTACT_SELECT_CONTACT_LABEL="Select Contact" COM_CONTACT_SELECT_USER="Select User" -COM_CONTACT_SHOW_EMAIL_ADDRESS_DESC="Show email address." COM_CONTACT_SHOW_EMAIL_ADDRESS_LABEL="Email Address" -COM_CONTACT_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no Contacts or subcategories." COM_CONTACT_SUBMENU_CATEGORIES="Categories" COM_CONTACT_SUBMENU_CONTACTS="Contacts" COM_CONTACT_TIP_ASSOCIATION="Associated contacts" -COM_CONTACT_TOGGLE_TO_FEATURE="Toggle to change contact state to 'Featured'." -COM_CONTACT_TOGGLE_TO_UNFEATURE="Toggle to change contact state to 'Unfeatured'." COM_CONTACT_UNFEATURED="Unfeatured contact" COM_CONTACT_WARNING_CATEGORY="This category is invalid." COM_CONTACT_WARNING_PROVIDE_VALID_NAME="Please provide a valid name." COM_CONTACT_WARNING_PROVIDE_VALID_URL="Please provide a valid URL." -COM_CONTACT_WARNING_SELECT_CONTACT_TOPUBLISH="Please select a contact to publish." COM_CONTACT_XML_DESCRIPTION="This component shows a listing of contact information." JGLOBAL_FIELDSET_MISCELLANEOUS="Miscellaneous Information" JGLOBAL_NEWITEMSLAST_DESC="New Contacts default to the last position. Ordering can be changed after this Contact is saved." JLIB_HTML_BATCH_USER_LABEL="Set Linked User" -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_contact.sys.ini b/administrator/language/en-GB/en-GB.com_contact.sys.ini index c65d6e6a9043c..c7e4820a281e1 100644 --- a/administrator/language/en-GB/en-GB.com_contact.sys.ini +++ b/administrator/language/en-GB/en-GB.com_contact.sys.ini @@ -8,8 +8,6 @@ COM_CONTACT_CATEGORIES="Categories" COM_CONTACT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of contact categories within a category." COM_CONTACT_CATEGORIES_VIEW_DEFAULT_OPTION="Default" COM_CONTACT_CATEGORIES_VIEW_DEFAULT_TITLE="List All Contact Categories" -COM_CONTACT_CATEGORY_ADD_TITLE="Contacts: New Category" -COM_CONTACT_CATEGORY_EDIT_TITLE="Contacts: Edit Category" COM_CONTACT_CATEGORY_VIEW_DEFAULT_DESC="This view lists the contacts in a category." COM_CONTACT_CATEGORY_VIEW_DEFAULT_OPTION="Default" COM_CONTACT_CATEGORY_VIEW_DEFAULT_TITLE="List Contacts in a Category" diff --git a/administrator/language/en-GB/en-GB.com_content.ini b/administrator/language/en-GB/en-GB.com_content.ini index deaddc6e90c9e..5c377cde054c2 100644 --- a/administrator/language/en-GB/en-GB.com_content.ini +++ b/administrator/language/en-GB/en-GB.com_content.ini @@ -3,22 +3,20 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 + COM_CONTENT="Articles" -COM_CONTENT_ACCESS_DELETE_DESC="New setting for delete actions on this article and the calculated setting based on the parent category and group permissions." -COM_CONTENT_ACCESS_EDIT_DESC="New setting for edit actions on this article and the calculated setting based on the parent category and group permissions." -COM_CONTENT_ACCESS_EDITSTATE_DESC="New setting for edit state actions on this article and the calculated setting based on the parent category and group permissions." +COM_CONTENT_ADD_NEW_MENU_ITEM="New Menu Item" +COM_CONTENT_ARTICLES_CAPTION="Table of articles" COM_CONTENT_ARTICLE_CONTENT="Content" -COM_CONTENT_ARTICLE_DETAILS="Article Details" COM_CONTENT_ARTICLES_TITLE="Articles" +COM_CONTENT_ARTICLE_CONTENT="Content" COM_CONTENT_ATTRIBS_ARTICLE_SETTINGS_LABEL="Options" COM_CONTENT_ATTRIBS_FIELDSET_LABEL="Options" -; COM_CONTENT_BATCH_MENU_LABEL is deprecated, use JLIB_HTML_BATCH_MENU_LABEL instead. -COM_CONTENT_BATCH_MENU_LABEL="To Move or Copy your selection please select a Category." COM_CONTENT_BATCH_OPTIONS="Batch process the selected articles" COM_CONTENT_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved articles. Otherwise, all actions are applied to the selected articles." COM_CONTENT_CHANGE_ARTICLE="Select or Change article" COM_CONTENT_CHANGE_ARTICLE_BUTTON="Select/Change" -COM_CONTENT_CHOOSE_CATEGORY_DESC="Select a parent category." +COM_CONTENT_CONFIGURATION="Articles: Options" COM_CONTENT_CONFIG_ARTICLE_SETTINGS_DESC="These settings apply for article layouts unless they are changed for a specific menu item." COM_CONTENT_CONFIG_BLOG_SETTINGS_DESC="These settings apply for blog or featured layouts unless they are changed for a specific menu item." COM_CONTENT_CONFIG_BLOG_SETTINGS_LABEL="Blog/Featured Layouts" @@ -27,119 +25,87 @@ COM_CONTENT_CONFIG_CATEGORY_SETTINGS_DESC="These settings apply for Articles Cat COM_CONTENT_CONFIG_EDITOR_LAYOUT="These options control the layout of the article editing page." COM_CONTENT_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Article Component will integrate with other extensions." COM_CONTENT_CONFIG_LIST_SETTINGS_DESC="These settings apply for List Layouts Options unless they are changed for a specific menu item or category." -COM_CONTENT_CONFIGURATION="Articles: Options" COM_CONTENT_CREATE_ARTICLE_CANCEL_REDIRECT_MENU_DESC="Select the page the user will be redirected to after Canceling article submission. The default is to redirect to the same article submission page (cleaning form)." COM_CONTENT_CREATE_ARTICLE_CANCEL_REDIRECT_MENU_LABEL="Cancel Redirect" COM_CONTENT_CREATE_ARTICLE_CATEGORY_LABEL="Default Category" -COM_CONTENT_CREATE_ARTICLE_CATEGORY_DESC="If set to 'Yes', this page will only let you create articles in the category selected below." -COM_CONTENT_CREATE_ARTICLE_CUSTOM_CANCEL_REDIRECT_DESC="If set to 'Yes', you can set a redirection page, distinct from above 'Submission/Cancel Redirect', to redirect to when user Cancels article submission.
    If set to 'No', when user Cancels article submission, the user is redirected to the above 'Submission/Cancel Redirect' page." +COM_CONTENT_CREATE_ARTICLE_CUSTOM_CANCEL_REDIRECT_DESC="If set to 'Yes', you can set a redirection page, distinct from above 'Submission/Cancel Redirect', to redirect to when user Cancels article submission.
    If set to 'No', when user Cancels article submission, the user is redirected to the above 'Submission/Cancel Redirect' page." COM_CONTENT_CREATE_ARTICLE_CUSTOM_CANCEL_REDIRECT_LABEL="Custom Redirect on Cancel" COM_CONTENT_CREATE_ARTICLE_REDIRECTMENU_DESC="Select the page the user will be redirected to after a successful article submission and after cancel (if not set differently below). The default is to redirect to the home page." COM_CONTENT_CREATE_ARTICLE_REDIRECTMENU_LABEL="Submission/Cancel Redirect" -COM_CONTENT_DRILL_CATEGORIES_LABEL="List or Blog: after choosing the display,
    make sure you define the Options in the desired layout." -COM_CONTENT_DRILL_DOWN_LAYOUT_DESC="When drilling down to a category, show articles in a list or blog layout." -COM_CONTENT_DRILL_DOWN_LAYOUT_LABEL="List or Blog Layout" -COM_CONTENT_EDIT_ARTICLE="Edit Article" -COM_CONTENT_EDITORCONFIG_FIELDSET_LABEL="Configure Edit Screen" COM_CONTENT_EDITING_LAYOUT="Editing Layout" +COM_CONTENT_EDITORCONFIG_FIELDSET_LABEL="Configure Edit Screen" +COM_CONTENT_EDIT_ARTICLE="Edit Article" COM_CONTENT_ERROR_ALL_LANGUAGE_ASSOCIATED="A content item set to All languages can't be associated. Associations have not been set." +COM_CONTENT_ERROR_UPDATE_STATE="Can not set state to the item" COM_CONTENT_FEATURED="Featured Article" COM_CONTENT_FEATURED_ARTICLES="Featured Articles" -COM_CONTENT_FEATURED_CATEGORIES_DESC="Optional list of categories. If selected, only featured articles from the selected categories will show." COM_CONTENT_FEATURED_CATEGORIES_LABEL="Select Categories" COM_CONTENT_FEATURED_ORDER="Featured Articles Order" COM_CONTENT_FEATURED_TITLE="Articles: Featured" -COM_CONTENT_FIELD_BROWSER_PAGE_TITLE_DESC="Optional text for the "Browser page title" element to be used when the article is viewed with a non-article menu item. If blank, the article's title is used instead." -COM_CONTENT_FIELD_BROWSER_PAGE_TITLE_LABEL="Browser Page Title" -COM_CONTENT_FIELD_ARTICLETEXT_DESC="Enter the article content in the text area." +COM_CONTENT_FIELDSET_PUBLISHING="Publishing" +COM_CONTENT_FIELDSET_RULES="Permissions" +COM_CONTENT_FIELDSET_URLS_AND_IMAGES="Images and Links" +COM_CONTENT_FIELDS_ARTICLE_FIELDS_TITLE="Articles: Fields" +COM_CONTENT_FIELDS_ARTICLE_FIELD_ADD_TITLE="Articles: New Field" +COM_CONTENT_FIELDS_ARTICLE_FIELD_EDIT_TITLE="Articles: Edit Field" +COM_CONTENT_FIELDS_TYPE_MODAL_ARTICLE="Article" COM_CONTENT_FIELD_ARTICLETEXT_LABEL="Article Text" -COM_CONTENT_FIELD_CAPTCHA_DESC="Select the captcha plugin that will be used in the article submit form. You may need to enter required information for your captcha plugin in the Plugin Manager.
    If 'Use Global' is selected, make sure a captcha plugin is selected in Global Configuration." +COM_CONTENT_FIELD_BROWSER_PAGE_TITLE_LABEL="Browser Page Title" COM_CONTENT_FIELD_CAPTCHA_LABEL="Allow Captcha on submit" -COM_CONTENT_FIELD_CREATED_BY_ALIAS_DESC="Enter an alias to be displayed instead of the name of the user who created the article." COM_CONTENT_FIELD_CREATED_BY_ALIAS_LABEL="Created by Alias" -COM_CONTENT_FIELD_CREATED_BY_DESC="Select the name of the user who created the article." COM_CONTENT_FIELD_CREATED_BY_LABEL="Created By" -COM_CONTENT_FIELD_CREATED_DESC="Created date." COM_CONTENT_FIELD_CREATED_LABEL="Created Date" -COM_CONTENT_FIELD_FEATURED_DESC="Assign the article to the featured blog layout." -COM_CONTENT_FIELD_FULL_DESC="Select or upload an image for the single article display." -COM_CONTENT_FIELD_FULL_LABEL="Full Article Image" COM_CONTENT_FIELD_FULLTEXT="Full text" -COM_CONTENT_FIELD_HITS_DESC="Number of hits for this article." -COM_CONTENT_FIELD_IMAGE_DESC="The image to be displayed." -COM_CONTENT_FIELD_IMAGE_ALT_DESC="Alternative text used for visitors without access to images." +COM_CONTENT_FIELD_FULL_LABEL="Full Article Image" COM_CONTENT_FIELD_IMAGE_ALT_LABEL="Alt Text" -COM_CONTENT_FIELD_IMAGE_CAPTION_DESC="Caption attached to the image." COM_CONTENT_FIELD_IMAGE_CAPTION_LABEL="Caption" COM_CONTENT_FIELD_IMAGE_OPTIONS="Image Options" -COM_CONTENT_FIELD_INFOBLOCK_POSITION_DESC="Puts the article information block above or below the text or splits it into two separate blocks, one above and the other below." COM_CONTENT_FIELD_INFOBLOCK_POSITION_LABEL="Position of Article Info" -COM_CONTENT_FIELD_INFOBLOCK_TITLE_DESC="Displays the 'Article Info' title on top of the article information block." COM_CONTENT_FIELD_INFOBLOCK_TITLE_LABEL="Article Info Title" -COM_CONTENT_FIELD_INTRO_DESC="Image for the intro text layouts such as blogs and featured." -COM_CONTENT_FIELD_INTRO_LABEL="Intro Image" COM_CONTENT_FIELD_INTROTEXT="Intro Text" -COM_CONTENT_FIELD_LANGUAGE_DESC="The language that the article is assigned to." -COM_CONTENT_FIELD_MODIFIED_DESC="The date and time that the article was last modified." +COM_CONTENT_FIELD_INTRO_LABEL="Intro Image" COM_CONTENT_FIELD_OPTION_ABOVE="Above" COM_CONTENT_FIELD_OPTION_BELOW="Below" COM_CONTENT_FIELD_OPTION_SPLIT="Split" -COM_CONTENT_FIELD_PUBLISH_DOWN_DESC="An optional date to Finish Publishing the article." COM_CONTENT_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" -COM_CONTENT_FIELD_PUBLISH_UP_DESC="An optional date to Start Publishing the article." COM_CONTENT_FIELD_PUBLISH_UP_LABEL="Start Publishing" -COM_CONTENT_FIELD_SELECT_ARTICLE_DESC="Select or create an article to be displayed." COM_CONTENT_FIELD_SELECT_ARTICLE_LABEL="Select Article" -COM_CONTENT_FIELD_SHOW_CAT_TAGS_DESC="Show the tags for the category." -COM_CONTENT_FIELD_SHOW_CAT_TAGS_LABEL="Show Tags" -COM_CONTENT_FIELD_SHOW_TAGS_DESC="Show the tags for each article." -COM_CONTENT_FIELD_SHOW_TAGS_LABEL="Show Tags" -COM_CONTENT_FIELD_URL_DESC="The actual link to which users will be redirected." -COM_CONTENT_FIELD_URL_LINK_TEXT_DESC="Text to display for the link." -COM_CONTENT_FIELD_URL_LINK_TEXT_LABEL="Link Text" +COM_CONTENT_FIELD_SHOW_CAT_TAGS_LABEL="Tags" +COM_CONTENT_FIELD_SHOW_TAGS_LABEL="Tags" COM_CONTENT_FIELD_URLA_LABEL="Link A" COM_CONTENT_FIELD_URLA_LINK_TEXT_LABEL="Link A Text" COM_CONTENT_FIELD_URLB_LABEL="Link B" COM_CONTENT_FIELD_URLB_LINK_TEXT_LABEL="Link B Text" COM_CONTENT_FIELD_URLC_LABEL="Link C" COM_CONTENT_FIELD_URLC_LINK_TEXT_LABEL="Link C Text" -COM_CONTENT_FIELD_URLS_OPTIONS="URL Options" COM_CONTENT_FIELD_URLSPOSITION_LABEL="Positioning of the Links" -COM_CONTENT_FIELD_URLSPOSITION_DESC="Display the links above or below the content." +COM_CONTENT_FIELD_URLS_OPTIONS="URL Options" COM_CONTENT_FIELD_VALUE_USE_ARTICLE_SETTINGS="Use Article Settings" -COM_CONTENT_FIELD_VERSION_DESC="A count of the number of times this article has been revised." COM_CONTENT_FIELD_VERSION_LABEL="Revision" COM_CONTENT_FIELD_XREFERENCE_DESC="An optional reference used to link to external data sources." COM_CONTENT_FIELD_XREFERENCE_LABEL="External Reference" -COM_CONTENT_FIELDS_ARTICLE_FIELDS_TITLE="Articles: Fields" -COM_CONTENT_FIELDS_ARTICLE_FIELD_ADD_TITLE="Articles: New Field" -COM_CONTENT_FIELDS_ARTICLE_FIELD_EDIT_TITLE="Articles: Edit Field" -COM_CONTENT_FIELDS_TYPE_MODAL_ARTICLE="Article" -COM_CONTENT_FIELDSET_PUBLISHING="Publishing" -COM_CONTENT_FIELDSET_RULES="Permissions" -COM_CONTENT_FIELDSET_URLS_AND_IMAGES="Images and Links" COM_CONTENT_FILTER_SEARCH_DESC="Search in title and alias. Prefix with ID: or AUTHOR: to search for an article ID or article author." COM_CONTENT_FILTER_SEARCH_LABEL="Search Articles" -COM_CONTENT_FLOAT_DESC="Controls placement of the image." COM_CONTENT_FLOAT_FULLTEXT_LABEL="Full Text Image Float" -COM_CONTENT_FLOAT_LABEL="Image Float" COM_CONTENT_FLOAT_INTRO_LABEL="Intro Image Float" +COM_CONTENT_FLOAT_LABEL="Image Float" COM_CONTENT_HEADING_ASSOCIATION="Association" COM_CONTENT_HEADING_DATE_CREATED="Date Created" COM_CONTENT_HEADING_DATE_MODIFIED="Date Modified" -COM_CONTENT_HEADING_DATE_PUBLISH_UP="Start Publishing" COM_CONTENT_HEADING_DATE_PUBLISH_DOWN="Finish Publishing" +COM_CONTENT_HEADING_DATE_PUBLISH_UP="Start Publishing" COM_CONTENT_ID_LABEL="ID" -; The following 2 strings are deprecated and will be removed with 4.0. -COM_CONTENT_ITEM_ASSOCIATIONS_FIELDSET_LABEL="Content Item Associations" -COM_CONTENT_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a content item for the target language. This association will let the Language Switcher module redirect to the associated content item in another language. If used, make sure to display the Language switcher module on the relevant pages. A content item set to language 'All' can't be associated." COM_CONTENT_LEFT="Left" COM_CONTENT_MODIFIED_ASC="Date Modified ascending" COM_CONTENT_MODIFIED_DESC="Date Modified descending" COM_CONTENT_MONTH="Month" +COM_CONTENT_NEW_ARTICLE="New Article" +COM_CONTENT_NONE="None" +COM_CONTENT_NO_ARTICLES_LABEL="No Articles Message" +COM_CONTENT_NO_ITEM_SELECTED="Please first make a selection from the list." +COM_CONTENT_NUMBER_CATEGORY_ITEMS_LABEL="# Articles in Category" COM_CONTENT_N_ITEMS_ARCHIVED="%s articles archived." COM_CONTENT_N_ITEMS_ARCHIVED_1="%s article archived." -COM_CONTENT_N_ITEMS_CHECKED_IN_0="No article checked in." COM_CONTENT_N_ITEMS_CHECKED_IN_1="%d article checked in." COM_CONTENT_N_ITEMS_CHECKED_IN_MORE="%d articles checked in." COM_CONTENT_N_ITEMS_DELETED="%s articles deleted." @@ -154,56 +120,58 @@ COM_CONTENT_N_ITEMS_UNFEATURED="%s articles unfeatured." COM_CONTENT_N_ITEMS_UNFEATURED_1="%s article unfeatured." COM_CONTENT_N_ITEMS_UNPUBLISHED="%s articles unpublished." COM_CONTENT_N_ITEMS_UNPUBLISHED_1="%s article unpublished." -COM_CONTENT_NEW_ARTICLE="New Article" -COM_CONTENT_NO_ARTICLES_DESC="If Show, the message 'There are no articles in this category' will display when there are no articles in the category or when 'Empty Categories' is set to show." -COM_CONTENT_NO_ARTICLES_LABEL="No Articles Message" -COM_CONTENT_NO_ITEM_SELECTED="Please first make a selection from the list." -COM_CONTENT_NONE="None" -COM_CONTENT_NUMBER_CATEGORY_ITEMS_DESC="If Show, the number of articles in the category will show." -COM_CONTENT_NUMBER_CATEGORY_ITEMS_LABEL="# Articles in Category" -COM_CONTENT_PAGE_ADD_ARTICLE="Articles: New" -COM_CONTENT_PAGE_EDIT_ARTICLE="Articles: Edit" -COM_CONTENT_PAGE_VIEW_ARTICLE="Articles: View" COM_CONTENT_PAGEBREAK_DOC_TITLE="Page Break" COM_CONTENT_PAGEBREAK_INSERT_BUTTON="Insert Page Break" COM_CONTENT_PAGEBREAK_TITLE="Page Title:" COM_CONTENT_PAGEBREAK_TOC="Table of Contents Alias:" +COM_CONTENT_PAGE_ADD_ARTICLE="Articles: New" +COM_CONTENT_PAGE_EDIT_ARTICLE="Articles: Edit" +COM_CONTENT_PAGE_VIEW_ARTICLE="Articles: View" +COM_CONTENT_PUBLISHED="Published" COM_CONTENT_PUBLISH_DOWN_ASC="Finish Publishing ascending" COM_CONTENT_PUBLISH_DOWN_DESC="Finish Publishing descending" COM_CONTENT_PUBLISH_UP_ASC="Start Publishing ascending" COM_CONTENT_PUBLISH_UP_DESC="Start Publishing descending" COM_CONTENT_RIGHT="Right" +COM_CONTENT_RUN_TRANSITIONS="Run Transitions" COM_CONTENT_SAVE_SUCCESS="Article saved." COM_CONTENT_SAVE_WARNING="Alias already existed so a number was added at the end. You can re-edit the article to customise the alias." COM_CONTENT_SELECT_AN_ARTICLE="Select an Article" +COM_CONTENT_SELECT_CONDITION="- Select Condition -" +COM_CONTENT_SELECT_STATE="- Select State -" +COM_CONTENT_SELECT_TRANSITION="- Select Transition -" COM_CONTENT_SHARED_DESC="These settings apply for Shared Options in List, Blog and Featured unless they are changed by the menu settings." COM_CONTENT_SHARED_LABEL="Shared" -COM_CONTENT_SHOW_ARTICLE_OPTIONS_DESC="Show or hide article options slider in the Backend article edit view. These options allow overriding of the global options." -COM_CONTENT_SHOW_ARTICLE_OPTIONS_LABEL="Show Article Options" -COM_CONTENT_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no articles or subcategories." -COM_CONTENT_SHOW_IMAGES_URLS_BACK_DESC="Show or hide fields to insert images and links in the Administrator." +COM_CONTENT_SHOW_ARTICLE_OPTIONS_LABEL="Article Options" COM_CONTENT_SHOW_IMAGES_URLS_BACK_LABEL="Administrator Images and Links" -COM_CONTENT_SHOW_IMAGES_URLS_FRONT_DESC="Show or hide fields to insert images and links when Frontend editing." COM_CONTENT_SHOW_IMAGES_URLS_FRONT_LABEL="Frontend Images and Links" -COM_CONTENT_SHOW_PUBLISHING_OPTIONS_DESC="Show or hide the publishing options slider in the article edit view. These options allow changes in dates and author identities." -COM_CONTENT_SHOW_PUBLISHING_OPTIONS_LABEL="Show Publishing Options" +COM_CONTENT_SHOW_PUBLISHING_OPTIONS_LABEL="Publishing Options" COM_CONTENT_SLIDER_EDITOR_CONFIG="Configure Edit Screen" +COM_CONTENT_STATE="State" COM_CONTENT_SUBMENU_CATEGORIES="Categories" COM_CONTENT_SUBMENU_FEATURED="Featured Articles" +COM_CONTENT_SUBMENU_WORKFLOWS="Workflows" COM_CONTENT_TIP_ASSOCIATION="Associated articles" -COM_CONTENT_TOGGLE_TO_FEATURE="Toggle to change article state to 'Featured'" -COM_CONTENT_TOGGLE_TO_UNFEATURE="Toggle to change article state to 'Unfeatured'" +COM_CONTENT_TRANSITION="Status" +COM_CONTENT_TRASHED="Trashed" COM_CONTENT_UNFEATURED="Unfeatured Article" -COM_CONTENT_URL_FIELD_BROWSERNAV_LABEL="URL Target Window" -COM_CONTENT_URL_FIELD_BROWSERNAV_DESC="Target browser window when the link is selected." +COM_CONTENT_UNPUBLISHED="Unpublished" COM_CONTENT_URL_FIELD_A_BROWSERNAV_LABEL="URL A Target Window" +COM_CONTENT_URL_FIELD_BROWSERNAV_LABEL="URL Target Window" COM_CONTENT_URL_FIELD_B_BROWSERNAV_LABEL="URL B Target Window" COM_CONTENT_URL_FIELD_C_BROWSERNAV_LABEL="URL C Target Window" COM_CONTENT_WARNING_PROVIDE_VALID_NAME="Please provide a valid, non-blank title." +COM_CONTENT_WORKFLOW="Workflow" +COM_CONTENT_WORKFLOW_DEFAULT_WORKFLOW="Use default (%s)" +COM_CONTENT_WORKFLOW_INHERIT_WORKFLOW="Inherit (%s)" +COM_CONTENT_WORKFLOW_INHERIT_WORKFLOW_NEW="Inherit" +COM_CONTENT_WORKFLOW_NOT_FOUND="No default workflow available, please define one or contact an administrator." +COM_CONTENT_WORKFLOW_TRANSITION_NOT_ALLOWED="You're not allowed to execute this transition" +COM_CONTENT_WORKFLOWS="Workflows" COM_CONTENT_XML_DESCRIPTION="Article management component." - JGLOBAL_NO_ITEM_SELECTED="No articles selected" JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE="You are not allowed to create new articles in this category." JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT="You are not allowed to edit one or more of these articles." -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." -JLIB_RULES_SETTING_NOTES_ITEM="Changes apply to this article only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_APPLICATION_ERROR_BATCH_CANNOT_EXECUTE_TRANSITION="You are not allowed to execute a transition for one or more of these articles." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES_ITEM="Changes apply to this article only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_content.sys.ini b/administrator/language/en-GB/en-GB.com_content.sys.ini index f6d6a3112e5cd..8a0bc2631b320 100644 --- a/administrator/language/en-GB/en-GB.com_content.sys.ini +++ b/administrator/language/en-GB/en-GB.com_content.sys.ini @@ -20,8 +20,6 @@ COM_CONTENT_CATEGORIES="Categories" COM_CONTENT_CATEGORIES_VIEW_DEFAULT_DESC="Shows a list of all the article categories within a category." COM_CONTENT_CATEGORIES_VIEW_DEFAULT_OPTION="Default" COM_CONTENT_CATEGORIES_VIEW_DEFAULT_TITLE="List All Categories" -COM_CONTENT_CATEGORY_ADD_TITLE="Articles: New Category" -COM_CONTENT_CATEGORY_EDIT_TITLE="Articles: Edit Category" COM_CONTENT_CATEGORY_VIEW_BLOG_DESC="Displays article introductions in a single or multi-column layout." COM_CONTENT_CATEGORY_VIEW_BLOG_OPTION="Blog" COM_CONTENT_CATEGORY_VIEW_BLOG_TITLE="Category Blog" @@ -29,8 +27,6 @@ COM_CONTENT_CATEGORY_VIEW_DEFAULT_DESC="Displays a list of articles in a categor COM_CONTENT_CATEGORY_VIEW_DEFAULT_OPTION="List" COM_CONTENT_CATEGORY_VIEW_DEFAULT_TITLE="Category List" COM_CONTENT_CATEGORY_VIEW_FEATURED_DESC="Show all featured articles from one or multiple categories in a single or multi-column layout." -COM_CONTENT_CATEGORY_VIEW_FEATURED_OPTION="Default" -COM_CONTENT_CATEGORY_VIEW_FEATURED_TITLE="Featured Articles Single Category" COM_CONTENT_CONTENT_TYPE_ARTICLE="Article" COM_CONTENT_CONTENT_TYPE_CATEGORY="Article Category" COM_CONTENT_FEATURED="Featured" diff --git a/administrator/language/en-GB/en-GB.com_contenthistory.ini b/administrator/language/en-GB/en-GB.com_contenthistory.ini index d9fedf02f2380..461b1d9b99ef3 100644 --- a/administrator/language/en-GB/en-GB.com_contenthistory.ini +++ b/administrator/language/en-GB/en-GB.com_contenthistory.ini @@ -3,15 +3,7 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 -COM_CONTENTHISTORY_BUTTON_COMPARE_ALL_ROWS_DESC="Select to see all values for the item, including ones that haven't changed." -COM_CONTENTHISTORY_BUTTON_COMPARE_ALL_ROWS="All Values" -COM_CONTENTHISTORY_BUTTON_COMPARE_CHANGED_ROWS_DESC="Select to see only those values that have changed." -COM_CONTENTHISTORY_BUTTON_COMPARE_CHANGED_ROWS="Changed Values" COM_CONTENTHISTORY_BUTTON_COMPARE_DESC="Choose two versions and select to compare them." -COM_CONTENTHISTORY_BUTTON_COMPARE_HTML_DESC="Select to see the HTML source code for the changes." -COM_CONTENTHISTORY_BUTTON_COMPARE_HTML="Show HTML Code" -COM_CONTENTHISTORY_BUTTON_COMPARE_TEXT_DESC="Select to see the item changes as text." -COM_CONTENTHISTORY_BUTTON_COMPARE_TEXT="Show Text" COM_CONTENTHISTORY_BUTTON_COMPARE="Compare" COM_CONTENTHISTORY_BUTTON_DELETE_DESC="Choose one or more versions and select to permanently delete them." COM_CONTENTHISTORY_BUTTON_DELETE="Delete" @@ -28,8 +20,8 @@ COM_CONTENTHISTORY_BUTTON_SELECT_TWO="Please select two versions." COM_CONTENTHISTORY_CHARACTER_COUNT="Character Count" COM_CONTENTHISTORY_COMPARE_DIFF="Changes" COM_CONTENTHISTORY_COMPARE_TITLE="Compare View" -COM_CONTENTHISTORY_COMPARE_VALUE1="Saved on %s %s" -COM_CONTENTHISTORY_COMPARE_VALUE2="Saved on %s %s" +COM_CONTENTHISTORY_COMPARE_NEW="New" +COM_CONTENTHISTORY_COMPARE_OLD="Old" COM_CONTENTHISTORY_ERROR_KEEP_NOT_PERMITTED="You are not permitted to change the keep forever status." COM_CONTENTHISTORY_KEEP_VERSION="Keep Forever" COM_CONTENTHISTORY_MODAL_TITLE="Item Version History" @@ -41,7 +33,6 @@ COM_CONTENTHISTORY_NO_ITEM_SELECTED="No history version selected." COM_CONTENTHISTORY_PREVIEW_FIELD="Field" COM_CONTENTHISTORY_PREVIEW_SUBTITLE_DATE="Preview of version from %s" COM_CONTENTHISTORY_PREVIEW_SUBTITLE="Version note: %s" -COM_CONTENTHISTORY_PREVIEW_TITLE="Preview of Selected Item" COM_CONTENTHISTORY_PREVIEW_VALUE="Value" COM_CONTENTHISTORY_VERSION_NOTE="Version Note" diff --git a/administrator/language/en-GB/en-GB.com_cpanel.ini b/administrator/language/en-GB/en-GB.com_cpanel.ini index 9071156762e0c..09ffe0d8a2974 100644 --- a/administrator/language/en-GB/en-GB.com_cpanel.ini +++ b/administrator/language/en-GB/en-GB.com_cpanel.ini @@ -4,14 +4,6 @@ ; Note : All ini files need to be saved as UTF-8 COM_CPANEL="Control Panel" -COM_CPANEL_HEADER_SUBMENU="Submenu" -COM_CPANEL_HEADER_SYSTEM="System" -COM_CPANEL_LINK_CHECKIN="Global Check-in" -COM_CPANEL_LINK_CLEAR_CACHE="Clear Cache" -COM_CPANEL_LINK_DASHBOARD="Dashboard" -COM_CPANEL_LINK_EXTENSIONS="Install Extensions" -COM_CPANEL_LINK_GLOBAL_CONFIG="Global Configuration" -COM_CPANEL_LINK_SYSINFO="System Information" COM_CPANEL_MESSAGES_BODY_NOCLOSE="There are important post-installation messages that require your attention." COM_CPANEL_MESSAGES_BODYMORE_NOCLOSE="This information area won't appear when you have hidden all the messages." COM_CPANEL_MESSAGES_REVIEW="Read Messages" @@ -19,19 +11,15 @@ COM_CPANEL_MESSAGES_TITLE="You have post-installation messages" COM_CPANEL_MSG_EACCELERATOR_BODY="eAccelerator is not compatible with Joomla! By selecting the Change to File Caching button below we will change the cache handler to file. If you want to use a different cache handler, please change it in the Global Configuration page." COM_CPANEL_MSG_EACCELERATOR_BUTTON="Change to File." COM_CPANEL_MSG_EACCELERATOR_TITLE="eAccelerator is not compatible with Joomla!" -COM_CPANEL_MSG_HTACCESS_BODY="A change to the default .htaccess and web.config files was made in Joomla! 3.4 to disallow folder listings by default. Users are recommended to implement this change in their files. Please see this page for more information." +COM_CPANEL_MSG_HTACCESS_BODY="A change to the default .htaccess and web.config files was made in Joomla! 3.4 to disallow folder listings by default. Users are recommended to implement this change in their files. Please see this page for more information." COM_CPANEL_MSG_HTACCESS_TITLE=".htaccess & web.config Update" -COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_TITLE="Prepare for the next Major Release of Joomla" -COM_CPANEL_MSG_JOOMLA40_PRE_CHECKS_BODY="

    Beginning with Joomla! 4.0 we are raising the minimum server requirements. If you are seeing this message then your current configuration does not meet these new minimum requirements.

    The minimum requirements are the following:

    • PHP 7.0
    • MySQL 5.5.3
    • PostgreSQL 9.2
    • MS SQL will not be supported
    • MySQL using the legacy `ext/mysql` PHP extension will not be supported, MySQLi or PDO MySQL must be used instead

    Please contact your hosting provider to ask how you can meet these raised server requirements - it is usually a very simple change. If you already meet these new requirements then this message will not be displayed.

    " COM_CPANEL_MSG_LANGUAGEACCESS340_TITLE="You have possible issues with your multilingual settings" -COM_CPANEL_MSG_LANGUAGEACCESS340_BODY="Since Joomla! 3.4.0 you may have issues with the System - Language Filter plugin on your website. To fix them please open the Language Manager and save each content language manually to make sure an Access level is saved." -; The following two strings are deprecated and will be removed with 4.0 -COM_CPANEL_MSG_PHPVERSION_BODY="Beginning with Joomla! 3.3, the version of PHP this site is using will no longer be supported. Joomla! 3.3 will require at least PHP version 5.3.10 to provide enhanced security features to its users." -COM_CPANEL_MSG_PHPVERSION_TITLE="Your PHP Version Will Be Unsupported in Joomla! 3.3" +COM_CPANEL_MSG_LANGUAGEACCESS340_BODY="Since Joomla! 3.4.0 you may have issues with the System - Language Filter plugin on your website. To fix them please open the Language Manager and save each content language manually to make sure an Access level is saved." COM_CPANEL_MSG_ROBOTS_TITLE="robots.txt Update" COM_CPANEL_MSG_ROBOTS_BODY="A change to the default robots.txt files was made in Joomla! 3.3 to allow Google to access templates and media files by default to improve SEO. This change is not applied automatically on upgrades and users are recommended to review the changes in the robots.txt.dist file and implement these changes in their own robots.txt file." -COM_CPANEL_MSG_STATS_COLLECTION_BODY="

    Since Joomla! 3.5 a statistics plugin will submit anonymous data to the Joomla Project. This will only submit the Joomla version, PHP version, database engine and version, and server operating system.

    This data is collected to ensure that future versions of Joomla can take advantage of the latest database and PHP features without affecting significant numbers of users. The need for this became clear when a minimum of PHP 5.3.10 was required when Joomla! 3.3 implemented the more secure Bcrypt passwords.

    In the interest of full transparency and to help developers this data is publicly available. An API and graphs will show the Joomla version, PHP versions and database engines in use.

    If you do not wish to provide the Joomla Project with this information you can disable the plugin called System - Joomla Statistics.

    " +COM_CPANEL_MSG_STATS_COLLECTION_BODY="

    Since Joomla! 3.5 a statistics plugin will submit anonymous data to the Joomla Project. This will only submit the Joomla version, PHP version, database engine and version, and server operating system.

    This data is collected to ensure that future versions of Joomla can take advantage of the latest database and PHP features without affecting significant numbers of users. The need for this became clear when a minimum of PHP 5.3.10 was required when Joomla! 3.3 implemented the more secure Bcrypt passwords.

    In the interest of full transparency and to help developers this data is publicly available. An API and graphs will show the Joomla version, PHP versions and database engines in use.

    If you do not wish to provide the Joomla Project with this information you can disable the plugin called System - Joomla Statistics.

    " COM_CPANEL_MSG_STATS_COLLECTION_TITLE="Stats Collection in Joomla" -COM_CPANEL_WELCOME_BEGINNERS_MESSAGE="

    Community resources are available for new users.

    " +COM_CPANEL_TITLE_SYSTEM_PANEL="System Panel" +COM_CPANEL_WELCOME_BEGINNERS_MESSAGE="

    Community resources are available for new users.

    " COM_CPANEL_WELCOME_BEGINNERS_TITLE="Welcome to Joomla!" COM_CPANEL_XML_DESCRIPTION="Control Panel component" diff --git a/administrator/language/en-GB/en-GB.com_csp.ini b/administrator/language/en-GB/en-GB.com_csp.ini new file mode 100644 index 0000000000000..f314eff675809 --- /dev/null +++ b/administrator/language/en-GB/en-GB.com_csp.ini @@ -0,0 +1,35 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +COM_CSP="Content Security Policy" +COM_CSP_CONFIGURATION="Content Security Policy: Options" +COM_CSP_EDIT_PLUGIN_SETTINGS="Edit Plugin Settings" +COM_CSP_FILTER_SEARCH_DESC="Search in the table fields. Prefix with ID: to search by ID." +COM_CSP_FILTER_SEARCH_LABEL="Search CSP Reports" +COM_CSP_HEADING_DOCUMENT_URI="URL" +COM_CSP_HEADING_BLOCKED_URI="Blocked Element" +COM_CSP_HEADING_DIRECTIVE="Directive" +COM_CSP_HEADING_CREATED="Created" +COM_CSP_HEADING_BLOCKED_URI_ASC="Blocked element ascending" +COM_CSP_HEADING_BLOCKED_URI_DESC="Blocked element descending" +COM_CSP_HEADING_CLIENT_ASC="Client ascending" +COM_CSP_HEADING_CLIENT_DESC="Client descending" +COM_CSP_HEADING_CREATED_ASC="Created ascending" +COM_CSP_HEADING_CREATED_DESC="Created descending" +COM_CSP_HEADING_DIRECTIVE_ASC="Directive ascending" +COM_CSP_HEADING_DIRECTIVE_DESC="Directive descending" +COM_CSP_HEADING_DOCUMENT_URI_ASC="URL ascending" +COM_CSP_HEADING_DOCUMENT_URI_DESC="URL descending" +COM_CSP_N_ITEMS_DELETED="%d reports deleted." +COM_CSP_N_ITEMS_DELETED_1="%d report deleted." +COM_CSP_N_ITEMS_PUBLISHED="%d reports published." +COM_CSP_N_ITEMS_PUBLISHED_1="%d report published." +COM_CSP_N_ITEMS_TRASHED="%d reports trashed." +COM_CSP_N_ITEMS_TRASHED_1="%d report trashed." +COM_CSP_N_ITEMS_UNPUBLISHED="%d reports unpublished." +COM_CSP_N_ITEMS_UNPUBLISHED_1="%d report unpublished." +COM_CSP_PLUGIN_MODAL_DISABLED="The %s is disabled. It needs to be enabled for this component to work." +COM_CSP_REPORTS="CSP Reports" +COM_CSP_SYSTEM_PLUGIN="HTTP Headers System Plugin" \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.com_csp.sys.ini b/administrator/language/en-GB/en-GB.com_csp.sys.ini new file mode 100644 index 0000000000000..a65a70547ec31 --- /dev/null +++ b/administrator/language/en-GB/en-GB.com_csp.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +COM_CSP="Content Security Policy" +COM_CSP_XML_DESCRIPTION="This component manages the Content Security Policy (CSP) reports." diff --git a/administrator/language/en-GB/en-GB.com_fields.ini b/administrator/language/en-GB/en-GB.com_fields.ini index 0c202fec9a8a6..b753c5864db5e 100644 --- a/administrator/language/en-GB/en-GB.com_fields.ini +++ b/administrator/language/en-GB/en-GB.com_fields.ini @@ -10,17 +10,13 @@ COM_FIELDS_ERROR_UNIQUE_NAME="Another Field has the same name (remember it may b COM_FIELDS_FIELD_CLASS_DESC="The class attributes of the field in the edit form. If multiple classes are needed, list them with spaces." COM_FIELDS_FIELD_CLASS_LABEL="Edit Class" COM_FIELDS_FIELD_SHOWLABEL_DESC="Show or Hide the label when the field renders." -COM_FIELDS_FIELD_SHOWLABEL_LABEL="Show Label" -COM_FIELDS_FIELD_DEFAULT_VALUE_DESC="The default value of the field." +COM_FIELDS_FIELD_SHOWLABEL_LABEL="Label" COM_FIELDS_FIELD_DEFAULT_VALUE_LABEL="Default Value" -COM_FIELDS_FIELD_DESCRIPTION_DESC="A description of the field that will be displayed in the label tooltip." COM_FIELDS_FIELD_DISPLAY_AFTER_DISPLAY="After Display" COM_FIELDS_FIELD_DISPLAY_AFTER_TITLE="After Title" COM_FIELDS_FIELD_DISPLAY_BEFORE_DISPLAY="Before Display" -COM_FIELDS_FIELD_DISPLAY_DESC="Joomla offers some content events which are triggered during the content creation process. This is the place to define how the custom fields should be integrated into content." COM_FIELDS_FIELD_DISPLAY_LABEL="Automatic Display" COM_FIELDS_FIELD_DISPLAY_NO_DISPLAY="Do not automatically display" -COM_FIELDS_FIELD_GROUP_DESC="The group this field belongs to." COM_FIELDS_FIELD_GROUP_LABEL="Field Group" COM_FIELDS_FIELD_PLACEHOLDER_DESC="Placeholder text which will appear inside the field as a hint to the user for the required input." COM_FIELDS_FIELD_PLACEHOLDER_LABEL="Placeholder" @@ -29,40 +25,23 @@ COM_FIELDS_FIELD_IMAGE_ALT_LABEL="Alt Text" COM_FIELDS_FIELD_IMAGE_DESC="Image label." COM_FIELDS_FIELD_IMAGE_LABEL="Image" COM_FIELDS_FIELD_INVALID_DEFAULT_VALUE="The default value is invalid." -COM_FIELDS_FIELD_LABEL_DESC="The label of the field to display." COM_FIELDS_FIELD_LABEL_LABEL="Label" -COM_FIELDS_FIELD_LANGUAGE_DESC="Assign a language to this field." -COM_FIELDS_FIELD_NOTE_DESC="An optional note for the field." COM_FIELDS_FIELD_NOTE_LABEL="Note" -COM_FIELDS_FIELD_PERMISSION_DELETE_DESC="New setting for delete actions on this field and the calculated setting based on the parent extension and group permissions." -COM_FIELDS_FIELD_PERMISSION_EDITSTATE_DESC="New setting for edit state actions on this field and the calculated setting based on the parent extension and group permissions." -COM_FIELDS_FIELD_PERMISSION_EDITVALUE_DESC="Who can edit the custom field value in the form editor?" -COM_FIELDS_FIELD_PERMISSION_EDIT_DESC="New setting for edit actions on this field and the calculated setting based on the parent extension and group permissions." COM_FIELDS_FIELD_RENDER_CLASS_DESC="The class attributes of the field when the field is rendered. If multiple classes are needed, list them with spaces." COM_FIELDS_FIELD_RENDER_CLASS_LABEL="Render Class" -COM_FIELDS_FIELD_REQUIRED_DESC="Is this a mandatory field?" COM_FIELDS_FIELD_REQUIRED_LABEL="Required" COM_FIELDS_FIELD_SHOW_ON_ADMIN="Administrator" COM_FIELDS_FIELD_SHOW_ON_BOTH="Both" -COM_FIELDS_FIELD_SHOW_ON_DESC="On which part of the site should the field be shown?" COM_FIELDS_FIELD_SHOW_ON_LABEL="Show On" COM_FIELDS_FIELD_SHOW_ON_SITE="Site" -COM_FIELDS_FIELD_TYPE_DESC="The type of the field." COM_FIELDS_FIELD_TYPE_LABEL="Type" COM_FIELDS_FIELD_USE_GLOBAL="Use settings from Plugin" -COM_FIELDS_GROUP_PERMISSION_CREATE_DESC="New setting for create actions in this field group and the calculated setting based on the parent extension permissions." -COM_FIELDS_GROUP_PERMISSION_DELETE_DESC="New setting for delete actions on this field group and the calculated setting based on the parent extension permissions." -COM_FIELDS_GROUP_PERMISSION_EDITOWN_DESC="New setting for edit own actions on this field group and the calculated setting based on the parent extension permissions." -COM_FIELDS_GROUP_PERMISSION_EDITSTATE_DESC="New setting for edit state actions on this field group and the calculated setting based on the parent extension permissions." -COM_FIELDS_GROUP_PERMISSION_EDITVALUE_DESC="Who can edit the field value in the form editor." -COM_FIELDS_GROUP_PERMISSION_EDIT_DESC="New setting for edit actions on this field group and the calculated setting based on the parent extension permissions." COM_FIELDS_MUSTCONTAIN_A_TITLE_FIELD="Field must have a title." COM_FIELDS_MUSTCONTAIN_A_TITLE_GROUP="Field Group must have a title." COM_FIELDS_FIELD_SAVE_SUCCESS="Field saved" COM_FIELDS_FIELD_N_ITEMS_ARCHIVED="%d fields archived" COM_FIELDS_FIELD_N_ITEMS_ARCHIVED_1="%d field archived" COM_FIELDS_FIELD_N_ITEMS_CHECKED_IN="%d fields checked in" -COM_FIELDS_FIELD_N_ITEMS_CHECKED_IN_0="No field checked in" COM_FIELDS_FIELD_N_ITEMS_CHECKED_IN_1="%d field checked in" COM_FIELDS_FIELD_N_ITEMS_DELETED="%d fields deleted" COM_FIELDS_FIELD_N_ITEMS_DELETED_1="%d field deleted" @@ -76,7 +55,6 @@ COM_FIELDS_GROUP_SAVE_SUCCESS="Field Group saved" COM_FIELDS_GROUP_N_ITEMS_ARCHIVED="%d field groups archived" COM_FIELDS_GROUP_N_ITEMS_ARCHIVED_1="%d field group archived" COM_FIELDS_GROUP_N_ITEMS_CHECKED_IN="%d field groups checked in" -COM_FIELDS_GROUP_N_ITEMS_CHECKED_IN_0="No field group checked in" COM_FIELDS_GROUP_N_ITEMS_CHECKED_IN_1="%d field group checked in" COM_FIELDS_GROUP_N_ITEMS_DELETED="%d field groups deleted" COM_FIELDS_GROUP_N_ITEMS_DELETED_1="%d field group deleted" @@ -86,7 +64,7 @@ COM_FIELDS_GROUP_N_ITEMS_TRASHED="%d field groups trashed" COM_FIELDS_GROUP_N_ITEMS_TRASHED_1="%d field group trashed" COM_FIELDS_GROUP_N_ITEMS_UNPUBLISHED="%d field groups unpublished" COM_FIELDS_GROUP_N_ITEMS_UNPUBLISHED_1="%d field group unpublished" -COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED="The System - Fields plugin is disabled. Custom fields will not display until you enable this plugin." +COM_FIELDS_SYSTEM_PLUGIN_NOT_ENABLED="The System - Fields plugin is disabled. Custom fields will not display until you enable this plugin." COM_FIELDS_VIEW_FIELDS_BATCH_OPTIONS="Batch process the selected fields." COM_FIELDS_VIEW_FIELDS_SELECT_GROUP="- Select Field Group -" COM_FIELDS_VIEW_FIELDS_SELECT_CATEGORY="- Select Assigned Category -" diff --git a/administrator/language/en-GB/en-GB.com_finder.ini b/administrator/language/en-GB/en-GB.com_finder.ini index 247a5a67fcb54..3d60d59d13f8c 100644 --- a/administrator/language/en-GB/en-GB.com_finder.ini +++ b/administrator/language/en-GB/en-GB.com_finder.ini @@ -7,129 +7,78 @@ COM_FINDER="Smart Search" COM_FINDER_ALLOW_EMPTY_QUERY_DESC="Only if a filter is selected, allow an empty search string to initiate a search within the filter constraints." COM_FINDER_ALLOW_EMPTY_QUERY_LABEL="Allow Empty Search" COM_FINDER_AN_ERROR_HAS_OCCURRED="An Error Has Occurred" -COM_FINDER_CONFIG_ALLOW_EMPTY_QUERY_DESCRIPTION="Only if a filter is selected, allow an empty search string to initiate a search within the filter restraints." COM_FINDER_CONFIG_ALLOW_EMPTY_QUERY_LABEL="Allow Empty Search" -COM_FINDER_CONFIG_BATCH_SIZE_DESCRIPTION="The batch size controls how many items are processed per batch. Large batch sizes require lots of memory whereas small batch sizes require less memory but execute more requests which tends to take longer." COM_FINDER_CONFIG_BATCH_SIZE_LABEL="Indexer Batch Size" -COM_FINDER_CONFIG_DESCRIPTION_LENGTH_DESC="Description text for search results will be truncated to the specified character length." -COM_FINDER_CONFIG_DESCRIPTION_LENGTH_DESCRIPTION="Description text for search results will be truncated to the specified character length." COM_FINDER_CONFIG_DESCRIPTION_LENGTH_LABEL="Description Length" -COM_FINDER_CONFIG_ENABLE_LOGGING_DESCRIPTION="Enable this option to create a log file in your site's logs folder during the index process. This file is useful for troubleshooting issues with the index process. It is recommended that logging be disabled unless necessary." COM_FINDER_CONFIG_ENABLE_LOGGING_LABEL="Enable Logging" -COM_FINDER_CONFIG_EXPAND_ADVANCED_DESC="Toggle if the advanced search options should be expanded by default." -COM_FINDER_CONFIG_EXPAND_ADVANCED_DESCRIPTION="Toggle if the advanced search options should be expanded by default." COM_FINDER_CONFIG_EXPAND_ADVANCED_LABEL="Expand Advanced Search" -COM_FINDER_CONFIG_FIELD_OPENSEARCH_DESCRIPTON_DESCRIPTION="Description displayed for this site as a search provider." COM_FINDER_CONFIG_FIELD_OPENSEARCH_DESCRIPTON_LABEL="OpenSearch Description" -COM_FINDER_CONFIG_FIELD_OPENSEARCH_NAME_DESCRIPTION="Name displayed for this site as a search provider." COM_FINDER_CONFIG_FIELD_OPENSEARCH_NAME_LABEL="OpenSearch Name" -COM_FINDER_CONFIG_GATHER_SEARCH_STATISTICS_DESCRIPTION="Record the search phrases submitted by visitors." COM_FINDER_CONFIG_GATHER_SEARCH_STATISTICS_LABEL="Gather Search Statistics" -COM_FINDER_CONFIG_HILIGHT_CONTENT_SEARCH_TERMS_DESCRIPTION="Toggle if search terms should be highlighted in search results." COM_FINDER_CONFIG_HILIGHT_CONTENT_SEARCH_TERMS_LABEL="Highlight Search Terms" -COM_FINDER_CONFIG_IMPORT_EXPORT="Import/Export" -COM_FINDER_CONFIG_IMPORT_EXPORT_HELP="Help" -COM_FINDER_CONFIG_IMPORT_EXPORT_INSTRUCTIONS="To export your configuration options, select the Export button in the toolbar above.

    To import an existing configuration, select the browse button to choose a file from your hard drive or copy/paste the data into the text field below and then select the Import button in the toolbar above." -COM_FINDER_CONFIG_IMPORT_FROM_FILE="Import From File:" -COM_FINDER_CONFIG_IMPORT_FROM_STRING="Import From Text:" -COM_FINDER_CONFIG_IMPORT_TOOLBAR_TITLE="Smart Search: Import/Export Configuration" -COM_FINDER_CONFIG_MEMORY_TABLE_LIMIT_DESCRIPTION="The memory table limit should not be changed unless you are getting errors indicating that the finder_tokens or finder_tokens_aggregate tables are full. The default is 30,000." +COM_FINDER_CONFIG_LANGUAGE_DEFAULT_DEFAULT_LANGUAGE="Default Site Language" +COM_FINDER_CONFIG_LANGUAGE_DEFAULT_DESC="Set the language to be used for non-multilingual sites or content marked as \"All\"." +COM_FINDER_CONFIG_LANGUAGE_DEFAULT_LABEL="Default Language" +COM_FINDER_CONFIG_LANGUAGE_DEFAULT_NONE="None" COM_FINDER_CONFIG_MEMORY_TABLE_LIMIT_LABEL="Memory Table Limit" -COM_FINDER_CONFIG_META_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The metadata comes from a number of sources including the meta keywords and meta description, author names, etc." COM_FINDER_CONFIG_META_MULTIPLIER_LABEL="Metadata Weight Multiplier" -COM_FINDER_CONFIG_MISC_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The miscellaneous text comes from a number of sources including comments and other associated data." COM_FINDER_CONFIG_MISC_MULTIPLIER_LABEL="Misc. Text Weight Multiplier" -COM_FINDER_CONFIG_PATH_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The path text comes from the SEF URL of the content." +COM_FINDER_CONFIG_OPENSEARCH_LABEL="Enable OpenSearch" COM_FINDER_CONFIG_PATH_MULTIPLIER_LABEL="Path Text Weight Multiplier" -COM_FINDER_CONFIG_SHOW_ADVANCED_DESC="Toggle if users should be able to see advanced search options." -COM_FINDER_CONFIG_SHOW_ADVANCED_DESCRIPTION="Toggle if users should be able to see advanced search options." COM_FINDER_CONFIG_SHOW_ADVANCED_LABEL="Advanced Search" -COM_FINDER_CONFIG_SHOW_ADVANCED_TIPS_DESCRIPTION="Toggle if users should be able to see advanced search tips." COM_FINDER_CONFIG_SHOW_ADVANCED_TIPS_LABEL="Advanced Tips" -COM_FINDER_CONFIG_SHOW_AUTOSUGGEST_DESCRIPTION="Toggle if automatic search suggestions should be displayed." COM_FINDER_CONFIG_SHOW_AUTOSUGGEST_LABEL="Search Suggestions" -COM_FINDER_CONFIG_SHOW_DATE_FILTERS_DESC="Show the start and end date filters in the advanced search." -COM_FINDER_CONFIG_SHOW_DATE_FILTERS_DESCRIPTION="Show the start and end date filters in the advanced search." COM_FINDER_CONFIG_SHOW_DATE_FILTERS_LABEL="Date Filters" -COM_FINDER_CONFIG_SHOW_DESCRIPTION_DESC="Toggle if the description should be displayed with search results." -COM_FINDER_CONFIG_SHOW_DESCRIPTION_DESCRIPTION="Toggle if the description should be displayed with search results." +COM_FINDER_CONFIG_SHOW_DATE_LABEL="Result Date" COM_FINDER_CONFIG_SHOW_DESCRIPTION_LABEL="Result Description" -COM_FINDER_CONFIG_SHOW_EXPLAINED_QUERY_DESC="Show or hide a detailed explanation of the search requested." COM_FINDER_CONFIG_SHOW_EXPLAINED_QUERY_LABEL="Query Explanation" -COM_FINDER_CONFIG_SHOW_FEED_DESC="Show the syndication feed link." -COM_FINDER_CONFIG_SHOW_FEED_LABEL="Show Feed" -COM_FINDER_CONFIG_SHOW_FEED_TEXT_DESC="Show the associated text with the feed, otherwise the title is shown in the feed." -COM_FINDER_CONFIG_SHOW_FEED_TEXT_LABEL="Show Feed Text" -COM_FINDER_CONFIG_SHOW_SUGGESTED_QUERY_DESC="Whether to suggest alternative search terms when a search produces no results." COM_FINDER_CONFIG_SHOW_SUGGESTED_QUERY_LABEL="Did You Mean" -COM_FINDER_CONFIG_SHOW_URL_DESC="Show the associated URL that for the item." -COM_FINDER_CONFIG_SHOW_URL_DESCRIPTION="Show the associated URL for the item." +COM_FINDER_CONFIG_SHOW_TAXONOMY_LABEL="Result Taxonomy" COM_FINDER_CONFIG_SHOW_URL_LABEL="Result URL" -COM_FINDER_CONFIG_SORT_DIRECTION_DESC="The direction in which to sort the search results." COM_FINDER_CONFIG_SORT_DIRECTION_LABEL="Sort Direction" COM_FINDER_CONFIG_SORT_OPTION_ASCENDING="Ascending" COM_FINDER_CONFIG_SORT_OPTION_DESCENDING="Descending" COM_FINDER_CONFIG_SORT_OPTION_LIST_PRICE="List price" COM_FINDER_CONFIG_SORT_OPTION_RELEVANCE="Relevance" COM_FINDER_CONFIG_SORT_OPTION_START_DATE="Date" -COM_FINDER_CONFIG_SORT_ORDER_DESC="The field on which to sort the search results." COM_FINDER_CONFIG_SORT_ORDER_LABEL="Sort Field" -COM_FINDER_CONFIG_STEMMER_DESCRIPTION="The language stemmer to use. Choose snowball if a stemmer for your language is not available or you have multilingual content." -COM_FINDER_CONFIG_STEMMER_ENABLE_DESCRIPTION="Enable language stemming if available." -COM_FINDER_CONFIG_STEMMER_ENABLE_LABEL="Enable Stemmer" -COM_FINDER_CONFIG_STEMMER_FR="French Only" -COM_FINDER_CONFIG_STEMMER_LABEL="Stemmer" -COM_FINDER_CONFIG_STEMMER_PORTER_EN="English Only" -COM_FINDER_CONFIG_STEMMER_SNOWBALL="Snowball" COM_FINDER_CONFIG_TEXT_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The body text comes from the summary and/or body of the content." COM_FINDER_CONFIG_TEXT_MULTIPLIER_LABEL="Body Text Weight Multiplier" COM_FINDER_CONFIG_TITLE_MULTIPLIER_DESCRIPTION="The multiplier is used to control how much influence matching text has on the overall relevance score of a search result. A multiplier is considered in relationship to the other multipliers. The title text comes from the title of the content." COM_FINDER_CONFIG_TITLE_MULTIPLIER_LABEL="Title Text Weight Multiplier" +COM_FINDER_CONFIG_TUPLECOUNT_LABEL="Search for Phrases" +COM_FINDER_CONFIG_TUPLECOUNT_PHRASE_DISABLED="Disabled (Improved performance)" +COM_FINDER_CONFIG_TUPLECOUNT_PHRASE_ENABLED="Enabled (Improved search results)" COM_FINDER_CONFIGURATION="Smart Search: Options" COM_FINDER_CREATE_FILTER="Create a filter." COM_FINDER_EDIT_FILTER="Edit Filter" -COM_FINDER_EXPORT="Export" -COM_FINDER_FIELD_CREATED_BY_ALIAS_DESC="Displayed name of the filter creator." COM_FINDER_FIELD_CREATED_BY_ALIAS_LABEL="Alias" -COM_FINDER_FIELD_CREATED_BY_DESC="Creator of the filter." COM_FINDER_FIELD_CREATED_BY_LABEL="Created By" -COM_FINDER_FIELD_MODIFIED_DESCRIPTION="The date and time that the filter was last modified." COM_FINDER_FIELDSET_INDEX_OPTIONS_DESCRIPTION="Indexing options" COM_FINDER_FIELDSET_INDEX_OPTIONS_LABEL="Index" COM_FINDER_FIELDSET_SEARCH_OPTIONS_DESCRIPTION="Smart Search options" COM_FINDER_FIELDSET_SEARCH_OPTIONS_LABEL="Smart Search" COM_FINDER_FILTER_BRANCH_LABEL="Search by %s" COM_FINDER_FILTER_BY="Show %s:" -COM_FINDER_FILTER_CONTENT_MAP_DESC="Filter the indexed content by content map." -COM_FINDER_FILTER_CONTENT_MAP_LABEL="Select the Content Map" COM_FINDER_FILTER_EDIT_TOOLBAR_TITLE="Smart Search: Edit Filter" -COM_FINDER_FILTER_END_DATE_DESCRIPTION="Format YYYY-MM-DD" COM_FINDER_FILTER_END_DATE_LABEL="End Date" -COM_FINDER_FILTER_FIELDSET_DETAILS="Filter Details" COM_FINDER_FILTER_FIELDSET_PARAMS="Filter Timeline" COM_FINDER_FILTER_HIDE_ALL="Collapse all" COM_FINDER_FILTER_MAP_COUNT="Map Count" -COM_FINDER_FILTER_MAP_COUNT_DESCRIPTION="The number of maps included in the filter." COM_FINDER_FILTER_NEW_TOOLBAR_TITLE="Smart Search: New Filter" -COM_FINDER_FILTER_SEARCH_DESCRIPTION="Filter the list by a title." COM_FINDER_FILTER_SELECT_CONTENT_MAP="- Select Content Map -" COM_FINDER_FILTER_SELECT_ALL_LABEL="Search All" COM_FINDER_FILTER_START_DATE_DESCRIPTION="Format YYYY-MM-DD" COM_FINDER_FILTER_START_DATE_LABEL="Start Date" COM_FINDER_FILTER_TIMESTAMP="Created On" COM_FINDER_FILTER_SHOW_ALL="Expand all" -COM_FINDER_FILTER_TITLE_DESCRIPTION="The title of the filter." COM_FINDER_FILTER_WHEN_AFTER="After" COM_FINDER_FILTER_WHEN_BEFORE="Before" -COM_FINDER_FILTER_WHEN_END_DATE_DESCRIPTION="When to search relative to the end date (before, after or exactly)" COM_FINDER_FILTER_WHEN_END_DATE_LABEL="When (End Date)" COM_FINDER_FILTER_WHEN_EXACTLY="Exactly" -COM_FINDER_FILTER_WHEN_START_DATE_DESCRIPTION="When to search relative to the start date (before, after or exactly)" COM_FINDER_FILTER_WHEN_START_DATE_LABEL="When (Start Date)" COM_FINDER_FILTERS="Filters" -COM_FINDER_FILTERS_DELETE_CONFIRMATION="Are you sure you want to delete the selected filters(s)?" COM_FINDER_FILTERS_TOOLBAR_TITLE="Smart Search: Search Filters" -COM_FINDER_GO="Go" COM_FINDER_HEADING_CHILDREN="Maps" COM_FINDER_HEADING_CREATED_BY="Created By" COM_FINDER_HEADING_CREATED_BY_ASC="Created By ascending" @@ -142,11 +91,14 @@ COM_FINDER_HEADING_MAP_COUNT="Map Count" COM_FINDER_HEADING_MAP_COUNT_ASC="Map Count ascending" COM_FINDER_HEADING_MAP_COUNT_DESC="Map Count descending" COM_FINDER_HEADING_NODES="Items" -COM_FINDER_IMPORT="Import" +COM_FINDER_HEADING_PHRASE="Search Phrase" +COM_FINDER_HEADING_RESULTS="Results" +COM_FINDER_HEADING_SEARCH_TERM_ASC="Search Phrase ascending" +COM_FINDER_HEADING_SEARCH_TERM_DESC="Search Phrase descending" COM_FINDER_INDEX="Index" COM_FINDER_INDEX_CONFIRM_DELETE_PROMPT="Are you sure you want to delete the selected item(s)?" COM_FINDER_INDEX_CONFIRM_PURGE_PROMPT="Are you sure you want to delete ALL items from the index? This can take a long time on large sites." -COM_FINDER_INDEX_DATE_INFO="Published Start: %s
    Published End: %s
    Content Start: %s
    Content End: %s" +COM_FINDER_INDEX_DATE_INFO="Published Start: %s
    Published End: %s
    Content Start: %s
    Content End: %s" COM_FINDER_INDEX_DATE_INFO_TITLE="Link Date Information" COM_FINDER_INDEX_FILTER_BY_STATE="Any Published State" COM_FINDER_INDEX_HEADING_DETAILS="Details" @@ -161,7 +113,7 @@ COM_FINDER_INDEX_HEADING_LINK_URL_ASC="Raw URL ascending" COM_FINDER_INDEX_HEADING_LINK_URL_DESC="Raw URL descending" COM_FINDER_INDEX_NO_CONTENT="No content matches your search criteria." COM_FINDER_INDEX_NO_DATA="No content has been indexed." -COM_FINDER_INDEX_PLUGIN_CONTENT_NOT_ENABLED="The Smart Search Content Plugin is disabled. Changes to content will not update the Smart Search index if you do not enable this plugin." +COM_FINDER_INDEX_PLUGIN_CONTENT_NOT_ENABLED="The Smart Search Content Plugin is disabled. Changes to content will not update the Smart Search index if you do not enable this plugin." COM_FINDER_INDEX_PURGE_FAILED="Failed to delete selected items." COM_FINDER_INDEX_PURGE_SUCCESS="All items have been deleted." COM_FINDER_INDEX_SEARCH_DESC="Search in title, URL and last updated date." @@ -184,24 +136,18 @@ COM_FINDER_INDEXER_MESSAGE_OPTIMIZE="The index tables are being optimised for th COM_FINDER_INDEXER_MESSAGE_RUNNING="Your content is being indexed. Do not close this window." COM_FINDER_ITEM_X_ONLY="%s Only" COM_FINDER_ITEMS="Content" -COM_FINDER_MAP_PUBLISH_FAILED="The selected map(s) could not be published. The returned error message is: %s." -COM_FINDER_MAP_PUBLISH_SUCCESS="The selected map(s) were published." -COM_FINDER_MAP_UNPUBLISH_FAILED="The selected map(s) could not be unpublished. The returned error message is: %s." -COM_FINDER_MAP_UNPUBLISH_SUCCESS="The selected map(s) were unpublished." +COM_FINDER_LOGGING_DISABLED="Gathering of statistics is disabled. Enable it in the Options." +COM_FINDER_MANAGER_SEARCHES="Search Term Analysis" COM_FINDER_MAPS="Maps" -COM_FINDER_MAPS_BRANCH_LINK="Select to show the children in this branch." -COM_FINDER_MAPS_BRANCHES="Branches Only" COM_FINDER_MAPS_CONFIRM_DELETE_PROMPT="Are you sure you want to delete the selected map(s)?" COM_FINDER_MAPS_COUNT_PUBLISHED_ITEMS="Published Indexed Content" COM_FINDER_MAPS_COUNT_UNPUBLISHED_ITEMS="Unpublished Indexed Content" COM_FINDER_MAPS_MULTILANG="Note: Language filter system plugin has been enabled, so this branch will not be used." COM_FINDER_MAPS_NO_CONTENT="No results to display. Either no content has been indexed or no content meets your filter criteria." -COM_FINDER_MAPS_RETURN_TO_BRANCHES="Return to Map Groups" COM_FINDER_MAPS_SELECT_BRANCH="- Select Map Group -" COM_FINDER_MAPS_SELECT_TYPE="- Select Type of Content -" COM_FINDER_MAPS_TOOLBAR_TITLE="Smart Search: Content Maps" COM_FINDER_MESSAGE_RETURNED="The following message was returned by the server:" -COM_FINDER_N_ITEMS_CHECKED_IN_0="No item checked in." COM_FINDER_N_ITEMS_CHECKED_IN_1="%d item checked in." COM_FINDER_N_ITEMS_CHECKED_IN_MORE="%d items checked in." COM_FINDER_N_ITEMS_DELETED="%d items deleted." @@ -220,10 +166,10 @@ COM_FINDER_QUERY_FILTER_TODAY="Today" COM_FINDER_QUERY_OPERATOR_AND="And" COM_FINDER_QUERY_OPERATOR_NOT="Not" COM_FINDER_QUERY_OPERATOR_OR="Or" -COM_FINDER_SEARCH_FILTER_SEARCH_DESC="Search in filter title." COM_FINDER_SEARCH_FILTER_SEARCH_LABEL="Search Filters" +COM_FINDER_SEARCH_IN_PHRASE_LABEL="Filter by searched phrase" +COM_FINDER_SEARCH_IN_PHRASE_DESC="Search for the logged phrase of a search" COM_FINDER_SEARCH_LABEL="Search %s:" -COM_FINDER_SEARCH_SEARCH_QUERY_DESC="Search in content map title." COM_FINDER_SEARCH_SEARCH_QUERY_LABEL="Search Content Maps" COM_FINDER_SELECT_SEARCH_FILTER="Select filter" COM_FINDER_STATISTICS="Statistics" @@ -235,7 +181,5 @@ COM_FINDER_STATISTICS_TITLE="Smart Search Statistics" COM_FINDER_SUBMENU_FILTERS="Search Filters" COM_FINDER_SUBMENU_INDEX="Indexed Content" COM_FINDER_SUBMENU_MAPS="Content Maps" -COM_FINDER_UPDATER_MESSAGE_COMPLETE="Smart Search is up to date." -COM_FINDER_UPDATER_MESSAGE_OPTIMIZE="Smart Search is optimising." -COM_FINDER_UPDATER_MESSAGE_PROCESS="Smart Search is updating." +COM_FINDER_SUBMENU_SEARCHES="Statistics" COM_FINDER_XML_DESCRIPTION="Smart Search." diff --git a/administrator/language/en-GB/en-GB.com_installer.ini b/administrator/language/en-GB/en-GB.com_installer.ini index 28163f9ea1375..ee3da899e5cf4 100644 --- a/administrator/language/en-GB/en-GB.com_installer.ini +++ b/administrator/language/en-GB/en-GB.com_installer.ini @@ -5,7 +5,6 @@ COM_INSTALLER="Installer" COM_INSTALLER_AUTHOR_INFORMATION="Author Information" -COM_INSTALLER_CACHETIMEOUT_DESC="For how many hours should Joomla cache update information. This is also the cache time for the Update Notification Plugin, if enabled" COM_INSTALLER_CACHETIMEOUT_LABEL="Updates Caching (in hours)" COM_INSTALLER_CONFIGURATION="Installer: Options" COM_INSTALLER_CONFIRM_UNINSTALL="Are you sure you want to uninstall? Confirming will permanently delete the selected item(s)!" @@ -37,6 +36,8 @@ COM_INSTALLER_HEADER_UPDATE="Extensions: Update" COM_INSTALLER_HEADER_UPDATESITES="Extensions: Update Sites" COM_INSTALLER_HEADER_WARNINGS="Extensions: Warnings" COM_INSTALLER_HEADING_CLIENT="Client" +COM_INSTALLER_HEADING_DATABASE_SCHEMA="Database Version" +COM_INSTALLER_HEADING_DATABASE_SCHEMA_DESC="Database Schema Version in #__schemas" COM_INSTALLER_HEADING_DETAILS_URL="Details URL" COM_INSTALLER_HEADING_DETAILSURL="URL Details" COM_INSTALLER_HEADING_FOLDER="Folder" @@ -56,9 +57,12 @@ COM_INSTALLER_HEADING_NAME_DESC="Name descending" COM_INSTALLER_HEADING_PACKAGE_ID="Package ID" COM_INSTALLER_HEADING_PACKAGE_ID_ASC="Package ID ascending" COM_INSTALLER_HEADING_PACKAGE_ID_DESC="Package ID descending" +COM_INSTALLER_HEADING_PROBLEMS="Problems" COM_INSTALLER_HEADING_TYPE="Type" COM_INSTALLER_HEADING_TYPE_ASC="Type ascending" COM_INSTALLER_HEADING_TYPE_DESC="Type descending" +COM_INSTALLER_HEADING_UPDATE_VERSION="Manifest Version" +COM_INSTALLER_HEADING_UPDATE_VERSION_DESC="Manifest Version in #__extensions manifest_cache" COM_INSTALLER_HEADING_UPDATESITE_NAME="Update Site" COM_INSTALLER_HEADING_UPDATESITE_NAME_ASC="Update Site ascending" COM_INSTALLER_HEADING_UPDATESITE_NAME_DESC="Update Site descending" @@ -69,14 +73,10 @@ COM_INSTALLER_INSTALL_ERROR="Error installing %s" COM_INSTALLER_INSTALL_FROM_DIRECTORY="Install from Folder" COM_INSTALLER_INSTALL_FROM_URL="Install from URL" COM_INSTALLER_INSTALL_FROM_WEB="Install from Web" -COM_INSTALLER_INSTALL_FROM_WEB_ADD_TAB="Add "Install from Web" tab" -COM_INSTALLER_INSTALL_FROM_WEB_INFO="Joomla! Extensions Directory™ (JED) now available with Install from Web on this page." -COM_INSTALLER_INSTALL_FROM_WEB_TOS="By selecting "_QQ_"Add Install from Web tab"_QQ_" below, you agree to the JED Terms of Service and all applicable third party license terms." COM_INSTALLER_INSTALL_LANGUAGE_SUCCESS="Installation of the %s language was successful." COM_INSTALLER_INSTALL_SUCCESS="Installation of the %s was successful." COM_INSTALLER_INSTALL_URL="Install URL" COM_INSTALLER_INVALID_EXTENSION_UPDATE="Invalid extension update" -COM_INSTALLER_LABEL_HIDEPROTECTED_DESC="Hide protected extensions. Protected extensions can't be uninstalled." COM_INSTALLER_LABEL_HIDEPROTECTED_LABEL="Hide Protected Extensions" COM_INSTALLER_LANGUAGES_AVAILABLE_LANGUAGES="Available Languages" COM_INSTALLER_LANGUAGES_FILTER_SEARCH_DESC="Search in language name and language tag." @@ -85,9 +85,8 @@ COM_INSTALLER_MANAGE_FILTER_SEARCH_DESC="Search in extension name. Prefix with I COM_INSTALLER_MANAGE_FILTER_SEARCH_LABEL="Search Extensions" COM_INSTALLER_MINIMUM_STABILITY_ALPHA="Alpha" COM_INSTALLER_MINIMUM_STABILITY_BETA="Beta" -COM_INSTALLER_MINIMUM_STABILITY_DESC="The minimum stability of the extension updates you would like to see. Development is the least stable, Stable is production quality. If an extension doesn't specify a level it is assumed to be Stable." COM_INSTALLER_MINIMUM_STABILITY_DEV="Development" -COM_INSTALLER_MINIMUM_STABILITY_LABEL="Minimum Stability" +COM_INSTALLER_MINIMUM_STABILITY_LABEL="Minimum Extension Stability" COM_INSTALLER_MINIMUM_STABILITY_STABLE="Stable" COM_INSTALLER_MINIMUM_STABILITY_RC="Release Candidate" COM_INSTALLER_MSG_DATABASE="This screen allows to you check that your database table structure is up to date with changes from the previous versions." @@ -95,19 +94,21 @@ COM_INSTALLER_MSG_DATABASE_ADD_COLUMN="Table %2$s does not have column %3$s. (Fr COM_INSTALLER_MSG_DATABASE_ADD_INDEX="Table %2$s does not have index %3$s. (From file %1$s.)" COM_INSTALLER_MSG_DATABASE_CHANGE_COLUMN_TYPE="Table %2$s has the wrong type or attributes for column %3$s with type %4$s. (From file %1$s.)" COM_INSTALLER_MSG_DATABASE_CHECKED_OK="%s database changes were checked." +COM_INSTALLER_MSG_DATABASE_CORE_ERRORS="There are tables not up to date!" +COM_INSTALLER_MSG_DATABASE_CORE_OK="All database table structures are up to date." COM_INSTALLER_MSG_DATABASE_CREATE_TABLE="Table %2$s does not exist. (From file %1$s.)" COM_INSTALLER_MSG_DATABASE_DRIVER="Database driver: %s." COM_INSTALLER_MSG_DATABASE_DROP_COLUMN="Table %2$s should not have column %3$s. (From file %1$s.)" COM_INSTALLER_MSG_DATABASE_DROP_INDEX="Table %2$s should not have index %3$s. (From file %1$s.)" -COM_INSTALLER_MSG_DATABASE_ERRORS="Warning: Database is not up to date!" +COM_INSTALLER_MSG_DATABASE_ERRORS="%d Problems" +COM_INSTALLER_MSG_DATABASE_ERRORS_0="No Problems" +COM_INSTALLER_MSG_DATABASE_ERRORS_1="%d Problem" COM_INSTALLER_MSG_DATABASE_FILTER_ERROR="No default text filters found." COM_INSTALLER_MSG_DATABASE_INFO="Other Information" -COM_INSTALLER_MSG_DATABASE_OK="Database table structure is up to date." -COM_INSTALLER_MSG_DATABASE_SCHEMA_ERROR="Database schema version (%s) does not match CMS version (%s)." -COM_INSTALLER_MSG_DATABASE_SCHEMA_VERSION="Database schema version (in #__schemas): %s." +COM_INSTALLER_MSG_DATABASE_SCHEMA_ERROR="Database version (%1$s) does not match manifest version (%2$s)." +COM_INSTALLER_MSG_DATABASE_SCHEMA_VERSION="Database version (in #__schemas): %s." COM_INSTALLER_MSG_DATABASE_SKIPPED="%s database changes did not alter table structure and were skipped." -COM_INSTALLER_MSG_DATABASE_UPDATE_VERSION="Update version (in #__extensions): %s." -COM_INSTALLER_MSG_DATABASE_UPDATEVERSION_ERROR="Database update version (%s) does not match CMS version (%s)." +COM_INSTALLER_MSG_DATABASE_UPDATEVERSION_ERROR="Database update version (%1$s) does not match %2$s version (%3$s)." COM_INSTALLER_MSG_DATABASE_UTF8_CONVERSION_UTF8="The Joomla! Core database tables have not been converted yet to UTF-8." COM_INSTALLER_MSG_DATABASE_UTF8_CONVERSION_UTF8MB4="The Joomla! Core database tables have not been converted yet to UTF-8 Multibyte (utf8mb4)." COM_INSTALLER_MSG_DESCFTP="For installing or uninstalling Extensions, Joomla will most likely need your FTP account details. Please enter them in the form fields below." @@ -132,7 +133,7 @@ COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB="The installer can't continue until Zl COM_INSTALLER_MSG_LANGUAGES_CANT_FIND_REMOTE_MANIFEST="The installer can't get the URL to the XML manifest file of the %s language." COM_INSTALLER_MSG_LANGUAGES_CANT_FIND_REMOTE_PACKAGE="The installer can't get the URL to the remote %s language." COM_INSTALLER_MSG_LANGUAGES_NOLANGUAGES="There are no available languages to install at the moment. Please select the "Find languages" button to check for updates on the Joomla! Languages server. You will need an internet connection for this to work." -COM_INSTALLER_MSG_LANGUAGES_TRY_LATER="Try again later or contact the language team coordinator." +COM_INSTALLER_MSG_LANGUAGES_TRY_LATER="Try again later or contact the language team coordinator." COM_INSTALLER_MSG_MANAGE_NOEXTENSION="There are no extensions installed matching your query." COM_INSTALLER_MSG_MANAGE_NOUPDATESITE="There are no update sites matching your query." COM_INSTALLER_MSG_N_DATABASE_ERROR_PANEL="%d Database Problems Found." @@ -140,21 +141,21 @@ COM_INSTALLER_MSG_N_DATABASE_ERROR_PANEL_1="1 Database Problem Found." COM_INSTALLER_MSG_UPDATE_ERROR="Error updating %s." COM_INSTALLER_MSG_UPDATE_NODESC="No description available for this item." COM_INSTALLER_MSG_UPDATE_NOUPDATES="There are no updates available at the moment. Please check again later." -COM_INSTALLER_MSG_UPDATE_SITES_COUNT_CHECK="Some update sites are disabled. You may want to check the Update Sites Manager." +COM_INSTALLER_MSG_UPDATE_SITES_COUNT_CHECK="Some update sites are disabled. You may want to check the Update Sites Manager." COM_INSTALLER_MSG_UPDATE_SUCCESS="Updating %s was successful." COM_INSTALLER_MSG_UPDATE_UPDATE="Update" -COM_INSTALLER_MSG_UPDATESITES_DELETE_ERROR="An error has occurred while trying to delete "_QQ_"%s"_QQ_" update site: %s." +COM_INSTALLER_MSG_UPDATESITES_DELETE_ERROR="An error has occurred while trying to delete \"%s\" update site: %s." COM_INSTALLER_MSG_UPDATESITES_DELETE_CANNOT_DELETE="%s update site cannot be deleted." COM_INSTALLER_MSG_UPDATESITES_N_DELETE_UPDATESITES_DELETED="%s update sites have been deleted." COM_INSTALLER_MSG_UPDATESITES_N_DELETE_UPDATESITES_DELETED_1="1 update site has been deleted." -COM_INSTALLER_MSG_UPDATESITES_REBUILD_EXTENSION_PLUGIN_NOT_ENABLED="The Joomla Extension Plugin is disabled. This plugin must be enabled to rebuild the update sites." +COM_INSTALLER_MSG_UPDATESITES_REBUILD_EXTENSION_PLUGIN_NOT_ENABLED="The Joomla Extension Plugin is disabled. This plugin must be enabled to rebuild the update sites." COM_INSTALLER_MSG_UPDATESITES_REBUILD_MESSAGE="Update sites have been rebuilt. No extension with an update site has been discovered." COM_INSTALLER_MSG_UPDATESITES_REBUILD_NOT_PERMITTED="Rebuilding update sites is not permitted." COM_INSTALLER_MSG_UPDATESITES_REBUILD_WARNING="Update sites have been rebuilt. No extension with updates sites discovered." COM_INSTALLER_MSG_UPDATESITES_REBUILD_SUCCESS="Update sites have been rebuilt from manifest files." -COM_INSTALLER_MSG_WARNING_NO_LANGUAGES_UPDATESERVER="The update table is not up to date. Please rebuild your update server table" +COM_INSTALLER_MSG_WARNING_NO_LANGUAGES_UPDATESERVER="The update table is not up to date. Please rebuild your update server table" COM_INSTALLER_MSG_WARNINGFURTHERINFO="Further information on warnings" -COM_INSTALLER_MSG_WARNINGFURTHERINFODESC="For more information on warnings, see the Joomla! Documentation Site." +COM_INSTALLER_MSG_WARNINGFURTHERINFODESC="For more information on warnings, see the Joomla! Documentation Site." COM_INSTALLER_MSG_WARNINGS_FILEUPLOADISDISABLEDDESC="File uploads are required to upload extensions into the installer." COM_INSTALLER_MSG_WARNINGS_FILEUPLOADSDISABLED="File uploads disabled." COM_INSTALLER_MSG_WARNINGS_JOOMLATMPNOTSET="The Joomla temporary folder is not set." @@ -167,7 +168,6 @@ COM_INSTALLER_MSG_WARNINGS_MEDMEMORYDESC="Potentially low PHP memory limit." COM_INSTALLER_MSG_WARNINGS_MEDMEMORYWARN="Your PHP memory limit is set below 16MB which may cause some issues when installing large extensions. Please set your memory limit to at least 16MB." COM_INSTALLER_MSG_WARNINGS_NONE="No warnings detected." COM_INSTALLER_MSG_WARNINGS_NOTCOMPLETE="

    Warning: Update Not Complete!

    The update is only partially complete. Please do the second update to complete the process.

    " -COM_INSTALLER_MSG_WARNINGS_NOTICE="There are some warnings detected." COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSET="The PHP temporary folder is not set." COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTSETDESC="The PHP temporary folder is the folder that PHP uses to store an uploaded file before Joomla can access this file. Whilst the folder not being set isn't always a problem, if you are having issues with manifest files not being detected or uploaded files not being detected, setting this in your php.ini file might fix the issue." COM_INSTALLER_MSG_WARNINGS_PHPUPLOADNOTWRITEABLE="The PHP temporary folder is not writeable." @@ -196,11 +196,6 @@ COM_INSTALLER_PACKAGE_FILE="Package File" COM_INSTALLER_PREFERENCES_DESCRIPTION="Fine tune how extensions installation and updates work." COM_INSTALLER_PREFERENCES_LABEL="Preferences" COM_INSTALLER_REINSTALL_BUTTON="Reinstall" -COM_INSTALLER_SHOW_JED_INFORMATION_DESC="Show or hide the information at the top of the installer page about the Joomla! Extensions Directory™." -COM_INSTALLER_SHOW_JED_INFORMATION_HIDE_MESSAGE="Hide message" -COM_INSTALLER_SHOW_JED_INFORMATION_LABEL="Joomla! Extensions Directory" -COM_INSTALLER_SHOW_JED_INFORMATION_SHOW_MESSAGE="Show message" -COM_INSTALLER_SHOW_JED_INFORMATION_TOOLTIP="Opens Installer Options for setting to hide this Joomla! Extensions Directory™ message." COM_INSTALLER_SUBMENU_DATABASE="Database" COM_INSTALLER_SUBMENU_DISCOVER="Discover" COM_INSTALLER_SUBMENU_INSTALL="Install" @@ -245,8 +240,6 @@ COM_INSTALLER_TYPE_TYPE_TEMPLATE="template" COM_INSTALLER_UNABLE_TO_FIND_INSTALL_PACKAGE="Unable to find install package" COM_INSTALLER_UNABLE_TO_INSTALL_JOOMLA_PACKAGE="The Joomla package cannot be installed through the Extension Manager. Please use the Joomla! Update component to update Joomla." COM_INSTALLER_UNINSTALL_ERROR="Error uninstalling %s." -; This string is deprecated and will be removed with 4.0. -COM_INSTALLER_UNINSTALL_LANGUAGE="A language should always have been installed as a package.
    To uninstall a language, filter type by package and uninstall the package." COM_INSTALLER_UNINSTALL_SUCCESS="Uninstalling the %s was successful." COM_INSTALLER_UPDATE_FILTER_SEARCH_DESC="Search in extension name. Prefix with ID:, UID: or EID: to search for a update ID, update site ID or extension ID." COM_INSTALLER_UPDATE_FILTER_SEARCH_LABEL="Search Extensions with Updates" @@ -260,6 +253,9 @@ COM_INSTALLER_UPLOAD_AND_INSTALL="Upload & Install" COM_INSTALLER_UPLOAD_INSTALL_JOOMLA_EXTENSION="Upload & Install Joomla Extension" COM_INSTALLER_UPLOAD_PACKAGE_FILE="Upload Package File" COM_INSTALLER_VALUE_CLIENT_SELECT="- Select Location -" +COM_INSTALLER_VALUE_CORE_NO="Show non-core extensions" +COM_INSTALLER_VALUE_CORE_SELECT="- Select Core -" +COM_INSTALLER_VALUE_CORE_YES="Show core extensions" COM_INSTALLER_VALUE_FOLDER_NONAPPLICABLE="N/A" COM_INSTALLER_VALUE_FOLDER_SELECT="- Select Folder -" COM_INSTALLER_VALUE_STATE_SELECT="- Select Status -" @@ -273,4 +269,4 @@ COM_INSTALLER_WEBINSTALLER_INSTALL_WEB_LOADING="Loading ..." COM_INSTALLER_WEBINSTALLER_INSTALL_WEB_LOADING_ERROR="Can't connect to the Joomla! server. Please try again later." COM_INSTALLER_WEBINSTALLER_LOAD_APPS="Select to load extensions browser" COM_INSTALLER_XML_DESCRIPTION="Installer component for adding, removing and upgrading extensions" -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_installer.sys.ini b/administrator/language/en-GB/en-GB.com_installer.sys.ini index 9f61e1b505939..a4159dce4e121 100644 --- a/administrator/language/en-GB/en-GB.com_installer.sys.ini +++ b/administrator/language/en-GB/en-GB.com_installer.sys.ini @@ -14,7 +14,7 @@ COM_INSTALLER_LANGUAGES_VIEW_DEFAULT_DESC="Install Language packs into your Joom COM_INSTALLER_LANGUAGES_VIEW_DEFAULT_TITLE="Install Languages" COM_INSTALLER_MANAGE_VIEW_DEFAULT_DESC="Manage extensions that are already installed on your Joomla! website." COM_INSTALLER_MANAGE_VIEW_DEFAULT_TITLE="Manage Extensions" -COM_INSTALLER_UPDATESITES_VIEW_DEFAULT_DESC="Manage "_QQ_"Update Sites"_QQ_" for various installed extensions." +COM_INSTALLER_UPDATESITES_VIEW_DEFAULT_DESC="Manage \"Update Sites\" for various installed extensions." COM_INSTALLER_UPDATESITES_VIEW_DEFAULT_TITLE="Update Sites" COM_INSTALLER_UPDATE_VIEW_DEFAULT_DESC="Find and Install updates for the installed extensions." COM_INSTALLER_UPDATE_VIEW_DEFAULT_TITLE="Update Extensions" diff --git a/administrator/language/en-GB/en-GB.com_joomlaupdate.ini b/administrator/language/en-GB/en-GB.com_joomlaupdate.ini index 28cb73bc173ff..6eec35bd743f2 100644 --- a/administrator/language/en-GB/en-GB.com_joomlaupdate.ini +++ b/administrator/language/en-GB/en-GB.com_joomlaupdate.ini @@ -4,14 +4,12 @@ ; Note : All ini files need to be saved as UTF-8 COM_JOOMLAUPDATE_CHECKED_UPDATES="Checked for updates." -COM_JOOMLAUPDATE_CONFIG_CUSTOMURL_DESC="This is a custom XML update source URL, used only when the "Update Source" option is set to "Custom URL"." COM_JOOMLAUPDATE_CONFIG_CUSTOMURL_LABEL="Custom URL" COM_JOOMLAUPDATE_CONFIG_SOURCES_DESC="Configure where Joomla gets its update information from." COM_JOOMLAUPDATE_CONFIG_SOURCES_LABEL="Update Source" COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM="Custom URL" COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_CUSTOM_ERROR="The custom URL field is empty." COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_DEFAULT="Default" -COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_DESC="The update channel Joomla will use to find out if there is an update available." COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_LABEL="Update Channel" COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_NEXT="Joomla Next" COM_JOOMLAUPDATE_CONFIG_UPDATESOURCE_TESTING="Testing" @@ -21,9 +19,6 @@ COM_JOOMLAUPDATE_TOOLBAR_CHECK="Check for Updates" COM_JOOMLAUPDATE_OVERVIEW="Joomla Update" COM_JOOMLAUPDATE_UPDATE_LOG_CLEANUP="Cleaning up after installation." COM_JOOMLAUPDATE_UPDATE_LOG_COMPLETE="Update to version %s is complete." -; The following two strings are deprecated and will be removed with 4.0 -COM_JOOMLAUPDATE_UPDATE_LOG_CONFIRM_FINALISE="The confirm for the finalise step has passed." -COM_JOOMLAUPDATE_UPDATE_LOG_CONFIRM_FINALISE_FAIL="The confirm of the finalise step has failed" COM_JOOMLAUPDATE_UPDATE_LOG_DELETE_FILES="Deleting removed files and folders." COM_JOOMLAUPDATE_UPDATE_LOG_FILE="File %s downloaded." COM_JOOMLAUPDATE_UPDATE_LOG_FINALISE="Finalising installation." @@ -32,11 +27,27 @@ COM_JOOMLAUPDATE_UPDATE_LOG_START="Update started by user %2$s (%1$s). Old versi COM_JOOMLAUPDATE_UPDATE_LOG_URL="Downloading update file from %s." COM_JOOMLAUPDATE_VIEW_COMPLETE_HEADING="Joomla Version Update Status" COM_JOOMLAUPDATE_VIEW_COMPLETE_MESSAGE="Your site has been updated. Your Joomla version is now %s." +COM_JOOMLAUPDATE_VIEW_DEFAULT_ACTUAL="Actual" +COM_JOOMLAUPDATE_VIEW_DEFAULT_COMPATIBILITY_CHECK="Joomla! %s Compatibility Check" +COM_JOOMLAUPDATE_VIEW_DEFAULT_DESCRIPTION_BREAK="*Extensions marked with No or Missing Compatibility Tag might break your website. Please consult with the developer before upgrading." +COM_JOOMLAUPDATE_VIEW_DEFAULT_DESCRIPTION_MISSING_TAG="*Extensions marked with Missing Compatibility Tag indicate the developer did not add a compatibility tag in the respective extension's XML." +COM_JOOMLAUPDATE_VIEW_DEFAULT_DESCRIPTION_UPDATE_REQUIRED="*Extensions marked with Yes (X.X.X) might require an update." +COM_JOOMLAUPDATE_VIEW_DEFAULT_DIRECTIVE="Directive" COM_JOOMLAUPDATE_VIEW_DEFAULT_DOWNLOAD_IN_PROGRESS="Downloading update file. Please wait ..." +COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_COMPATIBLE="Compatible" +COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_INSTALLED_VERSION="Installed version" +COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_NAME="Extension name" +COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_VERSION_MISSING="Missing Compatibility Tag" +COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSION_WARNING_UNKNOWN="Unkown error" +COM_JOOMLAUPDATE_VIEW_DEFAULT_EXTENSIONS="3rd Party Extensions Pre-Update Check" COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_DOWNLOAD_URL="We can't find a download URL" -COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_DOWNLOAD_URL_DESC="An update to Joomla %1$s was found, but it wasn't possible to fetch the download URL for that update. There are two possibilities why this happens:
    - Your host doesn't support the minimum requirements for Joomla %1$s and there is no alternative download for your configuration available.
    - There is a problem with the Joomla Update Server.

    Please try to download the update package from the official Joomla download page and use the Upload and Update tab." +COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_DOWNLOAD_URL_DESC="An update to Joomla %1$s was found, but it wasn't possible to fetch the download URL for that update. There is a problem with the Joomla Update Server.
    Please try to download the update package from the official Joomla download page and use the Upload and Update tab." +COM_JOOMLAUPDATE_VIEW_DEFAULT_DB_NOT_SUPPORTED="Your database type is not supported" +COM_JOOMLAUPDATE_VIEW_DEFAULT_DB_NOT_SUPPORTED_DESC="An update to Joomla %1$s was found, but your current database type is not supported by the new version.
    For further details take a look at the minimum requirements for Joomla %1$s." +COM_JOOMLAUPDATE_VIEW_DEFAULT_PHP_VERSION_NOT_SUPPORTED="Your PHP version is not supported" +COM_JOOMLAUPDATE_VIEW_DEFAULT_PHP_VERSION_NOT_SUPPORTED_DESC="An update to Joomla %1$s was found, but your currently installed PHP version does not match the minimum requirements for Joomla %1$s." COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_LIVE_UPDATE="Live Update is not available" -COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_LIVE_UPDATE_DESC="There is a new version of the Joomla Update Component that needs to be installed first. Click here to update the component." +COM_JOOMLAUPDATE_VIEW_DEFAULT_NO_LIVE_UPDATE_DESC="There is a new version of the Joomla Update Component that needs to be installed first. Click here to update the component." COM_JOOMLAUPDATE_VIEW_DEFAULT_FTP_DIRECTORY="FTP Root" COM_JOOMLAUPDATE_VIEW_DEFAULT_FTP_HOSTNAME="FTP Host" COM_JOOMLAUPDATE_VIEW_DEFAULT_FTP_PASSWORD="FTP Password" @@ -56,16 +67,20 @@ COM_JOOMLAUPDATE_VIEW_DEFAULT_NOUPDATES="No updates available." COM_JOOMLAUPDATE_VIEW_DEFAULT_NOUPDATESNOTICE="You already have the latest Joomla version, %s." COM_JOOMLAUPDATE_VIEW_DEFAULT_PACKAGE="Update package URL" COM_JOOMLAUPDATE_VIEW_DEFAULT_PACKAGE_REINSTALL="Reinstall package URL" +COM_JOOMLAUPDATE_VIEW_DEFAULT_PREUPDATE_CHECK="Pre-Update Check" +COM_JOOMLAUPDATE_VIEW_DEFAULT_RECOMMENDED="Recommended" +COM_JOOMLAUPDATE_VIEW_DEFAULT_RECOMMENDED_SETTINGS="Recommended settings" +COM_JOOMLAUPDATE_VIEW_DEFAULT_RECOMMENDED_SETTINGS_DESC="These settings are recommended for PHP in order to ensure full compatibility with Joomla. However, Joomla! will still operate if your settings do not quite match the recommended configuration." COM_JOOMLAUPDATE_VIEW_DEFAULT_TAB_ONLINE="Live Update" +COM_JOOMLAUPDATE_VIEW_DEFAULT_TAB_PRE_UPDATE_CHECK="Pre-Update Check" COM_JOOMLAUPDATE_VIEW_DEFAULT_TAB_UPLOAD="Upload & Update" COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATE_NOTICE="Before you update Joomla, ensure that the installed extensions are available for the new Joomla version." COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATEFOUND="A Joomla update was found." COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_CUSTOM="You are on the "%s" update channel. This is not an official Joomla update channel." COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_DEFAULT="You are on the "%s" update channel. Through this channel you'll receive notifications for all updates of the current Joomla release (3.x)" COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_NEXT="You are on the "%s" update channel. Through this channel you'll receive notifications for all updates of the current Joomla release (3.x) and you will also be notified when the future major release (4.x) will be available. Before upgrading to 4.x you'll need to assess its compatibility with your environment." -COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_TESTING="You are on the "%s" update channel. This channel is designed for testing new releases and fixes in Joomla.
    It is only intended for JBS (Joomla Bug Squad™) members and others within the Joomla community who are testing. Do not use this setting on a production site." +COM_JOOMLAUPDATE_VIEW_DEFAULT_UPDATES_INFO_TESTING="You are on the "%s" update channel. This channel is designed for testing new releases and fixes in Joomla.
    It is only intended for JBS (Joomla Bug Squad™) members and others within the Joomla community who are testing. Do not use this setting on a production site." COM_JOOMLAUPDATE_VIEW_DEFAULT_UPLOAD_INTRO="You can use this feature to update Joomla if your server is behind a firewall or otherwise unable to contact the update servers. First download the Joomla Upgrade Package in ZIP format from the official Joomla download page. Then use the fields below to upload and install it." -COM_JOOMLAUPDATE_VIEW_PROGRESS="Update progress" COM_JOOMLAUPDATE_VIEW_UPDATE_BYTESEXTRACTED="Bytes extracted" COM_JOOMLAUPDATE_VIEW_UPDATE_BYTESREAD="Bytes read" COM_JOOMLAUPDATE_VIEW_UPDATE_DOWNLOADFAILED="Download of update package failed." @@ -79,3 +94,21 @@ COM_JOOMLAUPDATE_VIEW_UPLOAD_CAPTIVE_INTRO_BODY="Make sure that the update file COM_JOOMLAUPDATE_VIEW_UPLOAD_CAPTIVE_INTRO_HEAD="Are you sure you want to install the file you uploaded?" COM_JOOMLAUPDATE_VIEW_UPLOAD_PACKAGE_FILE="Joomla package file" COM_JOOMLAUPDATE_XML_DESCRIPTION="Updates Joomla to the latest version with one click." + +;Copy of INSTL constants (Pre-Update check) +INSTL_DATABASE_SUPPORT="Database Support:" +INSTL_DATABASE_SUPPORTED="Database Supported (%s)" +INSTL_DISPLAY_ERRORS="Display Errors" +INSTL_FILE_UPLOADS="File Uploads" +INSTL_JSON_SUPPORT_AVAILABLE="JSON Support" +INSTL_MB_LANGUAGE_IS_DEFAULT="MB Language is Default" +INSTL_MB_STRING_OVERLOAD_OFF="MB String Overload Off" +INSTL_NOTICEMBLANGNOTDEFAULT="PHP mbstring language is not set to neutral. This can be set locally by entering php_value mbstring.language neutral in your .htaccess file." +INSTL_NOTICEMBSTRINGOVERLOAD="PHP mbstring function overload is set. This can be turned off locally by entering php_value mbstring.func_overload 0 in your .htaccess file." +INSTL_OUTPUT_BUFFERING="Output Buffering" +INSTL_PARSE_INI_FILE_AVAILABLE="INI Parser Support" +INSTL_PHP_VERSION_NEWER="PHP Version >= %s" +INSTL_SESSION_AUTO_START="Session Auto Start" +INSTL_XML_SUPPORT="XML Support" +INSTL_ZIP_SUPPORT_AVAILABLE="Native ZIP support" +INSTL_ZLIB_COMPRESSION_SUPPORT="Zlib Compression Support" \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.com_languages.ini b/administrator/language/en-GB/en-GB.com_languages.ini index e20bff907623b..f09fd7cd074ba 100644 --- a/administrator/language/en-GB/en-GB.com_languages.ini +++ b/administrator/language/en-GB/en-GB.com_languages.ini @@ -5,13 +5,9 @@ COM_LANGUAGES="Languages" COM_LANGUAGES_CONFIGURATION="Languages: Options" -COM_LANGUAGES_ERR_DELETE="Select a language to delete" COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED="No language selected." -COM_LANGUAGES_ERROR_LANG_TAG="
    The Language Tag should have 2 or 3 lowercase letters corresponding to the ISO language, a dash and 2 uppercase letters corresponding to the ISO country code.
    This should be the exact prefix used for the language installed or to be installed. Example: en-GB, srp-ME." +COM_LANGUAGES_ERROR_LANG_TAG="
    The Language Tag should have 2 or 3 lowercase letters corresponding to the ISO language, a dash and 2 uppercase letters corresponding to the ISO country code.
    This should be the exact prefix used for the language installed or to be installed. Example: en-GB, srp-ME." COM_LANGUAGES_ERROR_LANGUAGE_METAFILE_MISSING="Could not load %s language meta XML file from %s." -COM_LANGUAGES_ERR_PUBLISH="Select a language to publish." -COM_LANGUAGES_FIELD_DESCRIPTION_DESC="Enter a description for the language." -COM_LANGUAGES_FIELD_IMAGE_DESC="Name of the image file for this language when using the "Use image flags" Language Switcher basic option. Example: if 'en' is chosen, then the image will be en.gif. Images and CSS for this module are in media/mod_languages/." COM_LANGUAGES_FIELD_IMAGE_LABEL="Image" COM_LANGUAGES_FIELD_LANG_TAG_DESC="Enter the language tag – example: en-GB for English (en-GB). This should be the exact prefix used for the language installed or to be installed." COM_LANGUAGES_FIELD_LANG_TAG_LABEL="Language Tag" @@ -20,33 +16,19 @@ COM_LANGUAGES_INSTALLED_FILTER_SEARCH_DESC="Search in title and language tag." COM_LANGUAGES_INSTALLED_FILTER_SEARCH_LABEL="Search Installed Languages" COM_LANGUAGES_OVERRIDE_ERROR_RESERVED_WORDS="YES, NO, NULL, FALSE, ON, OFF, NONE, TRUE are reserved words and can't be used as language constants." COM_LANGUAGES_OVERRIDE_FIELD_BOTH_LABEL="For Both Locations" -COM_LANGUAGES_OVERRIDE_FIELD_BOTH_DESC="If this box is checked the override will be stored for both administrator (Backend) and site (Frontend). This is essential for creating language overrides for some plugins because their language files, while stored in backend, are also used in frontend (example: plg_content_vote).
    Please note that the two overrides will be completely independent from each other after storing them." COM_LANGUAGES_OVERRIDE_FIELD_CLIENT_LABEL="Location" -COM_LANGUAGES_OVERRIDE_FIELD_CLIENT_DESC="Indicates if the override is created for the site (Frontend) or Administrator (Backend) client." COM_LANGUAGES_OVERRIDE_FIELD_FILE_LABEL="File" -COM_LANGUAGES_OVERRIDE_FIELD_FILE_DESC="Language overrides are stored in a specific INI file (as it's the case for the original texts, too). Here you can see in which file the current override is stored." COM_LANGUAGES_OVERRIDE_FIELD_LANGUAGE_LABEL="Language" -COM_LANGUAGES_OVERRIDE_FIELD_LANGUAGE_DESC="Language for which the constant is overridden." COM_LANGUAGES_OVERRIDE_FIELD_KEY_LABEL="Language Constant" -COM_LANGUAGES_OVERRIDE_FIELD_KEY_DESC="The language constant of the string you want to override." COM_LANGUAGES_OVERRIDE_FIELD_OVERRIDE_LABEL="Text" -COM_LANGUAGES_OVERRIDE_FIELD_OVERRIDE_DESC="Enter the text that you want to be displayed instead of the original one.
    Please note that there may be placeholders (eg %s, %d or %1$s) in the text which could be important (they will be replaced by other texts before displaying), so you should leave them in there." COM_LANGUAGES_OVERRIDE_FIELD_SEARCHSTRING_LABEL="Search Text" -COM_LANGUAGES_OVERRIDE_FIELD_SEARCHSTRING_DESC="Please enter the text to search for here. It may be in any of the language files." COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_LABEL="Search For" -COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_DESC="Select if you want to search for constant names or the values (the actual text)." COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_CONSTANT="Constant" COM_LANGUAGES_OVERRIDE_FIELD_SEARCHTYPE_TEXT="Value" -COM_LANGUAGES_FIELD_PUBLISHED_DESC="Whether this content language is published or not. If published, it will display as a choice in the Language Switcher module in Frontend." -COM_LANGUAGES_FIELD_LANG_CODE_DESC="This Language Code will be appended to the site URL. When SEF is enabled, you will get http://example.com/en/. If SEF is disabled the suffix &lang=en will be appended at the end of the URL. Note the Language Code must be unique among all the languages." -COM_LANGUAGES_FIELD_LANG_CODE_LABEL="URL Language Code" -COM_LANGUAGES_FIELD_SITE_NAME_DESC="Enter a custom site name for this content language. If the site name is set to display, this custom site name will be used instead of the Global Configuration setting." +COM_LANGUAGES_FIELD_LANG_CODE_LABEL="URL Language Prefix" COM_LANGUAGES_FIELD_SITE_NAME_LABEL="Custom Site Name" COM_LANGUAGES_FIELDSET_SITE_NAME_LABEL="Site Name" -COM_LANGUAGES_FIELD_TITLE_DESC="The name of the language as it will appear in the lists." -COM_LANGUAGES_FIELD_TITLE_NATIVE_DESC="Title in native language." -COM_LANGUAGES_FIELD_TITLE_NATIVE_LABEL="Title Native" -COM_LANGUAGES_FILTER_CLIENT_LABEL="Filter Location:" +COM_LANGUAGES_FIELD_TITLE_NATIVE_LABEL="Title in Native Language" COM_LANGUAGES_FTP_DESC="For setting Languages as default, Joomla will most likely need your FTP account details. Please enter them in the form fields below." COM_LANGUAGES_FTP_TITLE="FTP Login Details" COM_LANGUAGES_HEADING_AUTHOR="Author" @@ -83,7 +65,7 @@ COM_LANGUAGES_HEADING_TITLE_NATIVE="Native Title" COM_LANGUAGES_HEADING_TITLE_NATIVE_ASC="Native Title ascending" COM_LANGUAGES_HEADING_TITLE_NATIVE_DESC="Native Title descending" COM_LANGUAGES_HOMEPAGE="Home" -COM_LANGUAGES_MSG_DEFAULT_LANGUAGE_SAVED="Default Language Saved. This does not affect users that have chosen a specific language on their profile or on the login page.
    Warning! When using the multilingual functionality (ie when the plugin System - Language Filter is enabled) the Site Default Language also has to be a published Content language." +COM_LANGUAGES_MSG_DEFAULT_LANGUAGE_SAVED="Default Language Saved. This does not affect users that have chosen a specific language on their profile or on the login page.
    Warning! When using the multilingual functionality (ie when the plugin System - Language Filter is enabled) the Site Default Language also has to be a published Content language." COM_LANGUAGES_MSG_SWITCH_ADMIN_LANGUAGE_SUCCESS="The Administrator Language has been switched to "%s"." COM_LANGUAGES_MULTILANGSTATUS_CONTACTS_ERROR="Some of the contacts linked to the user %s are incorrect." COM_LANGUAGES_MULTILANGSTATUS_CONTACTS_ERROR_TIP="Warning! A user/author should have only one contact to which is assigned language 'All' OR one contact for each published Content Language." @@ -101,32 +83,28 @@ COM_LANGUAGES_MULTILANGSTATUS_LANGUAGEFILTER="Language Filter Plugin" COM_LANGUAGES_MULTILANGSTATUS_LANGUAGEFILTER_DISABLED="This site is set as a multilingual site. The Language Filter plugin is not enabled although one or more Language Switcher modules AND/OR one or more specific Content language Default Home pages are published." COM_LANGUAGES_MULTILANGSTATUS_NONE="This site is not set as a multilingual site." COM_LANGUAGES_MULTILANGSTATUS_SITE_LANG_PUBLISHED="Published Site Languages" -COM_LANGUAGES_MULTILANGSTATUS_USELESS_HOMES="This site is not set as a multilingual site.
    Note: at least one Default Home page is assigned to a Content Language. This will not break a monolingual site but is useless." +COM_LANGUAGES_MULTILANGSTATUS_USELESS_HOMES="This site is not set as a multilingual site.
    Note: at least one Default Home page is assigned to a Content Language. This will not break a monolingual site but is useless." COM_LANGUAGES_N_ITEMS_DELETED="%d Content Languages deleted." COM_LANGUAGES_N_ITEMS_DELETED_1="%d Content Language deleted." COM_LANGUAGES_N_ITEMS_PUBLISHED="%d Content Languages published." COM_LANGUAGES_N_ITEMS_PUBLISHED_1="%d Content Language published." COM_LANGUAGES_N_ITEMS_TRASHED="%d Content Languages trashed." COM_LANGUAGES_N_ITEMS_TRASHED_1="%d Content Language trashed." -COM_LANGUAGES_N_ITEMS_UNPUBLISHED="%d Content Languages unpublished.
    Warning! When using the multilingual functionality (ie when the plugin System - Language Filter is enabled) the Site Default Language also has to be a published Content language." -COM_LANGUAGES_N_ITEMS_UNPUBLISHED_1="%d Content Language unpublished.
    Warning! When using the multilingual functionality (ie when the plugin System - Language Filter is enabled) the Site Default Language also has to be a published Content language." +COM_LANGUAGES_N_ITEMS_UNPUBLISHED="%d Content Languages unpublished.
    Warning! When using the multilingual functionality (ie when the plugin System - Language Filter is enabled) the Site Default Language also has to be a published Content language." +COM_LANGUAGES_N_ITEMS_UNPUBLISHED_1="%d Content Language unpublished.
    Warning! When using the multilingual functionality (ie when the plugin System - Language Filter is enabled) the Site Default Language also has to be a published Content language." COM_LANGUAGES_NO_ITEM_SELECTED="No languages selected." COM_LANGUAGES_SAVE_SUCCESS="Content Language saved." COM_LANGUAGES_SEARCH_IN_TITLE="Search in title." COM_LANGUAGES_SUBMENU_CONTENT="Content Languages" COM_LANGUAGES_SUBMENU_INSTALLED="Installed" -COM_LANGUAGES_SUBMENU_INSTALLED_ADMINISTRATOR="Installed - Administrator" -COM_LANGUAGES_SUBMENU_INSTALLED_SITE="Installed - Site" COM_LANGUAGES_SUBMENU_OVERRIDES="Overrides" COM_LANGUAGES_SWITCH_ADMIN="Switch Language" COM_LANGUAGES_VIEW_INSTALLED_ADMIN_TITLE="Languages: Installed (Administrator)" COM_LANGUAGES_VIEW_INSTALLED_SITE_TITLE="Languages: Installed (Site)" -COM_LANGUAGES_VIEW_INSTALLED_TITLE="Languages: Installed" COM_LANGUAGES_VIEW_LANGUAGE_EDIT_EDIT_TITLE="Languages: Edit Content Language" COM_LANGUAGES_VIEW_LANGUAGE_EDIT_NEW_TITLE="Languages: New Content Language" COM_LANGUAGES_VIEW_LANGUAGES_TITLE="Languages: Content" COM_LANGUAGES_VIEW_OVERRIDE_CLIENT_SITE="Site" -COM_LANGUAGES_VIEW_OVERRIDE_CLIENT_ADMINISTRATOR="Administrator" COM_LANGUAGES_VIEW_OVERRIDE_EDIT_TITLE="Languages: Edit Override" COM_LANGUAGES_VIEW_OVERRIDE_EDIT_NEW_OVERRIDE_LEGEND="Create a New Override" COM_LANGUAGES_VIEW_OVERRIDE_EDIT_EDIT_OVERRIDE_LEGEND="Edit this Override" @@ -139,7 +117,7 @@ COM_LANGUAGES_VIEW_OVERRIDE_RESULTS_LEGEND="Search Results" COM_LANGUAGES_VIEW_OVERRIDE_SAVE_SUCCESS="Language Override was saved." COM_LANGUAGES_VIEW_OVERRIDE_SEARCH_BUTTON="Search" COM_LANGUAGES_VIEW_OVERRIDE_SEARCH_LEGEND="Search text you want to change." -COM_LANGUAGES_VIEW_OVERRIDE_SEARCH_TIP="A language string is composed of two parts: a specific language constant and its value.
    For example, in the string: COM_CONTENT_READ_MORE="Read more: "
    'COM_CONTENT_READ_MORE' is the constant and 'Read more: ' is the value.
    You have to use the specific language constant to create an override of the value.
    Therefore, you can search for the constant or the value you want to change with the search field below.
    By selecting the desired result the correct constant will automatically be inserted into the form." +COM_LANGUAGES_VIEW_OVERRIDE_SEARCH_TIP="A language string is composed of two parts: a specific language constant and its value.
    For example, in the string: COM_CONTENT_READ_MORE="Read more: "
    'COM_CONTENT_READ_MORE' is the constant and 'Read more: ' is the value.
    You have to use the specific language constant to create an override of the value.
    Therefore, you can search for the constant or the value you want to change with the search field below.
    By selecting the desired result the correct constant will automatically be inserted into the form." COM_LANGUAGES_VIEW_OVERRIDES_FILTER_SEARCH_DESC="Search constant or text." COM_LANGUAGES_VIEW_OVERRIDES_KEY="Constant" COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM="%1$s - %2$s" @@ -151,4 +129,4 @@ COM_LANGUAGES_VIEW_OVERRIDES_PURGE_SUCCESS="Overrider cache table cleared." COM_LANGUAGES_VIEW_OVERRIDES_TEXT="Text" COM_LANGUAGES_VIEW_OVERRIDES_TITLE="Languages: Overrides" COM_LANGUAGES_XML_DESCRIPTION="Component for language management" -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_media.ini b/administrator/language/en-GB/en-GB.com_media.ini index 42c37e7279a2e..640fd47a1eb9a 100644 --- a/administrator/language/en-GB/en-GB.com_media.ini +++ b/administrator/language/en-GB/en-GB.com_media.ini @@ -4,52 +4,28 @@ ; Note : All ini files need to be saved as UTF-8 COM_MEDIA="Media" -COM_MEDIA_ALIGN="Image Float" -COM_MEDIA_ALIGN_DESC="This will apply the classes 'pull-left', 'pull-center' or 'pull-right' to the '
    ' or '' element." -COM_MEDIA_BROWSE_FILES="Browse files" -COM_MEDIA_CAPTION="Caption" -COM_MEDIA_CAPTION_CLASS_LABEL="Caption Class" -COM_MEDIA_CAPTION_CLASS_DESC="This will apply the entered class to the '
    ' element. For example: 'text-left', 'text-right', 'text-center'." -COM_MEDIA_CLEAR_LIST="Clear List" +COM_MEDIA_ACTIN_RENAME="Rename item" +COM_MEDIA_ACTION_DELETE="Delete item" +COM_MEDIA_ACTION_EDIT="Edit item" +COM_MEDIA_ACTION_PREVIEW="Preview item" +COM_MEDIA_ACTION_SHARE="Get a sharable link" COM_MEDIA_CONFIGURATION="Media: Options" -COM_MEDIA_CREATE_COMPLETE="Create Complete: %s" -COM_MEDIA_CREATE_FOLDER="Create Folder" +COM_MEDIA_CONFIRM_DELETE_MODEL_DESC="Are you sure you want to delete this item?" +COM_MEDIA_CONFIRM_DELETE_MODEL_HEADING="Confirm Delete" +COM_MEDIA_CONFIRM_DELETE_MODEL="Delete" COM_MEDIA_CREATE_NEW_FOLDER="Create New Folder" -COM_MEDIA_CURRENT_PROGRESS="Current progress" -COM_MEDIA_DELETE_COMPLETE="Delete Complete: %s" -COM_MEDIA_DESCFTPTITLE="FTP Login Details" -COM_MEDIA_DESCFTP="To upload, change and delete media files, Joomla will most likely need your FTP account details. Please enter them in the form fields below." -COM_MEDIA_DETAIL_VIEW="Detail View" -COM_MEDIA_DIRECTORY="Folder" -COM_MEDIA_DIRECTORY_UP="Folder Up" -COM_MEDIA_ERROR_BAD_REQUEST="Bad Request" -COM_MEDIA_ERROR_BEFORE_DELETE_0="Some error occurs before deleting the media." -COM_MEDIA_ERROR_BEFORE_DELETE_1="An error occurs before deleting the media: %s" -COM_MEDIA_ERROR_BEFORE_DELETE_MORE="Some errors occur before deleting the media: %s" -COM_MEDIA_ERROR_BEFORE_SAVE_0="Some error occurs before saving the media." -COM_MEDIA_ERROR_BEFORE_SAVE_1="An error occurs before saving the media: %s" -COM_MEDIA_ERROR_BEFORE_SAVE_MORE="Some errors occur before saving the media: %s" -COM_MEDIA_ERROR_CREATE_NOT_PERMITTED="Create not permitted." -COM_MEDIA_ERROR_FILE_EXISTS="File already exists." -COM_MEDIA_ERROR_UNABLE_TO_CREATE_FOLDER_WARNDIRNAME="Unable to create folder. Folder name must only have alphanumeric characters and no spaces." -COM_MEDIA_ERROR_UNABLE_TO_BROWSE_FOLDER_WARNDIRNAME="Unable to browse: %s. Folder name must only have alphanumeric characters and no spaces." -COM_MEDIA_ERROR_UNABLE_TO_DELETE_FILE_WARNFILENAME="Unable to delete: %s. File name must only have alphanumeric characters and no spaces." -COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_NOT_EMPTY="Unable to delete: %s. Folder is not empty!" -COM_MEDIA_ERROR_UNABLE_TO_DELETE_FOLDER_WARNDIRNAME="Unable to delete: %s." -COM_MEDIA_ERROR_UNABLE_TO_DELETE=" Unable to delete: " -COM_MEDIA_ERROR_UNABLE_TO_UPLOAD_FILE="Unable to upload file." -COM_MEDIA_ERROR_UPLOAD_INPUT="Please input a file to upload" -COM_MEDIA_ERROR_WARNFILENAME="File name must only have alphanumeric characters and no spaces." -COM_MEDIA_ERROR_WARNFILENOTSAFE="You have tried to upload file(s) that are not safe." -COM_MEDIA_ERROR_WARNFILETOOLARGE="This file is too large to upload." -COM_MEDIA_ERROR_WARNFILETYPE="This file type is not supported." -COM_MEDIA_ERROR_WARNIEXSS="Possible IE XSS Attack found." -COM_MEDIA_ERROR_WARNINVALID_IMG="Not a valid image." -COM_MEDIA_ERROR_WARNINVALID_MIME="Illegal or invalid mime type detected." -COM_MEDIA_ERROR_WARNNOTADMIN="Uploaded file is not an image file and you are not a manager or higher." -COM_MEDIA_ERROR_WARNNOTEMPTY="Not empty!" -COM_MEDIA_ERROR_WARNUPLOADTOOLARGE="Total size of upload exceeds the limit." -COM_MEDIA_FIELD_CHECK_MIME_DESC="Use MIME Magic or Fileinfo to try to verify files. Try disabling this if you get invalid mime type errors." +COM_MEDIA_CREATE_NEW_FOLDER_SUCCESS="Folder created." +COM_MEDIA_CREATE_NEW_FOLDER_ERROR="Error creating folder." +COM_MEDIA_DECREASE_GRID="Decrease grid size" +COM_MEDIA_DELETE_ERROR="Error deleting the item." +COM_MEDIA_DELETE_SUCCESS="Item deleted." +COM_MEDIA_EDIT="Media Edit" +COM_MEDIA_ERROR="An error occurred." +COM_MEDIA_ERROR_NO_PROVIDERS="No filesystem providers have been found. Please enable at least one filesystem plugin." +COM_MEDIA_ERROR_NOT_AUTHENTICATED="You are not authenticated. Please login." +COM_MEDIA_ERROR_NOT_AUTHORIZED="You are not authorized" +COM_MEDIA_ERROR_NOT_FOUND="File or Folder not found" +COM_MEDIA_FIELD_CHECK_MIME_DESC="Use MIME Magic or Fileinfo to attempt to verify files. Try disabling this if you get invalid mime type errors." COM_MEDIA_FIELD_CHECK_MIME_LABEL="Check MIME Types" COM_MEDIA_FIELD_IGNORED_EXTENSIONS_DESC="Ignored file extensions for MIME type checking and restricted uploads." COM_MEDIA_FIELD_IGNORED_EXTENSIONS_LABEL="Ignored Extensions" @@ -61,7 +37,7 @@ COM_MEDIA_FIELD_LEGAL_IMAGE_EXTENSIONS_DESC=" Image extensions (file types) you COM_MEDIA_FIELD_LEGAL_IMAGE_EXTENSIONS_LABEL="Legal Image Extensions (File Types)" COM_MEDIA_FIELD_LEGAL_MIME_TYPES_DESC="A comma separated list of legal MIME types to upload." COM_MEDIA_FIELD_LEGAL_MIME_TYPES_LABEL="Legal MIME Types" -COM_MEDIA_FIELD_MAXIMUM_SIZE_DESC="The maximum size for an upload (in megabytes). Use zero for no limit. Note: your server has a maximum limit." +COM_MEDIA_FIELD_MAXIMUM_SIZE_DESC="Use zero for no limit. Note: your server has a maximum limit." COM_MEDIA_FIELD_MAXIMUM_SIZE_LABEL="Maximum Size (in MB)" COM_MEDIA_FIELD_PATH_FILE_FOLDER_DESC="Enter the path to the files folder relative to the root of your webspace. Warning! Changing to another path than the default 'images' may break your links. Note: Do not start the path with a slash!" COM_MEDIA_FIELD_PATH_FILE_FOLDER_LABEL="Path to Files Folder" @@ -70,35 +46,31 @@ COM_MEDIA_FIELD_PATH_IMAGE_FOLDER_LABEL="Path to Images Folder" COM_MEDIA_FIELD_RESTRICT_UPLOADS_DESC="Restrict uploads for lower than manager users to images if Fileinfo or MIME Magic isn't installed." COM_MEDIA_FIELD_RESTRICT_UPLOADS_LABEL="Restrict Uploads" COM_MEDIA_FIELDSET_OPTIONS_LABEL="Media" -COM_MEDIA_FILES="Files" -COM_MEDIA_FILESIZE="File size" +COM_MEDIA_FILE_EXISTS_AND_OVERRIDE="%s already exists. Do you want to replace it?" COM_MEDIA_FOLDER="Folder" COM_MEDIA_FOLDERS="Media Folders" -COM_MEDIA_FOLDERS_PATH_LABEL="Warning! Path Folder
    Changing the 'Path to files folder' from the default of 'images' may break your links.
    The 'Path to images' folder has to be the same or a subfolder of 'Path to files'." -COM_MEDIA_IMAGE_DESCRIPTION="Image Description" -COM_MEDIA_IMAGE_DIMENSIONS="%1$s x %2$s" -COM_MEDIA_IMAGE_TITLE="%1$s - %2$s" -COM_MEDIA_IMAGE_URL="Image URL" -COM_MEDIA_INSERT_IMAGE="Insert Image" -COM_MEDIA_INSERT="Insert" -COM_MEDIA_INVALID_REQUEST="Invalid Request" -COM_MEDIA_MEDIA="Media" -COM_MEDIA_NAME="Image Name" -COM_MEDIA_NO_IMAGES_FOUND="No Images Found" -COM_MEDIA_NOT_SET="Not Set" -COM_MEDIA_OVERALL_PROGRESS="Overall Progress" -COM_MEDIA_PIXEL_DIMENSIONS="Dimensions (px)" -COM_MEDIA_PREVIEW="Preview" -COM_MEDIA_START_UPLOAD="Start Upload" -COM_MEDIA_THUMBNAIL_VIEW="Thumbnail View" -COM_MEDIA_TITLE="Image Title" -COM_MEDIA_UPLOAD_COMPLETE="Upload Complete: %s" -COM_MEDIA_UPLOAD_FILE="Upload file" -; The following two strings are deprecated with 3.7.0 and will be removed in 4.0 -COM_MEDIA_UPLOAD_FILES="Upload files (Maximum Size: %s MB)" -COM_MEDIA_UPLOAD_FILES_NOLIMIT="Upload files (No maximum size)" -COM_MEDIA_UPLOAD_SUCCESSFUL="Upload Successful" -COM_MEDIA_UPLOAD="Upload" -COM_MEDIA_UP="Up" -COM_MEDIA_XML_DESCRIPTION="Component for managing site media" -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +COM_MEDIA_FOLDERS_PATH_LABEL="Warning! Path Folder
    Changing the 'Path to files folder' from the default of 'images' may break your links.
    The 'Path to images' folder has to be the same or a subfolder of 'Path to files'." +COM_MEDIA_MEDIA_CREATED_AT="Created at" +COM_MEDIA_MEDIA_DIMENSION="Dimensions" +COM_MEDIA_MEDIA_EXTENSION="Extension" +COM_MEDIA_MEDIA_MIME_TYPE="MIME Type" +COM_MEDIA_MEDIA_MODIFIED_AT="Modified at" +COM_MEDIA_MEDIA_NAME="Name" +COM_MEDIA_MEDIA_SIZE="Size" +COM_MEDIA_MEDIA_TYPE="Type" +COM_MEDIA_NAME="Name" +COM_MEDIA_OPEN_ITEM_ACTIONS="Open item actions" +COM_MEDIA_RENAME="Rename" +COM_MEDIA_RENAME_ERROR="Error renaming item." +COM_MEDIA_RENAME_SUCCESS="Item renamed." +COM_MEDIA_RESET="Reset" +COM_MEDIA_SEARCH="Search..." +COM_MEDIA_SELECT_ALL="Toggle select all" +COM_MEDIA_SERVER_ERROR="Internal server error" +COM_MEDIA_SHARE="Share the file" +COM_MEDIA_SHARE_DESC="Share the file with others. Anyone with link can view the file" +COM_MEDIA_SHARE_COPY_FAILED_ERROR="Error copying to clipboard" +COM_MEDIA_TOGGLE_INFO="Toggle item info" +COM_MEDIA_TOGGLE_LIST_VIEW="Toggle between grid and table views" +COM_MEDIA_TOGGLE_SELECT_ITEM="Toggle select item" +COM_MEDIA_UPDLOAD_SUCCESS="Item uploaded." diff --git a/administrator/language/en-GB/en-GB.com_menus.ini b/administrator/language/en-GB/en-GB.com_menus.ini index c1cdd452e045a..7cab05a6a4629 100644 --- a/administrator/language/en-GB/en-GB.com_menus.ini +++ b/administrator/language/en-GB/en-GB.com_menus.ini @@ -9,7 +9,6 @@ COM_MENUS_ACTION_DESELECT="Deselect" COM_MENUS_ACTION_EXPAND="Expand" COM_MENUS_ACTION_SELECT="Select" COM_MENUS_ADD_MENU_MODULE="Add a module for this menu" -COM_MENUS_ADVANCED_FIELDSET_LABEL="Advanced" COM_MENUS_BASIC_FIELDSET_LABEL="Options" COM_MENUS_BATCH_MENU_ITEM_CANNOT_CREATE="You are not allowed to create new menu items." COM_MENUS_BATCH_MENU_ITEM_CANNOT_EDIT="You are not allowed to edit menu items." @@ -73,110 +72,70 @@ COM_MENUS_HTML_UNPUBLISH_HEADING="Unpublish the heading menu item" COM_MENUS_HTML_UNPUBLISH_SEPARATOR="Unpublish the separator menu item" COM_MENUS_HTML_UNPUBLISH_URL="Unpublish the URL menu item" COM_MENUS_INTEGRATION_FIELDSET_LABEL="Integration" -; The following 2 strings are deprecated and will be removed with 4.0. -COM_MENUS_ITEM_ASSOCIATIONS_FIELDSET_LABEL="Menu Item Associations" -COM_MENUS_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a menu item for the target language. This association will let the Language Switcher module redirect to the associated menu item in another language. If used, make sure to display the Language switcher module on the relevant pages. A menu item set to language 'All' can't be associated." COM_MENUS_ITEM_DETAILS="Details" -COM_MENUS_ITEM_FIELD_ALIAS_DESC="The alias is used in the URL when SEF is on." -COM_MENUS_ITEM_FIELD_ALIAS_MENU_DESC="Menu Item to link to." COM_MENUS_ITEM_FIELD_ALIAS_MENU_LABEL="Menu Item" -COM_MENUS_ITEM_FIELD_ANCHOR_CSS_DESC="An optional class to apply to the menu hyperlink." COM_MENUS_ITEM_FIELD_ANCHOR_CSS_LABEL="Link Class" -COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_DESC="An optional, custom description for the title attribute of the menu hyperlink." COM_MENUS_ITEM_FIELD_ANCHOR_TITLE_LABEL="Link Title Attribute" -COM_MENUS_ITEM_FIELD_ANCHOR_REL_DESC="An optional, custom rel attribute to get more information about the menu hyperlink (search engines purpose)." COM_MENUS_ITEM_FIELD_ANCHOR_REL_LABEL="Link Rel Attribute" -COM_MENUS_ITEM_FIELD_ASSIGNED_DESC="Shows which menu the link will appear in." COM_MENUS_ITEM_FIELD_ASSIGNED_LABEL=" Menu" COM_MENUS_ITEM_FIELD_ASSOCIATION_NO_VALUE="- No association -" -COM_MENUS_ITEM_FIELD_BROWSERNAV_DESC="Target browser window when the menu item is selected." COM_MENUS_ITEM_FIELD_BROWSERNAV_LABEL="Target Window" COM_MENUS_ITEM_FIELD_COMPONENTS_CONTAINER_HIDE_ITEMS_DESC="Select the menu items that should or should not be shown under this container. If there are no items to show, then this container will also be hidden.
    Please note that when you install a new component it will be displayed by default until you come back here and hide it too." COM_MENUS_ITEM_FIELD_COMPONENTS_CONTAINER_HIDE_ITEMS_LABEL="Show or Hide Menu Items" COM_MENUS_ITEM_FIELD_HIDE_UNASSIGNED="Hide Unassigned Modules" -COM_MENUS_ITEM_FIELD_HIDE_UNASSIGNED_DESC="Show or hide modules unassigned to this menu item." COM_MENUS_ITEM_FIELD_HIDE_UNASSIGNED_LABEL="Unassigned Modules" COM_MENUS_ITEM_FIELD_HIDE_UNPUBLISHED="Hide Unpublished Modules" -COM_MENUS_ITEM_FIELD_HIDE_UNPUBLISHED_DESC="Show or hide modules that are unpublished." COM_MENUS_ITEM_FIELD_HIDE_UNPUBLISHED_LABEL="Unpublished Modules" -COM_MENUS_ITEM_FIELD_HOME_DESC="Sets this menu item as the default or home page of the site. You must have a default page set at all times." COM_MENUS_ITEM_FIELD_HOME_LABEL="Default Page" -COM_MENUS_ITEM_FIELD_LANGUAGE_DESC="Assign a language to this menu item." -COM_MENUS_ITEM_FIELD_LINK_DESC="Link for this menu." COM_MENUS_ITEM_FIELD_LINK_LABEL="Link" -COM_MENUS_ITEM_FIELD_MENU_IMAGE_DESC="Select or upload an optional image to be used with the menu hyperlink." COM_MENUS_ITEM_FIELD_MENU_IMAGE_LABEL="Link Image" COM_MENUS_ITEM_FIELD_MENU_IMAGE_CSS_DESC="An optional, custom style to apply to the image element." COM_MENUS_ITEM_FIELD_MENU_IMAGE_CSS_LABEL="Image CSS Style" COM_MENUS_ITEM_FIELD_MENU_SHOW_DESC="Select 'No' if you want to hide this menu item. Note any submenu items will also be hidden." COM_MENUS_ITEM_FIELD_MENU_SHOW_LABEL="Display in Menu" -COM_MENUS_ITEM_FIELD_MENU_TEXT_DESC="If the optional image is added, adds the menu title next to the image. Default is 'Yes'." COM_MENUS_ITEM_FIELD_MENU_TEXT_LABEL="Add Menu Title" -COM_MENUS_ITEM_FIELD_NOTE_DESC="An optional note to display in the Menu Manager." -COM_MENUS_ITEM_FIELD_ORDERING_DESC="The menu item will be placed in the menu after the selected menu item." COM_MENUS_ITEM_FIELD_ORDERING_LABEL="Ordering" COM_MENUS_ITEM_FIELD_ORDERING_TEXT="Ordering will be available after saving." COM_MENUS_ITEM_FIELD_ORDERING_VALUE_FIRST="- First -" COM_MENUS_ITEM_FIELD_ORDERING_VALUE_LAST="- Last -" -COM_MENUS_ITEM_FIELD_PAGE_CLASS_DESC="Optional CSS class to add to elements in this page. This allows CSS styling specific to this page." COM_MENUS_ITEM_FIELD_PAGE_CLASS_LABEL="Page Class" -COM_MENUS_ITEM_FIELD_PAGE_HEADING_DESC="Optional alternative text for the Page heading." COM_MENUS_ITEM_FIELD_PAGE_HEADING_LABEL="Page Heading" -COM_MENUS_ITEM_FIELD_PAGE_TITLE_DESC="Optional text for the "Browser page title" element. If blank, a default value is used based on the Menu Item Title." COM_MENUS_ITEM_FIELD_PAGE_TITLE_LABEL="Browser Page Title" -COM_MENUS_ITEM_FIELD_PARENT_DESC="Select a parent item." COM_MENUS_ITEM_FIELD_PARENT_LABEL="Parent Item" -COM_MENUS_ITEM_FIELD_SECURE_DESC="Selects if this link should use HTTPS (encrypted HTTP connections with the https:// protocol prefix). Note, you must have HTTPS enabled on your server to utilise this option." -COM_MENUS_ITEM_FIELD_SECURE_LABEL="Secure" -COM_MENUS_ITEM_FIELD_SHOW_PAGE_HEADING_DESC="Show or hide the Browser Page Title in the heading of the page ( If no optional text entered - will default to value based on the Menu Item Title ). The Page heading is usually displayed inside the "H1" tag." COM_MENUS_ITEM_FIELD_SHOW_PAGE_HEADING_LABEL="Show Page Heading" -COM_MENUS_ITEM_FIELD_TEMPLATE_DESC="Select a specific template style for this menu item or use the default template." COM_MENUS_ITEM_FIELD_TEMPLATE_LABEL="Template Style" -COM_MENUS_ITEM_FIELD_TEXT_SEPARATOR_DESC="Choose whether this separator will be displayed as a label. If the title has only dashes (-) and spaces, it will not be displayed as a label." COM_MENUS_ITEM_FIELD_TEXT_SEPARATOR_LABEL="Display as a label" -COM_MENUS_ITEM_FIELD_TITLE_DESC="The title of the menu item that will display in the menu." COM_MENUS_ITEM_FIELD_TITLE_LABEL="Menu Title" -COM_MENUS_ITEM_FIELD_TYPE_DESC="The type of link: Component, URL, Alias, Separator or Heading." COM_MENUS_ITEM_FIELD_TYPE_LABEL="Menu Item Type" -COM_MENUS_ITEM_IS_DEFAULT="Is default" COM_MENUS_ITEM_MODULE_ASSIGNMENT="Module Assignment" -COM_MENUS_ITEM_REQUIRED="Required" COM_MENUS_ITEM_ROOT="Menu Item Root" COM_MENUS_ITEMS_REBUILD_FAILED="Failed rebuilding Menu Items list." COM_MENUS_ITEMS_REBUILD_SUCCESS="Menu items list rebuilt." COM_MENUS_ITEMS_SEARCH_FILTER="Search in title, alias and notes. Prefix with ID: to search for a menu item ID." COM_MENUS_ITEMS_SEARCH_FILTER_LABEL="Search Menu Items" -COM_MENUS_ITEMS_SET_HOME_0="No menu item set to home." COM_MENUS_ITEMS_SET_HOME_1="1 menu item set to home." COM_MENUS_ITEMS_SET_HOME_MORE="%d menu items set to home." COM_MENUS_ITEMS_UNSET_HOME="1 menu item unset to home." COM_MENUS_LABEL_HIDDEN="Hidden" COM_MENUS_LAYOUT_FEATURED_OPTIONS="Layout" -COM_MENUS_LAYOUT_MENUTYPE_OPTIONS_LABEL="Menu Type" COM_MENUS_LINKTYPE_OPTIONS_LABEL="Link Type" COM_MENUS_MENU_CLIENT_ID_LABEL="Client" -COM_MENUS_MENU_CLIENT_ID_DESC="Select if this Menu is to be used in the Site or the Administrator." COM_MENUS_MENU_CONFIRM_DELETE="Are you sure you want to delete these menus? Confirming will delete the selected menu types, all their menu items and the associated menu modules." -COM_MENUS_MENU_DESCRIPTION_DESC="A description about the purpose of the menu." COM_MENUS_MENU_DETAILS="Menu Details" COM_MENUS_MENU_EXPORT_BUTTON="Download as Preset" COM_MENUS_MENU_ITEM_SAVE_SUCCESS="Menu item saved." -COM_MENUS_MENU_MENUTYPE_DESC="The system name of the menu." -COM_MENUS_MENU_MENUTYPE_LABEL="Menu Type" +COM_MENUS_MENU_MENUTYPE_LABEL="Unique Name" COM_MENUS_MENU_SAVE_SUCCESS="Menu saved" COM_MENUS_MENU_SEARCH_FILTER="Search in Title or Menu type" COM_MENUS_MENU_SPRINTF="Menu: %s" COM_MENUS_MENUS="Menu items" COM_MENUS_MENU_TYPE_PROTECTED_MAIN_LABEL="Main (Protected)" -COM_MENUS_MENU_TITLE_DESC="The title of the menu to display in the Administrator Menubar and lists." COM_MENUS_MENUS_FILTER_SEARCH_DESC="Search in title and menu type." COM_MENUS_MENUS_FILTER_SEARCH_LABEL="Search Menus" ; in the following string ; %1$s is for module title, %2$s is for access-title, %3$s is for position COM_MENUS_MODULE_ACCESS_POSITION="%1$s (%2$s in %3$s)" -COM_MENUS_MODULE_SHOW_VARIES="Varies" COM_MENUS_MODULES="Modules" -COM_MENUS_N_ITEMS_CHECKED_IN_0="No menu item checked in." COM_MENUS_N_ITEMS_CHECKED_IN_1="%d menu item checked in." COM_MENUS_N_ITEMS_CHECKED_IN_MORE="%d menu items checked in." COM_MENUS_N_ITEMS_DELETED="%d menu items deleted." @@ -209,10 +168,7 @@ COM_MENUS_SELECT_MENU_FIRST="To use batch processing, please first select a Menu COM_MENUS_SELECT_MENU_FIRST_EXPORT="To use export, please first select a valid Menu in the manager." COM_MENUS_SUBMENU_ITEMS="Menu Items" COM_MENUS_SUBMENU_MENUS="Menus" -COM_MENUS_SUCCESS_REORDERED="Menu item reordered." -COM_MENUS_TIP_ALIAS_LABEL="Warning!
    Leave the alias field empty if the menu item alias and the menu item linked to by the alias have the same parent." COM_MENUS_TIP_ASSOCIATION="Associated menu items" -COM_MENUS_TITLE_EDIT_ITEM="Menu Manager: Title Edit Item" COM_MENUS_TITLE_TRANSLATION="Title (%s)" COM_MENUS_TOOLBAR_SET_HOME="Home" COM_MENUS_TYPE_ALIAS="Menu Item Alias" @@ -233,9 +189,8 @@ COM_MENUS_VIEW_EDIT_ITEM_TITLE="Menus: Edit Item" COM_MENUS_VIEW_EDIT_MENU_TITLE="Menus: Edit" COM_MENUS_VIEW_ITEMS_ALL_TITLE="Menus: All Menu Items" COM_MENUS_VIEW_ITEMS_MENU_TITLE="Menus: Items (%s)" -COM_MENUS_VIEW_ITEMS_TITLE="Menus: Items" COM_MENUS_VIEW_MENUS_TITLE="Menus" COM_MENUS_VIEW_NEW_ITEM_TITLE="Menus: New Item" COM_MENUS_VIEW_NEW_MENU_TITLE="Menus: Add" COM_MENUS_XML_DESCRIPTION="Component for creating menus." -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_messages.ini b/administrator/language/en-GB/en-GB.com_messages.ini index 70cf935792e99..4b877469b5ea5 100644 --- a/administrator/language/en-GB/en-GB.com_messages.ini +++ b/administrator/language/en-GB/en-GB.com_messages.ini @@ -15,22 +15,16 @@ COM_MESSAGES_ERROR_INVALID_FROM_USER="Invalid sender" COM_MESSAGES_ERROR_INVALID_MESSAGE="Invalid message content" COM_MESSAGES_ERROR_INVALID_SUBJECT="Invalid subject" COM_MESSAGES_ERROR_INVALID_TO_USER="Invalid recipient" -COM_MESSAGES_FIELD_AUTO_PURGE_DESC="Automatically delete private messages after the given number of days." +COM_MESSAGES_ERROR_MAIL_FAILED="The email could not be sent." COM_MESSAGES_FIELD_AUTO_PURGE_LABEL="Auto-delete Messages (days)" COM_MESSAGES_FIELD_DATE_TIME_LABEL="Posted" -COM_MESSAGES_FIELD_LOCK_DESC="Lock your private message inbox." COM_MESSAGES_FIELD_LOCK_LABEL="Lock Inbox" -COM_MESSAGES_FIELD_MAIL_ON_NEW_DESC="Email me when a new private message arrives." COM_MESSAGES_FIELD_MAIL_ON_NEW_LABEL="Email New Messages" -COM_MESSAGES_FIELD_MESSAGE_DESC="You must enter a message." COM_MESSAGES_FIELD_MESSAGE_LABEL="Message" -COM_MESSAGES_FIELD_SUBJECT_DESC="You must enter a subject." COM_MESSAGES_FIELD_SUBJECT_LABEL="Subject" COM_MESSAGES_FIELD_USER_ID_FROM_LABEL="From" -COM_MESSAGES_FIELD_USER_ID_TO_DESC="You must select a recipient." COM_MESSAGES_FIELD_USER_ID_TO_LABEL="Recipient" COM_MESSAGES_FILTER_SEARCH_LABEL="Search Messages" -COM_MESSAGES_FILTER_STATES_DESC="Filter by message state." COM_MESSAGES_FILTER_STATES_LABEL="State" COM_MESSAGES_HEADING_FROM="From" COM_MESSAGES_HEADING_FROM_ASC="From ascending" @@ -45,7 +39,6 @@ COM_MESSAGES_INVALID_REPLY_ID="Invalid recipient" COM_MESSAGES_MANAGER_MESSAGES="Private Messages" COM_MESSAGES_MARK_AS_READ="Mark as Read" COM_MESSAGES_MARK_AS_UNREAD="Mark as Unread" -COM_MESSAGES_MY_SETTINGS="My Settings" COM_MESSAGES_N_ITEMS_DELETED="%d messages deleted." COM_MESSAGES_N_ITEMS_DELETED_1="Message deleted." COM_MESSAGES_N_ITEMS_PUBLISHED="%d messages marked as read." @@ -61,7 +54,6 @@ COM_MESSAGES_OPTION_UNREAD="Unread" COM_MESSAGES_PLEASE_LOGIN="Please log in to %s to read your message." COM_MESSAGES_RE="Re:" COM_MESSAGES_READ="Messages" -COM_MESSAGES_READ_PRIVATE_MESSAGE="Read Private Message" COM_MESSAGES_SEARCH_IN_SUBJECT="Search in message subject and description." COM_MESSAGES_TOOLBAR_MARK_AS_READ="Mark as Read" COM_MESSAGES_TOOLBAR_MARK_AS_UNREAD="Mark as Unread" @@ -72,4 +64,4 @@ COM_MESSAGES_VIEW_PRIVATE_MESSAGE="Private Messages: View" COM_MESSAGES_WRITE_PRIVATE_MESSAGE="Private Messages: Write" COM_MESSAGES_XML_DESCRIPTION="Component for private messaging support in Backend." JLIB_APPLICATION_SAVE_SUCCESS="Message sent." -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_modules.ini b/administrator/language/en-GB/en-GB.com_modules.ini index cd1948b7036ac..b5eba9b69c3bd 100644 --- a/administrator/language/en-GB/en-GB.com_modules.ini +++ b/administrator/language/en-GB/en-GB.com_modules.ini @@ -5,7 +5,6 @@ COM_MODULES="Modules Manager" COM_MODULES_ACTION_EDITFRONTEND="Frontend Editing" -COM_MODULES_ACTION_EDITFRONTEND_COMPONENT_DESC="Allows users in the group to edit in Frontend." COM_MODULES_ADMIN_LANG_FILTER_FIELDSET_LABEL="Administrator Modules" COM_MODULES_ADMIN_LANG_FILTER_DESC="Allows filtering administrator modules per administrator language." COM_MODULES_ADMIN_LANG_FILTER_LABEL="Language Filtering" @@ -24,52 +23,30 @@ COM_MODULES_CONFIGURATION="Module: Options" COM_MODULES_CUSTOM_OUTPUT="Custom Output" COM_MODULES_ERR_XML="Module XML data not available" COM_MODULES_ERROR_CANNOT_FIND_MODULE="Can't find module" -COM_MODULES_ERROR_CANNOT_GET_MODULE="Can't get module" COM_MODULES_ERROR_INVALID_EXTENSION="Invalid module" COM_MODULES_ERROR_NO_MODULES_SELECTED="No module selected." COM_MODULES_EXTENSION_PUBLISHED_DISABLED="Module disabled and published." COM_MODULES_EXTENSION_PUBLISHED_ENABLED="Module enabled and published." COM_MODULES_EXTENSION_UNPUBLISHED_DISABLED="Module disabled and unpublished." COM_MODULES_EXTENSION_UNPUBLISHED_ENABLED="Module enabled and unpublished." -COM_MODULES_EXTRA_STYLE_DESC="Specify the style for the module or the modules in the position selected." -COM_MODULES_EXTRA_STYLE_TITLE="Module(s) style" COM_MODULES_FIELD_AUTOMATIC_TITLE_LABEL="Automatic Title" -COM_MODULES_FIELD_AUTOMATIC_TITLE_DESC="Set yes if you want an automatic translated title. Its use depends on the Administrator template." -COM_MODULES_FIELD_CACHE_TIME_DESC="The time in seconds before the module is recached." COM_MODULES_FIELD_CACHE_TIME_LABEL="Cache Time" -COM_MODULES_FIELD_CACHING_DESC="Use the global cache setting to cache the content of this module or disable caching for this module." COM_MODULES_FIELD_CACHING_LABEL="Caching" -COM_MODULES_FIELD_CLIENT_ID_DESC="The location of the module, Frontend or Backend. You can't change this value." COM_MODULES_FIELD_CLIENT_ID_LABEL="Module Location" -COM_MODULES_FIELD_CONTENT_DESC="Text" COM_MODULES_FIELD_CONTENT_LABEL="Text" -COM_MODULES_FIELD_MODULE_DESC="Module type." COM_MODULES_FIELD_MODULE_LABEL="Module Type" -COM_MODULES_FIELD_MODULECLASS_SFX_DESC="A suffix to be applied to the CSS class of the module. This allows for individual module styling." -COM_MODULES_FIELD_MODULECLASS_SFX_LABEL="Module Class Suffix" -COM_MODULES_FIELD_NOTE_DESC="An optional note to display in the Module Manager." +COM_MODULES_FIELD_MODULECLASS_SFX_LABEL="Module Class" COM_MODULES_FIELD_NOTE_LABEL="Note" -COM_MODULES_FIELD_POSITION_DESC="You may select a module position from the list of pre-defined positions or enter your own module position by typing the name in the field and pressing enter." COM_MODULES_FIELD_POSITION_LABEL="Position" -COM_MODULES_FIELD_PUBLISH_DOWN_DESC="An optional date to Finish Publishing the module." COM_MODULES_FIELD_PUBLISH_DOWN_LABEL="Finish Publishing" -COM_MODULES_FIELD_PUBLISH_UP_DESC="An optional date to Start Publishing the module." COM_MODULES_FIELD_PUBLISH_UP_LABEL="Start Publishing" -COM_MODULES_FIELD_PUBLISHED_DESC="If published, this module will display on your site Frontend or Backend depending on the module." -COM_MODULES_FIELD_SHOWTITLE_DESC="Show or hide module title on display. Effect will depend on the chrome style in the template." -COM_MODULES_FIELD_SHOWTITLE_LABEL="Show Title" -COM_MODULES_FIELD_TITLE_DESC="Module must have a title." +COM_MODULES_FIELD_SHOWTITLE_LABEL="Title" COM_MODULES_FIELD_VALUE_NOCACHING="No caching" COM_MODULES_FIELD_MODULE_TAG_LABEL="Module Tag" -COM_MODULES_FIELD_MODULE_TAG_DESC="The HTML tag for module." COM_MODULES_FIELD_BOOTSTRAP_SIZE_LABEL="Bootstrap Size" -COM_MODULES_FIELD_BOOTSTRAP_SIZE_DESC="An option to specify how many columns the module will use." COM_MODULES_FIELD_HEADER_TAG_LABEL="Header Tag" -COM_MODULES_FIELD_HEADER_TAG_DESC="The HTML tag for module header/title." COM_MODULES_FIELD_HEADER_CLASS_LABEL="Header Class" -COM_MODULES_FIELD_HEADER_CLASS_DESC="The CSS class for module header/title." COM_MODULES_FIELD_MODULE_STYLE_LABEL="Module Style" -COM_MODULES_FIELD_MODULE_STYLE_DESC="Use this option to override the template style for its position." COM_MODULES_FIELDSET_RULES="Permissions" COM_MODULES_FILTER_SEARCH_DESC="Filter by position name." COM_MODULES_GENERAL_FIELDSET_DESC="Configure module edit interface settings." @@ -88,9 +65,6 @@ COM_MODULES_HTML_PUBLISH_ENABLED="Publish module::Extension enabled" COM_MODULES_HTML_UNPUBLISH_DISABLED="Unpublish module::Extension disabled" COM_MODULES_HTML_UNPUBLISH_ENABLED="Unpublish module::Extension enabled" COM_MODULES_MANAGER_MODULE="Modules: %s" -COM_MODULES_MANAGER_MODULE_ADD="Modules: Add New Module" -COM_MODULES_MANAGER_MODULE_EDIT="Modules: Edit Module" -COM_MODULES_MANAGER_MODULES="Modules" COM_MODULES_MANAGER_MODULES_ADMIN="Modules (Administrator)" COM_MODULES_MANAGER_MODULES_SITE="Modules (Site)" COM_MODULES_MENU_ASSIGNMENT="Menu Assignment" @@ -106,10 +80,9 @@ COM_MODULES_MODULES="Modules" COM_MODULES_MODULES_FILTER_SEARCH_DESC="Search in module title and note. Prefix with ID: to search for a module ID." COM_MODULES_MODULES_FILTER_SEARCH_LABEL="Search Modules" COM_MODULES_MSG_MANAGE_NO_MODULES="There are no modules matching your query" -COM_MODULES_MSG_MANAGE_EXTENSION_DISABLED="This module is disabled. Use Extensions => Manage to enable it." +COM_MODULES_MSG_MANAGE_EXTENSION_DISABLED="The '%s' module is disabled. Use Extensions => Manage to enable it." COM_MODULES_N_ITEMS_ARCHIVED="%d modules archived." COM_MODULES_N_ITEMS_ARCHIVED_1="%d module archived." -COM_MODULES_N_ITEMS_CHECKED_IN_0="No module checked in." COM_MODULES_N_ITEMS_CHECKED_IN_1="%d module checked in." COM_MODULES_N_ITEMS_CHECKED_IN_MORE="%d modules checked in." COM_MODULES_N_ITEMS_DELETED="%d modules deleted." @@ -135,8 +108,6 @@ COM_MODULES_OPTION_POSITION_USER_DEFINED="User" COM_MODULES_OPTION_SELECT_CLIENT="- Select Type -" COM_MODULES_OPTION_SELECT_MENU_ITEM="- Select Menu Item -" COM_MODULES_OPTION_SELECT_MODULE="- Select Type -" -; Deprecated 4.0 -COM_MODULES_OPTION_SELECT_PAGE="- Select Page -" COM_MODULES_OPTION_SELECT_POSITION="- Select Position -" COM_MODULES_OPTION_SELECT_TYPE="- Select type -" COM_MODULES_POSITION_ANALYTICS="Analytics" @@ -201,4 +172,4 @@ COM_MODULES_DESELECT="Deselect" COM_MODULES_EXPAND="Expand" COM_MODULES_COLLAPSE="Collapse" COM_MODULES_SUBITEMS="Sub-items:" -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_modules.sys.ini b/administrator/language/en-GB/en-GB.com_modules.sys.ini index 75cb85d692ca0..00427b53a2670 100644 --- a/administrator/language/en-GB/en-GB.com_modules.sys.ini +++ b/administrator/language/en-GB/en-GB.com_modules.sys.ini @@ -5,7 +5,6 @@ COM_MODULES="Modules" COM_MODULES_ACTION_EDITFRONTEND="Frontend Editing" -COM_MODULES_ACTION_EDITFRONTEND_COMPONENT_DESC="Allows users in the group to edit in Frontend." COM_MODULES_GENERAL="General" COM_MODULES_MODULES_VIEW_DEFAULT_DESC="Shows a list of modules to manage" COM_MODULES_MODULES_VIEW_DEFAULT_TITLE="Module Manager" diff --git a/administrator/language/en-GB/en-GB.com_newsfeeds.ini b/administrator/language/en-GB/en-GB.com_newsfeeds.ini index 7e950d96404d7..6c8db64fa7c06 100644 --- a/administrator/language/en-GB/en-GB.com_newsfeeds.ini +++ b/administrator/language/en-GB/en-GB.com_newsfeeds.ini @@ -4,8 +4,6 @@ ; Note : All ini files need to be saved as UTF-8 COM_NEWSFEEDS="News Feeds" -; COM_NEWSFEEDS_BATCH_MENU_LABEL is deprecated, use JLIB_HTML_BATCH_MENU_LABEL instead. -COM_NEWSFEEDS_BATCH_MENU_LABEL="To Move or Copy your selection please select a Category." COM_NEWSFEEDS_BATCH_OPTIONS="Batch process the selected news feeds" COM_NEWSFEEDS_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved news feeds. Otherwise, all actions are applied to the selected news feeds." COM_NEWSFEEDS_CACHE_TIME_HEADING="Cache Time" @@ -13,99 +11,54 @@ COM_NEWSFEEDS_CACHE_TIME_HEADING_ASC="Cache Time ascending" COM_NEWSFEEDS_CACHE_TIME_HEADING_DESC="Cache Time descending" COM_NEWSFEEDS_CATEGORIES_DESC="These settings apply for News Feeds Categories Options unless they are changed for a specific menu item." COM_NEWSFEEDS_CHANGE_FEED="Select or Change News Feed" -; COM_NEWSFEEDS_CHANGE_FEED_BUTTON is deprecated, use COM_NEWSFEEDS_CHANGE_FEED instead; -COM_NEWSFEEDS_CHANGE_FEED_BUTTON="Select Feed" COM_NEWSFEEDS_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Newsfeeds Component will integrate with other extensions." COM_NEWSFEEDS_CONFIGURATION="News Feed: Options" COM_NEWSFEEDS_EDIT_NEWSFEED="Edit News Feed" COM_NEWSFEEDS_ERROR_UNIQUE_ALIAS="Another News feed from this category has the same alias (remember it may be a trashed item)." COM_NEWSFEEDS_ERROR_ALL_LANGUAGE_ASSOCIATED="A news feed item set to All languages can't be associated. Associations have not been set." -COM_NEWSFEEDS_FEED_CATEGORY_OPTIONS_LABEL="Feeds Category Display Options" -COM_NEWSFEEDS_FIELD_CACHETIME_DESC="The number of minutes before the news feed cache is refreshed." COM_NEWSFEEDS_FIELD_CACHETIME_LABEL="Cache Time" -COM_NEWSFEEDS_FIELD_CATEGORIES_OPTIONS_LABEL="Feeds Categories Display Options" -COM_NEWSFEEDS_FIELD_CATEGORY_DESC="The category that this feed is assigned to." -COM_NEWSFEEDS_FIELD_CHARACTER_COUNT_DESC="Number of characters to display per feed. 0 will show all the text." +COM_NEWSFEEDS_FIELD_CHARACTER_COUNT_DESC="0 will show all the text." COM_NEWSFEEDS_FIELD_CHARACTER_COUNT_LABEL="Characters Count" -COM_NEWSFEEDS_FIELD_CHARACTERS_COUNT_DESC="Number of characters to include in the feed. 0 will show all the text." +COM_NEWSFEEDS_FIELD_CHARACTERS_COUNT_DESC="0 will show all the text." COM_NEWSFEEDS_FIELD_CHARACTERS_COUNT_LABEL="Characters Count" COM_NEWSFEEDS_FIELD_CONFIG_CATEGORY_SETTINGS_DESC="These settings apply for News Feeds Category Options unless they are changed for a specific menu item." COM_NEWSFEEDS_FIELD_CONFIG_LIST_SETTINGS_DESC="These settings apply for List Layout Options unless they are changed for a specific menu item." COM_NEWSFEEDS_FIELD_CONFIG_NEWSFEED_SETTINGS_DESC="These settings apply for single news feeds unless they are changed for a specific menu item or news feed." COM_NEWSFEEDS_FIELD_CONFIG_NEWSFEED_SETTINGS_LABEL="News Feed" -COM_NEWSFEEDS_FIELD_DESCRIPTION_DESC="Enter a description for the feed." -COM_NEWSFEEDS_FIELD_FEED_DISPLAY_ORDER_DESC="The order used to display the feed." COM_NEWSFEEDS_FIELD_FEED_DISPLAY_ORDER_LABEL="Feed Display Order" -COM_NEWSFEEDS_FIELD_FEED_OPTIONS_DESC="Feeds display options." -COM_NEWSFEEDS_FIELD_FEED_OPTIONS_LABEL="Feeds Display Options" -COM_NEWSFEEDS_FIELD_FIRST_DESC="Select or upload the image to be displayed." COM_NEWSFEEDS_FIELD_FIRST_LABEL="First Image" -COM_NEWSFEEDS_FIELD_IMAGE_ALT_DESC="Alternative text used for visitors without access to images. Replaced with caption text if it is present." COM_NEWSFEEDS_FIELD_IMAGE_ALT_LABEL="Alt Text" -COM_NEWSFEEDS_FIELD_IMAGE_CAPTION_DESC="Caption attached to the image." COM_NEWSFEEDS_FIELD_IMAGE_CAPTION_LABEL="Caption" -COM_NEWSFEEDS_FIELD_LANGUAGE_DESC="Assign a language to this news feed." -COM_NEWSFEEDS_FIELD_LINK_DESC="Link to the news feed. IDN (International) Links are converted to punycode when they are saved." COM_NEWSFEEDS_FIELD_LINK_LABEL="Link" -COM_NEWSFEEDS_FIELD_MODIFIED_BY_DESC="Name of the user who modified this news feed." -COM_NEWSFEEDS_FIELD_MODIFIED_DESC="The date and time the news feed was last modified." -COM_NEWSFEEDS_FIELD_NUM_ARTICLES_COLUMN_DESC="Show or hide the Number of Articles in each Feed (You can set this value in each News feed)." COM_NEWSFEEDS_FIELD_NUM_ARTICLES_COLUMN_LABEL="# Articles" -COM_NEWSFEEDS_FIELD_NUM_ARTICLES_DESC="Number of articles from the feed to display." COM_NEWSFEEDS_FIELD_NUM_ARTICLES_LABEL="Number of Articles" -COM_NEWSFEEDS_FIELD_NUMBER_ITEMS_LIST_DESC="Default number of feeds to list on a page." -COM_NEWSFEEDS_FIELD_NUMBER_ITEMS_LIST_LABEL="# Feeds to List" -COM_NEWSFEEDS_FIELD_NUMFEEDS_DESC="Number of feeds to display." -COM_NEWSFEEDS_FIELD_NUMFEEDS_LABEL="Number of Feeds" -COM_NEWSFEEDS_FIELD_OPTIONS="Feed" -COM_NEWSFEEDS_FIELD_RTL_DESC="Select the language direction of the feed." COM_NEWSFEEDS_FIELD_RTL_LABEL="Language Direction" -COM_NEWSFEEDS_FIELD_SECOND_DESC="Select or upload the second image to be displayed." COM_NEWSFEEDS_FIELD_SECOND_LABEL="Second Image" -COM_NEWSFEEDS_FIELD_SELECT_CATEGORY_DESC="Choose a feed category to display." -COM_NEWSFEEDS_FIELD_SELECT_FEED_DESC="Select a feed to display." COM_NEWSFEEDS_FIELD_SELECT_FEED_LABEL="Feed" -COM_NEWSFEEDS_FIELD_SHOW_CAT_ITEMS_DESC="Show or hide the number of news feeds in category." COM_NEWSFEEDS_FIELD_SHOW_CAT_ITEMS_LABEL="# Feeds in Category" -COM_NEWSFEEDS_FIELD_SHOW_CAT_TAGS_DESC="Show the tags for a category." -COM_NEWSFEEDS_FIELD_SHOW_CAT_TAGS_LABEL="Show Tags" -COM_NEWSFEEDS_FIELD_SHOW_FEED_DESCRIPTION_DESC="Show or hide feed description." +COM_NEWSFEEDS_FIELD_SHOW_CAT_TAGS_LABEL="Tags" COM_NEWSFEEDS_FIELD_SHOW_FEED_DESCRIPTION_LABEL="Feed Description" -COM_NEWSFEEDS_FIELD_SHOW_FEED_IMAGE_DESC="Show or hide feed images." COM_NEWSFEEDS_FIELD_SHOW_FEED_IMAGE_LABEL="Feed Image" -COM_NEWSFEEDS_FIELD_SHOW_ITEM_DESCRIPTION_DESC="Show or hide feed content." COM_NEWSFEEDS_FIELD_SHOW_ITEM_DESCRIPTION_LABEL="Feed Content" -COM_NEWSFEEDS_FIELD_SHOW_LINKS_DESC="Show or hide feed links URL." COM_NEWSFEEDS_FIELD_SHOW_LINKS_LABEL="Feed Links" -COM_NEWSFEEDS_FIELD_SHOW_TAGS_DESC="Show the tags for a news feed." -COM_NEWSFEEDS_FIELD_SHOW_TAGS_LABEL="Show Tags" +COM_NEWSFEEDS_FIELD_SHOW_TAGS_LABEL="Tags" COM_NEWSFEEDS_FIELD_VALUE_LTR="Left to Right Direction" -COM_NEWSFEEDS_FIELD_VALUE_NONE="None" COM_NEWSFEEDS_FIELD_VALUE_RTL="Right to Left Direction" COM_NEWSFEEDS_FIELD_VALUE_SITE="Site Language Direction" COM_NEWSFEEDS_FIELD_VERSION_LABEL="Revision" -COM_NEWSFEEDS_FIELD_VERSION_DESC="A count of the number of times this news feed has been revised." -COM_NEWSFEEDS_FIELDSET_IMAGES="Images" COM_NEWSFEEDS_FIELDSET_MORE_OPTIONS_LABEL="Feed Display Options" COM_NEWSFEEDS_FILTER_SEARCH_DESC="Search in news feed title and alias. Prefix with ID: to search for a news feed ID." COM_NEWSFEEDS_FILTER_SEARCH_LABEL="Search News Feeds" -COM_NEWSFEEDS_FLOAT_DESC="Controls placement of the image." COM_NEWSFEEDS_FLOAT_FIRST_LABEL="First Image Float" COM_NEWSFEEDS_FLOAT_LABEL="Image Float" COM_NEWSFEEDS_FLOAT_SECOND_LABEL="Second Image Float" COM_NEWSFEEDS_HEADING_ASSOCIATION="Association" -COM_NEWSFEEDS_HITS_DESC="Number of hits for this news feed." -; The following 2 strings are deprecated and will be removed with 4.0. -COM_NEWSFEEDS_ITEM_ASSOCIATIONS_FIELDSET_LABEL="News Feed Item Association" -COM_NEWSFEEDS_ITEM_ASSOCIATIONS_FIELDSET_DESC="Multilingual only! This choice will only display if the Language Filter parameter 'Item Associations' is set to 'Yes'. Choose a news feed item for the target language. This association will let the Language Switcher module redirect to the associated news feed item in another language. If used, make sure to display the Language switcher module on the relevant pages. A news feed item set to language 'All' can't be associated." COM_NEWSFEEDS_LEFT="Left" -COM_NEWSFEEDS_MANAGER_NEWSFEED="News Feeds: New/Edit" COM_NEWSFEEDS_MANAGER_NEWSFEED_NEW="News Feeds: New" COM_NEWSFEEDS_MANAGER_NEWSFEED_EDIT="News Feeds: Edit" COM_NEWSFEEDS_MANAGER_NEWSFEEDS="News Feeds" COM_NEWSFEEDS_N_ITEMS_ARCHIVED="%d news feeds archived." COM_NEWSFEEDS_N_ITEMS_ARCHIVED_1="News feed archived." -COM_NEWSFEEDS_N_ITEMS_CHECKED_IN_0="No news feed checked in." COM_NEWSFEEDS_N_ITEMS_CHECKED_IN_1="News feed checked in." COM_NEWSFEEDS_N_ITEMS_CHECKED_IN_MORE="%d news feeds checked in." COM_NEWSFEEDS_N_ITEMS_DELETED="%d news feeds deleted." @@ -123,18 +76,15 @@ COM_NEWSFEEDS_NONE="None" COM_NEWSFEEDS_NUM_ARTICLES_HEADING="# Articles" COM_NEWSFEEDS_NUM_ARTICLES_HEADING_ASC="# Articles ascending" COM_NEWSFEEDS_NUM_ARTICLES_HEADING_DESC="# Articles descending" -COM_NEWSFEEDS_PUBLISH_ITEM="Publish News Feed" COM_NEWSFEEDS_RIGHT="Right" COM_NEWSFEEDS_SAVE_SUCCESS="News feed saved." COM_NEWSFEEDS_SEARCH_IN_TITLE="Search" COM_NEWSFEEDS_SELECT_A_FEED="Select a News Feed" COM_NEWSFEEDS_SELECT_FEED="Select feed" -COM_NEWSFEEDS_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no news feeds or subcategories." COM_NEWSFEEDS_SUBMENU_CATEGORIES="Categories" COM_NEWSFEEDS_SUBMENU_NEWSFEEDS="News Feeds" COM_NEWSFEEDS_TIP_ASSOCIATION="Associated news feeds" -COM_NEWSFEEDS_UNPUBLISH_ITEM="Unpublish News Feed" COM_NEWSFEEDS_WARNING_PROVIDE_VALID_NAME="Please provide a valid name." COM_NEWSFEEDS_XML_DESCRIPTION="This component manages RSS and Atom news feeds." JGLOBAL_NEWITEMSLAST_DESC="New news feeds default to the last position. The ordering can be changed after this news feed has been saved." -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_newsfeeds.sys.ini b/administrator/language/en-GB/en-GB.com_newsfeeds.sys.ini index 4f1afe095b3bd..181a23134ab31 100644 --- a/administrator/language/en-GB/en-GB.com_newsfeeds.sys.ini +++ b/administrator/language/en-GB/en-GB.com_newsfeeds.sys.ini @@ -8,8 +8,6 @@ COM_NEWSFEEDS_CATEGORIES="Categories" COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_DESC="Show all the news feed categories within a category." COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_OPTION="Default" COM_NEWSFEEDS_CATEGORIES_VIEW_DEFAULT_TITLE="List All News Feed Categories" -COM_NEWSFEEDS_CATEGORY_ADD_TITLE="News Feed: Add Category" -COM_NEWSFEEDS_CATEGORY_EDIT_TITLE="News Feed: Edit Category" COM_NEWSFEEDS_CATEGORY_VIEW_DEFAULT_DESC="Show all news feeds within a category." COM_NEWSFEEDS_CATEGORY_VIEW_DEFAULT_OPTION="Default" COM_NEWSFEEDS_CATEGORY_VIEW_DEFAULT_TITLE="List News Feeds in a Category" diff --git a/administrator/language/en-GB/en-GB.com_plugins.ini b/administrator/language/en-GB/en-GB.com_plugins.ini index d3935b27cee8b..ca014f137e24c 100644 --- a/administrator/language/en-GB/en-GB.com_plugins.ini +++ b/administrator/language/en-GB/en-GB.com_plugins.ini @@ -4,17 +4,11 @@ ; Note : All ini files need to be saved as UTF-8 COM_PLUGINS="Plugins" -COM_PLUGINS_ADVANCED_FIELDSET_LABEL="Advanced" -COM_PLUGINS_BASIC_FIELDSET_LABEL="Basic" COM_PLUGINS_CONFIGURATION="Plugin: Options" COM_PLUGINS_ELEMENT_HEADING="Element" COM_PLUGINS_ERROR_FILE_NOT_FOUND="The file %s could not be found." -COM_PLUGINS_FIELD_ELEMENT_DESC="Plugin main file name." COM_PLUGINS_FIELD_ELEMENT_LABEL="Plugin File" -COM_PLUGINS_FIELD_ENABLED_DESC="The enabled status of this plugin." -COM_PLUGINS_FIELD_FOLDER_DESC="Category/folder of plugins this plugin belongs to." COM_PLUGINS_FIELD_FOLDER_LABEL="Plugin Type" -COM_PLUGINS_FIELD_NAME_DESC="The name of the plugin as defined in its xml." COM_PLUGINS_FIELD_NAME_LABEL="Plugin Name" COM_PLUGINS_FILTER_SEARCH_LABEL="Search Plugins" COM_PLUGINS_FOLDER_HEADING="Type" @@ -25,7 +19,6 @@ COM_PLUGINS_HEADING_FOLDER_DESC="Type descending" COM_PLUGINS_MANAGER_PLUGIN="Plugins: %s" COM_PLUGINS_MANAGER_PLUGINS="Plugins" COM_PLUGINS_MSG_MANAGE_NO_PLUGINS="There are no plugins installed matching your query." -COM_PLUGINS_N_ITEMS_CHECKED_IN_0="No plugin checked in." COM_PLUGINS_N_ITEMS_CHECKED_IN_1="%d plugin checked in." COM_PLUGINS_N_ITEMS_CHECKED_IN_MORE="%d plugins checked in." COM_PLUGINS_N_ITEMS_PUBLISHED="%d plugins enabled." @@ -36,11 +29,10 @@ COM_PLUGINS_NAME_HEADING="Plugin Name" COM_PLUGINS_NO_ITEM_SELECTED="No plugins selected." COM_PLUGINS_OPTION_FOLDER="- Select Type -" COM_PLUGINS_PLUGIN="Plugin" -COM_PLUGINS_PLUGINS="Plugins" COM_PLUGINS_SAVE_SUCCESS="Plugin saved." COM_PLUGINS_SEARCH_IN_TITLE="Search in plugin name. Prefix with ID: to search for a plugin ID." COM_PLUGINS_XML_DESCRIPTION="This component manages Joomla plugins." COM_PLUGINS_XML_ERR="Plugins XML data not available." JLIB_HTML_PUBLISH_ITEM="Enable plugin" JLIB_HTML_UNPUBLISH_ITEM="Disable plugin" -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_postinstall.ini b/administrator/language/en-GB/en-GB.com_postinstall.ini index 567782e093ac8..7a35ad9e23a0e 100644 --- a/administrator/language/en-GB/en-GB.com_postinstall.ini +++ b/administrator/language/en-GB/en-GB.com_postinstall.ini @@ -11,7 +11,7 @@ COM_POSTINSTALL_HIDE_ALL_MESSAGES="Hide all messages" COM_POSTINSTALL_LBL_MESSAGES="Post-installation and Upgrade Messages" COM_POSTINSTALL_LBL_NOMESSAGES_DESC="You have read all the messages." COM_POSTINSTALL_LBL_NOMESSAGES_TITLE="No Messages" -COM_POSTINSTALL_LBL_RELEASENEWS="Release news from the Joomla! Project" +COM_POSTINSTALL_LBL_RELEASENEWS="Release news from the Joomla! Project" COM_POSTINSTALL_LBL_SINCEVERSION="Since version %s" COM_POSTINSTALL_MESSAGES_FOR="Showing messages for" COM_POSTINSTALL_MESSAGES_TITLE="Post-installation Messages for %s" diff --git a/administrator/language/en-GB/en-GB.com_redirect.ini b/administrator/language/en-GB/en-GB.com_redirect.ini index 57e55225b2b3e..a13ff65bf6fd2 100644 --- a/administrator/language/en-GB/en-GB.com_redirect.ini +++ b/administrator/language/en-GB/en-GB.com_redirect.ini @@ -14,8 +14,6 @@ COM_REDIRECT_CLEAR_FAIL="Failed to delete disabled links." COM_REDIRECT_CLEAR_SUCCESS="All disabled links have been deleted." COM_REDIRECT_COLLECT_MODAL_URLS_DISABLED="%1$s The 'Collect URLs' option in the %2$s is disabled. Error page URLs will not be collected by this component." COM_REDIRECT_COLLECT_URLS_ENABLED="%1$s The option 'Collect URLs' is enabled." -; The following string is deprecated and will be removed with 4.0. -COM_REDIRECT_COLLECT_URLS_DISABLED="The 'Collect URLs' option in the Redirect System Plugin is disabled. Error page URLs will not be collected by this component." COM_REDIRECT_CONFIGURATION="Redirect: Options" COM_REDIRECT_DISABLE_LINK="Disable Link" COM_REDIRECT_EDIT_LINK="Edit Link #%d" @@ -27,10 +25,7 @@ COM_REDIRECT_ERROR_DUPLICATE_URLS="The source and destination URLs can't be the COM_REDIRECT_ERROR_SOURCE_URL_REQUIRED="The redirect must have a source URL." COM_REDIRECT_FILTER_SEARCH_DESC="Search in expired URL, new URL, referring page and comment. Prefix with ID: to search for a link ID." COM_REDIRECT_FILTER_SEARCH_LABEL="Search Links" -COM_REDIRECT_FILTER_FILTER_HTTP_HEADER_LABEL="HTTP Status Code" -COM_REDIRECT_FILTER_FILTER_HTTP_HEADER_DESC="Filter by the redirect HTTP Status Code." COM_REDIRECT_FILTER_SELECT_OPTION_HTTP_HEADER="- Select HTTP Status Code -" -COM_REDIRECT_FIELD_COMMENT_DESC="Sometimes it is helpful to describe the URLs for redirect management later on." COM_REDIRECT_FIELD_COMMENT_LABEL="Comment" COM_REDIRECT_FIELD_CREATED_DATE_LABEL="Created Date" COM_REDIRECT_FIELD_NEW_URL_DESC="Enter the URL to be redirected to." @@ -60,13 +55,10 @@ COM_REDIRECT_HEADING_REFERRER_DESC="Referring Page descending" COM_REDIRECT_HEADING_STATUS_CODE="Status Code" COM_REDIRECT_HEADING_STATUS_CODE_ASC="Status Code ascending" COM_REDIRECT_HEADING_STATUS_CODE_DESC="Status Code descending" -COM_REDIRECT_HEADING_UPDATE_LINKS="Update selected links to the following new URL." -COM_REDIRECT_MANAGER_LINK="Redirects: New/Edit" COM_REDIRECT_MANAGER_LINK_EDIT="Redirects: Edit" COM_REDIRECT_MANAGER_LINK_NEW="Redirects: New" COM_REDIRECT_MANAGER_LINKS="Redirects: Links" COM_REDIRECT_MODE_LABEL="Activate Advanced Mode" -COM_REDIRECT_MODE_DESC="Enable more advanced functionality for the component. Only use this if you know what you're doing." COM_REDIRECT_N_ITEMS_ARCHIVED="%d links archived." COM_REDIRECT_N_ITEMS_ARCHIVED_1="Link archived." COM_REDIRECT_N_ITEMS_DELETED="%d links deleted." @@ -84,8 +76,6 @@ COM_REDIRECT_N_LINKS_UPDATED_1="1 link has been updated." COM_REDIRECT_NEW_LINK="New Link" COM_REDIRECT_NO_ITEM_ADDED="No links added." COM_REDIRECT_NO_ITEM_SELECTED="No links selected." -; The following string is deprecated and will be removed with 4.0. -COM_REDIRECT_PLUGIN_DISABLED="The Redirect System Plugin is disabled. It needs to be enabled for this component to work." COM_REDIRECT_PLUGIN_ENABLED="The Redirect Plugin is enabled." COM_REDIRECT_PLUGIN_MODAL_DISABLED="The %s is disabled. It needs to be enabled for this component to work." COM_REDIRECT_REDIRECTED_ON="Redirected on: %s." @@ -94,4 +84,4 @@ COM_REDIRECT_SEARCH_LINKS="Search in link fields." COM_REDIRECT_SYSTEM_PLUGIN="Redirect System Plugin" COM_REDIRECT_TOOLBAR_PURGE="Purge Disabled" COM_REDIRECT_XML_DESCRIPTION="This component implements link redirection." -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_search.ini b/administrator/language/en-GB/en-GB.com_search.ini index 132da5796ff09..f1eec1de08989 100644 --- a/administrator/language/en-GB/en-GB.com_search.ini +++ b/administrator/language/en-GB/en-GB.com_search.ini @@ -7,25 +7,17 @@ COM_SEARCH="Search" COM_SEARCH_ALL_WORDS="All Words" COM_SEARCH_ALPHABETICAL="Alphabetical" COM_SEARCH_ANY_WORDS="Any Words" -COM_SEARCH_CONFIG_FIELD_CREATED_DATE_DESC="Show created date." COM_SEARCH_CONFIG_FIELD_CREATED_DATE_LABEL="Created Date" -COM_SEARCH_CONFIG_GATHER_SEARCH_STATISTICS_DESC="Record the search phrases submitted by visitors." COM_SEARCH_CONFIG_GATHER_SEARCH_STATISTICS_LABEL="Gather Search Statistics" COM_SEARCH_CONFIG_FIELD_OPENSEARCH_NAME_LABEL="OpenSearch Name" -COM_SEARCH_CONFIG_FIELD_OPENSEARCH_NAME_DESC="Name displayed for this site as a search provider." COM_SEARCH_CONFIG_FIELD_OPENSEARCH_DESCRIPTON_LABEL="OpenSearch Description" -COM_SEARCH_CONFIG_FIELD_OPENSEARCH_DESCRIPTON_DESC="Description displayed for this site as a search provider." COM_SEARCH_CONFIGURATION="Search: Options" COM_SEARCH_EXACT_PHRASE="Exact phrase" -COM_SEARCH_FIELD_DESC="Word, words or phrase to search for." COM_SEARCH_FIELD_LABEL="Search Term (Optional)" -COM_SEARCH_FIELD_SEARCH_PHRASES_DESC="Show the search options." COM_SEARCH_FIELD_SEARCH_PHRASES_LABEL="Use Search Options" -COM_SEARCH_FIELD_SEARCH_AREAS_DESC="Show the search areas checkboxes." COM_SEARCH_FIELD_SEARCH_AREAS_LABEL="Use Search Areas" COM_SEARCH_FIELDSET_OPTIONAL_LABEL="Optional Search Term" COM_SEARCH_FIELDSET_SEARCH_OPTIONS_LABEL="Search" -COM_SEARCH_FOR_DESC="The type of search." COM_SEARCH_FOR_LABEL="Search For" COM_SEARCH_HEADING_PHRASE="Search Phrase" COM_SEARCH_HEADING_SEARCH_TERM_ASC="Search Phrase ascending" @@ -39,7 +31,6 @@ COM_SEARCH_MOST_POPULAR="Popularity" COM_SEARCH_NEWEST_FIRST="Newest First" COM_SEARCH_NO_RESULTS="Off" COM_SEARCH_OLDEST_FIRST="Oldest First" -COM_SEARCH_ORDERING_DESC="Defines what ordering results are listed in." COM_SEARCH_ORDERING_LABEL="Results Ordering" COM_SEARCH_SAVED_SEARCH_OPTIONS="Default Search Options" COM_SEARCH_SEARCH_IN_PHRASE="Search in phrases." diff --git a/administrator/language/en-GB/en-GB.com_tags.ini b/administrator/language/en-GB/en-GB.com_tags.ini index 4b75d816fb4a7..2c36979f998fc 100644 --- a/administrator/language/en-GB/en-GB.com_tags.ini +++ b/administrator/language/en-GB/en-GB.com_tags.ini @@ -5,9 +5,7 @@ COM_TAGS="Tags" COM_TAGS_ALL="All" -COM_TAGS_ALL_TAGS_DESCRIPTION_DESC="Description to display at the heading of tags list." COM_TAGS_ALL_TAGS_DESCRIPTION_LABEL="Heading Description" -COM_TAGS_ALL_TAGS_MEDIA_DESC="Select or upload the image to display in the heading of the tags list." COM_TAGS_ALL_TAGS_MEDIA_LABEL="Heading Image File" COM_TAGS_ANY="Any" COM_TAGS_BASE_ADD_TITLE="Tags: New" @@ -19,8 +17,6 @@ COM_TAGS_BATCH_OPTIONS="Batch process the selected tags" COM_TAGS_BATCH_TIP="Actions will apply to chosen Tags." COM_TAGS_COMPACT_COLUMNS_LABEL="Number of Columns" COM_TAGS_CONFIG_TAG_MIN_LENGTH_LABEL="Minimum Search Length" -COM_TAGS_CONFIG_TAG_MIN_LENGTH_DESC="This setting controls the minimum character length for the search and adding tags using the tags field Ajax mode." -COM_TAGS_CONFIG_ALL_TAGS_FIELD_LAYOUT_DESC="Choose a default layout for List of all tags." COM_TAGS_CONFIG_ALL_TAGS_FIELD_LAYOUT_LABEL="Default List All Tags Layout" COM_TAGS_CONFIG_ALL_TAGS_SETTINGS_DESC="These settings apply for a List of all Tags unless they are changed for a specific menu item." COM_TAGS_CONFIG_ALL_TAGS_SETTINGS_LABEL="List All Tags" @@ -34,7 +30,6 @@ COM_TAGS_CONFIG_SHARED_SETTINGS_DESC="These settings apply to all tag layouts un COM_TAGS_CONFIG_SHARED_SETTINGS_LABEL="Shared Layout" COM_TAGS_CONFIG_TAG_SETTINGS_DESC="These settings apply for a Tagged Items List or Compact List of Tagged Items unless they are changed for a specific menu item." COM_TAGS_CONFIG_TAG_SETTINGS_LABEL="Tagged Items" -COM_TAGS_CONFIG_TAGGED_ITEMS_FIELD_LAYOUT_DESC="Choose a default layout for tagged items. This layout will be used when a user selects a tag that doesn't have a menu item defined." COM_TAGS_CONFIG_TAGGED_ITEMS_FIELD_LAYOUT_LABEL="Default Tagged Items Layout" COM_TAGS_CONFIGURATION="Tags: Options" COM_TAGS_COUNT_ARCHIVED_ITEMS="Archived items" @@ -42,47 +37,23 @@ COM_TAGS_COUNT_PUBLISHED_ITEMS="Published items" COM_TAGS_COUNT_TRASHED_ITEMS="Trashed items" COM_TAGS_COUNT_UNPUBLISHED_ITEMS="Unpublished items" COM_TAGS_DELETE_NOT_ALLOWED="Delete not allowed for tag %s." -COM_TAGS_DESCRIPTION_DESC="Enter an optional tag description in the text area." COM_TAGS_ERROR_UNIQUE_ALIAS="Another Tag has the same alias (remember it may be a trashed item)." COM_TAGS_EXCLUDE="Exclude" -COM_TAGS_FIELD_CONFIG_HITS_DESC="Displays the number of hits." -COM_TAGS_FIELD_CONFIG_TAGDESCRIPTION_DESC="Configure com_tags." -COM_TAGS_FIELD_CONFIG_TAGDESCRIPTION_LABEL="Tags" -COM_TAGS_FIELD_CONTENT_TYPE_DESC="Only tagged items of these types will be displayed." COM_TAGS_FIELD_CONTENT_TYPE_LABEL="Content types" -COM_TAGS_FIELD_CREATED_DATE_DESC="The date and time that the tag was created." -COM_TAGS_FIELD_FULL_DESC="Select or upload an image that will be displayed in the single tag view." COM_TAGS_FIELD_FULL_LABEL="Full Image" -COM_TAGS_FIELD_HITS_DESC="Number of hits for this tag." -COM_TAGS_FIELD_IMAGE_ALT_DESC="Alt text for the image." COM_TAGS_FIELD_IMAGE_ALT_LABEL="Alt" -COM_TAGS_FIELD_IMAGE_CAPTION_DESC="Caption for the image." COM_TAGS_FIELD_IMAGE_CAPTION_LABEL="Caption" -COM_TAGS_FIELD_IMAGE_DESC="Select or upload an image for this tag." COM_TAGS_FIELD_IMAGE_LABEL="Image" -COM_TAGS_FIELD_INTRO_DESC="Select or upload an image that will be displayed as part of a list." COM_TAGS_FIELD_INTRO_LABEL="Teaser Image" -COM_TAGS_FIELD_ITEM_BODY_DESC="Show the body for each item." -COM_TAGS_FIELD_LANGUAGE_DESC="Assign a language to this tag." -COM_TAGS_FIELD_LANGUAGE_FILTER_DESC="Optionally filter the list of tags based on language." COM_TAGS_FIELD_LANGUAGE_FILTER_LABEL="Language Filter" -COM_TAGS_FIELD_MODIFIED_DESC="The date and time that the tag was last modified." -COM_TAGS_FIELD_NOTE_DESC="An optional note to display in the tag list." COM_TAGS_FIELD_NOTE_LABEL="Note" -COM_TAGS_FIELD_NUMBER_ITEMS_LIST_DESC="Default number of tagged items to list on a page." COM_TAGS_FIELD_NUMBER_ITEMS_LIST_LABEL="# Items to List" -COM_TAGS_FIELD_PARENT_DESC="Select a parent tag." COM_TAGS_FIELD_PARENT_LABEL="Parent" -COM_TAGS_FIELD_PARENT_TAG_DESC="If set only tags that are direct children of the selected tag will be displayed." COM_TAGS_FIELD_PARENT_TAG_LABEL="Parent Tag" -COM_TAGS_FIELD_SELECT_TAG_DESC="Select one or more tags." -COM_TAGS_FIELD_TAG_BODY_DESC="Show or hide the tag description." COM_TAGS_FIELD_TAG_BODY_LABEL="Description." COM_TAGS_FIELD_TAG_LABEL="Tag" COM_TAGS_FIELD_TAG_LINK_CLASS="CSS Class for tag link" -COM_TAGS_FIELD_TAG_LINK_CLASS_DESC="Add specific CSS classes for the tag link. If empty 'label label-info' will be added by the default tag layout." -COM_TAGS_FIELD_TYPE_DESC="Only tags of the selected types will be displayed (optional)." -COM_TAGS_FIELD_TYPE_LABEL="Content Type" +COM_TAGS_FIELD_TYPE_LABEL="Select Content Type" COM_TAGS_FIELDSET_DETAILS="Tag Details" COM_TAGS_FIELDSET_OPTIONS="Options" COM_TAGS_FIELDSET_PUBLISHING="Publishing" @@ -90,27 +61,22 @@ COM_TAGS_FIELDSET_TAGGED_ITEMS="Tagged Items" COM_TAGS_FIELDSET_URLS_AND_IMAGES="Links and Images" COM_TAGS_FILTER_SEARCH_DESC="Search in tag title, alias and note. Prefix with ID: to search for a tag ID." COM_TAGS_FILTER_SEARCH_LABEL="Search Tags" -COM_TAGS_FLOAT_DESC="Float attribute for the image." COM_TAGS_FLOAT_LABEL="Float" COM_TAGS_HAS_SUBCATEGORY_ITEMS="%d items are assigned to this tag's subtags." COM_TAGS_HAS_SUBCATEGORY_ITEMS_1="%d item is assigned to one of this tag's subtags." COM_TAGS_INCLUDE="Include" -COM_TAGS_INCLUDE_CHILDREN_DESC="Include or exclude child tags from the result list for a tag." COM_TAGS_INCLUDE_CHILDREN_LABEL="Child Tags" COM_TAGS_ITEM_OPTIONS="Item Options" COM_TAGS_ITEMS_SEARCH_FILTER="Search" COM_TAGS_LEFT="Left" COM_TAGS_LIST_ALL_SELECTION_OPTIONS="Selection Options" -COM_TAGS_LIST_MAX_CHARACTERS_DESC="The maximum number of characters to display from the description in each tag." COM_TAGS_LIST_MAX_CHARACTERS_LABEL="Maximum Characters" -COM_TAGS_LIST_MAX_DESC="The maximum number of results to return." COM_TAGS_LIST_MAX_LABEL="Maximum Items" COM_TAGS_LIST_SELECTION_OPTIONS="Item Selection Options" COM_TAGS_MANAGER_TAGS="Tags" COM_TAGS_MATCH_COUNT="Number of matching tags" COM_TAGS_N_ITEMS_ARCHIVED="%d tags archived." COM_TAGS_N_ITEMS_ARCHIVED_1="%d tag archived." -COM_TAGS_N_ITEMS_CHECKED_IN_0="No tag checked in." COM_TAGS_N_ITEMS_CHECKED_IN_1="%d tag checked in." COM_TAGS_N_ITEMS_CHECKED_IN_MORE="%d tags checked in." COM_TAGS_N_ITEMS_DELETED="%d tags deleted." @@ -124,8 +90,6 @@ COM_TAGS_N_ITEMS_TRASHED_1="%d tag trashed." COM_TAGS_N_ITEMS_UNPUBLISHED="%d tags unpublished." COM_TAGS_N_ITEMS_UNPUBLISHED_1="%d tag unpublished." COM_TAGS_NONE="None" -COM_TAGS_NUMBER_COLUMNS_DESC="Number of columns to arrange the tags in. Note that this may not be the number displayed if 12 does not divide evenly into it because display is based on a 12 column grid." -COM_TAGS_NUMBER_TAG_ITEMS_DESC="Shows the number of items with a given tag." COM_TAGS_NUMBER_TAG_ITEMS_LABEL="Show Number of Items" COM_TAGS_OPTIONS="Tag Options" COM_TAGS_PAGINATION_OPTIONS="Pagination Options" @@ -133,29 +97,17 @@ COM_TAGS_REBUILD_FAILURE="Failed rebuilding Tags tree data." COM_TAGS_REBUILD_SUCCESS="Tags tree data rebuilt." COM_TAGS_RIGHT="Right" COM_TAGS_SAVE_SUCCESS="Tag saved." -COM_TAGS_SEARCH_TYPE_DESC="All will return items that have all of the tags. Any will return items that have at least one of the tags." COM_TAGS_SEARCH_TYPE_LABEL="Match Type" COM_TAGS_SELECT_TAGTYPE="- Select Tag Type -" -COM_TAGS_SHOW_ALL_TAGS_DESCRIPTION_DESC="Optional description to show at the top of the all tags list." -COM_TAGS_SHOW_ALL_TAGS_DESCRIPTION_LABEL="Heading Description" -COM_TAGS_SHOW_ALL_TAGS_IMAGE_DESC="Shows an image at the heading of the tags list." COM_TAGS_SHOW_ALL_TAGS_IMAGE_LABEL="Show Heading Image" -COM_TAGS_SHOW_EMPTY_TAG_DESC="Show empty tags." -COM_TAGS_SHOW_ITEM_BODY_DESC="Show or hide the body text for the tagged items." COM_TAGS_SHOW_ITEM_BODY_LABEL="Item Body" -COM_TAGS_SHOW_ITEM_DESCRIPTION_DESC="Show or hide the description for each tag listed." COM_TAGS_SHOW_ITEM_DESCRIPTION_LABEL="Tag Descriptions" -COM_TAGS_SHOW_ITEM_IMAGE_DESC="Shows the first image for each item in the list." COM_TAGS_SHOW_ITEM_IMAGE_LABEL="Item Images" -COM_TAGS_SHOW_TAG_BODY_DESC="For a layout with one tag, show the tag description." COM_TAGS_SHOW_TAG_BODY_LABEL="Show Tag Description" -COM_TAGS_SHOW_TAG_DESCRIPTION_DESC="Show or hide the description for the tag (only used when a single tag is selected)." COM_TAGS_SHOW_TAG_DESCRIPTION_LABEL="Tag Description" -COM_TAGS_SHOW_TAG_IMAGE_DESC="For a layout with one tag, show the image for the tag." COM_TAGS_SHOW_TAG_IMAGE_LABEL="Tag Image" COM_TAGS_SHOW_TAG_LIST_DESCRIPTION_LABEL="Description" -COM_TAGS_SHOW_TAG_TITLE_DESC="For a layout with one tag, show the tag name." -COM_TAGS_SHOW_TAG_TITLE_LABEL="Show Tag Name" +COM_TAGS_SHOW_TAG_TITLE_LABEL="Tag Name" COM_TAGS_SUBSLIDER_DRILL_TAG_LIST_LABEL="Options for each item in the list." COM_TAGS_TAG_FIELD_MODE_AJAX="AJAX" COM_TAGS_TAG_FIELD_MODE_DESC="Ajax mode searches tags while typing and allows you on the fly tag creation. Nested tags show you a nested view with all the available tags." @@ -165,16 +117,10 @@ COM_TAGS_TAG_LIST_DESCRIPTION_DESC="Optional description to show at the top of t COM_TAGS_TAG_LIST_DESCRIPTION_LABEL="Layout Description" COM_TAGS_TAG_LIST_FIELD_ITEM_DESCRIPTION_LABEL="Item Body" COM_TAGS_TAG_LIST_ITEM_DESCRIPTION_DESC="Shows the body text for the individual items (depends on the source table)." -COM_TAGS_TAG_LIST_ITEM_HITS_DESC="Shows the number of hits for each individual item." -COM_TAGS_TAG_LIST_MEDIA_DESC="Select or upload the tag image (full image)." COM_TAGS_TAG_LIST_MEDIA_LABEL="Image" -COM_TAGS_TAG_LIST_SHOW_DATE_DESC="Show Date" -COM_TAGS_TAG_LIST_SHOW_DATE_LABEL="Show or hide a date column in the compact list layout. Select Hide to hide the date, or select which date you wish to show." -COM_TAGS_TAG_LIST_SHOW_HEADINGS_DESC="Show or hide the headings in the compact list layout." +COM_TAGS_TAG_LIST_SHOW_DATE_LABEL="Date" COM_TAGS_TAG_LIST_SHOW_HEADINGS_LABEL="Table Headings" -COM_TAGS_TAG_LIST_SHOW_ITEM_IMAGE_DESC="Shows the image for each item." COM_TAGS_TAG_LIST_SHOW_ITEM_IMAGE_LABEL="Item Image" -COM_TAGS_TAG_LIST_SHOW_ITEM_DESCRIPTION_DESC="Show or hide the description for each item in the list. The length may be limited using the Maximum Characters option." COM_TAGS_TAG_LIST_SHOW_ITEM_DESCRIPTION_LABEL="Item Description" COM_TAGS_TAG_VIEW_LIST_DESC="Displays a compact list of items with the selected tags." COM_TAGS_TAG_VIEW_LIST_OPTION="List view options" diff --git a/administrator/language/en-GB/en-GB.com_templates.ini b/administrator/language/en-GB/en-GB.com_templates.ini index 37c73f5e48a8b..8be1a8a198ff3 100644 --- a/administrator/language/en-GB/en-GB.com_templates.ini +++ b/administrator/language/en-GB/en-GB.com_templates.ini @@ -4,11 +4,9 @@ ; Note : All ini files need to be saved as UTF-8 COM_TEMPLATES="Templates" -COM_TEMPLATES_ADVANCED_FIELDSET_LABEL="Advanced" COM_TEMPLATES_ARE_YOU_SURE="Are you sure?" COM_TEMPLATES_ASSIGNED_1="Assigned to one menu item." COM_TEMPLATES_ASSIGNED_MORE="Assigned to %d menu items." -COM_TEMPLATES_BASIC_FIELDSET_LABEL="Options" COM_TEMPLATES_BUTTON_CLOSE_FILE="Close File" COM_TEMPLATES_BUTTON_COPY_TEMPLATE="Copy Template" COM_TEMPLATES_BUTTON_COPY_FILE="Copy File" @@ -31,18 +29,13 @@ COM_TEMPLATES_COMPILE_ERROR="An error occurred. Failed to compile." COM_TEMPLATES_COMPILE_LESS="You should compile %s to generate a CSS file." COM_TEMPLATES_COMPILE_SUCCESS="Successfully compiled LESS." COM_TEMPLATES_CONFIG_FIELDSET_DESC="Global configuration for templates." -COM_TEMPLATES_CONFIG_POSITIONS_DESC="Enable the preview of the module positions in the template by appending tp=1 to the web address. Also enables the Preview button in the list of templates." COM_TEMPLATES_CONFIG_POSITIONS_LABEL="Preview Module Positions" -COM_TEMPLATES_CONFIG_FONT_DESC="These file types will be available for font preview." COM_TEMPLATES_CONFIG_FONT_LABEL="Valid Font Formats" -COM_TEMPLATES_CONFIG_IMAGE_DESC="These file types will be available for cropping and resizing." COM_TEMPLATES_CONFIG_IMAGE_LABEL="Valid Image Formats" -COM_TEMPLATES_CONFIG_SOURCE_DESC="These file types will be available for editing." COM_TEMPLATES_CONFIG_SOURCE_LABEL="Valid Source Formats" COM_TEMPLATES_CONFIG_SUPPORTED_DESC="Be careful before changing the file types. Read the tool tips before editing." COM_TEMPLATES_CONFIG_SUPPORTED_LABEL="Supported File Formats" -COM_TEMPLATES_CONFIG_UPLOAD_DESC="The maximum upload size for files inside Template Manager." -COM_TEMPLATES_CONFIG_UPLOAD_LABEL="Upload Size (MB)" +COM_TEMPLATES_CONFIG_UPLOAD_LABEL="Max. Upload Size (MB)" COM_TEMPLATES_CONFIGURATION="Template: Options" COM_TEMPLATES_COPY_SUCCESS="New template called %s was installed." COM_TEMPLATES_CROP_AREA_ERROR="Crop area not selected." @@ -85,16 +78,10 @@ COM_TEMPLATES_ERROR_WARNFILENAME="Invalid file name. Please correct the name of COM_TEMPLATES_ERROR_WARNFILETOOLARGE="File bigger than 2 MB can't be uploaded." COM_TEMPLATES_ERROR_WARNFILETYPE="File format not supported." COM_TEMPLATES_ERROR_WARNIEXSS="Can't be uploaded. Has XSS." -COM_TEMPLATES_FIELD_CLIENT_DESC="Whether this template is used for the Frontend (0) or the Backend (1)." COM_TEMPLATES_FIELD_CLIENT_LABEL="Location" -COM_TEMPLATES_FIELD_HOME_ADMINISTRATOR_DESC="This template style is defined as the default." COM_TEMPLATES_FIELD_HOME_LABEL="Default" -COM_TEMPLATES_FIELD_HOME_SITE_DESC="If the multilingual functionality is not implemented, please limit your choice between No and All. This template style will be defined as the global default template style.
    If the System - Language Filter plugin is enabled and you use different template styles depending on your content languages please assign a language to this style." -COM_TEMPLATES_FIELD_SOURCE_DESC="Source code." COM_TEMPLATES_FIELD_SOURCE_LABEL="Source Code" -COM_TEMPLATES_FIELD_TEMPLATE_DESC="Template name." COM_TEMPLATES_FIELD_TEMPLATE_LABEL="Template" -COM_TEMPLATES_FIELD_TITLE_DESC="Style name." COM_TEMPLATES_FIELD_TITLE_LABEL="Style Name" COM_TEMPLATES_FILE_ARCHIVE_OPEN_FAIL="Failed to open the archive file." COM_TEMPLATES_FILE_ARCHIVE_EXISTS="Some files with the same name already exist." @@ -145,8 +132,6 @@ COM_TEMPLATES_HEADING_DEFAULT="Default" COM_TEMPLATES_HEADING_DEFAULT_ASC="Default ascending" COM_TEMPLATES_HEADING_DEFAULT_DESC="Default descending" COM_TEMPLATES_HEADING_IMAGE="Image" -COM_TEMPLATES_HEADING_LOCATION_ASC="Location ascending" -COM_TEMPLATES_HEADING_LOCATION_DESC="Location descending" COM_TEMPLATES_HEADING_PAGES="Pages" COM_TEMPLATES_HEADING_STYLE="Style" COM_TEMPLATES_HEADING_STYLE_ASC="Style ascending" @@ -159,9 +144,7 @@ COM_TEMPLATES_IMAGE_WIDTH="Width" COM_TEMPLATES_INVALID_FILE_NAME="Invalid file name. Please choose a file name with a-z, A-Z, 0-9, - and _." COM_TEMPLATES_INVALID_FILE_TYPE="File type not selected." COM_TEMPLATES_INVALID_FOLDER_NAME="Invalid folder name. Please choose a folder name with a-z, A-Z, 0-9, - and _." -COM_TEMPLATES_MANAGER="Templates" COM_TEMPLATES_MANAGER_ADD_STYLE="Templates: Add Style" -COM_TEMPLATES_MANAGER_EDIT_FILE="Templates: Edit File" COM_TEMPLATES_MANAGER_EDIT_STYLE="Templates: Edit Style" COM_TEMPLATES_MANAGE_FOLDERS="Manage Folders" COM_TEMPLATES_MANAGER_STYLES="Templates: Styles" @@ -185,11 +168,8 @@ COM_TEMPLATES_NEW_FILE_SELECT="Select a file type" COM_TEMPLATES_NEW_FILE_TYPE="File Type" COM_TEMPLATES_NO_TEMPLATE_SELECTED="No template selected." COM_TEMPLATES_OPTION_NONE=":: None ::" -; Deprecated 4.0 -COM_TEMPLATES_OPTION_SELECT_PAGE="- Select Page -" COM_TEMPLATES_OPTION_SELECT_MENU_ITEM="- Select Menu Item -" COM_TEMPLATES_OVERRIDE_CREATED="Override created in " -COM_TEMPLATES_OVERRIDE_EXISTS="Override already exists." COM_TEMPLATES_OVERRIDE_FAILED="Failed to create override." COM_TEMPLATES_OVERRIDE_SUCCESS="Successfully created the override." COM_TEMPLATES_OVERRIDES_COMPONENTS="Components" @@ -199,7 +179,6 @@ COM_TEMPLATES_PREVIEW="Preview" COM_TEMPLATES_RENAME_FILE="Rename file %s" COM_TEMPLATES_RESIZE_IMAGE="Resize Image" COM_TEMPLATES_SOURCE_CODE="Source" -COM_TEMPLATES_SITE_PREVIEW="Site Preview" COM_TEMPLATES_STYLE_CANNOT_DELETE_DEFAULT_STYLE="Can't delete default style." COM_TEMPLATES_STYLE_SAVE_SUCCESS="Style saved." COM_TEMPLATES_STYLES_FILTER_SEARCH_DESC="Search in style description." @@ -215,22 +194,12 @@ COM_TEMPLATES_SUCCESS_HOME_UNSET="Default style unset." COM_TEMPLATES_TAB_DESCRIPTION="Template Description" COM_TEMPLATES_TAB_EDITOR="Editor" COM_TEMPLATES_TAB_OVERRIDES="Create Overrides" -COM_TEMPLATES_TEMPLATE_ADD_CSS="Add new stylesheet" -COM_TEMPLATES_TEMPLATE_ADD_ERROR="Add custom error page template (optional)." COM_TEMPLATES_TEMPLATE_CLOSE="Close" COM_TEMPLATES_TEMPLATE_COPY="Copy Template" -COM_TEMPLATES_TEMPLATE_CSS="Stylesheets" COM_TEMPLATES_TEMPLATE_DESCRIPTION="Template description." COM_TEMPLATES_TEMPLATE_DETAILS="%s Details and Files" -COM_TEMPLATES_TEMPLATE_EDIT_CSS="Edit %s" -COM_TEMPLATES_TEMPLATE_EDIT_ERROR="Edit error page template" -COM_TEMPLATES_TEMPLATE_EDIT_MAIN="Edit main page template" -COM_TEMPLATES_TEMPLATE_EDIT_OFFLINEVIEW="Edit offline page template" -COM_TEMPLATES_TEMPLATE_EDIT_PRINTVIEW="Edit print view template" COM_TEMPLATES_TEMPLATE_FILENAME="Editing file "%s" in template "%s"." COM_TEMPLATES_TEMPLATE_FILES="Template Files" -COM_TEMPLATES_TEMPLATE_HTML="HTML files" -COM_TEMPLATES_TEMPLATE_MASTER_FILES="Template Master Files" COM_TEMPLATES_TEMPLATE_NEW_NAME_DESC="Enter the name of the new template. Please use letters, numbers and underscore only." COM_TEMPLATES_TEMPLATE_NEW_NAME_LABEL="New Template Name" COM_TEMPLATES_TEMPLATE_NO_PREVIEW="No preview available. You can enable preview in the options." @@ -243,4 +212,4 @@ COM_TEMPLATES_TOGGLE_FULL_SCREEN="Press Ctrl-Q to toggle Full Screen editing." COM_TEMPLATES_TOOLBAR_SET_HOME="Default" COM_TEMPLATES_WARNING_FORMAT_WILL_NOT_BE_VISIBLE="You have created a new file with the extension '%s'. This is supported but as you did not have that file extension in the list of supported formats this can't be displayed. Please double check the options for Templates and add the format if needed." COM_TEMPLATES_XML_DESCRIPTION="This component manages templates" -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_users.ini b/administrator/language/en-GB/en-GB.com_users.ini index 6866528469d38..562f512ff71dd 100644 --- a/administrator/language/en-GB/en-GB.com_users.ini +++ b/administrator/language/en-GB/en-GB.com_users.ini @@ -4,7 +4,6 @@ ; Note : All ini files need to be saved as UTF-8 COM_USERS="Users" -COM_USERS_ACTIONS_AVAILABLE="Actions Permitted" COM_USERS_ACTIVATED="Activated" COM_USERS_ADD_NOTE="Add a Note" COM_USERS_ASSIGNED_GROUPS="Assigned User Groups" @@ -15,42 +14,25 @@ COM_USERS_BATCH_OPTIONS="Batch process the selected users" COM_USERS_BATCH_SET="Set To Group" COM_USERS_CATEGORIES_TITLE="User Notes: Categories" COM_USERS_CATEGORY_HEADING="Category" -COM_USERS_CONFIG_FIELD_ALLOWREGISTRATION_DESC="If set to Yes, new Users are allowed to self-register." COM_USERS_CONFIG_FIELD_ALLOWREGISTRATION_LABEL="Allow User Registration" -COM_USERS_CONFIG_FIELD_CAPTCHA_DESC="Select the captcha plugin that will be used in the registration, password and username reminder forms. You may need to enter required information for your captcha plugin in the Plugin Manager.
    If 'Use Global' is selected, make sure a captcha plugin is selected in Global Configuration." COM_USERS_CONFIG_FIELD_CAPTCHA_LABEL="Captcha" -COM_USERS_CONFIG_FIELD_CHANGEUSERNAME_DESC="Allow users to change their Username when editing their profile." COM_USERS_CONFIG_FIELD_CHANGEUSERNAME_LABEL="Change Username" -COM_USERS_CONFIG_FIELD_FRONTEND_LANG_DESC="If 'Frontend User Parameters' is set to 'Show', users will be able to select their Frontend language preference when registering." COM_USERS_CONFIG_FIELD_FRONTEND_LANG_LABEL="Frontend Language" -COM_USERS_CONFIG_FIELD_FRONTEND_RESET_COUNT_DESC="The maximum number of password resets allowed within the time period. Zero indicates no limit." COM_USERS_CONFIG_FIELD_FRONTEND_RESET_COUNT_LABEL="Maximum Reset Count" -COM_USERS_CONFIG_FIELD_FRONTEND_RESET_TIME_DESC="The time period, in hours, for the reset counter." COM_USERS_CONFIG_FIELD_FRONTEND_RESET_TIME_LABEL="Reset Time" -COM_USERS_CONFIG_FIELD_FRONTEND_USERPARAMS_DESC="If set to Show, Users will be able to select their language, editor and Help Site preferences on their details screen when logged-in to the Frontend." COM_USERS_CONFIG_FIELD_FRONTEND_USERPARAMS_LABEL="Frontend User Parameters" -COM_USERS_CONFIG_FIELD_GUEST_USER_GROUP_DESC="The default Group that will be applied to Guest (not logged-in) Users." COM_USERS_CONFIG_FIELD_GUEST_USER_GROUP_LABEL="Guest User Group" -COM_USERS_CONFIG_FIELD_MAILBODY_SUFFIX_DESC="This is added after the mail text." COM_USERS_CONFIG_FIELD_MAILBODY_SUFFIX_LABEL="Mailbody Suffix" -COM_USERS_CONFIG_FIELD_MAILTOADMIN_DESC="If set to Yes then a notification mail will be sent to administrators if 'New User Account Activation' is set to 'None' or 'Self'." COM_USERS_CONFIG_FIELD_MAILTOADMIN_LABEL="Send Mail to Administrators" COM_USERS_CONFIG_FIELD_MINIMUM_INTEGERS="Minimum Integers" -COM_USERS_CONFIG_FIELD_MINIMUM_INTEGERS_DESC="Set the minimum number of integers that must be included in a password." +COM_USERS_CONFIG_FIELD_MINIMUM_LOWERCASE="Minimum Lower Case" COM_USERS_CONFIG_FIELD_MINIMUM_PASSWORD_LENGTH="Minimum Length" -COM_USERS_CONFIG_FIELD_MINIMUM_PASSWORD_LENGTH_DESC="Set the minimum length for a password." COM_USERS_CONFIG_FIELD_MINIMUM_SYMBOLS="Minimum Symbols" -COM_USERS_CONFIG_FIELD_MINIMUM_SYMBOLS_DESC="Set the minimum number of symbols (such as !@#$) required in a password." COM_USERS_CONFIG_FIELD_MINIMUM_UPPERCASE="Minimum Upper Case" -COM_USERS_CONFIG_FIELD_MINIMUM_UPPERCASE_DESC="Set the minimum number of upper case alphabetical characters required for a password." -COM_USERS_CONFIG_FIELD_NEW_USER_TYPE_DESC="The default group that will be applied to New Users Registering via the Frontend." COM_USERS_CONFIG_FIELD_NEW_USER_TYPE_LABEL="New User Registration Group" COM_USERS_CONFIG_FIELD_NOTES_HISTORY="User Notes History" COM_USERS_CONFIG_FIELD_SENDPASSWORD_LABEL="Send Password" -COM_USERS_CONFIG_FIELD_SENDPASSWORD_DESC="If set to Yes the user's first password will be emailed to the user as part of the registration mail." -COM_USERS_CONFIG_FIELD_SUBJECT_PREFIX_DESC="This is added in front of each mail subject." COM_USERS_CONFIG_FIELD_SUBJECT_PREFIX_LABEL="Subject Prefix" -COM_USERS_CONFIG_FIELD_USERACTIVATION_DESC="If set to None the user will be registered immediately. If set to Self the User will be emailed a link to activate their account before they can log in. If set to Administrator the user will be emailed a link to verify their email address and then all users set to receive system emails and who have the permission to create users will be notified to activate the user's account." COM_USERS_CONFIG_FIELD_USERACTIVATION_LABEL="New User Account Activation" COM_USERS_CONFIG_FIELD_USERACTIVATION_OPTION_ADMINACTIVATION="Administrator" COM_USERS_CONFIG_FIELD_USERACTIVATION_OPTION_SELFACTIVATION="Self" @@ -67,13 +49,11 @@ COM_USERS_DEBUG_EXPLICIT_ALLOW="Allowed" COM_USERS_DEBUG_EXPLICIT_DENY="Forbidden" COM_USERS_DEBUG_GROUP="Advanced Permissions Report" COM_USERS_DEBUG_GROUPS_LABEL="Advanced Groups Permissions" -COM_USERS_DEBUG_GROUPS_DESC="Display the Advanced Groups Permissions Reports." COM_USERS_DEBUG_IMPLICIT_DENY="Not Allowed" COM_USERS_DEBUG_LABEL="Advanced" COM_USERS_DEBUG_LEGEND="Legend:" COM_USERS_DEBUG_USER="Advanced Permissions Report" COM_USERS_DEBUG_USERS_LABEL="Advanced Users Permissions" -COM_USERS_DEBUG_USERS_DESC="Display the Advanced Users Permissions Reports." COM_USERS_DELETE_ERROR_INVALID_GROUP="You can't delete user groups to which you belong." COM_USERS_DESIRED_PASSWORD="Enter your desired password." COM_USERS_EDIT_NOTE="Edit Note" @@ -91,42 +71,26 @@ COM_USERS_FIELD_CATEGORY_ID_LABEL="Category" COM_USERS_FIELD_ID_LABEL="ID" COM_USERS_FIELD_LOGIN_MENUITEM="Menu Item" COM_USERS_FIELD_LOGIN_REDIRECT_PLACEHOLDER="index.php?Itemid=999&lang=en-GB" -COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_DESC="'Internal URL' lets you manually enter any internal URL in the Redirect field. 'Menu Item' lets you directly select an existing menu item.
    For a multilingual site, it is recommended to use 'Menu Item'." +COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_DESC="'Internal URL' lets you manually enter any internal URL in the Redirect field. 'Menu Item' lets you directly select an existing menu item.
    For a multilingual site, it is recommended to use 'Menu Item'." COM_USERS_FIELD_LOGIN_REDIRECT_CHOICE_LABEL="Choose Login Redirect Type" COM_USERS_FIELD_LOGIN_REDIRECT_ERROR="Only one of the login redirect fields should have a value." -COM_USERS_FIELD_LOGIN_REDIRECTMENU_DESC="Select or create the page the user will be redirected to after a successful login. The default is to stay on the same page." COM_USERS_FIELD_LOGIN_REDIRECTMENU_LABEL="Menu Item Login Redirect" COM_USERS_FIELD_LOGIN_URL="Internal URL" COM_USERS_FIELD_LOGOUT_REDIRECT_CHOICE_LABEL="Choose Logout Redirect Type" COM_USERS_FIELD_LOGOUT_REDIRECT_ERROR="Only one of the logout redirect fields should have a value." -COM_USERS_FIELD_LOGOUT_REDIRECTMENU_DESC="Select or create the page the user will be redirected to after ending their current session by logging out. The default is to stay on the same page." COM_USERS_FIELD_LOGOUT_REDIRECTMENU_LABEL="Menu Item Logout Redirect" -COM_USERS_FIELD_NOTEBODY_DESC="Note" COM_USERS_FIELD_NOTEBODY_LABEL="Note" -COM_USERS_FIELD_REVIEW_TIME_DESC="Review Date is a manually entered date you can use as fits in your workflow. Examples would be to put in a date when you want to review a user or the last date you reviewed the user." COM_USERS_FIELD_REVIEW_TIME_LABEL="Review Date" -COM_USERS_FIELD_STATE_DESC="Set publication status." -COM_USERS_FIELD_SUBJECT_DESC="The subject line for the note." COM_USERS_FIELD_SUBJECT_LABEL="Subject" COM_USERS_FIELD_USER_ID_LABEL="User" COM_USERS_FIELDS_USER_FIELDS_TITLE="Users: Fields" COM_USERS_FIELDS_USER_FIELD_ADD_TITLE="Users: New Field" COM_USERS_FIELDS_USER_FIELD_EDIT_TITLE="Users: Edit Field" COM_USERS_FILTER_ACTIVE="- Select Active State -" -COM_USERS_FILTER_COMPONENT_LABEL="Component" -COM_USERS_FILTER_COMPONENT_DESC="Component to debug." -COM_USERS_FILTER_LABEL="Filter Users by: " -COM_USERS_FILTER_LEVEL_END_LABEL="Level End" -COM_USERS_FILTER_LEVEL_END_DESC="Asset end level." -COM_USERS_FILTER_LEVEL_START_LABEL="Level Start" -COM_USERS_FILTER_LEVEL_START_DESC="Asset start level." -COM_USERS_FILTER_NOTES="Show notes list for this user" +COM_USERS_FILTER_NOTES="Show notes list" COM_USERS_FILTER_STATE="- Select State -" -COM_USERS_FILTER_USER_GROUP="Filter User Group" COM_USERS_FILTER_USERGROUP="- Select Group -" -COM_USERS_GROUP_FIELD_PARENT_DESC="Choose a Parent for this Group." COM_USERS_GROUP_FIELD_PARENT_LABEL="Group Parent" -COM_USERS_GROUP_FIELD_TITLE_DESC="Enter a Title for the Group." COM_USERS_GROUP_FIELD_TITLE_LABEL="Group Title" COM_USERS_GROUP_SAVE_SUCCESS="Group saved." COM_USERS_GROUPS_CONFIRM_DELETE="Are you sure you wish to delete groups that have users?" @@ -182,7 +146,6 @@ COM_USERS_HEADING_USERNAME_ASC="Username ascending" COM_USERS_HEADING_USERNAME_DESC="Username descending" COM_USERS_HEADING_USERS_IN_GROUP="Users in group" COM_USERS_LEVEL_DETAILS="Level Details" -COM_USERS_LEVEL_FIELD_TITLE_DESC="Enter a Title for this Access level." COM_USERS_LEVEL_FIELD_TITLE_LABEL="Level Title" COM_USERS_LEVEL_HEADER_ERROR="User header access level error." COM_USERS_LEVEL_SAVE_SUCCESS="Access level saved." @@ -191,22 +154,14 @@ COM_USERS_LEVELS_N_ITEMS_DELETED_1="1 View Permission Level deleted." COM_USERS_MAIL_DETAILS="Details" COM_USERS_MAIL_EMAIL_SENT_TO_N_USERS="Email sent to %s users." COM_USERS_MAIL_EMAIL_SENT_TO_N_USERS_1="Email sent to one user." -COM_USERS_MAIL_FIELD_EMAIL_DISABLED_USERS_DESC="If checked, disabled users will be included when sending mail." COM_USERS_MAIL_FIELD_EMAIL_DISABLED_USERS_LABEL="Send to Disabled Users" -COM_USERS_MAIL_FIELD_GROUP_DESC="Choose a group to send the mail to." COM_USERS_MAIL_FIELD_GROUP_LABEL="Group:" -COM_USERS_MAIL_FIELD_MESSAGE_DESC="Enter a default message." COM_USERS_MAIL_FIELD_MESSAGE_LABEL="Message" -COM_USERS_MAIL_FIELD_RECURSE_DESC="If checked, the email will also be sent to users who are members of any child groups of the selected groups." COM_USERS_MAIL_FIELD_RECURSE_LABEL="Mail to Child User Groups" -COM_USERS_MAIL_FIELD_SEND_AS_BLIND_CARBON_COPY_DESC="Hide the recipient list and use the site email address for the To: field." COM_USERS_MAIL_FIELD_SEND_AS_BLIND_CARBON_COPY_LABEL="Recipients as BCC" -COM_USERS_MAIL_FIELD_SEND_IN_HTML_MODE_DESC="If checked, the email will be sent with HTML tags. If not checked, email will be sent in plain text." COM_USERS_MAIL_FIELD_SEND_IN_HTML_MODE_LABEL="Send in HTML Mode" -COM_USERS_MAIL_FIELD_SUBJECT_DESC="Enter the subject of the mail." COM_USERS_MAIL_FIELD_SUBJECT_LABEL="Subject" COM_USERS_MAIL_FIELD_VALUE_ALL_USERS_GROUPS="All Users Groups" -COM_USERS_MAIL_MESSAGE="Message" COM_USERS_MAIL_NO_USERS_COULD_BE_FOUND_IN_THIS_GROUP="No users could be found in this group." COM_USERS_MAIL_ONLY_YOU_COULD_BE_FOUND_IN_THIS_GROUP="You are the only user in this group." COM_USERS_MAIL_PLEASE_FILL_IN_THE_FORM_CORRECTLY="Please fill in the form correctly." @@ -304,45 +259,26 @@ COM_USERS_UNACTIVATED="Unactivated" COM_USERS_USER_ACCOUNT_DETAILS="Account Details" COM_USERS_USER_BATCH_FAILED="An error was encountered while performing the batch operation: %s." COM_USERS_USER_BATCH_SUCCESS="Batch operation completed." -COM_USERS_USER_FIELD_BACKEND_LANGUAGE_DESC="Select the Language for the Administrator Backend interface. This will only affect this User." COM_USERS_USER_FIELD_BACKEND_LANGUAGE_LABEL="Backend Language" -COM_USERS_USER_FIELD_BACKEND_TEMPLATE_DESC="Select the template style for the Administrator Backend interface. This will only affect this User." COM_USERS_USER_FIELD_BACKEND_TEMPLATE_LABEL="Backend Template Style" COM_USERS_USER_FIELD_BLOCK="Blocked" -COM_USERS_USER_FIELD_BLOCK_DESC="Enable or Block this user." COM_USERS_USER_FIELD_BLOCK_LABEL="User Status" -COM_USERS_USER_FIELD_EDITOR_DESC="Editor for this user." COM_USERS_USER_FIELD_EDITOR_LABEL="Editor" -COM_USERS_USER_FIELD_EMAIL_DESC="Enter an email address for the user." COM_USERS_USER_FIELD_ENABLE="Enabled" -COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_DESC="Select the Language for the Frontend interface. This will only affect this User." COM_USERS_USER_FIELD_FRONTEND_LANGUAGE_LABEL="Frontend Language" -COM_USERS_USER_FIELD_HELPSITE_DESC="Help site for this user." COM_USERS_USER_FIELD_HELPSITE_LABEL="Help Site" -COM_USERS_USER_FIELD_LASTRESET_DESC="Date and time of last password reset." COM_USERS_USER_FIELD_LASTRESET_LABEL="Last Reset Date" -COM_USERS_USER_FIELD_LASTVISIT_DESC="Last visit date." COM_USERS_USER_FIELD_LASTVISIT_LABEL="Last Visit Date" -COM_USERS_USER_FIELD_NAME_DESC="Enter the name of the user." COM_USERS_USER_FIELD_NAME_LABEL="Name" COM_USERS_USER_FIELD_PASSWORD1_MESSAGE="The passwords you entered do not match. Please enter your desired password in the password field and confirm your entry by entering it in the confirm password field." -COM_USERS_USER_FIELD_PASSWORD2_DESC="Confirm the user's password." COM_USERS_USER_FIELD_PASSWORD2_LABEL="Confirm Password" -COM_USERS_USER_FIELD_PASSWORD_DESC="Enter the password for the user." -COM_USERS_USER_FIELD_REGISTERDATE_DESC="Registration date." COM_USERS_USER_FIELD_REGISTERDATE_LABEL="Registration Date" -COM_USERS_USER_FIELD_REQUIRERESET_DESC="Setting this option to yes requires the user to reset their password the next time they log into the site." COM_USERS_USER_FIELD_REQUIRERESET_LABEL="Require Password Reset" -COM_USERS_USER_FIELD_RESETCOUNT_DESC="Number of password resets since last reset date." COM_USERS_USER_FIELD_RESETCOUNT_LABEL="Password Reset Count" -COM_USERS_USER_FIELD_SENDEMAIL_DESC="If set to yes, the user will receive system emails." COM_USERS_USER_FIELD_SENDEMAIL_LABEL="Receive System Emails" -COM_USERS_USER_FIELD_TIMEZONE_DESC="Time zone for this user." COM_USERS_USER_FIELD_TIMEZONE_LABEL="Time Zone" COM_USERS_USER_FIELD_TWOFACTOR_LABEL="Authentication Method" -COM_USERS_USER_FIELD_TWOFACTOR_DESC="Which two factor authentication method you want to activate on the user account." -COM_USERS_USER_FIELD_USERNAME_DESC="Enter the login name (Username) for the user." -COM_USERS_USER_FIELD_USERNAME_LABEL="Login Name" +COM_USERS_USER_FIELD_USERNAME_LABEL="Login Name (Username)" COM_USERS_USER_GROUPS_HAVING_ACCESS="User Groups Having Viewing Access" COM_USERS_USER_HEADING="User" COM_USERS_USER_OTEPS="One time emergency passwords" @@ -376,7 +312,7 @@ COM_USERS_VIEW_NEW_USER_TITLE="Users: New" COM_USERS_VIEW_NOTES_TITLE="User Notes" COM_USERS_VIEW_USERS_TITLE="Users" COM_USERS_XML_DESCRIPTION="Component for managing users" -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." +JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." ; Categories overrides COM_CATEGORIES_CATEGORY_ADD_TITLE="User Notes: New Category" COM_CATEGORIES_CATEGORY_EDIT_TITLE="User Notes: Edit Category" diff --git a/administrator/language/en-GB/en-GB.com_weblinks.ini b/administrator/language/en-GB/en-GB.com_weblinks.ini deleted file mode 100644 index d2c7ac37484e9..0000000000000 --- a/administrator/language/en-GB/en-GB.com_weblinks.ini +++ /dev/null @@ -1,127 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -COM_WEBLINKS="Web Links" -COM_WEBLINKS_ACCESS_HEADING="Access" -COM_WEBLINKS_BATCH_OPTIONS="Batch process the selected links" -COM_WEBLINKS_BATCH_TIP="If a category is selected for move/copy, any actions selected will be applied to the copied or moved links. Otherwise, all actions are applied to the selected links." -COM_WEBLINKS_CATEGORIES_DESC="These settings apply for Web Links Categories Options unless they are changed for a specific menu item." -COM_WEBLINKS_CATEGORY_DESC="These settings apply for Web Links Category Options unless they are changed for a specific menu item." -COM_WEBLINKS_COMPONENT_DESC="These settings apply for Web Links unless they are changed for a specific menu item or web link." -COM_WEBLINKS_COMPONENT_LABEL="Web Link" -COM_WEBLINKS_CONFIG_INTEGRATION_SETTINGS_DESC="These settings determine how the Web Links Component will integrate with other extensions." -COM_WEBLINKS_CONFIGURATION="Web Links Manager Options" -COM_WEBLINKS_EDIT_WEBLINK="Edit Web Link" -COM_WEBLINKS_ERR_TABLES_NAME="There is already a Web Link with that name in this category. Please try again." -COM_WEBLINKS_ERR_TABLES_PROVIDE_URL="Please provide a valid URL" -COM_WEBLINKS_ERR_TABLES_TITLE="Your web link must have a title." -COM_WEBLINKS_ERROR_UNIQUE_ALIAS="Another web link from this category has the same alias (remember it may be a trashed item)." -COM_WEBLINKS_FIELD_ALIAS_DESC="The alias is for internal use only. Leave this blank and Joomla will fill in a default value from the title. It has to be unique for each web link in the same category." -COM_WEBLINKS_FIELD_CATEGORY_DESC="Choose a category for this Web link." -COM_WEBLINKS_FIELD_CATEGORYCHOOSE_DESC="Please choose a Web Links category to display." -COM_WEBLINKS_FIELD_CAPTCHA_DESC="Select the captcha plugin that will be used in the web link submit form. You may need to enter required information for your captcha plugin in the Plugin Manager.
    If 'Use Default' is selected, make sure a captcha plugin is selected in Global Configuration." -COM_WEBLINKS_FIELD_CAPTCHA_LABEL="Allow Captcha on Web Link" -COM_WEBLINKS_FIELD_CONFIG_CAT_SHOWNUMBERS_DESC="Show or hide the number of Web Links in each Category." -COM_WEBLINKS_FIELD_CONFIG_CAT_SHOWNUMBERS_LABEL="# Web Links" -COM_WEBLINKS_FIELD_CONFIG_COUNTCLICKS_DESC="If set to yes, the number of times the link has been clicked will be recorded." -COM_WEBLINKS_FIELD_CONFIG_COUNTCLICKS_LABEL="Count Clicks" -COM_WEBLINKS_FIELD_CONFIG_DESCRIPTION_DESC="Show or hide the description below." -COM_WEBLINKS_FIELD_CONFIG_HITS_DESC="Show or hide hits." -COM_WEBLINKS_FIELD_CONFIG_ICON_DESC="If Icon is chosen above, select an icon to display with the Web Links. If none is selected, the default icon will be used." -COM_WEBLINKS_FIELD_CONFIG_ICON_LABEL="Select Icon" -COM_WEBLINKS_FIELD_CONFIG_LINKDESCRIPTION_DESC="Show or hide the links description." -COM_WEBLINKS_FIELD_CONFIG_LINKDESCRIPTION_LABEL="Links Description" -COM_WEBLINKS_FIELD_CONFIG_OTHERCATS_DESC="Show or hide other categories." -COM_WEBLINKS_FIELD_CONFIG_OTHERCATS_LABEL="Other Categories" -COM_WEBLINKS_FIELD_CONFIG_SHOWREPORT_DESC="Show or hide the Report Bad Link option." -COM_WEBLINKS_FIELD_CONFIG_SHOWREPORT_LABEL="Reports" -COM_WEBLINKS_FIELD_COUNTCLICKS_DESC="If set to yes, the number of times the link has been clicked will be recorded." -COM_WEBLINKS_FIELD_COUNTCLICKS_LABEL="Count Clicks" -COM_WEBLINKS_FIELD_DESCRIPTION_DESC="Enter a description for the web link." -COM_WEBLINKS_FIELD_DISPLAY_NUM_DESC="Default number of Web links to list on a page." -COM_WEBLINKS_FIELD_DISPLAY_NUM_LABEL="# of Web links to List" -COM_WEBLINKS_FIELD_FIRST_DESC="The image to be displayed." -COM_WEBLINKS_FIELD_FIRST_LABEL="First Image" - -COM_WEBLINKS_FIELD_HEIGHT_DESC="Height of the target popup or modal window. Defaults to 600x500 if one field is left empty." -COM_WEBLINKS_FIELD_HEIGHT_LABEL="Height" -COM_WEBLINKS_FIELD_ICON_DESC="Displays a text, an icon or nothing with the Web links. Default is 'Icon'." -COM_WEBLINKS_FIELD_ICON_LABEL="Text/Icon/Web Link Only" -COM_WEBLINKS_FIELD_ICON_OPTION_ICON="Icon" -COM_WEBLINKS_FIELD_ICON_OPTION_TEXT="Text" -COM_WEBLINKS_FIELD_ICON_OPTION_WEBLINK="Web Link Only" -COM_WEBLINKS_FIELD_IMAGE_ALT_DESC="Alternative text used for visitors without access to images. Replaced with caption text if it is present." -COM_WEBLINKS_FIELD_IMAGE_ALT_LABEL="Alt Text" -COM_WEBLINKS_FIELD_IMAGE_CAPTION_DESC="Caption attached to the image." -COM_WEBLINKS_FIELD_IMAGE_CAPTION_LABEL="Caption" - -COM_WEBLINKS_FIELD_LANGUAGE_DESC="Assign a language to this web link." -COM_WEBLINKS_FIELD_MODIFIED_DESC="The date and time the link was last modified." -COM_WEBLINKS_FIELD_SECOND_DESC="The second image to be displayed." -COM_WEBLINKS_FIELD_SECOND_LABEL="Second Image" -COM_WEBLINKS_FIELD_SELECT_CATEGORY_DESC="Select a web links category to display." -COM_WEBLINKS_FIELD_SELECT_CATEGORY_LABEL="Select a Category" -COM_WEBLINKS_FIELD_SHOW_CAT_TAGS_DESC="Show the tags for a category." -COM_WEBLINKS_FIELD_SHOW_CAT_TAGS_LABEL="Show Tags" -COM_WEBLINKS_FIELD_SHOW_TAGS_DESC="Show the tags for a web link." -COM_WEBLINKS_FIELD_SHOW_TAGS_LABEL="Show Tags" -COM_WEBLINKS_FIELD_STATE_DESC="Set publication status." -COM_WEBLINKS_FIELD_TARGET_DESC="Target browser window when the link is selected." -COM_WEBLINKS_FIELD_TARGET_LABEL="Target" -COM_WEBLINKS_FIELD_TITLE_DESC="Web Link must have a title." -COM_WEBLINKS_FIELD_URL_DESC="You must enter a URL. IDN (International) Links are converted to punycode when they are saved." -COM_WEBLINKS_FIELD_URL_LABEL="URL" -COM_WEBLINKS_FIELD_VALUE_REPORTED="Reported" -COM_WEBLINKS_FIELD_VERSION_DESC="A count of the number of times this web link has been revised." -COM_WEBLINKS_FIELD_VERSION_LABEL="Revision" -COM_WEBLINKS_FIELD_WIDTH_DESC="Width of the target popup or modal window. Defaults to 600x500 if one field is left empty." -COM_WEBLINKS_FIELD_WIDTH_LABEL="Width" -COM_WEBLINKS_FIELDSET_IMAGES="Images" -COM_WEBLINKS_FIELDSET_OPTIONS="Options" -COM_WEBLINKS_FILTER_CATEGORY="Filter Category" -COM_WEBLINKS_FILTER_SEARCH_DESC="Search in web link title and alias. Prefix with ID: to search for a web link ID." -COM_WEBLINKS_FILTER_SEARCH_LABEL="Search Web Links" -COM_WEBLINKS_FILTER_STATE="Filter State" -COM_WEBLINKS_FLOAT_DESC="Controls placement of the image." -COM_WEBLINKS_FLOAT_LABEL="Image Float" -COM_WEBLINKS_HITS_DESC="Number of hits for this web link." -COM_WEBLINKS_LEFT="Left" -COM_WEBLINKS_LIST_LAYOUT_DESC="These settings apply for Web Links List Layout Options unless they are changed for a specific menu item." -COM_WEBLINKS_MANAGER_WEBLINK="Web Links" -COM_WEBLINKS_MANAGER_WEBLINKS="Web Links" -COM_WEBLINKS_MANAGER_WEBLINK_EDIT="Web Link: Edit" -COM_WEBLINKS_MANAGER_WEBLINK_NEW="Web Link: New" -COM_WEBLINKS_N_ITEMS_ARCHIVED="%d web links archived." -COM_WEBLINKS_N_ITEMS_ARCHIVED_1="%d web link archived." -COM_WEBLINKS_N_ITEMS_CHECKED_IN_0="No web link checked in." -COM_WEBLINKS_N_ITEMS_CHECKED_IN_1="%d web link checked in." -COM_WEBLINKS_N_ITEMS_CHECKED_IN_MORE="%d web links checked in." -COM_WEBLINKS_N_ITEMS_DELETED="%d web links deleted." -COM_WEBLINKS_N_ITEMS_DELETED_1="%d web link deleted." -COM_WEBLINKS_N_ITEMS_PUBLISHED="%d web links published." -COM_WEBLINKS_N_ITEMS_PUBLISHED_1="%d web link published." -COM_WEBLINKS_N_ITEMS_TRASHED="%d web links trashed." -COM_WEBLINKS_N_ITEMS_TRASHED_1="%d web link trashed." -COM_WEBLINKS_N_ITEMS_UNPUBLISHED="%d web links unpublished." -COM_WEBLINKS_N_ITEMS_UNPUBLISHED_1="%d web link unpublished." -COM_WEBLINKS_NEW_WEBLINK="New Web Link" -COM_WEBLINKS_NONE="None" -COM_WEBLINKS_OPTION_FILTER_ACCESS="- Filter Access -" -COM_WEBLINKS_OPTION_FILTER_CATEGORY="- Filter Category -" -COM_WEBLINKS_OPTION_FILTER_PUBLISHED="- Filter State -" -COM_WEBLINKS_OPTIONS="Options" -COM_WEBLINKS_ORDER_HEADING="Order" -COM_WEBLINKS_RIGHT="Right" -COM_WEBLINKS_SAVE_SUCCESS="Web link saved" -COM_WEBLINKS_SEARCH_IN_TITLE="Search in title" -COM_WEBLINKS_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no Web links or subcategories." -COM_WEBLINKS_SUBMENU_CATEGORIES="Categories" -COM_WEBLINKS_SUBMENU_WEBLINKS="Web Links" -COM_WEBLINKS_XML_DESCRIPTION="Component for web links management" -JGLOBAL_NO_ITEM_SELECTED="No web links selected" -JGLOBAL_NEWITEMSLAST_DESC="New Web links default to the last position. Ordering can be changed after this Web link is saved." -JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE="You are not allowed to create new web links in this category." -JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT="You are not allowed to edit one or more of these web links." -JLIB_RULES_SETTING_NOTES="Changes apply to this component only.
    Inherited - a Global Configuration setting or higher level setting is applied.
    Denied always wins - whatever is set at the Global or higher level and applies to all child elements.
    Allowed will enable the action for this component unless overruled by a Global Configuration setting." diff --git a/administrator/language/en-GB/en-GB.com_weblinks.sys.ini b/administrator/language/en-GB/en-GB.com_weblinks.sys.ini deleted file mode 100644 index 12d92492da8d1..0000000000000 --- a/administrator/language/en-GB/en-GB.com_weblinks.sys.ini +++ /dev/null @@ -1,25 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -COM_WEBLINKS="Web Links" -COM_WEBLINKS_CATEGORIES="Categories" -COM_WEBLINKS_CATEGORIES_VIEW_DEFAULT_DESC="Show all the web link categories within a category." -COM_WEBLINKS_CATEGORIES_VIEW_DEFAULT_OPTION="Default" -COM_WEBLINKS_CATEGORIES_VIEW_DEFAULT_TITLE="List All Web Link Categories" -COM_WEBLINKS_CATEGORY_ADD_TITLE="Category Manager: Add A New Web Links Category" -COM_WEBLINKS_CATEGORY_EDIT_TITLE="Category Manager: Edit A Web Links Category" -COM_WEBLINKS_CATEGORY_VIEW_DEFAULT_DESC="Displays a list of Web Links for a category." -COM_WEBLINKS_CATEGORY_VIEW_DEFAULT_OPTION="Default" -COM_WEBLINKS_CATEGORY_VIEW_DEFAULT_TITLE="List Web Links in a Category" -COM_WEBLINKS_CONTENT_TYPE_WEBLINK="Web Link" -COM_WEBLINKS_CONTENT_TYPE_CATEGORY="Web Links Category" -COM_WEBLINKS_FORM_VIEW_DEFAULT_DESC="Display a form to submit a web link in the Frontend." -COM_WEBLINKS_FORM_VIEW_DEFAULT_OPTION="Default" -COM_WEBLINKS_FORM_VIEW_DEFAULT_TITLE="Submit a Web Link" -COM_WEBLINKS_LINKS="Links" -COM_WEBLINKS_TAGS_WEBLINK="Web Link" -COM_WEBLINKS_TAGS_CATEGORY="Web Link Category" -COM_WEBLINKS_XML_DESCRIPTION="Component for web links management." - diff --git a/administrator/language/en-GB/en-GB.com_workflow.ini b/administrator/language/en-GB/en-GB.com_workflow.ini new file mode 100644 index 0000000000000..411e1ff238c63 --- /dev/null +++ b/administrator/language/en-GB/en-GB.com_workflow.ini @@ -0,0 +1,101 @@ +; Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved. +; Joomla! Project +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +COM_CONTACT_FIELD_CATEGORY_LIST_DESC="Please choose a category from the list." +COM_WORKFLOW_ARE_YOU_SURE="Are you sure?" +COM_WORKFLOW_CONDITION_ASC="Condition ascending" +COM_WORKFLOW_AUTHOR="Author" +COM_WORKFLOW_BASIC_TAB="Basic" +COM_WORKFLOW_CONDITION="Condition of items in this stage: " +COM_WORKFLOW_CONDITION_DESC="Condition descending" +COM_WORKFLOW_CONDITION_DESC="Defines item behaviour." +COM_WORKFLOW_CONFIGURATION="Workflow: Options" +COM_WORKFLOW_COUNT_STAGES="Stages" +COM_WORKFLOW_COUNT_TRANSITIONS="Transitions" +COM_WORKFLOW_CREATED_AT_ASC="Date Created ascending" +COM_WORKFLOW_CREATED_AT_DESC="Date Created descending" +COM_WORKFLOW_CREATED_DESC="Date Created" +COM_WORKFLOW_CREATED_LABEL="Date Created" +COM_WORKFLOW_DATE_CREATED="Date Created" +COM_WORKFLOW_DATE_MODIFIED="Date Modified" +COM_WORKFLOW_DEFAULT="Default" +COM_WORKFLOW_DEFAULT_ITEM="Default option is already set for a different item." +COM_WORKFLOW_DESCRIPTION="Description" +COM_WORKFLOW_DESC_TAB="Description" +COM_WORKFLOW_DISABLE_DEFAULT="Cannot change default stage of this item." +COM_WORKFLOW_EDIT="Edit" +COM_WORKFLOW_EDIT_TAB="Edit" +COM_WORKFLOW_ERROR_UPDATE_STAGE="Error while updating the stage." +COM_WORKFLOW_FIELD_CATEGORY_LIST_LABEL="Category List" +COM_WORKFLOW_FIELD_IS_DEFAULT_DESC="If set to default, this will be saved for the component." +COM_WORKFLOW_FIELD_IS_DEFAULT_LABEL="Default" +COM_WORKFLOW_FIELD_NAME_LABEL="Name" +COM_WORKFLOW_FILTER_SEARCH_DESC="Filter the list of items." +COM_WORKFLOW_FILTER_SEARCH_LABEL="Search" +COM_WORKFLOW_FROM_STAGE="From Stage" +COM_WORKFLOW_FROM_STAGE_DESC="Select current stage." +COM_WORKFLOW_ID="ID" +COM_WORKFLOW_ITEM_MUST_PUBLISHED="Item must be published to set default stage." +COM_WORKFLOW_ITEM_SET_DEFAULT="Item set to default." +COM_WORKFLOW_ITEM_UNSET_DEFAULT="Default stage unset." +COM_WORKFLOW_LIST_LIMIT="Output Limit" +COM_WORKFLOW_LIST_LIMIT_DESC="Limit the list of items." +COM_WORKFLOW_MANAGE="Manage" +COM_WORKFLOW_MODIFIED_AT_ASC="Date Modified ascending" +COM_WORKFLOW_MODIFIED_AT_DESC="Date Modified descending" +COM_WORKFLOW_MODIFIED_DESC="Date Modified" +COM_WORKFLOW_MODIFIED_LABEL="Date Modified" +COM_WORKFLOW_MSG_DELETE_DEFAULT="You are trying to delete the default item." +COM_WORKFLOW_MSG_FROM_TO_STAGE="From Stage and To Stage must have different names." +COM_WORKFLOW_MSG_DELETE_IS_ASSIGNED="This item is in use by the component." +COM_WORKFLOW_MSG_WORKFLOWS_DELETE_ERROR="There was a problem while deleting the item: " +COM_WORKFLOW_NA="N/A" +COM_WORKFLOW_NAME="Name" +COM_WORKFLOW_NEW="New" +COM_WORKFLOW_N_ITEMS_ARCHIVED="%s items archived." +COM_WORKFLOW_N_ITEMS_ARCHIVED_1="%s item archived." +COM_WORKFLOW_N_ITEMS_CHECKED_IN="%s items checked in." +COM_WORKFLOW_N_ITEMS_CHECKED_IN_1="%s item checked in." +COM_WORKFLOW_N_ITEMS_DELETED="%s items deleted." +COM_WORKFLOW_N_ITEMS_DELETED_1="%s item deleted." +COM_WORKFLOW_N_ITEMS_PUBLISHED="%s items published." +COM_WORKFLOW_N_ITEMS_PUBLISHED_1="%s item published." +COM_WORKFLOW_N_ITEMS_TRASHED="%s items trashed." +COM_WORKFLOW_N_ITEMS_TRASHED_1="%s item trashed." +COM_WORKFLOW_N_ITEMS_UNPUBLISHED="%s items unpublished." +COM_WORKFLOW_N_ITEMS_UNPUBLISHED_1="%s item unpublished." +COM_WORKFLOW_PARAMS_TAB="Parameters" +COM_WORKFLOW_PUBLISHED="Published" +COM_WORKFLOW_PUBLISHED_DESC="Defines item behaviour." +COM_WORKFLOW_PUBLISHED_LABEL="Status" +COM_WORKFLOW_RULES_TAB="Permissions" +COM_WORKFLOW_SELECT_CONDITION="- Select Condition -" +COM_WORKFLOW_SELECT_FROM_STAGE="- Select Current Stage -" +COM_WORKFLOW_SELECT_TO_STAGE="- Select Target Stage -" +COM_WORKFLOW_STAGE="Existing Stages" +COM_WORKFLOW_STAGES="Stages" +COM_WORKFLOW_STAGES_LIST="%s Stages List" +COM_WORKFLOW_STAGE_ADD="Add Stage" +COM_WORKFLOW_STAGE_EDIT="Edit Stage" +COM_WORKFLOW_TOOLBAR_DEFAULT="Default" +COM_WORKFLOW_TO_STAGE="To Stage" +COM_WORKFLOW_TO_STAGE_DESC="Select target stage." +COM_WORKFLOW_TOO_MANY_ITEMS="Too many items selected." +COM_WORKFLOW_TRANSITION="Transition" +COM_WORKFLOW_TRANSITIONS="Transitions" +COM_WORKFLOW_TRANSITIONS_LIST="%s Transitions List" +COM_WORKFLOW_TRANSITION_ADD="Add Transition" +COM_WORKFLOW_TRANSITION_DUPLICATE="This transition already exists." +COM_WORKFLOW_TRANSITION_EDIT="Edit Transition" +COM_WORKFLOW_TRANSITION_THE_SAME_STAGE="Current stage and target stage are the same." +COM_WORKFLOW_TRASHED="Trashed" +COM_WORKFLOW_UNPUBLISH_DEFAULT_ERROR="You can't unpublish the default workflow." +COM_WORKFLOW_UNPUBLISHED="Unpublished" +COM_WORKFLOW_USER_GROUPS="User Group" +COM_WORKFLOW_USER_GROUPS_DESC="Select user group." +COM_WORKFLOW_WORKFLOW_NOTE="Note" +COM_WORKFLOW_WORKFLOWS_ADD="Add Workflow" +COM_WORKFLOW_WORKFLOWS_EDIT="Edit Workflow" +COM_WORKFLOW_WORKFLOWS_LIST="Workflows List" diff --git a/administrator/language/en-GB/en-GB.com_workflow.sys.ini b/administrator/language/en-GB/en-GB.com_workflow.sys.ini new file mode 100644 index 0000000000000..ad6492bcfc1c4 --- /dev/null +++ b/administrator/language/en-GB/en-GB.com_workflow.sys.ini @@ -0,0 +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 +; Note : All ini files need to be saved as UTF-8 + +COM_WORKFLOW="Workflows" +COM_WORKFLOW_MESSAGES_VIEW_DEFAULT_DESC="Customised workflow support for Joomla! site" +COM_WORKFLOW_MESSAGES_VIEW_DEFAULT_TITLE="Workflows" +COM_WORKFLOW_XML_DESCRIPTION="Customised workflow support for Joomla! site" \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.com_wrapper.ini b/administrator/language/en-GB/en-GB.com_wrapper.ini index b223cbf68260d..365caca95c5ec 100644 --- a/administrator/language/en-GB/en-GB.com_wrapper.ini +++ b/administrator/language/en-GB/en-GB.com_wrapper.ini @@ -6,17 +6,11 @@ COM_WRAPPER="Wrapper" COM_WRAPPER_FIELD_ADD_DESC="By default, http:// will be added unless it detects http:// or https:// in the URL you provide. This allows you to switch off this functionality." COM_WRAPPER_FIELD_ADD_LABEL="Auto Add" -COM_WRAPPER_FIELD_FRAME_DESC="Show frame border which wrap the iframe." COM_WRAPPER_FIELD_FRAME_LABEL="Frame Border" -COM_WRAPPER_FIELD_HEIGHT_DESC="Height of the iframe window in pixels." COM_WRAPPER_FIELD_HEIGHT_LABEL="Height" -COM_WRAPPER_FIELD_HEIGHTAUTO_DESC="If height is set to auto, the height will automatically be set to the size of the external page. This will only work for pages on your own domain. If you see a JavaScript error, make sure this parameter is disabled. This will break XHTML compatibility for this page." COM_WRAPPER_FIELD_HEIGHTAUTO_LABEL="Auto Height" COM_WRAPPER_FIELD_LABEL_SCROLLBARSPARAMS="Scroll Bar Parameters" -COM_WRAPPER_FIELD_SCROLLBARS_DESC="Show or hide the horizontal & vertical scrollbars. If you choose 'Auto', make sure the Auto advanced parameter is set." COM_WRAPPER_FIELD_SCROLLBARS_LABEL="Scroll Bars" -COM_WRAPPER_FIELD_URL_DESC="URL to site/file you wish to display within the iframe." COM_WRAPPER_FIELD_URL_LABEL="URL" COM_WRAPPER_FIELD_VALUE_AUTO="Auto" -COM_WRAPPER_FIELD_WIDTH_DESC="Width of the iframe window. You may enter an absolute figure in pixels or a relative figure by adding a %." COM_WRAPPER_XML_DESCRIPTION="Displays an iframe to wrap an external page or site into Joomla!" diff --git a/administrator/language/en-GB/en-GB.ini b/administrator/language/en-GB/en-GB.ini index b4078de2faa2d..237dcb12fa0d2 100644 --- a/administrator/language/en-GB/en-GB.ini +++ b/administrator/language/en-GB/en-GB.ini @@ -40,12 +40,14 @@ JH5="h5" JH6="h6" ERROR="Error" -MESSAGE="Message" +INFO="Info" NOTICE="Notice" +MESSAGE="Message" WARNING="Warning" JADMINISTRATION="Administration" JADMINISTRATOR="Administrator" +JALIAS="Alias" JALL="All" JALL_LANGUAGE="All" JAPPLY="Save" @@ -134,29 +136,20 @@ JYES="Yes" JACTIONS="Actions for: %s" JACTION_ADMIN="Configure ACL & Options" -JACTION_ADMIN_COMPONENT_DESC="Allows users in the group to edit the options and permissions of this extension." JACTION_ADMIN_GLOBAL="Super User" -JACTION_ADMIN_GLOBAL_DESC="Allows users in the group to perform any action regardless of the settings." JACTION_COMPONENT_SETTINGS="Component Settings" JACTION_CREATE="Create" -JACTION_CREATE_COMPONENT_DESC="Allows users in the group to create any content in this extension." JACTION_DELETE="Delete" -JACTION_DELETE_COMPONENT_DESC="Allows users in the group to delete any content in this extension." JACTION_EDIT="Edit" -JACTION_EDIT_COMPONENT_DESC="Allows users in the group to edit any content in this extension." JACTION_EDITOWN="Edit Own" -JACTION_EDITOWN_COMPONENT_DESC="Allows users in the group to edit any content they submitted in this extension." JACTION_EDITVALUE="Edit Custom Field Value" -JACTION_EDITVALUE_COMPONENT_DESC="Allows users in the group to edit any value of custom fields submitted in this extension." JACTION_EDITSTATE="Edit State" -JACTION_EDITSTATE_COMPONENT_DESC="Allows users in the group to change the state of any content in this extension." +JACTION_EXECUTETRANSITION="Execute transition" JACTION_LOGIN_ADMIN="Administrator Login" JACTION_LOGIN_OFFLINE="Offline Access" JACTION_LOGIN_SITE="Site Login" JACTION_MANAGE="Access Administration Interface" -JACTION_MANAGE_COMPONENT_DESC="Allows users in the group to access the administration interface for this extension." JACTION_OPTIONS="Configure Options Only" -JACTION_OPTIONS_COMPONENT_DESC="Allows users in the group to edit the options except the permissions of this extension." JBROWSERTARGET_MODAL="Modal" JBROWSERTARGET_NEW="Open in new window" @@ -168,7 +161,7 @@ JERROR_ALERTNOTEMPLATE="The template for this display is not available." JERROR_AN_ERROR_HAS_OCCURRED="An error has occurred." JERROR_CORE_CREATE_NOT_PERMITTED="Create not permitted." JERROR_CORE_DELETE_NOT_PERMITTED="Delete not permitted." -JERROR_COULD_NOT_FIND_TEMPLATE="Could not find template "_QQ_"%s"_QQ_"." +JERROR_COULD_NOT_FIND_TEMPLATE="Could not find template \"%s\"." JERROR_INVALID_CONTROLLER="Invalid controller" JERROR_INVALID_CONTROLLER_CLASS="Invalid controller class" JERROR_LAYOUT_PREVIOUS_ERROR="Previous Error" @@ -184,7 +177,7 @@ JERROR_SAVE_FAILED="Could not save data. Error: %s" JFIELD_ACCESS_DESC="The access level group that is allowed to view this item." JFIELD_ACCESS_LABEL="Access" -JFIELD_ALIAS_DESC="The Alias will be used in the SEF URL. Leave this blank and Joomla will fill in a default value from the title. This value will depend on the SEO settings (Global Configuration->Site).
    Using Unicode will produce UTF-8 aliases. You may also enter manually any UTF-8 character. Spaces and some forbidden characters will be changed to hyphens.
    When using default transliteration it will produce an alias in lower case and with dashes instead of spaces. You may enter the Alias manually. Use lowercase letters and hyphens (-). No spaces or underscores are allowed. Default value will be a date and time if the title is typed in non-latin letters." +JFIELD_ALIAS_DESC="The Alias will be used in the SEF URL. Leave this blank and Joomla will fill in a default value from the title. This value will depend on the SEO settings (Global Configuration->Site).
    Using Unicode will produce UTF-8 aliases. You may also enter manually any UTF-8 character. Spaces and some forbidden characters will be changed to hyphens.
    When using default transliteration it will produce an alias in lower case and with dashes instead of spaces. You may enter the Alias manually. Use lowercase letters and hyphens (-). No spaces or underscores are allowed. Default value will be a date and time if the title is typed in non-latin letters." JFIELD_ALIAS_LABEL="Alias" JFIELD_ALIAS_PLACEHOLDER="Auto-generate from title" JFIELD_ALT_COMPONENT_LAYOUT_DESC="Use a layout from the supplied component view or overrides in the templates." @@ -203,6 +196,9 @@ JFIELD_BASIS_LOGOUT_DESCRIPTION_LABEL="Logout Description Text" JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_DESC="Show or hide logout description." JFIELD_BASIS_LOGOUT_DESCRIPTION_SHOW_LABEL="Logout Description" JFIELD_CATEGORY_DESC="The category that this item is assigned to. You may select an existing category or enter a new category by typing the name in the field and pressing enter." +JFIELD_COLOR_SELECT="Select a colour" +JFIELD_COLOR_TRANSPARENT="No colour, transparent" +JFIELD_COLOR_VALUE="Colour with hexadecimal value of" JFIELD_ENABLED_DESC="The enabled status of this item." JFIELD_FIELDS_CATEGORY_DESC="Select the category that this field is assigned to." JFIELD_KEY_REFERENCE_DESC="Used to store information referring to an external resource." @@ -211,11 +207,11 @@ JFIELD_LANGUAGE_DESC="Assign a language to this article." JFIELD_LANGUAGE_LABEL="Language" JFIELD_LOGIN_IMAGE_DESC="Select or upload an image to display on login page." JFIELD_LOGIN_IMAGE_LABEL="Login Image" -JFIELD_LOGIN_REDIRECT_URL_DESC="If a URL is entered here, users will be redirected to it after login.
    The URL must be internal (eg: index.php?Itemid=999)." +JFIELD_LOGIN_REDIRECT_URL_DESC="If a URL is entered here, users will be redirected to it after login.
    The URL must be internal (eg: index.php?Itemid=999)." JFIELD_LOGIN_REDIRECT_URL_LABEL="Login Redirect" JFIELD_LOGOUT_IMAGE_DESC="Select or upload an image to display on logout page." JFIELD_LOGOUT_IMAGE_LABEL="Logout Image" -JFIELD_LOGOUT_REDIRECT_URL_DESC="If a URL is entered here, users will be redirected to it after logout.
    The URL must be internal (eg: index.php?Itemid=999)." +JFIELD_LOGOUT_REDIRECT_URL_DESC="If a URL is entered here, users will be redirected to it after logout.
    The URL must be internal (eg: index.php?Itemid=999)." JFIELD_LOGOUT_REDIRECT_URL_LABEL="Logout Redirect" JFIELD_LOGOUT_REDIRECT_PAGE_DESC="Select or create the page the user will be redirected to after ending their current session by logging out. The default is to stay on the same page." JFIELD_LOGOUT_REDIRECT_PAGE_LABEL="Logout Redirection Page" @@ -242,6 +238,10 @@ JFIELD_OPTION_NONE="None" JFIELD_ORDERING_DESC="Select the ordering." JFIELD_ORDERING_LABEL="Ordering" JFIELD_PARAMS_LABEL="Options" +JFIELD_PASSWORD_INDICATE_INCOMPLETE="Password doesn't meet site's requirements" +JFIELD_PASSWORD_INDICATE_COMPLETE="Password accepted" +JFIELD_PASSWORD_NOTE_LBL="Password must contain:" +JFIELD_PASSWORD_NOTE_DESC="%1s symbol(s), %2s uppercase letter(s), %3s lowercase letter(s), %4s number(s) and be %5s characters long" JFIELD_PLG_SEARCH_ALL_DESC="Include published items in the search." JFIELD_PLG_SEARCH_ALL_LABEL="Search Published" JFIELD_PLG_SEARCH_ARCHIVED_DESC="Include archived items in the search." @@ -251,7 +251,7 @@ JFIELD_PLG_SEARCH_SEARCHLIMIT_LABEL="Search Limit" JFIELD_PUBLISHED_DESC="Set publication status." JFIELD_READMORE_DESC="Add a custom text instead of Read More." JFIELD_READMORE_LABEL="Read More Text" -JFIELD_SPACER_LABEL="
    " +JFIELD_SPACER_LABEL="
    " JFIELD_TITLE_DESC="Title" JFIELD_VERSION_HISTORY_DESC="This button allows you to open a window to view older versions of this item." JFIELD_VERSION_HISTORY_LABEL="Prior Versions" @@ -260,7 +260,6 @@ JFIELD_XREFERENCE_DESC="An optional field to allow this record to be cross-refer JFIELD_XREFERENCE_LABEL="External Reference" JGLOBAL_ACROSS="Across" JGLOBAL_ACTION_PERMISSIONS_LABEL="Permissions" -JGLOBAL_ACTION_PERMISSIONS_DESCRIPTION="Set the action permissions for this asset" JGLOBAL_ADD_CUSTOM_CATEGORY="Add new Category" JGLOBAL_ALL_ARTICLE="Max Levels Articles" JGLOBAL_ALL_LIST="Max Levels as List" @@ -306,7 +305,10 @@ JGLOBAL_AUTO="Auto" JGLOBAL_BATCH_MOVE_PARENT_NOT_FOUND="Can't find the destination parent for this move." JGLOBAL_BATCH_MOVE_ROW_NOT_FOUND="Can't find the destination row for this move." JGLOBAL_BATCH_PROCESS="Process" +JGLOBAL_BATCH_WORKFLOW_STATE_ROW_NOT_FOUND="Can't find the destination row for this state change." JGLOBAL_BLOG="Blog" +JGLOBAL_BLOG_CLASS="Blog Class" +JGLOBAL_BLOG_CLASS_LEADING="Blog Class (Leading Articles)" JGLOBAL_BLOG_LAYOUT_OPTIONS="Blog Layout" JGLOBAL_CATEGORIES_OPTIONS="Categories" JGLOBAL_CATEGORY_LAYOUT_DESC="Layout" @@ -329,8 +331,8 @@ JGLOBAL_COPY="(copy)" JGLOBAL_CREATED="Created" JGLOBAL_CREATED_DATE="Created Date" JGLOBAL_CUSTOM_CATEGORY="New Categories" -JGLOBAL_CUSTOM_FIELDS_ENABLE_DESC="Enable the creation of custom fields." -JGLOBAL_CUSTOM_FIELDS_ENABLE_LABEL="Enable Custom Fields" +JGLOBAL_CUSTOM_FIELDS_ENABLE_DESC="Enable the creation or editing of custom fields." +JGLOBAL_CUSTOM_FIELDS_ENABLE_LABEL="Edit Custom Fields" JGLOBAL_DATE_FORMAT_DESC="Optional format string for showing the date. For example, D M Y for day month year or you can use d-m-y for a short version eg. 28-12-16. See http://www.php.net/manual/en/function.date.php. If left blank, it uses DATE_FORMAT_LC1 from your language file." JGLOBAL_DATE_FORMAT_LABEL="Date Format" JGLOBAL_DESCRIPTION="Description" @@ -345,7 +347,7 @@ JGLOBAL_EMPTY_CATEGORIES_DESC="Show or hide categories that have no articles and JGLOBAL_EMPTY_CATEGORIES_LABEL="Empty Categories" JGLOBAL_ERROR_INSUFFICIENT_BATCH_INFORMATION="Insufficient information to perform the batch operation" JGLOBAL_FEED_SHOW_READMORE_DESC="Displays a "Read More" link in the news feeds if Intro Text is set to Show." -JGLOBAL_FEED_SHOW_READMORE_LABEL="Show "Read More"" +JGLOBAL_FEED_SHOW_READMORE_LABEL=""Read More" Link" JGLOBAL_FEED_SUMMARY_DESC="If set to Intro Text, only the Intro Text of each article will show in the news feed. If set to Full Text, the whole article will show in the news feed." JGLOBAL_FEED_SUMMARY_LABEL="Include in Feed" JGLOBAL_FIELDS="Fields" @@ -403,7 +405,7 @@ JGLOBAL_FILTER_GROUPS_DESC="This sets the user groups that you want filters appl JGLOBAL_FILTER_GROUPS_LABEL="Filter Groups" JGLOBAL_FILTER_TAGS_DESC="2. List additional tags, separating each tag name with a space or comma. For example: p,div,span." JGLOBAL_FILTER_TAGS_LABEL="Filter Tags2" -JGLOBAL_FILTER_TYPE_DESC="1. Blacklist allows all tags and attributes except for those in the blacklist.
    -- Tags for the Default Blacklist include: 'applet', 'body', 'bgsound', 'base', 'basefont', 'canvas', 'embed', 'frame', 'frameset', 'head', 'html', 'id', 'iframe', 'ilayer', 'layer', 'link', 'meta', 'name', 'object', 'script', 'style', 'title', 'xml'
    -- Attributes for the Default Blacklist include: 'action', 'background', 'codebase', 'dynsrc', 'lowsrc', 'formaction'
    -- You can blacklist additional tags and attributes by adding to the Filter Tags and Filter Attributes fields, separating each tag or attribute name with a comma.
    -- Custom Blacklist allows you to override the Default Blacklist. Add the tags and attributes to be blacklisted in the Filter Tags and Filter Attributes fields.

    Whitelist allows only the tags listed in the Filter Tags and Filter Attributes fields.

    No HTML removes all HTML tags from the content when it is saved.

    Please note that these settings work regardless of the editor that you are using.
    Even if you are using a WYSIWYG editor, the filtering settings may strip additional tags and attributes prior to saving information in the database." +JGLOBAL_FILTER_TYPE_DESC="1. Blacklist allows all tags and attributes except for those in the blacklist.
    -- Tags for the Default Blacklist include: 'applet', 'body', 'bgsound', 'base', 'basefont', 'canvas', 'embed', 'frame', 'frameset', 'head', 'html', 'id', 'iframe', 'ilayer', 'layer', 'link', 'meta', 'name', 'object', 'script', 'style', 'title', 'xml'
    -- Attributes for the Default Blacklist include: 'action', 'background', 'codebase', 'dynsrc', 'lowsrc', 'formaction'
    -- You can blacklist additional tags and attributes by adding to the Filter Tags and Filter Attributes fields, separating each tag or attribute name with a comma.
    -- Custom Blacklist allows you to override the Default Blacklist. Add the tags and attributes to be blacklisted in the Filter Tags and Filter Attributes fields.

    Whitelist allows only the tags listed in the Filter Tags and Filter Attributes fields.

    No HTML removes all HTML tags from the content when it is saved.

    Please note that these settings work regardless of the editor that you are using.
    Even if you are using a WYSIWYG editor, the filtering settings may strip additional tags and attributes prior to saving information in the database." JGLOBAL_FILTER_TYPE_LABEL="Filter Type1" JGLOBAL_FULL_TEXT="Full Text" JGLOBAL_GT=">" @@ -418,13 +420,12 @@ JGLOBAL_INDEX_NOFOLLOW="Index, No follow" JGLOBAL_INHERIT="Inherit" JGLOBAL_INTEGRATION_LABEL="Integration" JGLOBAL_INTRO_TEXT="Intro Text" -JGLOBAL_ISFREESOFTWARE="%s is free software released under the GNU General Public License." +JGLOBAL_ISFREESOFTWARE="%s is free software released under the GNU General Public License." JGLOBAL_KEEP_TYPING="Keep typing ..." JGLOBAL_LANGUAGE_VERSION_NOT_PLATFORM="Language pack does not match this Joomla! version. Some strings may be missing and will be displayed in English." JGLOBAL_LEAST_HITS="Least Hits" JGLOBAL_LEFT="Left" -JGLOBAL_LINK_AUTHOR_DESC="If set to Yes, the Name of the article's Author will be linked to its contact page. You must create a contact linked to the author's user record, and the "Content - Contact" plugin must be enabled, for this to be in effect." -JGLOBAL_LINK_AUTHOR_LABEL="Link Author" +JGLOBAL_LINK_AUTHOR_LABEL="Link to Author's Contact Page" JGLOBAL_LINK_CATEGORY_DESC="If set to Yes, and if Show Category is set to 'Show', the Category Title will link to a layout showing articles in that Category." JGLOBAL_LINK_CATEGORY_LABEL="Link Category" JGLOBAL_LINK_PARENT_CATEGORY_DESC="If set to Yes, and if Show Parent is set to 'Show', the Parent Category Title will link to a layout showing articles in that Category." @@ -432,12 +433,12 @@ JGLOBAL_LINK_PARENT_CATEGORY_LABEL="Link Parent" JGLOBAL_LINKED_TITLES_DESC="If set to Yes, the article title will be a link to the article." JGLOBAL_LINKED_TITLES_LABEL="Linked Titles" JGLOBAL_LIST="List" -JGLOBAL_LIST_ALIAS="(Alias: %s)" +JGLOBAL_LIST_ALIAS="Alias: %s" JGLOBAL_LIST_ALIAS_NOTE="(Alias: %s, Note: %s)" JGLOBAL_LIST_AUTHOR_DESC="Show or hide the article author in the list of articles." -JGLOBAL_LIST_AUTHOR_LABEL="Show Author in List" +JGLOBAL_LIST_AUTHOR_LABEL="Author" JGLOBAL_LIST_HITS_DESC="Show or hide article hits in the list of articles." -JGLOBAL_LIST_HITS_LABEL="Show Hits in List" +JGLOBAL_LIST_HITS_LABEL="Hits" JGLOBAL_LIST_LAYOUT_OPTIONS="List Layouts" JGLOBAL_LIST_NAME="(Name: %s)" JGLOBAL_LIST_NAME_NOTE="(Name: %s, Note: %s)" @@ -493,8 +494,8 @@ JGLOBAL_ORDERING_DATE_LABEL="Date for Ordering" JGLOBAL_OTPMETHOD_NONE="Disable Two Factor Authentication" JGLOBAL_PAGINATION_DESC="Show or hide Pagination support. Pagination provides page links at the bottom of the page that allow the User to navigate to additional pages. These are needed if the Information will not fit on one page." JGLOBAL_PAGINATION_LABEL="Pagination" -JGLOBAL_PAGINATION_RESULTS_DESC="Show or hide pagination results information, for example, "Page 1 of 4"." -JGLOBAL_PAGINATION_RESULTS_LABEL="Pagination Results" +JGLOBAL_PAGINATION_RESULTS_DESC="Show or hide pagination summary, for example, "Page 1 of 4"." +JGLOBAL_PAGINATION_RESULTS_LABEL="Pagination Summary" JGLOBAL_PASSWORD="Password" JGLOBAL_PASSWORD_RESET_REQUIRED="You are required to reset your password before proceeding." JGLOBAL_PERMISSIONS_ANCHOR="Set Permissions" @@ -514,10 +515,6 @@ JGLOBAL_SAVE_HISTORY_OPTIONS_DESC="Automatically save old versions of an item. I JGLOBAL_SAVE_HISTORY_OPTIONS_LABEL="Enable Versions" JGLOBAL_SECRETKEY="Secret Key" JGLOBAL_SECRETKEY_HELP="If you have enabled two factor authentication in your user account please enter your secret key. If you do not know what this means, you can leave this field blank." -JGLOBAL_SEF_ADVANCED_DESC="Modern routing enables advanced features but may change your URLs. Legacy routing ensures full compatibility for existing sites. This is configured per component." -JGLOBAL_SEF_ADVANCED_LABEL="URL Routing" -JGLOBAL_SEF_ADVANCED_LEGACY="Legacy" -JGLOBAL_SEF_ADVANCED_MODERN="Modern" JGLOBAL_SEF_NOIDS_DESC="Remove the IDs from the URLs of this component." JGLOBAL_SEF_NOIDS_LABEL="Remove IDs from URLs" JGLOBAL_SELECT_ALLOW_DENY_GROUP="Change %s permission for %s group." @@ -529,72 +526,72 @@ JGLOBAL_SELECTION_INVERT="Toggle Selection" JGLOBAL_SELECTION_INVERT_ALL="Toggle All Selections" JGLOBAL_SELECTION_NONE="Clear Selection" JGLOBAL_SHOW_ASSOCIATIONS_DESC="Multilingual only. If set to Show, the associated articles flags or URL Language Code will be displayed." -JGLOBAL_SHOW_ASSOCIATIONS_LABEL="Show Associations" +JGLOBAL_SHOW_ASSOCIATIONS_LABEL="Associations" JGLOBAL_SHOW_AUTHOR_DESC="If set to Show, the Name of the article's Author will be displayed." -JGLOBAL_SHOW_AUTHOR_LABEL="Show Author" +JGLOBAL_SHOW_AUTHOR_LABEL="Author" JGLOBAL_SHOW_CATEGORY_DESC="If set to Show, the title of the article’s category will show." JGLOBAL_SHOW_CATEGORY_DESCRIPTION_DESC="Show or hide the description of the selected Category." JGLOBAL_SHOW_CATEGORY_DESCRIPTION_LABEL="Category Description" JGLOBAL_SHOW_CATEGORY_IMAGE_DESC="Show or hide the image of the selected Category." JGLOBAL_SHOW_CATEGORY_IMAGE_LABEL="Category Image" -JGLOBAL_SHOW_CATEGORY_HEADING_TITLE_TEXT_LABEL="Show Subcategories Text" +JGLOBAL_SHOW_CATEGORY_HEADING_TITLE_TEXT_LABEL="Subcategories Text" JGLOBAL_SHOW_CATEGORY_HEADING_TITLE_TEXT_DESC="If Show, the "Subcategories" will show as a subheading on the page. The subheading is usually displayed inside the "H3" tag." -JGLOBAL_SHOW_CATEGORY_LABEL="Show Category" +JGLOBAL_SHOW_CATEGORY_LABEL="Category" JGLOBAL_SHOW_CATEGORY_TITLE="Category Title" JGLOBAL_SHOW_CATEGORY_TITLE_DESC="If Show, the Category Title will show as a subheading on the page. The subheading is usually displayed inside the "H2" tag." JGLOBAL_SHOW_CREATE_DATE_DESC="If set to Show, the date and time an Article was created will be displayed. This is a global setting but can be changed at Menu and Article levels." -JGLOBAL_SHOW_CREATE_DATE_LABEL="Show Create Date" +JGLOBAL_SHOW_CREATE_DATE_LABEL="Create Date" JGLOBAL_SHOW_DATE_DESC="Show or hide a date column in the list of articles, or select which date you wish to show." -JGLOBAL_SHOW_DATE_LABEL="Show Date" +JGLOBAL_SHOW_DATE_LABEL="Date" JGLOBAL_SHOW_EMAIL_ICON_DESC="Show or hide the email link. This allows you to email an article." -JGLOBAL_SHOW_EMAIL_ICON_LABEL="Show Email" +JGLOBAL_SHOW_EMAIL_ICON_LABEL="Email" JGLOBAL_SHOW_EMPTY_CATEGORIES_DESC="If Show, empty categories will display. A category is only empty if it has no items or subcategories." JGLOBAL_SHOW_EMPTY_CATEGORIES_LABEL="Empty Categories" JGLOBAL_SHOW_FEATURED_ARTICLES_DESC="Select to show, hide or only display featured articles." JGLOBAL_SHOW_FEATURED_ARTICLES_LABEL="Featured Articles" JGLOBAL_SHOW_FEED_LINK_DESC="Show or hide an RSS Feed Link. (A Feed Link will show up as a feed icon in the address bar of most modern browsers)." -JGLOBAL_SHOW_FEED_LINK_LABEL="Show Feed Link" +JGLOBAL_SHOW_FEED_LINK_LABEL="RSS Feed Link" JGLOBAL_SHOW_FLAG_DESC="If set to 'Yes', will display language choice as image flags. Otherwise will use the content language URL Language Code." JGLOBAL_SHOW_FLAG_LABEL="Use Image Flags" JGLOBAL_SHOW_FULL_DESCRIPTION="Show full description ..." JGLOBAL_SHOW_HEADINGS_DESC="Show or hide the headings in list layouts." JGLOBAL_SHOW_HEADINGS_LABEL="Table Headings" -JGLOBAL_SHOW_HITS_DESC="If set to Show, the number of Hits on a particular Article will be displayed." -JGLOBAL_SHOW_HITS_LABEL="Show Hits" +JGLOBAL_SHOW_HITS_LABEL="Hits" JGLOBAL_SHOW_ICONS_DESC="Print and email will utilise icons or text." -JGLOBAL_SHOW_ICONS_LABEL="Show Icons" +JGLOBAL_SHOW_ICONS_LABEL="Icons" JGLOBAL_SHOW_INTRO_DESC="If set to Show, the Intro Text of the article will show when you drill down to the article. If set to Hide, only the part of the article after the "Read More" break will show." -JGLOBAL_SHOW_INTRO_LABEL="Show Intro Text" +JGLOBAL_SHOW_INTRO_LABEL="Intro Text" JGLOBAL_SHOW_MODIFY_DATE_DESC="If set to Show, the date and time an Article was last modified will be displayed." -JGLOBAL_SHOW_MODIFY_DATE_LABEL="Show Modify Date" +JGLOBAL_SHOW_MODIFY_DATE_LABEL="Modify Date" JGLOBAL_SHOW_NAVIGATION_DESC="If set to Show, shows a navigation link (Next, Previous) between articles." -JGLOBAL_SHOW_NAVIGATION_LABEL="Show Navigation" +JGLOBAL_SHOW_NAVIGATION_LABEL="Navigation" JGLOBAL_SHOW_PARENT_CATEGORY_DESC="If set to Show, the title of the article’s parent category will show." -JGLOBAL_SHOW_PARENT_CATEGORY_LABEL="Show Parent" +JGLOBAL_SHOW_PARENT_CATEGORY_LABEL="Parent" JGLOBAL_SHOW_PRINT_ICON_DESC="Show or hide the print. This allows you to print an article." -JGLOBAL_SHOW_PRINT_ICON_LABEL="Show Print" +JGLOBAL_SHOW_PRINT_ICON_LABEL="Print" JGLOBAL_SHOW_PUBLISH_DATE_DESC="If set to Show, the date and time an Article was published will be displayed. This is a global setting but can be changed at the Category, Menu and Article levels." -JGLOBAL_SHOW_PUBLISH_DATE_LABEL="Show Publish Date" +JGLOBAL_SHOW_PUBLISH_DATE_LABEL="Publish Date" JGLOBAL_SHOW_READMORE_DESC="If set to Show, the Read more ...Link will show if Main text has been provided for the Article." -JGLOBAL_SHOW_READMORE_LABEL="Show "Read More"" +JGLOBAL_SHOW_READMORE_LABEL=""Read More" Link" JGLOBAL_SHOW_READMORE_TITLE_DESC="If set to show the title of the Article will be shown on the Read More button." -JGLOBAL_SHOW_READMORE_TITLE_LABEL="Show Title with Read More" +JGLOBAL_SHOW_READMORE_TITLE_LABEL="Title with Read More" JGLOBAL_SHOW_READMORE_LIMIT_DESC="Set a limit of number of characters in Article Title to show in Read More button." -JGLOBAL_SHOW_READMORE_LIMIT_LABEL="Read More Limit" +JGLOBAL_SHOW_READMORE_LIMIT_LABEL="Read More Limit (characters)" JGLOBAL_SHOW_SUBCATEGORIES_DESCRIPTION_DESC="Show or hide the subcategories descriptions." JGLOBAL_SHOW_SUBCATEGORIES_DESCRIPTION_LABEL="Subcategories Descriptions" JGLOBAL_SHOW_SUBCATEGORY_CONTENT_LABEL="Include Subcategories" JGLOBAL_SHOW_SUBCATEGORY_CONTENT_DESC="If None, only articles from this category will show. If a number, all articles from the category and the subcategories up to and including that level will show in the blog." JGLOBAL_SHOW_TAGS_DESC="Show the tags for this link." -JGLOBAL_SHOW_TAGS_LABEL="Show Tags" +JGLOBAL_SHOW_TAGS_LABEL="Tags" JGLOBAL_SHOW_TITLE_DESC="If set to Show, the article title is shown." -JGLOBAL_SHOW_TITLE_LABEL="Show Title" +JGLOBAL_SHOW_TITLE_LABEL="Title" JGLOBAL_SHOW_UNAUTH_LINKS_DESC="If set to Yes, links to registered content will be shown even if you are not logged-in. You will need to log in to access the full item." -JGLOBAL_SHOW_UNAUTH_LINKS_LABEL="Show Unauthorised Links" +JGLOBAL_SHOW_UNAUTH_LINKS_LABEL="Unauthorised Links" JGLOBAL_SHOW_VOTE_DESC="If set to show, a voting system will be enabled for Articles." -JGLOBAL_SHOW_VOTE_LABEL="Show Voting" +JGLOBAL_SHOW_VOTE_LABEL="Voting" JGLOBAL_SINGLE_LEVEL="Single Level" JGLOBAL_SORT_BY="Sort Table By:" +JGLOBAL_SORTED_BY="Sorted by:" JGLOBAL_START_PUBLISH_AFTER_FINISH="Item start publishing date must be before finish publishing date" JGLOBAL_SUBHEADING_DESC="Optional text to show as a subheading." JGLOBAL_SUBHEADING_LABEL="Page Subheading" @@ -603,7 +600,7 @@ JGLOBAL_SUBMENU_CLEAR_CACHE="Clear Cache" JGLOBAL_SUBMENU_PURGE_EXPIRED_CACHE="Clear Expired Cache" JGLOBAL_SUBSLIDER_BLOG_EXTENDED_LABEL="The option below gives the ability to include articles from subcategories in the Blog layout." JGLOBAL_SUBSLIDER_BLOG_LAYOUT_LABEL="If a field is left blank, global settings will be used." -JGLOBAL_SUBSLIDER_DRILL_CATEGORIES_LABEL="These options are also used when you select
    one of the category links, on the first page and/or thereafter,
    unless they are changed for a specific menu item." +JGLOBAL_SUBSLIDER_DRILL_CATEGORIES_LABEL="These options are also used when you select
    one of the category links, on the first page and/or thereafter,
    unless they are changed for a specific menu item." JGLOBAL_TITLE="Title" JGLOBAL_TITLE_ASC="Title ascending" JGLOBAL_TITLE_DESC="Title descending" @@ -624,6 +621,7 @@ JGLOBAL_VOTES_ASC="Votes ascending" JGLOBAL_VOTES_DESC="Votes descending" JGLOBAL_WARNJAVASCRIPT="Warning! JavaScript must be enabled for proper operation of the Administrator Backend." JGLOBAL_WIDTH="Width" +JGLOBAL_WORKFLOWS_ENABLE_LABEL="Edit Workflows" JGRID_HEADING_ACCESS="Access" JGRID_HEADING_ACCESS_ASC="Access ascending" @@ -674,7 +672,6 @@ JHELP_COMPONENTS_COM_SEARCH_OPTIONS="Components_Search_Manager_Options" JHELP_COMPONENTS_COM_TAGS_OPTIONS="Components_Tags_Manager_Options" JHELP_COMPONENTS_COM_TEMPLATES_OPTIONS="Components_Template_Manager_Options" JHELP_COMPONENTS_COM_USERS_OPTIONS="Components_Users_Configuration" -JHELP_COMPONENTS_COM_WEBLINKS_OPTIONS="Components_Web_Links_Manager_Options" JHELP_COMPONENTS_CONTACT_CATEGORIES="Components_Contacts_Categories" JHELP_COMPONENTS_CONTACT_CATEGORY_ADD="Components_Contacts_Categories_Edit" JHELP_COMPONENTS_CONTACT_CATEGORY_EDIT="Components_Contacts_Categories_Edit" @@ -683,6 +680,7 @@ JHELP_COMPONENTS_CONTACTS_CONTACTS="Components_Contacts_Contacts" JHELP_COMPONENTS_CONTENT_CATEGORIES="Components_Content_Categories" JHELP_COMPONENTS_CONTENT_CATEGORY_ADD="Components_Content_Categories_Edit" JHELP_COMPONENTS_CONTENT_CATEGORY_EDIT="Components_Content_Categories_Edit" +JHELP_COMPONENTS_CSP_REPORTS="Components_Csp_Reports" JHELP_COMPONENTS_FIELDS_FIELDS="Components_Fields_Fields" JHELP_COMPONENTS_FIELDS_FIELDS_EDIT="Components_Fields_Fields_Edit" JHELP_COMPONENTS_FIELDS_FIELD_GROUPS="Components_Fields_Field_Groups" @@ -714,11 +712,6 @@ JHELP_COMPONENTS_TAGS_MANAGER_EDIT="Components_Tags_Manager_Edit" JHELP_COMPONENTS_USERS_CATEGORIES="Users_User_Note_Categories" JHELP_COMPONENTS_USERS_CATEGORY_ADD="Users_User_Note_Category_Edit" JHELP_COMPONENTS_USERS_CATEGORY_EDIT="Users_User_Note_Category_Edit" -JHELP_COMPONENTS_WEBLINKS_CATEGORIES="Components_Weblinks_Categories" -JHELP_COMPONENTS_WEBLINKS_CATEGORY_ADD="Components_Weblinks_Categories_Edit" -JHELP_COMPONENTS_WEBLINKS_CATEGORY_EDIT="Components_Weblinks_Categories_Edit" -JHELP_COMPONENTS_WEBLINKS_LINKS_EDIT="Components_Weblinks_Links_Edit" -JHELP_COMPONENTS_WEBLINKS_LINKS="Components_Weblinks_Links" JHELP_CONTENT_ARTICLE_MANAGER="Content_Article_Manager" JHELP_CONTENT_ARTICLE_MANAGER_EDIT="Content_Article_Manager_Edit" JHELP_CONTENT_FEATURED_ARTICLES="Content_Featured_Articles" @@ -776,7 +769,6 @@ JHELP_EXTENSIONS_MODULE_MANAGER_STATISTICS="Extensions_Module_Manager_Statistics JHELP_EXTENSIONS_MODULE_MANAGER_SYNDICATION_FEEDS="Extensions_Module_Manager_Syndication_Feeds" JHELP_EXTENSIONS_MODULE_MANAGER_TAGS_POPULAR="Extensions_Module_Manager_Tags_Popular" JHELP_EXTENSIONS_MODULE_MANAGER_TAGS_SIMILAR="Extensions_Module_Manager_Tags_Similar" -JHELP_EXTENSIONS_MODULE_MANAGER_WEBLINKS="Extensions_Module_Manager_Weblinks" JHELP_EXTENSIONS_MODULE_MANAGER_WHO_ONLINE="Extensions_Module_Manager_Who_Online" JHELP_EXTENSIONS_MODULE_MANAGER_WRAPPER="Extensions_Module_Manager_Wrapper" JHELP_EXTENSIONS_PLUGIN_MANAGER="Extensions_Plugin_Manager" @@ -821,9 +813,6 @@ JHELP_MENUS_MENU_ITEM_USER_PROFILE="Menus_Menu_Item_User_Profile" JHELP_MENUS_MENU_ITEM_USER_PROFILE_EDIT="Menus_Menu_Item_User_Profile_Edit" JHELP_MENUS_MENU_ITEM_USER_REGISTRATION="Menus_Menu_Item_User_Registration" JHELP_MENUS_MENU_ITEM_USER_REMINDER="Menus_Menu_Item_User_Reminder" -JHELP_MENUS_MENU_ITEM_WEBLINK_CATEGORIES="Menus_Menu_Item_Weblink_Categories" -JHELP_MENUS_MENU_ITEM_WEBLINK_CATEGORY="Menus_Menu_Item_Weblink_Category" -JHELP_MENUS_MENU_ITEM_WEBLINK_SUBMIT="Menus_Menu_Item_Weblink_Submit" JHELP_MENUS_MENU_ITEM_WRAPPER="Menus_Menu_Item_Wrapper" JHELP_MENUS_MENU_MANAGER="Menus_Menu_Manager" JHELP_MENUS_MENU_MANAGER_EDIT="Menus_Menu_Manager_Edit" @@ -855,7 +844,6 @@ JLIB_DATABASE_ERROR_CONNECT_DATABASE="Unable to connect to the Database: %s" JLIB_DATABASE_ERROR_CONNECT_MYSQL="Could not connect to MySQL." JLIB_DATABASE_ERROR_DATABASE_CONNECT="Could not connect to database" JLIB_DATABASE_ERROR_LOAD_DATABASE_DRIVER="Unable to load Database Driver: %s" -JLIB_ERROR_INFINITE_LOOP="Infinite loop detected in JError" JOPTION_ACCESS_SHOW_ALL_ACCESS="Show All Access" JOPTION_ACCESS_SHOW_ALL_GROUPS="Show All Groups" @@ -952,8 +940,8 @@ JWARNING_ARCHIVE_MUST_SELECT="You must select at least one item to archive." JWARNING_UNPUBLISH_MUST_SELECT="You must select at least one item to unpublish." JWARNING_TRASH_MUST_SELECT="You must select at least one item to remove." JWARNING_DELETE_MUST_SELECT="You must select at least one item to permanently delete." -JWARNING_REMOVE_ROOT_USER="You are logged-in using the emergency Root User setting in configuration.php.
    You should remove $root_user from the configuration.php as soon as you have restored control to your site to avoid future security breaches.
    Select here to try to do it automatically." -JWARNING_REMOVE_ROOT_USER_ADMIN="The emergency Root User setting is enabled for the user(id): %s.
    You should remove $root_user from the configuration.php as soon as you have restored control to your site to avoid future security breaches.
    Select here to try to do it automatically." +JWARNING_REMOVE_ROOT_USER="You are logged-in using the emergency Root User setting in configuration.php.
    You should remove $root_user from the configuration.php as soon as you have restored control to your site to avoid future security breaches.
    Select here to try to do it automatically." +JWARNING_REMOVE_ROOT_USER_ADMIN="The emergency Root User setting is enabled for the user(id): %s.
    You should remove $root_user from the configuration.php as soon as you have restored control to your site to avoid future security breaches.
    Select here to try to do it automatically." ; Date format @@ -1019,8 +1007,6 @@ FRIDAY="Friday" DECIMALS_SEPARATOR="." THOUSANDS_SEPARATOR="," -; Time Zones - this data has been removed as it is no longer used by Joomla 3.x - ; Mailer Codes PHPMAILER_PROVIDE_ADDRESS="You must provide at least one recipient email address." PHPMAILER_MAILER_IS_NOT_SUPPORTED="Mailer is not supported." @@ -1044,16 +1030,13 @@ PHPMAILER_SMTP_CONNECT_FAILED="SMTP connect failed" PHPMAILER_TLS="Could not start TLS" ; Database types (allows for a more descriptive label than the internal name) -MYSQL="MySQL" +MYSQL="MySQL (PDO)" MYSQLI="MySQLi" ORACLE="Oracle" -PDOMYSQL="MySQL (PDO)" +PGSQL="PostgreSQL (PDO)" POSTGRESQL="PostgreSQL" -SQLAZURE="Microsoft SQL Azure" SQLITE="SQLite" -SQLSRV="Microsoft SQL Server" ; Search tools -JSEARCH_TOOLS="Search Tools" -JSEARCH_TOOLS_DESC="Filter the list items." -JSEARCH_TOOLS_ORDERING="Order by:" +JTABLE_OPTIONS="Table Options" +JTABLE_OPTIONS_ORDERING="Order by:" diff --git a/administrator/language/en-GB/en-GB.lib_joomla.ini b/administrator/language/en-GB/en-GB.lib_joomla.ini index 7d25468d1b213..f084bdef304f0 100644 --- a/administrator/language/en-GB/en-GB.lib_joomla.ini +++ b/administrator/language/en-GB/en-GB.lib_joomla.ini @@ -42,6 +42,7 @@ JLIB_APPLICATION_ERROR_MODEL_GET_NAME="JModel: :getName() : Can't get or parse c JLIB_APPLICATION_ERROR_MODULE_LOAD="Error loading module %s" JLIB_APPLICATION_ERROR_PATHWAY_LOAD="Unable to load pathway: %s" JLIB_APPLICATION_ERROR_REORDER_FAILED="Reorder failed. Error: %s" +JLIB_APPLICATION_ERROR_RUN_TRANSITION="Unable to run transition." JLIB_APPLICATION_ERROR_ROUTER_LOAD="Unable to load router: %s" JLIB_APPLICATION_ERROR_MODELCLASS_NOT_FOUND="Model class %s not found in file." JLIB_APPLICATION_ERROR_SAVE_FAILED="Save failed with the following error: %s" @@ -58,6 +59,7 @@ JLIB_APPLICATION_SUBMIT_SAVE_SUCCESS="Item submitted." JLIB_APPLICATION_SUCCESS_BATCH="Batch process completed." JLIB_APPLICATION_SUCCESS_ITEM_REORDERED="Ordering saved." JLIB_APPLICATION_SUCCESS_ORDERING_SAVED="Ordering saved." +JLIB_APPLICATION_SUCCESS_RUN_TRANSITION="New state saved." JLIB_APPLICATION_SUCCESS_LOAD_HISTORY="Prior version restored. Saved on %s %s." JLIB_LOGIN_AUTHENTICATE="Username and password do not match or you do not have an account yet." @@ -162,13 +164,13 @@ JLIB_DATABASE_ERROR_CLASS_NOT_FOUND_IN_FILE="Table class %s not found in file." JLIB_DATABASE_ERROR_CONNECT_DATABASE="Unable to connect to the Database: %s" JLIB_DATABASE_ERROR_CONNECT_MYSQL="Could not connect to MySQL." JLIB_DATABASE_ERROR_DATABASE_CONNECT="Could not connect to database." -JLIB_DATABASE_ERROR_DATABASE_UPGRADE_FAILED="MySQL Database Upgrade failed. Please check the Database Fixer." +JLIB_DATABASE_ERROR_DATABASE_UPGRADE_FAILED="MySQL Database Upgrade failed. Please check the Database Fixer." JLIB_DATABASE_ERROR_DELETE_CATEGORY="Left-Right data inconsistency. Can't delete category." JLIB_DATABASE_ERROR_DELETE_FAILED="%s: :delete failed - %s" JLIB_DATABASE_ERROR_DELETE_ROOT_CATEGORIES="Root categories can't be deleted." JLIB_DATABASE_ERROR_EMAIL_INUSE="This email address is already registered." JLIB_DATABASE_ERROR_EMPTY_ROW_RETURNED="The database row is empty." -JLIB_DATABASE_ERROR_FUNCTION_FAILED="DB function failed with error number %s
    %s" +JLIB_DATABASE_ERROR_FUNCTION_FAILED="DB function failed with error number %s
    %s" JLIB_DATABASE_ERROR_GET_NEXT_ORDER_FAILED="%s: :getNextOrder failed - %s" JLIB_DATABASE_ERROR_GET_TREE_FAILED="%s: :getTree Failed - %s" JLIB_DATABASE_ERROR_GETNODE_FAILED="%s: :_getNode Failed - %s" @@ -201,7 +203,9 @@ JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_CATEGORY="Category must have a title." JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_EXTENSION="Extension must have a title." JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_MENUITEM="Menu Item must have a title." JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_MODULE="Module must have a title." +JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_STATE="State must have a title." JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_UPDATESITE="Update site must have a title." +JLIB_DATABASE_ERROR_MUSTCONTAIN_A_TITLE_WORKFLOW="Workflow must have a title." JLIB_DATABASE_ERROR_NEGATIVE_NOT_PERMITTED="%s can't be negative." JLIB_DATABASE_ERROR_NO_ROWS_SELECTED="No rows selected." JLIB_DATABASE_ERROR_NOT_SUPPORTED_FILE_NOT_FOUND="Table %s not supported. File not found." @@ -217,7 +221,7 @@ JLIB_DATABASE_ERROR_REORDER_FAILED="%s: :reorder failed - %s" JLIB_DATABASE_ERROR_REORDER_UPDATE_ROW_FAILED="%s: :reorder update the row %s failed - %s" JLIB_DATABASE_ERROR_ROOT_NODE_NOT_FOUND="Root node not found." JLIB_DATABASE_ERROR_STORE_FAILED_UPDATE_ASSET_ID="The asset_id field could not be updated." -JLIB_DATABASE_ERROR_STORE_FAILED="%1$s: :store failed
    %2$s" +JLIB_DATABASE_ERROR_STORE_FAILED="%1$s: :store failed
    %2$s" JLIB_DATABASE_ERROR_USERGROUP_TITLE="User group must have a title." JLIB_DATABASE_ERROR_USERGROUP_TITLE_EXISTS="User group title already exists. Title must be unique with the same parent." JLIB_DATABASE_ERROR_USERLEVEL_NAME_EXISTS="Level with the name "%s" already exists." @@ -233,8 +237,7 @@ JLIB_DOCUMENT_ERROR_UNABLE_LOAD_DOC_CLASS="Unable to load document class." JLIB_ENVIRONMENT_SESSION_EXPIRED="Your session has expired. Please log in again." JLIB_ENVIRONMENT_SESSION_INVALID="Invalid session cookie. Please check that you have cookies enabled in your web browser." JLIB_ERROR_COMPONENTS_ACL_CONFIGURATION_FILE_MISSING_OR_IMPROPERLY_STRUCTURED="The %s component's ACL configuration file is either missing or improperly structured." -JLIB_ERROR_INFINITE_LOOP="Infinite loop detected in JError." -JLIB_EVENT_ERROR_DISPATCHER="JEventDispatcher: :register: Event handler not recognised. Handler: %s" +JLIB_EVENT_ERROR_DISPATCHER="DispatcherInterface: :register: Event handler not recognised. Handler: %s" JLIB_FILESYSTEM_BZIP_NOT_SUPPORTED="BZip2 Not Supported." JLIB_FILESYSTEM_BZIP_UNABLE_TO_READ="Unable to read archive (bz2)." JLIB_FILESYSTEM_BZIP_UNABLE_TO_WRITE="Unable to write archive (bz2)." @@ -308,12 +311,15 @@ JLIB_FORM_BUTTON_SELECT="Select" JLIB_FORM_CHANGE_IMAGE="Change Image" JLIB_FORM_CHANGE_IMAGE_BUTTON="Change Image Button" JLIB_FORM_CHANGE_USER="Select User" +JLIB_FORM_CONTAINS_INVALID_FIELDS="The form cannot be submitted as it's missing required data.
    Please correct the marked fields and try again." JLIB_FORM_ERROR_FIELDS_CATEGORY_ERROR_EXTENSION_EMPTY="Extension attribute is empty in the category field." JLIB_FORM_ERROR_FIELDS_GROUPEDLIST_ELEMENT_NAME="Unknown element type: %s" JLIB_FORM_ERROR_NO_DATA="No data." JLIB_FORM_ERROR_VALIDATE_FIELD="Invalid xml field." JLIB_FORM_ERROR_XML_FILE_DID_NOT_LOAD="XML file did not load." JLIB_FORM_FIELD_INVALID="Invalid field: " +JLIB_FORM_FIELD_REQUIRED_CHECK="One of the options must be selected" +JLIB_FORM_FIELD_REQUIRED_VALUE="Field value cannot be empty" JLIB_FORM_INPUTMODE="latin" JLIB_FORM_INVALID_FORM_OBJECT="Invalid Form Object: :%s" JLIB_FORM_INVALID_FORM_RULE="Invalid Form Rule: :%s" @@ -326,29 +332,21 @@ JLIB_FORM_VALIDATE_FIELD_INVALID="Invalid field: %s" JLIB_FORM_VALIDATE_FIELD_REQUIRED="Field required: %s" JLIB_FORM_VALIDATE_FIELD_RULE_MISSING="Validation Rule missing: %s" JLIB_FORM_VALIDATE_FIELD_URL_SCHEMA_MISSING="Invalid URL: URL schema is missing in %1$s. Please add one of the following at the beginning: %2$s." -JLIB_FORM_VALUE_CACHE_APC="Alternative PHP Cache" JLIB_FORM_VALUE_CACHE_APCU="APC User Cache" -JLIB_FORM_VALUE_CACHE_CACHELITE="Cache_Lite" -JLIB_FORM_VALUE_CACHE_EACCELERATOR="eAccelerator" JLIB_FORM_VALUE_CACHE_FILE="File" -JLIB_FORM_VALUE_CACHE_MEMCACHE="Memcache" JLIB_FORM_VALUE_CACHE_MEMCACHED="Memcached (Experimental)" JLIB_FORM_VALUE_CACHE_REDIS="Redis" JLIB_FORM_VALUE_CACHE_WINCACHE="Windows Cache" -JLIB_FORM_VALUE_CACHE_XCACHE="XCache" -JLIB_FORM_VALUE_SESSION_APC="Alternative PHP Cache" +JLIB_FORM_VALUE_SESSION_APCU="APC User Cache" JLIB_FORM_VALUE_SESSION_DATABASE="Database" -JLIB_FORM_VALUE_SESSION_EACCELERATOR="eAccelerator" -JLIB_FORM_VALUE_SESSION_MEMCACHE="Memcache" +JLIB_FORM_VALUE_SESSION_FILESYSTEM="Filesystem" JLIB_FORM_VALUE_SESSION_MEMCACHED="Memcached (Experimental)" -JLIB_FORM_VALUE_SESSION_NONE="PHP" JLIB_FORM_VALUE_SESSION_REDIS="Redis" JLIB_FORM_VALUE_SESSION_WINCACHE="Windows Cache" -JLIB_FORM_VALUE_SESSION_XCACHE="XCache" JLIB_FORM_VALUE_TIMEZONE_UTC="Universal Time, Coordinated (UTC)" JLIB_FORM_VALUE_FROM_TEMPLATE="From Template" JLIB_FORM_VALUE_INHERITED="Inherited" - +JLIB_FORM_FIELD_INVALID_VALUE="This value is not valid" JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_ACL="ACL" JLIB_HTML_ACCESS_MODIFY_DESC_CAPTION_TABLE="Table" JLIB_HTML_ACCESS_SUMMARY_DESC_CAPTION="ACL Summary Table" @@ -375,6 +373,9 @@ JLIB_HTML_BATCH_USER_LABEL="Set User." JLIB_HTML_BATCH_USER_LABEL_DESC="Not making a selection will keep the original user when processing." JLIB_HTML_BATCH_USER_NOCHANGE="- Keep original User -" JLIB_HTML_BATCH_USER_NOUSER="No User." +JLIB_HTML_BATCH_WORKFLOW_STAGE_LABEL="Change Stage" +JLIB_HTML_BATCH_WORKFLOW_STAGE_LABEL_DESC="Change stage of selected items" +JLIB_HTML_BATCH_WORKFLOW_STAGE_NOCHANGE="- Keep original Workflow Stage -" JLIB_HTML_BEHAVIOR_ABOUT_THE_CALENDAR="About the Calendar" JLIB_HTML_BEHAVIOR_CLOSE="Close" JLIB_HTML_BEHAVIOR_DATE_SELECTION="Date selection:\n" @@ -449,6 +450,7 @@ JLIB_HTML_START="Start" JLIB_HTML_UNPUBLISH_ITEM="Unpublish Item" JLIB_HTML_VIEW_ALL="View All" JLIB_HTML_SETDEFAULT_ITEM="Set default" +JLIB_HTML_UNKNOWN_STATE="Unknown State" JLIB_HTML_UNSETDEFAULT_ITEM="Unset default" JLIB_INSTALLER_ABORT="Aborting language installation: %s" @@ -572,7 +574,7 @@ JLIB_INSTALLER_ERROR_COMP_UPDATE_FAILED_TO_CREATE_DIRECTORY_ADMIN="Component Upd JLIB_INSTALLER_ERROR_COMP_UPDATE_FAILED_TO_CREATE_DIRECTORY_SITE="Component Update: Failed to create site folder: %s" JLIB_INSTALLER_ERROR_CREATE_DIRECTORY="JInstaller: :Install: Failed to create folder: %s" JLIB_INSTALLER_ERROR_CREATE_FOLDER_FAILED="Failed to create folder [%s]" -JLIB_INSTALLER_ERROR_DEPRECATED_FORMAT="Deprecated install format (client="_QQ_"both"_QQ_"), use package installer in future." +JLIB_INSTALLER_ERROR_DEPRECATED_FORMAT="Deprecated install format (client=\"both\"), use package installer in future." JLIB_INSTALLER_ERROR_DISCOVER_INSTALL_UNSUPPORTED="A %s extension can not be installed using the discover method. Please install this extension from Extension Manager: Install." JLIB_INSTALLER_ERROR_DOWNGRADE="Sorry! You cannot downgrade from version %s to %s" JLIB_INSTALLER_ERROR_DOWNLOAD_SERVER_CONNECT="Error connecting to the server: %s" @@ -642,7 +644,9 @@ JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DEFAULT="Template Uninstall: Can't r JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_DIRECTORY="Template Uninstall: Folder does not exist, can't remove files." JLIB_INSTALLER_ERROR_TPL_UNINSTALL_TEMPLATE_ID_EMPTY="Template Uninstall: Template ID is empty, can't uninstall files." JLIB_INSTALLER_ERROR_TPL_UNINSTALL_WARNCORETEMPLATE="Template Uninstall: Trying to uninstall a core template: %s" +JLIB_INSTALLER_ERROR_UNINSTALL_PROTECTED_EXTENSION="Extension Uninstall: Cannot uninstall a protected extension." JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE="Unknown Client Type [%s]" +JLIB_INSTALLER_ERROR_UNKNOWN_EXTENSION="Extension Uninstall: Unknown Extension." JLIB_INSTALLER_FILE_ERROR_MOVE="Error on moving file %s" JLIB_INSTALLER_INCORRECT_SEQUENCE="Downgrading from version %1$s to version %2$s is not allowed." JLIB_INSTALLER_INSTALL="Install" @@ -661,7 +665,7 @@ JLIB_INSTALLER_WARNING_UNABLE_TO_INSTALL_CONTENT_LANGUAGE="Unable to create a co JLIB_JS_AJAX_ERROR_CONNECTION_ABORT="A connection abort has occurred while fetching the JSON data." JLIB_JS_AJAX_ERROR_NO_CONTENT="No content was returned." JLIB_JS_AJAX_ERROR_OTHER="An error has occurred while fetching the JSON data: HTTP %s status code." -JLIB_JS_AJAX_ERROR_PARSE="A parse error has occurred while processing the following JSON data:
    %s" +JLIB_JS_AJAX_ERROR_PARSE="A parse error has occurred while processing the following JSON data:
    %s" JLIB_JS_AJAX_ERROR_TIMEOUT="A timeout has occurred while fetching the JSON data." JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METAFILE="Could not load %s language XML file from %s." @@ -714,7 +718,7 @@ JLIB_RULES_SAVE_BEFORE_CHANGE_PERMISSIONS="Please save before changing permissio JLIB_RULES_SELECT_ALLOW_DENY_GROUP="Allow or deny %s for users in the %s group." JLIB_RULES_SELECT_SETTING="Select New Setting" JLIB_RULES_SETTING_NOTES="If you change the setting, it will apply to this and all child groups, components and content. Note that Denied will overrule any inherited setting and also the setting in any child group, component or content. In the case of a setting conflict, Deny will take precedence. Not Set is equivalent to Denied but can be changed in child groups, components and content." -JLIB_RULES_SETTING_NOTES_ITEM="If you change the setting, it will apply to this item. Note that:
    Inherited means that the permissions from global configuration, parent group and category will be used.
    Denied means that no matter what the global configuration, parent group or category settings are, the group being edited can't take this action on this item.
    Allowed means that the group being edited will be able to take this action for this item (but if this is in conflict with the global configuration, parent group or category it will have no impact; a conflict will be indicated by Not Allowed (Inherited) under Calculated Settings)." +JLIB_RULES_SETTING_NOTES_ITEM="If you change the setting, it will apply to this item. Note that:
    Inherited means that the permissions from global configuration, parent group and category will be used.
    Denied means that no matter what the global configuration, parent group or category settings are, the group being edited can't take this action on this item.
    Allowed means that the group being edited will be able to take this action for this item (but if this is in conflict with the global configuration, parent group or category it will have no impact; a conflict will be indicated by Not Allowed (Inherited) under Calculated Settings)." JLIB_RULES_SETTINGS_DESC="Manage the permission settings for the user groups below. See notes at the bottom." JLIB_STEMMER_INVALID_STEMMER="Invalid stemmer type %s" @@ -741,7 +745,71 @@ JLIB_USER_ERROR_UNABLE_TO_FIND_USER="Unable to find a user with given activation JLIB_USER_ERROR_UNABLE_TO_LOAD_USER="JUser: :_load: Unable to load user with ID: %s" JLIB_USER_EXCEPTION_ACCESS_USERGROUP_INVALID="User group does not exist." JLIB_UTIL_ERROR_APP_INSTANTIATION="Application Startup Error." -JLIB_UTIL_ERROR_CONNECT_DATABASE="JDatabase: :getInstance: Could not connect to database
    joomla.library: %1$s - %2$s" +JLIB_UTIL_ERROR_CONNECT_DATABASE="JDatabase: :getInstance: Could not connect to database
    joomla.library: %1$s - %2$s" JLIB_UTIL_ERROR_DOMIT="DommitDocument is deprecated. Use DomDocument instead." JLIB_UTIL_ERROR_LOADING_FEED_DATA="Error loading feed data." JLIB_UTIL_ERROR_XML_LOAD="Failed loading XML file." + +JLIB_FORM_FIELD_PARAM_CALENDAR_FORMAT_DESC="The date format to be used. This is in the format used by PHP to specify date string formats (see below). If no format argument is given, '%Y-%m-%d' is assumed (giving dates like '2008-04-16')." +JLIB_FORM_FIELD_PARAM_CALENDAR_FORMAT_LABEL="Format" + +JLIB_FORM_FIELD_PARAM_CHECKBOX_MULTIPLE_DESC="Allow multiple values to be selected." +JLIB_FORM_FIELD_PARAM_CHECKBOX_MULTIPLE_LABEL="Multiple" +JLIB_FORM_FIELD_PARAM_CHECKBOX_MULTIPLE_VALUES_DESC="The options of the list." +JLIB_FORM_FIELD_PARAM_CHECKBOX_MULTIPLE_VALUES_KEY_LABEL="Key" +JLIB_FORM_FIELD_PARAM_CHECKBOX_MULTIPLE_VALUES_LABEL="Checkbox Values" +JLIB_FORM_FIELD_PARAM_CHECKBOX_MULTIPLE_VALUES_VALUE_LABEL="Value" + +JLIB_FORM_FIELD_PARAM_EDITOR_BUTTONS_HIDE_DESC="Hide the buttons in the comma separated list." +JLIB_FORM_FIELD_PARAM_EDITOR_BUTTONS_HIDE_LABEL="Hide Buttons" +JLIB_FORM_FIELD_PARAM_EDITOR_HEIGHT_DESC="Defines the height (in pixels) of the WYSIWYG editor and defaults to 250px" +JLIB_FORM_FIELD_PARAM_EDITOR_HEIGHT_LABEL="Height" +JLIB_FORM_FIELD_PARAM_EDITOR_SHOW_BUTTONS_DESC="Should the buttons being shown." +JLIB_FORM_FIELD_PARAM_EDITOR_SHOW_BUTTONS_LABEL="Show Buttons" +JLIB_FORM_FIELD_PARAM_EDITOR_WIDTH_DESC="Defines the width (in pixels) of the WYSIWYG editor and defaults to 100%" +JLIB_FORM_FIELD_PARAM_EDITOR_WIDTH_LABEL="Width" + +JLIB_FORM_FIELD_PARAM_IMAGELIST_DIRECTORY_DESC="The filesystem path to the directory containing the image files to be listed." +JLIB_FORM_FIELD_PARAM_IMAGELIST_DIRECTORY_LABEL="Directory" +JLIB_FORM_FIELD_PARAM_INTEGER_FIRST_DESC="This value is the lowest on the list." +JLIB_FORM_FIELD_PARAM_INTEGER_FIRST_LABEL="First" +JLIB_FORM_FIELD_PARAM_INTEGER_LAST_DESC="This value is the highest on the list." +JLIB_FORM_FIELD_PARAM_INTEGER_LAST_LABEL="Last" +JLIB_FORM_FIELD_PARAM_INTEGER_STEP_DESC="Each option will be the previous option incremented by this integer, starting with the first value until the last value is reached." +JLIB_FORM_FIELD_PARAM_INTEGER_STEP_LABEL="Step" + +JLIB_FORM_FIELD_PARAM_LIST_MULTIPLE_DESC="Allow multiple values to be selected." +JLIB_FORM_FIELD_PARAM_LIST_MULTIPLE_LABEL="Multiple" +JLIB_FORM_FIELD_PARAM_LIST_MULTIPLE_VALUES_DESC="The options of the list." +JLIB_FORM_FIELD_PARAM_LIST_MULTIPLE_VALUES_LABEL="List Values" +JLIB_FORM_FIELD_PARAM_LIST_MULTIPLE_VALUES_VALUE_LABEL="Value" +JLIB_FORM_FIELD_PARAM_LIST_MULTIPLE_VALUES_NAME_LABEL="Name" + +JLIB_FORM_FIELD_PARAM_MEDIA_IMAGE_CLASS_DESC="The class which is added to the image (src tag)." +JLIB_FORM_FIELD_PARAM_MEDIA_IMAGE_CLASS_LABEL="Image Class" +JLIB_FORM_FIELD_PARAM_MEDIA_PREVIEW_DESC="Shows or hides the preview of the selected image." +JLIB_FORM_FIELD_PARAM_MEDIA_PREVIEW_INLINE="Inline" +JLIB_FORM_FIELD_PARAM_MEDIA_PREVIEW_LABEL="Preview" +JLIB_FORM_FIELD_PARAM_MEDIA_PREVIEW_TOOLTIP="Tooltip" +JLIB_FORM_FIELD_PARAM_MEDIA_HOME_LABEL="Home Directory" +JLIB_FORM_FIELD_PARAM_MEDIA_HOME_DESC="Should the directory with the files point to a user directory." + +JLIB_FORM_FIELD_PARAM_RADIO_MULTIPLE_DESC="Allow multiple values to be selected." +JLIB_FORM_FIELD_PARAM_RADIO_MULTIPLE_LABEL="Multiple" +JLIB_FORM_FIELD_PARAM_RADIO_MULTIPLE_VALUES_DESC="The options of the list." +JLIB_FORM_FIELD_PARAM_RADIO_MULTIPLE_VALUES_KEY_LABEL="Key" +JLIB_FORM_FIELD_PARAM_RADIO_MULTIPLE_VALUES_LABEL="Radio Values" +JLIB_FORM_FIELD_PARAM_RADIO_MULTIPLE_VALUES_VALUE_LABEL="Value" + +JLIB_FORM_FIELD_PARAM_SQL_QUERY_DESC="The SQL query which will provide the data for the drop-down list. The query must return two columns; one called 'value' which will hold the values of the list items; the other called 'text' containing the text in the drop-down list." +JLIB_FORM_FIELD_PARAM_SQL_QUERY_LABEL="Query" + +JLIB_FORM_FIELD_PARAM_TEXTAREA_COLS_DESC="The number of columns of the field." +JLIB_FORM_FIELD_PARAM_TEXTAREA_COLS_LABEL="Columns" +JLIB_FORM_FIELD_PARAM_TEXTAREA_ROWS_DESC="The number of rows of the field." +JLIB_FORM_FIELD_PARAM_TEXTAREA_ROWS_LABEL="Rows" + +JLIB_FORM_FIELD_PARAM_URL_RELATIVE_DESC="Are relative URLs allowed." +JLIB_FORM_FIELD_PARAM_URL_RELATIVE_LABEL="Relative" +JLIB_FORM_FIELD_PARAM_URL_SCHEMES_DESC="The allowed schemes." +JLIB_FORM_FIELD_PARAM_URL_SCHEMES_LABEL="Schemes" diff --git a/administrator/language/en-GB/en-GB.mod_feed.ini b/administrator/language/en-GB/en-GB.mod_feed.ini index c0a6019b15a81..a48f21b8e5526 100644 --- a/administrator/language/en-GB/en-GB.mod_feed.ini +++ b/administrator/language/en-GB/en-GB.mod_feed.ini @@ -7,20 +7,11 @@ MOD_FEED="Feed Display" MOD_FEED_ERR_CACHE="Please make cache folder writable." MOD_FEED_ERR_NO_URL="No feed URL specified." MOD_FEED_ERR_FEED_NOT_RETRIEVED="Feed not found." -MOD_FEED_FIELD_DESCRIPTION_DESC="Show the description text for the whole Feed." MOD_FEED_FIELD_DESCRIPTION_LABEL="Feed Description" -MOD_FEED_FIELD_IMAGE_DESC="Show the image associated with the whole feed." MOD_FEED_FIELD_IMAGE_LABEL="Feed Image" -MOD_FEED_FIELD_ITEMDESCRIPTION_DESC="Show the Description or Intro text of individual RSS Items." MOD_FEED_FIELD_ITEMDESCRIPTION_LABEL="Item Description" -MOD_FEED_FIELD_ITEMS_DESC="Enter number of RSS items to display." -MOD_FEED_FIELD_ITEMS_LABEL="Items" -MOD_FEED_FIELD_RSSTITLE_DESC="Display news feed title." +MOD_FEED_FIELD_ITEMS_LABEL="Items to Display" MOD_FEED_FIELD_RSSTITLE_LABEL="Feed Title" -MOD_FEED_FIELD_RSSURL_DESC="Enter the URL of the RSS/RDF/ATOM feed." MOD_FEED_FIELD_RSSURL_LABEL="Feed URL" -MOD_FEED_FIELD_RTL_DESC="Display feed in RTL direction." MOD_FEED_FIELD_RTL_LABEL="RTL Feed" -MOD_FEED_FIELD_WORDCOUNT_DESC="Allows you to limit the amount of visible Item description text. 0 will show all the text." -MOD_FEED_FIELD_WORDCOUNT_LABEL="Word Count" MOD_FEED_XML_DESCRIPTION="This module allows the displaying of a syndicated feed." diff --git a/administrator/language/en-GB/en-GB.mod_feed.sys.ini b/administrator/language/en-GB/en-GB.mod_feed.sys.ini index 56b6f497f327e..506dc3a26cb55 100644 --- a/administrator/language/en-GB/en-GB.mod_feed.sys.ini +++ b/administrator/language/en-GB/en-GB.mod_feed.sys.ini @@ -6,4 +6,3 @@ MOD_FEED="Feed Display" MOD_FEED_XML_DESCRIPTION="This module allows the displaying of a syndicated feed." MOD_FEED_LAYOUT_DEFAULT="Default" - diff --git a/administrator/language/en-GB/en-GB.mod_latest.ini b/administrator/language/en-GB/en-GB.mod_latest.ini index 5da22a713e087..7dddc749d21ae 100644 --- a/administrator/language/en-GB/en-GB.mod_latest.ini +++ b/administrator/language/en-GB/en-GB.mod_latest.ini @@ -6,12 +6,8 @@ MOD_LATEST="Articles - Latest" MOD_LATEST_CREATED="Created" MOD_LATEST_CREATED_BY="Created By" -MOD_LATEST_FIELD_AUTHORS_DESC="A filter for the authors." MOD_LATEST_FIELD_AUTHORS_LABEL="Authors" -MOD_LATEST_FIELD_CATEGORY_DESC="Select Articles from a specific Category or all Categories." -MOD_LATEST_FIELD_COUNT_DESC="The number of items to display (default 5)." -MOD_LATEST_FIELD_COUNT_LABEL="Count" -MOD_LATEST_FIELD_ORDERING_DESC="Ordering options." +MOD_LATEST_FIELD_COUNT_LABEL="Items to Display" MOD_LATEST_FIELD_ORDERING_LABEL="Order" MOD_LATEST_FIELD_VALUE_AUTHORS_ANYONE="Anyone" MOD_LATEST_FIELD_VALUE_AUTHORS_BY_ME="Added or modified by me" diff --git a/administrator/language/en-GB/en-GB.mod_logged.ini b/administrator/language/en-GB/en-GB.mod_logged.ini index feb38d336d420..825a2a16d7ceb 100644 --- a/administrator/language/en-GB/en-GB.mod_logged.ini +++ b/administrator/language/en-GB/en-GB.mod_logged.ini @@ -5,15 +5,11 @@ MOD_LOGGED="Logged-in Users" -MOD_LOGGED_ADMINISTRATOR="Administrator" -MOD_LOGGED_EDIT_USER="Edit user" -MOD_LOGGED_FIELD_COUNT_DESC="The number of items to display (default 5)." -MOD_LOGGED_FIELD_COUNT_LABEL="Count" -MOD_LOGGED_FIELD_NAME_DESC="Displays name or username." +MOD_LOGGED_FIELD_COUNT_LABEL="Users to Display" MOD_LOGGED_LAST_ACTIVITY="Last Activity" MOD_LOGGED_LOGOUT="Logout" MOD_LOGGED_NAME="Name" -MOD_LOGGED_SITE="Site" +MOD_LOGGED_NO_SESSION_METADATA="Session metadata is disabled, cannot display the list of logged-in users." MOD_LOGGED_TITLE="Last Logged-in Users" MOD_LOGGED_TITLE_1="Last Logged-in User" MOD_LOGGED_TITLE_MORE="Last %s Logged-in Users" diff --git a/administrator/language/en-GB/en-GB.mod_login.ini b/administrator/language/en-GB/en-GB.mod_login.ini index 704896ed23229..365ea688e1515 100644 --- a/administrator/language/en-GB/en-GB.mod_login.ini +++ b/administrator/language/en-GB/en-GB.mod_login.ini @@ -4,10 +4,8 @@ ; Note : All ini files need to be saved as UTF-8 MOD_LOGIN="Login Form" -MOD_LOGIN_FIELD_USESECURE_DESC="Submit encrypted login data using HTTPS (encrypted HTTP connections with the https:// protocol prefix). Note, you must have HTTPS enabled on your server to utilise this option." -MOD_LOGIN_FIELD_USESECURE_LABEL="Encrypt Login Form" MOD_LOGIN_LANGUAGE="Language" -MOD_LOGIN_LOGIN="Log in" +MOD_LOGIN_LOGIN_TITLE="Administrator Log In" MOD_LOGIN_XML_DESCRIPTION="This module displays a username and password login form. It should not be unpublished." MOD_LOGIN_REMIND="Forgot your username?" MOD_LOGIN_RESET="Forgot your password?" diff --git a/administrator/language/en-GB/en-GB.mod_menu.ini b/administrator/language/en-GB/en-GB.mod_menu.ini index df62a5794cc8b..ec1353fda9516 100644 --- a/administrator/language/en-GB/en-GB.mod_menu.ini +++ b/administrator/language/en-GB/en-GB.mod_menu.ini @@ -9,14 +9,13 @@ MOD_MENU_COMPONENTS="Components" MOD_MENU_COM_CONTENT="Content" MOD_MENU_COM_CONTENT_ARTICLE_MANAGER="Articles" MOD_MENU_COM_CONTENT_CATEGORY_MANAGER="Categories" +MOD_MENU_COM_CONTENT_WORKFLOW_MANAGER="Workflows" MOD_MENU_COM_CONTENT_FEATURED="Featured Articles" MOD_MENU_COM_CONTENT_NEW_ARTICLE="Add New Article" MOD_MENU_COM_CONTENT_NEW_CATEGORY="Add New Category" MOD_MENU_COM_LANGUAGES_SUBMENU_CONTENT="Content Languages" MOD_MENU_COM_LANGUAGES_SUBMENU_INSTALLED="Installed" MOD_MENU_COM_LANGUAGES_SUBMENU_OVERRIDES="Overrides" -MOD_MENU_COM_TEMPLATES_SUBMENU_STYLES="Styles" -MOD_MENU_COM_TEMPLATES_SUBMENU_TEMPLATES="Templates" MOD_MENU_COM_USERS="Users" MOD_MENU_COM_USERS_ADD_GROUP="Add New Group" MOD_MENU_COM_USERS_ADD_LEVEL="Add New Access Level" @@ -28,48 +27,43 @@ MOD_MENU_COM_USERS_USER_MANAGER="Manage" MOD_MENU_COM_USERS_ADD_NOTE="Add User Note" MOD_MENU_COM_USERS_NOTES="User Notes" MOD_MENU_COM_USERS_NOTE_CATEGORIES="User Note Categories" +MOD_MENU_FIELDS="Fields" +MOD_MENU_FIELDS_GROUP="Field Groups" MOD_MENU_CONFIGURATION="Global Configuration" MOD_MENU_CONTROL_PANEL="Control Panel" MOD_MENU_EXTENSIONS_EXTENSIONS="Extensions" MOD_MENU_EXTENSIONS_EXTENSION_MANAGER="Manage" MOD_MENU_EXTENSIONS_LANGUAGE_MANAGER="Language(s)" -MOD_MENU_EXTENSIONS_MODULE_MANAGER="Modules" +MOD_MENU_EXTENSIONS_MODULE_MANAGER_SITE="Site Modules" +MOD_MENU_EXTENSIONS_MODULE_MANAGER_ADMINISTRATOR="Administrator Modules" MOD_MENU_EXTENSIONS_PLUGIN_MANAGER="Plugins" -MOD_MENU_EXTENSIONS_TEMPLATE_MANAGER="Templates" MOD_MENU_FIELD_CHECK_DESC="Check for the presence of important menu items." MOD_MENU_FIELD_CHECK_LABEL="Check Menu" -MOD_MENU_FIELD_FORUMURL_DESC="Enter the URL to a forum other than the default." -MOD_MENU_FIELD_FORUMURL_LABEL="Custom Support Forum" +MOD_MENU_FIELD_FORUMURL_LABEL="Custom Support Forum URL" MOD_MENU_FIELD_MENUTYPE_LABEL="Menu to Show" -MOD_MENU_FIELD_MENUTYPE_DESC="Choose which menu should be rendered with this instance of module." MOD_MENU_FIELD_MENUTYPE_OPTION_PREDEFINED="Use a Preset" MOD_MENU_FIELD_PRESET_LABEL="Choose Preset" MOD_MENU_FIELD_PRESET_DESC="Choose a preset to use as the backend menu" MOD_MENU_FIELD_SHOWHELP="Help Menu" -MOD_MENU_FIELD_SHOWHELP_DESC="Show or hide the Help menu which includes links to various joomla.org sites useful to users." MOD_MENU_FIELD_SHOWNEW="Add New Shortcuts" -MOD_MENU_FIELD_SHOWNEW_DESC="Show or hide various 'Add New ...' shortcuts against users, groups, access levels, articles and categories." -MOD_MENU_FIELDS="Fields" -MOD_MENU_FIELDS_GROUP="Field Groups" MOD_MENU_GLOBAL_CHECKIN="Global Check-in" MOD_MENU_HELP="Help" MOD_MENU_HELP_COMMUNITY="Community Portal" -MOD_MENU_HELP_CURRENT="Help with this page" MOD_MENU_HELP_DEVELOPER="Developer Resources" MOD_MENU_HELP_DOCUMENTATION="Documentation Wiki" MOD_MENU_HELP_EXTENSIONS="Joomla! Extensions" MOD_MENU_HELP_JOOMLA="Joomla! Help" -MOD_MENU_HELP_LINKS="Useful Joomla! links" MOD_MENU_HELP_RESOURCES="Joomla! Resources" MOD_MENU_HELP_SECURITY="Security Centre" MOD_MENU_HELP_SHOP="Joomla! Shop" MOD_MENU_HELP_SUPPORT_OFFICIAL_FORUM="Official Support Forum" +MOD_MENU_TOGGLE_MENU="Toggle Menu" ; the string below will be used if the localised sample data has a URL for the desired community forum or if the 'Custom Support Forum' field parameter in the Administrator Menu module has a URL MOD_MENU_HELP_SUPPORT_CUSTOM_FORUM="Custom Support Forum" ; Enter in the string below the # of the specific language forum in https://forum.joomla.org/ (example: 19 for French). If left empty, it will use '511' which is the section for all languages forums. MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM_VALUE="511" -; If you have chosen to display in the string above the section for all languages, translate the string below. -; If you have displayed the specific language forum, use something like "Official French Forum" in your language. +; If you have chosen to display in the string above the section for all languages, translate the string below. +; If you have displayed the specific language forum, use something like "Official French Forum" in your language. MOD_MENU_HELP_SUPPORT_OFFICIAL_LANGUAGE_FORUM="Official Language Forums" MOD_MENU_HELP_TRANSLATIONS="Joomla! Translations" MOD_MENU_HELP_XCHANGE="Stack Exchange" @@ -80,9 +74,6 @@ MOD_MENU_IMPORTANT_ITEM_MODULE_MANAGER="Module Manager" MOD_MENU_IMPORTANT_ITEM_COMPONENTS_CONTAINER="Components Container" MOD_MENU_IMPORTANT_ITEMS_INACCESSIBLE_LIST_WARNING="The administrator menu %1$s does not have - %2$s. Select to turn on the menu recovery mode." MOD_MENU_INSTALLER_SUBMENU_DATABASE="Database" -MOD_MENU_INSTALLER_SUBMENU_DISCOVER="Discover" -MOD_MENU_INSTALLER_SUBMENU_INSTALL="Install" -MOD_MENU_INSTALLER_SUBMENU_LANGUAGES="Install Languages" MOD_MENU_INSTALLER_SUBMENU_MANAGE="Manage" MOD_MENU_INSTALLER_SUBMENU_UPDATE="Update" MOD_MENU_INSTALLER_SUBMENU_UPDATESITES="Update Sites" @@ -95,15 +86,45 @@ MOD_MENU_MENUS_ALL_ITEMS="All Menu Items" MOD_MENU_MENU_MANAGER="Manage" MOD_MENU_MENU_MANAGER_NEW_MENU="Add New Menu" MOD_MENU_MENU_MANAGER_NEW_MENU_ITEM="Add New Menu Item" -MOD_MENU_NEW_PRIVATE_MESSAGE="New Private Message" MOD_MENU_PURGE_EXPIRED_CACHE="Clear Expired Cache" MOD_MENU_READ_PRIVATE_MESSAGES="Read Private Messages" MOD_MENU_RECOVERY_EXIT="Exit Recovery Mode" MOD_MENU_RECOVERY_MENU_ROOT="Menu Recovery" MOD_MENU_SETTINGS="Settings" -MOD_MENU_MAINTENANCE="Maintenance" MOD_MENU_SYSTEM_INFORMATION="System Information" -MOD_MENU_SYSTEM="System" -MOD_MENU_TOOLS="Tools" MOD_MENU_USER_PROFILE="My Profile" MOD_MENU_XML_DESCRIPTION="This module displays an administrator menu module." +MOD_MENU_COM_CONTENT_WORKFLOW="Workflows" +MOD_MENU_SYSTEM="System" +MOD_MENU_INSTALL="Install" +MOD_MENU_TEMPLATES="Templates" +MOD_MENU_ACCESS="Access" +MOD_MENU_MAINTAIN="Maintain" +MOD_MENU_MANAGE="Manage" +MOD_MENU_INFORMATION="Information" +MOD_MENU_UPDATE="Update" +MOD_MENU_INSTALL_EXTENSIONS="Extensions" +MOD_MENU_INSTALL_LANGUAGES="Install Languages" +MOD_MENU_INSTALL_DISCOVER="Discover" +MOD_MENU_TEMPLATE_SITE_TEMPLATES="Site Templates" +MOD_MENU_TEMPLATE_SITE_STYLES="Site Template Styles" +MOD_MENU_TEMPLATE_ADMIN_STYLES="Administrator Template Styles" +MOD_MENU_TEMPLATE_ADMIN_TEMPLATES="Administrator Templates" +MOD_MENU_ACCESS_GROUPS="Groups" +MOD_MENU_ACCESS_LEVELS="Levels" +MOD_MENU_ACCESS_SETTINGS="Settings" +MOD_MENU_ACCESS_TEXT_FILTERS="Text Filters" +MOD_MENU_MANAGE_CSP="Content Security Policy" +MOD_MENU_MANAGE_EXTENSIONS="Extensions" +MOD_MENU_MANAGE_LANGUAGES="Language(s)" +MOD_MENU_MANAGE_LANGUAGES_CONTENT="Content Language(s)" +MOD_MENU_MANAGE_LANGUAGES_OVERRIDES="Language Overrides" +MOD_MENU_MANAGE_PLUGINS="Plugins" +MOD_MENU_MANAGE_REDIRECTS="Redirects" +MOD_MENU_INFORMATION_WARNINGS="Warnings" +MOD_MENU_INFORMATION_POST_INSTALL_MESSAGES="Installation Messages" +MOD_MENU_SYSTEM_INFORMATION_SYSINFO="System Information" +MOD_MENU_SYSTEM_INFORMATION_DATABASE="Database" +MOD_MENU_UPDATE_JOOMLA="Joomla" +MOD_MENU_UPDATE_EXTENSIONS="Extensions" +MOD_MENU_UPDATE_SOURCES="Update Sources" diff --git a/administrator/language/en-GB/en-GB.mod_popular.ini b/administrator/language/en-GB/en-GB.mod_popular.ini index dc0d100bcc6f3..e43c8f0189314 100644 --- a/administrator/language/en-GB/en-GB.mod_popular.ini +++ b/administrator/language/en-GB/en-GB.mod_popular.ini @@ -5,11 +5,8 @@ MOD_POPULAR="Popular Articles" MOD_POPULAR_CREATED="Created" -MOD_POPULAR_FIELD_AUTHORS_DESC="A filter for the Authors." MOD_POPULAR_FIELD_AUTHORS_LABEL="Authors" -MOD_POPULAR_FIELD_CATEGORY_DESC="Select Articles from a specific Category or all Categories." -MOD_POPULAR_FIELD_COUNT_DESC="The number of items to display (default 5)." -MOD_POPULAR_FIELD_COUNT_LABEL="Count" +MOD_POPULAR_FIELD_COUNT_LABEL="Items to Display" MOD_POPULAR_FIELD_VALUE_ADDED_OR_MODIFIED_BY_ME="Added or modified by me" MOD_POPULAR_FIELD_VALUE_ANYONE="Anyone" MOD_POPULAR_FIELD_VALUE_NOT_ADDED_OR_MODIFIED_BY_ME="Not added or modified by me" diff --git a/administrator/language/en-GB/en-GB.mod_quickicon.ini b/administrator/language/en-GB/en-GB.mod_quickicon.ini index 9815084ff2d49..b255daae67b04 100644 --- a/administrator/language/en-GB/en-GB.mod_quickicon.ini +++ b/administrator/language/en-GB/en-GB.mod_quickicon.ini @@ -7,15 +7,12 @@ MOD_QUICKICON="Quick Icons" MOD_QUICKICON_ADD_NEW_ARTICLE="New Article" MOD_QUICKICON_ARTICLE_MANAGER="Articles" MOD_QUICKICON_CATEGORY_MANAGER="Categories" -MOD_QUICKICON_CLEAR_CACHE="Clear Cache" MOD_QUICKICON_CONFIGURATION="Configuration" MOD_QUICKICON_CONTENT="Content" MOD_QUICKICON_EXTENSIONS="Extensions" MOD_QUICKICON_EXTENSION_MANAGER="Extension Manager" -MOD_QUICKICON_FRONTPAGE_MANAGER="Front Page Manager" -MOD_QUICKICON_GLOBAL_CHECKIN="Global Check-in" MOD_QUICKICON_GLOBAL_CONFIGURATION="Global" -MOD_QUICKICON_GROUP_DESC="The group of this module (this value is compared with the group value used in Quick Icons plugins to inject icons). The 'mod_quickicon' group always displays the Joomla! core icons." +MOD_QUICKICON_GROUP_DESC="The group of this module (this value is compared with the group value used in Quick Icons plugins to inject icons). The 'mod_quickicon' group always displays the Joomla! core icons." MOD_QUICKICON_GROUP_LABEL="Group" MOD_QUICKICON_INSTALL_EXTENSIONS="Install Extensions" MOD_QUICKICON_LANGUAGE_MANAGER="Language(s)" @@ -23,11 +20,8 @@ MOD_QUICKICON_MAINTENANCE="Maintenance" MOD_QUICKICON_MEDIA_MANAGER="Media" MOD_QUICKICON_MENU_MANAGER="Menu(s)" MOD_QUICKICON_MODULE_MANAGER="Modules" -MOD_QUICKICON_PROFILE="Edit Profile" MOD_QUICKICON_STRUCTURE="Structure" -MOD_QUICKICON_SYSTEM_INFORMATION="System Information" MOD_QUICKICON_TEMPLATE_MANAGER="Templates" -MOD_QUICKICON_TITLE="Quick Icons" MOD_QUICKICON_USER_MANAGER="Users" MOD_QUICKICON_USERS="Users" MOD_QUICKICON_XML_DESCRIPTION="This module shows Quick Icons that are visible on the Control Panel (administrator area home page)." diff --git a/administrator/language/en-GB/en-GB.mod_sampledata.ini b/administrator/language/en-GB/en-GB.mod_sampledata.ini index 84829ace15b65..7030605f372b6 100644 --- a/administrator/language/en-GB/en-GB.mod_sampledata.ini +++ b/administrator/language/en-GB/en-GB.mod_sampledata.ini @@ -7,4 +7,5 @@ MOD_SAMPLEDATA="Sample Data" MOD_SAMPLEDATA_CONFIRM_START="Proceeding will install a sample data set into your Joomla website. This process can't be reverted once done." MOD_SAMPLEDATA_INVALID_RESPONSE="There is an error in the sample data plugins. Response is invalid." MOD_SAMPLEDATA_ITEM_ALREADY_PROCESSED="This sample data set is already installed." +MOD_SAMPLEDATA_NOTAVAILABLE="Sample data can't be installed or no sample data available." MOD_SAMPLEDATA_XML_DESCRIPTION="This Module allows to install sample data." diff --git a/administrator/language/en-GB/en-GB.mod_stats_admin.ini b/administrator/language/en-GB/en-GB.mod_stats_admin.ini index 477ecf7bda0f9..a3c4782fbe80d 100644 --- a/administrator/language/en-GB/en-GB.mod_stats_admin.ini +++ b/administrator/language/en-GB/en-GB.mod_stats_admin.ini @@ -7,16 +7,11 @@ MOD_STATS_ADMIN="Statistics" MOD_STATS_ARTICLES="Articles" MOD_STATS_ARTICLES_VIEW_HITS="Articles View Hits" MOD_STATS_CACHING="Caching" -MOD_STATS_FIELD_COUNTER_DESC="Display hit counter." MOD_STATS_FIELD_COUNTER_LABEL="Hit Counter" -MOD_STATS_FIELD_INCREASECOUNTER_DESC="Enter the number of hits to increase the counter by." MOD_STATS_FIELD_INCREASECOUNTER_LABEL="Increase Counter" -MOD_STATS_FIELD_SERVERINFO_DESC="Display server information." MOD_STATS_FIELD_SERVERINFO_LABEL="Server Information" -MOD_STATS_FIELD_SITEINFO_DESC="Display site information." MOD_STATS_FIELD_SITEINFO_LABEL="Site Information" MOD_STATS_GZIP="Gzip" -MOD_STATS_MYSQL="MySQL" MOD_STATS_OS="OS" MOD_STATS_PHP="PHP" MOD_STATS_TIME="Time" diff --git a/administrator/language/en-GB/en-GB.mod_status.ini b/administrator/language/en-GB/en-GB.mod_status.ini index aac0da98a5e1a..468884337e67b 100644 --- a/administrator/language/en-GB/en-GB.mod_status.ini +++ b/administrator/language/en-GB/en-GB.mod_status.ini @@ -7,27 +7,16 @@ MOD_STATUS="User Status" MOD_STATUS_BACKEND_USERS_0="Administrators" MOD_STATUS_BACKEND_USERS_1="Administrator" MOD_STATUS_BACKEND_USERS_MORE="Administrators" -MOD_STATUS_FIELD_SHOW_VIEWSITE_LABEL="View Site" -MOD_STATUS_FIELD_SHOW_VIEWSITE_DESC="Show a link to the website home page." -MOD_STATUS_FIELD_LINK_VIEWADMIN_LABEL="Show Admin" -MOD_STATUS_FIELD_SHOW_VIEWADMIN_LABEL="View Administrator" -MOD_STATUS_FIELD_SHOW_VIEWADMIN_DESC="Show a link to open a new Administrator window." -MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_ADMIN_DESC="Show the number of users logged-in to the Backend." +MOD_STATUS_EDIT_ACCOUNT="Edit Account" MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_ADMIN_LABEL="Logged-in Backend Users" -MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_DESC="Show the number of users logged-in to the Frontend." MOD_STATUS_FIELD_SHOW_LOGGEDIN_USERS_LABEL="Logged-in Users" -MOD_STATUS_FIELD_SHOW_MESSAGES_DESC="Show the messages count for the current user's inbox." -MOD_STATUS_FIELD_SHOW_MESSAGES_LABEL="Messages" -MOD_STATUS_LOG_OUT="Log out" -MOD_STATUS_MESSAGES_0="%d Messages" -MOD_STATUS_MESSAGES_1="%d Message" -MOD_STATUS_MESSAGES_LABEL_0="Messages" -MOD_STATUS_MESSAGES_LABEL_1="Message" -MOD_STATUS_MESSAGES_LABEL_MORE="Messages" -MOD_STATUS_MESSAGES_MORE="%d Messages" +MOD_STATUS_POST_INSTALLATION_MESSAGES="Post-installation messages" +MOD_STATUS_PREVIEW="Preview %s" +MOD_STATUS_PRIVATE_MESSAGES="Private Messages" MOD_STATUS_TOTAL_USERS_0="Users" MOD_STATUS_TOTAL_USERS_1="User" MOD_STATUS_TOTAL_USERS_MORE="Users" +MOD_STATUS_USER_MENU="User Menu" MOD_STATUS_USERS_0="Visitors" MOD_STATUS_USERS_1="Visitor" MOD_STATUS_USERS_MORE="Visitors" diff --git a/administrator/language/en-GB/en-GB.mod_submenu.ini b/administrator/language/en-GB/en-GB.mod_submenu.ini deleted file mode 100644 index e11bf776e14b6..0000000000000 --- a/administrator/language/en-GB/en-GB.mod_submenu.ini +++ /dev/null @@ -1,8 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -MOD_SUBMENU="Administrator Sub-Menu" -MOD_SUBMENU_XML_DESCRIPTION="This module shows the Sub-Menu Navigation Module." - diff --git a/administrator/language/en-GB/en-GB.mod_submenu.sys.ini b/administrator/language/en-GB/en-GB.mod_submenu.sys.ini deleted file mode 100644 index 639dffb27d6e1..0000000000000 --- a/administrator/language/en-GB/en-GB.mod_submenu.sys.ini +++ /dev/null @@ -1,9 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -MOD_SUBMENU="Administrator Sub-Menu" -MOD_SUBMENU_XML_DESCRIPTION="This module shows the Sub-Menu Navigation Module." -MOD_SUBMENU_LAYOUT_DEFAULT="Default" - diff --git a/administrator/language/en-GB/en-GB.mod_version.ini b/administrator/language/en-GB/en-GB.mod_version.ini index 7eb188129c335..79bea5d9f3985 100644 --- a/administrator/language/en-GB/en-GB.mod_version.ini +++ b/administrator/language/en-GB/en-GB.mod_version.ini @@ -4,10 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 MOD_VERSION="Joomla! Version Information" -MOD_VERSION_FORMAT_DESC="The long version includes code name and date." -MOD_VERSION_FORMAT_LABEL="Version Format" -MOD_VERSION_FORMAT_LONG="Long" -MOD_VERSION_FORMAT_SHORT="Short" -MOD_VERSION_PRODUCT_DESC="Include the text "Joomla!"." -MOD_VERSION_PRODUCT_LABEL="Show Joomla!" MOD_VERSION_XML_DESCRIPTION="This module displays the Joomla! version." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini b/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini index 8d02e7fe9fbf7..7e7b85f0491a6 100644 --- a/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini +++ b/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini @@ -3,11 +3,8 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 -PLG_AUTH_COOKIE_ERROR_LOG_INVALIDATED_COOKIES="The authentication tokens were invalidated for user %u because there was no matching record." PLG_AUTH_COOKIE_ERROR_LOG_LOGIN_FAILED="Cookie login failed for user %u." -PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_DESC="The number of days until the authentication cookie will expire. Other factors may cause it to expire before this. Longer lengths are less secure." -PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_LABEL="Cookie Lifetime" -PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_DESC="The length of the key to use to encrypt the cookie. Longer lengths are more secure, but they will slow performance." +PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_LABEL="Cookie Lifetime (days)" PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_LABEL="Key Length" -PLG_AUTH_COOKIE_XML_DESCRIPTION="Handles Joomla's cookie User authentication.
    Warning! You must have at least one other authentication plugin enabled.
    You will also need a plugin such as the System - Remember Me plugin to implement cookie login." +PLG_AUTH_COOKIE_XML_DESCRIPTION="Handles Joomla's cookie User authentication.
    Warning! You must have at least one other authentication plugin enabled.
    You will also need a plugin such as the System - Remember Me plugin to implement cookie login." PLG_AUTHENTICATION_COOKIE="Authentication - Cookie" diff --git a/administrator/language/en-GB/en-GB.plg_authentication_cookie.sys.ini b/administrator/language/en-GB/en-GB.plg_authentication_cookie.sys.ini index d2c3ea89c2887..6785e69a44071 100644 --- a/administrator/language/en-GB/en-GB.plg_authentication_cookie.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_authentication_cookie.sys.ini @@ -3,5 +3,5 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 -PLG_AUTH_COOKIE_XML_DESCRIPTION="Handles Joomla's cookie User authentication.
    Warning! You must have at least one other authentication plugin enabled.
    You will also need a plugin such as the System - Remember Me plugin to implement cookie login." +PLG_AUTH_COOKIE_XML_DESCRIPTION="Handles Joomla's cookie User authentication.
    Warning! You must have at least one other authentication plugin enabled.
    You will also need a plugin such as the System - Remember Me plugin to implement cookie login." PLG_AUTHENTICATION_COOKIE="Authentication - Cookie" diff --git a/administrator/language/en-GB/en-GB.plg_authentication_gmail.ini b/administrator/language/en-GB/en-GB.plg_authentication_gmail.ini deleted file mode 100644 index c1fa6dfd446cd..0000000000000 --- a/administrator/language/en-GB/en-GB.plg_authentication_gmail.ini +++ /dev/null @@ -1,22 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -PLG_AUTHENTICATION_GMAIL="Authentication - Gmail" -PLG_GMAIL_ERROR_ACCOUNT_DISABLED_OR_NOT_ACTIVATED="Your local account is disabled or not activated." -PLG_GMAIL_ERROR_LOCAL_USERNAME_CONFLICT="A local username conflicts with your Gmail username." -PLG_GMAIL_FIELD_APPLYSUFFIX_DESC="Options for applying the suffix: Don't apply the suffix, only apply the suffix if missing (any user supplied suffix will be used) or always apply the suffix replacing any user supplied suffix." -PLG_GMAIL_FIELD_APPLYSUFFIX_LABEL="Apply Username Suffix" -PLG_GMAIL_FIELD_BACKEND_LOGIN_DESC="Allow Backend login via Gmail account?" -PLG_GMAIL_FIELD_BACKEND_LOGIN_LABEL="Backend Login" -PLG_GMAIL_FIELD_SUFFIX_DESC="A suffix to use for the username, typically gmail.com (or googlemail.com) is the suffix but you may wish to use a Google Apps for Your Domain suffix, this doesn't include the @ symbol. If left blank username suffix will be ignored." -PLG_GMAIL_FIELD_SUFFIX_LABEL="Username Suffix" -PLG_GMAIL_FIELD_USER_BLACKLIST_DESC="A list of usernames not permitted to log in via the Gmail plugin. The usernames should be separated by a comma." -PLG_GMAIL_FIELD_USER_BLACKLIST_LABEL="User Blacklist" -PLG_GMAIL_FIELD_VALUE_APPLYSUFFIXALWAYS="Always use suffix" -PLG_GMAIL_FIELD_VALUE_APPLYSUFFIXMISSING="Apply suffix if missing" -PLG_GMAIL_FIELD_VALUE_NOAPPLYSUFFIX="Don't Apply Suffix" -PLG_GMAIL_FIELD_VERIFYPEER_DESC="Verify the peer connection using a CA certificate. In some situations authentication will fail due to certificate issues, disabling this should resolve the situation in that case." -PLG_GMAIL_FIELD_VERIFYPEER_LABEL="Verify Peer" -PLG_GMAIL_XML_DESCRIPTION="Handles User Authentication with a Gmail or Googlemail account (Requires cURL).
    Users may need to enable Access for less secure apps at https://www.google.com/settings/security/lesssecureapps to be able to log in using this method.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_authentication_gmail.sys.ini b/administrator/language/en-GB/en-GB.plg_authentication_gmail.sys.ini deleted file mode 100644 index 530998b1b5a9c..0000000000000 --- a/administrator/language/en-GB/en-GB.plg_authentication_gmail.sys.ini +++ /dev/null @@ -1,7 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -PLG_AUTHENTICATION_GMAIL="Authentication - Gmail" -PLG_GMAIL_XML_DESCRIPTION="Handles User Authentication with a Gmail or Googlemail account (Requires cURL).
    Users may need to enable Access for less secure apps at https://www.google.com/settings/security/lesssecureapps to be able to log in using this method.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." diff --git a/administrator/language/en-GB/en-GB.plg_authentication_joomla.ini b/administrator/language/en-GB/en-GB.plg_authentication_joomla.ini index ea9741ff0f3ad..f7ad2450c3cf0 100644 --- a/administrator/language/en-GB/en-GB.plg_authentication_joomla.ini +++ b/administrator/language/en-GB/en-GB.plg_authentication_joomla.ini @@ -4,5 +4,5 @@ ; Note : All ini files need to be saved as UTF-8 PLG_AUTH_JOOMLA_ERR_SECRET_CODE_WITHOUT_TFA="You need to enable two factor authentication in your user profile to use the secret code field." -PLG_AUTH_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User authentication.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." -PLG_AUTHENTICATION_JOOMLA="Authentication - Joomla" \ No newline at end of file +PLG_AUTH_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User authentication.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." +PLG_AUTHENTICATION_JOOMLA="Authentication - Joomla" diff --git a/administrator/language/en-GB/en-GB.plg_authentication_joomla.sys.ini b/administrator/language/en-GB/en-GB.plg_authentication_joomla.sys.ini index 9932218416a93..9ed5f0597a519 100644 --- a/administrator/language/en-GB/en-GB.plg_authentication_joomla.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_authentication_joomla.sys.ini @@ -3,5 +3,5 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 -PLG_AUTH_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User authentication.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." -PLG_AUTHENTICATION_JOOMLA="Authentication - Joomla" \ No newline at end of file +PLG_AUTH_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User authentication.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." +PLG_AUTHENTICATION_JOOMLA="Authentication - Joomla" diff --git a/administrator/language/en-GB/en-GB.plg_authentication_ldap.ini b/administrator/language/en-GB/en-GB.plg_authentication_ldap.ini index fc16bfe8527b4..d7717d4bba34b 100644 --- a/administrator/language/en-GB/en-GB.plg_authentication_ldap.ini +++ b/administrator/language/en-GB/en-GB.plg_authentication_ldap.ini @@ -4,21 +4,16 @@ ; Note : All ini files need to be saved as UTF-8 PLG_AUTHENTICATION_LDAP="Authentication - LDAP" -PLG_LDAP_FIELD_AUTHMETHOD_DESC="The authorisation method to validate the credentials." PLG_LDAP_FIELD_AUTHMETHOD_LABEL="Authorisation Method" -PLG_LDAP_FIELD_BASEDN_DESC="The base DN of your LDAP server, eg o=example.com." PLG_LDAP_FIELD_BASEDN_LABEL="Base DN" PLG_LDAP_FIELD_EMAIL_DESC="LDAP attribute which has the User's email address." PLG_LDAP_FIELD_EMAIL_LABEL="Map: Email" PLG_LDAP_FIELD_FULLNAME_DESC="LDAP attribute which has the User's full name." PLG_LDAP_FIELD_FULLNAME_LABEL="Map: Full Name" -PLG_LDAP_FIELD_HOST_DESC="Eg: openldap.example.com." PLG_LDAP_FIELD_HOST_LABEL="Host" -PLG_LDAP_FIELD_NEGOCIATE_DESC="Negotiate TLS encryption with the LDAP server. This requires all traffic to and from the LDAP server to be encrypted." PLG_LDAP_FIELD_NEGOCIATE_LABEL="Negotiate TLS" PLG_LDAP_FIELD_PASSWORD_DESC="The Connect Password is the password of an administrative account. This is used in Authenticate then Bind and Authenticated Compare authorisation methods." PLG_LDAP_FIELD_PASSWORD_LABEL="Connect Password" -PLG_LDAP_FIELD_PORT_DESC="Default port is 389." PLG_LDAP_FIELD_PORT_LABEL="Port" PLG_LDAP_FIELD_REFERRALS_DESC="This option sets the value of the LDAP_OPT_REFERRALS flag. You will need to set it to No for Windows 2003 servers." PLG_LDAP_FIELD_REFERRALS_LABEL="Follow Referrals" @@ -34,4 +29,4 @@ PLG_LDAP_FIELD_V3_DESC="Default is LDAP2, but the latest versions of OpenLdap re PLG_LDAP_FIELD_V3_LABEL="LDAP V3" PLG_LDAP_FIELD_VALUE_BINDSEARCH="Bind and Search" PLG_LDAP_FIELD_VALUE_BINDUSER="Bind Directly as User" -PLG_LDAP_XML_DESCRIPTION="Handles User Authentication against an LDAP server.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." +PLG_LDAP_XML_DESCRIPTION="Handles User Authentication against an LDAP server.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." diff --git a/administrator/language/en-GB/en-GB.plg_authentication_ldap.sys.ini b/administrator/language/en-GB/en-GB.plg_authentication_ldap.sys.ini index 795bd6f29e6b8..d205bfd121d60 100644 --- a/administrator/language/en-GB/en-GB.plg_authentication_ldap.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_authentication_ldap.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_AUTHENTICATION_LDAP="Authentication - LDAP" -PLG_LDAP_XML_DESCRIPTION="Handles User Authentication against an LDAP server.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." +PLG_LDAP_XML_DESCRIPTION="Handles User Authentication against an LDAP server.
    Warning! You must have at least one authentication plugin enabled or you will lose all access to your site." diff --git a/administrator/language/en-GB/en-GB.plg_behaviour_taggable.ini b/administrator/language/en-GB/en-GB.plg_behaviour_taggable.ini new file mode 100644 index 0000000000000..b0c6d1d356007 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_behaviour_taggable.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_BEHAVIOUR_TAGGABLE="Behaviour - Taggable" +PLG_BEHAVIOUR_TAGGABLE_XML_DESCRIPTION="Allows content items to be tagged." diff --git a/administrator/language/en-GB/en-GB.plg_behaviour_taggable.sys.ini b/administrator/language/en-GB/en-GB.plg_behaviour_taggable.sys.ini new file mode 100644 index 0000000000000..b0c6d1d356007 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_behaviour_taggable.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_BEHAVIOUR_TAGGABLE="Behaviour - Taggable" +PLG_BEHAVIOUR_TAGGABLE_XML_DESCRIPTION="Allows content items to be tagged." diff --git a/administrator/language/en-GB/en-GB.plg_behaviour_versionable.ini b/administrator/language/en-GB/en-GB.plg_behaviour_versionable.ini new file mode 100644 index 0000000000000..c401a63d4e213 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_behaviour_versionable.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_BEHAVIOUR_VERSIONABLE="Behaviour - Versionable" +PLG_BEHAVIOUR_VERSIONABLE_XML_DESCRIPTION="Allows content items to be versioned." diff --git a/administrator/language/en-GB/en-GB.plg_behaviour_versionable.sys.ini b/administrator/language/en-GB/en-GB.plg_behaviour_versionable.sys.ini new file mode 100644 index 0000000000000..c401a63d4e213 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_behaviour_versionable.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_BEHAVIOUR_VERSIONABLE="Behaviour - Versionable" +PLG_BEHAVIOUR_VERSIONABLE_XML_DESCRIPTION="Allows content items to be versioned." diff --git a/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini b/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini index 29821c12ebe7c..76aa1732437d1 100644 --- a/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini +++ b/administrator/language/en-GB/en-GB.plg_captcha_recaptcha.ini @@ -3,36 +3,18 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 -PLG_CAPTCHA_RECAPTCHA_XML_DESCRIPTION="This CAPTCHA plugin uses the reCAPTCHA service to prevent spammers while it helps to digitize books, newspapers and old radio shows. To get a site and secret key for your domain, go to https://www.google.com/recaptcha. To use this for new account registration, go to Options in the User Manager and select CAPTCHA - reCAPTCHA as the CAPTCHA." +PLG_CAPTCHA_RECAPTCHA_XML_DESCRIPTION="This CAPTCHA plugin uses the reCAPTCHA service to prevent spammers while it helps to digitize books, newspapers and old radio shows. To get a site and secret key for your domain, go to https://www.google.com/recaptcha. To use this for new account registration, go to Options in the User Manager and select CAPTCHA - reCAPTCHA as the CAPTCHA." PLG_CAPTCHA_RECAPTCHA="CAPTCHA - reCAPTCHA" -PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_ACTION="Update reCAPTCHA settings" -PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_TITLE="reCAPTCHA v1 - discontinued" -PLG_PLG_RECAPTCHA_VERSION_1_POSTINSTALL_BODY="Support for reCAPTCHA v1 will be turned off by Google on March 31, 2018. Please update the settings in the reCAPTCHA plugin to use Version 2.0." + ; Params -PLG_RECAPTCHA_VERSION_1_WARNING_LABEL="You have selected Version 1.0. As of March 31, 2018 this will no longer work and you should use Version 2.0." PLG_RECAPTCHA_VERSION_LABEL="Version" -PLG_RECAPTCHA_VERSION_DESC="Version 2.0 is the recommended version." -; The following two strings are deprecated and will be removed with 4.0. They generate wrong plural detection in Crowdin. -PLG_RECAPTCHA_VERSION_1="1.0" -PLG_RECAPTCHA_VERSION_2="2.0" -PLG_RECAPTCHA_VERSION_V1="1.0" PLG_RECAPTCHA_VERSION_V2="2.0" PLG_RECAPTCHA_PUBLIC_KEY_LABEL="Site Key" -PLG_RECAPTCHA_PUBLIC_KEY_DESC="Used in the JavaScript code that is served to your users. See the plugin description for instructions on getting a site key." PLG_RECAPTCHA_PRIVATE_KEY_LABEL="Secret Key" -PLG_RECAPTCHA_PRIVATE_KEY_DESC="Used in the communication between your server and the reCAPTCHA server. Be sure to keep it a secret. See the plugin description for instructions on getting a secret key." PLG_RECAPTCHA_THEME_LABEL="Theme" -PLG_RECAPTCHA_THEME_DESC="Defines which theme to use for reCAPTCHA." -PLG_RECAPTCHA_THEME_RED="Red" -PLG_RECAPTCHA_THEME_WHITE="White" -PLG_RECAPTCHA_THEME_BLACKGLASS="BlackGlass" -PLG_RECAPTCHA_THEME_CLEAN="Clean" PLG_RECAPTCHA_THEME_LIGHT="Light" PLG_RECAPTCHA_THEME_DARK="Dark" -PLG_RECAPTCHA_LANG_LABEL="Language" -PLG_RECAPTCHA_LANG_DESC="Select the language for the reCAPTCHA. If default is set and the language file has a custom translation, it will be used." PLG_RECAPTCHA_SIZE_LABEL="Size" -PLG_RECAPTCHA_SIZE_DESC="Select the size for the reCAPTCHA field." PLG_RECAPTCHA_THEME_NORMAL="Normal" PLG_RECAPTCHA_THEME_COMPACT="Compact" @@ -41,25 +23,3 @@ PLG_RECAPTCHA_ERROR_NO_PRIVATE_KEY="reCAPTCHA plugin needs a secret key to be se PLG_RECAPTCHA_ERROR_NO_PUBLIC_KEY="reCAPTCHA plugin needs a site key to be set in its parameters. Please contact a site administrator." PLG_RECAPTCHA_ERROR_EMPTY_SOLUTION="Please complete the CAPTCHA." PLG_RECAPTCHA_ERROR_NO_IP="For security reasons, you must pass the remote IP address to reCAPTCHA." -PLG_RECAPTCHA_ERROR_UNKNOWN="Unknown error." -PLG_RECAPTCHA_ERROR_INVALID_SITE_PUBLIC_KEY="We weren't able to verify the site key." -PLG_RECAPTCHA_ERROR_INVALID_SITE_PRIVATE_KEY="We weren't able to verify the secret key." -PLG_RECAPTCHA_ERROR_INVALID_REQUEST_COOKIE="The challenge parameter of the verify script was incorrect." -PLG_RECAPTCHA_ERROR_INCORRECT_CAPTCHA_SOL="The CAPTCHA was incorrect." -PLG_RECAPTCHA_ERROR_VERIFY_PARAMS_INCORRECT="The parameters to verify were incorrect, make sure you are passing all the required parameters." -PLG_RECAPTCHA_ERROR_INVALID_REFERRER="reCAPTCHA API keys are tied to a specific domain name for security reasons." -PLG_RECAPTCHA_ERROR_RECAPTCHA_NOT_REACHABLE="Unable to contact the reCAPTCHA verify server." - -; Uncomment(remove the ";" from the beginning of the line) the following lines if reCAPTCHA is not available in your language -; When uncommenting, do NOT translate PLG_RECAPTCHA_CUSTOM_LANG -; As of 01/01/2012, the following languages do not need translation: en, nl, fr, de, pt, ru, es, tr -;PLG_RECAPTCHA_CUSTOM_LANG="true" -;PLG_RECAPTCHA_INSTRUCTIONS_VISUAL="Type the two words:" -;PLG_RECAPTCHA_INSTRUCTIONS_AUDIO="Type what you hear:" -;PLG_RECAPTCHA_PLAY_AGAIN="Play sound again" -;PLG_RECAPTCHA_CANT_HEAR_THIS="Download sound as MP3" -;PLG_RECAPTCHA_VISUAL_CHALLENGE="Get a visual challenge" -;PLG_RECAPTCHA_AUDIO_CHALLENGE="Get an audio challenge" -;PLG_RECAPTCHA_REFRESH_BTN="Get a new challenge" -;PLG_RECAPTCHA_HELP_BTN="Help" -;PLG_RECAPTCHA_INCORRECT_TRY_AGAIN="Incorrect. Try again." diff --git a/administrator/language/en-GB/en-GB.plg_content_emailcloak.ini b/administrator/language/en-GB/en-GB.plg_content_emailcloak.ini index aba3b809ee960..5b3a129eb4d42 100644 --- a/administrator/language/en-GB/en-GB.plg_content_emailcloak.ini +++ b/administrator/language/en-GB/en-GB.plg_content_emailcloak.ini @@ -5,7 +5,6 @@ PLG_CONTENT_EMAILCLOAK="Content - Email Cloaking" PLG_CONTENT_EMAILCLOAK_LINKABLE="As linkable mailto address" -PLG_CONTENT_EMAILCLOAK_MODE_DESC="Select how email addresses will be displayed." PLG_CONTENT_EMAILCLOAK_MODE_LABEL="Mode" PLG_CONTENT_EMAILCLOAK_NONLINKABLE="Non-linkable Text" PLG_CONTENT_EMAILCLOAK_XML_DESCRIPTION="Cloaks all email addresses in content from spambots using JavaScript." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_content_joomla.ini b/administrator/language/en-GB/en-GB.plg_content_joomla.ini index 6ef4aba23a195..8ea1521672693 100644 --- a/administrator/language/en-GB/en-GB.plg_content_joomla.ini +++ b/administrator/language/en-GB/en-GB.plg_content_joomla.ini @@ -6,6 +6,12 @@ PLG_CONTENT_JOOMLA="Content - Joomla" PLG_CONTENT_JOOMLA_FIELD_CHECK_CATEGORIES_DESC="Check that categories are fully empty before they are deleted." PLG_CONTENT_JOOMLA_FIELD_CHECK_CATEGORIES_LABEL="Check Category Deletion" +PLG_CONTENT_JOOMLA_FIELD_CHECK_STAGES_DESC="Check that stages are not assigned to an item before they are deleted." +PLG_CONTENT_JOOMLA_FIELD_CHECK_STAGES_LABEL="Check Stages Deletion" PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_FE_DESC="Email users if 'Send email' is on when there is a new article submitted via the Frontend." PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_FE_LABEL="Email on New Site Article" -PLG_CONTENT_JOOMLA_XML_DESCRIPTION="This plugin does category processing for core extensions; sends an email when new article is submitted in the Frontend." \ No newline at end of file +PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_STAGE_DESC="Email users if 'Send email' is on when there is a status change of an article." +PLG_CONTENT_JOOMLA_FIELD_EMAIL_NEW_STAGE_LABEL="Email on transition execution" +PLG_CONTENT_JOOMLA_ON_STAGE_CHANGE_MSG="The status of an article has been changed by '%1$s' entitled '%2$s'." +PLG_CONTENT_JOOMLA_ON_STAGE_CHANGE_SUBJECT="Status of article has changed" +PLG_CONTENT_JOOMLA_XML_DESCRIPTION="This plugin does category processing for core extensions; sends an email when new article is submitted in the Frontend or a transition is executed." diff --git a/administrator/language/en-GB/en-GB.plg_content_loadmodule.ini b/administrator/language/en-GB/en-GB.plg_content_loadmodule.ini index 26f451aebf6e1..43d7d583dab85 100644 --- a/administrator/language/en-GB/en-GB.plg_content_loadmodule.ini +++ b/administrator/language/en-GB/en-GB.plg_content_loadmodule.ini @@ -4,7 +4,6 @@ ; Note : All ini files need to be saved as UTF-8 PLG_CONTENT_LOADMODULE="Content - Load Modules" -PLG_LOADMODULE_FIELD_STYLE_DESC="Code that will wrap Modules." PLG_LOADMODULE_FIELD_STYLE_LABEL="Style" PLG_LOADMODULE_FIELD_VALUE_DIVS="Wrapped by Divs" PLG_LOADMODULE_FIELD_VALUE_HORIZONTAL="Wrapped by table (horizontal)" diff --git a/administrator/language/en-GB/en-GB.plg_content_pagebreak.ini b/administrator/language/en-GB/en-GB.plg_content_pagebreak.ini index ca0a686f06c8c..8ae6d2c3dbf69 100644 --- a/administrator/language/en-GB/en-GB.plg_content_pagebreak.ini +++ b/administrator/language/en-GB/en-GB.plg_content_pagebreak.ini @@ -10,18 +10,12 @@ PLG_CONTENT_PAGEBREAK_ARTICLE_INDEX="Article Index" PLG_CONTENT_PAGEBREAK_NO_TITLE="No title" PLG_CONTENT_PAGEBREAK_PAGES="Pages" PLG_CONTENT_PAGEBREAK_PAGE_NUM="Page %s" -PLG_CONTENT_PAGEBREAK_SHOW_ALL_DESC="Displays the full article." PLG_CONTENT_PAGEBREAK_SHOW_ALL_LABEL="Show All" PLG_CONTENT_PAGEBREAK_SITE_ARTICLEINDEXTEXT="Custom Article Index Heading" -PLG_CONTENT_PAGEBREAK_SITE_ARTICLEINDEXTEXT_DESC="Enter a custom text for the Article Index Heading. If empty, standard will be used." -PLG_CONTENT_PAGEBREAK_SITE_ARTICLEINDEX_DESC="Show or hide Article Index Heading. The Heading displays on top of the Table of Contents." PLG_CONTENT_PAGEBREAK_SITE_ARTICLEINDEX_LABEL="Article Index Heading" -PLG_CONTENT_PAGEBREAK_SITE_TITLE_DESC="Title and heading attributes from Plugin added to Site Title tag." -PLG_CONTENT_PAGEBREAK_SITE_TITLE_LABEL="Show Site Title" +PLG_CONTENT_PAGEBREAK_SITE_TITLE_LABEL="Site Title" PLG_CONTENT_PAGEBREAK_SLIDERS="Sliders" -PLG_CONTENT_PAGEBREAK_STYLE_DESC="Display the article with separate pages, tabs or sliders." PLG_CONTENT_PAGEBREAK_STYLE_LABEL="Presentation Style" PLG_CONTENT_PAGEBREAK_TABS="Tabs" -PLG_CONTENT_PAGEBREAK_TOC_DESC="Display a table of contents on multipage Articles." PLG_CONTENT_PAGEBREAK_TOC_LABEL="Table of Contents" -PLG_CONTENT_PAGEBREAK_XML_DESCRIPTION="Allow the creation of a paginated article with an optional table of contents.

    Insert page breaks through the use of the page break button normally found in the WYSIWYG editor toolbar. The location of the page break in an article will be displayed in the editor as a simple horizontal line.

    The text displayed will depend on the options chosen and may be either the title, alternate text (if provided) or page numbers.

    The HTML usage is:
    <hr class="system-pagebreak" />
    <hr class="system-pagebreak" title="The page title" /> or
    <hr class="system-pagebreak" alt="The first page" /> or
    <hr class="system-pagebreak" title="The page title" alt="The first page" /> or
    <hr class="system-pagebreak" alt="The first page" title="The page title" />" +PLG_CONTENT_PAGEBREAK_XML_DESCRIPTION="Allow the creation of a paginated article with an optional table of contents.

    Insert page breaks through the use of the page break button normally found in the WYSIWYG editor toolbar. The location of the page break in an article will be displayed in the editor as a simple horizontal line.

    The text displayed will depend on the options chosen and may be either the title, alternate text (if provided) or page numbers.

    The HTML usage is:
    <hr class="system-pagebreak" />
    <hr class="system-pagebreak" title="The page title" /> or
    <hr class="system-pagebreak" alt="The first page" /> or
    <hr class="system-pagebreak" title="The page title" alt="The first page" /> or
    <hr class="system-pagebreak" alt="The first page" title="The page title" />" diff --git a/administrator/language/en-GB/en-GB.plg_content_pagebreak.sys.ini b/administrator/language/en-GB/en-GB.plg_content_pagebreak.sys.ini index bacb670bfdeb3..3e36078f300c6 100644 --- a/administrator/language/en-GB/en-GB.plg_content_pagebreak.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_content_pagebreak.sys.ini @@ -5,4 +5,4 @@ PLG_CONTENT_PAGEBREAK="Content - Page Break" -PLG_CONTENT_PAGEBREAK_XML_DESCRIPTION="Allow the creation of a paginated article with an optional table of contents.

    Insert page breaks through the use of the page break button normally found in the WYSIWYG editor toolbar. The location of the page break in an article will be displayed in the editor as a simple horizontal line.

    The text displayed will depend on the options chosen and may be either the title, alternate text (if provided) or page numbers.

    The HTML usage is:
    <hr class="system-pagebreak" />
    <hr class="system-pagebreak" title="The page title" /> or
    <hr class="system-pagebreak" alt="The first page" /> or
    <hr class="system-pagebreak" title="The page title" alt="The first page" /> or
    <hr class="system-pagebreak" alt="The first page" title="The page title" />" +PLG_CONTENT_PAGEBREAK_XML_DESCRIPTION="Allow the creation of a paginated article with an optional table of contents.

    Insert page breaks through the use of the page break button normally found in the WYSIWYG editor toolbar. The location of the page break in an article will be displayed in the editor as a simple horizontal line.

    The text displayed will depend on the options chosen and may be either the title, alternate text (if provided) or page numbers.

    The HTML usage is:
    <hr class="system-pagebreak" />
    <hr class="system-pagebreak" title="The page title" /> or
    <hr class="system-pagebreak" alt="The first page" /> or
    <hr class="system-pagebreak" title="The page title" alt="The first page" /> or
    <hr class="system-pagebreak" alt="The first page" title="The page title" />" diff --git a/administrator/language/en-GB/en-GB.plg_content_pagenavigation.ini b/administrator/language/en-GB/en-GB.plg_content_pagenavigation.ini index 8adbfd7ca9711..8acfebdcde36d 100644 --- a/administrator/language/en-GB/en-GB.plg_content_pagenavigation.ini +++ b/administrator/language/en-GB/en-GB.plg_content_pagenavigation.ini @@ -4,11 +4,8 @@ ; Note : All ini files need to be saved as UTF-8 PLG_CONTENT_PAGENAVIGATION="Content - Page Navigation" -PLG_PAGENAVIGATION_FIELD_DISPLAY_DESC="Choose what to display as the link text." PLG_PAGENAVIGATION_FIELD_DISPLAY_LABEL="Link Text" -PLG_PAGENAVIGATION_FIELD_POSITION_DESC="The position of the Page Navigation function on the viewed page in relation to the text." PLG_PAGENAVIGATION_FIELD_POSITION_LABEL="Position" -PLG_PAGENAVIGATION_FIELD_RELATIVE_DESC="Assigns the relative location for the Position parameter. Text will place it directly above or below the article content. Full Article will place it above or below the full display including title and readmore." PLG_PAGENAVIGATION_FIELD_RELATIVE_LABEL="Relative To" PLG_PAGENAVIGATION_FIELD_VALUE_ABOVE="Above" PLG_PAGENAVIGATION_FIELD_VALUE_ARTICLE="Full Article" diff --git a/administrator/language/en-GB/en-GB.plg_content_vote.ini b/administrator/language/en-GB/en-GB.plg_content_vote.ini index b7fba7ba3bfb5..9cf610191131b 100644 --- a/administrator/language/en-GB/en-GB.plg_content_vote.ini +++ b/administrator/language/en-GB/en-GB.plg_content_vote.ini @@ -6,7 +6,6 @@ PLG_CONTENT_VOTE="Content - Vote" PLG_VOTE_BOTTOM="Bottom" PLG_VOTE_LABEL="Please Rate" -PLG_VOTE_POSITION_DESC="Set where the voting is displayed." PLG_VOTE_POSITION_LABEL="Position" PLG_VOTE_RATE="Rate" PLG_VOTE_STAR_ACTIVE="Star Active" diff --git a/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.ini b/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.ini index c4487e74cd5c4..394dab980174c 100644 --- a/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.ini +++ b/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.ini @@ -5,4 +5,4 @@ PLG_EDITORS-XTD_FIELDS="Button - Field" PLG_EDITORS-XTD_FIELDS_BUTTON_FIELD="Field" -PLG_EDITORS-XTD_FIELDS_XML_DESCRIPTION="Displays a button to insert a custom field into an editor area. Displays a popup allowing you to choose the field.
    Warning!: the custom field will not be rendered if the Content - Fields plugin is not enabled." +PLG_EDITORS-XTD_FIELDS_XML_DESCRIPTION="Displays a button to insert a custom field into an editor area. Displays a popup allowing you to choose the field.
    Warning!: the custom field will not be rendered if the Content - Fields plugin is not enabled." diff --git a/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.sys.ini b/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.sys.ini index 2765df4ceafe6..8cef15ba80187 100644 --- a/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_editors-xtd_fields.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_EDITORS-XTD_FIELDS="Button - Field" -PLG_EDITORS-XTD_FIELDS_XML_DESCRIPTION="Displays a button to insert a custom field into an editor area. Displays a popup allowing you to choose the field.
    Warning!: the custom field will not be rendered if the Content - Fields plugin is not enabled." +PLG_EDITORS-XTD_FIELDS_XML_DESCRIPTION="Displays a button to insert a custom field into an editor area. Displays a popup allowing you to choose the field.
    Warning!: the custom field will not be rendered if the Content - Fields plugin is not enabled." diff --git a/administrator/language/en-GB/en-GB.plg_editors_codemirror.ini b/administrator/language/en-GB/en-GB.plg_editors_codemirror.ini index 060bc6cd81487..d1d75e4deeca0 100644 --- a/administrator/language/en-GB/en-GB.plg_editors_codemirror.ini +++ b/administrator/language/en-GB/en-GB.plg_editors_codemirror.ini @@ -3,43 +3,24 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 -PLG_CODEMIRROR_FIELD_ACTIVELINE_COLOR_DESC="The colour to use for highlighting the active line. Will be displayed at 50% opacity." PLG_CODEMIRROR_FIELD_ACTIVELINE_COLOR_LABEL="Active Line Colour" -PLG_CODEMIRROR_FIELD_ACTIVELINE_DESC="Adds a highlight to the line the cursor is on." PLG_CODEMIRROR_FIELD_ACTIVELINE_LABEL="Highlight Active Line" -PLG_CODEMIRROR_FIELD_AUTOCLOSEBRACKET_DESC="Automatic bracket completion." PLG_CODEMIRROR_FIELD_AUTOCLOSEBRACKET_LABEL="Bracket Completion" -PLG_CODEMIRROR_FIELD_AUTOCLOSETAGS_DESC="Automatic tag completion." PLG_CODEMIRROR_FIELD_AUTOCLOSETAGS_LABEL="Tag Completion" -PLG_CODEMIRROR_FIELD_AUTOFOCUS_DESC="Auto focus." PLG_CODEMIRROR_FIELD_AUTOFOCUS_LABEL="Auto Focus" -PLG_CODEMIRROR_FIELD_CODEFOLDING_DESC="Allow blocks of code to be folded." PLG_CODEMIRROR_FIELD_CODEFOLDING_LABEL="Code Folding" -PLG_CODEMIRROR_FIELD_FONT_FAMILY_DESC="The font to use in the editor. If not installed, will be loaded from https://www.google.com/fonts/." PLG_CODEMIRROR_FIELD_FONT_FAMILY_LABEL="Font" -PLG_CODEMIRROR_FIELD_FONT_SIZE_DESC="The size of the font in the editor." PLG_CODEMIRROR_FIELD_FONT_SIZE_LABEL="Font Size (px)" -PLG_CODEMIRROR_FIELD_FULLSCREEN_DESC="Select the function key to use to toggle fullscreen mode." PLG_CODEMIRROR_FIELD_FULLSCREEN_LABEL="Toggle Fullscreen" -PLG_CODEMIRROR_FIELD_FULLSCREEN_MOD_DESC="Select any modifier keys to use with the fullscreen toggle key." -PLG_CODEMIRROR_FIELD_FULLSCREEN_MOD_LABEL="Use Modifiers" -PLG_CODEMIRROR_FIELD_HIGHLIGHT_MATCH_COLOR_DESC="The background colour to use for highlighting matching tags. Will be displayed at 50% opacity." +PLG_CODEMIRROR_FIELD_FULLSCREEN_MOD_LABEL="Toggle Fullscreen Modifier" PLG_CODEMIRROR_FIELD_HIGHLIGHT_MATCH_COLOR_LABEL="Matching Tag Colour" -PLG_CODEMIRROR_FIELD_LINE_HEIGHT_DESC="The height of one line of text. This is in ems, meaning that 1.0 is equal to the font size and 2.0 is equal to 2x the font size." PLG_CODEMIRROR_FIELD_LINE_HEIGHT_LABEL="Line Height (em)" -PLG_CODEMIRROR_FIELD_LINENUMBERS_DESC="Display line numbers." PLG_CODEMIRROR_FIELD_LINENUMBERS_LABEL="Line Numbers" -PLG_CODEMIRROR_FIELD_LINEWRAPPING_DESC="Enable/Disable line wrapping." PLG_CODEMIRROR_FIELD_LINEWRAPPING_LABEL="Line Wrapping" -PLG_CODEMIRROR_FIELD_MARKERGUTTER_DESC="Code Marker and Code Folding." PLG_CODEMIRROR_FIELD_MARKERGUTTER_LABEL="Gutters" -PLG_CODEMIRROR_FIELD_MATCHBRACKETS_DESC="Highlight matching brackets." PLG_CODEMIRROR_FIELD_MATCHBRACKETS_LABEL="Match Brackets" -PLG_CODEMIRROR_FIELD_MATCHTAGS_DESC="Highlight matching tags." PLG_CODEMIRROR_FIELD_MATCHTAGS_LABEL="Match Tags" -PLG_CODEMIRROR_FIELD_SELECTIONMATCHES_DESC="Highlight instances of the selected word throughout the document." PLG_CODEMIRROR_FIELD_SELECTIONMATCHES_LABEL="Highlight Selection Matches" -PLG_CODEMIRROR_FIELD_THEME_DESC="Sets the colours for the editor." PLG_CODEMIRROR_FIELD_THEME_LABEL="Theme" PLG_CODEMIRROR_FIELD_VALUE_FONT_FAMILY_DEFAULT="Browser Default" PLG_CODEMIRROR_FIELD_VALUE_FULLSCREEN_MOD_ALT="Alt" @@ -47,16 +28,11 @@ PLG_CODEMIRROR_FIELD_VALUE_FULLSCREEN_MOD_CMD="Command" PLG_CODEMIRROR_FIELD_VALUE_FULLSCREEN_MOD_CTRL="Control" PLG_CODEMIRROR_FIELD_VALUE_FULLSCREEN_MOD_SHIFT="Shift" PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_DEFAULT="Default" -PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_DESC="Select the scrollbar style you'd like CodeMirror to use." PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_LABEL="Scrollbar Style" PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_OVERLAY="Overlay" PLG_CODEMIRROR_FIELD_VALUE_SCROLLBARSTYLE_SIMPLE="Simple" -PLG_CODEMIRROR_FIELD_VALUE_THEME_DARK="Dark" -PLG_CODEMIRROR_FIELD_VALUE_THEME_LIGHT="Light" -PLG_CODEMIRROR_FIELD_VIM_KEYBINDING_DESC="Select this option to make CodeMirror work in Vim mode." PLG_CODEMIRROR_FIELD_VIM_KEYBINDING_LABEL="Vim Keybinding" PLG_CODEMIRROR_FIELDSET_APPEARANCE_OPTIONS_LABEL="Appearance Options" PLG_CODEMIRROR_FIELDSET_TOOLBAR_OPTIONS_LABEL="Toolbar Options" -PLG_CODEMIRROR_TOGGLE_FULL_SCREEN="Press %1$s %2$s to toggle Full Screen editing." PLG_CODEMIRROR_XML_DESCRIPTION="This plugin loads the CodeMirror editor." PLG_EDITORS_CODEMIRROR="Editor - CodeMirror" diff --git a/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini b/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini index f482600d14310..21abdaa3aa991 100644 --- a/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini +++ b/administrator/language/en-GB/en-GB.plg_editors_tinymce.ini @@ -5,152 +5,65 @@ PLG_EDITORS_TINYMCE="Editor - TinyMCE" PLG_TINY_BUTTON_TOGGLE_EDITOR="Toggle editor" -PLG_TINY_CONFIG_TEXTFILTER_ACL_DESC="If on, the text filter from the Joomla Global Configuration for every user group is applied.
    If off, the filters as defined here are used for all user groups." PLG_TINY_CONFIG_TEXTFILTER_ACL_LABEL="Use Joomla Text Filter" +PLG_TINY_CORE_BUTTONS="CMS Content" PLG_TINY_ERR_CUSTOMCSSFILENOTPRESENT="The file name %s was entered in the TinyMCE Custom CSS field. This file could not be found in the default template folder. No styles are available." PLG_TINY_ERR_EDITORCSSFILENOTPRESENT="Could not find the file 'editor.css' in the template or templates/system folder. No styles are available." PLG_TINY_ERR_UNSUPPORTEDBROWSER="Drag and drop image upload is not available for your browser. Please consider using a fully HTML5 compatible browser." -PLG_TINY_FIELD_ADVIMAGE_DESC="Turn on/off a more advanced image dialog." PLG_TINY_FIELD_ADVIMAGE_LABEL="Advanced Image" -PLG_TINY_FIELD_ADVLIST_DESC="Turn on/off to enable to set number formats and bullet types in ordered and unordered lists." PLG_TINY_FIELD_ADVLIST_LABEL="Advanced List" -PLG_TINY_FIELD_ALIGN_DESC="Turn on/off to enable the alignment of the text." -PLG_TINY_FIELD_ALIGN_LABEL="Text Alignment" -PLG_TINY_FIELD_BLOCKQUOTE_DESC="Turn on/off blockquotes." -PLG_TINY_FIELD_BLOCKQUOTE_LABEL="Blockquote" -PLG_TINY_FIELD_CODESAMPLE_DESC="Turn on/off code highlighting" -PLG_TINY_FIELD_CODESAMPLE_LABEL="Code Sample" -PLG_TINY_FIELD_COLORS_DESC="Show or hide the Colours control buttons." -PLG_TINY_FIELD_COLORS_LABEL="Colours" -PLG_TINY_FIELD_CONTEXTMENU_DESC="Turn on/off Context Menu." PLG_TINY_FIELD_CONTEXTMENU_LABEL="Context Menu" PLG_TINY_FIELD_CSS_DESC="By default the Plugin looks for an editor.css file. If it can't find one in the default template CSS folder, it loads the editor.css file from the system template." PLG_TINY_FIELD_CSS_LABEL="Template CSS Classes" -PLG_TINY_FIELD_CUSTOMBUTTON_DESC="Add custom button(s)." PLG_TINY_FIELD_CUSTOMBUTTON_LABEL="Custom Button" -PLG_TINY_FIELD_CUSTOMPLUGIN_DESC="Add custom plugin(s)." PLG_TINY_FIELD_CUSTOMPLUGIN_LABEL="Custom Plugin" -PLG_TINY_FIELD_CUSTOM_CSS_DESC="Optional CSS file that will override the standard editor.css file. Enter a file name to point to a file in the CSS folder of the default template (for example, templates/beez3/css/). Or enter a full URL path to the custom CSS file. If you enter a value in this field, this file will be used instead of the editor.css file." +PLG_TINY_FIELD_CUSTOM_CSS_DESC="Optional CSS file that will override the standard editor.css file. Enter a file name to point to a file in the CSS folder of the default template (for example, templates/cassiopeia/css/). Or enter a full URL path to the custom CSS file. If you enter a value in this field, this file will be used instead of the editor.css file." PLG_TINY_FIELD_CUSTOM_CSS_LABEL="Custom CSS Classes" -PLG_TINY_FIELD_CUSTOM_PATH_DESC="The directory with the image files to be listed relative to the default image folder (set in Media > Options)." PLG_TINY_FIELD_CUSTOM_PATH_LABEL="Images Directory" -PLG_TINY_FIELD_DATE_DESC="Show or hide the Insert Date button." -PLG_TINY_FIELD_DATE_LABEL="Insert Date" -PLG_TINY_FIELD_DIRECTION_DESC="Choose default text direction." PLG_TINY_FIELD_DIRECTION_LABEL="Text Direction" -PLG_TINY_FIELD_DRAG_DROP_DESC="Enable drag and drop for uploading images" PLG_TINY_FIELD_DRAG_DROP_LABEL="Images Drag and Drop" -PLG_TINY_FIELD_ELEMENTS_DESC="Allows the addition of specific valid elements to the existing rule set." PLG_TINY_FIELD_ELEMENTS_LABEL="Extended Valid Elements" -PLG_TINY_FIELD_ENCODING_DESC="Controls how HTML entities are encoded. Recommended setting is 'raw'. 'named' = used named entity encoding (for example, '<'). 'numeric' = use numeric HTML encoding (for example, '%03c'). raw = Do not encode HTML entities. Note that searching content may not work properly if setting is not 'raw'." PLG_TINY_FIELD_ENCODING_LABEL="Entity Encoding" -PLG_TINY_FIELD_FONTS_DESC="Show or hide the Font control selectors." -PLG_TINY_FIELD_FONTS_LABEL="Fonts" -PLG_TINY_FIELD_FULLSCREEN_DESC="Show or hide the Fullscreen button." -PLG_TINY_FIELD_FULLSCREEN_LABEL="Fullscreen" -PLG_TINY_FIELD_FUNCTIONALITY_DESC="Select level of functionality." -PLG_TINY_FIELD_FUNCTIONALITY_LABEL="Functionality" -PLG_TINY_FIELD_HR_DESC="Show or hide the Horizontal Rule button." -PLG_TINY_FIELD_HR_LABEL="Horizontal Rule" -PLG_TINY_FIELD_HTMLHEIGHT_DESC="Height of HTML editor. Only applies in Advanced and Extended mode." PLG_TINY_FIELD_HTMLHEIGHT_LABEL="HTML Height" -PLG_TINY_FIELD_HTMLWIDTH_DESC="Width of HTML editor. Should normally be left empty to let it flow. Only applies in Advanced and Extended mode." PLG_TINY_FIELD_HTMLWIDTH_LABEL="HTML Width" -PLG_TINY_FIELD_INLINEPOPUPS_DESC="All dialogs to open as floating div layers instead of popup windows. This option can be very useful to get around popup blockers." -PLG_TINY_FIELD_INLINEPOPUPS_LABEL="Inline Popups" PLG_TINY_FIELD_LABEL_ADVANCEDPARAMS="Advanced" -PLG_TINY_FIELD_LANGCODE_DESC="Editor UI Language. The value will be used if Automatic language is not set." PLG_TINY_FIELD_LANGCODE_LABEL="Language Code" -PLG_TINY_FIELD_LANGSELECT_DESC="If Yes, editor language will automatically match selected UI language. If the tiny language does not exist, the editor language will default to English." PLG_TINY_FIELD_LANGSELECT_LABEL="Automatic Language Selection" -PLG_TINY_FIELD_LINK_DESC="Select to enable the Link icons." -PLG_TINY_FIELD_LINK_LABEL="Links" -PLG_TINY_FIELD_MEDIA_DESC="Show or hide the Media button." -PLG_TINY_FIELD_MEDIA_LABEL="Media" -PLG_TINY_FIELD_MOBILE_DESC="This mode puts any mobile devices into the simple functionality with enlarged buttons for easy access." PLG_TINY_FIELD_MOBILE_LABEL="Mobile Mode" -PLG_TINY_FIELD_NAME_EXTENDED_LABEL="Extended Mode Options
    Below you can set the access level for each one of the fields individually.
    Please keep in mind that these options will only have an effect in Extended mode." -PLG_TINY_FIELD_NEWLINES_DESC="New lines will be created using the selected option." PLG_TINY_FIELD_NEWLINES_LABEL="New Lines" -PLG_TINY_FIELD_NONBREAKING_DESC="Insert non-breaking space entities." -PLG_TINY_FIELD_NONBREAKING_LABEL="Non-breaking" PLG_TINY_FIELD_NUMBER_OF_SETS_LABEL="Number of Sets" -PLG_TINY_FIELD_NUMBER_OF_SETS_DESC="Number of sets that can be created. Minimum 3" -PLG_TINY_FIELD_PASTE_DESC="Show or hide the Paste button." -PLG_TINY_FIELD_PASTE_LABEL="Paste" -PLG_TINY_FIELD_PATH_DESC="If set to ON, it displays the set classes for the marked text." PLG_TINY_FIELD_PATH_LABEL="Element Path" -PLG_TINY_FIELD_PRINT_DESC="Turn on/off the print and print preview icons in the editor." -PLG_TINY_FIELD_PRINT_LABEL="Print/Preview" -PLG_TINY_FIELD_PROHIBITED_DESC="Elements that will be cleaned from the text. Do not leave empty - if you do not want to prohibit anything enter dummy text eg cms." PLG_TINY_FIELD_PROHIBITED_LABEL="Prohibited Elements" -PLG_TINY_FIELD_RESIZE_HORIZONTAL_DESC="Enable/disable the horizontal resizing." PLG_TINY_FIELD_RESIZE_HORIZONTAL_LABEL="Horizontal Resizing" -PLG_TINY_FIELD_RESIZING_DESC="Enable/disable the resizing of the editor area (vertically and also horizontally if 'Horizontal Resizing' is enabled)." PLG_TINY_FIELD_RESIZING_LABEL="Resizing" -PLG_TINY_FIELD_RTL_DESC="Show or hide the RTL button." -PLG_TINY_FIELD_RTL_LABEL="Directionality" -; The two following strings are deprecated -PLG_TINY_FIELD_SAVEWARNING_DESC="Gives warning if you cancel without saving changes." -PLG_TINY_FIELD_SAVEWARNING_LABEL="Save Warning" -PLG_TINY_FIELD_SEARCH-REPLACE_DESC="Show or hide the Search & Replace button." -PLG_TINY_FIELD_SEARCH-REPLACE_LABEL="Search & Replace" -PLG_TINY_FIELD_SETACCESS_DESC="Restrict users that will use this set to those in the selected user groups.
    If a user belongs to multiple groups, the set used will be the one which is assigned to a group higher in the hierarchy.
    Example: if a set is assigned to Author and another set to Publishers, if the user belongs to both groups, the set assigned to Publishers will be used." PLG_TINY_FIELD_SETACCESS_LABEL="Assign this Set to" -PLG_TINY_FIELD_SKIN_ADMIN_DESC="Select skin for the Administrator Backend interface." PLG_TINY_FIELD_SKIN_ADMIN_LABEL="Administrator Skin" -PLG_TINY_FIELD_SKIN_DESC="Select skin for the Frontend interface." PLG_TINY_FIELD_SKIN_INFO_DESC="Copy your new skins to: /media/editors/tinymce/skins." -PLG_TINY_FIELD_SKIN_INFO_LABEL="For customised skins go to: Skin Creator" +PLG_TINY_FIELD_SKIN_INFO_LABEL="For customised skins go to: Skin Creator" PLG_TINY_FIELD_SKIN_LABEL="Site Skin" -PLG_TINY_FIELD_SMILIES_DESC="Show or hide the Smilies buttons." -PLG_TINY_FIELD_SMILIES_LABEL="Smilies" -PLG_TINY_FIELD_TABLE_DESC="Show or hide the Table control buttons." -PLG_TINY_FIELD_TABLE_LABEL="Table" -PLG_TINY_FIELD_TEMPLATE_DESC="Show or hide the Insert predefined template content button." -PLG_TINY_FIELD_TEMPLATE_LABEL="Template" -PLG_TINY_FIELD_URLS_DESC="URL behaviour." PLG_TINY_FIELD_URLS_LABEL="URLs" PLG_TINY_FIELD_VALIDELEMENTS_DESC="Defines which elements will stay in the edited text when the editor saves (the default rule set for this option is a mixture of the full HTML5 and HTML4 specification)." PLG_TINY_FIELD_VALIDELEMENTS_LABEL="Valid Elements" PLG_TINY_FIELD_VALUE_ABSOLUTE="Absolute" PLG_TINY_FIELD_VALUE_ADVANCED="Advanced" -PLG_TINY_FIELD_VALUE_ALWAYS="Always" -PLG_TINY_FIELD_VALUE_BOTTOM="Bottom" PLG_TINY_FIELD_VALUE_BR="BR Elements" -PLG_TINY_FIELD_VALUE_CENTER="Center" -PLG_TINY_FIELD_VALUE_DEFAULT="Default" PLG_TINY_FIELD_VALUE_EXTENDED="Extended" -PLG_TINY_FIELD_VALUE_FRONT="Front Only" -PLG_TINY_FIELD_VALUE_LEFT="Left" PLG_TINY_FIELD_VALUE_LTR="Left to Right" PLG_TINY_FIELD_VALUE_NAMED="named" -PLG_TINY_FIELD_VALUE_NEVER="Never" PLG_TINY_FIELD_VALUE_NUMERIC="numeric" PLG_TINY_FIELD_VALUE_P="P Elements" PLG_TINY_FIELD_VALUE_RAW="raw" PLG_TINY_FIELD_VALUE_RELATIVE="Relative" -PLG_TINY_FIELD_VALUE_RIGHT="Right" PLG_TINY_FIELD_VALUE_RTL="Right to Left" PLG_TINY_FIELD_VALUE_SIMPLE="Simple" -PLG_TINY_FIELD_VALUE_TOP="Top" -PLG_TINY_FIELD_VISUALBLOCKS_DESC="See the outline of HTML block elements." -PLG_TINY_FIELD_VISUALBLOCKS_LABEL="Visualblocks" -PLG_TINY_FIELD_VISUALCHARS_DESC="See invisible characters, specifically non-breaking spaces." -PLG_TINY_FIELD_VISUALCHARS_LABEL="Visualchars" -PLG_TINY_FIELD_WORDCOUNT_DESC="Turn on/off word count." PLG_TINY_FIELD_WORDCOUNT_LABEL="Word Count" -PLG_TINY_LEGACY_WARNING="The TinyMCE Editor Plugin has been updated. Currently it uses your existing configuration. By editing the plugin, you can now assign and customise various layouts to specific user groups.
    Warning: when editing the plugin, you will lose all your previous settings!" -PLG_TINY_SET_TARGET_PANEL_DESCRIPTION="Existing sets of the TinyMCE panel, and options for each set.
    In each set you can add or remove from the available menus and buttons." +PLG_TINY_LEGACY_WARNING="The TinyMCE Editor Plugin has been updated. Currently it uses your existing configuration. By editing the plugin, you can now assign and customise various layouts to specific user groups.
    Warning: when editing the plugin, you will lose all your previous settings!" +PLG_TINY_SET_TARGET_PANEL_DESCRIPTION="Existing sets of the TinyMCE panel, and options for each set.
    In each set you can add or remove from the available menus and buttons." PLG_TINY_SET_TITLE="Set %s" PLG_TINY_SET_PRESET_BUTTON_ADVANCED="Use advanced preset" PLG_TINY_SET_PRESET_BUTTON_MEDIUM="Use medium preset" PLG_TINY_SET_PRESET_BUTTON_SIMPLE="Use simple preset" -PLG_TINY_SET_SOURCE_PANEL_DESCRIPTION="All available menus and buttons.
    Use them (drag and drop) to edit or build your custom TinyMCE panel." -PLG_TINY_TEMPLATE_LAYOUT1_DESC="HTML layout." -PLG_TINY_TEMPLATE_LAYOUT1_TITLE="Layout" -PLG_TINY_TEMPLATE_SNIPPET1_DESC="Simple HTML snippet." -PLG_TINY_TEMPLATE_SNIPPET1_TITLE="Simple Snippet" +PLG_TINY_SET_SOURCE_PANEL_DESCRIPTION="All available menus and buttons.
    Use them (drag and drop) to edit or build your custom TinyMCE panel." ; TinyMCE toolbar buttons PLG_TINY_TOOLBAR_BUTTON_FONTSELECT="Font Select" PLG_TINY_TOOLBAR_BUTTON_FONTSIZESELECT="Font Size Select" diff --git a/administrator/language/en-GB/en-GB.plg_extension_namespacemap.ini b/administrator/language/en-GB/en-GB.plg_extension_namespacemap.ini new file mode 100644 index 0000000000000..681f7eb2bbc68 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_extension_namespacemap.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_EXTENSION_NAMESPACEMAP="Extension - Namespace Updater" +PLG_EXTENSION_NAMESPACEMAP_XML_DESCRIPTION="Automatically builds and updates the libraries\autoload_psr4.php file that is used to autoload extensions.
    Warning! This plugin must be enabled it runs on extension install, update and deletion." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_extension_namespacemap.sys.ini b/administrator/language/en-GB/en-GB.plg_extension_namespacemap.sys.ini new file mode 100644 index 0000000000000..681f7eb2bbc68 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_extension_namespacemap.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_EXTENSION_NAMESPACEMAP="Extension - Namespace Updater" +PLG_EXTENSION_NAMESPACEMAP_XML_DESCRIPTION="Automatically builds and updates the libraries\autoload_psr4.php file that is used to autoload extensions.
    Warning! This plugin must be enabled it runs on extension install, update and deletion." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_fields_checkboxes.ini b/administrator/language/en-GB/en-GB.plg_fields_checkboxes.ini index f76e652bd7906..00ead42218447 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_checkboxes.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_checkboxes.ini @@ -5,7 +5,6 @@ PLG_FIELDS_CHECKBOXES="Fields - Checkboxes" PLG_FIELDS_CHECKBOXES_LABEL="Checkboxes (%s)" -PLG_FIELDS_CHECKBOXES_PARAMS_OPTIONS_DESC="The values of the checkboxes." PLG_FIELDS_CHECKBOXES_PARAMS_OPTIONS_LABEL="Checkbox Values" PLG_FIELDS_CHECKBOXES_PARAMS_OPTIONS_VALUE_LABEL="Value" PLG_FIELDS_CHECKBOXES_PARAMS_OPTIONS_NAME_LABEL="Text" diff --git a/administrator/language/en-GB/en-GB.plg_fields_editor.ini b/administrator/language/en-GB/en-GB.plg_fields_editor.ini index 615efee27340e..0428f0c9ab8d0 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_editor.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_editor.ini @@ -6,12 +6,8 @@ PLG_FIELDS_EDITOR="Fields - Editor" PLG_FIELDS_EDITOR_LABEL="Editor (%s)" PLG_FIELDS_EDITOR_PARAMS_BUTTONS_HIDE_LABEL="Hide Buttons" -PLG_FIELDS_EDITOR_PARAMS_FILTER_DESC="Allow the system to save certain html tags or raw data." PLG_FIELDS_EDITOR_PARAMS_FILTER_LABEL="Filter" -PLG_FIELDS_EDITOR_PARAMS_HEIGHT_DESC="Defines the height (in pixels) of the WYSIWYG editor and defaults to 250px." PLG_FIELDS_EDITOR_PARAMS_HEIGHT_LABEL="Height" -PLG_FIELDS_EDITOR_PARAMS_SHOW_BUTTONS_DESC="Should the editors-xtd plugin buttons be shown?" -PLG_FIELDS_EDITOR_PARAMS_SHOW_BUTTONS_LABEL="Show Buttons" -PLG_FIELDS_EDITOR_PARAMS_WIDTH_DESC="Defines the width (in pixels) of the WYSIWYG editor and defaults to 100%." +PLG_FIELDS_EDITOR_PARAMS_SHOW_BUTTONS_LABEL="Buttons" PLG_FIELDS_EDITOR_PARAMS_WIDTH_LABEL="Width" PLG_FIELDS_EDITOR_XML_DESCRIPTION="This plugin lets you create new fields of type 'editor' in any extensions where custom fields are supported." diff --git a/administrator/language/en-GB/en-GB.plg_fields_imagelist.ini b/administrator/language/en-GB/en-GB.plg_fields_imagelist.ini index 54979dc4657a8..f37c38cb19055 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_imagelist.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_imagelist.ini @@ -5,10 +5,7 @@ PLG_FIELDS_IMAGELIST="Fields - Imagelist" PLG_FIELDS_IMAGELIST_LABEL="List of Images (%s)" -PLG_FIELDS_IMAGELIST_PARAMS_DIRECTORY_DESC="The directory with the image files to be listed relative to the default image folder (set in Media > Options)." PLG_FIELDS_IMAGELIST_PARAMS_DIRECTORY_LABEL="Directory" -PLG_FIELDS_IMAGELIST_PARAMS_IMAGE_CLASS_DESC="The class which is added to the image (src tag)." PLG_FIELDS_IMAGELIST_PARAMS_IMAGE_CLASS_LABEL="Image Class" -PLG_FIELDS_IMAGELIST_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." PLG_FIELDS_IMAGELIST_PARAMS_MULTIPLE_LABEL="Multiple" PLG_FIELDS_IMAGELIST_XML_DESCRIPTION="This plugin lets you create new fields of type 'imagelist' in any extensions where custom fields are supported." diff --git a/administrator/language/en-GB/en-GB.plg_fields_integer.ini b/administrator/language/en-GB/en-GB.plg_fields_integer.ini index 8415cae48be46..9ab9e04f7ec56 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_integer.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_integer.ini @@ -5,12 +5,8 @@ PLG_FIELDS_INTEGER="Fields - Integer" PLG_FIELDS_INTEGER_LABEL="Integer (%s)" -PLG_FIELDS_INTEGER_PARAMS_FIRST_DESC="This value is the lowest on the list." PLG_FIELDS_INTEGER_PARAMS_FIRST_LABEL="First" -PLG_FIELDS_INTEGER_PARAMS_LAST_DESC="This value is the highest on the list." PLG_FIELDS_INTEGER_PARAMS_LAST_LABEL="Last" -PLG_FIELDS_INTEGER_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." PLG_FIELDS_INTEGER_PARAMS_MULTIPLE_LABEL="Multiple" -PLG_FIELDS_INTEGER_PARAMS_STEP_DESC="Each option will be the previous option incremented by this integer, starting with the first value until the last value is reached." -PLG_FIELDS_INTEGER_PARAMS_STEP_LABEL="Step" +PLG_FIELDS_INTEGER_PARAMS_STEP_LABEL="Step Increment" PLG_FIELDS_INTEGER_XML_DESCRIPTION="This plugin lets you create new fields of type 'integer' in any extensions where custom fields are supported." diff --git a/administrator/language/en-GB/en-GB.plg_fields_list.ini b/administrator/language/en-GB/en-GB.plg_fields_list.ini index dcc3fc173b418..f9bdfbc9b22e5 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_list.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_list.ini @@ -5,9 +5,7 @@ PLG_FIELDS_LIST="Fields - List" PLG_FIELDS_LIST_LABEL="List (%s)" -PLG_FIELDS_LIST_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." PLG_FIELDS_LIST_PARAMS_MULTIPLE_LABEL="Multiple" -PLG_FIELDS_LIST_PARAMS_OPTIONS_DESC="The values of the list." PLG_FIELDS_LIST_PARAMS_OPTIONS_LABEL="List Values" PLG_FIELDS_LIST_PARAMS_OPTIONS_VALUE_LABEL="Value" PLG_FIELDS_LIST_PARAMS_OPTIONS_NAME_LABEL="Text" diff --git a/administrator/language/en-GB/en-GB.plg_fields_media.ini b/administrator/language/en-GB/en-GB.plg_fields_media.ini index 8047cdc0858e6..cc7b0f3b21f6c 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_media.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_media.ini @@ -5,11 +5,8 @@ PLG_FIELDS_MEDIA="Fields - Media" PLG_FIELDS_MEDIA_LABEL="Media (%s)" -PLG_FIELDS_MEDIA_PARAMS_DIRECTORY_DESC="The directory with the image files to be listed relative to the default image folder (set in Media > Options)." PLG_FIELDS_MEDIA_PARAMS_DIRECTORY_LABEL="Directory" -PLG_FIELDS_MEDIA_PARAMS_IMAGE_CLASS_DESC="The class which is added to the image (src tag)." PLG_FIELDS_MEDIA_PARAMS_IMAGE_CLASS_LABEL="Image Class" -PLG_FIELDS_MEDIA_PARAMS_PREVIEW_DESC="Shows or hides the preview of the selected image." PLG_FIELDS_MEDIA_PARAMS_PREVIEW_INLINE="Inline" PLG_FIELDS_MEDIA_PARAMS_PREVIEW_LABEL="Preview" PLG_FIELDS_MEDIA_PARAMS_PREVIEW_TOOLTIP="Tooltip" diff --git a/administrator/language/en-GB/en-GB.plg_fields_radio.ini b/administrator/language/en-GB/en-GB.plg_fields_radio.ini index ca70c1b46c6b7..78ff40f018593 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_radio.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_radio.ini @@ -5,7 +5,6 @@ PLG_FIELDS_RADIO="Fields - Radio" PLG_FIELDS_RADIO_LABEL="Radio (%s)" -PLG_FIELDS_RADIO_PARAMS_OPTIONS_DESC="The values of the radio list." PLG_FIELDS_RADIO_PARAMS_OPTIONS_NAME_LABEL="Text" PLG_FIELDS_RADIO_PARAMS_OPTIONS_LABEL="Radio Values" PLG_FIELDS_RADIO_PARAMS_OPTIONS_VALUE_LABEL="Value" diff --git a/administrator/language/en-GB/en-GB.plg_fields_sql.ini b/administrator/language/en-GB/en-GB.plg_fields_sql.ini index 0ca95c90204ba..8e8c93c444226 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_sql.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_sql.ini @@ -6,7 +6,6 @@ PLG_FIELDS_SQL="Fields - SQL" PLG_FIELDS_SQL_CREATE_NOT_POSSIBLE="Only a Super User can create an SQL field!" PLG_FIELDS_SQL_LABEL="SQL (%s)" -PLG_FIELDS_SQL_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." PLG_FIELDS_SQL_PARAMS_MULTIPLE_LABEL="Multiple" ; In the string below the terms 'value' and 'text' should not be translated PLG_FIELDS_SQL_PARAMS_QUERY_DESC="The SQL query which will provide the data for the dropdown list. The query must return two columns; one called 'value' which will hold the values of the list items; the other called 'text' with the text in the dropdown list." diff --git a/administrator/language/en-GB/en-GB.plg_fields_text.ini b/administrator/language/en-GB/en-GB.plg_fields_text.ini index 41a1373d5de08..9fcbf1a2fac5d 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_text.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_text.ini @@ -5,8 +5,6 @@ PLG_FIELDS_TEXT="Fields - Text" PLG_FIELDS_TEXT_LABEL="Text (%s)" -PLG_FIELDS_TEXT_PARAMS_FILTER_DESC="Allow the system to save certain html tags or raw data." PLG_FIELDS_TEXT_PARAMS_FILTER_LABEL="Filter" -PLG_FIELDS_TEXT_PARAMS_MAXLENGTH_LABEL="Maximum Length" -PLG_FIELDS_TEXT_PARAMS_MAXLENGTH_DESC="The maximum number of characters that can be entered." +PLG_FIELDS_TEXT_PARAMS_MAXLENGTH_LABEL="Maximum Length (characters)" PLG_FIELDS_TEXT_XML_DESCRIPTION="This plugin lets you create new fields of type 'text' in any extensions where custom fields are supported." diff --git a/administrator/language/en-GB/en-GB.plg_fields_textarea.ini b/administrator/language/en-GB/en-GB.plg_fields_textarea.ini index 50c63b8fbf44f..92a286a90bf11 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_textarea.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_textarea.ini @@ -5,12 +5,8 @@ PLG_FIELDS_TEXTAREA="Fields - Textarea" PLG_FIELDS_TEXTAREA_LABEL="Text Area (%s)" -PLG_FIELDS_TEXTAREA_PARAMS_COLS_DESC="The width of the visible text area in characters. If omitted the width is determined by the browser. The value does not limit the number of characters that may be entered." PLG_FIELDS_TEXTAREA_PARAMS_COLS_LABEL="Columns" -PLG_FIELDS_TEXTAREA_PARAMS_FILTER_DESC="Allow the system to save certain html tags or raw data." PLG_FIELDS_TEXTAREA_PARAMS_FILTER_LABEL="Filter" -PLG_FIELDS_TEXTAREA_PARAMS_MAXLENGTH_LABEL="Maximum Length" -PLG_FIELDS_TEXTAREA_PARAMS_MAXLENGTH_DESC="The maximum number of characters that can be entered." -PLG_FIELDS_TEXTAREA_PARAMS_ROWS_DESC="The height of the visible text area in lines. If omitted the height is determined by the browser. The value does not limit the number of lines that may be entered." +PLG_FIELDS_TEXTAREA_PARAMS_MAXLENGTH_LABEL="Maximum Length (characters)" PLG_FIELDS_TEXTAREA_PARAMS_ROWS_LABEL="Rows" PLG_FIELDS_TEXTAREA_XML_DESCRIPTION="This plugin lets you create new fields of type 'textarea' in any extensions where custom fields are supported." diff --git a/administrator/language/en-GB/en-GB.plg_fields_url.ini b/administrator/language/en-GB/en-GB.plg_fields_url.ini index 4b0888a2c6522..54226d17319c3 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_url.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_url.ini @@ -5,8 +5,6 @@ PLG_FIELDS_URL="Fields - URL" PLG_FIELDS_URL_LABEL="URL (%s)" -PLG_FIELDS_URL_PARAMS_RELATIVE_DESC="Are relative URLs allowed." -PLG_FIELDS_URL_PARAMS_RELATIVE_LABEL="Relative" -PLG_FIELDS_URL_PARAMS_SCHEMES_DESC="The allowed schemes." +PLG_FIELDS_URL_PARAMS_RELATIVE_LABEL="Relative URLs" PLG_FIELDS_URL_PARAMS_SCHEMES_LABEL="Schemes" PLG_FIELDS_URL_XML_DESCRIPTION="This plugin lets you create new fields of type 'URL' in any extensions where custom fields are supported." diff --git a/administrator/language/en-GB/en-GB.plg_fields_user.ini b/administrator/language/en-GB/en-GB.plg_fields_user.ini index 5891df0721537..3a68374d893ba 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_user.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_user.ini @@ -4,7 +4,6 @@ ; Note : All ini files need to be saved as UTF-8 PLG_FIELDS_USER="Fields - User" -PLG_FIELDS_USER_DEFAULT_VALUE_DESC="The default user." PLG_FIELDS_USER_DEFAULT_VALUE_LABEL="Default User" PLG_FIELDS_USER_LABEL="User (%s)" PLG_FIELDS_USER_XML_DESCRIPTION="This plugin lets you create new fields of type 'user' in any extensions where custom fields are supported." diff --git a/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.ini b/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.ini index 97612a281a31f..0bfa19bc8bfc4 100644 --- a/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.ini +++ b/administrator/language/en-GB/en-GB.plg_fields_usergrouplist.ini @@ -7,6 +7,5 @@ PLG_FIELDS_USERGROUPLIST="Fields - Usergrouplist" PLG_FIELDS_USERGROUPLIST_DEFAULT_VALUE_DESC="A comma separated list of user group ids." PLG_FIELDS_USERGROUPLIST_DEFAULT_VALUE_LABEL="Default User Groups" PLG_FIELDS_USERGROUPLIST_LABEL="User Groups (%s)" -PLG_FIELDS_USERGROUPLIST_PARAMS_MULTIPLE_DESC="Allow multiple values to be selected." PLG_FIELDS_USERGROUPLIST_PARAMS_MULTIPLE_LABEL="Multiple" PLG_FIELDS_USERGROUPLIST_XML_DESCRIPTION="This plugin lets you create new fields of type 'usergrouplist' in any extensions where custom fields are supported." diff --git a/administrator/language/en-GB/en-GB.plg_filesystem_local.ini b/administrator/language/en-GB/en-GB.plg_filesystem_local.ini new file mode 100644 index 0000000000000..6f33c7dfac757 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_filesystem_local.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_FILESYSTEM_LOCAL="FileSystem - Local" +PLG_FILESYSTEM_LOCAL_DEFAULT_NAME="Local" +PLG_FILESYSTEM_LOCAL_DIRECTORIES_DIRECTORY_LABEL="Select directories" +PLG_FILESYSTEM_LOCAL_DIRECTORIES_LABEL="Directories" +PLG_FILESYSTEM_LOCAL_XML_DESCRIPTION="Filesystem plugin to define one or multiple local repositories to store your media files." diff --git a/administrator/language/en-GB/en-GB.plg_filesystem_local.sys.ini b/administrator/language/en-GB/en-GB.plg_filesystem_local.sys.ini new file mode 100644 index 0000000000000..ab57762e81ec4 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_filesystem_local.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_FILESYSTEM_LOCAL="FileSystem - Local" +PLG_FILESYSTEM_LOCAL_XML_DESCRIPTION="Filesystem plugin to define one or multiple local repositories to store your media files." diff --git a/administrator/language/en-GB/en-GB.plg_finder_categories.sys.ini b/administrator/language/en-GB/en-GB.plg_finder_categories.sys.ini index 0864389ae1825..17e4de302eea2 100644 --- a/administrator/language/en-GB/en-GB.plg_finder_categories.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_finder_categories.sys.ini @@ -4,6 +4,5 @@ ; Note : All ini files need to be saved as UTF-8 PLG_FINDER_CATEGORIES="Smart Search - Categories" -PLG_FINDER_CATEGORIES_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Categories" plugin." PLG_FINDER_CATEGORIES_XML_DESCRIPTION="This plugin indexes Joomla! Categories." PLG_FINDER_STATISTICS_CATEGORY="Category" diff --git a/administrator/language/en-GB/en-GB.plg_finder_contacts.sys.ini b/administrator/language/en-GB/en-GB.plg_finder_contacts.sys.ini index 832df889f448f..81096d6c915f0 100644 --- a/administrator/language/en-GB/en-GB.plg_finder_contacts.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_finder_contacts.sys.ini @@ -4,6 +4,5 @@ ; Note : All ini files need to be saved as UTF-8 PLG_FINDER_CONTACTS="Smart Search - Contacts" -PLG_FINDER_CONTACTS_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Contacts" plugin." PLG_FINDER_CONTACTS_XML_DESCRIPTION="This plugin indexes Joomla! Contacts." PLG_FINDER_STATISTICS_CONTACT="Contact" diff --git a/administrator/language/en-GB/en-GB.plg_finder_content.sys.ini b/administrator/language/en-GB/en-GB.plg_finder_content.sys.ini index 89a8134851e76..8cd359314a1cd 100644 --- a/administrator/language/en-GB/en-GB.plg_finder_content.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_finder_content.sys.ini @@ -4,6 +4,5 @@ ; Note : All ini files need to be saved as UTF-8 PLG_FINDER_CONTENT="Smart Search - Content" -PLG_FINDER_CONTENT_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Content" plugin." PLG_FINDER_CONTENT_XML_DESCRIPTION="Updates the indexes of Joomla! Articles whenever an article is created, modified or deleted. NOTE the Content - Smart Search plugin must be enabled." PLG_FINDER_STATISTICS_ARTICLE="Article" diff --git a/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.sys.ini b/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.sys.ini index 857f3d30dcd98..750ad43a72c3a 100644 --- a/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_finder_newsfeeds.sys.ini @@ -4,6 +4,5 @@ ; Note : All ini files need to be saved as UTF-8 PLG_FINDER_NEWSFEEDS="Smart Search - News Feeds" -PLG_FINDER_NEWSFEEDS_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Joomla! News Feeds" plugin." PLG_FINDER_NEWSFEEDS_XML_DESCRIPTION="This plugin indexes Joomla! News feeds." PLG_FINDER_STATISTICS_NEWS_FEED="News Feed" diff --git a/administrator/language/en-GB/en-GB.plg_finder_tags.sys.ini b/administrator/language/en-GB/en-GB.plg_finder_tags.sys.ini index 7ed87669dcaf5..8bf3b7922de6b 100644 --- a/administrator/language/en-GB/en-GB.plg_finder_tags.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_finder_tags.sys.ini @@ -5,5 +5,4 @@ PLG_FINDER_STATISTICS_TAG="Tag" PLG_FINDER_TAGS="Smart Search - Tags" -PLG_FINDER_TAGS_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Tags" plugin." PLG_FINDER_TAGS_XML_DESCRIPTION="This plugin indexes Joomla! Tags." diff --git a/administrator/language/en-GB/en-GB.plg_finder_weblinks.ini b/administrator/language/en-GB/en-GB.plg_finder_weblinks.ini deleted file mode 100644 index aaf6bc174fae3..0000000000000 --- a/administrator/language/en-GB/en-GB.plg_finder_weblinks.ini +++ /dev/null @@ -1,10 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -PLG_FINDER_WEBLINKS="Smart Search - Web Links" -PLG_FINDER_WEBLINKS_XML_DESCRIPTION="This plugin indexes Joomla! Web Links." - -PLG_FINDER_QUERY_FILTER_BRANCH_P_WEB_LINK="Web links" -PLG_FINDER_QUERY_FILTER_BRANCH_S_WEB_LINK="Web link" diff --git a/administrator/language/en-GB/en-GB.plg_finder_weblinks.sys.ini b/administrator/language/en-GB/en-GB.plg_finder_weblinks.sys.ini deleted file mode 100644 index 20094e1b40b47..0000000000000 --- a/administrator/language/en-GB/en-GB.plg_finder_weblinks.sys.ini +++ /dev/null @@ -1,9 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -PLG_FINDER_STATISTICS_WEB_LINK="Web Link" -PLG_FINDER_WEBLINKS="Smart Search - Web Links" -PLG_FINDER_WEBLINKS_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "Smart Search - Web Links" plugin." -PLG_FINDER_WEBLINKS_XML_DESCRIPTION="This plugin indexes Joomla! Web Links." diff --git a/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini b/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini index e90fecdaf6e53..c2cee64013400 100644 --- a/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini +++ b/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini @@ -4,7 +4,6 @@ ; Note : All ini files need to be saved as UTF-8 PLG_INSTALLER_URLINSTALLER_BUTTON="Check and Install" -PLG_INSTALLER_URLINSTALLER_INSTALLER_URLFOLDERINSTALLER="Installer - Install from URL." PLG_INSTALLER_URLINSTALLER_NO_URL="Please enter a URL." PLG_INSTALLER_URLINSTALLER_PLUGIN_XML_DESCRIPTION="This plugin allows you to install packages from a URL." PLG_INSTALLER_URLINSTALLER_TEXT="Install from URL" diff --git a/administrator/language/en-GB/en-GB.plg_installer_webinstaller.ini b/administrator/language/en-GB/en-GB.plg_installer_webinstaller.ini index 82610224c18eb..edbdd8cee7fbf 100644 --- a/administrator/language/en-GB/en-GB.plg_installer_webinstaller.ini +++ b/administrator/language/en-GB/en-GB.plg_installer_webinstaller.ini @@ -4,9 +4,7 @@ ; Note : All ini files need to be saved as UTF-8 PLG_INSTALLER_WEBINSTALLER="Installer - Install from Web" -PLG_INSTALLER_WEBINSTALLER_LOAD_APPS="Display the extensions" -PLG_INSTALLER_WEBINSTALLER_TAB_POSITION_DESC="Place the Install from Web tab first or last." -PLG_INSTALLER_WEBINSTALLER_TAB_POSITION_LABEL="Tab Position" -PLG_INSTALLER_WEBINSTALLER_TAB_POSITION_FIRST="First" -PLG_INSTALLER_WEBINSTALLER_TAB_POSITION_LAST="Last" -PLG_INSTALLER_WEBINSTALLER_XML_DESCRIPTION="This plugin offers functionality for the 'Install from Web' tab." +PLG_INSTALLER_WEBINSTALLER_CANNOT_INSTALL_EXTENSION_IN_PLUGIN="This extension cannot be installed via the install from web system. Please visit the developer's website to purchase/download." +; The [SITEURL] placeholder should not be translated as it is used in the JavaScript API to insert the correct URL +PLG_INSTALLER_WEBINSTALLER_REDIRECT_TO_EXTERNAL_SITE_TO_INSTALL="You will be redirected to the following link to complete the registration/purchase: [SITEURL]" +PLG_INSTALLER_WEBINSTALLER_XML_DESCRIPTION="This plugin allows you to install directly from the Joomla! Extension Directory." diff --git a/administrator/language/en-GB/en-GB.plg_installer_webinstaller.sys.ini b/administrator/language/en-GB/en-GB.plg_installer_webinstaller.sys.ini index 5149faf128a85..1d168780533e4 100644 --- a/administrator/language/en-GB/en-GB.plg_installer_webinstaller.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_installer_webinstaller.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_INSTALLER_WEBINSTALLER="Installer - Install from Web" -PLG_INSTALLER_WEBINSTALLER_XML_DESCRIPTION="This plugin offers functionality for the 'Install from Web' tab." +PLG_INSTALLER_WEBINSTALLER_XML_DESCRIPTION="This plugin allows you to install directly from the Joomla! Extension Directory." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_media-action_crop.ini b/administrator/language/en-GB/en-GB.plg_media-action_crop.ini new file mode 100644 index 0000000000000..e01618c865de3 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_media-action_crop.ini @@ -0,0 +1,17 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_MEDIA-ACTION_CROP="Media Action - Crop" +PLG_MEDIA-ACTION_CROP_LABEL="Crop" +PLG_MEDIA-ACTION_CROP_PARAM_DEFAULT_RATIO="Default aspect ratio" +PLG_MEDIA-ACTION_CROP_PARAM_HEIGHT="Height" +PLG_MEDIA-ACTION_CROP_PARAM_LANDSCAPE="Landscape" +PLG_MEDIA-ACTION_CROP_PARAM_NO_RATIO="None" +PLG_MEDIA-ACTION_CROP_PARAM_PORTRAIT="Portrait" +PLG_MEDIA-ACTION_CROP_PARAM_WIDTH="Width" +PLG_MEDIA-ACTION_CROP_PARAM_X="X-Axis" +PLG_MEDIA-ACTION_CROP_PARAM_Y="Y-Axis" +PLG_MEDIA-ACTION_CROP_QUALITY="Quality" +PLG_MEDIA-ACTION_CROP_XML_DESCRIPTION="Adds crop functionality for images." diff --git a/administrator/language/en-GB/en-GB.plg_media-action_crop.sys.ini b/administrator/language/en-GB/en-GB.plg_media-action_crop.sys.ini new file mode 100644 index 0000000000000..e42e5458cb7cc --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_media-action_crop.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_MEDIA-ACTION_CROP="Media Action - Crop" +PLG_MEDIA-ACTION_CROP_XML_DESCRIPTION="Crop functionality for images." diff --git a/administrator/language/en-GB/en-GB.plg_media-action_resize.ini b/administrator/language/en-GB/en-GB.plg_media-action_resize.ini new file mode 100644 index 0000000000000..f95b14660d45d --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_media-action_resize.ini @@ -0,0 +1,17 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_MEDIA-ACTION_RESIZE="Media Action - Resize" +PLG_MEDIA-ACTION_RESIZE_BATCH_DESC="Settings for server side actions when images are created." +PLG_MEDIA-ACTION_RESIZE_BATCH_LABEL="Batch Settings" +PLG_MEDIA-ACTION_RESIZE_BATCH_MAX_HEIGHT_LABEL="Image Max Height" +PLG_MEDIA-ACTION_RESIZE_BATCH_MAX_HEIGHT_DESC="The maximum height of an image to resize. When empty, no resizing is performed." +PLG_MEDIA-ACTION_RESIZE_BATCH_MAX_WIDTH_LABEL="Image Max Width" +PLG_MEDIA-ACTION_RESIZE_BATCH_MAX_WIDTH_DESC="The maximum width of an image to resize. When empty, no resizing is performed." +PLG_MEDIA-ACTION_RESIZE_LABEL="Resize" +PLG_MEDIA-ACTION_RESIZE_PARAM_WIDTH="Width" +PLG_MEDIA-ACTION_RESIZE_PARAM_HEIGHT="Height" +PLG_MEDIA-ACTION_RESIZE_QUALITY="Quality" +PLG_MEDIA-ACTION_RESIZE_XML_DESCRIPTION="Resize functionality for images." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_media-action_resize.sys.ini b/administrator/language/en-GB/en-GB.plg_media-action_resize.sys.ini new file mode 100644 index 0000000000000..9bcb3d19d9f4d --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_media-action_resize.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_MEDIA-ACTION_RESIZE="Media Action - Resize" +PLG_MEDIA-ACTION_RESIZE_XML_DESCRIPTION="Resize functionality for images." diff --git a/administrator/language/en-GB/en-GB.plg_media-action_rotate.ini b/administrator/language/en-GB/en-GB.plg_media-action_rotate.ini new file mode 100644 index 0000000000000..6de686440a3b3 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_media-action_rotate.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_MEDIA-ACTION_ROTATE="Media Action - Rotate" +PLG_MEDIA-ACTION_ROTATE_LABEL="Rotate" +PLG_MEDIA-ACTION_ROTATE_PARAM_ANGLE="Angle" +PLG_MEDIA-ACTION_ROTATE_PARAM_DIRECTION="Direction" +PLG_MEDIA-ACTION_ROTATE_PARAM_DIRECTION_RIGHT="Right" +PLG_MEDIA-ACTION_ROTATE_PARAM_DIRECTION_LEFT="Left" +PLG_MEDIA-ACTION_ROTATE_QUALITY="Quality" +PLG_MEDIA-ACTION_ROTATE_XML_DESCRIPTION="Adds rotate functionality for images." diff --git a/administrator/language/en-GB/en-GB.plg_media-action_rotate.sys.ini b/administrator/language/en-GB/en-GB.plg_media-action_rotate.sys.ini new file mode 100644 index 0000000000000..061e274a0efe9 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_media-action_rotate.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_MEDIA-ACTION_ROTATE="Media Action - Rotate" +PLG_MEDIA-ACTION_ROTATE_XML_DESCRIPTION="Adds rotate functionality for images." diff --git a/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.ini b/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.ini index 81f7d7b690757..8ce9d51c961f3 100644 --- a/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.ini +++ b/administrator/language/en-GB/en-GB.plg_quickicon_extensionupdate.ini @@ -8,8 +8,8 @@ PLG_QUICKICON_EXTENSIONUPDATE_CHECKING="Checking extensions ..." PLG_QUICKICON_EXTENSIONUPDATE_ERROR="Unknown extensions ..." PLG_QUICKICON_EXTENSIONUPDATE_GROUP_DESC="The group of this plugin (this value is compared with the group value used in Quick Icons modules to inject icons)." PLG_QUICKICON_EXTENSIONUPDATE_GROUP_LABEL="Group" -PLG_QUICKICON_EXTENSIONUPDATE_UPDATEFOUND="Updates are available! %s" +PLG_QUICKICON_EXTENSIONUPDATE_UPDATEFOUND="Updates are available! %s" PLG_QUICKICON_EXTENSIONUPDATE_UPDATEFOUND_BUTTON="View Updates" -PLG_QUICKICON_EXTENSIONUPDATE_UPDATEFOUND_MESSAGE="%s Extension Update(s) are available:" -PLG_QUICKICON_EXTENSIONUPDATE_UPTODATE="All extensions are up to date." +PLG_QUICKICON_EXTENSIONUPDATE_UPDATEFOUND_MESSAGE="%s Extension Update(s) are available:" +PLG_QUICKICON_EXTENSIONUPDATE_UPTODATE="Extensions are up to date." PLG_QUICKICON_EXTENSIONUPDATE_XML_DESCRIPTION="Checks for updates of your installed third-party extensions and notifies you when you visit the Control Panel page." diff --git a/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.ini b/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.ini index 7541d4d7f15c6..3892948912ac5 100644 --- a/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.ini +++ b/administrator/language/en-GB/en-GB.plg_quickicon_joomlaupdate.ini @@ -4,12 +4,12 @@ ; Note : All ini files need to be saved as UTF-8 PLG_QUICKICON_JOOMLAUPDATE="Quick Icon - Joomla Update Notification" -PLG_QUICKICON_JOOMLAUPDATE_CHECKING="Checking Joomla..." -PLG_QUICKICON_JOOMLAUPDATE_ERROR="Unknown Joomla..." +PLG_QUICKICON_JOOMLAUPDATE_CHECKING="Checking Joomla ..." +PLG_QUICKICON_JOOMLAUPDATE_ERROR="Unknown Joomla ..." PLG_QUICKICON_JOOMLAUPDATE_GROUP_DESC="The group of this plugin (this value is compared with the group value used in Quick Icons modules to inject icons)." PLG_QUICKICON_JOOMLAUPDATE_GROUP_LABEL="Group" -PLG_QUICKICON_JOOMLAUPDATE_UPDATEFOUND="Joomla %s, Update now!" +PLG_QUICKICON_JOOMLAUPDATE_UPDATEFOUND="Joomla %s, Update now!" PLG_QUICKICON_JOOMLAUPDATE_UPDATEFOUND_BUTTON="Update Now" -PLG_QUICKICON_JOOMLAUPDATE_UPDATEFOUND_MESSAGE="Joomla %s is available:" +PLG_QUICKICON_JOOMLAUPDATE_UPDATEFOUND_MESSAGE="Joomla %s is available:" PLG_QUICKICON_JOOMLAUPDATE_UPTODATE="Joomla is up to date." PLG_QUICKICON_JOOMLAUPDATE_XML_DESCRIPTION="Checks for Joomla updates and notifies you when you visit the Control Panel page." diff --git a/administrator/language/en-GB/en-GB.plg_sampledata_blog.ini b/administrator/language/en-GB/en-GB.plg_sampledata_blog.ini index 18cc9629640c8..bc7651c8b227b 100644 --- a/administrator/language/en-GB/en-GB.plg_sampledata_blog.ini +++ b/administrator/language/en-GB/en-GB.plg_sampledata_blog.ini @@ -61,4 +61,5 @@ PLG_SAMPLEDATA_BLOG_STEP_SKIPPED="Step %1$u Skipped: '%2$s' is either not instal PLG_SAMPLEDATA_BLOG_STEP1_SUCCESS="Step 1: Articles done!" PLG_SAMPLEDATA_BLOG_STEP2_SUCCESS="Step 2: Menus done!" PLG_SAMPLEDATA_BLOG_STEP3_SUCCESS="Step 3: Modules done!" +PLG_SAMPLEDATA_BLOG_STEP4_SUCCESS="Blog Sample Data has been installed!" PLG_SAMPLEDATA_BLOG_XML_DESCRIPTION="Provides the blog sample data. Can be installed using the sample data module." diff --git a/administrator/language/en-GB/en-GB.plg_sampledata_multilang.ini b/administrator/language/en-GB/en-GB.plg_sampledata_multilang.ini new file mode 100644 index 0000000000000..b471c7da3ff55 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_sampledata_multilang.ini @@ -0,0 +1,32 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SAMPLEDATA_MULTILANG="Sample Data - Multilingual" +PLG_SAMPLEDATA_MULTILANG_ERROR_ALLCATEGORIES="Step %1$u: Failed creating the 'List All Categories (%2$s)' menu item." +PLG_SAMPLEDATA_MULTILANG_ERROR_ARTICLE="Step %1$u: Failed creating the Article (%2$s)." +PLG_SAMPLEDATA_MULTILANG_ERROR_ASSOC_ALLCATEGORIES="Step %1$u: Failed associating the 'List All Categories' menu items." +PLG_SAMPLEDATA_MULTILANG_ERROR_ASSOC_VARIOUS="Step %1$u: Failed associating some categories, articles or 'Category Blog' menu items." +PLG_SAMPLEDATA_MULTILANG_ERROR_BLOG="Step %1$u: Failed creating the 'Category Blog (%2$s)' menu item." +PLG_SAMPLEDATA_MULTILANG_ERROR_CATEGORY="Step %1$u: Failed creating the Category (%2$s)." +PLG_SAMPLEDATA_MULTILANG_ERROR_CONTENTLANGUAGES="Step %1$u: Failed publishing some content languages." +PLG_SAMPLEDATA_MULTILANG_ERROR_LANGFILTER="Step %1$u: Failed enabling the %2$s plugin." +PLG_SAMPLEDATA_MULTILANG_ERROR_MAINMENU_MODULE="Step %1$u: Failed unpublishing the 'Main Menu' Module containing the 'Home' menu item set to ALL languages." +PLG_SAMPLEDATA_MULTILANG_ERROR_MENUMODULES="Step %1$u: Failed creating the %2$s menu module." +PLG_SAMPLEDATA_MULTILANG_ERROR_MENUS="Step %1$u: Failed creating the Main menu (%2$s)." +PLG_SAMPLEDATA_MULTILANG_ERROR_SWITCHER="Step %1$u: Failed creating and enabling the %2$s." +PLG_SAMPLEDATA_MULTILANG_MISSING_LANGUAGE="The site should have at least 2 languages installed and their content languages created." +PLG_SAMPLEDATA_MULTILANG_OVERVIEW_DESC="Sample data which will set up a multilingual site.
    Before launching, make sure you have at least 2 languages installed with their Content Languages and that no sample data has been installed." +PLG_SAMPLEDATA_MULTILANG_OVERVIEW_TITLE="Multilingual Sample Data" +PLG_SAMPLEDATA_MULTILANG_STEP1_SUCCESS="Step 1: The Language Filter plugin has been enabled!" +PLG_SAMPLEDATA_MULTILANG_STEP2_SUCCESS="Step 2: The Language Switcher module has been created and published!" +PLG_SAMPLEDATA_MULTILANG_STEP3_SUCCESS="Step 3: All Content Languages have been published!" +PLG_SAMPLEDATA_MULTILANG_STEP4_SUCCESS="Step 4: Specific Main Menus have been created as well as associated 'List All Categories' menu items!" +PLG_SAMPLEDATA_MULTILANG_STEP5_SUCCESS="Step 5: Specific Main Menus modules have been created!" +PLG_SAMPLEDATA_MULTILANG_STEP6_SUCCESS="Step 6: Categories, articles and 'Category Blog' menu items have been created and associated!" +PLG_SAMPLEDATA_MULTILANG_STEP7_SUCCESS="Step 7: The Main Menu Module containing the Home menu item set to ALL languages has been unpublished!" +PLG_SAMPLEDATA_MULTILANG_STEP8_SUCCESS="Multilingual Sample Data has been installed!" +PLG_SAMPLEDATA_MULTILANG_STEP_FAILED="Step %1$u Failed: %2$s" +PLG_SAMPLEDATA_MULTILANG_STEP_SKIPPED="Step %1$u Skipped: '%2$s' is either not installed or disabled." +PLG_SAMPLEDATA_MULTILANG_XML_DESCRIPTION="Provides the multilingual sample data. Can be installed using the sample data module." diff --git a/administrator/language/en-GB/en-GB.plg_sampledata_multilang.sys.ini b/administrator/language/en-GB/en-GB.plg_sampledata_multilang.sys.ini new file mode 100644 index 0000000000000..3e148e96eb24c --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_sampledata_multilang.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SAMPLEDATA_MULTILANG="Sample Data - Multilingual" +PLG_SAMPLEDATA_MULTILANG_XML_DESCRIPTION="Provides the multilingual sample data. Can be installed using the sample data module." diff --git a/administrator/language/en-GB/en-GB.plg_search_categories.ini b/administrator/language/en-GB/en-GB.plg_search_categories.ini index cc032df4669f3..add46f4ba4130 100644 --- a/administrator/language/en-GB/en-GB.plg_search_categories.ini +++ b/administrator/language/en-GB/en-GB.plg_search_categories.ini @@ -6,6 +6,4 @@ PLG_SEARCH_CATEGORIES_CATEGORIES="Categories" PLG_SEARCH_CATEGORIES="Search - Categories" -PLG_SEARCH_CATEGORIES_FIELD_SEARCHLIMIT_DESC="Number of search items to return." -PLG_SEARCH_CATEGORIES_FIELD_SEARCHLIMIT_LABEL="Search Limit" PLG_SEARCH_CATEGORIES_XML_DESCRIPTION="Enables searching of Category information." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_search_contacts.ini b/administrator/language/en-GB/en-GB.plg_search_contacts.ini index 81003bcd7ab7d..57c67434a3311 100644 --- a/administrator/language/en-GB/en-GB.plg_search_contacts.ini +++ b/administrator/language/en-GB/en-GB.plg_search_contacts.ini @@ -5,6 +5,4 @@ PLG_SEARCH_CONTACTS="Search - Contacts" PLG_SEARCH_CONTACTS_CONTACTS="Contacts" -PLG_SEARCH_CONTACTS_FIELD_SEARCHLIMIT_DESC="Number of search items to return." -PLG_SEARCH_CONTACTS_FIELD_SEARCHLIMIT_LABEL="Search Limit" PLG_SEARCH_CONTACTS_XML_DESCRIPTION="Enables searching of the Contact Component." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_search_content.ini b/administrator/language/en-GB/en-GB.plg_search_content.ini index f7cfa5bd77c83..281f18519b982 100644 --- a/administrator/language/en-GB/en-GB.plg_search_content.ini +++ b/administrator/language/en-GB/en-GB.plg_search_content.ini @@ -4,10 +4,7 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SEARCH_CONTENT="Search - Content" -PLG_SEARCH_CONTENT_FIELD_ARCHIVED_DESC="Enables searching of Archived Articles." PLG_SEARCH_CONTENT_FIELD_ARCHIVED_LABEL="Archived Articles" -PLG_SEARCH_CONTENT_FIELD_CONTENT_DESC="Enables searching of all Articles." PLG_SEARCH_CONTENT_FIELD_CONTENT_LABEL="Articles" -PLG_SEARCH_CONTENT_FIELD_SEARCHLIMIT_DESC="Number of search items to return." PLG_SEARCH_CONTENT_FIELD_SEARCHLIMIT_LABEL="Search Limit" PLG_SEARCH_CONTENT_XML_DESCRIPTION="Enables searching in Articles." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_search_newsfeeds.ini b/administrator/language/en-GB/en-GB.plg_search_newsfeeds.ini index 3cc45d5b7d182..28e12699c1587 100644 --- a/administrator/language/en-GB/en-GB.plg_search_newsfeeds.ini +++ b/administrator/language/en-GB/en-GB.plg_search_newsfeeds.ini @@ -4,7 +4,5 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SEARCH_NEWSFEEDS="Search - News Feeds" -PLG_SEARCH_NEWSFEEDS_FIELD_SEARCHLIMIT_DESC="Number of search items to return." -PLG_SEARCH_NEWSFEEDS_FIELD_SEARCHLIMIT_LABEL="Search Limit" PLG_SEARCH_NEWSFEEDS_NEWSFEEDS="News Feeds" PLG_SEARCH_NEWSFEEDS_XML_DESCRIPTION="Enables searching of News feeds." diff --git a/administrator/language/en-GB/en-GB.plg_search_tags.ini b/administrator/language/en-GB/en-GB.plg_search_tags.ini index b37087a9ebd85..d750e564ff22f 100644 --- a/administrator/language/en-GB/en-GB.plg_search_tags.ini +++ b/administrator/language/en-GB/en-GB.plg_search_tags.ini @@ -4,10 +4,7 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SEARCH_TAGS="Search - Tags" -PLG_SEARCH_TAGS_FIELD_SEARCHLIMIT_DESC="Number of search items to return." -PLG_SEARCH_TAGS_FIELD_SEARCHLIMIT_LABEL="Search Limit" -PLG_SEARCH_TAGS_FIELD_SHOW_TAGGED_ITEMS_DESC="Display or not the items that hold the tags related to the search." -PLG_SEARCH_TAGS_FIELD_SHOW_TAGGED_ITEMS_LABEL="Show Tagged Items" +PLG_SEARCH_TAGS_FIELD_SHOW_TAGGED_ITEMS_LABEL="Tagged Items" PLG_SEARCH_TAGS_ITEM_TAGGED_WITH="%s tagged with: %s" PLG_SEARCH_TAGS_TAGS="Tags" PLG_SEARCH_TAGS_XML_DESCRIPTION="Enables searching in Tags." diff --git a/administrator/language/en-GB/en-GB.plg_search_weblinks.ini b/administrator/language/en-GB/en-GB.plg_search_weblinks.ini deleted file mode 100644 index 518ef8613bea0..0000000000000 --- a/administrator/language/en-GB/en-GB.plg_search_weblinks.ini +++ /dev/null @@ -1,10 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -PLG_SEARCH_WEBLINKS="Search - Web Links" -PLG_SEARCH_WEBLINKS_FIELD_SEARCHLIMIT_DESC="Number of search items to return." -PLG_SEARCH_WEBLINKS_FIELD_SEARCHLIMIT_LABEL="Search Limit" -PLG_SEARCH_WEBLINKS_WEBLINKS="Web Links" -PLG_SEARCH_WEBLINKS_XML_DESCRIPTION="Enables searching of Web Links Component." diff --git a/administrator/language/en-GB/en-GB.plg_search_weblinks.sys.ini b/administrator/language/en-GB/en-GB.plg_search_weblinks.sys.ini deleted file mode 100644 index c115072d73360..0000000000000 --- a/administrator/language/en-GB/en-GB.plg_search_weblinks.sys.ini +++ /dev/null @@ -1,7 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -PLG_SEARCH_WEBLINKS="Search - Web Links" -PLG_SEARCH_WEBLINKS_XML_DESCRIPTION="Enables searching of Web Links Component." diff --git a/administrator/language/en-GB/en-GB.plg_system_cache.ini b/administrator/language/en-GB/en-GB.plg_system_cache.ini index 91daea815a0bb..d8c619ac39ad9 100644 --- a/administrator/language/en-GB/en-GB.plg_system_cache.ini +++ b/administrator/language/en-GB/en-GB.plg_system_cache.ini @@ -3,13 +3,9 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 -PLG_CACHE_FIELD_BROWSERCACHE_DESC="If yes, use mechanism for storing page cache in the browser." PLG_CACHE_FIELD_BROWSERCACHE_LABEL="Use Browser Caching" -PLG_CACHE_FIELD_EXCLUDE_DESC="Specify which URLs you want to exclude from caching, each on a separate line. Regular expressions are supported, eg.
    about\-[a-z]+ - will exclude all URLs that have 'about-', for example 'about-us', 'about-me', 'about-joomla' etc.
    \/component\/users\/ - will exclude all URLs that have /component/users/" +PLG_CACHE_FIELD_EXCLUDE_DESC="Specify which URLs you want to exclude from caching, each on a separate line. Regular expressions are supported, eg.
    about\-[a-z]+ - will exclude all URLs that have 'about-', for example 'about-us', 'about-me', 'about-joomla' etc.
    \/component\/users\/ - will exclude all URLs that have /component/users/" PLG_CACHE_FIELD_EXCLUDE_LABEL="Exclude URLs" -PLG_CACHE_FIELD_EXCLUDE_MENU_ITEMS_DESC="Select which menu items you want to exclude from caching." PLG_CACHE_FIELD_EXCLUDE_MENU_ITEMS_LABEL="Exclude Menu Items" -PLG_CACHE_FIELD_LIFETIME_DESC="Page cache lifetime in minutes." -PLG_CACHE_FIELD_LIFETIME_LABEL="Cache Lifetime" PLG_CACHE_XML_DESCRIPTION="Provides page caching." PLG_SYSTEM_CACHE="System - Page Cache" diff --git a/administrator/language/en-GB/en-GB.plg_system_debug.ini b/administrator/language/en-GB/en-GB.plg_system_debug.ini index b626d0d91f58e..1ededccde7b7c 100644 --- a/administrator/language/en-GB/en-GB.plg_system_debug.ini +++ b/administrator/language/en-GB/en-GB.plg_system_debug.ini @@ -10,52 +10,36 @@ PLG_DEBUG_CALL_STACK_FILE_AND_LINE="File and line number" PLG_DEBUG_CALL_STACK_SAME_FILE="Same as call in the line below." PLG_DEBUG_ERRORS="Errors" PLG_DEBUG_EXPLAIN="Explain" -PLG_DEBUG_FIELD_ALLOWED_GROUPS_DESC="Optionally restrict users that can see debug information to those in the selected user groups. If none selected, all users will see the debug information." PLG_DEBUG_FIELD_ALLOWED_GROUPS_LABEL="Allowed Groups" -PLG_DEBUG_FIELD_EXECUTEDSQL_DESC="If enabled, executed SQL queries will be logged. Only use this setting for short periods of time and for benchmarking purposes." PLG_DEBUG_FIELD_EXECUTEDSQL_LABEL="Log Executed Queries" -PLG_DEBUG_FIELD_LANGUAGE_ERRORFILES_DESC="Display a list of the language files that are in error according to the Joomla ini specification." -PLG_DEBUG_FIELD_LANGUAGE_ERRORFILES_LABEL="Show Errors When Parsing Language Files" -PLG_DEBUG_FIELD_LANGUAGE_FILES_DESC="Display a list of the language files that Joomla has tried to load." -PLG_DEBUG_FIELD_LANGUAGE_FILES_LABEL="Show Language Files" -PLG_DEBUG_FIELD_LANGUAGE_STRING_DESC="Display a list of the untranslated language strings." -PLG_DEBUG_FIELD_LANGUAGE_STRING_LABEL="Show Language String" -PLG_DEBUG_FIELD_LOGS_DESC="Display a list of logged messages." -PLG_DEBUG_FIELD_LOGS_LABEL="Show Log Entries" +PLG_DEBUG_FIELD_LANGUAGE_ERRORFILES_LABEL="Errors When Parsing Language Files" +PLG_DEBUG_FIELD_LANGUAGE_FILES_LABEL="Language Files" +PLG_DEBUG_FIELD_LANGUAGE_STRING_LABEL="Language String" +PLG_DEBUG_FIELD_LOGS_LABEL="Log Entries" PLG_DEBUG_FIELD_LOG_CATEGORIES_DESC="A comma separated list of log categories to include. Common log categories include but are not limited to: database, databasequery, database-error, deprecated and jerror. If empty, all categories will be shown." PLG_DEBUG_FIELD_LOG_CATEGORIES_LABEL="Log Categories" -PLG_DEBUG_FIELD_LOG_CATEGORY_MODE_DESC="Select if the listed categories should be included or excluded." PLG_DEBUG_FIELD_LOG_CATEGORY_MODE_EXCLUDE="Exclude" PLG_DEBUG_FIELD_LOG_CATEGORY_MODE_INCLUDE="Include" PLG_DEBUG_FIELD_LOG_CATEGORY_MODE_LABEL="Log Category Mode" -PLG_DEBUG_FIELD_LOG_DEPRECATED_DESC="If enabled, API marked as deprecated will be logged. Only use this setting for short periods of time for refactoring purposes." PLG_DEBUG_FIELD_LOG_DEPRECATED_LABEL="Log Deprecated API" -PLG_DEBUG_FIELD_LOG_EVERYTHING_DESC="If enabled, all log messages produced by Joomla! will be logged except for deprecated API and database queries. Only use this setting for short periods of time for site debugging purposes." PLG_DEBUG_FIELD_LOG_EVERYTHING_LABEL="Log Almost Everything" PLG_DEBUG_FIELD_LOG_PRIORITIES_ALERT="Alert" PLG_DEBUG_FIELD_LOG_PRIORITIES_ALL="All" PLG_DEBUG_FIELD_LOG_PRIORITIES_CRITICAL="Critical" PLG_DEBUG_FIELD_LOG_PRIORITIES_DEBUG="Debug" -PLG_DEBUG_FIELD_LOG_PRIORITIES_DESC="Select which log priority levels to display." PLG_DEBUG_FIELD_LOG_PRIORITIES_EMERGENCY="Emergency" PLG_DEBUG_FIELD_LOG_PRIORITIES_ERROR="Error" PLG_DEBUG_FIELD_LOG_PRIORITIES_INFO="Info" PLG_DEBUG_FIELD_LOG_PRIORITIES_LABEL="Log Priorities" PLG_DEBUG_FIELD_LOG_PRIORITIES_NOTICE="Notice" PLG_DEBUG_FIELD_LOG_PRIORITIES_WARNING="Warning" -PLG_DEBUG_FIELD_MEMORY_DESC="Display the total memory usage." -PLG_DEBUG_FIELD_MEMORY_LABEL="Show Memory Usage" -PLG_DEBUG_FIELD_PROFILING_DESC="Display the profiling waypoints." -PLG_DEBUG_FIELD_PROFILING_LABEL="Show Profiling" -PLG_DEBUG_FIELD_QUERIES_DESC="Display a list of the queries executed while displaying the page." -PLG_DEBUG_FIELD_QUERIES_LABEL="Show Queries" -PLG_DEBUG_FIELD_QUERY_TYPES_DESC="Display a list of unique query types and their number of occurrences for the current page. Useful for finding out about repeated queries that are either redundant or which can be grouped into a single, more efficient query." -PLG_DEBUG_FIELD_QUERY_TYPES_LABEL="Show Query Types" +PLG_DEBUG_FIELD_MEMORY_LABEL="Memory Usage" +PLG_DEBUG_FIELD_PROFILING_LABEL="Profiling" +PLG_DEBUG_FIELD_QUERIES_LABEL="Queries" +PLG_DEBUG_FIELD_QUERY_TYPES_LABEL="Query Types" PLG_DEBUG_FIELD_REFRESH_ASSETS_DESC="If enabled will, on each page reload, add a different hash to every script/stylesheet file with auto version so that they never use the browser cache." PLG_DEBUG_FIELD_REFRESH_ASSETS_LABEL="Refresh Assets" -PLG_DEBUG_FIELD_SESSION_DESC="Display the session data." -PLG_DEBUG_FIELD_SESSION_LABEL="Show Session Data" -PLG_DEBUG_FIELD_STRIP_FIRST_DESC="In multi-word strings, always strip the first word." +PLG_DEBUG_FIELD_SESSION_LABEL="Session Data" PLG_DEBUG_FIELD_STRIP_FIRST_LABEL="Strip First Word" PLG_DEBUG_FIELD_STRIP_PREFIX_DESC="Strip words from the beginning of the string. For multiple words, use the format: (word1|word2)." PLG_DEBUG_FIELD_STRIP_PREFIX_LABEL="Strip From Start" diff --git a/administrator/language/en-GB/en-GB.plg_system_highlight.sys.ini b/administrator/language/en-GB/en-GB.plg_system_highlight.sys.ini index 6539a55df7139..08178bb920c2d 100644 --- a/administrator/language/en-GB/en-GB.plg_system_highlight.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_system_highlight.sys.ini @@ -4,5 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_SYSTEM_HIGHLIGHT="System - Highlight" -PLG_SYSTEM_HIGHLIGHT_ERROR_ACTIVATING_PLUGIN="Could not automatically activate the "System - Highlight" plugin" PLG_SYSTEM_HIGHLIGHT_XML_DESCRIPTION="System plugin to highlight specified terms." diff --git a/administrator/language/en-GB/en-GB.plg_system_httpheaders.ini b/administrator/language/en-GB/en-GB.plg_system_httpheaders.ini new file mode 100644 index 0000000000000..c0b53d71faef9 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_httpheaders.ini @@ -0,0 +1,57 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +; Please do not translate the word 'HTTP Headers' in the following two language strings +PLG_SYSTEM_HTTPHEADERS="System - HTTP Headers" +PLG_SYSTEM_HTTPHEADERS_ADDITIONAL_HEADER="Additional HTTP Headers" +; Please do not translate the name of the HTTP Headers in the following language string +PLG_SYSTEM_HTTPHEADERS_ADDITIONAL_HEADER_DESC="The supported headers are:

    • Strict-Transport-Security
    • Content-Security-Policy
    • Content-Security-Policy-Report-Only
    • X-Frame-Options
    • X-XSS-Protection
    • X-Content-Type-Options
    • Referrer-Policy
    • Expect-CT
    " +; Please do not translate the word 'HTTP Header' in the following two language strings +PLG_SYSTEM_HTTPHEADERS_ADDITIONAL_HEADER_KEY="HTTP Header" +PLG_SYSTEM_HTTPHEADERS_ADDITIONAL_HEADER_VALUE="HTTP Header Value" +; Please do not translate the following language string +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY="Content Security Policy (CSP)" +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_MODE="Mode" +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_MODE_AUTO="Automatic" +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_MODE_CUSTOM="Custom" +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_MODE_DETECT="Detect" +; Please only change the URL in the following language string +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_NONCE_ENABLED="Nonce" +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_NONCE_ENABLED_DESC="Enable the whitelist for specific inline scripts using a cryptographic nonce (number used once) for all scripts and styles using the Joomla API. Specifying a nonce makes a modern browser ignore 'unsafe-inline' which could still be set for older browsers without nonce support." +; Please do not translate 'Content-Security-Policy' & 'Content-Security-Policy-Report-Only' in the following language string +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_REPORT_ONLY_DESC="Use the header 'Content-Security-Policy-Report-Only' instead of 'Content-Security-Policy'." +; Please do not translate the following language string +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_REPORT_ONLY="Report-Only" +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_VALUES="Add Directive" +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_VALUES_DIRECTIVE="Policy Directive" +PLG_SYSTEM_HTTPHEADERS_CONTENTSECURITYPOLICY_VALUES_VALUE="Value" +PLG_SYSTEM_HTTPHEADERS_HEADER_CLIENT="Client" +PLG_SYSTEM_HTTPHEADERS_HEADER_CLIENT_BOTH="Both" +; Please do not translate the following language string +PLG_SYSTEM_HTTPHEADERS_HSTS="HTTP Strict Transport Security (HSTS)" +; Please do not translate the following language string +PLG_SYSTEM_HTTPHEADERS_HSTS_MAXAGE="max-age" +; Please do not translate 'max-age' in the following language string +PLG_SYSTEM_HTTPHEADERS_HSTS_MAXAGE_DESC="This option sets the time for 'max-age', it is specified in seconds. The default value is 31536000, which corresponds to one year" +; Please do not translate the following language string +PLG_SYSTEM_HTTPHEADERS_HSTS_PRELOAD="Preload" +PLG_SYSTEM_HTTPHEADERS_HSTS_PRELOAD_DESC="This option activates the opt-in for inclusion in so-called browser preload lists." +PLG_SYSTEM_HTTPHEADERS_HSTS_PRELOAD_NOTE="Important" +; Please do not translate 'max-age' in the following language string +PLG_SYSTEM_HTTPHEADERS_HSTS_PRELOAD_NOTE_DESC="HSTS means that your domain can no longer be called without HTTPS. Once added to the preload list, this is not easy to undo. Domains can be removed, but it takes months for users to make a change with a browser update.
    This option is very important to prevent 'man-in-the-middle attacks', so it should be activated in any case, but only if you are sure that HTTPS is supported for domain and all subdomains in the long run! The value for 'max-age' must be set to 63072000 (2 years) for recording." +PLG_SYSTEM_HTTPHEADERS_HSTS_SUBDOMAINS_DESC="HSTS should also be enabled for subdomains usually the subdomain 'www' is taken into account when creating the SSL certificate. If further subdomains are used, please note that they are also provided with a valid SSL certificate." +PLG_SYSTEM_HTTPHEADERS_HSTS_SUBDOMAINS="Also for subdomains" +PLG_SYSTEM_HTTPHEADERS_POSTINSTALL_INTRODUCTION_TITLE="HTTP Security Headers" +; Please do not translate the names of the http headers in the following language string +PLG_SYSTEM_HTTPHEADERS_POSTINSTALL_INTRODUCTION_BODY="Joomla! comes with a built-in plugin that handles http security headers. It helps to secure your site by setting the following headers with the default values:

    The full list of supported headers are:

    These headers help your browser to protect your website from XSS and Clickjacking attacks." +PLG_SYSTEM_HTTPHEADERS_POSTINSTALL_INTRODUCTION_ACTION="Enable default security headers" +; Please do not translate the following 3 language strings +PLG_SYSTEM_HTTPHEADERS_REFERRERPOLICY="Referrer-Policy" +PLG_SYSTEM_HTTPHEADERS_XCONTENTTYPEOPTIONS="X-Content-Type-Options" +PLG_SYSTEM_HTTPHEADERS_XFRAMEOPTIONS="X-Frame-Options" +; Please do not translate 'HTTP Security Headers' in the following language string +PLG_SYSTEM_HTTPHEADERS_XML_DESCRIPTION="This Plugin helps you to set the HTTP Security Headers" +; Please do not translate the following language string +PLG_SYSTEM_HTTPHEADERS_XXSSPROTECTION="X-XSS-Protection" \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_system_httpheaders.sys.ini b/administrator/language/en-GB/en-GB.plg_system_httpheaders.sys.ini new file mode 100644 index 0000000000000..d49dfac17c0ed --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_httpheaders.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +; Please do not translate the word 'HTTP Headers' in the following two language strings +PLG_SYSTEM_HTTPHEADERS="System - HTTP Headers" +PLG_SYSTEM_HTTPHEADERS_XML_DESCRIPTION="This Plugin can set some Security HTTP Headers" diff --git a/administrator/language/en-GB/en-GB.plg_system_languagecode.ini b/administrator/language/en-GB/en-GB.plg_system_languagecode.ini index 20bc4c41164d4..78bad7a92f5f7 100644 --- a/administrator/language/en-GB/en-GB.plg_system_languagecode.ini +++ b/administrator/language/en-GB/en-GB.plg_system_languagecode.ini @@ -7,4 +7,4 @@ PLG_SYSTEM_LANGUAGECODE="System - Language Code" PLG_SYSTEM_LANGUAGECODE_FIELD_DESC="Changes the language code used for the %s language." PLG_SYSTEM_LANGUAGECODE_FIELDSET_DESC="Changes the language code for the generated HTML document. Example usage: You have installed the fr-FR language pack and want the Search Engines to recognise the page as aimed at French-speaking Canada. Add the tag 'fr-CA' to the corresponding field for 'fr-FR' to resolve this." PLG_SYSTEM_LANGUAGECODE_FIELDSET_LABEL="Language Codes" -PLG_SYSTEM_LANGUAGECODE_XML_DESCRIPTION="Provides the ability to change the language code in the generated HTML document to improve SEO.
    The fields will appear when the plugin is enabled and saved.
    More information at W3.org." +PLG_SYSTEM_LANGUAGECODE_XML_DESCRIPTION="Provides the ability to change the language code in the generated HTML document to improve SEO.
    The fields will appear when the plugin is enabled and saved.
    More information at W3.org." diff --git a/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini b/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini index 9d957af004674..6391066045f7c 100644 --- a/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini +++ b/administrator/language/en-GB/en-GB.plg_system_languagefilter.ini @@ -5,24 +5,16 @@ PLG_SYSTEM_LANGUAGEFILTER="System - Language Filter" PLG_SYSTEM_LANGUAGEFILTER_BROWSER_SETTINGS="Browser Settings" -PLG_SYSTEM_LANGUAGEFILTER_FIELD_ALTERNATE_META_DESC="Add alternative meta tags for items with associated items in other languages." PLG_SYSTEM_LANGUAGEFILTER_FIELD_ALTERNATE_META_LABEL="Add Alternate Meta Tags" -PLG_SYSTEM_LANGUAGEFILTER_FIELD_AUTOMATIC_CHANGE_DESC="This option will automatically change the content language used in the Frontend when a user site language is changed." PLG_SYSTEM_LANGUAGEFILTER_FIELD_AUTOMATIC_CHANGE_LABEL="Automatic Language Change" -PLG_SYSTEM_LANGUAGEFILTER_FIELD_COOKIE_DESC="Language cookies can be set to expire at the end of the session or after a year. Default is session." PLG_SYSTEM_LANGUAGEFILTER_FIELD_COOKIE_LABEL="Cookie Lifetime" -PLG_SYSTEM_LANGUAGEFILTER_FIELD_DETECT_BROWSER_DESC="Choose site default language or try to detect the browser settings language. It will default to site language if browser settings can't be found." PLG_SYSTEM_LANGUAGEFILTER_FIELD_DETECT_BROWSER_LABEL="Language Selection for new Visitors" -PLG_SYSTEM_LANGUAGEFILTER_FIELD_ITEM_ASSOCIATIONS_DESC="This option will allow item associations when switching from one language to another. Default home menu items are always associated." -PLG_SYSTEM_LANGUAGEFILTER_FIELD_ITEM_ASSOCIATIONS_LABEL="Associations" -PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_DESC="This option will add the x-default meta tag to improve SEO." +PLG_SYSTEM_LANGUAGEFILTER_FIELD_ITEM_ASSOCIATIONS_LABEL="Item Associations" PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_LABEL="Add x-default Meta Tag" -PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_LANGUAGE_DESC="Choose the x-default language." PLG_SYSTEM_LANGUAGEFILTER_FIELD_XDEFAULT_LANGUAGE_LABEL="x-default Language" PLG_SYSTEM_LANGUAGEFILTER_OPTION_DEFAULT_LANGUAGE="Default frontend language" -PLG_SYSTEM_LANGUAGEFILTER_FIELD_REMOVE_DEFAULT_PREFIX_DESC="Remove the defined URL Language Code of the Content Language that corresponds to the default site language when Search Engine Friendly URLs is set to 'Yes'." PLG_SYSTEM_LANGUAGEFILTER_FIELD_REMOVE_DEFAULT_PREFIX_LABEL="Remove URL Language Code" PLG_SYSTEM_LANGUAGEFILTER_OPTION_SESSION="Session" PLG_SYSTEM_LANGUAGEFILTER_OPTION_YEAR="Year" PLG_SYSTEM_LANGUAGEFILTER_SITE_LANGUAGE="Site Language" -PLG_SYSTEM_LANGUAGEFILTER_XML_DESCRIPTION="This plugin filters the displayed content depending on language.
    This plugin is to be enabled only when the Language Switcher module is published.
    If this plugin is activated, it is recommended to also publish the Administrator multilingual status module." +PLG_SYSTEM_LANGUAGEFILTER_XML_DESCRIPTION="This plugin filters the displayed content depending on language.
    This plugin is to be enabled only when the Language Switcher module is published.
    If this plugin is activated, it is recommended to also publish the Administrator multilingual status module." diff --git a/administrator/language/en-GB/en-GB.plg_system_log.ini b/administrator/language/en-GB/en-GB.plg_system_log.ini index 24c3e975a3277..877d4da357de0 100644 --- a/administrator/language/en-GB/en-GB.plg_system_log.ini +++ b/administrator/language/en-GB/en-GB.plg_system_log.ini @@ -5,5 +5,4 @@ PLG_LOG_XML_DESCRIPTION="Provides logging when the user login fails." PLG_SYSTEM_LOG="System - User Log" -PLG_SYSTEM_LOG_FIELD_LOG_USERNAME_DESC="This option will log the username used when an authentication fails." PLG_SYSTEM_LOG_FIELD_LOG_USERNAME_LABEL="Log Usernames" diff --git a/administrator/language/en-GB/en-GB.plg_system_p3p.ini b/administrator/language/en-GB/en-GB.plg_system_p3p.ini deleted file mode 100644 index a2b9dc81203e3..0000000000000 --- a/administrator/language/en-GB/en-GB.plg_system_p3p.ini +++ /dev/null @@ -1,9 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -PLG_P3P_XML_DESCRIPTION="The system P3P policy plugin allows Joomla! to send a customised string of P3P policy tags in the HTTP header. This is required for the sessions to work on certain browsers, ie Internet Explorer 6 and 7." -PLG_SYSTEM_P3P="System - P3P Policy" -PLG_P3P_HEADER_DESCRIPTION="Enter your P3P policy tags. For more information consult The Platform for Privacy Preferences specification, https://www.w3.org/TR/P3P/" -PLG_P3P_HEADER_LABEL="P3P Tags" \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_system_p3p.sys.ini b/administrator/language/en-GB/en-GB.plg_system_p3p.sys.ini deleted file mode 100644 index 6ff09375bb509..0000000000000 --- a/administrator/language/en-GB/en-GB.plg_system_p3p.sys.ini +++ /dev/null @@ -1,7 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -PLG_P3P_XML_DESCRIPTION="The system P3P policy plugin allows Joomla! to send a customised string of P3P policy tags in the HTTP header. This is required for the sessions to work on certain browsers, ie Internet Explorer 6 and 7." -PLG_SYSTEM_P3P="System - P3P Policy" diff --git a/administrator/language/en-GB/en-GB.plg_system_redirect.ini b/administrator/language/en-GB/en-GB.plg_system_redirect.ini index c8533535be1a2..9a882052ed1e0 100644 --- a/administrator/language/en-GB/en-GB.plg_system_redirect.ini +++ b/administrator/language/en-GB/en-GB.plg_system_redirect.ini @@ -5,7 +5,6 @@ PLG_SYSTEM_REDIRECT="System - Redirect" PLG_SYSTEM_REDIRECT_ERROR_UPDATING_DATABASE="An error occurred while updating the database." -PLG_SYSTEM_REDIRECT_FIELD_COLLECT_URLS_DESC="This option controls the collection of URLs. This is useful to avoid unnecessary load on the database." PLG_SYSTEM_REDIRECT_FIELD_COLLECT_URLS_LABEL="Collect URLs" PLG_SYSTEM_REDIRECT_FIELD_EXCLUDE_URLS_DESC="Define regular expressions or terms which should be excluded in saving." PLG_SYSTEM_REDIRECT_FIELD_EXCLUDE_URLS_LABEL="Exclude URLs" diff --git a/administrator/language/en-GB/en-GB.plg_system_sef.ini b/administrator/language/en-GB/en-GB.plg_system_sef.ini index 71791b0499047..aaaf8446ee535 100644 --- a/administrator/language/en-GB/en-GB.plg_system_sef.ini +++ b/administrator/language/en-GB/en-GB.plg_system_sef.ini @@ -6,4 +6,4 @@ PLG_SEF_XML_DESCRIPTION="Adds SEF support to links in the document. It operates directly on the HTML and does not require a special tag." PLG_SYSTEM_SEF="System - SEF" PLG_SEF_DOMAIN_LABEL="Site Domain" -PLG_SEF_DOMAIN_DESCRIPTION="If your site can be accessed through more than one domain enter the preferred (sometimes referred to as canonical) domain here.
    Note: https://example.com and https://www.example.com are different domains." \ No newline at end of file +PLG_SEF_DOMAIN_DESCRIPTION="If your site can be accessed through more than one domain enter the preferred (sometimes referred to as canonical) domain here.
    Note: https://example.com and https://www.example.com are different domains." diff --git a/administrator/language/en-GB/en-GB.plg_system_stats.ini b/administrator/language/en-GB/en-GB.plg_system_stats.ini index e1b5b48374895..37882eb01bed5 100644 --- a/administrator/language/en-GB/en-GB.plg_system_stats.ini +++ b/administrator/language/en-GB/en-GB.plg_system_stats.ini @@ -7,10 +7,6 @@ PLG_SYSTEM_STATS="System - Joomla! Statistics" PLG_SYSTEM_STATS_BTN_NEVER_SEND="Never" PLG_SYSTEM_STATS_BTN_SEND_ALWAYS="Always" PLG_SYSTEM_STATS_BTN_SEND_NOW="Once" -; The following two strings are deprecated for 4.0 -PLG_SYSTEM_STATS_DEBUG_DESC="Enable debug for testing purposes. Statistics will be sent on every page load." -PLG_SYSTEM_STATS_DEBUG_LABEL="Debug" -PLG_SYSTEM_STATS_INTERVAL_DESC="Statistics will be sent every X hours. The default is 12." PLG_SYSTEM_STATS_INTERVAL_LABEL="Interval (hours)" PLG_SYSTEM_STATS_LABEL_CMS_VERSION="CMS Version" PLG_SYSTEM_STATS_LABEL_DB_TYPE="DB Type" @@ -19,7 +15,6 @@ PLG_SYSTEM_STATS_LABEL_MESSAGE_TITLE="Joomla! would like your permission to coll PLG_SYSTEM_STATS_LABEL_PHP_VERSION="PHP Version" PLG_SYSTEM_STATS_LABEL_SERVER_OS="Server OS" PLG_SYSTEM_STATS_LABEL_UNIQUE_ID="Unique ID" -PLG_SYSTEM_STATS_MODE_DESC="Select the way that you want the statistics to be sent." PLG_SYSTEM_STATS_MODE_LABEL="Mode" PLG_SYSTEM_STATS_MODE_OPTION_ALWAYS_SEND="Always send" PLG_SYSTEM_STATS_MODE_OPTION_NEVER_SEND="Never send" @@ -28,6 +23,5 @@ PLG_SYSTEM_STATS_MSG_ALLOW_SENDING_DATA="Enable Joomla Statistics?" PLG_SYSTEM_STATS_MSG_JOOMLA_WANTS_TO_SEND_DATA="To better understand our install base and end user environments it is helpful if you send some site information back to a Joomla! controlled central server. No identifying data is captured at any point. You can change these settings later from Plugins > System - Joomla! Statistics." PLG_SYSTEM_STATS_MSG_WHAT_DATA_WILL_BE_SENT="Select here to see the information that will be sent." PLG_SYSTEM_STATS_RESET_UNIQUE_ID="Reset Unique ID" -PLG_SYSTEM_STATS_UNIQUE_ID_DESC="An identifier that allows the Joomla! project to count unique installs of the plugin. This is sent with the statistics back to the server." PLG_SYSTEM_STATS_UNIQUE_ID_LABEL="Unique ID" PLG_SYSTEM_STATS_XML_DESCRIPTION="System Plugin that sends environment statistics to a server controlled by the Joomla! project for statistical analysis. Statistics sent include PHP version, CMS version, Database type, Database version and Server type." diff --git a/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.ini b/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.ini index a71cac38671b2..cfff5e2fda2ba 100644 --- a/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.ini +++ b/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.ini @@ -8,11 +8,10 @@ PLG_TWOFACTORAUTH_TOTP_ERR_VALIDATIONFAILED="You did not enter a valid security PLG_TWOFACTORAUTH_TOTP_INTRO="This feature allows you to use Google Authenticator, or a compatible application such as FreeOTP, for two factor authentication. In addition to your username and password you will also need to provide a six digit security code to be able to login to this site. The security code is rotated every 30 seconds. This provides extra protection against hackers logging in to your account even if they were able to get hold of your password." PLG_TWOFACTORAUTH_TOTP_METHOD_TITLE="Google Authenticator" PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_TITLE="Two Factor Authentication is Available" -PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_BODY="

    Joomla! comes with a built-in two factor authentication system. It secures your site login with a secondary secret code that's changing every 30 seconds. You can use your mobile device and the Google Authenticator app to produce that code.

    By selecting the button below:

    • Joomla! will enable the two factor authentication plugins
    • Two Factor Authentication is going to be available for all users.
    • Each user can configure Two Factor Authentication in User Details.
    • You can always disable Two Factor Authentication plugin, or configure it for Backend usage only.
    • You will be taken to your user profile page where you can find more information on two factor authentication and enable it for your user account.
    " +PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_BODY="

    Joomla! comes with a built-in two factor authentication system. It secures your site login with a secondary secret code that's changing every 30 seconds. You can use your mobile device and the Google Authenticator app to produce that code.

    By selecting the button below:

    • Joomla! will enable the two factor authentication plugins
    • Two Factor Authentication is going to be available for all users.
    • Each user can configure Two Factor Authentication in User Details.
    • You can always disable Two Factor Authentication plugin, or configure it for Backend usage only.
    • You will be taken to your user profile page where you can find more information on two factor authentication and enable it for your user account.
    " PLG_TWOFACTORAUTH_TOTP_POSTINSTALL_ACTION="Enable two factor authentication" PLG_TWOFACTORAUTH_TOTP_SECTION_ADMIN="Administrator (Backend)" PLG_TWOFACTORAUTH_TOTP_SECTION_BOTH="Both" -PLG_TWOFACTORAUTH_TOTP_SECTION_DESC="In which sections of your site do you want to enable two factor authentication?" PLG_TWOFACTORAUTH_TOTP_SECTION_LABEL="Site Section" PLG_TWOFACTORAUTH_TOTP_SECTION_SITE="Site (Frontend)" PLG_TWOFACTORAUTH_TOTP_STEP1_HEAD="Step 1 - Get Google Authenticator" @@ -22,7 +21,7 @@ PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM1_LINK="https://support.google.com/accounts/bin PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM2="Compatible clients for other devices and operating system (listed in Wikipedia)." ; Change and check this link if there is a translation in your language available. (current: German, Spanish, French, Japanese, Polish) PLG_TWOFACTORAUTH_TOTP_STEP1_ITEM2_LINK="https://en.wikipedia.org/wiki/Google_Authenticator#Implementation" -PLG_TWOFACTORAUTH_TOTP_STEP1_TEXT="Download and install Google Authenticator, or a compatible application such as FreeOTP, on your smartphone or desktop. Use one of the following:" +PLG_TWOFACTORAUTH_TOTP_STEP1_TEXT="Download and install Google Authenticator, or a compatible application such as FreeOTP, on your smartphone or desktop. Use one of the following:" PLG_TWOFACTORAUTH_TOTP_STEP1_WARN="Please remember to sync your device's clock with a time-server. Time drift in your device may cause an inability to log in to your site." PLG_TWOFACTORAUTH_TOTP_STEP2_ACCOUNT="Account" PLG_TWOFACTORAUTH_TOTP_STEP2_ALTTEXT="Alternatively, you can scan the following QR code in Google Authenticator." @@ -33,4 +32,4 @@ PLG_TWOFACTORAUTH_TOTP_STEP2_TEXT="You will need to enter the following informat PLG_TWOFACTORAUTH_TOTP_STEP3_HEAD="Step 3 - Activate Two Factor Authentication" PLG_TWOFACTORAUTH_TOTP_STEP3_SECURITYCODE="Security Code" PLG_TWOFACTORAUTH_TOTP_STEP3_TEXT="To verify that everything is set up properly, please enter the security code displayed in Google Authenticator in the field below and select the button. If the code is correct, the Two Factor Authentication feature will be enabled." -PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION="Allows users on your site to use two factor authentication using Google Authenticator or other compatible time-based One Time Password generators such as FreeOTP. To use two factor authentication please edit the user profile and enable two factor authentication." +PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION="Allows users on your site to use two factor authentication using Google Authenticator or other compatible time-based One Time Password generators such as FreeOTP. To use two factor authentication please edit the user profile and enable two factor authentication." diff --git a/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.sys.ini b/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.sys.ini index 0d0a68de1665c..d5060282bc847 100644 --- a/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_twofactorauth_totp.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_TWOFACTORAUTH_TOTP="Two Factor Authentication - Google Authenticator" -PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION="Allows users on your site to use two factor authentication using Google Authenticator or other compatible time-based One Time Password generators such as FreeOTP. To use two factor authentication please edit the user profile and enable two factor authentication." \ No newline at end of file +PLG_TWOFACTORAUTH_TOTP_XML_DESCRIPTION="Allows users on your site to use two factor authentication using Google Authenticator or other compatible time-based One Time Password generators such as FreeOTP. To use two factor authentication please edit the user profile and enable two factor authentication." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.ini b/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.ini index f7ada89ba603f..5e51b12ac8077 100644 --- a/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.ini +++ b/administrator/language/en-GB/en-GB.plg_twofactorauth_yubikey.ini @@ -12,7 +12,6 @@ PLG_TWOFACTORAUTH_TOTP_RESET_HEAD="Your YubiKey is already linked to your user a PLG_TWOFACTORAUTH_TOTP_RESET_TEXT="Your YubiKey is already linked to your user account. If you want to unlink your YubiKey from your user account or use another YubiKey, please first disable two factor authentication and save your user profile. Then come back to this user profile page and re-activate two factor authentication with the YubiKey method." PLG_TWOFACTORAUTH_YUBIKEY_SECTION_ADMIN="Administrator (Backend)" PLG_TWOFACTORAUTH_YUBIKEY_SECTION_BOTH="Both" -PLG_TWOFACTORAUTH_YUBIKEY_SECTION_DESC="In which sections of your site do you want to enable two factor authentication?" PLG_TWOFACTORAUTH_YUBIKEY_SECTION_LABEL="Site Section" PLG_TWOFACTORAUTH_YUBIKEY_SECTION_SITE="Site (Frontend)" PLG_TWOFACTORAUTH_YUBIKEY_SECURITYCODE="Security Code" diff --git a/administrator/language/en-GB/en-GB.plg_user_contactcreator.ini b/administrator/language/en-GB/en-GB.plg_user_contactcreator.ini index d593e0ef36dce..f23c6dfd90c03 100644 --- a/administrator/language/en-GB/en-GB.plg_user_contactcreator.ini +++ b/administrator/language/en-GB/en-GB.plg_user_contactcreator.ini @@ -7,8 +7,6 @@ PLG_CONTACTCREATOR_ERR_FAILED_CREATING_CONTACT="Automatic contact creation faile PLG_CONTACTCREATOR_ERR_NO_CATEGORY="Contact automatic creation failed because contact category is not set!" PLG_CONTACTCREATOR_FIELD_AUTOMATIC_WEBPAGE_DESC="A formatted string to automatically generate a contact's web page. [name] is replaced with the name, [username] is replaced with the username, [userid] is replaced with the user ID and [email] is replaced with the email." PLG_CONTACTCREATOR_FIELD_AUTOMATIC_WEBPAGE_LABEL="Automatic Webpage" -PLG_CONTACTCREATOR_FIELD_AUTOPUBLISH_DESC="Optionally have the contact default to published or unpublished." PLG_CONTACTCREATOR_FIELD_AUTOPUBLISH_LABEL="Automatically Publish the Contact" -PLG_CONTACTCREATOR_FIELD_CATEGORY_DESC="Category to assign contacts to by default." PLG_CONTACTCREATOR_XML_DESCRIPTION="Plugin to automatically create contact information for new users." PLG_USER_CONTACTCREATOR="User - Contact Creator" diff --git a/administrator/language/en-GB/en-GB.plg_user_joomla.ini b/administrator/language/en-GB/en-GB.plg_user_joomla.ini index 32134929e354b..c867be2ecc3ac 100644 --- a/administrator/language/en-GB/en-GB.plg_user_joomla.ini +++ b/administrator/language/en-GB/en-GB.plg_user_joomla.ini @@ -4,17 +4,13 @@ ; Note : All ini files need to be saved as UTF-8 PLG_USER_JOOMLA="User - Joomla!" -PLG_USER_JOOMLA_FIELD_AUTOREGISTER_DESC="Automatically create Registered Users where possible." PLG_USER_JOOMLA_FIELD_AUTOREGISTER_LABEL="Auto-create Users" -PLG_USER_JOOMLA_FIELD_FORCELOGOUT_DESC="Set to No to disable this." PLG_USER_JOOMLA_FIELD_FORCELOGOUT_LABEL="Force Logout for all Sessions?" -PLG_USER_JOOMLA_FIELD_MAILTOUSER_DESC="When an administrator creates a user account, this determines if an email, which has their username and password, is sent to the user." PLG_USER_JOOMLA_FIELD_MAILTOUSER_LABEL="Notification Mail to User" -PLG_USER_JOOMLA_FIELD_STRONG_PASSWORDS_DESC="If set to yes, use the bcrypt encryption method if available in this version of PHP." PLG_USER_JOOMLA_FIELD_STRONG_PASSWORDS_LABEL="Strong Passwords" PLG_USER_JOOMLA_NEW_USER_EMAIL_BODY="Hello %s,\n\n\nYou have been added as a User to %s by an Administrator.\n\nThis email has your username and password to log in to %s\n\nUsername: %s\nPassword: %s\n\n\nPlease do not respond to this message as it is automatically generated and is for information purposes only." PLG_USER_JOOMLA_NEW_USER_EMAIL_SUBJECT="New User Details" PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_BTN="Enable Strong Password Encryption" -PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_TEXT="As a security feature, Joomla allows you to switch to strong password encryption.
    To turn strong passwords on select the button below. Alternatively you can edit the User - Joomla plugin and change the strong password setting to On.
    Before enabling you should verify that all third party registration/login, user management or bridge extensions installed on your site support this strong password encryption." +PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_TEXT="As a security feature, Joomla allows you to switch to strong password encryption.
    To turn strong passwords on select the button below. Alternatively you can edit the User - Joomla plugin and change the strong password setting to On.
    Before enabling you should verify that all third party registration/login, user management or bridge extensions installed on your site support this strong password encryption." PLG_USER_JOOMLA_POSTINSTALL_STRONGPW_TITLE="Strong passwords" -PLG_USER_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User synchronisation.
    Warning! You must have enabled at least one plugin that handles the user session management or you will lose all access to your site." +PLG_USER_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User synchronisation.
    Warning! You must have enabled at least one plugin that handles the user session management or you will lose all access to your site." diff --git a/administrator/language/en-GB/en-GB.plg_user_joomla.sys.ini b/administrator/language/en-GB/en-GB.plg_user_joomla.sys.ini index 1e51c1d246fc1..6465f62ceaea9 100644 --- a/administrator/language/en-GB/en-GB.plg_user_joomla.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_user_joomla.sys.ini @@ -4,4 +4,4 @@ ; Note : All ini files need to be saved as UTF-8 PLG_USER_JOOMLA="User - Joomla!" -PLG_USER_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User synchronisation.
    Warning! You must have enabled at least one plugin that handles the user session management or you will lose all access to your site." +PLG_USER_JOOMLA_XML_DESCRIPTION="Handles Joomla's default User synchronisation.
    Warning! You must have enabled at least one plugin that handles the user session management or you will lose all access to your site." diff --git a/administrator/language/en-GB/en-GB.plg_user_profile.ini b/administrator/language/en-GB/en-GB.plg_user_profile.ini index 50fdeb3174525..3afa21db551ad 100644 --- a/administrator/language/en-GB/en-GB.plg_user_profile.ini +++ b/administrator/language/en-GB/en-GB.plg_user_profile.ini @@ -9,34 +9,21 @@ COM_CONTENT_SELECT_AN_ARTICLE="Select an Article" PLG_USER_PROFILE="User - Profile" PLG_USER_PROFILE_ERROR_INVALID_DOB="The date of birth you entered is invalid. Please enter a valid date." PLG_USER_PROFILE_ERROR_INVALID_DOB_FUTURE_DATE="The date of birth you entered is in the future." -PLG_USER_PROFILE_FIELD_ABOUT_ME_DESC="Choose an option for the field About Me." PLG_USER_PROFILE_FIELD_ABOUT_ME_LABEL="About Me" -PLG_USER_PROFILE_FIELD_ADDRESS1_DESC="Choose an option for the field Address1." PLG_USER_PROFILE_FIELD_ADDRESS1_LABEL="Address 1" -PLG_USER_PROFILE_FIELD_ADDRESS2_DESC="Choose an option for the field Address2." PLG_USER_PROFILE_FIELD_ADDRESS2_LABEL="Address 2" -PLG_USER_PROFILE_FIELD_CITY_DESC="Choose an option for the field City." PLG_USER_PROFILE_FIELD_CITY_LABEL="City" -PLG_USER_PROFILE_FIELD_COUNTRY_DESC="Choose an option for the field Country." PLG_USER_PROFILE_FIELD_COUNTRY_LABEL="Country" -PLG_USER_PROFILE_FIELD_DOB_DESC="Choose an option for the field Date of Birth." PLG_USER_PROFILE_FIELD_DOB_LABEL="Date of Birth" -PLG_USER_PROFILE_FIELD_FAVORITE_BOOK_DESC="Choose an option for the field Favourite Book." PLG_USER_PROFILE_FIELD_FAVORITE_BOOK_LABEL="Favourite Book" PLG_USER_PROFILE_FIELD_NAME_PROFILE_REQUIRE_USER="User profile fields for profile edit form" PLG_USER_PROFILE_FIELD_NAME_REGISTER_REQUIRE_USER="User profile fields for registration and administrator user forms" -PLG_USER_PROFILE_FIELD_PHONE_DESC="Choose an option for the field Phone." PLG_USER_PROFILE_FIELD_PHONE_LABEL="Phone" -PLG_USER_PROFILE_FIELD_POSTAL_CODE_DESC="Choose an option for the field Postal/ZIP Code." PLG_USER_PROFILE_FIELD_POSTAL_CODE_LABEL="Postal/ZIP Code" -PLG_USER_PROFILE_FIELD_REGION_DESC="Choose an option for the field Region." PLG_USER_PROFILE_FIELD_REGION_LABEL="Region" -PLG_USER_PROFILE_FIELD_TOS_ARTICLE_DESC="Select the desired Terms of Service article from the list." PLG_USER_PROFILE_FIELD_TOS_ARTICLE_LABEL="Select TOS Article" -PLG_USER_PROFILE_FIELD_TOS_DESC="Agree to terms of service." PLG_USER_PROFILE_FIELD_TOS_DESC_SITE="Please read the Terms of Service. You will not be able to register if you do not agree with them." PLG_USER_PROFILE_FIELD_TOS_LABEL="Terms of Service" -PLG_USER_PROFILE_FIELD_WEB_SITE_DESC="Choose an option for the field website." PLG_USER_PROFILE_FIELD_WEB_SITE_LABEL="Website" PLG_USER_PROFILE_FILL_FIELD_DESC_SITE="If required, please fill this field." PLG_USER_PROFILE_OPTION_AGREE="Agree" diff --git a/administrator/language/en-GB/en-GB.tpl_hathor.ini b/administrator/language/en-GB/en-GB.tpl_hathor.ini deleted file mode 100644 index 63b27730fbac6..0000000000000 --- a/administrator/language/en-GB/en-GB.tpl_hathor.ini +++ /dev/null @@ -1,33 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -HATHOR="Hathor Administrator template" -TPL_HATHOR_ALTERNATE_MENU_DESC="Use the alternative menu which integrates mouse and keyboard. JavaScript Required. The regular menu for Hathor is accessible with or without JavaScript, but leaves the mouse and keyboard independent." -TPL_HATHOR_ALTERNATE_MENU_LABEL="Alternative Menu" -TPL_HATHOR_BOLD_TEXT_DESC="Use bold text." -TPL_HATHOR_BOLD_TEXT_LABEL="Bold Text" -TPL_HATHOR_CHANGED_DEFAULT_TEMPLATE_TO_ISIS="We have set the default administrator template style to '%s'" -TPL_HATHOR_CHECKMARK_ALL="Checkmark All" -TPL_HATHOR_COLOUR_CHOICE_BLUE="Blue" -TPL_HATHOR_COLOUR_CHOICE_DESC="Select the colour palette to use with the template. You can use this option to select a high contrast version or use it to create custom branding." -TPL_HATHOR_COLOUR_CHOICE_LABEL="Select Colour" -TPL_HATHOR_COLOUR_CHOICE_STANDARD="Standard" -TPL_HATHOR_COLOUR_CHOICE_HIGH_CONTRAST="High Contrast" -TPL_HATHOR_COLOUR_CHOICE_BROWN="Brown" -TPL_HATHOR_COM_MENUS_MENU="Menu" -TPL_HATHOR_COM_MODULES_CUSTOM_POSITION_LABEL="Select" -TPL_HATHOR_CPANEL_LINK_TEXT="Return to Control Panel" -TPL_HATHOR_GO="Go" -TPL_HATHOR_LOGO_DESC="Select or upload a custom logo for the administrator template." -TPL_HATHOR_LOGO_LABEL="Logo" -TPL_HATHOR_MAIN_MENU="Main Menu" -TPL_HATHOR_MESSAGE_POSTINSTALL_TITLE="Information about the Hathor administrator template" -TPL_HATHOR_MESSAGE_POSTINSTALL_BODY="The Hathor administrator template style is set as your personal or global default administrator template. Please note - any new features for Joomla will only be available with the Isis template. We recommend that you switch your default backend template style to Isis. You can do this by selecting the button below. This will only change the default setting for the administrator template, if you have access to it, as well as your personal default style, if necessary. It does not change the frontend template or any other user's settings." -TPL_HATHOR_MESSAGE_POSTINSTALL_ACTION="Set the default administrator template style to Isis" -TPL_HATHOR_SHOW_SITE_NAME_DESC="Show the site name in the template header." -TPL_HATHOR_SHOW_SITE_NAME_LABEL="Show Site Name" -TPL_HATHOR_SKIP_TO_MAIN_CONTENT="Skip to Main Content" -TPL_HATHOR_SUB_MENU="Sub Menu" -TPL_HATHOR_XML_DESCRIPTION="Hathor is an accessible Administrator template for Joomla! The Colour CSS files can also be used for custom colour branding." diff --git a/administrator/language/en-GB/en-GB.tpl_hathor.sys.ini b/administrator/language/en-GB/en-GB.tpl_hathor.sys.ini deleted file mode 100644 index fe42e0d196257..0000000000000 --- a/administrator/language/en-GB/en-GB.tpl_hathor.sys.ini +++ /dev/null @@ -1,19 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -HATHOR="Hathor Administrator template" -TPL_HATHOR_POSITION_CP_SHELL="Unused" -TPL_HATHOR_POSITION_CPANEL="Control Panel" -TPL_HATHOR_POSITION_DEBUG="Debug" -TPL_HATHOR_POSITION_FOOTER="Footer" -TPL_HATHOR_POSITION_ICON="Quick Icons" -TPL_HATHOR_POSITION_LOGIN="Login" -TPL_HATHOR_POSITION_MENU="Menu" -TPL_HATHOR_POSITION_POSTINSTALL="Postinstall" -TPL_HATHOR_POSITION_STATUS="Status" -TPL_HATHOR_POSITION_SUBMENU="Submenu" -TPL_HATHOR_POSITION_TITLE="Title" -TPL_HATHOR_POSITION_TOOLBAR="Toolbar" -TPL_HATHOR_XML_DESCRIPTION="Hathor is an accessible Administrator template for Joomla! The Colour CSS files can also be used for custom colour branding." \ No newline at end of file diff --git a/administrator/language/en-GB/en-GB.tpl_isis.ini b/administrator/language/en-GB/en-GB.tpl_isis.ini deleted file mode 100644 index 65eb10b81c6cc..0000000000000 --- a/administrator/language/en-GB/en-GB.tpl_isis.ini +++ /dev/null @@ -1,43 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -ISIS="Isis Administrator template" -TPL_ISIS_CLEAR_CACHE="Clear Cache" -TPL_ISIS_COLOR_DESC="Choose a colour for the navigation bar. If left blank, the default value will be used." -TPL_ISIS_COLOR_HEADER_DESC="Choose a colour for the header. If left blank, the default value will be used." -TPL_ISIS_COLOR_HEADER_LABEL="Header Colour" -TPL_ISIS_COLOR_LABEL="Nav Bar Colour" -TPL_ISIS_COLOR_LOGIN_BACKGROUND_DESC="Choose a colour for the background of the login screen. If left blank, the default value will be used." -TPL_ISIS_COLOR_LOGIN_BACKGROUND_LABEL="Login Background Colour" -TPL_ISIS_COLOR_SIDEBAR_DESC="Choose a colour for the Sidebar Background. If left blank, the default value will be used." -TPL_ISIS_COLOR_SIDEBAR_LABEL="Sidebar Colour" -TPL_ISIS_COLOR_LINK_DESC="Choose a colour for the Link. If left blank, the default value will be used." -TPL_ISIS_COLOR_LINK_LABEL="Link Colour" -TPL_ISIS_CONTROL_PANEL="Control Panel" -TPL_ISIS_EDIT_ACCOUNT="Edit Account" -TPL_ISIS_FIELD_ADMIN_MENUS_DESC="If you intend to use Joomla Administrator on a monitor, set this to 'No'. It will prevent the collapse of the Administrator menus when reducing the width of the window. Default is 'Yes'." -TPL_ISIS_FIELD_ADMIN_MENUS_LABEL="Collapse Administrator Menu" -TPL_ISIS_HEADER_DESC="Optional display of header." -TPL_ISIS_HEADER_LABEL="Display Header" -TPL_ISIS_INSTALLER="Installer" -TPL_ISIS_ISFREESOFTWARE="Joomla is free software released under the GNU General Public License." -TPL_ISIS_LOGIN_LOGO_DESC="Select or upload a custom logo for the login area of administrator template." -TPL_ISIS_LOGIN_LOGO_LABEL="Login Logo" -TPL_ISIS_LOGO_DESC="Upload a custom logo for the administrator template." -TPL_ISIS_LOGO_LABEL="Logo" -TPL_ISIS_LOGOUT="Logout" -TPL_ISIS_PREVIEW="Preview %s" -TPL_ISIS_SKIP_TO_MAIN_CONTENT="Skip to Main Content" -TPL_ISIS_SKIP_TO_MAIN_CONTENT_HERE="Main content begins here" -TPL_ISIS_STATUS_BOTTOM="Fixed bottom" -TPL_ISIS_STATUS_DESC="Choose the location of the status module." -TPL_ISIS_STATUS_LABEL="Status Module Position" -TPL_ISIS_STATUS_TOP="Top" -TPL_ISIS_STICKY_DESC="Optionally set the toolbar to a fixed (pinned) location." -TPL_ISIS_STICKY_LABEL="Pinned Toolbar" -TPL_ISIS_TOGGLE_MENU="Toggle Navigation" -TPL_ISIS_TOOLBAR="Toolbar" -TPL_ISIS_USERMENU="User Menu" -TPL_ISIS_XML_DESCRIPTION="Continuing the Egyptian god/goddess theme (Khepri from 1.5 and Hathor from 1.6), Isis is the Joomla 3 administrator template based on Bootstrap and the launch of the Joomla User Interface library (JUI)." diff --git a/administrator/language/en-GB/en-GB.tpl_isis.sys.ini b/administrator/language/en-GB/en-GB.tpl_isis.sys.ini deleted file mode 100644 index fdc72b89c4aab..0000000000000 --- a/administrator/language/en-GB/en-GB.tpl_isis.sys.ini +++ /dev/null @@ -1,20 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -ISIS="Isis Administrator template" -TPL_ISIS_POSITION_BOTTOM="Bottom" -TPL_ISIS_POSITION_CPANEL="Cpanel" -TPL_ISIS_POSITION_CP_SHELL="Unused" -TPL_ISIS_POSITION_DEBUG="Debug" -TPL_ISIS_POSITION_FOOTER="Footer" -TPL_ISIS_POSITION_ICON="Quick Icons" -TPL_ISIS_POSITION_LOGIN="Login" -TPL_ISIS_POSITION_MENU="Menu" -TPL_ISIS_POSITION_POSTINSTALL="Postinstall" -TPL_ISIS_POSITION_STATUS="Status" -TPL_ISIS_POSITION_SUBMENU="Submenu" -TPL_ISIS_POSITION_TITLE="Title" -TPL_ISIS_POSITION_TOOLBAR="Toolbar" -TPL_ISIS_XML_DESCRIPTION="Continuing the Egyptian god/goddess theme (Khepri from 1.5 and Hathor from 1.6), Isis is the Joomla 3 administrator template based on Bootstrap and the launch of the Joomla User Interface library (JUI)." diff --git a/administrator/language/en-GB/en-GB.xml b/administrator/language/en-GB/en-GB.xml index ce15674694266..f1aeac683e9e8 100644 --- a/administrator/language/en-GB/en-GB.xml +++ b/administrator/language/en-GB/en-GB.xml @@ -1,8 +1,8 @@ - + English (en-GB) - 3.8.7 - March 2018 + 4.0.0 + July 2018 Joomla! Project admin@joomla.org www.joomla.org diff --git a/administrator/language/en-GB/install.xml b/administrator/language/en-GB/install.xml index 4fe5c259a623a..9e9f71d985d85 100644 --- a/administrator/language/en-GB/install.xml +++ b/administrator/language/en-GB/install.xml @@ -1,9 +1,9 @@ - + English (en-GB) en-GB - 3.8.7 - March 2018 + 4.0.0 + July 2018 Joomla! Project admin@joomla.org www.joomla.org diff --git a/administrator/manifests/files/joomla.xml b/administrator/manifests/files/joomla.xml index 32906edc88712..fb4fe09509178 100644 --- a/administrator/manifests/files/joomla.xml +++ b/administrator/manifests/files/joomla.xml @@ -6,8 +6,8 @@ www.joomla.org (C) 2005 - 2018 Open Source Matters. All rights reserved GNU General Public License version 2 or later; see LICENSE.txt - 3.8.7-dev - March 2018 + 4.0.0-alpha5-dev + July 2018 FILES_JOOMLA_XML_DESCRIPTION administrator/components/com_admin/script.php @@ -15,8 +15,6 @@ administrator/components/com_admin/sql/updates/mysql - administrator/components/com_admin/sql/updates/sqlazure - administrator/components/com_admin/sql/updates/sqlazure administrator/components/com_admin/sql/updates/postgresql diff --git a/administrator/manifests/libraries/fof.xml b/administrator/manifests/libraries/fof.xml deleted file mode 100644 index 1b91bb7f6018e..0000000000000 --- a/administrator/manifests/libraries/fof.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - FOF - fof - LIB_FOF_XML_DESCRIPTION - 2015-04-22 13:15:32 - Nicholas K. Dionysopoulos / Akeeba Ltd - nicholas@akeebabackup.com - https://www.akeebabackup.com - (C)2011-2015 Nicholas K. Dionysopoulos - GNU GPLv2 or later - 2.4.3 - Akeeba Ltd - https://www.AkeebaBackup.com/download.html - - - en-GB/en-GB.lib_fof.ini - - - - autoloader - config - controller - database - dispatcher - download - encrypt - form - hal - inflector - integration - input - layout - less - model - platform - query - render - string - table - template - toolbar - utils - view - LICENSE.txt - include.php - version.txt - - diff --git a/administrator/manifests/libraries/idna_convert.xml b/administrator/manifests/libraries/idna_convert.xml deleted file mode 100644 index 6f8c36daab3c0..0000000000000 --- a/administrator/manifests/libraries/idna_convert.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - LIB_IDNA - idna_convert - 0.8.0 - LIB_IDNA_XML_DESCRIPTION - 2004 - 2004-2011 phlyLabs Berlin, http://phlylabs.de - https://www.gnu.org/licenses/lgpl-2.1.html GNU/LGPL - phlyLabs - phlymail@phlylabs.de - http://phlylabs.de - Joomla! - https://www.joomla.org - - idna_convert - - diff --git a/administrator/manifests/libraries/phputf8.xml b/administrator/manifests/libraries/phputf8.xml deleted file mode 100644 index 9c809faddc69f..0000000000000 --- a/administrator/manifests/libraries/phputf8.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - LIB_PHPUTF8 - phputf8 - 0.5 - LIB_PHPUTF8_XML_DESCRIPTION - 2006 - Copyright various authors - https://www.gnu.org/licenses/gpl-2.0.html GNU/GPL - Harry Fuecks - hfuecks@gmail.com - http://sourceforge.net/projects/phputf8 - Joomla! - https://www.joomla.org - - phputf8 - - diff --git a/administrator/manifests/packages/pkg_en-GB.xml b/administrator/manifests/packages/pkg_en-GB.xml index a06dd1bd1ed24..0d927c8d3efd1 100644 --- a/administrator/manifests/packages/pkg_en-GB.xml +++ b/administrator/manifests/packages/pkg_en-GB.xml @@ -1,9 +1,9 @@ - + English (en-GB) Language Pack en-GB - 3.8.7.1 - March 2018 + 4.0.0.1 + July 2018 Joomla! Project admin@joomla.org www.joomla.org diff --git a/administrator/manifests/packages/pkg_weblinks.xml b/administrator/manifests/packages/pkg_weblinks.xml deleted file mode 100644 index 5a6e2dedf5d7a..0000000000000 --- a/administrator/manifests/packages/pkg_weblinks.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - pkg_weblinks - weblinks - December 2012 - Joomla! Project - (C) 2005 - 2018 Open Source Matters. All rights reserved. - admin@joomla.org - www.joomla.org - Joomla! Project - admin@joomla.org - www.joomla.org - 3.4.1 - GNU General Public License version 2 or later; see LICENSE.txt - PKG_WEBLINKS_XML_DESCRIPTION - - - com_weblinks.zip - mod_weblinks.zip - plg_finder_weblinks.zip - plg_search_weblinks.zip - - - en-GB/en-GB.pkg_weblinks.sys.ini - - - - https://raw.githubusercontent.com/joomla-extensions/weblinks/master/manifest.xml - - diff --git a/administrator/modules/mod_custom/mod_custom.php b/administrator/modules/mod_custom/mod_custom.php index deeb16dfd8946..df736252ab06f 100644 --- a/administrator/modules/mod_custom/mod_custom.php +++ b/administrator/modules/mod_custom/mod_custom.php @@ -9,13 +9,17 @@ defined('_JEXEC') or die; +use Joomla\CMS\Helper\ModuleHelper; +use Joomla\CMS\Plugin\PluginHelper; +use Joomla\CMS\HTML\HTMLHelper; + if ($params->def('prepare_content', 1)) { - JPluginHelper::importPlugin('content'); - $module->content = JHtml::_('content.prepare', $module->content, '', 'mod_custom.content'); + PluginHelper::importPlugin('content'); + $module->content = HTMLHelper::_('content.prepare', $module->content, '', 'mod_custom.content'); } // Replace 'images/' to '../images/' when using an image from /images in backend. $module->content = preg_replace('*src\=\"(?!administrator\/)images/*', 'src="../images/', $module->content); -require JModuleHelper::getLayoutPath('mod_custom', $params->get('layout', 'default')); +require ModuleHelper::getLayoutPath('mod_custom', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_custom/mod_custom.xml b/administrator/modules/mod_custom/mod_custom.xml index 03c73d10527ba..f98ba4e108be9 100644 --- a/administrator/modules/mod_custom/mod_custom.xml +++ b/administrator/modules/mod_custom/mod_custom.xml @@ -29,11 +29,11 @@ type="radio" label="MOD_CUSTOM_FIELD_PREPARE_CONTENT_LABEL" description="MOD_CUSTOM_FIELD_PREPARE_CONTENT_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" > - +
    + class="custom-select" + /> + /> @@ -67,7 +65,6 @@ name="cache_time" type="number" label="COM_MODULES_FIELD_CACHE_TIME_LABEL" - description="COM_MODULES_FIELD_CACHE_TIME_DESC" default="900" />
    diff --git a/administrator/modules/mod_feed/Helper/FeedHelper.php b/administrator/modules/mod_feed/Helper/FeedHelper.php new file mode 100644 index 0000000000000..ffb71aadbdad9 --- /dev/null +++ b/administrator/modules/mod_feed/Helper/FeedHelper.php @@ -0,0 +1,56 @@ +get('rssurl', ''); + + // Get RSS parsed object + try + { + $feed = new FeedFactory; + $rssDoc = $feed->getFeed($rssurl); + } + catch (\Exception $e) + { + return Text::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED'); + } + + if (empty($rssDoc)) + { + return Text::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED'); + } + + return $rssDoc; + } +} diff --git a/administrator/modules/mod_feed/helper.php b/administrator/modules/mod_feed/helper.php deleted file mode 100644 index 2bd6109078bbf..0000000000000 --- a/administrator/modules/mod_feed/helper.php +++ /dev/null @@ -1,52 +0,0 @@ -get('rssurl', ''); - - // Get RSS parsed object - try - { - jimport('joomla.feed.factory'); - $feed = new JFeedFactory; - $rssDoc = $feed->getFeed($rssurl); - } - catch (Exception $e) - { - return JText::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED'); - } - - if (empty($rssDoc)) - { - return JText::_('MOD_FEED_ERR_FEED_NOT_RETRIEVED'); - } - - return $rssDoc; - } -} diff --git a/administrator/modules/mod_feed/mod_feed.php b/administrator/modules/mod_feed/mod_feed.php index 185bf6ebfda50..b6d9f948de922 100644 --- a/administrator/modules/mod_feed/mod_feed.php +++ b/administrator/modules/mod_feed/mod_feed.php @@ -9,23 +9,9 @@ defined('_JEXEC') or die; -// Include the feed functions only once -JLoader::register('ModFeedHelper', __DIR__ . '/helper.php'); - -$rssurl = $params->get('rssurl', ''); -$rssrtl = $params->get('rssrtl', 0); - -// Check if feed URL has been set -if (empty ($rssurl)) -{ - echo '
    '; - echo JText::_('MOD_FEED_ERR_NO_URL'); - echo '
    '; - - return; -} - -$feed = ModFeedHelper::getFeed($params); +$feed = \Joomla\Module\Feed\Administrator\Helper\FeedHelper::getFeed($params); +$rssurl = $params->get('rssurl', ''); +$rssrtl = $params->get('rssrtl', 0); $moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'), ENT_COMPAT, 'UTF-8'); -require JModuleHelper::getLayoutPath('mod_feed', $params->get('layout', 'default')); +require \Joomla\CMS\Helper\ModuleHelper::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 7fcbe497bf764..de57db7b10228 100644 --- a/administrator/modules/mod_feed/mod_feed.xml +++ b/administrator/modules/mod_feed/mod_feed.xml @@ -9,9 +9,10 @@ www.joomla.org 3.0.0 MOD_FEED_XML_DESCRIPTION + Joomla\Module\Feed mod_feed.php - helper.php + Helper tmpl @@ -26,7 +27,6 @@ name="rssurl" type="url" label="MOD_FEED_FIELD_RSSURL_LABEL" - description="MOD_FEED_FIELD_RSSURL_DESC" filter="url" size="50" required="true" @@ -37,55 +37,39 @@ name="rssrtl" type="radio" label="MOD_FEED_FIELD_RTL_LABEL" - description="MOD_FEED_FIELD_RTL_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="0" > - - - - - - - + + - - + + @@ -93,36 +77,26 @@ name="rssitemdesc" type="radio" label="MOD_FEED_FIELD_ITEMDESCRIPTION_LABEL" - description="MOD_FEED_FIELD_ITEMDESCRIPTION_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" > - - + + -
    + class="custom-select" + /> @@ -130,7 +104,6 @@ name="cache" type="list" label="COM_MODULES_FIELD_CACHING_LABEL" - description="COM_MODULES_FIELD_CACHING_DESC" default="1" > @@ -141,8 +114,7 @@ name="cache_time" type="number" label="COM_MODULES_FIELD_CACHE_TIME_LABEL" - description="COM_MODULES_FIELD_CACHE_TIME_DESC" - default="900" + default="900" />
    diff --git a/administrator/modules/mod_feed/tmpl/default.php b/administrator/modules/mod_feed/tmpl/default.php index 12fd8ec81b25a..09032a4e28588 100644 --- a/administrator/modules/mod_feed/tmpl/default.php +++ b/administrator/modules/mod_feed/tmpl/default.php @@ -9,13 +9,25 @@ defined('_JEXEC') or die; +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Filter\OutputFilter; + +// Check if feed URL has been set +if (empty ($rssurl)) +{ + echo '
    ' . Text::_('MOD_FEED_ERR_NO_URL') . '
    '; + + return; +} + if (!empty($feed) && is_string($feed)) { echo $feed; } else { - $lang = JFactory::getLanguage(); + $lang = Factory::getLanguage(); $myrtl = $params->get('rssrtl'); $direction = ' '; @@ -23,18 +35,15 @@ { $direction = ' redirect-rtl'; } - // Feed description elseif ($lang->isRtl() && $myrtl == 1) { $direction = ' redirect-ltr'; } - elseif ($lang->isRtl() && $myrtl == 2) { $direction = ' redirect-rtl'; } - elseif ($myrtl == 0) { $direction = ' redirect-ltr'; @@ -50,10 +59,10 @@ if ($feed != false) : // Image handling - $iUrl = isset($feed->image) ? $feed->image : null; - $iTitle = isset($feed->imagetitle) ? $feed->imagetitle : null; + $iUrl = $feed->image ?? null; + $iTitle = $feed->imagetitle ?? null; ?> -
    +
    - + get('rssdesc', 1)) : ?> description; ?> - + get('rssimage', 1) && $iUrl) : ?> - <?php echo @$iTitle; ?> + <?php echo @$iTitle; ?> - + -
      +
        get('rssitems', 5); $i++) : if (!$feed->offsetExists($i)) : @@ -87,21 +96,22 @@ $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; ?> -
      • +
      • - + get('rssitemdesc') && !empty($text)) : ?>
        get('word_count'), true, false); + $text = OutputFilter::stripImages($text); + // Strip HTML + $text = strip_tags($text); echo str_replace(''', "'", $text); ?>
        diff --git a/administrator/modules/mod_latest/Helper/ModLatestHelper.php b/administrator/modules/mod_latest/Helper/ModLatestHelper.php new file mode 100644 index 0000000000000..9c9c08f444204 --- /dev/null +++ b/administrator/modules/mod_latest/Helper/ModLatestHelper.php @@ -0,0 +1,140 @@ +setState('list.select', 'a.id, a.title, a.checked_out, a.checked_out_time, ' . + ' 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')) + { + case 'm_dsc': + $model->setState('list.ordering', 'modified DESC, created'); + $model->setState('list.direction', 'DESC'); + break; + + case 'c_dsc': + default: + $model->setState('list.ordering', 'created'); + $model->setState('list.direction', 'DESC'); + break; + } + + // Set Category Filter + $categoryId = $params->get('catid'); + + if (is_numeric($categoryId)) + { + $model->setState('filter.category_id', $categoryId); + } + + // Set User Filter. + $userId = $user->get('id'); + + switch ($params->get('user_id')) + { + case 'by_me': + $model->setState('filter.author_id', $userId); + break; + + case 'not_me': + $model->setState('filter.author_id', $userId); + $model->setState('filter.author_id.include', false); + break; + } + + // Set the Start and Limit + $model->setState('list.start', 0); + $model->setState('list.limit', $params->get('count', 5)); + + $items = $model->getItems(); + + if ($error = $model->getError()) + { + throw new \Exception($error, 500); + + return false; + } + + // Set the links + foreach ($items as &$item) + { + $item->link = ''; + + if ($user->authorise('core.edit', 'com_content.article.' . $item->id)) + { + $item->link = Route::_('index.php?option=com_content&task=article.edit&id=' . $item->id); + } + } + + return $items; + } + + /** + * Get the alternate title for the module. + * + * @param \Joomla\Registry\Registry $params The module parameters. + * + * @return string The alternate title for the module. + */ + public static function getTitle($params) + { + $who = $params->get('user_id'); + $catid = (int) $params->get('catid'); + $type = $params->get('ordering') === 'c_dsc' ? '_CREATED' : '_MODIFIED'; + $title = ''; + + if ($catid) + { + $category = Categories::getInstance('Content')->get($catid); + $title = Text::_('MOD_POPULAR_UNEXISTING'); + + if ($category) + { + $title = $category->title; + } + } + + return Text::plural( + 'MOD_LATEST_TITLE' . $type . ($catid ? '_CATEGORY' : '') . ($who != '0' ? "_$who" : ''), + (int) $params->get('count', 5), + $title + ); + } +} diff --git a/administrator/modules/mod_latest/helper.php b/administrator/modules/mod_latest/helper.php deleted file mode 100644 index 38bebab57275a..0000000000000 --- a/administrator/modules/mod_latest/helper.php +++ /dev/null @@ -1,139 +0,0 @@ - true)); - - // Set List SELECT - $model->setState('list.select', 'a.id, a.title, a.checked_out, a.checked_out_time, ' . - ' 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')) - { - case 'm_dsc': - $model->setState('list.ordering', 'modified DESC, created'); - $model->setState('list.direction', 'DESC'); - break; - - case 'c_dsc': - default: - $model->setState('list.ordering', 'created'); - $model->setState('list.direction', 'DESC'); - break; - } - - // Set Category Filter - $categoryId = $params->get('catid'); - - if (is_numeric($categoryId)) - { - $model->setState('filter.category_id', $categoryId); - } - - // Set User Filter. - $userId = $user->get('id'); - - switch ($params->get('user_id')) - { - case 'by_me': - $model->setState('filter.author_id', $userId); - break; - - case 'not_me': - $model->setState('filter.author_id', $userId); - $model->setState('filter.author_id.include', false); - break; - } - - // Set the Start and Limit - $model->setState('list.start', 0); - $model->setState('list.limit', $params->get('count', 5)); - - $items = $model->getItems(); - - if ($error = $model->getError()) - { - JError::raiseError(500, $error); - - return false; - } - - // Set the links - foreach ($items as &$item) - { - if ($user->authorise('core.edit', 'com_content.article.' . $item->id)) - { - $item->link = JRoute::_('index.php?option=com_content&task=article.edit&id=' . $item->id); - } - else - { - $item->link = ''; - } - } - - return $items; - } - - /** - * Get the alternate title for the module. - * - * @param \Joomla\Registry\Registry $params The module parameters. - * - * @return string The alternate title for the module. - */ - public static function getTitle($params) - { - $who = $params->get('user_id'); - $catid = (int) $params->get('catid'); - $type = $params->get('ordering') == 'c_dsc' ? '_CREATED' : '_MODIFIED'; - - if ($catid) - { - $category = JCategories::getInstance('Content')->get($catid); - - if ($category) - { - $title = $category->title; - } - else - { - $title = JText::_('MOD_POPULAR_UNEXISTING'); - } - } - else - { - $title = ''; - } - - return JText::plural('MOD_LATEST_TITLE' . $type . ($catid ? '_CATEGORY' : '') . ($who != '0' ? "_$who" : ''), (int) $params->get('count'), $title); - } -} diff --git a/administrator/modules/mod_latest/mod_latest.php b/administrator/modules/mod_latest/mod_latest.php index ac8f754afcc57..4d51cc5825a69 100644 --- a/administrator/modules/mod_latest/mod_latest.php +++ b/administrator/modules/mod_latest/mod_latest.php @@ -9,14 +9,14 @@ defined('_JEXEC') or die; -// Include dependencies. -JLoader::register('ModLatestHelper', __DIR__ . '/helper.php'); +use Joomla\Component\Content\Administrator\Model\ArticlesModel; +use Joomla\Module\Latest\Administrator\Helper\ModLatestHelper; -$list = ModLatestHelper::getList($params); +$list = ModLatestHelper::getList($params, new ArticlesModel(array('ignore_request' => true))); if ($params->get('automatic_title', 0)) { $module->title = ModLatestHelper::getTitle($params); } -require JModuleHelper::getLayoutPath('mod_latest', $params->get('layout', 'default')); +require \Joomla\CMS\Helper\ModuleHelper::getLayoutPath('mod_latest', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_latest/mod_latest.xml b/administrator/modules/mod_latest/mod_latest.xml index c345a14a7bc8a..4d58f23a4bd92 100644 --- a/administrator/modules/mod_latest/mod_latest.xml +++ b/administrator/modules/mod_latest/mod_latest.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 MOD_LATEST_XML_DESCRIPTION + Joomla\Module\Latest mod_latest.php helper.php @@ -26,7 +27,6 @@ name="count" type="number" label="MOD_LATEST_FIELD_COUNT_LABEL" - description="MOD_LATEST_FIELD_COUNT_DESC" default="5" /> @@ -34,7 +34,6 @@ name="ordering" type="list" label="MOD_LATEST_FIELD_ORDERING_LABEL" - description="MOD_LATEST_FIELD_ORDERING_DESC" default="c_dsc" > @@ -45,7 +44,6 @@ name="catid" type="category" label="JCATEGORY" - description="MOD_LATEST_FIELD_CATEGORY_DESC" id="catid" extension="com_content" default="" @@ -57,7 +55,6 @@ name="user_id" type="list" label="MOD_LATEST_FIELD_AUTHORS_LABEL" - description="MOD_LATEST_FIELD_AUTHORS_DESC" default="0" > @@ -70,14 +67,13 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" - /> + class="custom-select" + /> @@ -85,12 +81,11 @@ name="automatic_title" type="radio" label="COM_MODULES_FIELD_AUTOMATIC_TITLE_LABEL" - description="COM_MODULES_FIELD_AUTOMATIC_TITLE_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="0" > - + diff --git a/administrator/modules/mod_latest/tmpl/default.php b/administrator/modules/mod_latest/tmpl/default.php index 3a4ac0bfc64ca..ab4646b8a8e8d 100644 --- a/administrator/modules/mod_latest/tmpl/default.php +++ b/administrator/modules/mod_latest/tmpl/default.php @@ -9,43 +9,54 @@ defined('_JEXEC') or die; -JHtml::_('bootstrap.tooltip'); +use Joomla\CMS\Language\Text; +use Joomla\CMS\HTML\HTMLHelper; + ?> -
        - + + + + + + + + + + + $item) : ?> -
        -
        - state, $i, 'articles.', false, 'cb', $item->publish_up, $item->publish_down); ?> - checked_out) : ?> - editor, $item->checked_out_time); ?> - - - - link) : ?> - - title, ENT_QUOTES, 'UTF-8'); ?> - - title, ENT_QUOTES, 'UTF-8'); ?> - - - - - author_name; ?> - -
        -
        -
        - created, JText::_('DATE_FORMAT_LC5')); ?> -
        -
        -
        + + + + + - -
        -
        -
        -
        -
        - - + + + + + + +
        title; ?>
        + checked_out) : ?> + editor, $item->checked_out_time); ?> + + link) : ?> + + title, ENT_QUOTES, 'UTF-8'); ?> + + + title, ENT_QUOTES, 'UTF-8'); ?> + + + author_name; ?> + + + + + publish_up, Text::_('DATE_FORMAT_LC4')); ?> + + +
        + +
        \ No newline at end of file diff --git a/administrator/modules/mod_logged/Helper/LoggedHelper.php b/administrator/modules/mod_logged/Helper/LoggedHelper.php new file mode 100644 index 0000000000000..6279545eff420 --- /dev/null +++ b/administrator/modules/mod_logged/Helper/LoggedHelper.php @@ -0,0 +1,85 @@ +getQuery(true) + ->select('s.time, s.client_id, u.id, u.name, u.username') + ->from('#__session AS s') + ->join('LEFT', '#__users AS u ON s.userid = u.id') + ->where('s.guest = 0'); + $db->setQuery($query, 0, $params->get('count', 5)); + + try + { + $results = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + throw $e; + } + + foreach ($results as $k => $result) + { + $results[$k]->logoutLink = ''; + + if ($user->authorise('core.manage', 'com_users')) + { + $results[$k]->editLink = Route::_('index.php?option=com_users&task=user.edit&id=' . $result->id); + $results[$k]->logoutLink = Route::_('index.php?option=com_login&task=logout&uid=' . $result->id . '&' . Session::getFormToken() . '=1'); + } + + if ($params->get('name', 1) == 0) + { + $results[$k]->name = $results[$k]->username; + } + } + + return $results; + } + + /** + * Get the alternate title for the module + * + * @param \Joomla\Registry\Registry $params The module parameters. + * + * @return string The alternate title for the module. + */ + public static function getTitle($params) + { + return Text::plural('MOD_LOGGED_TITLE', $params->get('count', 5)); + } +} diff --git a/administrator/modules/mod_logged/helper.php b/administrator/modules/mod_logged/helper.php deleted file mode 100644 index 78388db7e2783..0000000000000 --- a/administrator/modules/mod_logged/helper.php +++ /dev/null @@ -1,78 +0,0 @@ -getQuery(true) - ->select('s.time, s.client_id, u.id, u.name, u.username') - ->from('#__session AS s') - ->join('LEFT', '#__users AS u ON s.userid = u.id') - ->where('s.guest = 0'); - $db->setQuery($query, 0, $params->get('count', 5)); - - try - { - $results = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - throw $e; - } - - foreach ($results as $k => $result) - { - $results[$k]->logoutLink = ''; - - if ($user->authorise('core.manage', 'com_users')) - { - $results[$k]->editLink = JRoute::_('index.php?option=com_users&task=user.edit&id=' . $result->id); - $results[$k]->logoutLink = JRoute::_('index.php?option=com_login&task=logout&uid=' . $result->id . '&' . JSession::getFormToken() . '=1'); - } - - if ($params->get('name', 1) == 0) - { - $results[$k]->name = $results[$k]->username; - } - } - - return $results; - } - - /** - * Get the alternate title for the module - * - * @param \Joomla\Registry\Registry $params The module parameters. - * - * @return string The alternate title for the module. - */ - public static function getTitle($params) - { - return JText::plural('MOD_LOGGED_TITLE', $params->get('count')); - } -} diff --git a/administrator/modules/mod_logged/mod_logged.php b/administrator/modules/mod_logged/mod_logged.php index 6b96cff5ff778..08fc49f48074d 100644 --- a/administrator/modules/mod_logged/mod_logged.php +++ b/administrator/modules/mod_logged/mod_logged.php @@ -9,14 +9,23 @@ defined('_JEXEC') or die; -// Include dependencies. -JLoader::register('ModLoggedHelper', __DIR__ . '/helper.php'); - -$users = ModLoggedHelper::getList($params); +use Joomla\CMS\Factory; +use Joomla\CMS\Helper\ModuleHelper; +use Joomla\Module\Logged\Administrator\Helper\LoggedHelper; if ($params->get('automatic_title', 0)) { - $module->title = ModLoggedHelper::getTitle($params); + $module->title = LoggedHelper::getTitle($params); } -require JModuleHelper::getLayoutPath('mod_logged', $params->get('layout', 'default')); +// Check if session metadata tracking is enabled +if (Factory::getConfig()->get('session_metadata', true)) +{ + $users = LoggedHelper::getList($params); + + require ModuleHelper::getLayoutPath('mod_logged', $params->get('layout', 'default')); +} +else +{ + require ModuleHelper::getLayoutPath('mod_logged', 'disabled'); +} diff --git a/administrator/modules/mod_logged/mod_logged.xml b/administrator/modules/mod_logged/mod_logged.xml index ac57a7ea84dff..ae27e31c9822e 100644 --- a/administrator/modules/mod_logged/mod_logged.xml +++ b/administrator/modules/mod_logged/mod_logged.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 MOD_LOGGED_XML_DESCRIPTION + Joomla\Module\Logged mod_logged.php tmpl @@ -25,7 +26,6 @@ name="count" type="number" label="MOD_LOGGED_FIELD_COUNT_LABEL" - description="MOD_LOGGED_FIELD_COUNT_DESC" default="5" /> @@ -33,7 +33,6 @@ name="name" type="list" label="MOD_LOGGED_NAME" - description="MOD_LOGGED_FIELD_NAME_DESC" default="1" > @@ -45,14 +44,13 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" - /> + class="custom-select" + /> @@ -60,12 +58,11 @@ name="automatic_title" type="radio" label="COM_MODULES_FIELD_AUTOMATIC_TITLE_LABEL" - description="COM_MODULES_FIELD_AUTOMATIC_TITLE_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="0" > - + diff --git a/administrator/modules/mod_logged/tmpl/default.php b/administrator/modules/mod_logged/tmpl/default.php index cc084a3666158..ff5117e7a659c 100644 --- a/administrator/modules/mod_logged/tmpl/default.php +++ b/administrator/modules/mod_logged/tmpl/default.php @@ -9,42 +9,59 @@ defined('_JEXEC') or die; -JHtml::_('bootstrap.tooltip'); +use Joomla\CMS\Language\Text; +use Joomla\CMS\HTML\HTMLHelper; + ?> -
        + + + + + + + + + + -
        -
        - client_id == 0) : ?> - - +
        + + + + - + +
        title; ?>
        + get('name', 1) == 0) : ?> + + + + +
        + editLink)) : ?> + + name, ENT_QUOTES, 'UTF-8'); ?> + + name, ENT_QUOTES, 'UTF-8'); ?> - - - editLink)) : ?> - - name; ?> - - name; ?> - - - - - client_id === null) : ?> - - client_id) : ?> - - - - - - -
        -
        - time, JText::_('DATE_FORMAT_LC5')); ?> -
        -
        - +
        + client_id === null) : ?> + + client_id) : ?> + + + + + + + + + + + + + time, Text::_('DATE_FORMAT_LC5')); ?> + + +
        diff --git a/administrator/modules/mod_logged/tmpl/disabled.php b/administrator/modules/mod_logged/tmpl/disabled.php new file mode 100644 index 0000000000000..276c8630fdee1 --- /dev/null +++ b/administrator/modules/mod_logged/tmpl/disabled.php @@ -0,0 +1,15 @@ + +

        + +

        diff --git a/administrator/modules/mod_login/Helper/LoginHelper.php b/administrator/modules/mod_login/Helper/LoginHelper.php new file mode 100644 index 0000000000000..248613f677d2b --- /dev/null +++ b/administrator/modules/mod_login/Helper/LoginHelper.php @@ -0,0 +1,110 @@ +isRtl()) + { + foreach ($languages as &$language) + { + $language['text'] = $language['text'] . '‎'; + } + } + + array_unshift($languages, HTMLHelper::_('select.option', '', Text::_('JDEFAULTLANGUAGE'))); + + return HTMLHelper::_('select.genericlist', $languages, 'lang', 'class="custom-select"', 'value', 'text', null); + } + + /** + * Get the redirect URI after login. + * + * @return string + */ + public static function getReturnUri() + { + $uri = Uri::getInstance(); + $return = 'index.php' . $uri->toString(array('query')); + + if ($return != 'index.php?option=com_login') + { + return base64_encode($return); + } + else + { + return base64_encode('index.php'); + } + } + + /** + * Creates a list of two factor authentication methods used in com_users + * on user view + * + * @return array + * + * @deprecated 4.0 Use JAuthenticationHelper::getTwoFactorMethods() instead. + */ + public static function getTwoFactorMethods() + { + try + { + Log::add( + sprintf('%s() is deprecated, use JAuthenticationHelper::getTwoFactorMethods() instead.', __METHOD__), + Log::WARNING, + 'deprecated' + ); + } + catch (\RuntimeException $exception) + { + // Informational log only + } + + return AuthenticationHelper::getTwoFactorMethods(); + } +} diff --git a/administrator/modules/mod_login/helper.php b/administrator/modules/mod_login/helper.php deleted file mode 100644 index 122261b12a19e..0000000000000 --- a/administrator/modules/mod_login/helper.php +++ /dev/null @@ -1,100 +0,0 @@ -isRtl()) - { - foreach ($languages as &$language) - { - $language['text'] = $language['text'] . '‎'; - } - } - - array_unshift($languages, JHtml::_('select.option', '', JText::_('JDEFAULTLANGUAGE'))); - - return JHtml::_('select.genericlist', $languages, 'lang', 'class="advancedSelect" tabindex="4"', 'value', 'text', null); - } - - /** - * Get the redirect URI after login. - * - * @return string - */ - public static function getReturnUri() - { - $uri = JUri::getInstance(); - $return = 'index.php' . $uri->toString(array('query')); - - if ($return != 'index.php?option=com_login') - { - return base64_encode($return); - } - else - { - return base64_encode('index.php'); - } - } - - /** - * Creates a list of two factor authentication methods used in com_users - * on user view - * - * @return array - * - * @deprecated 4.0 Use JAuthenticationHelper::getTwoFactorMethods() instead. - */ - public static function getTwoFactorMethods() - { - try - { - JLog::add( - sprintf('%s() is deprecated, use JAuthenticationHelper::getTwoFactorMethods() instead.', __METHOD__), - JLog::WARNING, - 'deprecated' - ); - } - catch (RuntimeException $exception) - { - // Informational log only - } - - return JAuthenticationHelper::getTwoFactorMethods(); - } -} diff --git a/administrator/modules/mod_login/mod_login.php b/administrator/modules/mod_login/mod_login.php index f777066e834fd..ec2a50635d551 100644 --- a/administrator/modules/mod_login/mod_login.php +++ b/administrator/modules/mod_login/mod_login.php @@ -9,11 +9,12 @@ defined('_JEXEC') or die; -// Include the login functions only once -JLoader::register('ModLoginHelper', __DIR__ . '/helper.php'); +use Joomla\CMS\Helper\AuthenticationHelper; +use Joomla\CMS\Helper\ModuleHelper; +use Joomla\Module\Login\Administrator\Helper\LoginHelper; -$langs = ModLoginHelper::getLanguageList(); -$twofactormethods = JAuthenticationHelper::getTwoFactorMethods(); -$return = ModLoginHelper::getReturnUri(); +$langs = LoginHelper::getLanguageList(); +$twofactormethods = AuthenticationHelper::getTwoFactorMethods(); +$return = LoginHelper::getReturnUri(); -require JModuleHelper::getLayoutPath('mod_login', $params->get('layout', 'default')); +require ModuleHelper::getLayoutPath('mod_login', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_login/mod_login.xml b/administrator/modules/mod_login/mod_login.xml index cbde311bd470e..559aaddbc285b 100644 --- a/administrator/modules/mod_login/mod_login.xml +++ b/administrator/modules/mod_login/mod_login.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 MOD_LOGIN_XML_DESCRIPTION + Joomla\Module\Login mod_login.php tmpl @@ -21,32 +22,18 @@ -
        - - - - -
        diff --git a/administrator/modules/mod_login/tmpl/default.php b/administrator/modules/mod_login/tmpl/default.php index 6ed257d62d43e..ec1e0cd3a2742 100644 --- a/administrator/modules/mod_login/tmpl/default.php +++ b/administrator/modules/mod_login/tmpl/default.php @@ -9,94 +9,110 @@ defined('_JEXEC') or die; -JHtml::_('behavior.keepalive'); -JHtml::_('bootstrap.tooltip'); +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; +use Joomla\CMS\Uri\Uri; +use Joomla\CMS\Factory; + +HTMLHelper::_('behavior.core'); +HTMLHelper::_('behavior.formvalidator'); +HTMLHelper::_('behavior.keepalive'); +HTMLHelper::_('script', 'system/fields/passwordview.min.js', ['version' => 'auto', 'relative' => true]); +HTMLHelper::_('script', 'mod_login/admin-login.min.js', ['version' => 'auto', 'relative' => true]); + +Text::script('JSHOW'); +Text::script('JHIDE'); -// Load chosen if we have language selector, ie, more than one administrator language installed and enabled. -if ($langs) -{ - JHtml::_('formbehavior.chosen', '.advancedSelect'); -} ?> -
        -
        -
        -
        - -
        -
        - + 1): ?> -
        -
        -
        - - - - - - - +
        + +
        + + +
        -
        -
        -
        -
        - - - - - -
        -
        +
        + +
        -
        -
        -
        - -
        +
        + +
        +
        +
        + + + +
        +
        - - - - + + + +
        diff --git a/administrator/modules/mod_menu/Helper/MenuHelper.php b/administrator/modules/mod_menu/Helper/MenuHelper.php new file mode 100644 index 0000000000000..16632e2b9ad2a --- /dev/null +++ b/administrator/modules/mod_menu/Helper/MenuHelper.php @@ -0,0 +1,65 @@ +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)'); + + // 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); + + try + { + $result = $db->loadObjectList(); + } + catch (\RuntimeException $e) + { + $result = array(); + Factory::getApplication()->enqueueMessage(Text::sprintf('JERROR_LOADING_MENUS', $e->getMessage()), 'error'); + } + + return $result; + } +} diff --git a/administrator/modules/mod_menu/Menu/CssMenu.php b/administrator/modules/mod_menu/Menu/CssMenu.php new file mode 100644 index 0000000000000..4e859d34678eb --- /dev/null +++ b/administrator/modules/mod_menu/Menu/CssMenu.php @@ -0,0 +1,502 @@ +tree) + { + $this->tree = new Tree; + } + + return $this->tree; + } + + /** + * Populate the menu items in the menu tree object + * + * @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 load($params, $enabled) + { + $this->tree = $this->getTree(); + $this->params = $params; + $this->enabled = $enabled; + $menutype = $this->params->get('menutype', '*'); + + if ($menutype === '*') + { + $name = $this->params->get('preset', 'joomla'); + $levels = MenuHelper::loadPreset($name); + } + else + { + $items = MenusHelper::getMenuItems($menutype, true); + + if ($this->enabled && $this->params->get('check')) + { + if ($this->check($items, $this->params)) + { + $this->params->set('recovery', true); + + // In recovery mode, load the preset inside a special root node. + $this->tree->addChild(new Node\Heading('MOD_MENU_RECOVERY_MENU_ROOT'), true); + + $levels = MenuHelper::loadPreset('joomla'); + $levels = $this->preprocess($levels); + + $this->populateTree($levels); + + $this->tree->addChild(new Node\Separator); + + // Add link to exit recovery mode + $uri = clone Uri::getInstance(); + $uri->setVar('recover_menu', 0); + + $this->tree->addChild(new Node\Url('MOD_MENU_RECOVERY_EXIT', $uri->toString())); + + $this->tree->getParent(); + } + } + + $levels = MenuHelper::createLevels($items); + } + + $levels = $this->preprocess($levels); + + $this->populateTree($levels); + } + + /** + * Method to render a given level of a menu using provided layout file + * + * @param string $layoutFile The layout file to be used to render + * + * @return void + * + * @since 3.8.0 + */ + public function renderSubmenu($layoutFile) + { + if (is_file($layoutFile)) + { + $children = $this->tree->getCurrent()->getChildren(); + + foreach ($children as $child) + { + $this->tree->setCurrent($child); + + // This sets the scope to this object for the layout file and also isolates other `include`s + require $layoutFile; + } + } + } + + /** + * 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) + { + $me = Factory::getUser(); + $authMenus = $me->authorise('core.manage', 'com_menus'); + $authModules = $me->authorise('core.manage', 'com_modules'); + + if (!$authMenus && !$authModules) + { + return false; + } + + $app = Factory::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 ($rMenu || $rModule || $rContainer) + { + $recovery = $app->getUserStateFromRequest('mod_menu.recovery', 'recover_menu', 0, 'int'); + + if ($recovery) + { + return true; + } + + $missing = array(); + + if ($rMenu) + { + $missing[] = Text::_('MOD_MENU_IMPORTANT_ITEM_MENU_MANAGER'); + } + + if ($rModule) + { + $missing[] = Text::_('MOD_MENU_IMPORTANT_ITEM_MODULE_MANAGER'); + } + + if ($rContainer) + { + $missing[] = Text::_('MOD_MENU_IMPORTANT_ITEM_COMPONENTS_CONTAINER'); + } + + $uri = clone Uri::getInstance(); + $uri->setVar('recover_menu', 1); + + $table = Table::getInstance('MenuType'); + $menutype = $params->get('menutype'); + + $table->load(array('menutype' => $menutype)); + + $menutype = $table->get('title', $menutype); + $message = Text::sprintf('MOD_MENU_IMPORTANT_ITEMS_INACCESSIBLE_LIST_WARNING', $menutype, implode(', ', $missing), $uri); + + $app->enqueueMessage($message, 'warning'); + } + + return false; + } + + /** + * Filter and perform other preparatory tasks for loaded menu items based on access rights and module configurations for display + * + * @param \stdClass[] $items The levelled array of menu item objects + * + * @return array + * + * @since 3.8.0 + */ + protected function preprocess($items) + { + $result = array(); + $user = Factory::getUser(); + $language = Factory::getLanguage(); + + $noSeparator = true; + + // Call preprocess for the menu items on plugins. + // Plugins should normally process the current level only unless their logic needs deep levels too. + Factory::getApplication()->triggerEvent('onPreprocessMenuItems', array('com_menus.administrator.module', &$items, $this->params, $this->enabled)); + + foreach ($items as $i => &$item) + { + // Exclude item with menu item option set to exclude from menu modules + if ($item->params->get('menu_show', 1) == 0) + { + continue; + } + + $item->scope = $item->scope ?? 'default'; + $item->icon = $item->icon ?? ''; + + // 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')) || ($item->scope === 'edit' && !$this->params->get('shownew'))) + { + continue; + } + + 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 = $this->params->get('forum_url'); + } + } + + // Exclude item if is not enabled + if ($item->element && !ComponentHelper::isEnabled($item->element)) + { + continue; + } + + // Exclude Mass Mail if disabled in global configuration + if ($item->scope === 'massmail' && (Factory::getApplication()->get('massmailoff', 0) == 1)) + { + continue; + } + + // Exclude item if the component is not authorised + $assetName = $item->element; + + if ($item->element === 'com_categories') + { + parse_str($item->link, $query); + $assetName = $query['extension'] ?? 'com_content'; + } + elseif ($item->element === 'com_fields') + { + parse_str($item->link, $query); + + // Only display Fields menus when enabled in the component + $createFields = null; + + if (isset($query['context'])) + { + $createFields = ComponentHelper::getParams(strstr($query['context'], '.', true))->get('custom_fields_enable', 1); + } + + if (!$createFields) + { + continue; + } + + list($assetName) = isset($query['context']) ? explode('.', $query['context'], 2) : array('com_fields'); + } + elseif ($item->element === 'com_workflow') + { + parse_str($item->link, $query); + + // Only display Fields menus when enabled in the component + $workflow = null; + + if (isset($query['extension'])) + { + $workflow = ComponentHelper::getParams($query['extension'])->get('workflows_enable', 1); + } + + if (!$workflow) + { + continue; + } + + list($assetName) = isset($query['extension']) ? explode('.', $query['extension'], 2) : array('com_workflow'); + } + elseif ($item->element === 'com_config' && !$user->authorise('core.admin')) + { + continue; + } + elseif ($item->element === 'com_admin') + { + parse_str($item->link, $query); + + if (isset($query['view']) && $query['view'] === 'sysinfo' && !$user->authorise('core.admin')) + { + continue; + } + } + + if ($assetName && !$user->authorise(($item->scope === 'edit') ? 'core.create' : 'core.manage', $assetName)) + { + continue; + } + + // Exclude if link is invalid + if (!in_array($item->type, array('separator', 'heading', 'container')) && trim($item->link) === '') + { + continue; + } + + // Process any children if exists + $item->submenu = $this->preprocess($item->submenu); + + // Populate automatic children for container items + if ($item->type === 'container') + { + $exclude = (array) $item->params->get('hideitems') ?: array(); + $components = MenusHelper::getMenuItems('main', false, $exclude); + + $item->components = MenuHelper::createLevels($components); + $item->components = $this->preprocess($item->components); + $item->components = ArrayHelper::sortObjects($item->components, 'text', 1, false, true); + } + + // 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; + } + + // 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; + } + + $noSeparator = true; + } + else + { + $noSeparator = false; + } + + // 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); + } + + if ($item->type === 'separator' && $item->params->get('text_separator') == 0) + { + $item->title = ''; + } + + $item->text = Text::_($item->title); + + $result[$i] = $item; + } + + // If last one was a separator remove it too. + if ($noSeparator && isset($i)) + { + unset($result[$i]); + } + + return $result; + } + + /** + * Load the menu items from a hierarchical list of items into the menu tree + * + * @param \stdClass[] $levels Menu items as a hierarchical list format + * + * @return void + * + * @since 3.8.0 + */ + protected function populateTree($levels) + { + foreach ($levels as $item) + { + $class = $this->enabled ? $item->class : 'disabled'; + + 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); + + 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); + + 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); + + 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); + + if ($this->enabled) + { + $this->populateTree($item->submenu); + + // 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/Menu/MenuNode.php b/administrator/modules/mod_menu/Menu/MenuNode.php new file mode 100644 index 0000000000000..8ee4c2f9b852a --- /dev/null +++ b/administrator/modules/mod_menu/Menu/MenuNode.php @@ -0,0 +1,196 @@ +title = $titleicon ? $title . $titleicon : $title; + $this->link = OutputFilter::ampReplace($link); + $this->class = $class; + $this->active = $active; + + $this->id = null; + + if (!empty($link) && $link !== '#') + { + $uri = new Uri($link); + $params = $uri->getQuery(true); + $parts = array(); + + foreach ($params as $value) + { + $parts[] = str_replace(array('.', '_'), '-', $value); + } + + $this->id = implode('-', $parts); + } + + $this->target = $target; + } + + /** + * Add child to this node + * + * If the child already has a parent, the link is unset + * + * @param MenuNode &$child The child to be added + * + * @return void + */ + public function addChild(MenuNode &$child) + { + $child->setParent($this); + } + + /** + * Set the parent of a this node + * + * If the node already has a parent, the link is unset + * + * @param JMenuNode &$parent The JMenuNode for parent to be set or null + * + * @return void + */ + public function setParent(MenuNode &$parent = null) + { + $hash = spl_object_hash($this); + + if (!is_null($this->_parent)) + { + unset($this->_parent->_children[$hash]); + } + + if (!is_null($parent)) + { + $parent->_children[$hash] = &$this; + } + + $this->_parent = &$parent; + } + + /** + * Get the children of this node + * + * @return array The children + */ + public function &getChildren() + { + return $this->_children; + } + + /** + * Get the parent of this node + * + * @return mixed JMenuNode object with the parent or null for no parent + */ + public function &getParent() + { + return $this->_parent; + } + + /** + * Test if this node has children + * + * @return boolean True if there are children + */ + public function hasChildren() + { + return (bool) count($this->_children); + } + + /** + * Test if this node has a parent + * + * @return boolean True if there is a parent + */ + public function hasParent() + { + return $this->getParent() != null; + } +} diff --git a/administrator/modules/mod_menu/helper.php b/administrator/modules/mod_menu/helper.php deleted file mode 100644 index 9e9a515e7d085..0000000000000 --- a/administrator/modules/mod_menu/helper.php +++ /dev/null @@ -1,60 +0,0 @@ -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)'); - - // 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); - - try - { - $result = $db->loadObjectList(); - } - catch (RuntimeException $e) - { - $result = array(); - JFactory::getApplication()->enqueueMessage(JText::sprintf('JERROR_LOADING_MENUS', $e->getMessage()), 'error'); - } - - return $result; - } -} diff --git a/administrator/modules/mod_menu/menu.php b/administrator/modules/mod_menu/menu.php deleted file mode 100644 index d6aa6ac4b10ea..0000000000000 --- a/administrator/modules/mod_menu/menu.php +++ /dev/null @@ -1,477 +0,0 @@ -tree) - { - $this->tree = new Tree; - } - - return $this->tree; - } - - /** - * Populate the menu items in the menu tree object - * - * @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 load($params, $enabled) - { - $this->tree = $this->getTree(); - $this->params = $params; - $this->enabled = $enabled; - $menutype = $this->params->get('menutype', '*'); - - if ($menutype === '*') - { - $name = $this->params->get('preset', 'joomla'); - $levels = MenuHelper::loadPreset($name); - } - else - { - $items = MenusHelper::getMenuItems($menutype, true); - - if ($this->enabled && $this->params->get('check')) - { - if ($this->check($items, $this->params)) - { - $this->params->set('recovery', true); - - // In recovery mode, load the preset inside a special root node. - $this->tree->addChild(new Node\Heading('MOD_MENU_RECOVERY_MENU_ROOT'), true); - - $levels = MenuHelper::loadPreset('joomla'); - $levels = $this->preprocess($levels); - - $this->populateTree($levels); - - $this->tree->addChild(new Node\Separator); - - // Add link to exit recovery mode - $uri = clone JUri::getInstance(); - $uri->setVar('recover_menu', 0); - - $this->tree->addChild(new Node\Url('MOD_MENU_RECOVERY_EXIT', $uri->toString())); - - $this->tree->getParent(); - } - } - - $levels = MenuHelper::createLevels($items); - } - - $levels = $this->preprocess($levels); - - $this->populateTree($levels); - } - - /** - * Method to render a given level of a menu using provided layout file - * - * @param string $layoutFile The layout file to be used to render - * - * @return void - * - * @since 3.8.0 - */ - public function renderSubmenu($layoutFile) - { - if (is_file($layoutFile)) - { - $children = $this->tree->getCurrent()->getChildren(); - - foreach ($children as $child) - { - $this->tree->setCurrent($child); - - // This sets the scope to this object for the layout file and also isolates other `include`s - require $layoutFile; - } - } - } - - /** - * 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) - { - $me = JFactory::getUser(); - $authMenus = $me->authorise('core.manage', 'com_menus'); - $authModules = $me->authorise('core.manage', 'com_modules'); - - if (!$authMenus && !$authModules) - { - return false; - } - - $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 ($rMenu || $rModule || $rContainer) - { - $recovery = $app->getUserStateFromRequest('mod_menu.recovery', 'recover_menu', 0, 'int'); - - if ($recovery) - { - return true; - } - - $missing = array(); - - if ($rMenu) - { - $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_MENU_MANAGER'); - } - - if ($rModule) - { - $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_MODULE_MANAGER'); - } - - if ($rContainer) - { - $missing[] = JText::_('MOD_MENU_IMPORTANT_ITEM_COMPONENTS_CONTAINER'); - } - - $uri = clone JUri::getInstance(); - $uri->setVar('recover_menu', 1); - - $table = JTable::getInstance('MenuType'); - $menutype = $params->get('menutype'); - - $table->load(array('menutype' => $menutype)); - - $menutype = $table->get('title', $menutype); - $message = JText::sprintf('MOD_MENU_IMPORTANT_ITEMS_INACCESSIBLE_LIST_WARNING', $menutype, implode(', ', $missing), $uri); - - $app->enqueueMessage($message, 'warning'); - } - - return false; - } - - /** - * Filter and perform other preparatory tasks for loaded menu items based on access rights and module configurations for display - * - * @param \stdClass[] $items The levelled array of menu item objects - * - * @return array - * - * @since 3.8.0 - */ - protected function preprocess($items) - { - $result = array(); - $user = JFactory::getUser(); - $language = JFactory::getLanguage(); - - $noSeparator = true; - - // 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) - { - // Exclude item with menu item option set to exclude from menu modules - if ($item->params->get('menu_show', 1) == 0) - { - continue; - } - - $item->scope = isset($item->scope) ? $item->scope : 'default'; - $item->icon = isset($item->icon) ? $item->icon : ''; - - // 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')) || ($item->scope === 'edit' && !$this->params->get('shownew'))) - { - continue; - } - - 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 = $this->params->get('forum_url'); - } - } - - // Exclude item if is not enabled - if ($item->element && !JComponentHelper::isEnabled($item->element)) - { - continue; - } - - // Exclude Mass Mail if disabled in global configuration - if ($item->scope === 'massmail' && (JFactory::getApplication()->get('massmailoff', 0) == 1)) - { - continue; - } - - // Exclude item if the component is not authorised - $assetName = $item->element; - - 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); - - // Only display Fields menus when enabled in the component - $createFields = null; - - if (isset($query['context'])) - { - $createFields = JComponentHelper::getParams(strstr($query['context'], '.', true))->get('custom_fields_enable', 1); - } - - if (!$createFields) - { - continue; - } - - list($assetName) = isset($query['context']) ? explode('.', $query['context'], 2) : array('com_fields'); - } - elseif ($item->element === 'com_config' && !$user->authorise('core.admin')) - { - continue; - } - elseif ($item->element === 'com_admin') - { - parse_str($item->link, $query); - - if (isset($query['view']) && $query['view'] === 'sysinfo' && !$user->authorise('core.admin')) - { - continue; - } - } - - if ($assetName && !$user->authorise(($item->scope === 'edit') ? 'core.create' : 'core.manage', $assetName)) - { - continue; - } - - // Exclude if link is invalid - if (!in_array($item->type, array('separator', 'heading', 'container')) && trim($item->link) === '') - { - continue; - } - - // Process any children if exists - $item->submenu = $this->preprocess($item->submenu); - - // Populate automatic children for container items - if ($item->type === 'container') - { - $exclude = (array) $item->params->get('hideitems') ?: array(); - $components = MenusHelper::getMenuItems('main', false, $exclude); - - $item->components = MenuHelper::createLevels($components); - $item->components = $this->preprocess($item->components); - $item->components = ArrayHelper::sortObjects($item->components, 'text', 1, false, true); - } - - // 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; - } - - // 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; - } - - $noSeparator = true; - } - else - { - $noSeparator = false; - } - - // 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); - } - - if ($item->type === 'separator' && $item->params->get('text_separator') == 0) - { - $item->title = ''; - } - - $item->text = JText::_($item->title); - - $result[$i] = $item; - } - - // If last one was a separator remove it too. - if ($noSeparator && isset($i)) - { - unset($result[$i]); - } - - return $result; - } - - /** - * Load the menu items from a hierarchical list of items into the menu tree - * - * @param stdClass[] $levels Menu items as a hierarchical list format - * - * @return void - * - * @since 3.8.0 - */ - protected function populateTree($levels) - { - foreach ($levels as $item) - { - $class = $this->enabled ? $item->class : 'disabled'; - - 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); - - 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); - - 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); - - 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); - - if ($this->enabled) - { - $this->populateTree($item->submenu); - - // 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 83397a3f36ea0..c09600344f9e4 100644 --- a/administrator/modules/mod_menu/mod_menu.php +++ b/administrator/modules/mod_menu/mod_menu.php @@ -9,21 +9,19 @@ defined('_JEXEC') or die; +use Joomla\CMS\Factory; +use Joomla\CMS\Helper\ModuleHelper; +use Joomla\Module\Menu\Administrator\Menu\CssMenu; 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'); - /** @var Registry $params */ -$lang = JFactory::getLanguage(); -$user = JFactory::getUser(); -$input = JFactory::getApplication()->input; +$lang = Factory::getLanguage(); +$user = Factory::getUser(); +$input = Factory::getApplication()->input; $enabled = !$input->getBool('hidemainmenu'); -$menu = new JAdminCssMenu; +$menu = new CssMenu; $menu->load($params, $enabled); // Render the module layout -require JModuleHelper::getLayoutPath('mod_menu', $params->get('layout', 'default')); +require ModuleHelper::getLayoutPath('mod_menu', $params->get('layout', 'default')); diff --git a/administrator/modules/mod_menu/mod_menu.xml b/administrator/modules/mod_menu/mod_menu.xml index abc6d49dabfc3..aaf672a673503 100644 --- a/administrator/modules/mod_menu/mod_menu.xml +++ b/administrator/modules/mod_menu/mod_menu.xml @@ -9,6 +9,7 @@ www.joomla.org 3.0.0 MOD_MENU_XML_DESCRIPTION + Joomla\Module\Menu mod_menu.php preset @@ -23,12 +24,11 @@ -
        +
        @@ -48,20 +48,19 @@ type="radio" label="MOD_MENU_FIELD_CHECK_LABEL" description="MOD_MENU_FIELD_CHECK_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" showon="menutype!:*" > - + @@ -73,8 +72,7 @@ name="showhelp" type="radio" label="MOD_MENU_FIELD_SHOWHELP" - description="MOD_MENU_FIELD_SHOWHELP_DESC" - class="btn-group btn-group-yesno" + class="switcher" default="1" showon="menutype:*" > @@ -99,14 +97,13 @@ name="layout" type="modulelayout" label="JFIELD_ALT_LAYOUT_LABEL" - description="JFIELD_ALT_MODULE_LAYOUT_DESC" + class="custom-select" />
        diff --git a/administrator/modules/mod_menu/tmpl/default.php b/administrator/modules/mod_menu/tmpl/default.php index d4bca98bb268d..cc8f2327eb8a0 100644 --- a/administrator/modules/mod_menu/tmpl/default.php +++ b/administrator/modules/mod_menu/tmpl/default.php @@ -9,9 +9,15 @@ defined('_JEXEC') or die; -$doc = JFactory::getDocument(); -$direction = $doc->direction == 'rtl' ? 'pull-right' : ''; -$class = $enabled ? 'nav ' . $direction : 'nav disabled ' . $direction; +use Joomla\CMS\Helper\ModuleHelper; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; + +HTMLHelper::_('script', 'mod_menu/admin-menu.min.js', ['version' => 'auto', 'relative' => true], ['defer' => true]); + +$doc = \Joomla\CMS\Factory::getDocument(); +$direction = $doc->direction === 'rtl' ? 'float-right' : ''; +$class = $enabled ? 'nav navbar-nav nav-stacked main-nav clearfix ' . $direction : 'nav navbar-nav nav-stacked main-nav clearfix disabled ' . $direction; // Recurse through children of root node if they exist $menuTree = $menu->getTree(); @@ -19,14 +25,19 @@ if ($root->hasChildren()) { - echo '
        \n"; if ($css = $menuTree->getCss()) { diff --git a/administrator/modules/mod_menu/tmpl/default_submenu.php b/administrator/modules/mod_menu/tmpl/default_submenu.php index 82721c8b891cc..3bf7107217df3 100644 --- a/administrator/modules/mod_menu/tmpl/default_submenu.php +++ b/administrator/modules/mod_menu/tmpl/default_submenu.php @@ -6,17 +6,21 @@ * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ -use Joomla\CMS\Menu\Node\Separator; defined('_JEXEC') or die; +use Joomla\CMS\Menu\Node\Separator; +use Joomla\CMS\Language\Text; + /** * ========================================================================================================= - * IMPORTANT: The scope of this layout file is the `JAdminCssMenu` object and NOT the module context. + * IMPORTANT: The scope of this layout file is the `var \Joomla\Module\Menu\Administrator\Menu\CssMenu` object + * and NOT the module context. * ========================================================================================================= */ -/** @var JAdminCssMenu $this */ +/** @var \Joomla\Module\Menu\Administrator\Menu\CssMenu $this */ $current = $this->tree->getCurrent(); +$class = ''; // Build the CSS class suffix if (!$this->enabled) @@ -29,40 +33,33 @@ } elseif ($current->hasChildren()) { + $class = ' class="dropdown-submenu"'; + if ($current->getLevel() == 1) { - $class = ' class="dropdown"'; + $class = ' class="parent"'; } - elseif ($current->get('class') == 'scrollable-menu') + elseif ($current->get('class') === 'scrollable-menu') { $class = ' class="dropdown scrollable-menu"'; } - else - { - $class = ' class="dropdown-submenu"'; - } -} -else -{ - $class = ''; } // Print the item -echo ''; +echo ''; // Print a link if it exists -$linkClass = array(); -$dataToggle = ''; -$dropdownCaret = ''; +$linkClass = []; +$dataToggle = ''; +$iconClass = ''; if ($current->hasChildren()) { - $linkClass[] = 'dropdown-toggle'; - $dataToggle = ' data-toggle="dropdown"'; + $linkClass[] = 'collapse-arrow'; - if ($current->getLevel() == 1) + if ($current->getLevel() > 2) { - $dropdownCaret = ' '; + $dataToggle = ' data-toggle="dropdown"'; } } else @@ -70,49 +67,42 @@ $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'); +// Get the menu link +$link = $current->get('link'); - 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); - } - } +// Get the menu icon +$icon = $this->tree->getIconClass(); +$iconClass = ($icon != '' && $current->getLevel() == 1) ? '' : ''; - $target = $current->get('target') ? 'target="' . $current->get('target') . '"' : ''; +if ($current->get('link') === '#') +{ + $link = '#collapse' . $this->tree->getCounter(); +} - echo '' . - JText::_($current->get('title')) . $icon . $dropdownCaret . ''; +if ($link !== null && $current->get('target') !== null && $current->get('target') !== '') +{ + echo "get('target') . "\">" + . $iconClass + . '' . Text::_($current->get('title')) . ""; +} +elseif ($link !== null) +{ + echo "" + . $iconClass + . '' . Text::_($current->get('title')) . ""; +} +elseif ($current->get('title') !== null && $current->get('class') !== 'separator') +{ + echo "" + . $iconClass + . '' . Text::_($current->get('title')) . ""; } -// Separator else { - echo '' . JText::_($current->get('title')) . ''; + echo '' . Text::_($current->get('title')) . ''; } // Recurse through children if they exist @@ -122,11 +112,12 @@ { $id = $current->get('id') ? ' id="menu-' . strtolower($current->get('id')) . '"' : ''; - echo '' . "\n"; + echo '' . "\n"; } else { - echo ' -
        -
        diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/containeropen.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/containeropen.php deleted file mode 100644 index 5ac5f72e071c5..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/containeropen.php +++ /dev/null @@ -1,14 +0,0 @@ - - -
        -
          diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/help.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/help.php deleted file mode 100644 index 9c1eb0ec67e4c..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/help.php +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/iconclass.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/iconclass.php deleted file mode 100644 index c9b2f7852a477..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/iconclass.php +++ /dev/null @@ -1,12 +0,0 @@ - -icon-32- diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/link.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/link.php deleted file mode 100644 index 439a02e9d2165..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/link.php +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/modal.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/modal.php deleted file mode 100644 index a400f396d2f39..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/modal.php +++ /dev/null @@ -1,22 +0,0 @@ - - - - - diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/popup.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/popup.php deleted file mode 100644 index 03e36cf9c0e7a..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/popup.php +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/separator.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/separator.php deleted file mode 100644 index f971f38cf7620..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/separator.php +++ /dev/null @@ -1,16 +0,0 @@ - -
        • >
        • diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/slider.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/slider.php deleted file mode 100644 index 3a2ff10610c23..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/slider.php +++ /dev/null @@ -1,22 +0,0 @@ - - -> - - - diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/standard.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/standard.php deleted file mode 100644 index 4260708439078..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/standard.php +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/title.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/title.php deleted file mode 100644 index d91fb68df2e01..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/title.php +++ /dev/null @@ -1,30 +0,0 @@ - $icon) - { - $icons[$i] = 'icon-48-' . preg_replace('#\.[^.]*$#', '', $icon); - } - $class .= ' ' . htmlspecialchars(implode(' ', $icons), ENT_COMPAT, 'UTF-8'); -} -?> -
          -

          - -

          -
          diff --git a/administrator/templates/hathor/html/layouts/joomla/toolbar/versions.php b/administrator/templates/hathor/html/layouts/joomla/toolbar/versions.php deleted file mode 100644 index 9e27efa9b8400..0000000000000 --- a/administrator/templates/hathor/html/layouts/joomla/toolbar/versions.php +++ /dev/null @@ -1,19 +0,0 @@ - - - - diff --git a/administrator/templates/hathor/html/layouts/plugins/user/profile/fields/dob.php b/administrator/templates/hathor/html/layouts/plugins/user/profile/fields/dob.php deleted file mode 100644 index 15540918e62df..0000000000000 --- a/administrator/templates/hathor/html/layouts/plugins/user/profile/fields/dob.php +++ /dev/null @@ -1,18 +0,0 @@ - -
          diff --git a/administrator/templates/hathor/html/mod_login/default.php b/administrator/templates/hathor/html/mod_login/default.php deleted file mode 100644 index a34592684e0f5..0000000000000 --- a/administrator/templates/hathor/html/mod_login/default.php +++ /dev/null @@ -1,55 +0,0 @@ - -
          -
          - - - - - - - 1): ?> -
          -
          - - -
          -
          - - - - - - -
          - -
          -
          - -
          -
          - -
          - - - - - -
          -
          diff --git a/administrator/templates/hathor/html/mod_quickicon/default.php b/administrator/templates/hathor/html/mod_quickicon/default.php deleted file mode 100644 index 320ffb212c5a6..0000000000000 --- a/administrator/templates/hathor/html/mod_quickicon/default.php +++ /dev/null @@ -1,18 +0,0 @@ - - -
          - -
          - diff --git a/administrator/templates/hathor/html/modules.php b/administrator/templates/hathor/html/modules.php deleted file mode 100644 index fba14ec0887e7..0000000000000 --- a/administrator/templates/hathor/html/modules.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * This gives template designers ultimate control over how modules are rendered. - * - * NOTICE: All chrome wrapping methods should be named: modChrome_{STYLE} and take the same - * two arguments. - */ - -/* - * Module chrome for rendering the module in a submenu - */ -function modChrome_xhtmlid($module, &$params, &$attribs) -{ - if ($module->content) - { - ?> -
          - - content; ?> -
          - -
          - -
          - diff --git a/administrator/templates/hathor/html/pagination.php b/administrator/templates/hathor/html/pagination.php deleted file mode 100644 index 8eb739108297f..0000000000000 --- a/administrator/templates/hathor/html/pagination.php +++ /dev/null @@ -1,153 +0,0 @@ -base : integer - * $item->prefix : string - * $item->link : string - * $item->text : string - * - * pagination_item_inactive - * Input variable $item is an object with fields: - * $item->base : integer - * $item->prefix : string - * $item->link : string - * $item->text : string - * - * This gives template designers ultimate control over how pagination is rendered. - * - * NOTE: If you override pagination_item_active OR pagination_item_inactive you MUST override them both - */ - -function pagination_list_footer($list) -{ - /** - * Fix javascript jump menu - * - * Remove the onchange=Joomla.submitform from the select tag - * Add in a button with onclick instead - */ - $fixlimit = $list['limitfield']; - $fixlimit = preg_replace('/onchange="Joomla.submitform\(\);"/', '', $fixlimit); - - $html = '
          '; - - return $html; -} - -function pagination_list_render($list) -{ - $html = null; - - if ($list['start']['active']) - { - $html .= '
          '. $list['start']['data']. '
          '; - } else { - $html .= '
          '. $list['start']['data']. '
          '; - } - if ($list['previous']['active']) - { - $html .= '
          '; - } else { - $html .= '
          '; - } - - $html .= '
          '; - foreach ($list['pages'] as $page) - { - $html .= $page['data']; - } - $html .= '
          '; - - if ($list['next']['active']) - { - $html .= '
          '; - } else { - $html .= '
          '; - } - if ($list['end']['active']) - { - $html .= '
          '. $list['end']['data']. '
          '; - } else { - $html .= '
          '. $list['end']['data']. '
          '; - } - - return $html; -} - -function pagination_item_active(&$item) -{ - if ($item->base > 0) - { - return ''.$item->text. ''; - } - else - { - return ''.$item->text. ''; - } -} - -function pagination_item_inactive(&$item) -{ - if ($item->active) - { - $class = 'class="active"'; - } - else - { - $class = ''; - } - return '' . $item->text . ''; -} diff --git a/administrator/templates/hathor/images/admin/blank.png b/administrator/templates/hathor/images/admin/blank.png deleted file mode 100644 index 1797bf909a764..0000000000000 Binary files a/administrator/templates/hathor/images/admin/blank.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/collapseall.png b/administrator/templates/hathor/images/admin/collapseall.png deleted file mode 100644 index 3d50db8208660..0000000000000 Binary files a/administrator/templates/hathor/images/admin/collapseall.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/disabled.png b/administrator/templates/hathor/images/admin/disabled.png deleted file mode 100644 index 5218081bee8dd..0000000000000 Binary files a/administrator/templates/hathor/images/admin/disabled.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/downarrow-1.png b/administrator/templates/hathor/images/admin/downarrow-1.png deleted file mode 100644 index c94074e5963e8..0000000000000 Binary files a/administrator/templates/hathor/images/admin/downarrow-1.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/downarrow.png b/administrator/templates/hathor/images/admin/downarrow.png deleted file mode 100644 index a27a7585f7916..0000000000000 Binary files a/administrator/templates/hathor/images/admin/downarrow.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/downarrow0.png b/administrator/templates/hathor/images/admin/downarrow0.png deleted file mode 100644 index bd9f310e25124..0000000000000 Binary files a/administrator/templates/hathor/images/admin/downarrow0.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/expandall.png b/administrator/templates/hathor/images/admin/expandall.png deleted file mode 100644 index 233cb73562a7c..0000000000000 Binary files a/administrator/templates/hathor/images/admin/expandall.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/featured.png b/administrator/templates/hathor/images/admin/featured.png deleted file mode 100644 index a3e2c15965d89..0000000000000 Binary files a/administrator/templates/hathor/images/admin/featured.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/filesave.png b/administrator/templates/hathor/images/admin/filesave.png deleted file mode 100644 index 65a45b551ed04..0000000000000 Binary files a/administrator/templates/hathor/images/admin/filesave.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/filter_16.png b/administrator/templates/hathor/images/admin/filter_16.png deleted file mode 100644 index cbc62b7d30f78..0000000000000 Binary files a/administrator/templates/hathor/images/admin/filter_16.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/icon-16-allow.png b/administrator/templates/hathor/images/admin/icon-16-allow.png deleted file mode 100644 index d28a18b2f21e3..0000000000000 Binary files a/administrator/templates/hathor/images/admin/icon-16-allow.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/icon-16-allowinactive.png b/administrator/templates/hathor/images/admin/icon-16-allowinactive.png deleted file mode 100644 index d20e059da06b9..0000000000000 Binary files a/administrator/templates/hathor/images/admin/icon-16-allowinactive.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/icon-16-deny.png b/administrator/templates/hathor/images/admin/icon-16-deny.png deleted file mode 100644 index a5b37aa2c36d0..0000000000000 Binary files a/administrator/templates/hathor/images/admin/icon-16-deny.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/icon-16-denyinactive.png b/administrator/templates/hathor/images/admin/icon-16-denyinactive.png deleted file mode 100644 index 0dc1b43e0fa08..0000000000000 Binary files a/administrator/templates/hathor/images/admin/icon-16-denyinactive.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/icon-16-links.png b/administrator/templates/hathor/images/admin/icon-16-links.png deleted file mode 100644 index 52b4cb434eb81..0000000000000 Binary files a/administrator/templates/hathor/images/admin/icon-16-links.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/icon-16-notice-note.png b/administrator/templates/hathor/images/admin/icon-16-notice-note.png deleted file mode 100644 index a207d70ae835c..0000000000000 Binary files a/administrator/templates/hathor/images/admin/icon-16-notice-note.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/icon-16-protected.png b/administrator/templates/hathor/images/admin/icon-16-protected.png deleted file mode 100644 index b72ad93568e40..0000000000000 Binary files a/administrator/templates/hathor/images/admin/icon-16-protected.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/menu_divider.png b/administrator/templates/hathor/images/admin/menu_divider.png deleted file mode 100644 index 174df4cd75ad2..0000000000000 Binary files a/administrator/templates/hathor/images/admin/menu_divider.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/note_add_16.png b/administrator/templates/hathor/images/admin/note_add_16.png deleted file mode 100644 index 68e7ee66e85b2..0000000000000 Binary files a/administrator/templates/hathor/images/admin/note_add_16.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/publish_g.png b/administrator/templates/hathor/images/admin/publish_g.png deleted file mode 100644 index d3794988476dd..0000000000000 Binary files a/administrator/templates/hathor/images/admin/publish_g.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/publish_r.png b/administrator/templates/hathor/images/admin/publish_r.png deleted file mode 100644 index 1405a7900f5ee..0000000000000 Binary files a/administrator/templates/hathor/images/admin/publish_r.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/publish_x.png b/administrator/templates/hathor/images/admin/publish_x.png deleted file mode 100644 index 8719043981ae1..0000000000000 Binary files a/administrator/templates/hathor/images/admin/publish_x.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/publish_y.png b/administrator/templates/hathor/images/admin/publish_y.png deleted file mode 100644 index 4652e87c2e529..0000000000000 Binary files a/administrator/templates/hathor/images/admin/publish_y.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/sort_asc.png b/administrator/templates/hathor/images/admin/sort_asc.png deleted file mode 100644 index 1204f31f50f22..0000000000000 Binary files a/administrator/templates/hathor/images/admin/sort_asc.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/sort_desc.png b/administrator/templates/hathor/images/admin/sort_desc.png deleted file mode 100644 index c0ca72e6c8f39..0000000000000 Binary files a/administrator/templates/hathor/images/admin/sort_desc.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/tick.png b/administrator/templates/hathor/images/admin/tick.png deleted file mode 100644 index 2b11164d73a67..0000000000000 Binary files a/administrator/templates/hathor/images/admin/tick.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/trash.png b/administrator/templates/hathor/images/admin/trash.png deleted file mode 100644 index b2d671a41d012..0000000000000 Binary files a/administrator/templates/hathor/images/admin/trash.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/uparrow-1.png b/administrator/templates/hathor/images/admin/uparrow-1.png deleted file mode 100644 index 20175936c331c..0000000000000 Binary files a/administrator/templates/hathor/images/admin/uparrow-1.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/uparrow.png b/administrator/templates/hathor/images/admin/uparrow.png deleted file mode 100644 index def39656bc43d..0000000000000 Binary files a/administrator/templates/hathor/images/admin/uparrow.png and /dev/null differ diff --git a/administrator/templates/hathor/images/admin/uparrow0.png b/administrator/templates/hathor/images/admin/uparrow0.png deleted file mode 100644 index 60602b836a59f..0000000000000 Binary files a/administrator/templates/hathor/images/admin/uparrow0.png and /dev/null differ diff --git a/administrator/templates/hathor/images/arrow.png b/administrator/templates/hathor/images/arrow.png deleted file mode 100644 index 7fe1a536d1007..0000000000000 Binary files a/administrator/templates/hathor/images/arrow.png and /dev/null differ diff --git a/administrator/templates/hathor/images/bg-menu.gif b/administrator/templates/hathor/images/bg-menu.gif deleted file mode 100644 index f36c587265496..0000000000000 Binary files a/administrator/templates/hathor/images/bg-menu.gif and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-alert.png b/administrator/templates/hathor/images/header/icon-48-alert.png deleted file mode 100644 index 297b582682a5b..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-alert.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-apply.png b/administrator/templates/hathor/images/header/icon-48-apply.png deleted file mode 100644 index 179c201726d43..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-apply.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-archive.png b/administrator/templates/hathor/images/header/icon-48-archive.png deleted file mode 100644 index 87bbe30229327..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-archive.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-article-add.png b/administrator/templates/hathor/images/header/icon-48-article-add.png deleted file mode 100644 index b9249fd45efee..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-article-add.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-article-edit.png b/administrator/templates/hathor/images/header/icon-48-article-edit.png deleted file mode 100644 index 2d271335e8697..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-article-edit.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-article.png b/administrator/templates/hathor/images/header/icon-48-article.png deleted file mode 100644 index 0f629c9ac824b..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-article.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-assoc.png b/administrator/templates/hathor/images/header/icon-48-assoc.png deleted file mode 100644 index 4444f875dba94..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-assoc.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-banner-categories.png b/administrator/templates/hathor/images/header/icon-48-banner-categories.png deleted file mode 100644 index bf588204dee93..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-banner-categories.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-banner-client.png b/administrator/templates/hathor/images/header/icon-48-banner-client.png deleted file mode 100644 index 9a5df6767c306..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-banner-client.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-banner-tracks.png b/administrator/templates/hathor/images/header/icon-48-banner-tracks.png deleted file mode 100644 index 9be1442b4cdc5..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-banner-tracks.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-banner.png b/administrator/templates/hathor/images/header/icon-48-banner.png deleted file mode 100644 index 3e36c154dab23..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-banner.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-calendar.png b/administrator/templates/hathor/images/header/icon-48-calendar.png deleted file mode 100644 index 151a52bf0de4f..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-calendar.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-category-add.png b/administrator/templates/hathor/images/header/icon-48-category-add.png deleted file mode 100644 index 5ee7740a5fa51..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-category-add.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-category.png b/administrator/templates/hathor/images/header/icon-48-category.png deleted file mode 100644 index 354f185329668..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-category.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-checkin.png b/administrator/templates/hathor/images/header/icon-48-checkin.png deleted file mode 100644 index 6ab4cddae23f5..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-checkin.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-clear.png b/administrator/templates/hathor/images/header/icon-48-clear.png deleted file mode 100644 index 76dee7ce3657d..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-clear.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-component.png b/administrator/templates/hathor/images/header/icon-48-component.png deleted file mode 100644 index c4179a6ea2b1b..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-component.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-config.png b/administrator/templates/hathor/images/header/icon-48-config.png deleted file mode 100644 index 1b895fcb6be4b..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-config.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-contacts-categories.png b/administrator/templates/hathor/images/header/icon-48-contacts-categories.png deleted file mode 100644 index 73a689b52646f..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-contacts-categories.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-contacts.png b/administrator/templates/hathor/images/header/icon-48-contacts.png deleted file mode 100644 index d2128a1c4814a..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-contacts.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-content.png b/administrator/templates/hathor/images/header/icon-48-content.png deleted file mode 100644 index 363020bc5c043..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-content.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-cpanel.png b/administrator/templates/hathor/images/header/icon-48-cpanel.png deleted file mode 100644 index 8fa510d203593..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-cpanel.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-default.png b/administrator/templates/hathor/images/header/icon-48-default.png deleted file mode 100644 index de1b8053665a7..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-default.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-deny.png b/administrator/templates/hathor/images/header/icon-48-deny.png deleted file mode 100644 index 291da1926913c..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-deny.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-download.png b/administrator/templates/hathor/images/header/icon-48-download.png deleted file mode 100644 index bbd5d9171a1e8..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-download.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-edit.png b/administrator/templates/hathor/images/header/icon-48-edit.png deleted file mode 100644 index e24a733cf3b59..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-edit.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-extension.png b/administrator/templates/hathor/images/header/icon-48-extension.png deleted file mode 100644 index b26131d15547f..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-extension.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-featured.png b/administrator/templates/hathor/images/header/icon-48-featured.png deleted file mode 100644 index acfe49a793508..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-featured.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-frontpage.png b/administrator/templates/hathor/images/header/icon-48-frontpage.png deleted file mode 100644 index 285b65e4c8f52..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-frontpage.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-generic.png b/administrator/templates/hathor/images/header/icon-48-generic.png deleted file mode 100644 index c50f01e968906..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-generic.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-groups-add.png b/administrator/templates/hathor/images/header/icon-48-groups-add.png deleted file mode 100644 index 411fd886d65fd..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-groups-add.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-groups.png b/administrator/templates/hathor/images/header/icon-48-groups.png deleted file mode 100644 index 21d52f2464e30..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-groups.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-help-forum.png b/administrator/templates/hathor/images/header/icon-48-help-forum.png deleted file mode 100644 index 62133d7ec5dc3..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-help-forum.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-help-this.png b/administrator/templates/hathor/images/header/icon-48-help-this.png deleted file mode 100644 index b1845f5cacdac..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-help-this.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-help_header.png b/administrator/templates/hathor/images/header/icon-48-help_header.png deleted file mode 100644 index 559b654bfe558..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-help_header.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-inbox.png b/administrator/templates/hathor/images/header/icon-48-inbox.png deleted file mode 100644 index 29f412989ddee..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-inbox.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-info.png b/administrator/templates/hathor/images/header/icon-48-info.png deleted file mode 100644 index 0d8641d021c76..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-info.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-install.png b/administrator/templates/hathor/images/header/icon-48-install.png deleted file mode 100644 index 5747c4d7a4bc4..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-install.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-jupdate-updatefound.png b/administrator/templates/hathor/images/header/icon-48-jupdate-updatefound.png deleted file mode 100644 index 288ab8bd9a00a..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-jupdate-updatefound.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-jupdate-uptodate.png b/administrator/templates/hathor/images/header/icon-48-jupdate-uptodate.png deleted file mode 100644 index 924b1dbcdd386..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-jupdate-uptodate.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-language.png b/administrator/templates/hathor/images/header/icon-48-language.png deleted file mode 100644 index 902d11c285799..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-language.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-levels-add.png b/administrator/templates/hathor/images/header/icon-48-levels-add.png deleted file mode 100644 index e5458d5abef9e..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-levels-add.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-levels.png b/administrator/templates/hathor/images/header/icon-48-levels.png deleted file mode 100644 index 3a87ad0f59c39..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-levels.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-links-cat.png b/administrator/templates/hathor/images/header/icon-48-links-cat.png deleted file mode 100644 index 7b20b25705f78..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-links-cat.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-links.png b/administrator/templates/hathor/images/header/icon-48-links.png deleted file mode 100644 index b534e8a37cf70..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-links.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-massmail.png b/administrator/templates/hathor/images/header/icon-48-massmail.png deleted file mode 100644 index c0c8fcd180fce..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-massmail.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-media.png b/administrator/templates/hathor/images/header/icon-48-media.png deleted file mode 100644 index 4fbb51cd05473..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-media.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-menu-add.png b/administrator/templates/hathor/images/header/icon-48-menu-add.png deleted file mode 100644 index 5c901aa879b7d..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-menu-add.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-menu.png b/administrator/templates/hathor/images/header/icon-48-menu.png deleted file mode 100644 index 26194944d963a..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-menu.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-menumgr.png b/administrator/templates/hathor/images/header/icon-48-menumgr.png deleted file mode 100644 index 58146f31933d0..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-menumgr.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-module.png b/administrator/templates/hathor/images/header/icon-48-module.png deleted file mode 100644 index 0a8e444eb7a80..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-module.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-move.png b/administrator/templates/hathor/images/header/icon-48-move.png deleted file mode 100644 index 70772a3958d88..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-move.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-new-privatemessage.png b/administrator/templates/hathor/images/header/icon-48-new-privatemessage.png deleted file mode 100644 index 7bab1e70e5bd8..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-new-privatemessage.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-newcategory.png b/administrator/templates/hathor/images/header/icon-48-newcategory.png deleted file mode 100644 index 5797c9cee8a1a..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-newcategory.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-newsfeeds-cat.png b/administrator/templates/hathor/images/header/icon-48-newsfeeds-cat.png deleted file mode 100644 index 886b5765f85d3..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-newsfeeds-cat.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-newsfeeds.png b/administrator/templates/hathor/images/header/icon-48-newsfeeds.png deleted file mode 100644 index f1bd76d09d6f3..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-newsfeeds.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-notice.png b/administrator/templates/hathor/images/header/icon-48-notice.png deleted file mode 100644 index 16e1b96ea6078..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-notice.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-plugin.png b/administrator/templates/hathor/images/header/icon-48-plugin.png deleted file mode 100644 index d127b6cdc42d2..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-plugin.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-preview.png b/administrator/templates/hathor/images/header/icon-48-preview.png deleted file mode 100644 index 40dd10be4f235..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-preview.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-print.png b/administrator/templates/hathor/images/header/icon-48-print.png deleted file mode 100644 index 37e11dee49ab6..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-print.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-purge.png b/administrator/templates/hathor/images/header/icon-48-purge.png deleted file mode 100644 index 97346a9742902..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-purge.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-puzzle.png b/administrator/templates/hathor/images/header/icon-48-puzzle.png deleted file mode 100644 index f0019d8df74e3..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-puzzle.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-read-privatemessage.png b/administrator/templates/hathor/images/header/icon-48-read-privatemessage.png deleted file mode 100644 index cd255df8d06e4..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-read-privatemessage.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-readmess.png b/administrator/templates/hathor/images/header/icon-48-readmess.png deleted file mode 100644 index 208b79345f0e0..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-readmess.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-redirect.png b/administrator/templates/hathor/images/header/icon-48-redirect.png deleted file mode 100644 index 580a555aee93c..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-redirect.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-revert.png b/administrator/templates/hathor/images/header/icon-48-revert.png deleted file mode 100644 index 9bf2944a04d00..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-revert.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-search.png b/administrator/templates/hathor/images/header/icon-48-search.png deleted file mode 100644 index 79004021d0396..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-search.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-section.png b/administrator/templates/hathor/images/header/icon-48-section.png deleted file mode 100644 index e6e0195ddbdee..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-section.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-send.png b/administrator/templates/hathor/images/header/icon-48-send.png deleted file mode 100644 index 7ca3994a4d916..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-send.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-static.png b/administrator/templates/hathor/images/header/icon-48-static.png deleted file mode 100644 index 363020bc5c043..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-static.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-stats.png b/administrator/templates/hathor/images/header/icon-48-stats.png deleted file mode 100644 index 64659fdeb67f2..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-stats.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-tags.png b/administrator/templates/hathor/images/header/icon-48-tags.png deleted file mode 100644 index 9ba2124d1f24e..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-tags.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-themes.png b/administrator/templates/hathor/images/header/icon-48-themes.png deleted file mode 100644 index 7e31c86fe966b..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-themes.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-trash.png b/administrator/templates/hathor/images/header/icon-48-trash.png deleted file mode 100644 index 1a388bbe03ced..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-trash.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-unarchive.png b/administrator/templates/hathor/images/header/icon-48-unarchive.png deleted file mode 100644 index 6e3b0581e8c7e..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-unarchive.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-upload.png b/administrator/templates/hathor/images/header/icon-48-upload.png deleted file mode 100644 index 7d76ece323eb4..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-upload.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-user-add.png b/administrator/templates/hathor/images/header/icon-48-user-add.png deleted file mode 100644 index ab2112e4b1714..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-user-add.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-user-edit.png b/administrator/templates/hathor/images/header/icon-48-user-edit.png deleted file mode 100644 index ab2112e4b1714..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-user-edit.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-user-profile.png b/administrator/templates/hathor/images/header/icon-48-user-profile.png deleted file mode 100644 index 0d8641d021c76..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-user-profile.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-user.png b/administrator/templates/hathor/images/header/icon-48-user.png deleted file mode 100644 index cc6e43a62c6f5..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-user.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-48-writemess.png b/administrator/templates/hathor/images/header/icon-48-writemess.png deleted file mode 100644 index 827d99a0697d3..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-48-writemess.png and /dev/null differ diff --git a/administrator/templates/hathor/images/header/icon-messaging.png b/administrator/templates/hathor/images/header/icon-messaging.png deleted file mode 100644 index 46a377b202a17..0000000000000 Binary files a/administrator/templates/hathor/images/header/icon-messaging.png and /dev/null differ diff --git a/administrator/templates/hathor/images/j_arrow.png b/administrator/templates/hathor/images/j_arrow.png deleted file mode 100644 index 772bb4d908aa0..0000000000000 Binary files a/administrator/templates/hathor/images/j_arrow.png and /dev/null differ diff --git a/administrator/templates/hathor/images/j_arrow_down.png b/administrator/templates/hathor/images/j_arrow_down.png deleted file mode 100644 index 5e7334113d8db..0000000000000 Binary files a/administrator/templates/hathor/images/j_arrow_down.png and /dev/null differ diff --git a/administrator/templates/hathor/images/j_arrow_left.png b/administrator/templates/hathor/images/j_arrow_left.png deleted file mode 100644 index bee0eb1c0c31f..0000000000000 Binary files a/administrator/templates/hathor/images/j_arrow_left.png and /dev/null differ diff --git a/administrator/templates/hathor/images/j_arrow_right.png b/administrator/templates/hathor/images/j_arrow_right.png deleted file mode 100644 index ed65eeda45ce1..0000000000000 Binary files a/administrator/templates/hathor/images/j_arrow_right.png and /dev/null differ diff --git a/administrator/templates/hathor/images/j_login_lock.png b/administrator/templates/hathor/images/j_login_lock.png deleted file mode 100644 index b14c49b76baa0..0000000000000 Binary files a/administrator/templates/hathor/images/j_login_lock.png and /dev/null differ diff --git a/administrator/templates/hathor/images/j_logo.png b/administrator/templates/hathor/images/j_logo.png deleted file mode 100644 index 3b1f5dfecfbda..0000000000000 Binary files a/administrator/templates/hathor/images/j_logo.png and /dev/null differ diff --git a/administrator/templates/hathor/images/logo.png b/administrator/templates/hathor/images/logo.png deleted file mode 100644 index 00d0220049204..0000000000000 Binary files a/administrator/templates/hathor/images/logo.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-alert.png b/administrator/templates/hathor/images/menu/icon-16-alert.png deleted file mode 100644 index c1e0ed45691a8..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-alert.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-apply.png b/administrator/templates/hathor/images/menu/icon-16-apply.png deleted file mode 100644 index 415fe20597eb6..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-apply.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-archive.png b/administrator/templates/hathor/images/menu/icon-16-archive.png deleted file mode 100644 index 1a948a56443fb..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-archive.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-article.png b/administrator/templates/hathor/images/menu/icon-16-article.png deleted file mode 100644 index c3a39d4af904f..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-article.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-assoc.png b/administrator/templates/hathor/images/menu/icon-16-assoc.png deleted file mode 100644 index f0f8c5a35b7e0..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-assoc.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-back-user.png b/administrator/templates/hathor/images/menu/icon-16-back-user.png deleted file mode 100644 index 61ae0e0a06476..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-back-user.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-banner-categories.png b/administrator/templates/hathor/images/menu/icon-16-banner-categories.png deleted file mode 100644 index 8ce715f76e5d8..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-banner-categories.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-banner-client.png b/administrator/templates/hathor/images/menu/icon-16-banner-client.png deleted file mode 100644 index 9e071732d6bd1..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-banner-client.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-banner-tracks.png b/administrator/templates/hathor/images/menu/icon-16-banner-tracks.png deleted file mode 100644 index 7f7f121804d1a..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-banner-tracks.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-banner.png b/administrator/templates/hathor/images/menu/icon-16-banner.png deleted file mode 100644 index 2b030c9cc023e..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-banner.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-calendar.png b/administrator/templates/hathor/images/menu/icon-16-calendar.png deleted file mode 100644 index e2de0b7ec5d95..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-calendar.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-category.png b/administrator/templates/hathor/images/menu/icon-16-category.png deleted file mode 100644 index f0c7a4f8d0eac..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-category.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-checkin.png b/administrator/templates/hathor/images/menu/icon-16-checkin.png deleted file mode 100644 index 2b11164d73a67..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-checkin.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-clear.png b/administrator/templates/hathor/images/menu/icon-16-clear.png deleted file mode 100644 index b609ada0f9658..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-clear.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-component.png b/administrator/templates/hathor/images/menu/icon-16-component.png deleted file mode 100644 index 051a57b278407..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-component.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-config.png b/administrator/templates/hathor/images/menu/icon-16-config.png deleted file mode 100644 index c4edc5e3658bd..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-config.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-contacts-categories.png b/administrator/templates/hathor/images/menu/icon-16-contacts-categories.png deleted file mode 100644 index 05fee27648997..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-contacts-categories.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-contacts.png b/administrator/templates/hathor/images/menu/icon-16-contacts.png deleted file mode 100644 index 24a8e8ee7ab96..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-contacts.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-content.png b/administrator/templates/hathor/images/menu/icon-16-content.png deleted file mode 100644 index 073aefa14daf4..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-content.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-cpanel.png b/administrator/templates/hathor/images/menu/icon-16-cpanel.png deleted file mode 100644 index c6d7761aa18e0..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-cpanel.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-default.png b/administrator/templates/hathor/images/menu/icon-16-default.png deleted file mode 100644 index ab7702f9391ad..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-default.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-delete.png b/administrator/templates/hathor/images/menu/icon-16-delete.png deleted file mode 100644 index a93bed32d135b..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-delete.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-deny.png b/administrator/templates/hathor/images/menu/icon-16-deny.png deleted file mode 100644 index 58d4407667f7a..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-deny.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-download.png b/administrator/templates/hathor/images/menu/icon-16-download.png deleted file mode 100644 index 396357c712d99..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-download.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-edit.png b/administrator/templates/hathor/images/menu/icon-16-edit.png deleted file mode 100644 index 936fe76cf73e6..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-edit.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-featured.png b/administrator/templates/hathor/images/menu/icon-16-featured.png deleted file mode 100644 index dfd4e1de35bf9..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-featured.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-frontpage.png b/administrator/templates/hathor/images/menu/icon-16-frontpage.png deleted file mode 100644 index 675de06a1e49c..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-frontpage.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-generic.png b/administrator/templates/hathor/images/menu/icon-16-generic.png deleted file mode 100644 index fa1099cb3156c..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-generic.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-groups.png b/administrator/templates/hathor/images/menu/icon-16-groups.png deleted file mode 100644 index 28c67dcc6df96..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-groups.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-community.png b/administrator/templates/hathor/images/menu/icon-16-help-community.png deleted file mode 100644 index 7b39c5fc16f5c..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-community.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-dev.png b/administrator/templates/hathor/images/menu/icon-16-help-dev.png deleted file mode 100644 index 3187674abe503..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-dev.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-docs.png b/administrator/templates/hathor/images/menu/icon-16-help-docs.png deleted file mode 100644 index e8f6f4e47ba53..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-docs.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-forum.png b/administrator/templates/hathor/images/menu/icon-16-help-forum.png deleted file mode 100644 index bc0d3837a603c..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-forum.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-jed.png b/administrator/templates/hathor/images/menu/icon-16-help-jed.png deleted file mode 100644 index 498a01ac4d4c9..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-jed.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-jrd.png b/administrator/templates/hathor/images/menu/icon-16-help-jrd.png deleted file mode 100644 index 79a9d30d03de3..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-jrd.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-security.png b/administrator/templates/hathor/images/menu/icon-16-help-security.png deleted file mode 100644 index 0050ca5d110fe..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-security.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-shop.png b/administrator/templates/hathor/images/menu/icon-16-help-shop.png deleted file mode 100644 index e24dc8a539301..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-shop.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-this.png b/administrator/templates/hathor/images/menu/icon-16-help-this.png deleted file mode 100644 index c90eac90e0a6e..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-this.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help-trans.png b/administrator/templates/hathor/images/menu/icon-16-help-trans.png deleted file mode 100644 index 1f2264c1ee9d6..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help-trans.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-help.png b/administrator/templates/hathor/images/menu/icon-16-help.png deleted file mode 100644 index 8c3a8ab93b126..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-help.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-inbox.png b/administrator/templates/hathor/images/menu/icon-16-inbox.png deleted file mode 100644 index f808d62dcc20a..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-inbox.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-info.png b/administrator/templates/hathor/images/menu/icon-16-info.png deleted file mode 100644 index 3080bfdf070f8..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-info.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-install.png b/administrator/templates/hathor/images/menu/icon-16-install.png deleted file mode 100644 index f393945ac7b9d..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-install.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-levels.png b/administrator/templates/hathor/images/menu/icon-16-levels.png deleted file mode 100644 index f5a808f89bccf..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-levels.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-links-cat.png b/administrator/templates/hathor/images/menu/icon-16-links-cat.png deleted file mode 100644 index bc2a50ba7bb08..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-links-cat.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-links.png b/administrator/templates/hathor/images/menu/icon-16-links.png deleted file mode 100644 index 52b4cb434eb81..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-links.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-logout.png b/administrator/templates/hathor/images/menu/icon-16-logout.png deleted file mode 100644 index aab064a4789b9..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-logout.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-maintenance.png b/administrator/templates/hathor/images/menu/icon-16-maintenance.png deleted file mode 100644 index 642c5552d2a88..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-maintenance.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-massmail.png b/administrator/templates/hathor/images/menu/icon-16-massmail.png deleted file mode 100644 index d460e1ad2409b..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-massmail.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-media.png b/administrator/templates/hathor/images/menu/icon-16-media.png deleted file mode 100644 index ffb9498ee2eaf..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-media.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-menu.png b/administrator/templates/hathor/images/menu/icon-16-menu.png deleted file mode 100644 index c6a0ee429a6f0..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-menu.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-menumgr.png b/administrator/templates/hathor/images/menu/icon-16-menumgr.png deleted file mode 100644 index 88a2d1b3094b2..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-menumgr.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-messages.png b/administrator/templates/hathor/images/menu/icon-16-messages.png deleted file mode 100644 index 56fc7804879a4..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-messages.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-messaging.png b/administrator/templates/hathor/images/menu/icon-16-messaging.png deleted file mode 100644 index 33ffed14b5853..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-messaging.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-module.png b/administrator/templates/hathor/images/menu/icon-16-module.png deleted file mode 100644 index 55ba9dbd552ef..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-module.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-move.png b/administrator/templates/hathor/images/menu/icon-16-move.png deleted file mode 100644 index 6d709fccf108c..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-move.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-new-privatemessage.png b/administrator/templates/hathor/images/menu/icon-16-new-privatemessage.png deleted file mode 100644 index f8f1ea8fc9726..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-new-privatemessage.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-new.png b/administrator/templates/hathor/images/menu/icon-16-new.png deleted file mode 100644 index 8c4b8ba62b432..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-new.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-newarticle.png b/administrator/templates/hathor/images/menu/icon-16-newarticle.png deleted file mode 100644 index c78257d136e7a..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-newarticle.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-newcategory.png b/administrator/templates/hathor/images/menu/icon-16-newcategory.png deleted file mode 100644 index fd4318c6b0202..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-newcategory.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-newgroup.png b/administrator/templates/hathor/images/menu/icon-16-newgroup.png deleted file mode 100644 index cb5b82cf014f2..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-newgroup.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-newlevel.png b/administrator/templates/hathor/images/menu/icon-16-newlevel.png deleted file mode 100644 index 4ff0fb9a6bf76..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-newlevel.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-newsfeeds-cat.png b/administrator/templates/hathor/images/menu/icon-16-newsfeeds-cat.png deleted file mode 100644 index 55ebb428d0917..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-newsfeeds-cat.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-newsfeeds.png b/administrator/templates/hathor/images/menu/icon-16-newsfeeds.png deleted file mode 100644 index 6639ec8402638..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-newsfeeds.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-newuser.png b/administrator/templates/hathor/images/menu/icon-16-newuser.png deleted file mode 100644 index 25d4cfd2cbc89..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-newuser.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-nopreview.png b/administrator/templates/hathor/images/menu/icon-16-nopreview.png deleted file mode 100644 index cc79db627356e..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-nopreview.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-notdefault.png b/administrator/templates/hathor/images/menu/icon-16-notdefault.png deleted file mode 100644 index 8e5ced866959e..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-notdefault.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-notice.png b/administrator/templates/hathor/images/menu/icon-16-notice.png deleted file mode 100644 index 59f8b36534c67..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-notice.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-plugin.png b/administrator/templates/hathor/images/menu/icon-16-plugin.png deleted file mode 100644 index 852c87dd9d76b..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-plugin.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-preview.png b/administrator/templates/hathor/images/menu/icon-16-preview.png deleted file mode 100644 index e532f7d7b9b8e..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-preview.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-print.png b/administrator/templates/hathor/images/menu/icon-16-print.png deleted file mode 100644 index a1b9f31514e97..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-print.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-purge.png b/administrator/templates/hathor/images/menu/icon-16-purge.png deleted file mode 100644 index 3aa8a5e231f70..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-purge.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-puzzle.png b/administrator/templates/hathor/images/menu/icon-16-puzzle.png deleted file mode 100644 index fcc02d53a26ec..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-puzzle.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-read-privatemessage.png b/administrator/templates/hathor/images/menu/icon-16-read-privatemessage.png deleted file mode 100644 index ee2f44033991e..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-read-privatemessage.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-readmess.png b/administrator/templates/hathor/images/menu/icon-16-readmess.png deleted file mode 100644 index 4c5f30464ab0f..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-readmess.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-redirect.png b/administrator/templates/hathor/images/menu/icon-16-redirect.png deleted file mode 100644 index 3a30b15b418e9..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-redirect.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-revert.png b/administrator/templates/hathor/images/menu/icon-16-revert.png deleted file mode 100644 index 0b6c71f365de5..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-revert.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-search.png b/administrator/templates/hathor/images/menu/icon-16-search.png deleted file mode 100644 index 04cf3852aee95..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-search.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-send.png b/administrator/templates/hathor/images/menu/icon-16-send.png deleted file mode 100644 index 188add672da15..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-send.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-stats.png b/administrator/templates/hathor/images/menu/icon-16-stats.png deleted file mode 100644 index f0c4c04596354..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-stats.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-tags.png b/administrator/templates/hathor/images/menu/icon-16-tags.png deleted file mode 100644 index 94411880b986e..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-tags.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-themes.png b/administrator/templates/hathor/images/menu/icon-16-themes.png deleted file mode 100644 index 2f20de7b95535..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-themes.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-trash.png b/administrator/templates/hathor/images/menu/icon-16-trash.png deleted file mode 100644 index 9c100938a6604..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-trash.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-unarticle.png b/administrator/templates/hathor/images/menu/icon-16-unarticle.png deleted file mode 100644 index 793ea003e9236..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-unarticle.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-upload.png b/administrator/templates/hathor/images/menu/icon-16-upload.png deleted file mode 100644 index 41549c52ebc71..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-upload.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-user-dd.png b/administrator/templates/hathor/images/menu/icon-16-user-dd.png deleted file mode 100644 index a7ab24643df23..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-user-dd.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-user-note.png b/administrator/templates/hathor/images/menu/icon-16-user-note.png deleted file mode 100644 index d634a59c81f47..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-user-note.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-user.png b/administrator/templates/hathor/images/menu/icon-16-user.png deleted file mode 100644 index 51f4ba5110f5b..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-user.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-viewsite.png b/administrator/templates/hathor/images/menu/icon-16-viewsite.png deleted file mode 100644 index 121997e531c4c..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-viewsite.png and /dev/null differ diff --git a/administrator/templates/hathor/images/menu/icon-16-writemess.png b/administrator/templates/hathor/images/menu/icon-16-writemess.png deleted file mode 100644 index f24cfb3db9041..0000000000000 Binary files a/administrator/templates/hathor/images/menu/icon-16-writemess.png and /dev/null differ diff --git a/administrator/templates/hathor/images/mini_icon.png b/administrator/templates/hathor/images/mini_icon.png deleted file mode 100644 index 91a2a59d2a940..0000000000000 Binary files a/administrator/templates/hathor/images/mini_icon.png and /dev/null differ diff --git a/administrator/templates/hathor/images/notice-info.png b/administrator/templates/hathor/images/notice-info.png deleted file mode 100644 index 939933a5715d6..0000000000000 Binary files a/administrator/templates/hathor/images/notice-info.png and /dev/null differ diff --git a/administrator/templates/hathor/images/required.png b/administrator/templates/hathor/images/required.png deleted file mode 100644 index 3cb1bc128db19..0000000000000 Binary files a/administrator/templates/hathor/images/required.png and /dev/null differ diff --git a/administrator/templates/hathor/images/selector-arrow-hc.png b/administrator/templates/hathor/images/selector-arrow-hc.png deleted file mode 100644 index a613f31e114ee..0000000000000 Binary files a/administrator/templates/hathor/images/selector-arrow-hc.png and /dev/null differ diff --git a/administrator/templates/hathor/images/selector-arrow-rtl.png b/administrator/templates/hathor/images/selector-arrow-rtl.png deleted file mode 100644 index 9f721c50463cc..0000000000000 Binary files a/administrator/templates/hathor/images/selector-arrow-rtl.png and /dev/null differ diff --git a/administrator/templates/hathor/images/selector-arrow-std.png b/administrator/templates/hathor/images/selector-arrow-std.png deleted file mode 100644 index 15e3d8fe83b86..0000000000000 Binary files a/administrator/templates/hathor/images/selector-arrow-std.png and /dev/null differ diff --git a/administrator/templates/hathor/images/selector-arrow.png b/administrator/templates/hathor/images/selector-arrow.png deleted file mode 100644 index 9e7687e582639..0000000000000 Binary files a/administrator/templates/hathor/images/selector-arrow.png and /dev/null differ diff --git a/administrator/templates/hathor/images/system/calendar.png b/administrator/templates/hathor/images/system/calendar.png deleted file mode 100644 index 586bc28ed06b0..0000000000000 Binary files a/administrator/templates/hathor/images/system/calendar.png and /dev/null differ diff --git a/administrator/templates/hathor/images/system/selector-arrow.png b/administrator/templates/hathor/images/system/selector-arrow.png deleted file mode 100644 index 9e7687e582639..0000000000000 Binary files a/administrator/templates/hathor/images/system/selector-arrow.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-adduser.png b/administrator/templates/hathor/images/toolbar/icon-32-adduser.png deleted file mode 100644 index a34c2455f3a23..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-adduser.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-alert.png b/administrator/templates/hathor/images/toolbar/icon-32-alert.png deleted file mode 100644 index c4bd24ec35122..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-alert.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-apply.png b/administrator/templates/hathor/images/toolbar/icon-32-apply.png deleted file mode 100644 index 423fcacb1bf78..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-apply.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-archive.png b/administrator/templates/hathor/images/toolbar/icon-32-archive.png deleted file mode 100644 index 13a72777ef76d..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-archive.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-article-add.png b/administrator/templates/hathor/images/toolbar/icon-32-article-add.png deleted file mode 100644 index 0778bd989368c..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-article-add.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-article.png b/administrator/templates/hathor/images/toolbar/icon-32-article.png deleted file mode 100644 index bf16fa6aca4ed..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-article.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-back.png b/administrator/templates/hathor/images/toolbar/icon-32-back.png deleted file mode 100644 index 7b8d35a0022f1..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-back.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-banner-categories.png b/administrator/templates/hathor/images/toolbar/icon-32-banner-categories.png deleted file mode 100644 index 732c0110aca9f..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-banner-categories.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-banner-client.png b/administrator/templates/hathor/images/toolbar/icon-32-banner-client.png deleted file mode 100644 index 5ad4ea221f326..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-banner-client.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-banner-tracks.png b/administrator/templates/hathor/images/toolbar/icon-32-banner-tracks.png deleted file mode 100644 index d39c1ebe03ed4..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-banner-tracks.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-banner.png b/administrator/templates/hathor/images/toolbar/icon-32-banner.png deleted file mode 100644 index e51c03e06b52e..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-banner.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-batch.png b/administrator/templates/hathor/images/toolbar/icon-32-batch.png deleted file mode 100644 index b3cd07e4dde59..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-batch.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-calendar.png b/administrator/templates/hathor/images/toolbar/icon-32-calendar.png deleted file mode 100644 index 5a72d6ee5d821..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-calendar.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-cancel.png b/administrator/templates/hathor/images/toolbar/icon-32-cancel.png deleted file mode 100644 index b143e100b9c30..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-cancel.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-checkin.png b/administrator/templates/hathor/images/toolbar/icon-32-checkin.png deleted file mode 100644 index 04e4e5b349e53..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-checkin.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-cog.png b/administrator/templates/hathor/images/toolbar/icon-32-cog.png deleted file mode 100644 index abbff3602148c..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-cog.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-component.png b/administrator/templates/hathor/images/toolbar/icon-32-component.png deleted file mode 100644 index 7ffc421a88cbf..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-component.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-config.png b/administrator/templates/hathor/images/toolbar/icon-32-config.png deleted file mode 100644 index 53de9648c9d12..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-config.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-contacts-categories.png b/administrator/templates/hathor/images/toolbar/icon-32-contacts-categories.png deleted file mode 100644 index 7ea47e95e6bd3..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-contacts-categories.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-contacts.png b/administrator/templates/hathor/images/toolbar/icon-32-contacts.png deleted file mode 100644 index 2b7abca4ce33c..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-contacts.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-copy.png b/administrator/templates/hathor/images/toolbar/icon-32-copy.png deleted file mode 100644 index dc036ec8d141a..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-copy.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-css.png b/administrator/templates/hathor/images/toolbar/icon-32-css.png deleted file mode 100644 index 1b75813bbca44..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-css.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-default.png b/administrator/templates/hathor/images/toolbar/icon-32-default.png deleted file mode 100644 index 90c8aa95eb1c8..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-default.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-delete-style.png b/administrator/templates/hathor/images/toolbar/icon-32-delete-style.png deleted file mode 100644 index 247ead53598f1..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-delete-style.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-delete.png b/administrator/templates/hathor/images/toolbar/icon-32-delete.png deleted file mode 100644 index 4d05ecdb12412..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-delete.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-deny.png b/administrator/templates/hathor/images/toolbar/icon-32-deny.png deleted file mode 100644 index 4ac081c68ac5d..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-deny.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-download.png b/administrator/templates/hathor/images/toolbar/icon-32-download.png deleted file mode 100644 index d09df7824f306..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-download.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-edit.png b/administrator/templates/hathor/images/toolbar/icon-32-edit.png deleted file mode 100644 index 344b3e79d51de..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-edit.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-error.png b/administrator/templates/hathor/images/toolbar/icon-32-error.png deleted file mode 100644 index 0cc0aaa71aae3..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-error.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-export.png b/administrator/templates/hathor/images/toolbar/icon-32-export.png deleted file mode 100644 index d9d59835859af..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-export.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-extension.png b/administrator/templates/hathor/images/toolbar/icon-32-extension.png deleted file mode 100644 index 8a45ae77ea682..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-extension.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-featured.png b/administrator/templates/hathor/images/toolbar/icon-32-featured.png deleted file mode 100644 index 1662afae21702..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-featured.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-forward.png b/administrator/templates/hathor/images/toolbar/icon-32-forward.png deleted file mode 100644 index c3ac95d324b9c..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-forward.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-help.png b/administrator/templates/hathor/images/toolbar/icon-32-help.png deleted file mode 100644 index fbf408cd9a97e..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-help.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-html.png b/administrator/templates/hathor/images/toolbar/icon-32-html.png deleted file mode 100644 index 1570f323ebab7..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-html.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-inbox.png b/administrator/templates/hathor/images/toolbar/icon-32-inbox.png deleted file mode 100644 index 490d275c198fb..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-inbox.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-info.png b/administrator/templates/hathor/images/toolbar/icon-32-info.png deleted file mode 100644 index 0f6c8ca981ab9..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-info.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-links.png b/administrator/templates/hathor/images/toolbar/icon-32-links.png deleted file mode 100644 index bd867afce4d51..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-links.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-lock.png b/administrator/templates/hathor/images/toolbar/icon-32-lock.png deleted file mode 100644 index a9180af81e354..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-lock.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-menu.png b/administrator/templates/hathor/images/toolbar/icon-32-menu.png deleted file mode 100644 index bc0b5fd498422..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-menu.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-messaging.png b/administrator/templates/hathor/images/toolbar/icon-32-messaging.png deleted file mode 100644 index ee6080cd4035a..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-messaging.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-messanging.png b/administrator/templates/hathor/images/toolbar/icon-32-messanging.png deleted file mode 100644 index ee6080cd4035a..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-messanging.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-module.png b/administrator/templates/hathor/images/toolbar/icon-32-module.png deleted file mode 100644 index eb21806726580..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-module.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-move.png b/administrator/templates/hathor/images/toolbar/icon-32-move.png deleted file mode 100644 index 2ef3a18968a97..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-move.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-new-privatemessage.png b/administrator/templates/hathor/images/toolbar/icon-32-new-privatemessage.png deleted file mode 100644 index 5546a3162ebe9..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-new-privatemessage.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-new-style.png b/administrator/templates/hathor/images/toolbar/icon-32-new-style.png deleted file mode 100644 index cf23704f31625..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-new-style.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-new.png b/administrator/templates/hathor/images/toolbar/icon-32-new.png deleted file mode 100644 index a4e1b78a832d6..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-new.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-notice.png b/administrator/templates/hathor/images/toolbar/icon-32-notice.png deleted file mode 100644 index cb6db185bb7db..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-notice.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-preview.png b/administrator/templates/hathor/images/toolbar/icon-32-preview.png deleted file mode 100644 index eefa6a51e00b6..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-preview.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-print.png b/administrator/templates/hathor/images/toolbar/icon-32-print.png deleted file mode 100644 index 8ed65a3333b0d..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-print.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-publish.png b/administrator/templates/hathor/images/toolbar/icon-32-publish.png deleted file mode 100644 index 3bd38264d6e03..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-publish.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-purge.png b/administrator/templates/hathor/images/toolbar/icon-32-purge.png deleted file mode 100644 index c87eebd05c700..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-purge.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-read-privatemessage.png b/administrator/templates/hathor/images/toolbar/icon-32-read-privatemessage.png deleted file mode 100644 index eb40ead2cd341..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-read-privatemessage.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-refresh.png b/administrator/templates/hathor/images/toolbar/icon-32-refresh.png deleted file mode 100644 index e974d56fd3ff9..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-refresh.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-remove.png b/administrator/templates/hathor/images/toolbar/icon-32-remove.png deleted file mode 100644 index 65ffdb3e859e9..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-remove.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-revert.png b/administrator/templates/hathor/images/toolbar/icon-32-revert.png deleted file mode 100644 index 60b139696fcfc..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-revert.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-save-copy.png b/administrator/templates/hathor/images/toolbar/icon-32-save-copy.png deleted file mode 100644 index 3885723b13678..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-save-copy.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-save-new.png b/administrator/templates/hathor/images/toolbar/icon-32-save-new.png deleted file mode 100644 index e5a115a2a4729..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-save-new.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-save.png b/administrator/templates/hathor/images/toolbar/icon-32-save.png deleted file mode 100644 index 399dec5c32ed2..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-save.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-search.png b/administrator/templates/hathor/images/toolbar/icon-32-search.png deleted file mode 100644 index a3be36a395d2f..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-search.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-send.png b/administrator/templates/hathor/images/toolbar/icon-32-send.png deleted file mode 100644 index 51ae41456d8db..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-send.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-stats.png b/administrator/templates/hathor/images/toolbar/icon-32-stats.png deleted file mode 100644 index b3eb1ebe91686..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-stats.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-trash.png b/administrator/templates/hathor/images/toolbar/icon-32-trash.png deleted file mode 100644 index 89efa4ac03173..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-trash.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-unarchive.png b/administrator/templates/hathor/images/toolbar/icon-32-unarchive.png deleted file mode 100644 index 32b95072766d0..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-unarchive.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-unblock.png b/administrator/templates/hathor/images/toolbar/icon-32-unblock.png deleted file mode 100644 index eccc84a45050d..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-unblock.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-unpublish.png b/administrator/templates/hathor/images/toolbar/icon-32-unpublish.png deleted file mode 100644 index 1cf06556e5110..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-unpublish.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-upload.png b/administrator/templates/hathor/images/toolbar/icon-32-upload.png deleted file mode 100644 index e41e613b80683..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-upload.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-user-add.png b/administrator/templates/hathor/images/toolbar/icon-32-user-add.png deleted file mode 100644 index 8bbf9d819b129..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-user-add.png and /dev/null differ diff --git a/administrator/templates/hathor/images/toolbar/icon-32-xml.png b/administrator/templates/hathor/images/toolbar/icon-32-xml.png deleted file mode 100644 index 95831db9fea4a..0000000000000 Binary files a/administrator/templates/hathor/images/toolbar/icon-32-xml.png and /dev/null differ diff --git a/administrator/templates/hathor/index.php b/administrator/templates/hathor/index.php deleted file mode 100644 index a29cb2946dad5..0000000000000 --- a/administrator/templates/hathor/index.php +++ /dev/null @@ -1,179 +0,0 @@ -setHtml5(true); - -// jQuery needed by template.js -JHtml::_('jquery.framework'); - -// Add template js -JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); - -// Add html5 shiv -JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); - -// Load optional RTL Bootstrap CSS -JHtml::_('bootstrap.loadCss', false, $this->direction); - -// Load system style CSS -JHtml::_('stylesheet', 'templates/system/css/system.css', array('version' => 'auto')); - -// Load template CSS -JHtml::_('stylesheet', 'template.css', array('version' => 'auto', 'relative' => true)); - -// Load additional CSS styles for colors -if (!$this->params->get('colourChoice')) -{ - $colour = 'standard'; -} -else -{ - $colour = htmlspecialchars($this->params->get('colourChoice')); -} - -JHtml::_('stylesheet', 'colour_' . $colour . '.css', array('version' => 'auto', 'relative' => true)); - -// Load additional CSS styles for rtl sites -if ($this->direction === 'rtl') -{ - JHtml::_('stylesheet', 'template_rtl.css', array('version' => 'auto', 'relative' => true)); - JHtml::_('stylesheet', 'colour_' . $colour . '_rtl.css', array('version' => 'auto', 'relative' => true)); -} - -// Load additional CSS styles for bold Text -if ($this->params->get('boldText')) -{ - JHtml::_('stylesheet', 'boldtext.css', array('version' => 'auto', 'relative' => true)); -} - -// Load specific language related CSS -JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); - -// Load custom.css -JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); - -// IE specific -JHtml::_('stylesheet', 'ie8.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 8')); -JHtml::_('stylesheet', 'ie7.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 7')); - -// Logo file -if ($this->params->get('logoFile')) -{ - $logo = JUri::root() . $this->params->get('logoFile'); -} -else -{ - $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo.png'; -} - -$this->addScriptDeclaration(" - (function($){ - $(document).ready(function () { - // Patches to fix some wrong render of chosen fields - $('.chzn-container, .chzn-drop, .chzn-choices .search-field input').each(function (index) { - $(this).css({ - 'width': 'auto' - }); - }); - }); - })(jQuery); -"); -?> - - - - - - - -
          - - - - - -
          - -
          - -
          - - - - - -
          - input->getInt('hidemainmenu')) : ?> -

          - - - -
          - -
          - -
          - -
          -
          - -
          -
          -

          - - -
          -
          - -
          -
          -
          -
          - - - - diff --git a/administrator/templates/hathor/js/template.js b/administrator/templates/hathor/js/template.js deleted file mode 100644 index c60644898da7f..0000000000000 --- a/administrator/templates/hathor/js/template.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @package Hathor - * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - */ - -/** - * Functions - */ - -/** - * Change the skip nav target to work with webkit browsers (Safari/Chrome) and - * Opera - */ -function setSkip() { - var $ = jQuery.noConflict(); - var browser = $.browser; - if (browser.chrome || browser.safari || browser.opera) { - var $target = $('#skiptarget'); - $target.attr('href',"#skiptarget"); - $target.text("Start of main content"); - $target.attr("tabindex", "0"); - $('#skiplink').on("click", function(){ - $('#skiptarget').focus(); - }); - } -} - -/** - * Set the Aria Role based on the id - * - * @param id - * @param rolevalue - * @return - */ -function setRoleAttribute(id, rolevalue) { - if (jQuery('#' + id).length) { - jQuery('#'+ id).attr("role", rolevalue); - } -} - -/** - * Set the WAI-ARIA Roles Specify the html id then aria role - * - * @return - */ -function setAriaRoleElementsById() { - setRoleAttribute("header", "banner"); - setRoleAttribute("element-box", "main"); - setRoleAttribute("footer", "contentinfo"); - setRoleAttribute("nav", "navigation"); - setRoleAttribute("submenu", "navigation"); - setRoleAttribute("system-message", "alert"); -} - -/** - * This sets the given Aria Property state to true for the given element - * - * @param el - * The element (tag.class) - * @param prop - * The property to set to true - * @return - */ -function setPropertyAttribute(el, prop) { - if (jQuery(el).length) { - jQuery(el).attr(prop, "true"); - } -} - -/** - * Set the WAI-ARIA Properties Specify the tag.class then the aria property to - * set to true If classes are changed on the fly (i.e. aria-invalid) they need - * to be changed there instead of here. - * - * @return - */ -function setAriaProperties() { - setPropertyAttribute("input.required", "aria-required"); - setPropertyAttribute("textarea.required", "aria-required"); - setPropertyAttribute("input.readonly", "aria-readonly"); - setPropertyAttribute("input.invalid", "aria-invalid"); - setPropertyAttribute("textarea.invalid", "aria-invalid"); -} - - -/** - * Process file - */ - -/** from accessible suckerfish menu by Matt Carroll, - * mootooled by Bill Tomczak - */ - -jQuery(function($){ - var $menu = $('#menu'); - if ($menu.length && !$menu.hasClass('disabled')) { - $menu.find('li').each(function(){ - $(this).on('mouseenter', function(){ - $(this).addClass('sfhover'); - }); - $(this).on('mouseleave', function() { - $(this).removeClass('sfhover'); - }); - }); - - $menu.find('a').each(function() { - $(this).on('focus', function() { - $(this).addClass('sffocus'); - $(this).closest('li').addClass('sfhover'); - }); - $(this).on('blur', function() { - $(this).removeClass('sffocus'); - $(this).closest('li').removeClass('sfhover'); - }); - }); - } -}); - -jQuery(function() { - setSkip(); - setAriaRoleElementsById(); - setAriaProperties(); -}); \ No newline at end of file diff --git a/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.ini b/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.ini deleted file mode 100644 index 084cad298a9cc..0000000000000 --- a/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.ini +++ /dev/null @@ -1,29 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -HATHOR="Hathor Administrator template" -TPL_HATHOR_ALTERNATE_MENU_DESC="Use the alternative menu which integrates mouse and keyboard. JavaScript Required. The regular menu for Hathor is accessible with or without Javascript, but leaves the mouse and keyboard independent." -TPL_HATHOR_ALTERNATE_MENU_LABEL="Alternative Menu" -TPL_HATHOR_BOLD_TEXT_DESC="Use bold text." -TPL_HATHOR_BOLD_TEXT_LABEL="Bold Text" -TPL_HATHOR_CHECKMARK_ALL="Checkmark All" -TPL_HATHOR_COLOUR_CHOICE_BLUE="Blue" -TPL_HATHOR_COLOUR_CHOICE_DESC="Select the colour palette to use with the template. You can use this option to select a high contrast version or use it to create custom branding." -TPL_HATHOR_COLOUR_CHOICE_LABEL="Select Colour" -TPL_HATHOR_COLOUR_CHOICE_STANDARD="Standard" -TPL_HATHOR_COLOUR_CHOICE_HIGH_CONTRAST="High Contrast" -TPL_HATHOR_COLOUR_CHOICE_BROWN="Brown" -TPL_HATHOR_COM_MENUS_MENU="Menu" -TPL_HATHOR_COM_MODULES_CUSTOM_POSITION_LABEL="Select" -TPL_HATHOR_CPANEL_LINK_TEXT="Return to Control Panel" -TPL_HATHOR_GO="Go" -TPL_HATHOR_LOGO_DESC="Select or upload a custom logo for the administrator template." -TPL_HATHOR_LOGO_LABEL="Logo" -TPL_HATHOR_MAIN_MENU="Main Menu" -TPL_HATHOR_SHOW_SITE_NAME_DESC="Show the site name in the template header." -TPL_HATHOR_SHOW_SITE_NAME_LABEL="Show Site Name" -TPL_HATHOR_SKIP_TO_MAIN_CONTENT="Skip to Main Content" -TPL_HATHOR_SUB_MENU="Sub Menu" -TPL_HATHOR_XML_DESCRIPTION="Hathor is an accessible Administrator template for Joomla! The Colour CSS files can also be used for custom colour branding." diff --git a/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.sys.ini b/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.sys.ini deleted file mode 100644 index 43cd299193933..0000000000000 --- a/administrator/templates/hathor/language/en-GB/en-GB.tpl_hathor.sys.ini +++ /dev/null @@ -1,19 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -HATHOR="Hathor Administrator template" -TPL_HATHOR_POSITION_CP_SHELL="Unused" -TPL_HATHOR_POSITION_CPANEL="Control Panel" -TPL_HATHOR_POSITION_DEBUG="Debug" -TPL_HATHOR_POSITION_FOOTER="Footer" -TPL_HATHOR_POSITION_ICON="Quick Icons" -TPL_HATHOR_POSITION_LOGIN="Login" -TPL_HATHOR_POSITION_MENU="Menu" -TPL_HATHOR_POSITION_POSTINSTALL="Postinstall" -TPL_HATHOR_POSITION_STATUS="Status" -TPL_HATHOR_POSITION_SUBMENU="Submenu" -TPL_HATHOR_POSITION_TITLE="Title" -TPL_HATHOR_POSITION_TOOLBAR="Toolbar" -TPL_HATHOR_XML_DESCRIPTION="Hathor is an accessible Administrator template for Joomla! The Colour CSS files can also be used for custom colour branding." diff --git a/administrator/templates/hathor/less/buttons.less b/administrator/templates/hathor/less/buttons.less deleted file mode 100644 index 550f8053b5476..0000000000000 --- a/administrator/templates/hathor/less/buttons.less +++ /dev/null @@ -1,82 +0,0 @@ -// -// Buttons -// This is a custom version of Bootstrap's buttons.less file suited for Hathor's needs -// -------------------------------------------------- - - -// Base styles -// -------------------------------------------------- - -// Core -#form-login .btn { - display: inline-block; - .ie7-inline-block(); - padding: 4px 14px; - margin-bottom: 0; // For input.btn - font-size: @baseFontSize; - line-height: @baseLineHeight; - *line-height: @baseLineHeight; - text-align: center; - vertical-align: middle; - cursor: pointer; - .buttonBackground(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75)); - border: 1px solid @btnBorder; - *border: 0; // Remove the border to prevent IE7's black border on input:focus - border-bottom-color: darken(@btnBorder, 10%); - .border-radius(4px); - .ie7-restore-left-whitespace(); // Give IE7 some love - .box-shadow(~"inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05)"); - - // Hover state - &:hover { - color: @grayDark; - text-decoration: none; - background-color: darken(@white, 10%); - *background-color: darken(@white, 15%); /* Buttons in IE7 don't get borders, so darken on hover */ - background-position: 0 -15px; - - // transition is only when going to hover, otherwise the background - // behind the gradient (there for IE<=9 fallback) gets mismatched - .transition(background-position .1s linear); - } - - // Focus state for keyboard and accessibility - &:focus { - .tab-focus(); - } - - // Active state - &.active, - &:active { - background-color: darken(@white, 10%); - background-color: darken(@white, 15%) e("\9"); - background-image: none; - outline: 0; - .box-shadow(~"inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)"); - } - - // Disabled state - &.disabled, - &[disabled] { - cursor: default; - background-color: darken(@white, 10%); - background-image: none; - .opacity(65); - .box-shadow(none); - } - -} - -// Button Sizes -// -------------------------------------------------- - -// Large -.btn-large { - padding: 9px 14px; - font-size: @baseFontSize + 2px; - line-height: normal; - .border-radius(5px); -} -.btn-large [class^="icon-"] { - margin-top: 2px; -} diff --git a/administrator/templates/hathor/less/colour_baseline.less b/administrator/templates/hathor/less/colour_baseline.less deleted file mode 100644 index 530da15508b7a..0000000000000 --- a/administrator/templates/hathor/less/colour_baseline.less +++ /dev/null @@ -1,1779 +0,0 @@ -// colour_baseline.less -// -// Baseline CSS for the Hathor colours. -// Compilers should include this in their colour's imports, but not directly -// compile using this file. -// ----------------------------------------------------- - -// Core variables and mixins -@import "../../../../media/jui/less/mixins.less"; - -// Bootstrap Buttons -// Using override for Hathor to target specific instances only -@import "buttons.less"; - -// Bootstrap Forms -// Using override for Hathor since we're not pulling in all Bootstrap form styles -@import "forms.less"; - -// Bootstrap Labels and Badges -@import "../../../../media/jui/less/labels-badges.less"; - -/* - * General styles - */ -body { - background-color: @bodyBackground; - color: @textColor; -} - -h1 { - color: @textColor; -} - -a:link { - color: @linkColor; -} - -a:visited { - color: @linkColor; -} - -/* - * Overall Styles - */ -#header { - background: @bodyBackground url(../images/j_logo.png) no-repeat; -} - -#header h1.title { - color: @textColor; -} - -#nav { - #gradient > .vertical(@gradientTop, @gradientBottom); - border: 1px solid @mainBorder; -} - -#content { - background: @bodyBackground; -} - -#no-submenu { - border-bottom: 1px solid @mainBorder; -} - -#element-box { - background: @bodyBackground; - border-right: 1px solid @mainBorder; - border-bottom: 1px solid @mainBorder; - border-left: 1px solid @mainBorder; -} - -#element-box.login { - border-top: 1px solid @mainBorder; -} - -/* - * Various Styles - */ -.enabled, -.success, -.allow, -span.writable { - color: @successText; -} - -.disabled, -p.error, -.warning, -.deny, -span.unwritable { - color: @errorText; -} - -.nowarning { - color: @textColor; -} - -.none, -.protected { - color: @mainBorder; -} - -span.note { - background: @bodyBackground; - color: @textColor; -} - -div.checkin-tick { - background: url(../images/admin/tick.png) 20px 50% no-repeat; -} - -/* - * Overlib - */ -.ol-foreground { - background-color: @altBackground; -} - -.ol-background { - background-color: @successText; -} - -.ol-textfont { - color: @textColor; -} - -.ol-captionfont { - color: @bodyBackground; -} - -.ol-captionfont a { - color: @linkColor; -} - -/* - * Subheader, toolbar, page title - */ -div.subheader .padding { - background: @bodyBackground; -} - -.pagetitle h2 { - color: @textColor; -} - -div.configuration { - color: @textColor; - background-image: url(../images/menu/icon-16-config.png); - background-repeat: no-repeat; -} - -div.toolbar-box { - border-right: 1px solid @mainBorder; - border-bottom: 1px solid @mainBorder; - border-left: 1px solid @mainBorder; - background: @bodyBackground; -} - -div.toolbar-list li { - color: @textColor; -} - -div.toolbar-list li.divider { - border-right: 1px dotted @hoverBackground; -} - -div.toolbar-list a { - border-left: 1px solid @hoverBackground; - border-top: 1px solid @hoverBackground; - border-right: 1px solid @mainBorder; - border-bottom: 1px solid @mainBorder; - background: @altBackground; -} - -div.toolbar-list a:hover { - border-left: 1px solid @nwBorder; - border-top: 1px solid @nwBorder; - border-right: 1px solid @seBorder; - border-bottom: 1px solid @seBorder; - background: @hoverBackground; - color: @toolbarColor; -} - -div.btn-toolbar { - margin-left: 5px; - padding-top: 3px; -} - -div.btn-toolbar li.divider { - border-right: 1px dotted @hoverBackground; -} - -div.btn-toolbar div.btn-group button { - border-left: 1px solid @hoverBackground; - border-top: 1px solid @hoverBackground; - border-right: 1px solid @mainBorder; - border-bottom: 1px solid @mainBorder; - #gradient > .vertical(@gradientTop, @gradientBottom); - padding: 5px 4px 5px 4px; -} - -div.btn-toolbar div.btn-group button:hover { - border-left: 1px solid @nwBorder; - border-top: 1px solid @nwBorder; - border-right: 1px solid @seBorder; - border-bottom: 1px solid @seBorder; - background: @hoverBackground; - color: @toolbarColor; - cursor: pointer; -} - -div.btn-toolbar a { - border-left: 1px solid @hoverBackground; - border-top: 1px solid @hoverBackground; - border-right: 1px solid @mainBorder; - border-bottom: 1px solid @mainBorder; - #gradient > .vertical(@gradientTop, @gradientBottom); - padding: 6px 5px; - text-align: center; - white-space: nowrap; - font-size: 1.2em; - text-decoration: none; -} - -div.btn-toolbar a:hover { - border-left: 1px solid @nwBorder; - border-top: 1px solid @nwBorder; - border-right: 1px solid @seBorder; - border-bottom: 1px solid @seBorder; - background: @hoverBackground; - color: @toolbarColor; - cursor: pointer; -} - -div.btn-toolbar div.btn-group button.inactive { - background: @altBackground; -} - -/* - * Pane Slider pane Toggler styles - */ -.pane-sliders .title { - color: @textColor; -} - -.pane-sliders .panel { - border: 1px solid @mainBorder; -} - -.pane-sliders .panel h3 { - #gradient > .vertical(@gradientTop, @gradientBottom); - color: @linkColor; -} - -.pane-sliders .panel h3:hover { - background: @hoverBackground; -} - -.pane-sliders .panel h3:hover a { - text-decoration: none; -} - -.pane-sliders .adminlist { - border: 0 none; -} - -.pane-sliders .adminlist td { - border: 0 none; -} - -.pane-toggler span { - background: transparent url(../images/j_arrow.png) 5px 50% no-repeat; -} - -.pane-toggler-down span { - background: transparent url(../images/j_arrow_down.png) 5px 50% no-repeat; -} - -.pane-toggler-down { - border-bottom: 1px solid @mainBorder; -} - -/* - * Tabs - */ -dl.tabs dt { - border: 1px solid @mainBorder; - #gradient > .vertical(@gradientTop, @gradientBottom); - color: @linkColor; -} - -dl.tabs dt:hover { - background: @hoverBackground; -} - -dl.tabs dt.open { - background: @bodyBackground; - border-bottom: 1px solid @bodyBackground; - color: @textColor; -} - -dl.tabs dt.open a:visited { - color: @textColor; -} - -dl.tabs dt a:hover { - text-decoration: none; -} - -dl.tabs dt a:focus { - text-decoration: underline; -} - -div.current { - border: 1px solid @mainBorder; - background: @bodyBackground; -} - -/* - * New parameter styles - */ -div.current fieldset { - border: none 0; -} - -div.current fieldset.adminform { - border: 1px solid @mainBorder; -} - -/* - * Login Settings - */ -#login-page .pagetitle h2 { - background: transparent; -} - -#login-page #header { - border-bottom: 1px solid @mainBorder; -} - -#login-page #lock { - background: url(../images/j_login_lock.png) 50% 0 no-repeat; -} - -#login-page #element-box.login { - #gradient > .vertical(@gradientTop, @gradientBottom); -} - -#form-login { - background: @bodyBackground; - border: 1px solid @mainBorder; -} - -#form-login label { - color: @textColor; -} - -#form-login div.button1 a { - color: @linkColor; -} - -/* - * Cpanel Settings - */ -#cpanel div.icon a, .cpanel div.icon a { - color: @linkColor; - border-left: 1px solid @hoverBackground; - border-top: 1px solid @hoverBackground; - border-right: 1px solid @mainBorder; - border-bottom: 1px solid @mainBorder; - #gradient > .vertical(@gradientTop, @gradientBottom); -} - -#cpanel div.icon a:hover, -#cpanel div.icon a:focus, -.cpanel div.icon a:hover, -.cpanel div.icon a:focus { - border-left: 1px solid @nwBorder; - border-top: 1px solid @nwBorder; - border-right: 1px solid @seBorder; - border-bottom: 1px solid @seBorder; - color: @linkColor; - background: @hoverBackground; -} - -/* - * Form Styles - */ -fieldset { - border: 1px @mainBorder solid; -} - -legend { - color: @textColor; -} - -fieldset ul.checklist input:focus { - outline: thin dotted @textColor; -} - -fieldset#filter-bar { - border-top: 0 solid @mainBorder; - border-right: 0 solid @mainBorder; - border-bottom: 1px solid @mainBorder; - border-left: 0 solid @mainBorder; -} - -fieldset#filter-bar ol, fieldset#filter-bar ul { - border: 0; -} - -fieldset#filter-bar ol li fieldset, fieldset#filter-bar ul li fieldset { - border: 0; -} - -/* Note: these visual cues should be augmented by aria */ -.invalid { - color: @errorText; -} - -/* must be augmented by aria at the same time if changed dynamically by js -aria-invalid=true or aria-invalid=false */ -input.invalid { - border: 1px solid @errorText; -} - -/* augmented by aria in template javascript */ -input.readonly, span.faux-input { - border: 0; -} - -input.required { - background-color: @inputBackground; -} - -input.disabled { - background-color: @disabledBackground; -} - -input, select, span.faux-input { - background-color: @bodyBackground; - border: 1px solid @mainBorder; -} - -/* Inputs used as buttons */ -input[type="button"], input[type="submit"], input[type="reset"] { - color: @linkColor; - #gradient > .vertical(@gradientTop, @gradientBottom); -} - -input[type="button"]:hover, input[type="button"]:focus, -input[type="submit"]:hover, input[type="submit"]:focus, -input[type="reset"]:hover, input[type="reset"]:focus { - background: @hoverBackground; -} - -textarea { - background-color: @bodyBackground; - border: 1px solid @mainBorder; -} - -input:focus, select:focus, textarea:focus, option:focus, -input:hover, select:hover, textarea:hover, option:hover { - background-color: @hoverBackground; - color: @linkColor; -} - -/* - * Option or Parameter styles - */ -.paramrules { - background: @altBackground; -} - -span.gi { - color: @mainBorder; -} - -/* - * Admintable Styles - */ -table.admintable td.key, table.admintable td.paramlist_key { - background-color: @altBackground; - color: @textColor; - border-bottom: 1px solid @mainBorder; - border-right: 1px solid @mainBorder; -} - -table.paramlist td.paramlist_description { - background-color: @altBackground; - color: @textColor; - border-bottom: 1px solid @mainBorder; - border-right: 1px solid @mainBorder; -} - -/* - * Admin Form Styles - */ -fieldset.adminform { - border: 1px solid @mainBorder; -} - -/* - * Table styles are for use with tabular data - */ -table.adminform { - background-color: @bodyBackground; -} - -table.adminform tr.row0 { - background-color: @bodyBackground; -} - -table.adminform tr.row1 { - background-color: @hoverBackground; -} - -table.adminform th { - color: @textColor; - background: @bodyBackground; -} - -table.adminform tr { - border-bottom: 1px solid @mainBorder; - border-right: 1px solid @mainBorder; -} - -/* - * Adminlist Table layout - */ -table.adminlist { - border-spacing: 1px; - background-color: @bodyBackground; - color: @textColor; -} - -table.adminlist.modal { - border-top: 1px solid @mainBorder; - border-right: 1px solid @mainBorder; - border-left: 1px solid @mainBorder; -} - -table.adminlist a { - color: @linkColor; -} - -table.adminlist thead th { - background: @bodyBackground; - color: @textColor; - border-bottom: 1px solid @mainBorder; -} - -/* - * Table row styles - */ -table.adminlist tbody tr { - background: @bodyBackground; -} - -table.adminlist tbody tr.row1 { - background: @bodyBackground; -} - -table.adminlist tbody tr.row1:last-child td, -table.adminlist tbody tr.row1:last-child th { - border-bottom: 1px solid @mainBorder; -} - -table.adminlist tbody tr.row0:hover td, -table.adminlist tbody tr.row1:hover td, -table.adminlist tbody tr.row0:hover th, -table.adminlist tbody tr.row1:hover th, -table.adminlist tbody tr.row0:focus td, -table.adminlist tbody tr.row1:focus td, -table.adminlist tbody tr.row0:focus th, -table.adminlist tbody tr.row1:focus th { - background-color: @hoverBackground; -} - -table.adminlist tbody tr td, -table.adminlist tbody tr th { - border-right: 1px solid @mainBorder; -} - -table.adminlist tbody tr td:last-child { - border-right: none; -} - -table.adminlist tbody tr.row0:last-child td, -table.adminlist tbody tr.row0:last-child th { - border-bottom: 1px solid @mainBorder; -} - -table.adminlist tbody tr.row0 td, -table.adminlist tbody tr.row0 th { - #gradient > .vertical(@gradientTop, @gradientBottom); -} - -table.adminlist { - border-bottom: 0 solid @mainBorder; -} - -table.adminlist tfoot tr { - color: @textColor; -} - -/* - * Table td/th styles - */ -table.adminlist tfoot td, -table.adminlist tfoot th { - background-color: @bodyBackground; - border-top: 1px solid @mainBorder; -} - -/* - * Adminlist buttons - */ -table.adminlist tr td.btns a { - border: 1px solid @mainBorder; - #gradient > .vertical(@gradientTop, @gradientBottom); - color: @linkColor; -} - -table.adminlist tr td.btns a:hover, -table.adminlist tr td.btns a:active, -table.adminlist tr td.btns a:focus { - background-color: @bodyBackground; -} - -/* - * Saving order icon styling in admin tables - */ -a.saveorder { - background: url(../images/admin/filesave.png) no-repeat; -} - -a.saveorder.inactive { - background-position: 0 -16px; -} - -/* - * Saving order icon styling in admin tables - */ -fieldset.batch { - background: @bodyBackground; -} - -/** - * Button styling - */ -button { - color: @toolbarColor; - border: 1px solid @mainBorder; - #gradient > .vertical(@gradientTop, @gradientBottom); -} - -button:hover, -button:focus { - background: @hoverBackground; -} - -.invalid { - color: #ff0000; -} - -/* Button 1 Type */ -.button1 { - border: 1px solid @mainBorder; - color: @linkColor; - #gradient > .vertical(@gradientTop, @gradientBottom); -} - -/* Use this if you add images to the buttons such as directional arrows */ -.button1 a { - color: @linkColor; -/* add padding if you are using the directional images */ -/* padding: 0 30px 0 6px; */ -} - -.button1 a:hover, -.button1 a:focus { - background: @hoverBackground; -} - -/* Button 2 Type */ -.button2-left, -.button2-right { - border: 1px solid @mainBorder; - #gradient > .vertical(@gradientTop, @gradientBottom); -} - -.button2-left a, -.button2-right a, -.button2-left span, -.button2-right span { - color: @linkColor; -} - -/* these are inactive buttons */ -.button2-left span, -.button2-right span { - color: #999999; -} - -.page span, -.blank span { - color: @linkColor; -} - -.button2-left a:hover, -.button2-right a:hover, -.button2-left a:focus, -.button2-right a:focus { - background: @hoverBackground; -} - -/** - * Pagination styles - */ - -/* Grey out the current page number */ -.pagination .page span { - color: #999999; -} - -/** - * Tooltips - */ -.tip { - background: #000000; - border: 1px solid #FFFFFF; -} - -.tip-title { - background: url(../images/selector-arrow-std.png) no-repeat; -} - -/** - * Calendar - */ -a img.calendar { - background: url(../images/calendar.png) no-repeat; -} - -/** - * JGrid styles - */ -.jgrid span.publish { - background-image: url(../images/admin/tick.png); -} - -.jgrid span.unpublish { - background-image: url(../images/admin/publish_x.png); -} - -.jgrid span.archive { - background-image: url(../images/menu/icon-16-archive.png); -} - -.jgrid span.trash { - background-image: url(../images/menu/icon-16-trash.png); -} - -.jgrid span.default { - background-image: url(../images/menu/icon-16-default.png); -} - -.jgrid span.notdefault { - background-image: url(../images/menu/icon-16-notdefault.png); -} - -.jgrid span.checkedout { - background-image: url(../images/admin/checked_out.png); -} - -.jgrid span.downarrow { - background-image: url(../images/admin/downarrow.png); -} - -.jgrid span.downarrow_disabled { - background-image: url(../images/admin/downarrow0.png); -} - -.jgrid span.uparrow { - background-image: url(../images/admin/uparrow.png); -} - -.jgrid span.uparrow_disabled { - background-image: url(../images/admin/uparrow0.png); -} - -.jgrid span.published { - background-image: url(../images/admin/publish_g.png); -} - -.jgrid span.expired { - background-image: url(../images/admin/publish_r.png); -} - -.jgrid span.pending { - background-image: url(../images/admin/publish_y.png); -} - -.jgrid span.warning { - background-image: url(../images/admin/publish_y.png); -} - -/** - * Toolbar icons - * These icons are used for the toolbar buttons - * The classes are constructed dynamically when the toolbar is created - */ -.icon-32-send { - background-image: url(../images/toolbar/icon-32-send.png); -} - -.icon-32-delete { - background-image: url(../images/toolbar/icon-32-delete.png); -} - -.icon-32-help { - background-image: url(../images/toolbar/icon-32-help.png); -} - -.icon-32-cancel { - background-image: url(../images/toolbar/icon-32-cancel.png); -} - -.icon-32-checkin { - background-image: url(../images/toolbar/icon-32-checkin.png); -} - -.icon-32-options { - background-image: url(../images/toolbar/icon-32-config.png); -} - -.icon-32-apply { - background-image: url(../images/toolbar/icon-32-apply.png); -} - -.icon-32-back { - background-image: url(../images/toolbar/icon-32-back.png); -} - -.icon-32-forward { - background-image: url(../images/toolbar/icon-32-forward.png); -} - -.icon-32-save { - background-image: url(../images/toolbar/icon-32-save.png); -} - -.icon-32-edit { - background-image: url(../images/toolbar/icon-32-edit.png); -} - -.icon-32-copy { - background-image: url(../images/toolbar/icon-32-copy.png); -} - -.icon-32-move { - background-image: url(../images/toolbar/icon-32-move.png); -} - -.icon-32-new { - background-image: url(../images/toolbar/icon-32-new.png); -} - -.icon-32-upload { - background-image: url(../images/toolbar/icon-32-upload.png); -} - -.icon-32-assign { - background-image: url(../images/toolbar/icon-32-publish.png); -} - -.icon-32-html { - background-image: url(../images/toolbar/icon-32-html.png); -} - -.icon-32-css { - background-image: url(../images/toolbar/icon-32-css.png); -} - -.icon-32-menus { - background-image: url(../images/toolbar/icon-32-menu.png); -} - -.icon-32-publish { - background-image: url(../images/toolbar/icon-32-publish.png); -} - -.icon-32-unblock { - background-image: url(../images/toolbar/icon-32-unblock.png); -} - -.icon-32-unpublish { - background-image: url(../images/toolbar/icon-32-unpublish.png); -} - -.icon-32-restore { - background-image: url(../images/toolbar/icon-32-revert.png); -} - -.icon-32-trash { - background-image: url(../images/toolbar/icon-32-trash.png); -} - -.icon-32-archive { - background-image: url(../images/toolbar/icon-32-archive.png); -} - -.icon-32-unarchive { - background-image: url(../images/toolbar/icon-32-unarchive.png); -} - -.icon-32-preview { - background-image: url(../images/toolbar/icon-32-preview.png); -} - -.icon-32-default { - background-image: url(../images/toolbar/icon-32-default.png); -} - -.icon-32-refresh { - background-image: url(../images/toolbar/icon-32-refresh.png); -} - -.icon-32-save-new { - background-image: url(../images/toolbar/icon-32-save-new.png); -} - -.icon-32-save-copy { - background-image: url(../images/toolbar/icon-32-save-copy.png); -} - -.icon-32-error { - background-image: url(../images/toolbar/icon-32-error.png); -} - -.icon-32-new-style { - background-image: url(../images/toolbar/icon-32-new-style.png); -} - -.icon-32-delete-style { - background-image: url(../images/toolbar/icon-32-delete-style.png); -} - -.icon-32-purge { - background-image: url(../images/toolbar/icon-32-purge.png); -} - -.icon-32-remove { - background-image: url(../images/toolbar/icon-32-remove.png); -} - -.icon-32-featured { - background-image: url(../images/toolbar/icon-32-featured.png); -} - -.icon-32-unfeatured { - background-image: url(../images/toolbar/icon-32-featured.png); - background-position: 0% 100%; -} - -.icon-32-export { - background-image: url(../images/toolbar/icon-32-export.png); -} - -.icon-32-stats { - background-image: url(../images/toolbar/icon-32-stats.png); -} - -.icon-32-print { - background-image: url(../images/toolbar/icon-32-print.png); -} - -.icon-32-batch { - background-image: url(../images/toolbar/icon-32-batch.png); -} - -.icon-32-envelope { - background-image: url(../images/toolbar/icon-32-messaging.png); -} - -.icon-32-download { - background-image: url(../images/toolbar/icon-32-export.png); -} - -.icon-32-bars { - background-image: url(../images/toolbar/icon-32-stats.png); -} - -/** - * Quick Icons - * Also knows as Header Icons - * These are used for the Quick Icons on the Control Panel - * The same classes are also assigned the Component Title - */ -.icon-48-categories { - background-image: url(../images/header/icon-48-category.png); -} - -.icon-48-category-edit { - background-image: url(../images/header/icon-48-category.png); -} - -.icon-48-category-add { - background-image: url(../images/header/icon-48-category-add.png); -} - -.icon-48-generic { - background-image: url(../images/header/icon-48-generic.png); -} - -.icon-48-banners { - background-image: url(../images/header/icon-48-banner.png); -} - -.icon-48-banners-categories { - background-image: url(../images/header/icon-48-banner-categories.png); -} - -.icon-48-banners-category-edit { - background-image: url(../images/header/icon-48-banner-categories.png); -} - -.icon-48-banners-category-add { - background-image: url(../images/header/icon-48-category-add.png); -} - -.icon-48-banners-clients { - background-image: url(../images/header/icon-48-banner-client.png); -} - -.icon-48-banners-tracks { - background-image: url(../images/header/icon-48-banner-tracks.png); -} - -.icon-48-checkin { - background-image: url(../images/header/icon-48-checkin.png); -} - -.icon-48-clear { - background-image: url(../images/header/icon-48-clear.png); -} - -.icon-48-contact { - background-image: url(../images/header/icon-48-contacts.png); -} - -.icon-48-contact-categories { - background-image: url(../images/header/icon-48-contacts-categories.png); -} - -.icon-48-contact-category-edit { - background-image: url(../images/header/icon-48-contacts-categories.png); -} - -.icon-48-contact-category-add { - background-image: url(../images/header/icon-48-category-add.png); -} - -.icon-48-purge { - background-image: url(../images/header/icon-48-purge.png); -} - -.icon-48-cpanel { - background-image: url(../images/header/icon-48-cpanel.png); -} - -.icon-48-config { - background-image: url(../images/header/icon-48-config.png); -} - -.icon-48-groups { - background-image: url(../images/header/icon-48-groups.png); -} - -.icon-48-groups-add { - background-image: url(../images/header/icon-48-groups-add.png); -} - -.icon-48-levels { - background-image: url(../images/header/icon-48-levels.png); -} - -.icon-48-levels-add { - background-image: url(../images/header/icon-48-levels-add.png); -} - -.icon-48-module { - background-image: url(../images/header/icon-48-module.png); -} - -.icon-48-menu { - background-image: url(../images/header/icon-48-menu.png); -} - -.icon-48-menu-add { - background-image: url(../images/header/icon-48-menu-add.png); -} - -.icon-48-menumgr { - background-image: url(../images/header/icon-48-menumgr.png); -} - -.icon-48-trash { - background-image: url(../images/header/icon-48-trash.png); -} - -.icon-48-user { - background-image: url(../images/header/icon-48-user.png); -} - -.icon-48-user-add { - background-image: url(../images/header/icon-48-user-add.png); -} - -.icon-48-user-edit { - background-image: url(../images/header/icon-48-user-edit.png); -} - -.icon-48-user-profile { - background-image: url(../images/header/icon-48-user-profile.png); -} - -.icon-48-inbox { - background-image: url(../images/header/icon-48-inbox.png); -} - -.icon-48-new-privatemessage { - background-image: url(../images/header/icon-48-new-privatemessage.png); -} - -.icon-48-msgconfig { - background-image: url(../images/header/icon-48-message_config.png); -} - -.icon-48-langmanager { - background-image: url(../images/header/icon-48-language.png); -} - -.icon-48-mediamanager { - background-image: url(../images/header/icon-48-media.png); -} - -.icon-48-plugin { - background-image: url(../images/header/icon-48-plugin.png); -} - -.icon-48-help_header { - background-image: url(../images/header/icon-48-help_header.png); -} - -.icon-48-impressions { - background-image: url(../images/header/icon-48-stats.png); -} - -.icon-48-browser { - background-image: url(../images/header/icon-48-stats.png); -} - -.icon-48-searchtext { - background-image: url(../images/header/icon-48-stats.png); -} - -.icon-48-thememanager { - background-image: url(../images/header/icon-48-themes.png); -} - -.icon-48-writemess { - background-image: url(../images/header/icon-48-writemess.png); -} - -.icon-48-featured { - background-image: url(../images/header/icon-48-featured.png); -} - -.icon-48-sections { - background-image: url(../images/header/icon-48-section.png); -} - -.icon-48-article-add { - background-image: url(../images/header/icon-48-article-add.png); -} - -.icon-48-article-edit { - background-image: url(../images/header/icon-48-article-edit.png); -} - -.icon-48-article { - background-image: url(../images/header/icon-48-article.png); -} - -.icon-48-content-categories { - background-image: url(../images/header/icon-48-category.png); -} - -.icon-48-content-category-edit { - background-image: url(../images/header/icon-48-category.png); -} - -.icon-48-content-category-add { - background-image: url(../images/header/icon-48-category-add.png); -} - -.icon-48-install { - background-image: url(../images/header/icon-48-extension.png); -} - -.icon-48-dbbackup { - background-image: url(../images/header/icon-48-backup.png); -} - -.icon-48-dbrestore { - background-image: url(../images/header/icon-48-dbrestore.png); -} - -.icon-48-dbquery { - background-image: url(../images/header/icon-48-query.png); -} - -.icon-48-systeminfo { - background-image: url(../images/header/icon-48-info.png); -} - -.icon-48-massmail { - background-image: url(../images/header/icon-48-massmail.png); -} - -.icon-48-redirect { - background-image: url(../images/header/icon-48-redirect.png); -} - -.icon-48-search { - background-image: url(../images/header/icon-48-search.png); -} - -.icon-48-finder { - background-image: url(../images/header/icon-48-search.png); -} - -.icon-48-newsfeeds { - background-image: url(../images/header/icon-48-newsfeeds.png); -} - -.icon-48-newsfeeds-categories { - background-image: url(../images/header/icon-48-newsfeeds-cat.png); -} - -.icon-48-newsfeeds-category-edit { - background-image: url(../images/header/icon-48-newsfeeds-cat.png); -} - -.icon-48-newsfeeds-category-add { - background-image: url(../images/header/icon-48-category-add.png); -} - -.icon-48-weblinks { - background-image: url(../images/header/icon-48-links.png); -} - -.icon-48-weblinks-categories { - background-image: url(../images/header/icon-48-links-cat.png); -} - -.icon-48-weblinks-category-edit { - background-image: url(../images/header/icon-48-links-cat.png); -} - -.icon-48-weblinks-category-add { - background-image: url(../images/header/icon-48-category-add.png); -} - -.icon-48-tags { - background-image: url(../images/header/icon-48-tags.png); -} - -.icon-48-assoc { - background-image: url(../images/header/icon-48-assoc.png); -} - -.icon-48-puzzle { - background-image: url(../images/header/icon-48-puzzle.png); -} - -/** - * General styles - */ -div.message { - border: 1px solid @mainBorder; - color: @textColor; -} - -.helpFrame { - border-left: 0 solid @mainBorder; - border-right: none; - border-top: none; - border-bottom: none; -} - -.outline { - border: 1px solid @mainBorder; - background: @bodyBackground; -} - -/** - * Modal Styles - */ -dl.menu_type dt { - border-bottom: 1px solid @mainBorder; -} - -ul#new-modules-list { - border-top: 1px solid @mainBorder; -} - -/** - * User Accessibility - */ - -/* Skip to Content Visual Styling */ -#skiplinkholder a, #skiplinkholder a:link, #skiplinkholder a:visited { - color: @bodyBackground; - background: @linkColor; - border-bottom: solid #336 2px; -} - -/** - * Admin Form Styles - */ -fieldset.panelform { - border: none 0; -} - -/** - * ACL STYLES relocated from com_users/media/grid.css - */ -a.move_up { - background-image: url('../images/admin/uparrow.png'); -} - -span.move_up { - background-image: url('../images/admin/uparrow0.png'); -} - -a.move_down { - background-image: url('../images/admin/downarrow.png'); -} - -span.move_down { - background-image: url('../images/admin/downarrow0.png'); -} - -a.grid_false { - background-image: url('../images/admin/publish_x.png'); -} - -a.grid_true { - background-image: url('../images/admin/tick.png'); -} - -a.grid_trash { - background-image: url('../images/admin/icon-16-trash.png'); -} - -/** - * ACL PANEL STYLES - */ - -/* All Tabs */ - -tr.row1 { - background-color: @altBackground; -} - -/* Summary Tab */ -table.aclsummary-table td.col2, -table.aclsummary-table th.col2, -table.aclsummary-table td.col3, -table.aclsummary-table th.col3, -table.aclsummary-table td.col4, -table.aclsummary-table th.col4, -table.aclsummary-table td.col5, -table.aclsummary-table th.col5, -table.aclsummary-table td.col6, -table.aclsummary-table th.col6, -table.aclmodify-table td.col2, -table.aclmodify-table th.col2 { - border-left: 1px solid @mainBorder; -} - -/* Icons */ - -span.icon-16-unset { - background: url(../images/admin/icon-16-denyinactive.png) no-repeat; -} - -span.icon-16-allowed { - background: url(../images/admin/icon-16-allow.png) no-repeat; -} - -span.icon-16-denied { - background: url(../images/admin/icon-16-deny.png) no-repeat; -} - -span.icon-16-locked { - background: url(../images/admin/checked_out.png) 0 0 no-repeat; -} - -label.icon-16-allow { - background: url(../images/admin/icon-16-allow.png) no-repeat; -} - -label.icon-16-deny { - background: url(../images/admin/icon-16-deny.png) no-repeat; -} - -a.icon-16-allow { - background: url(../images/admin/icon-16-allow.png) no-repeat; -} - -a.icon-16-deny { - background: url(../images/admin/icon-16-deny.png) no-repeat; -} - -a.icon-16-allowinactive { - background: url(../images/admin/icon-16-allowinactive.png) no-repeat; -} - -a.icon-16-denyinactive { - background: url(../images/admin/icon-16-denyinactive.png) no-repeat; -} - -/* ACL footer/legend */ - -ul.acllegend li.acl-allowed { - background: url(../images/admin/icon-16-allow.png) no-repeat left; -} - -ul.acllegend li.acl-denied { - background: url(../images/admin/icon-16-deny.png) no-repeat left; -} - -li.acl-editgroups, -li.acl-resetbtn { - background-color: @altBackground; - border: 1px solid @mainBorder; -} - -li.acl-editgroups a, -li.acl-resetbtn a { - color: @linkColor; -} - -li.acl-editgroups:hover, -li.acl-resetbtn:hover, -li.acl-editgroups:focus, -li.acl-resetbtn:focus { - background-color: @hoverBackground; -} - -/* ACL Config --------- */ -table#acl-config { - border: 1px solid @mainBorder; -} - -table#acl-config th, -table#acl-config td { - background: @altBackground; - border-bottom: 1px solid @mainBorder; -} - -table#acl-config th.acl-groups { - border-right: 1px solid @mainBorder; -} - -/** -* Mod_rewrite Warning -*/ -#jform_sef_rewrite-lbl { - background: url(../images/admin/icon-16-notice-note.png) right top no-repeat; -} - -/** -* Permission Rules -*/ - -#permissions-sliders .tip { - background: @bodyBackground; - border: 1px solid @mainBorder; -} - -#permissions-sliders ul#rules, -#permissions-sliders ul#rules ul { - border: solid 0 @mainBorder; - background: @bodyBackground; -} - -ul#rules li .pane-sliders .panel h3.title { - border: solid 0 @mainBorder; -} - -#permissions-sliders ul#rules .pane-slider { - border: solid 1px @mainBorder; -} - -#permissions-sliders ul#rules li h3 { - border: solid 1px @mainBorder; -} - -#permissions-sliders ul#rules li h3.pane-toggler-down a { - border: solid 0; -} - -#permissions-sliders ul#rules .group-kind { - color: @textColor; -} - -#permissions-sliders ul#rules table.group-rules { - border: solid 1px @mainBorder; -} - -#permissions-sliders ul#rules table.group-rules td { - border-right: solid 1px @mainBorder; - border-bottom: solid 1px @mainBorder; -} - -#permissions-sliders ul#rules table.group-rules th { - background: @hoverBackground; - border-right: solid 1px @mainBorder; - border-bottom: solid 1px @mainBorder; - color: @textColor; -} - -ul#rules table.aclmodify-table { - border: solid 1px @mainBorder; -} - -ul#rules table.group-rules td label { - border: solid 0 @mainBorder; -} - -#permissions-sliders ul#rules .mypanel { - border: solid 0 @mainBorder; -} - -#permissions-sliders ul#rules table.group-rules td { - background: @bodyBackground; -} - -#permissions-sliders span.level { - color: @mainBorder; - background-image: none; -} - -/* - * Debug styles - */ -.check-0, -table.adminlist tbody td.check-0 { - background-color: @permissionDefault; -} - -.check-a, -table.adminlist tbody td.check-a { - background-color: @permissionAllowed; -} - -.check-d, -table.adminlist tbody td.check-d { - background-color: @permissionDenied; -} - -/** - * System Messages - */ - -#system-message dd ul { - color: @textColor; -} - -#system-message dd.error ul { - color: @textColor; -} - -#system-message dd.message ul { - color: @textColor; -} - -#system-message dd.notice ul { - color: @textColor; -} - -/** CSS file for Accessible Admin Menu - * based on Matt Carrolls' son of suckerfish - * with javascript by Bill Tomczak - */ - -/* Note: set up the font-size on the id and used 100% on the elements. - If ul/li/a are different ems, then the shifting back via non-js keyboard - doesn't work properly */ - -/** - * Menu Styling - */ -#menu { -/* this is on the main ul */ - color: @textColor; -} - -#menu ul.dropdown-menu { -/* all lists */ - #gradient > .vertical(@gradientTop, @gradientBottom); - color: @textColor; -} - -#menu ul.dropdown-menu li.dropdown-submenu { - background: url(../images/j_arrow.png) no-repeat right 50%; -} - -#menu ul.dropdown-menu li.divider { - margin-bottom: 0; - border-bottom: 1px dotted @mainBorder; -} - -#menu a { - color: @toolbarColor; - background-repeat: no-repeat; - background-position: left 50%; -} - -#menu li { -/* all list items */ - border-right: 1px solid @mainBorder; - background-color: transparent; -} - -#menu li a:hover, #menu li a:focus { - background-color: @hoverBackground; -} - -#menu li.disabled a:hover, -#menu li.disabled a:focus, -#menu li.disabled a { - color: @mainBorder; - #gradient > .vertical(@gradientTop, @gradientBottom); -} - -#menu li ul { -/* second-level lists */ - border: 1px solid @mainBorder; -} - -#menu li li { -/* second-level row */ - background-color: transparent; -} - -/** - * Styling parents - */ - -/* 1 level - sfhover */ -#menu li.sfhover a { - background-color: @hoverBackground; -} - -/* 2 level - normal */ -#menu li.sfhover li a { - background-color: transparent; -} - -/* 2 level - hover */ -#menu li.sfhover li.sfhover a, #menu li li a:focus { - background-color: @hoverBackground; -} - -/* 3 level - normal */ -#menu li.sfhover li.sfhover li a { - background-color: transparent; -} - -/* 3 level - hover */ -#menu li.sfhover li.sfhover li.sfhover a, #menu li li li a:focus { - background-color: @hoverBackground; -} - -/* bring back the focus elements into view */ -#menu li li a:focus, #menu li li li a:focus { - background-color: @hoverBackground; -} - -#menu li li li a:focus { - background-color: @hoverBackground; -} - -/** - * Submenu styling - */ -#submenu { - border-bottom: 1px solid @mainBorder; -/* border-bottom plus padding-bottom is the technique */ -/* This is the background befind the tabs */ -/*background: @bodyBackground;*/ -} - -#submenu li, #submenu span.nolink { - #gradient > .vertical(@gradientTop, @gradientBottom); - border: 1px solid @mainBorder; - color: @linkColor; -} - -#submenu li:hover, #submenu li:focus { - background: @hoverBackground; -} - -#submenu li.active, #submenu span.nolink.active { - background: @bodyBackground; - border-bottom: 1px solid @bodyBackground; -} - -#submenu li.active a, -#submenu span.nolink.active { - color: #000; -} - -.element-invisible { - margin: 0; - padding: 0; -} - -/* -- Codemirror Editor ----------- */ -div.CodeMirror-wrapping { - border: 1px solid @mainBorder; -} - -/* User Notes */ -table.adminform tr.row0 { - background-color: @bodyBackground; -} - -ul.alternating > li:nth-child(odd) { - background-color: @bodyBackground; -} - -ul.alternating > li:nth-child(even) { - background-color: @altBackground; -} - -ol.alternating > li:nth-child(odd) { - background-color: @bodyBackground; -} - -ol.alternating > li:nth-child(even) { - background-color: @altBackground; -} - -/* Installer Database */ -#installer-database, #installer-discover, #installer-update, #installer-warnings { - border-top: 1px solid @mainBorder; -} - -#installer-database p.warning { - background: transparent url(../images/admin/icon-16-deny.png) center left no-repeat; -} - -#installer-database p.nowarning { - background: transparent url(../images/admin/icon-16-allow.png) center left no-repeat; -} - -/* Override default bootstrap font-size */ -.input-append, -.input-prepend { - font-size: 1.2em; -} diff --git a/administrator/templates/hathor/less/colour_blue.less b/administrator/templates/hathor/less/colour_blue.less deleted file mode 100644 index 2fca62c9e3721..0000000000000 --- a/administrator/templates/hathor/less/colour_blue.less +++ /dev/null @@ -1,38 +0,0 @@ -// colour_blue.less -// -// Less to compile Hathor in the blue colour scheme -// ----------------------------------------------------- - -/** - * #2c2c2c Text - * #054993 Links - * #ffffff Background, border, text - * #c3d2e5 Background alternate, button/icon/menu background - * #a5bbd4-c3d2e5 Gradient Background - * #e5f0fa Background (input required) - * #e5d9c3 Background Hover, Top/Left icon borders - * #738498 Main borders - * #868778 Top/Left hover borders - * #f6f7db Right/Bottom hover borders - * - * Special Use Colors: - * #a20000 Text Error, border invalid - * #cccccc Text (faded) - * #005800 Text (success) - * #eeeeee Background (input disabled) - * #ffffcf Background permissions debug - * #cfffda Background permissions debug - * #ffcfcf Background permissions debug - */ - -// Import the variables file first to get common variables loaded -@import "hathor_variables.less"; - -// Define variables unique to this colour scheme, as well as override variables already defined in the common file -@altBackground: #c3d2e5; -@gradientTop: #a5bbd4; -@gradientBottom: #c3d2e5; -@mainBorder: #738498; - -// Import the baseline to compile the CSS -@import "colour_baseline.less"; diff --git a/administrator/templates/hathor/less/colour_brown.less b/administrator/templates/hathor/less/colour_brown.less deleted file mode 100644 index ffa966561bf37..0000000000000 --- a/administrator/templates/hathor/less/colour_brown.less +++ /dev/null @@ -1,42 +0,0 @@ -// colour_brown.less -// -// Less to compile Hathor in the brown colour scheme -// ----------------------------------------------------- - -/** - * #2c2c2c Text - * #054993 Links - * #ffffff Background, border, text - * #d5c1b2 Background alternate, button/icon/menu background - * #d5c1b2-d5c1b2 Gradient Background - * #e5f0fa Background (input required) - * #e1d3c8 Background Hover, Top/Left icon borders - * #000000 Main borders - * #000000 Top/Left hover borders - * #000000 Right/Bottom hover borders - * - * Special Use Colors: - * #a20000 Text Error, border invalid - * #cccccc Text (faded) - * #005800 Text (success) - * #eeeeee Background (input disabled) - * #ffffcf Background permissions debug - * #cfffda Background permissions debug - * #ffcfcf Background permissions debug - */ - -// Import the variables file first to get common variables loaded -@import "hathor_variables.less"; - -// Define variables unique to this colour scheme, as well as override variables already defined in the common file -@altBackground: #d5c1b2; -@gradientTop: #d5c1b2; -@gradientBottom: #d5c1b2; -@mainBorder: #000000; -@toolbarColor: #054993; -@hoverBackground: #e5d9c3; -@nwBorder: #868778; -@seBorder: #f6f7db; - -// Import the baseline to compile the CSS -@import "colour_baseline.less"; diff --git a/administrator/templates/hathor/less/colour_standard.less b/administrator/templates/hathor/less/colour_standard.less deleted file mode 100644 index b7de935bd8987..0000000000000 --- a/administrator/templates/hathor/less/colour_standard.less +++ /dev/null @@ -1,38 +0,0 @@ -// colour_standard.less -// -// Less to compile Hathor in the default colour scheme -// ----------------------------------------------------- - -/** - * Main colors: - * #2c2c2c Text - * #054993 Links - * #ffffff Background, border, text - * #f9fade Background alternate, button/icon/menu background - * #e5f0fa Background (input required) - * #e3e4ca Background Hover, Right/Bottom icon borders - * #c7c8b2 Main borders - * #868778 Top/Left icon hover borders - * #f6f7db Right/Bottom icon hover borders - * - * Special Use Colors: - * #a20000 Text Error, border invalid - * #cccccc Text (faded) - * #005800 Text (success) - * #eeeeee Background (input disabled) - * #ffffcf Background‚ permissions debug - * #cfffda Background‚ permissions debug - * #ffcfcf Background‚ permissions debug - */ - -// Import the variables file first to get common variables loaded -@import "hathor_variables.less"; - -// Define variables unique to this colour scheme, as well as override variables already defined in the common file -@altBackground: #f9fade; -@gradientTop: #f9fade; -@gradientBottom: #f9fade; -@mainBorder: #c7c8b2; - -// Import the baseline to compile the CSS -@import "colour_baseline.less"; diff --git a/administrator/templates/hathor/less/forms.less b/administrator/templates/hathor/less/forms.less deleted file mode 100644 index bf43faa937dc7..0000000000000 --- a/administrator/templates/hathor/less/forms.less +++ /dev/null @@ -1,196 +0,0 @@ -// -// Forms -// This is a custom version of Bootstrap's forms.less file suited for Hathor's needs -// -------------------------------------------------- - -// Ensure input-prepend/append never wraps -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} -// Allow us to put symbols and text within the input field for a cleaner look -.input-append, -.input-prepend { - margin-bottom: 5px; - font-size: 0; - white-space: nowrap; // Prevent span and input from separating - - input, - select, - .uneditable-input { - position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness - margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms - *margin-left: 0; - font-size: @baseFontSize; - vertical-align: top; - .border-radius(0 @inputBorderRadius @inputBorderRadius 0); - // Make input on top when focused so blue border and shadow always show - &:focus { - z-index: 2; - } - } - .add-on { - display: inline-block; - width: auto; - height: @baseLineHeight; - min-width: 16px; - padding: 4px 5px; - font-size: @baseFontSize; - font-weight: normal; - line-height: @baseLineHeight; - text-align: center; - text-shadow: 0 1px 0 @white; - background-color: @grayLighter; - border: 1px solid #ccc; - } - .add-on, - .btn { - margin-left: -1px; - vertical-align: top; - .border-radius(0); - } - .active { - background-color: lighten(@green, 30); - border-color: @green; - } -} -.input-prepend { - .add-on, - .btn { - margin-right: -1px; - } - .add-on:first-child, - .btn:first-child { - .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); - } -} -.input-append { - input, - select, - .uneditable-input { - .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); - } - .add-on:last-child, - .btn:last-child { - .border-radius(0 @inputBorderRadius @inputBorderRadius 0); - } -} -// Remove all border-radius for inputs with both prepend and append -.input-prepend.input-append { - input, - select, - .uneditable-input { - .border-radius(0); - } - .add-on:first-child, - .btn:first-child { - margin-right: -1px; - .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); - } - .add-on:last-child, - .btn:last-child { - margin-left: -1px; - .border-radius(0 @inputBorderRadius @inputBorderRadius 0); - } -} -/* Allow for input prepend/append in search forms */ -.form-search .input-append .search-query, -.form-search .input-prepend .search-query { - .border-radius(0); // Override due to specificity -} -.form-search .input-append .search-query { - .border-radius(14px 0 0 14px) -} -.form-search .input-append .btn { - .border-radius(0 14px 14px 0) -} -.form-search .input-prepend .search-query { - .border-radius(0 14px 14px 0) -} -.form-search .input-prepend .btn { - .border-radius(14px 0 0 14px) -} -.form-search, -.form-inline, -.form-horizontal { - input, - textarea, - select, - .help-inline, - .uneditable-input, - .input-prepend, - .input-append { - display: inline-block; - .ie7-inline-block(); - margin-bottom: 0; - vertical-align: middle; - } - // Re-hide hidden elements due to specifity - .hide { - display: none; - } -} -// Remove margin for input-prepend/-append -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} -/* Accessible Hidden Elements (good for hidden labels and such) */ -.element-invisible{ - position: absolute; - padding: 0 !important; - margin: 0 !important; - border: 0; - height: 1px; - width: 1px !important; - overflow: hidden; -} - -// Login form only -// Shared size and type resets -#form-login select, -#form-login input[type="text"], -#form-login input[type="password"] { - display: inline-block; - padding: 4px 6px; - margin-bottom: 9px; - font-size: @baseFontSize; - line-height: @baseLineHeight; - color: @gray; - .border-radius(@inputBorderRadius); - width: 175px; -} - -/* Field subform repeatable */ -.subform-repeatable-wrapper{ - - div.btn-toolbar{ - float: none; - } - - .text-right{ - text-align: right; - } - - .ui-sortable-helper{ - background: @white; - } - - tr.ui-sortable-helper{ - display: table; - } - - .subform-repeatable-group{ - clear: both; - } -} diff --git a/administrator/templates/hathor/less/hathor_variables.less b/administrator/templates/hathor/less/hathor_variables.less deleted file mode 100644 index 36bf2f542789b..0000000000000 --- a/administrator/templates/hathor/less/hathor_variables.less +++ /dev/null @@ -1,140 +0,0 @@ -// hathor_variables.less -// -// Less file containing Bootstrap variables needed to compile its CSS -// ----------------------------------------------------- - -// Grays -// ------------------------- -@black: #000000; -@grayDarker: #222222; -@grayDark: #333333; -@gray: #555555; -@grayLight: #999999; -@grayLighter: #eeeeee; -@white: #ffffff; - -// Accent colors -// ------------------------- -@blue: #049cdb; -@blueDark: #0064cd; -@green: #46a546; -@red: #9d261d; -@yellow: #ffc40d; -@orange: #f89406; -@pink: #c3325f; -@purple: #7a43b6; - -// Scaffolding -// ------------------------- -@bodyBackground: @white; -@textColor: #2c2c2c; - -// Links -// ------------------------- -@linkColor: #054993; -@linkColorHover: darken(@linkColor, 15%); - -// Typography -// ------------------------- -@baseFontSize: 13px; -@baseLineHeight: 15px; - -@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily -@headingsFontWeight: bold; // instead of browser default, bold -@headingsColor: inherit; // empty to use BS default, @textColor - -// Component sizing -// ------------------------- -@baseBorderRadius: 4px; -@borderRadiusLarge: 6px; -@borderRadiusSmall: 3px; - -// Buttons -// ------------------------- -@btnBackground: @white; -@btnBackgroundHighlight: darken(@white, 10%); -@btnBorder: #bbb; - -@btnPrimaryBackground: @linkColor; -@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 20%); - -@btnInfoBackground: #5bc0de; -@btnInfoBackgroundHighlight: #2f96b4; - -@btnSuccessBackground: #62c462; -@btnSuccessBackgroundHighlight: #51a351; - -@btnWarningBackground: lighten(@orange, 15%); -@btnWarningBackgroundHighlight: @orange; - -@btnDangerBackground: #ee5f5b; -@btnDangerBackgroundHighlight: #bd362f; - -@btnInverseBackground: #444; -@btnInverseBackgroundHighlight: @grayDarker; - -// Forms -// ------------------------- -@inputBackground: #e5f0fa; -@inputBorder: #ccc; -@inputBorderRadius: 3px; -@inputDisabledBackground: @grayLighter; -@formActionsBackground: #f5f5f5; -@inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -@zindexDropdown: 1000; -@zindexTooltip: 1030; -@zindexFixedNavbar: 1030; -@zindexModalBackdrop: 1040; -@zindexModal: 1050; -@zindexPopover: 1060; - -// Form states and alerts -// ------------------------- -@warningText: #c09853; -@warningBackground: #fcf8e3; -@warningBorder: darken(spin(@warningBackground, -10), 3%); - -@errorText: #a20000; -@errorBackground: #f2dede; -@errorBorder: darken(spin(@errorBackground, -10), 3%); - -@successText: #005800; -@successBackground: #dff0d8; -@successBorder: darken(spin(@successBackground, -10), 5%); - -@infoText: #3a87ad; -@infoBackground: #d9edf7; -@infoBorder: darken(spin(@infoBackground, -10), 7%); - -// Tooltips and popovers -// ------------------------- -@tooltipColor: @white; -@tooltipBackground: @black; -@tooltipArrowWidth: 5px; -@tooltipArrowColor: @tooltipBackground; - -@popoverBackground: @white; -@popoverArrowWidth: 10px; -@popoverArrowColor: @white; -@popoverTitleBackground: darken(@popoverBackground, 3%); - -// Special enhancement for popovers -@popoverArrowOuterWidth: @popoverArrowWidth + 1; -@popoverArrowOuterColor: rgba(0,0,0,.25); - -// Variables unique to Hathor -// ------------------------- -@toolbarColor: @linkColor; -@hoverBackground: #e5d9c3; -@nwBorder: #868778; -@seBorder: #f6f7db; -@fadedText: #cccccc; -@disabledBackground: #eeeeee; -@permissionDefault: #ffffcf; -@permissionAllowed: #cfffda; -@permissionDenied: #ffcfcf; diff --git a/administrator/templates/hathor/less/icomoon.less b/administrator/templates/hathor/less/icomoon.less deleted file mode 100644 index f2e9c3a592c3a..0000000000000 --- a/administrator/templates/hathor/less/icomoon.less +++ /dev/null @@ -1,11 +0,0 @@ -@font-face { - font-family: 'IcoMoon'; - src: url('../../../../media/jui/fonts/IcoMoon.eot'); - src: url('../../../../media/jui/fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), - url('../../../../media/jui/fonts/IcoMoon.woff') format('woff'), - url('../../../../media/jui/fonts/IcoMoon.ttf') format('truetype'), - url('../../../../media/jui/fonts/IcoMoon.svg#IcoMoon') format('svg'); - font-weight: normal; - font-style: normal; -} -@import "../../../../media/jui/less/icomoon.less"; diff --git a/administrator/templates/hathor/less/modals.less b/administrator/templates/hathor/less/modals.less deleted file mode 100644 index 64f84116f42f4..0000000000000 --- a/administrator/templates/hathor/less/modals.less +++ /dev/null @@ -1,108 +0,0 @@ -// MODALS -// ------ - -// Recalculate z-index where appropriate -.modal-open { - .dropdown-menu { z-index: @zindexDropdown + @zindexModal; } - .dropdown.open { *z-index: @zindexDropdown + @zindexModal; } - .popover { z-index: @zindexPopover + @zindexModal; } - .tooltip { z-index: @zindexTooltip + @zindexModal; } -} - -// Background -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: @zindexModalBackdrop; - background-color: @black; - // Fade for backdrop - &.fade { opacity: 0; } -} - -.modal-backdrop, -.modal-backdrop.fade.in { - .opacity(80); -} - -// Base modal -div.modal { - position: fixed; - top: 50%; - left: 50%; - z-index: @zindexModal; - overflow: auto; - width: 80%; - margin: -250px 0 0 -40%; - background-color: @white; - border: 1px solid #999; - border: 1px solid rgba(0,0,0,.3); - *border: 1px solid #999; /* IE6-7 */ - .border-radius(6px); - .box-shadow(0 3px 7px rgba(0,0,0,0.3)); - .background-clip(padding-box); - &.fade { - .transition(e('opacity .3s linear, top .3s ease-out')); - top: -25%; - } - &.fade.in { top: 50%; } -} -.modal-header { - padding: 9px 15px; - border-bottom: 1px solid #eee; - // Close icon - .close { - float: right; - margin-top: 2px; - } -} - -// Body (where all modal content resides) -.modal-body { - overflow-y: auto; - max-height: 400px; - padding: 15px; -} -// Remove bottom margin if need be -.modal-form { - margin-bottom: 0; -} - -// Footer (for actions) -.modal-footer { - padding: 14px 15px 15px; - margin-bottom: 0; - text-align: right; // right align buttons - background-color: #f5f5f5; - border-top: 1px solid #ddd; - .border-radius(0 0 6px 6px); - .box-shadow(inset 0 1px 0 @white); - .clearfix(); // clear it in case folks use .pull-* classes on buttons - - // Properly space out buttons - .btn + .btn { - margin-left: 5px; - margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs - } - // but override that for button groups - .btn-group .btn + .btn { - margin-left: -1px; - } -} - -/* Prevent scrolling on the parent window of a modal */ -body.modal-open { - overflow: hidden; - -ms-overflow-style: none; -} - -/* Buttons bar in modal iframe */ -.modal-buttons { - padding: 15px 0px; -} -.modal-buttons button { - font-size: 1.2em; - line-height: 1.6em; -} diff --git a/administrator/templates/hathor/less/template.less b/administrator/templates/hathor/less/template.less deleted file mode 100644 index 4c5710afc9723..0000000000000 --- a/administrator/templates/hathor/less/template.less +++ /dev/null @@ -1,3565 +0,0 @@ -// Import the variables file first to get common variables loaded -@import "hathor_variables.less"; - -// Core variables and mixins -@import "../../../../media/jui/less/mixins.less"; - -// Bootstrap Component Animations -@import "../../../../media/jui/less/component-animations.less"; - -// Bootstrap Modals -@import "modals.less"; -//@import "../../../../media/jui/less/modals.joomla.less"; - -// Bootstrap Popovers -@import "../../../../media/jui/less/popovers.less"; - -// Icon Font -@import "icomoon.less"; - -/** - * CSS Reset - */ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, font, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - background: transparent; -} - -blockquote, q { - quotes: none; -} - -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} - -del { - text-decoration: line-through; -} - -/** - * General styles - */ -html { - overflow-y: scroll; - height: 100%; -} - -body { - margin: 0; - padding: 0; - font-size: 62.5%; - line-height: 1.5em; - height: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -body, td, th, span, a { - font-family: Arial, Helvetica, sans-serif; -} - -html, body { - height: 100%; -} - -a, img { - padding: 0; - margin: 0; -} - -img { - border: 0 none; -} - -form { - margin: 0; - padding: 0; -} - -ul { - padding: 0; - margin: 0; -} - -h1 { - margin: 0; - padding-bottom: 8px; - font-size: 1.4em; - font-weight: bold; - line-height: 2em; -} - -h2 { - padding-top: .83em; - padding-bottom: .83em; -} - -h3 { - font-size: 1.4em; -} - -a:link { - color: #054993; - text-decoration: none; -} - -a:visited { - color: #054993; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -a:focus { - text-decoration: underline; -} - -iframe { - border: 0; -} - -/* new styles */ - -.enabled { - color: #005800; - font-weight: bold; -} - -.disabled { - color: #a20000; - font-weight: bold; -} - -p.error { - color: #a20000; - font-weight: bold; -} - -.warning { - color: #a20000; - font-weight: bold; -} - -.nowarning { - color: #2c2c2c; - font-weight: bold; -} - -.success { - color: #005800; - font-weight: bold; -} - -.allow { - color: #005800; -} - -span.writable { - color: #005800; -} - -.deny { - color: #a20000; -} - -span.unwritable { - color: #a20000; -} - -.none { - color: #aaaaaa; -} - -.pointer { - cursor: pointer; -} - -.nowrap { - white-space: nowrap; -} - -p.nowarning, p.warning { - margin: 10px; -} - -/* end new styles */ - -/** - * Overall Styles - */ -#minwidth, #minwidth-body { - min-width: 980px; -} - -#containerwrap { - position: relative; -} - -#header { - position: relative; -} - -#header h1.title { - font-size: 1.5em; - font-weight: normal; - line-height: 25px; - margin: 0; - padding: 0 0 0 120px; -} - -#footer { - padding: 10px 20px; -} - -#footer .copyright { - margin: 0 0 0 0; - text-align: center; -} - -#footer p { - font-size: 1.2em; -} - -#nav .no-nav { - line-height: 2em; -} - -#content { - margin: 5px 20px 20px 20px; -} - -.cpanel-page div#element-box { - padding: 15px; -} - -/** - * Status layout - */ -#module-status { - float: right; - position: relative; - top: -48px; -} - -#module-status div.btn-group { - display: block; - float: left; - padding: 4px 10px 0 10px; - font-size: 1.2em; -} - -#module-status div.divider { - display: none; -} - -#module-status .unread-messages a { - font-weight: bold; -} - -.title-ua { - position: relative; - width: 60%; -} - -/** - * Various Styles - */ -.enabled, -.disabled, -p.error, -.warning, -.nowarning, -.success { - font-weight: bold; -} - -.pointer { - cursor: pointer; -} - -.nowrap { - white-space: nowrap; -} - -span.note { - display: block; - padding: 5px; -} - -div.checkin-tick { - text-indent: -9999px; -} - -/** - * Overlib - */ -.ol-textfont { - font-family: Arial, Helvetica, sans-serif; - font-size: 1.2em; -} - -.ol-captionfont { - font-family: Arial, Helvetica, sans-serif; - font-size: 1.2em; - font-weight: bold; -} - -.ol-captionfont a { - text-decoration: none; -} - -/** - * Subheader, toolbar, page title - */ -div.subheader .padding { - padding: 0; -} - -div.pagetitle { - padding: 0 0 5px 5px; - margin: 0; - background-repeat: no-repeat; - background-position: left 50%; - line-height: 54px; - width: 100%; - margin-top: -20px; - height: 60px; -} - -.tabs-left > .nav-tabs { - float: left; - margin-right: 19px; - border-right: 1px solid #DDD; -} - -tabs-below > .nav-tabs, .tabs-right > .nav-tabs, .tabs-left > .nav-tabs { - border-bottom: 0; -} - -/* Tabbed Content */ -.tab-content { - overflow: visible; -} - -.tabs-left .tab-content { - overflow: auto; -} - -/* Non-linkable nav-tabs */ -.nav-tabs > li > span { - display: block; - margin-right: 2px; - padding-right: 12px; - padding-left: 12px; - padding-top: 8px; - padding-bottom: 8px; - line-height: 18px; - border: 1px solid transparent; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} - -/* Extended Joomla Button Classes */ -.btn-micro { - padding: 1px 4px; - font-size: 10px; - line-height: 8px; -} - -/* Joomla => Bootstrap Tooltip */ -.tip-wrap { - max-width: 200px; - padding: 3px 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - z-index: 100; -} - -.pagetitle h2 { - padding: 0 0 0 50px; - font-size: 1.3em; - font-weight: bold; - line-height: 48px; - font-style: italic; -} - -div.configuration { - font-size: 1.2em; - font-weight: bold; - line-height: 2em; - padding-left: 30px; - margin-left: 10px; -} - -div.toolbar-box h3 { - height: 0; - overflow: hidden; - position: absolute; - padding: 0; - margin: 0; -} - -.btn-toolbar { - margin-bottom: 3px; - margin-top: 14px; -} - -div.btn-toolbar, div.toolbar-list { - float: left; - text-align: left; - padding: 0; -} - -div.toolbar-list li { - padding: 5px 1px 5px 4px; - text-align: center; - height: 52px; - list-style: none; - float: left; -} - -div.toolbar-list li.spacer { - width: 10px; -} - -div.toolbar-list li.divider { - width: 10px; - margin-right: 10px; -} - -div.toolbar-list span { - float: none; - width: 32px; - height: 32px; - margin: 0 auto; - display: block; -} - -div.toolbar-list a { - display: block; - float: left; - white-space: nowrap; - padding: 1px 5px; - cursor: pointer; - font-weight: bold; -} - -div.btn-toolbar div.btn-group button { - display: block; - float: left; - white-space: nowrap; - padding: 1px 5px; - cursor: pointer; - text-align: center; -} - -div.btn-toolbar button:hover, div.btn-toolbar button:focus, div.toolbar-list a:hover, div.toolbar-list a:focus { - text-decoration: none; -} - -/** - * Massmail component - */ -td#mm_pane { - width: 90%; -} - -input#mm_subject { - width: 200px; -} - -textarea#mm_message { - width: 100%; -} -textarea { - resize:both; -} -textarea.vert { - resize:vertical; -} -textarea.noResize { - resize:none; -} - -/** - * Pane Slider pane Toggler styles - */ -.pane-sliders { - margin: 0; - position: relative; -} - -.pane-sliders .title { - margin: 0; - padding: 2px; - cursor: pointer; -} - -.pane-sliders .panel { - margin-bottom: 3px; -} - -.pane-sliders .adminlist td { - border: 0 none; -} - -h3.pane-toggler-down a:focus, -h3.pane-toggler a:focus { - outline: none; -} - -.pane-toggler span { - padding-left: 20px; -} - -.pane-toggler-down span { - padding-left: 20px; -} - -/* The following line hides the unseen panel (prevents the mouse from activating in IE, so overridden in the ie css files) */ -/*.pane-toggler + div.pane-slider {display: none;}*/ -.pane-slider.pane-hide { - display: none; -} - -div#position-icon.pane-sliders div.pane-down div.quickicon-wrapper { - margin: 5px 0 5px 0; -} - -div#position-icon.pane-sliders div.pane-down .quickicon-wrapper .icon { - padding: 5px 0 5px 10px; - margin: 0; -} - -/** - * Tabs - */ -dl.tabs { - float: left; - margin: 10px 0 -1px 0; - z-index: 50; -} - -dl.tabs dt { - float: left; - padding: 4px 10px; - margin-left: 3px; -} - -dl.tabs dt.open { - z-index: 100; -} - -div.current { - clear: both; - padding: 10px 10px; -} - -div.current dd { - padding: 0; - margin: 0; -} - -/* New parameter styles */ - -dl#content-pane.tabs { - margin: 1px 0 0 0; -} - -div.current label, div.current span.faux-label { - display: block; - min-width: 150px; - float: left; - clear: left; - margin-top: 8px; -} - -div.current fieldset.radio { - float: left; -} - -div.current fieldset.radio input { - clear: none; - min-width: 15px; - float: left; - margin: 3px 0 0 2px; -} - -div.current fieldset.radio label { - clear: none; - min-width: 45px; - float: left; - margin: 3px 0 0 2px; -} - -div.current fieldset.checkboxes { - float: left; - clear: right; -} - -div.current fieldset.checkboxes input { - clear: left; - min-width: 15px; - float: left; - margin: 3px 0 0 2px; -} - -div.current fieldset.checkboxes label { - clear: right; - min-width: 45px; - margin: 3px 0 0 2px; -} - -div.current input, -div.current span.faux-input, -div.current textarea, -div.current select { - clear: none; - float: left; - margin: 3px 0 0 2px; -} - -div.current select { - margin-bottom: 15px; -} - -div.current table#acl-config th.acl-groups { - text-align: left; -} - -div.current table#filter-config th.acl-groups { - text-align: left; -} - -div.current table#filter-config select { - margin-bottom: 0; -} - -/* -------- Menu Assigments ---------- */ -div#menu-assignment { - clear: left; -} - -div#menu-assignment ul.menu-links { - float: left; - width: 49%; -} - -div#menu-assignment ul.menu-links label { - clear: none; - float: left; - margin: 3px 0 0 2px; -} - -div#menu-assignment ul.menu-links input { - clear: left; - float: left; -} - -button.jform-rightbtn { - float: right; - margin-right: 0; -} - -p.tab-description { - font-size: 1.091em; - margin-left: 0; - margin-top: 5px; -} - -/* end new parameter styles */ - -/** - * Login Settings - */ -#login-page input, #login-page select { - float: right; - clear: none; -} - -#login-page .login { - margin: 0 auto; - width: 575px; - margin-bottom: 100px; -} - -#login-page .pagetitle h2 { - margin: -70px 0 30px 0; - font-size: 2em; - padding: 0; -} - -#login-page p { - margin: 0; - padding: 0; - margin-bottom: 1em; - font-size: 1.2em; -} - -#login-page #header { - margin-bottom: 100px; -} - -#login-page .login-inst { - float: left; - width: 35%; -} - -#login-page .login-box { - float: right; - width: 63%; -} - -#login-page #lock { - width: 150px; - height: 137px; -} - -#login-page #element-box.login { - padding: 20px; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} - -#login-page .button { - text-align: right; -} - -#login-page .login-text { - text-align: left; - width: 40%; - float: left; -} - -#form-login { - float: left; - padding: 1.1em; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} - -#form-login fieldset { - border: none; -} - -#form-login label { - display: block; - float: left; - clear: left; - width: 100px; - text-align: right; - padding: 4px; - color: #2c2c2c; - font-weight: bold; - font-size: 1.4em; - margin-bottom: 15px; -} - -#form-login div.button1 div.next { - float: left; -} - -#form-login div.button1 a { - height: 2.2em; - line-height: 2.2em; - font-size: 1.5em; - cursor: default; - padding: 0 15px 0 15px; -} - -.login-submit { - border: 0; - padding: 0; - margin: 0; - width: 0; - height: 0; -} - -/** - * Cpanel Settings - */ -#cpanel div.icon, .cpanel div.icon { - text-align: center; - margin-right: 5px; - float: left; - margin-bottom: 5px; -} - -#cpanel div.icon a, .cpanel div.icon a { - display: block; - float: left; - height: auto; - min-height: 97px; - width: 108px; - color: #2c2c2c; - vertical-align: middle; - text-decoration: none; - font-weight: bold; -} - -#cpanel img, .cpanel img { - padding: 10px; - margin: 0 auto; -} - -#cpanel span, .cpanel span { - display: block; - text-align: center; - padding: 0 0 5px; -} - -div.cpanel-icons { - width: 54%; - float: left; -} - -div.cpanel-component { - width: 45%; - float: right; -} - -/** - * Standard Layout Styles - */ - -div.col { - float: left; -} - -div.options-section.col { - float: right; -} - -div.col1 { - float: left; - width: 45%; -} - -div.col2 { - float: right; - width: 45%; -} - -/* Avoid using the width divs. They are here for 3PD Extensions if needed - * Use the specific layout divs listed after. See also the th.width entries */ -div.width-1 { - width: 1%; -} - -div.width-3 { - width: 3%; -} - -div.width-5 { - width: 5%; -} - -div.width-10 { - width: 10%; -} - -div.width-20 { - width: 20%; -} - -div.width-30 { - width: 30%; -} - -div.width-35 { - width: 35%; -} - -div.width-40 { - width: 40%; -} - -div.width-45 { - width: 45%; -} - -div.width-50 { - width: 50%; -} - -div.width-55 { - width: 55%; -} - -div.width-60 { - width: 60%; -} - -div.width-65 { - width: 65%; -} - -div.width-70 { - width: 70%; -} - -div.width-80 { - width: 80%; -} - -div.width-100 { - width: 100%; -} - -.clrlft { - clear: left; -} - -.clrrt { - clear: right; -} - -.fltlft { - float: left; -} - -.fltrt { - float: right; -} - -.fltnone { - float: none; -} - -/* Layout Divs */ -div.main-section { - width: 60%; -} - -div.options-section { - width: 38%; - margin: 10px 10px 10px 0; -} - -/* for bluestork style html */ -div.width-40.fltrt { - width: 38%; - margin: 10px 10px 10px 0; -} - -div.rules-section { - width: 98%; - margin: 10px; -} - -/** - * Form Styles - */ - -fieldset { - margin: 2px 10px 2px 10px; - padding: 5px; - text-align: left; -} - -legend { - font-size: 1.3em; - font-weight: bold; - padding-bottom: 5px; -} - -fieldset p { - margin: 10px 0; - font-size: 1.2em; -} - -fieldset ol, ol#property-values, fieldset ul, ul#property-values { - margin: 0; - padding: 0; -} - -fieldset li, ol#property-values li, ul#property-values li { - list-style: none; - margin: 0; - padding: 5px; -} - -fieldset.adminform fieldset.radio, -fieldset.panelform fieldset.radio, -fieldset.adminform-legacy fieldset.radio { - border: 0; - float: left; - padding: 0; - margin: 0 0 5px 0; - clear: right; -} - -fieldset.adminform fieldset.radio label, -fieldset.panelform fieldset.radio label, -fieldset.adminform fieldset.radio span.faux-label, -fieldset.panelform fieldset.radio span.faux-label { - min-width: 40px; - float: left; - clear: none; -} - -/* checkboxes */ -fieldset.adminform fieldset.checkboxes, -fieldset.panelform fieldset.checkboxes, -fieldset.adminform-legacy fieldset.checkboxes { - border: 0; - float: left; - padding: 0; - margin: 0 0 5px 0; - clear: right; -} - -fieldset.adminform fieldset.checkboxes input[type="checkbox"], -fieldset.panelform fieldset.checkboxes input[type="checkbox"] { - float: left; - clear: left; -} - -fieldset.adminform fieldset.checkboxes label, -fieldset.panelform fieldset.checkboxes label, -fieldset.adminform fieldset.checkboxes span.faux-label, -fieldset.panelform fieldset.checkboxes span.faux-label { - clear: right; -} - -/* end checkboxes */ - -/* spacer */ -div.current span.spacer > span.before, -fieldset.adminform span.spacer > span.before, -fieldset.panelform span.spacer > span.before { - clear: both; - overflow: hidden; - height: 0; - display: block; -} - -/* end spacer */ - -fieldset.panelform-legacy label, -fieldset.adminform-legacy label, -fieldset.panelform-legacy span.faux-label, -fieldset.adminform-legacy span.faux-label { - min-width: 150px; - float: left; - -} - - -fieldset.adminform, -fieldset.panelform { - .input-prepend, - .input-append { - float: left; - } - .adminformlist .btn.modal, - .input-prepend > *, - .input-append > * { - float: none; - vertical-align: middle; - } -} - -/* JParameter classes on radio button labels */ -fieldset.panelform-legacy label.radiobtn-jno, -fieldset.panelform-legacy label.radiobtn-jyes, -fieldset.panelform-legacy label.radiobtn-show, -fieldset.panelform-legacy label.radiobtn-hide, -fieldset.panelform-legacy label.radiobtn-off, -fieldset.panelform-legacy label.radiobtn-on { - min-width: 40px !important; - clear: none !important; -} - -#jform_plugdesc-lbl, -#jform_description-lbl { - font-weight: bold; - clear: both; - margin-top: 15px; -} - -p.jform_desc { - clear: left; -} - -div#jform_ordering { - font-size: 1.091em; - margin-top: 3px; -} - -fieldset ul.checklist { - margin-left: 27px; -} - -fieldset ul.checklist input, -fieldset ul.checklist label { - float: none; -} - -fieldset ul.checklist input:focus { - outline: thin dotted #333333; -} - -fieldset#filter-bar { - margin: 0; - padding: 5px 10px 5px 10px; - float: left; - width: 98% -} - -fieldset#filter-bar ol, fieldset#filter-bar ul { - list-style: none; - margin: 0; - padding: 5px 0 0; -} - -fieldset#filter-bar ol li, fieldset#filter-bar ul li { - float: left; - padding: 0 5px 0 0; -} - -fieldset#filter-bar ol li fieldset, fieldset#filter-bar ul li fieldset { - margin: 0; - padding: 0; -} - -fieldset#filter-bar .filter-search { - float: left; - padding-bottom: 3px; -} - -fieldset#filter-bar .filter-select { - float: right; -} - -fieldset#filter-bar input#search { - width: 10em; -} - -/* Note: these visual cues should be augmented by aria */ -.invalid { - font-weight: bold; -} - -/* augmented by aria in template javascript */ -input.readonly, span.faux-input { - border: 0; -} - -.star { - color: #cc0000; - font-size: 1.2em; -} - -input, select, span.faux-input { - font-size: 1.2em; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} - -span.readonly { - float: left; - font-size: 1.2em; - line-height: 2em; -} - -div.readonly { - font-size: 1.2em; - line-height: 2em; -} - -div.extdescript { - margin-left: 10px; -} - -input[type="button"], -input[type="submit"], -input[type="reset"] { - font-family: Arial, Helvetica, sans-serif; - padding: 1px 6px; - font-size: 1.2em; - line-height: 1.5em; -} - -textarea { - font-size: 1.4em; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} - -input.button { - cursor: pointer; -} - -label { - font-weight: bold; - font-size: 1.1em; -} - -span.faux-label { - font-weight: bold; - font-size: 1.1em; -} - -label.selectlabel { - position: absolute; - left: -1000em; -} - -/** - * Option or Parameter styles - */ - -.paramrules { - padding: 10px; -} - -span.gi { - font-weight: bold; - margin-right: 5px; -} - -span.gtr { - visibility: hidden; - margin-right: 5px; -} - -/** - * Admintable Styles - */ -table.admintable td { - padding: 3px; - font-size: 1em; -} - -table.admintable td.key, table.admintable td.paramlist_key { - text-align: right; - width: 140px; - font-weight: bold; - font-size: 1em; -} - -table.admintable td.key label, table.admintable td.paramlist_key label { - font-size: 1em; -} - -table.admintable td.paramlist_value label { - font-size: 1em; -} - -table.admintable input, table.admintable span.faux-input, table.admintable select { - font-size: 1em; -} - -table.paramlist td.paramlist_description { - text-align: left; - width: 170px; - font-weight: normal; -} - -table.admintable td.key.vtop { - vertical-align: top; -} - -/** - * Admin Form Styles - */ -fieldset.adminform { - margin: 0 10px 10px 10px; - overflow: hidden; -} - -.adminformlist .btn.modal{ - float: left; - margin-top: 7px; -} - -ul.adminformlist, -ul.adminformlist li, -dl.adminformlist, -dl.adminformlist li { - margin: 0; - padding: 0; - list-style: none; -} - -ul.adminformlist pre { - font-size: 1.3em; -} - -ul.adminformlist .button2-left, ul.adminformlist .button2-left { - margin-top: 5px; -} - -/* Table styles are for use with tabular data */ -table.adminform { - width: 100%; - border-collapse: collapse; - margin: 8px 0 10px 0; - margin-bottom: 15px; -} - -table.adminform.nospace { - margin-bottom: 0; -} - -table.adminform th { - font-size: 1.4em; - padding: 6px 2px 4px 4px; - text-align: left; - height: 25px; -} - -table.adminform td { - padding: 3px; - text-align: left; -} - -table.adminform td#filter-bar { - text-align: left; -} - -table.adminform td.helpMenu { - text-align: right; -} - -table.adminform tr { - padding-left: 10px; - padding-right: 10px; -} - -/** - * Table formating styles - */ -td.center, th.center { - text-align: center; -} - -/* Avoid using the width classes. They are here for 3PD Extensions if needed - * Use the specific layout table headers listed after. See also the div.width entries */ -th.width-1 { - width: 1%; -} - -th.width-3 { - width: 3%; -} - -th.width-5 { - width: 5%; -} - -th.width-10 { - width: 10%; -} - -th.width-12 { - width: 12%; -} - -th.width-15 { - width: 15%; -} - -th.width-20 { - width: 20%; -} - -th.width-25 { - width: 25%; -} - -th.width-30 { - width: 30%; -} - -th.width-40 { - width: 40%; -} - -/* Table header layout classes */ -th.row-number-col { - width: 3%; -} - -th.checkmark-col { - width: 1%; -} - -th.state-col { - width: 5%; -} - -th.ordering-col { - width: 10%; -} - -th.ordering-col a { - display: block; - float: left; - margin-left: 3px; -} - -th.ordering-col a img { - margin-left: 4px; - margin-right: 4px; -} - -.categories th.ordering-col input, .categories td.order input { - font-size: 1em; -} - -th.category-col { - width: 5%; -} - -th.access-col { - width: 10%; -} - -.categories th.access-col { - width: 5%; -} - -th.hits-col { - width: 5%; -} - -th.id-col { - width: 3%; -} - -th.featured-col { - width: 5%; -} - -th.created-by-col { - width: 15%; -} - -th.date-col { - width: 5%; -} - -th.language-col { - width: 5%; -} - -th.home-col { - width: 5%; -} - -/** - * Adminlist Table layout - */ -table.adminlist { - width: 100%; - float: left; -} - -table.adminlist td, table.adminlist th { - padding: 4px; - font-size: 1.2em; -} - -table.adminlist thead th { - text-align: center; -} - -table.adminlist thead a:hover { - text-decoration: none; -} - -table.adminlist thead th img { - vertical-align: middle; -} - -table.adminlist tbody th { - font-weight: bold; -} - -/* Table row styles */ -table.adminlist tr { - padding-left: 30px; - padding-right: 30px; -} - -table.adminlist tbody tr { - text-align: left; -} - -table.adminlist tbody tr td, -table.adminlist tbody tr th { - height: 25px; -} - -table.adminlist tfoot tr { - text-align: center; -} - -/* Table td/th styles */ -table.adminlist tfoot td, table.adminlist tfoot th { - text-align: center; -} - -table.adminlist td.order { - text-align: center; - white-space: nowrap; -} - -table.adminlist td.order span { - float: left; - width: 20px; - text-align: center; -} - -table.adminlist td.order input { - text-align: center; - width: 3em; - font-size: 100%; -} - -/** - * Tree indentation & nesting - Up to 10 levels deep so don't go crazy : - */ -#media-tree_tree ul { - list-style: none outside none; - margin: 0 10px; -} - -table.adminlist td.indent-4 { - padding-left: 4px; -} - -table.adminlist td.indent-19 { - padding-left: 19px; -} - -table.adminlist td.indent-34 { - padding-left: 34px; -} - -table.adminlist td.indent-49 { - padding-left: 49px; -} - -table.adminlist td.indent-64 { - padding-left: 64px; -} - -table.adminlist td.indent-79 { - padding-left: 79px; -} - -table.adminlist td.indent-94 { - padding-left: 94px; -} - -table.adminlist td.indent-109 { - padding-left: 109px; -} - -table.adminlist td.indent-124 { - padding-left: 124px; -} - -table.adminlist td.indent-139 { - padding-left: 139px; -} - -/** - * Adminlist buttons - */ -table.adminlist tr td.btns a { - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - padding: 3px 20px; -} - -table.adminlist tr td.btns a:hover, table.adminlist tr td.btns a:active, table.adminlist tr td.btns a:focus { - text-decoration: none; -} - -/** - * Adminlist lists - */ -table.adminlist td li { - list-style: inside; -} - -/** - * Modal Modules styles - */ -ul#new-modules-list { - margin-left: 50px; - font-size: 1.4em; - line-height: 1.5em; -} - -/** - * Utility styles - */ -/* General Clearing Class */ -.clr { - clear: both; - overflow: hidden; - height: 0; -} - -.clearfix:after { - content: "."; - display: block; - height: 0; - clear: both; - visibility: hidden; -} - -.menu-module-list { - list-style-position: inside; - padding-left: 10px; - margin-left: 5px; -} - -/* stu nicholls solution for centering divs */ -.container { - clear: both; - text-decoration: none; -} - -* html .container { - display: inline-block; -} - -/* table solution for global config */ -table.noshow { - width: 100%; - border-collapse: collapse; - padding: 0; - margin: 0; -} - -table.noshow tr { - vertical-align: top; -} - -table.noshow fieldset { - margin: 15px 7px 7px 7px; -} - -/** - * Saving order icon styling in admin tables - */ -a.saveorder { - width: 16px; - height: 16px; - display: block; - overflow: hidden; - float: right; - margin-right: 8px; -} - -/** - * Button styling - */ -#editor-xtd-buttons { - padding: 5px; -} - -button { - font-family: Arial, Helvetica, sans-serif; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - margin-right: 3px; - margin-left: 3px; -} - -.invalid { - font-weight: bold; -} - -/* Button 1 Type */ -.button1, .button1 div { - height: 1%; - float: right; -} - -.button1 { - white-space: nowrap; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} - -.button1 a { - display: block; - height: 2.2em; - float: left; - line-height: 2.2em; - font-size: 1.2em; - font-weight: bold; - cursor: default; - padding: 0 6px 0 6px; - /* add padding if you are using the directional images */ - /* padding: 0 30px 0 6px; */ -} - -.button1 a:hover, .button1 a:focus { - text-decoration: none; -} - -/* Button 2 Type */ -.button2-left, .button2-right { - float: left; - line-height: 1.5em; - font-size: 1.2em; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} - -.button2-left.smallsub, .button2-right.smallsub { - line-height: 1.2em; - font-size: .9em; -} - -.button2-left a, .button2-right a, .button2-left span, .button2-right span { - display: block; - float: left; - cursor: default; -} - -/* these are inactive buttons */ -.button2-left span, .button2-right span { - cursor: default; -} - -.button2-left .page a, .button2-right .page a, -.button2-left .page span, .button2-right .page span, -.button2-left .blank a, .button2-right .blank a, -.button2-left .blank span, .button2-right .blank span { - padding: 0 6px; -} - -.page span, .blank span { - font-weight: bold; -} - -.button2-left a:hover, -.button2-right a:hover, -.button2-left a:focus, -.button2-right a:focus { - text-decoration: none; -} - -.button2-left a, .button2-left span { - padding: 0 24px 0 6px; -} - -.button2-right a, .button2-right span { - padding: 0 6px 0 24px; -} - -.button2-left { - float: left; - margin-left: 5px; -} - -.button2-right { - float: left; - margin-left: 5px; -} - -/** - * Pagination styles - */ - -/* Normal pagination styles */ -div.containerpg { - position: relative; - left: 50%; - float: left; - clear: left; -} - -div.pagination { - position: relative; - left: -50%; - margin: 0 auto; - padding: .5em; -} - -.pagination div.limit { - float: left; - margin: 0 10px; - font-size: 1.2em; - height: 1.8em; - line-height: 1.8em; -} - -.pagination div.limit label { - font-size: 100%; - height: 1.8em; - line-height: 1.8em; -} - -.pagination div.limit select { - font-size: 100%; -} - -/* The Go submittal button */ -.pagination button { - font-size: 100%; - height: 2.0em; - line-height: 1.8em; - margin-right: 20px; -} - -div.pagination .button2-right, div.pagination .button2-left { - font-size: 1.2em; - height: 1.6em; - line-height: 1.6em; -} - -/* Style if pagination is part of the table (old style) */ -table.adminlist .pagination { - display: table; - padding: 0; - margin: 0 auto; - font-size: .8em; -} - -table.adminlist .pagination button { - font-size: 1.2em; - height: 1.6em; - line-height: 1.5em; - margin-right: 20px; -} - -/** - * MCE Editor - */ -div.toggle-editor { - margin-top: 9px; -} - -/** - * Tooltips - */ -.tip { - float: left; - padding: 5px; - max-width: 400px; - z-index: 50; -} - -.tip-title { - padding: 0; - margin: 0; - font-size: 120%; - margin-top: -15px; - padding-top: 15px; - padding-bottom: 5px; -} - -.tip-text { - font-size: 100%; - text-align: left; - margin: 0; -} - -/** - * Calendar - */ -a img.calendar { - width: 16px; - height: 16px; - margin-left: 3px; - cursor: pointer; - vertical-align: middle; -} - -/** - * JGrid styles - */ -a.jgrid:hover { - text-decoration: none; -} - -.jgrid span.state { - display: inline-block; - height: 16px; - width: 16px; -} - -.jgrid span.text { - display: none; -} - -/** - * Icons - * The Background Icons for Menus, Toolbars, Quick Icons - * are now in the color css files - */ - -/** - * General styles - */ -div.message { - text-align: center; - font-family: Arial, Helvetica, sans-serif; - font-size: 1.2em; - padding: 3px; - margin-bottom: 10px; - font-weight: bold; -} - -.helpIndex { - border: 0; - width: 100%; - height: 100%; - padding: 0; - overflow: auto; -} - -.helpFrame { - width: 100%; - height: 800px; - padding: 0 5px 0 10px; -} - -#treecellhelp { - width: 25%; - display: block; - position: relative; - float: left; - margin: 0; - padding: 2px; - overflow: hidden; -} - -#datacellhelp { - width: 73%; - display: block; - float: left; - margin: 0; - padding: 2px 0 0 0; -} - -.outline { - padding: 2px; -} - -/** - * Modal Styles - */ - -h2.modal-title { - margin-left: 15px; - margin-bottom: 0; - margin-top: 5px; - font-size: 1.8em; - padding-bottom: .5em; -} - -ul.menu_types { - padding: 0 0 0 15px; - width: 95%; - margin: 0; -} - -ul.menu_types li, -dl.menu_type dd ul li { - width: 240px; - list-style: none; - display: block; - float: left; - margin-right: 10px; -} - -ul.menu_types li { - width: 47%; -} - -dl.menu_type { - width: 240px; - margin: 0; - padding: 0; -} - -dl.menu_type dt { - font-weight: bold; - font-size: 1.5em; - float: left; - margin: 13px 0 5px 0; - width: 240px; -} - -dl.menu_type dd { - clear: left; - margin: 0; -} - -dl.menu_type dd a { - font-size: 1.2em; -} - -dl.menu_type dd ul li { - margin: 0; -} - -ul#new-modules-list { - padding: 5px 0 0 15px; - width: 95%; - margin: 0; - list-style: none; -} - -ul#new-modules-list li { - list-style: none; - display: block; - float: left; - margin: 0 20px 0 0; - width: 47%; -} - -ul#new-modules-list li a { - font-size: 1em; - line-height: 1.5em; -} - -body.contentpane #filter-bar { - font-size: 80%; -} - -body.contentpane input, body.contentpane select { - font-size: 120%; -} - -#filter-bar input, #filter-bar select, #filter-bar button { - font-size: 110%; -} - -/** - * User Accessibility - */ - -/* Skip to Content Structural Styling */ -#skiplinkholder a, #skiplinkholder a:link, #skiplinkholder a:visited { - display: block; - width: 99%; - position: absolute; - top: 0; - left: -200%; - z-index: 2; -} - -#skiplinkholder a:focus, #skiplinkholder a:active { - left: 0; - top: 0; - z-index: 100; -} - -#skiplinkholder p { - margin: 0; -} - -#skiptargetholder { - position: absolute; - left: -200%; -} - -/* Skip to Content Visual Styling */ -#skiplinkholder a, #skiplinkholder a:link, #skiplinkholder a:visited { - text-decoration: underline; - padding: 5px; - font-size: 1.3em; - font-weight: bold; - padding-left: 20px; - padding-right: 20px; -} - -/* Hide overlayed controls so that keyboarders can get to the modal */ -.body-overlayed a, -.body-overlayed input, -.body-overlayed button { - visibility: hidden; -} - -.body-overlayed #sbox-window a, -.body-overlayed #sbox-window input, -.body-overlayed #sbox-window button { - visibility: visible; -} - -/** - * Admin Form Styles - */ - -/* For elements that aren't to be seen by users unless the user does something - * like clicking on a header to see the collapsed section. */ -.element-hidden, .hide { - display: none; -} - -.hidebtn { - border: 0 !important; - padding: 0 !important; - margin: 0; - width: 0; - height: 0; -} - -/* For elements that aren't to be seen by visual users but do need to be read by screenreaders. - * Cannot be used for elements that can get focus such as links and form elements */ -.element-invisible, .hidelabeltxt { - height: 0; - overflow: hidden; - position: absolute; - padding: 0; - margin: 0; -} - -/* Firefox has issues styling legend so this is a universal fix - for making the legend invisible (i.e. visually it's not there, but screen readers see it */ - -legend.element-invisible { - position: absolute !important; - margin: 0; - padding: 0; - border: 0; - margin-left: -10000px; - font-size: 1px; - height: 0; -} - -fieldset.panelform { - overflow: hidden; - clear: both; -} - -fieldset.adminform label, -fieldset.panelform label, -fieldset.adminform span.faux-label, -fieldset.panelform span.faux-label { - line-height: 2em; - clear: left; - min-width: 12em; - float: left; - margin-left: 10px; - margin-right: 5px; -} - -fieldset.adminform.long label, -fieldset.panelform.long label, -fieldset.adminform.long span.faux-label, -fieldset.panelform.long span.faux-label { - min-width: 18em; -} - -fieldset.adminform fieldset.radio label, -fieldset.panelform fieldset.radio label, -fieldset.adminform fieldset.radio span.faux-label, -fieldset.panelform fieldset.radio span.faux-label { - margin-left: 0; -} - -fieldset.adminform input, fieldset.adminform span.faux-input, fieldset.adminform textarea, fieldset.adminform select, fieldset.adminform img, fieldset.adminform button, -fieldset.panelform input, fieldset.panelform span.faux-input, fieldset.panelform textarea, fieldset.panelform select, fieldset.panelform img, fieldset.panelform button { - float: left; - margin: 5px 5px 5px 0; - width: auto; -} - -/* -------- Batch Section ---------- */ -fieldset.batch { - margin: 20px 10px 10px 10px; - padding: 10px; -} - -fieldset.batch label { - margin: 5px; - min-width: 40px; -} - -fieldset.batch button { - margin: 3px; -} - -fieldset#batch-choose-action { - clear: left; - border: 0 none; -} - -fieldset.batch label { - float: left; - clear: none; -} - -fieldset label#batch-choose-action-lbl { - clear: left; - margin-top: 15px; -} - -label#batch-language-lbl, -label#batch-user-lbl { - clear: left; - margin-right: 10px; - margin-top: 15px; -} - -select#batch-language-id, -select#batch-user-id { - margin-top: 15px; -} - -select#batch-category-id, -select#batch-position-id, -select#batch-menu-id { - margin-right: 30px; -} - -fieldset.batch select, fieldset.batch input, fieldset.batch img, fieldset.batch button { - float: left; -} - -label#batch-access-lbl, -label#batch-client-lbl { - margin-right: 10px; -} - -div#jform_ordering { - font-size: 1.091em; - margin-top: 3px; -} - -/* Banner edit */ -#jform_impmade, #jform_clicks { - width: 30px; -} - -fieldset.panelform label#jform-imp { - min-width: 3em; - font-size: 1.091em; -} - -fieldset.adminform input#jform_clickurl { - width: 20em; -} - -/** - * ACL STYLES relocated from com_users/media/grid.css - */ - -a.move_up { - display: inline-block; - height: 16px; - text-indent: -1000em; - width: 16px; -} - -span.move_up { - display: inline-block; - height: 16px; - width: 16px; -} - -a.move_down { - display: inline-block; - height: 16px; - text-indent: -1000em; - width: 16px; -} - -span.move_down { - display: inline-block; - height: 16px; - width: 16px; -} - -a.grid_false { - display: inline-block; - height: 16px; - text-indent: -1000em; - width: 16px; -} - -a.grid_true { - display: inline-block; - height: 16px; - text-indent: -1000em; - width: 16px; -} - -a.grid_trash { - display: inline-block; - height: 16px; - text-indent: -1000em; - width: 16px; -} - -/** - * ACL PANEL STYLES - */ -div.acl-options { - width: 100%; -} - -/* All Tabs */ -table.aclsummary-table, -table.aclmodify-table { - border-collapse: collapse; - width: 100%; - font-size: 1.091em; -} - -td.col1 { - font-size: 1.091em; - text-align: left; - padding: 4px; -} - -table.aclsummary-table caption, -table.aclmodify-table caption { - display: none; -} - -/* Summary Tab */ -table.aclsummary-table th.col1 { - width: 25%; -} - -table.aclsummary-table th.col2, -table.aclsummary-table th.col3, -table.aclsummary-table th.col4, -table.aclsummary-table th.col5, -table.aclsummary-table th.col6 { - width: 15%; - vertical-align: bottom; - text-align: center; -} - -/* Icons (background images moved to color css files */ -span.icon-16-unset, -span.icon-16-allowed, -span.icon-16-denied, -span.icon-16-locked { - padding-left: 18px; -} - -label.icon-16-allow, -label.icon-16-deny, -a.icon-16-allow, -a.icon-16-deny, -a.icon-16-allowinactive, -a.icon-16-denyinactive { - display: block; - height: 16px; - width: 16px; - margin: 0 auto; -} - -label.icon-16-allow { - text-indent: -9999em; - position: relative; - left: 40%; -} - -label.icon-16-deny { - text-indent: -9999em; - position: relative; - left: 40%; -} - -/* Create, Edit, Edit State & Delete Tabs */ -table.aclmodify-table th.col2, -table.aclmodify-table th.col3, -table.aclmodify-table th.col4 { - width: 20%; - vertical-align: bottom; - text-align: center; -} - -table.aclmodify-table select { - margin: 1px; -} - -table.aclsummary-table td label, -table.aclmodify-table td label { - min-width: 20px; -} - -/* ACL footer/legend */ -ul.acllegend { - list-style: none; - font-size: 1.091em; - padding-bottom: 10px; -} - -ul.acllegend li { - display: block; - float: left; - padding-right: 20px; - margin: 15px 0 15px 10px; -} - -ul.acllegend li.acl-allowed { - padding-left: 20px; - padding-right: 10px; -} - -ul.acllegend li.acl-denied { - padding-left: 20px; - padding-right: 20px; -} - -ul.acllegend li.acl-editgroups { - padding-right: 10px; -} - -ul.acllegend li.acl-resetbtn { - padding-right: 0; -} - -li.acl-editgroups, -li.acl-resetbtn { - display: block; - float: left; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} - -li.acl-editgroups a, -li.acl-resetbtn a { - padding: 6px; - cursor: default; -} - -li.acl-editgroups a:hover, -li.acl-resetbtn a:hover, -li.acl-editgroups a:focus, -li.acl-resetbtn a:focus { - text-decoration: none; - cursor: default; -} - -li.acl-editgroups:hover, -li.acl-resetbtn:hover, -li.acl-editgroups:focus, -li.acl-resetbtn:focus { - text-decoration: none; - cursor: default; -} - -table#acl-config { - width: 100%; - margin-top: 15px; -} - -table#acl-config th, -table#acl-config td { - height: 2em; - background: #f9fade; - text-align: center; - vertical-align: middle; -} - -table#acl-config th.acl-groups { - padding-left: 8px; - font-weight: bold; - text-align: left; -} - -table#acl-config th.acl-groups span.gi { - margin-right: 2px; -} - -table#acl-config td { - width: 9em; -} - -table#acl-config td select { - float: none; -} - -.acl-action { - font-size: 1.091em; - margin: auto 0; -} - -.acl-groups { - font-size: 1.091em; - font-weight: normal; -} - -label#jform_rules-lbl { - float: none; - white-space: nowrap; - display: none; - visibility: hidden; -} - -label#jform_filters-lbl { - float: none; - white-space: nowrap; - display: none; - visibility: hidden; -} - -/** -* Options modal- config -*/ -ul.config-option-list, -ul.config-option-list li { - margin: 0; - padding: 0; - list-style: none; -} - -ul.config-option-list fieldset { - margin: 0; - padding-left: 0; - padding-right: 0; -} - -/* * -* Permission Rules -*/ -#permissions-sliders { - margin-top: 15px; -} - -#permissions-sliders ul#rules, -#permissions-sliders ul#rules ul { - margin: 0 !important; - padding: 0 !important; - list-style-type: none; -} - -#permissions-sliders ul#rules li { - margin: 0; - padding: 0; -} - -#permissions-sliders ul#rules table.group-rules { - border-collapse: collapse; - margin: 5px; - width: 100%; -} - -#permissions-sliders ul#rules table.group-rules td { - padding: 4px; - vertical-align: middle; - text-align: left; - overflow: hidden; -} - -#permissions-sliders ul#rules table.group-rules th { - font-size: 1.2em; - overflow: hidden; - font-weight: bold; -} - -#permissions-sliders .panel { - margin-bottom: 3px; - margin-left: 0; - border: 0; -} - -#permissions-sliders p.rule-desc { - font-size: 1.1em; -} - -#permissions-sliders div.rule-notes { - font-size: 1.1em; -} - -ul#rules table.group-rules td label { - margin: 0 !important; - line-height: 1.1em; -} - -ul#rules table.group-rules td span { - font-size: 1.1em; - padding-bottom: 4px; -} - -ul#rules table.group-rules td span span { - font-size: 100%; -} - -table.group-rules td select { - margin: 0 !important; -} - -#permissions-sliders ul#rules .mypanel { - padding: 0; - line-height: 1.3em; -} - -#permissions-sliders .mypanel table.group-rules caption { - font-size: 1.3em; -} - -#permissions-sliders ul#rules { - padding: 5px; -} - -#permissions-sliders ul#rules table.group-rules th { - text-align: left; - padding: 4px; -} - -#permissions-sliders ul#rules table.group-rules td label { - min-width: 1em; -} - -#permissions-sliders .pane-toggler span { - padding-left: 20px; -} - -#permissions-sliders .pane-toggler-down span { - padding-left: 20px; -} - -#permissions-sliders .pane-toggler-down span.level, -#permissions-sliders .pane-toggler span.level { - padding: 0; -} - -/* - * Debug styles - */ - -.swatch { - text-align: center; - padding: 0 15px 0 15px; -} - -/* Tab changes for accessibility */ -dl.tabs dt h3 { - padding: 0; - font-size: 100%; -} - -/** - * Helpmenus - */ -ul.helpmenu li { - float: right; - margin: 10px; - padding: 0; - list-style-type: none; - font-weight: bold; -} - -/* CSS file for Accessible Admin Menu - * based on Matt Carrolls' son of suckerfish - * with javascript by Bill Tomczak - */ - -/* Note: set up the font-size on the id and used 100% on the elements. - If ul/li/a are different ems, then the shifting back via non-js keyboard - doesn't work properly */ - -/** - * Menu Styling - */ -#menu { - /* this is on the main ul */ - position: relative; - z-index: 100; - padding: 0; - margin: 0; - width: 100%; - list-style: none; - font-size: 1.2em; - font-weight: bold; -} - -#menu ul { - /* all lists */ - padding: 0; - margin: 0; - list-style: none; - font-size: 100%; -} - -#menu ul li.separator { - margin-bottom: 1em; -} - -#menu a { - padding: 0.35em 2.5em 0.35em 2em; - vertical-align: middle; - display: block; - /* width: 10em; */ - text-decoration: none; - font-size: 100%; -} - -#menu li { - /* all list items */ - float: left; - /* width: 12em; width needed or else Opera goes nuts */ - font-size: 100%; -} - -#menu li a { - white-space: nowrap; -} - -#menu li li a { - margin-bottom: 1px; - margin-top: 1px; - width: 10em; -} - -#menu li.disabled a:hover, -#menu li.disabled a:focus, -#menu li.disabled a { - cursor: default; -} - -#menu li ul { - /* second-level lists */ - position: absolute; - width: 16em; - margin-left: -1000em; - /* using left instead of display to hide menus because display: none isn't read by screen readers */ -} - -#menu li li { - /* second-level row */ - border: none; - width: 16em; -} - -#menu li ul ul { - /* third-and-above-level lists */ - margin: -2.3em 0 0 -1000em; - /* top margin is equal to parent line height+bottom padding */ -} - -#menu li:hover ul ul, #menu li.sfhover ul ul { - margin-left: -1000em; -} - -#menu li:hover ul, #menu li.sfhover ul { - /* lists nested under hovered list items */ - margin-left: 0; -} - -#menu li li:hover ul, #menu li li.sfhover ul { - margin-left: 16em; -} - -/** - * Menu Icons - * These icons are used on the Administrator menu - * The classes are constructed dynamically when the menu is generated - */ -[class^="menu-"], -[class*=" menu-"] { - background-position: 3px 50% !important; -} -.menu-archive { - background-image: url(../images/menu/icon-16-archive.png); -} - -.menu-article { - background-image: url(../images/menu/icon-16-article.png); -} - -.menu-associations { - background-image: url(../images/menu/icon-16-assoc.png); -} - -.menu-banners { - background-image: url(../images/menu/icon-16-banner.png); -} - -.menu-banners-clients { - background-image: url(../images/menu/icon-16-banner-client.png); -} - -.menu-banners-tracks { - background-image: url(../images/menu/icon-16-banner-tracks.png); -} - -.menu-banners-cat { - background-image: url(../images/menu/icon-16-banner-categories.png); -} - -.menu-category { - background-image: url(../images/menu/icon-16-category.png); -} - -.menu-checkin { - background-image: url(../images/menu/icon-16-checkin.png); -} - -.menu-clear { - background-image: url(../images/menu/icon-16-clear.png); -} - -.menu-component { - background-image: url(../images/menu/icon-16-component.png); -} - -.menu-config { - background-image: url(../images/menu/icon-16-config.png); -} - -.menu-contact { - background-image: url(../images/menu/icon-16-contacts.png); -} - -.menu-contact-cat { - background-image: url(../images/menu/icon-16-contacts-categories.png); -} - -.menu-content { - background-image: url(../images/menu/icon-16-content.png); -} - -.menu-cpanel { - background-image: url(../images/menu/icon-16-cpanel.png); -} - -.menu-default { - background-image: url(../images/menu/icon-16-default.png); -} - -.menu-featured { - background-image: url(../images/menu/icon-16-featured.png); -} - -.menu-fields { - background-image: url(../images/menu/icon-16-puzzle.png); -} - -.menu-groups { - background-image: url(../images/menu/icon-16-groups.png); -} - -.menu-help { - background-image: url(../images/menu/icon-16-help.png); -} - -.menu-help-this { - background-image: url(../images/menu/icon-16-help-this.png); -} - -.menu-help-forum { - background-image: url(../images/menu/icon-16-help-forum.png); -} - -.menu-help-docs { - background-image: url(../images/menu/icon-16-help-docs.png); -} - -.menu-help-jed { - background-image: url(../images/menu/icon-16-help-jed.png); -} - -.menu-help-jrd { - background-image: url(../images/menu/icon-16-help-jrd.png); -} - -.menu-help-community { - background-image: url(../images/menu/icon-16-help-community.png); -} - -.menu-help-security { - background-image: url(../images/menu/icon-16-help-security.png); -} - -.menu-help-dev { - background-image: url(../images/menu/icon-16-help-dev.png); -} - -.menu-help-shop { - background-image: url(../images/menu/icon-16-help-shop.png); -} - -.menu-info { - background-image: url(../images/menu/icon-16-info.png); -} - -.menu-install { - background-image: url(../images/menu/icon-16-install.png); -} - -.menu-joomlaupdate { - background-image: url(../images/menu/icon-16-install.png); -} - -.menu-language { - background-image: url(../images/menu/icon-16-language.png); -} - -.menu-levels { - background-image: url(../images/menu/icon-16-levels.png); -} - -.menu-logout { - background-image: url(../images/menu/icon-16-logout.png); -} - -.menu-maintenance { - background-image: url(../images/menu/icon-16-maintenance.png); -} - -.menu-massmail { - background-image: url(../images/menu/icon-16-massmail.png); -} - -.menu-media { - background-image: url(../images/menu/icon-16-media.png); -} - -.menu-menu { - background-image: url(../images/menu/icon-16-menu.png); -} - -.menu-menumgr { - background-image: url(../images/menu/icon-16-menumgr.png); -} - -.menu-messages { - background-image: url(../images/menu/icon-16-messaging.png); -} - -.menu-messages-add { - background-image: url(../images/menu/icon-16-new-privatemessage.png); -} - -.menu-messages-read { - background-image: url(../images/menu/icon-16-messages.png); -} - -.menu-module { - background-image: url(../images/menu/icon-16-module.png); -} - -.menu-newarticle { - background-image: url(../images/menu/icon-16-newarticle.png); -} - -.menu-newcategory { - background-image: url(../images/menu/icon-16-newcategory.png); -} - -.menu-newgroup { - background-image: url(../images/menu/icon-16-newgroup.png); -} - -.menu-newlevel { - background-image: url(../images/menu/icon-16-newlevel.png); -} - -.menu-newuser { - background-image: url(../images/menu/icon-16-newuser.png); -} - -.menu-plugin { - background-image: url(../images/menu/icon-16-plugin.png); -} - -.menu-profile { - background-image: url(../images/menu/icon-16-user.png); -} - -.menu-purge { - background-image: url(../images/menu/icon-16-purge.png); -} - -.menu-readmess { - background-image: url(../images/menu/icon-16-readmess.png); -} - -.menu-section { - background-image: url(../images/menu/icon-16-section.png); -} - -.menu-static { - background-image: url(../images/menu/icon-16-static.png); -} - -.menu-stats { - background-image: url(../images/menu/icon-16-stats.png); -} - -.menu-themes { - background-image: url(../images/menu/icon-16-themes.png); -} - -.menu-trash { - background-image: url(../images/menu/icon-16-trash.png); -} - -.menu-user { - background-image: url(../images/menu/icon-16-user.png); -} - -.menu-user-note { - background-image: url(../images/menu/icon-16-user-note.png); -} - -.menu-delete { - background-image: url(../images/menu/icon-16-delete.png); -} - -.menu-help-trans { - background-image: url(../images/menu/icon-16-help-trans.png); -} - -.menu-newsfeeds { - background-image: url(../images/menu/icon-16-newsfeeds.png); -} - -.menu-newsfeeds-cat { - background-image: url(../images/menu/icon-16-newsfeeds-cat.png); -} - -.menu-redirect { - background-image: url(../images/menu/icon-16-redirect.png); -} - -.menu-search { - background-image: url(../images/menu/icon-16-search.png); -} - -.menu-finder { - background-image: url(../images/menu/icon-16-search.png); -} - -.menu-weblinks { - background-image: url(../images/menu/icon-16-links.png); -} - -.menu-weblinks-cat { - background-image: url(../images/menu/icon-16-links-cat.png); -} - -.menu-tags { - background-image: url(../images/menu/icon-16-tags.png); -} - -.menu-postinstall { - background-image: url(../images/menu/icon-16-generic.png); -} -.icon-32-cog { - background-image: url(../images/toolbar/icon-32-cog.png); -} - -/** - * Extra positioning rules for limited noscript keyboard accessibility - * need the backgrounds here to keep the background as the nav background - * since it is overlaying other content. - * Using margin-left instead of left so that can move back without javascript - * display downlevel ul - */ -#menu li a:focus+ul { - margin-left: 0; -} - -#menu li li a:focus+ul { - margin-left: 1016em; -} - -/* bring back the focus elements into view */ -#menu li li a:focus { - margin-left: 1000em; - width: 10em; -} - -#menu li li li a:focus { - margin-left: 2016em; - width: 10em; -} - -#menu li:hover a:focus, #menu li.sfhover a.sffocus { - margin-left: 0; -} - -#menu li li:hover a:focus+ul, #menu li li.sfhover a.sffocus+ul { - margin-left: 16em; -} - -/** - * Sidebar styling - */ -#sidebar { - float:left; - margin: 15px 5px; -} - -/** - * Submenu styling - */ -#submenu { - list-style: none; - padding: 0; - margin: 0; - /* border-bottom plus padding-bottom is the technique */ - padding-bottom: 2.5em; - line-height: 2em; -} - -#submenu ul, #submenu li { - display: inline; - list-style-type: none; - margin: 0; - padding: 0; -} - -#submenu li, #submenu span.nolink { - float: left; - font-weight: bold; - margin-right: 8px; - padding: 2px 10px 2px 10px; - text-decoration: none; - cursor: pointer; - -moz-border-radius-topright: 3px; - -moz-border-radius-topleft: 3px; - -webkit-border-top-right-radius: 3px; - -webkit-border-top-left-radius: 3px; - border-top-right-radius: 3px; - border-top-left-radius: 3px; -} - -#submenu span.nolink { - color: #999; -} - -#submenu li.active, #submenu span.nolink.active { - cursor: default; -} - -#submenu li.active a, #submenu span.nolink.active, #submenu li a:hover, #submenu li a:focus { - text-decoration: none; -} - -/* -- CUSTOM LANG STRINGS STYLES ----------- */ - -.red { - font-weight: bold; - color: #c00; -} - -/* -- OTHER STYLES ----------- */ - -.pre_message { - font-size: 1.3em; -} - -/* -- Update check badges -- */ -span.update-badge { - background-image: -moz-linear-gradient(center bottom, #FF0000 41%, #FC7E7E 79%); - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.41, rgb(255, 0, 0)), color-stop(0.79, rgb(252, 126, 126))); - border: 2px solid white; - border-radius: 1.5em 1.5em 1.5em 1.5em; - color: white; - display: block; - float: left; - font-size: 1.2em; - font-weight: bold; - height: 1.2em; - left: 60px; - min-width: 1em; - padding: 0 0.1em 0; - position: relative; - top: -88px; -} - -/* User Notes */ -.unotes ul, .unotes ol { - list-style: none; - list-style-position: inside; - padding-left: 0; - padding-right: 0; - -} - -.unotes div.utitle { - padding: 10px; - float: left; - font-size: 1.2em; - line-height: 1.2em; -} - -.unotes h4 { - margin-top: 0; - margin-bottom: 0; - font-size: 1.3em; -} - -.unotes .ubody { - padding-left: 10px; - padding-right: 10px; - font-size: 1.2em; - line-height: 1.5em; -} - -.unotes p { - padding-bottom: 10px; -} - -/* com-install styling */ -div#database-sliders { - margin: 10px; -} - -fieldset.uploadform { - margin-top: 10px; - margin-bottom: 10px; - min-height: 200px; -} - -/* Installer Database */ -#installer-database, #installer-discover, #installer-update, #installer-warnings { - margin-top: 10px; -} - -#installer-database #sidebar { - float: none -} - -#installer-database p.warning { - padding-left: 20px; -} - -#installer-database p.nowarning { - padding-left: 20px; -} - -/* Spinner */ -.joomlaupdate_spinner { - float: left; - margin-right: 15px; -} - -.btn-group { - position: relative; - display: inline-block; -} - -.btn-group + .btn-group { - margin-left: 5px; -} - -.btn-group > .btn { - position: relative; - float: left; - margin-left: -1px; -} - -.icon-48-cpanel { - height: 50px; - width: 50%; -} - -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f5f5f5; - border: 1px solid #eee; - border: 1px solid rgba(0, 0, 0, 0.05); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); -} - -.well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); -} - -.well-large { - padding: 24px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} - -.well-small { - padding: 9px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} - -/* Striped */ -.list-striped, -.row-striped { - list-style: none; - line-height: 18px; - text-align: left; - vertical-align: middle; - border-top: 1px solid #dddddd; - margin-left: 0; - font-size: 1.2em; - padding: 9px; -} - -.list-striped li, -.list-striped dd, -.row-striped .row, -.row-striped .row-fluid { - border-bottom: 1px solid #dddddd; - padding: 8px; -} - -.list-striped li:nth-child(odd), -.list-striped dd:nth-child(odd), -.row-striped .row:nth-child(odd), -.row-striped .row-fluid:nth-child(odd) { - background-color: #f9f9f9; -} - -.list-striped li:hover, -.list-striped dd:hover, -.row-striped .row:hover, -.row-striped .row-fluid:hover { - background-color: #f5f5f5; -} - -.row-striped .row-fluid { - width: 100%; - box-sizing: border-box; -} - -.row-striped .row-fluid [class*="span"] { - min-height: 10px; -} - -.alert { - padding: 8px 35px 8px 14px; - margin-bottom: 18px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - background-color: #fcf8e3; - border: 1px solid #fbeed5; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - color: #c09853; - font-size: 120%; -} - -.alert-heading { - color: inherit; -} - -.alert .close { - position: relative; - right: -30px; - top: -5px; - line-height: 18px; - float: right; - font-size: 20px; - font-weight: bold; -} - -.alert-success { - background-color: #dff0d8; - border-color: #d6e9c6; - color: #468847; -} - -.alert-danger, -.alert-error { - background-color: #f2dede; - border-color: #eed3d7; - color: #b94a48; -} - -.alert-info { - background-color: #d9edf7; - border-color: #bce8f1; - color: #3a87ad; -} - -.alert-block { - padding-top: 14px; - padding-bottom: 14px; -} - -.alert-block > p, -.alert-block > ul { - margin-bottom: 0; -} - -.alert-block p + p { - margin-top: 5px; -} - -.btn-group > .btn:hover, .btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active { - z-index: 2; -} - -.btn-group > .btn { - position: relative; - float: left; - margin-left: -1px; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} - -table { - max-width: 100%; - background-color: transparent; - border-collapse: collapse; - border-spacing: 0; -} - -.table { - width: 100%; - margin-bottom: 18px; -} - -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} - -.tab-content > .active, -.pill-content > .active { - display: block; -} - -.tabs-below > .nav-tabs { - border-top: 1px solid #ddd; -} - -#status .btn-toolbar, #status p { - margin: 0px; -} - -.navbar .btn-group { - margin: 0; - padding: 5px 5px 6px; -} - -/** - * Media - */ -.media .btn { - margin: 10px 20px; -} - -.thumbnails > li { - list-style: none outside none; - float: left; - margin-bottom: 18px; - margin-left: 20px; -} - -#mediamanager-form { - margin: 10px; -} -.is-tagbox { - float: left; -} - -/* Item associations */ -.item-associations { - margin: 0; -} -.item-associations li { - list-style: none; - display: inline-block; - margin: 0 0 3px 0; -} -.item-associations li a, -table.adminlist .item-associations li a { - color: #ffffff; -} - -.hidden { - display: none; - visibility: hidden; -} - -// Bootstrap Tooltips (need to load last, something is overriding these styles in the CSS, debug later ;-) ) -@import "../../../../media/jui/less/tooltip.less"; - -.tooltip { - max-width: 400px; -} -.tooltip-inner { - max-width: none; - text-align: left; - text-shadow: none; -} -th .tooltip-inner { - font-weight: normal; -} -.tooltip.hasimage { - opacity: 1; -} -fieldset.panelform .tooltip img { - float: none; - margin: 0; -} -//Toggle editor button -div.toggle-editor { - float: right; -} - -.text-left { - text-align: left; -} -.text-right { - text-align: right; -} -.text-center { - text-align: center; -} -.module-edit { - display: inline-block; -} -.break-word { - word-break: break-all; - word-wrap: break-word; -} -.muted { - color: #999; -} -/* Popover minimum height - overwrite bootstrap default */ -.popover-content { - min-height: 33px; -} \ No newline at end of file diff --git a/administrator/templates/hathor/less/variables.less b/administrator/templates/hathor/less/variables.less deleted file mode 100644 index 11e990a1f1e3a..0000000000000 --- a/administrator/templates/hathor/less/variables.less +++ /dev/null @@ -1,216 +0,0 @@ -// Variables.less -// Variables to customize the look and feel of Bootstrap -// ----------------------------------------------------- - - - -// GLOBAL VALUES -// -------------------------------------------------- - - -// Grays -// ------------------------- -@black: #000; -@grayDarker: #222; -@grayDark: #333; -@gray: #555; -@grayLight: #999; -@grayLighter: #eee; -@white: #fff; - - -// Accent colors -// ------------------------- -@blue: #049cdb; -@blueDark: #0064cd; -@green: #46a546; -@red: #9d261d; -@yellow: #ffc40d; -@orange: #f89406; -@pink: #c3325f; -@purple: #7a43b6; - - -// Scaffolding -// ------------------------- -@bodyBackground: @white; -@textColor: @grayDark; - - -// Links -// ------------------------- -@linkColor: #08c; -@linkColorHover: darken(@linkColor, 15%); - - -// Typography -// ------------------------- -@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; -@serifFontFamily: Georgia, "Times New Roman", Times, serif; -@monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace; - -@baseFontSize: 13px; -@baseFontFamily: @sansFontFamily; -@baseLineHeight: 18px; -@altFontFamily: @serifFontFamily; - -@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily -@headingsFontWeight: bold; // instead of browser default, bold -@headingsColor: inherit; // empty to use BS default, @textColor - - -// Tables -// ------------------------- -@tableBackground: transparent; // overall background-color -@tableBackgroundAccent: #f9f9f9; // for striping -@tableBackgroundHover: #f5f5f5; // for hover -@tableBorder: #ddd; // table and cell border - - -// Buttons -// ------------------------- -@btnBackground: @white; -@btnBackgroundHighlight: darken(@white, 10%); -@btnBorder: #ccc; - -@btnPrimaryBackground: #2384d3; -@btnPrimaryBackgroundHighlight: #15497c; - -@btnInfoBackground: #5bc0de; -@btnInfoBackgroundHighlight: #2f96b4; - -@btnSuccessBackground: #62c462; -@btnSuccessBackgroundHighlight: #51a351; - -@btnWarningBackground: lighten(@orange, 15%); -@btnWarningBackgroundHighlight: @orange; - -@btnDangerBackground: #ee5f5b; -@btnDangerBackgroundHighlight: #bd362f; - -@btnInverseBackground: @gray; -@btnInverseBackgroundHighlight: @grayDarker; - - -// Forms -// ------------------------- -@inputBackground: @white; -@inputBorder: #ccc; -@inputBorderRadius: 3px; -@inputDisabledBackground: @grayLighter; -@formActionsBackground: #f5f5f5; - -// Dropdowns -// ------------------------- -@dropdownBackground: @white; -@dropdownBorder: rgba(0,0,0,.2); -@dropdownLinkColor: @grayDark; -@dropdownLinkColorHover: @white; -@dropdownLinkBackgroundHover: @linkColor; -@dropdownDividerTop: #e5e5e5; -@dropdownDividerBottom: @white; - - - -// COMPONENT VARIABLES -// -------------------------------------------------- - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -@zindexDropdown: 1000; -@zindexTooltip: 1020; -@zindexFixedNavbar: 1030; -@zindexModalBackdrop: 1040; -@zindexModal: 1050; -@zindexPopover: 1060; - -// Sprite icons path -// ------------------------- -@iconSpritePath: "../img/glyphicons-halflings.png"; -@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; - - -// Input placeholder text color -// ------------------------- -@placeholderText: @grayLight; - - -// Hr border color -// ------------------------- -@hrBorder: @grayLighter; - - -// Navbar -// ------------------------- -@navbarHeight: 40px; -@navbarBackground: @grayDarker; -@navbarBackgroundHighlight: @grayDark; - -@navbarText: @grayLight; -@navbarLinkColor: @grayLight; -@navbarLinkColorHover: @white; -@navbarLinkColorActive: @navbarLinkColorHover; -@navbarLinkBackgroundHover: transparent; -@navbarLinkBackgroundActive: @navbarBackground; - -@navbarSearchBackground: lighten(@navbarBackground, 25%); -@navbarSearchBackgroundFocus: @white; -@navbarSearchBorder: darken(@navbarSearchBackground, 30%); -@navbarSearchPlaceholderColor: #ccc; -@navbarBrandColor: @navbarLinkColor; - - -// Hero unit -// ------------------------- -@heroUnitBackground: @grayLighter; -@heroUnitHeadingColor: inherit; -@heroUnitLeadColor: inherit; - - -// Form states and alerts -// ------------------------- -@warningText: #c09853; -@warningBackground: #fcf8e3; -@warningBorder: darken(spin(@warningBackground, -10), 3%); - -@errorText: #b94a48; -@errorBackground: #f2dede; -@errorBorder: darken(spin(@errorBackground, -10), 3%); - -@successText: #468847; -@successBackground: #dff0d8; -@successBorder: darken(spin(@successBackground, -10), 5%); - -@infoText: #3a87ad; -@infoBackground: #d9edf7; -@infoBorder: darken(spin(@infoBackground, -10), 7%); - - - -// GRID -// -------------------------------------------------- - -// Default 940px grid -// ------------------------- -@gridColumns: 12; -@gridColumnWidth: 60px; -@gridGutterWidth: 20px; -@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); - -// Fluid grid -// ------------------------- -@fluidGridColumnWidth: 6.382978723%; -@fluidGridGutterWidth: 2.127659574%; - - -// Login -// ------------------------- -@loginBackground: #142849; -@loginBackgroundHighlight: #165387; - -// Header -// ------------------------- -@headerBackground: #1a3867; -@headerBackgroundHighlight: #17568c; \ No newline at end of file diff --git a/administrator/templates/hathor/login.php b/administrator/templates/hathor/login.php deleted file mode 100644 index 74708ece85dca..0000000000000 --- a/administrator/templates/hathor/login.php +++ /dev/null @@ -1,140 +0,0 @@ -setScheme(((int) $app->get('force_ssl', 0) === 2) ? 'https' : 'http'); - -// Output as HTML5 -$this->setHtml5(true); - -// jQuery needed by template.js -JHtml::_('jquery.framework'); - -// Add template js -JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); - -// Add html5 shiv -JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); - -// Load optional RTL Bootstrap CSS -JHtml::_('bootstrap.loadCss', false, $this->direction); - -// Load system style CSS -JHtml::_('stylesheet', 'templates/system/css/system.css', array('version' => 'auto')); - -// Loadtemplate CSS -JHtml::_('stylesheet', 'template.css', array('version' => 'auto', 'relative' => true)); - -// Load additional CSS styles for colors -if (!$this->params->get('colourChoice')) -{ - $colour = 'standard'; -} -else -{ - $colour = htmlspecialchars($this->params->get('colourChoice'), ENT_COMPAT, 'UTF-8'); -} - -JHtml::_('stylesheet', 'colour_' . $colour . '.css', array('version' => 'auto', 'relative' => true)); - -// Load additional CSS styles for rtl sites -if ($this->direction === 'rtl') -{ - JHtml::_('stylesheet', 'template_rtl.css', array('version' => 'auto', 'relative' => true)); - JHtml::_('stylesheet', 'colour_' . $colour . '_rtl.css', array('version' => 'auto', 'relative' => true)); -} - -// Load additional CSS styles for bold Text -if ($this->params->get('boldText')) -{ - JHtml::_('stylesheet', 'boldtext.css', array('version' => 'auto', 'relative' => true)); -} - -// Load specific language related CSS -JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); - -// Load custom.css -JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); - -// IE specific -JHtml::_('stylesheet', 'ie8.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 8')); -JHtml::_('stylesheet', 'ie7.css', array('version' => 'auto', 'relative' => true, 'conditional' => 'IE 7')); - -// Logo file -if ($this->params->get('logoFile')) -{ - $logo = JUri::root() . $this->params->get('logoFile'); -} -else -{ - $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo.png'; -} -?> - - - - - - -
          - - - -
          - - - -
          -
          -
          - - - - diff --git a/administrator/templates/hathor/postinstall/hathormessage.php b/administrator/templates/hathor/postinstall/hathormessage.php deleted file mode 100644 index bacfbca2f176e..0000000000000 --- a/administrator/templates/hathor/postinstall/hathormessage.php +++ /dev/null @@ -1,134 +0,0 @@ -authorise('core.edit.state', 'com_templates')) - { - $query = $db->getQuery(true) - ->select('template') - ->from($db->quoteName('#__template_styles')) - ->where($db->quoteName('home') . ' = ' . $db->quote('1')) - ->where($db->quoteName('client_id') . ' = 1'); - - // Get the global setting about the default template - $globalTemplate = $db->setQuery($query)->loadResult(); - } - - // Get the current user admin style - $adminstyle = $user->getParam('admin_style'); - - if ($adminstyle) - { - $query = $db->getQuery(true) - ->select('template') - ->from($db->quoteName('#__template_styles')) - ->where($db->quoteName('id') . ' = ' . (int) $adminstyle) - ->where($db->quoteName('client_id') . ' = 1'); - - // Get the template name associated to the admin style - $template = $db->setquery($query)->loadResult(); - } - - if (($globalTemplate != 'hathor') && ($template != 'hathor')) - { - // Hathor is not default not global and not in the user so no message needed - return false; - } - - // Hathor is default please add the message - return true; -} - -/** - * Set the default backend template back to isis if you are allowed to do this - * This also sets the current user setting to isis if not done yet - * - * @return void - * - * @since 3.7 - */ -function hathormessage_postinstall_action() -{ - $db = JFactory::getDbo(); - $user = JFactory::getUser(); - - $query = $db->getQuery(true) - ->select(array('id', 'title')) - ->from($db->quoteName('#__template_styles')) - ->where($db->quoteName('template') . ' = "isis"') - ->where($db->quoteName('client_id') . ' = 1'); - - $isisStyleId = $db->setQuery($query)->loadColumn(); - $isisStyleName = $db->setQuery($query)->loadColumn(1); - $adminstyle = $user->getParam('admin_style'); - - // The user uses the system setting so no need to change that. - if ($adminstyle) - { - $query = $db->getQuery(true) - ->select('template') - ->from($db->quoteName('#__template_styles')) - ->where($db->quoteName('id') . ' = ' . (int) $adminstyle) - ->where($db->quoteName('client_id') . ' = 1'); - - $template = $db->setQuery($query)->loadResult(); - - // The current user uses hathor - if ($template == 'hathor') - { - $user->setParam('admin_style', $isisStyleId['0']); - $user->save(); - } - } - - // We can only do that if you have edit permissions in com_templates - if ($user->authorise('core.edit.state', 'com_templates')) - { - $query = $db->getQuery(true) - ->update($db->quoteName('#__template_styles')) - ->set($db->quoteName('home') . ' = ' . $db->quote('0')) - ->where($db->quoteName('template') . ' = "hathor"') - ->where($db->quoteName('client_id') . ' = 1'); - - // Execute - $db->setQuery($query)->execute(); - - $query = $db->getQuery(true) - ->update($db->quoteName('#__template_styles')) - ->set($db->quoteName('home') . ' = ' . $db->quote('1')) - ->where($db->quoteName('template') . ' = "isis"') - ->where($db->quoteName('client_id') . ' = 1') - ->where($db->quoteName('id') . ' = ' . $isisStyleId[0]); - - // Execute - $db->setQuery($query)->execute(); - } - - // The postinstall component load the language to late... so we need to make sure it is loaded here. - JFactory::getLanguage()->load('tpl_hathor', JPATH_ADMINISTRATOR, null, false, true); - - // Template was successfully changed to isis - JFactory::getApplication()->enqueueMessage(JText::sprintf('TPL_HATHOR_CHANGED_DEFAULT_TEMPLATE_TO_ISIS', $isisStyleName[0]), 'message'); -} diff --git a/administrator/templates/hathor/templateDetails.xml b/administrator/templates/hathor/templateDetails.xml deleted file mode 100644 index 1b3b7bba40977..0000000000000 --- a/administrator/templates/hathor/templateDetails.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - - hathor - May 2010 - Andrea Tarr - admin@joomla.org - Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. - GNU General Public License version 2 or later; see LICENSE.txt - 3.0.0 - TPL_HATHOR_XML_DESCRIPTION - - component.php - cpanel.php - error.php - favicon.ico - index.php - login.php - LICENSE.txt - templateDetails.xml - template_preview.png - template_thumbnail.png - css - html - images - js - language - - - - menu - submenu - toolbar - title - status - icon - cp_shell - cpanel - login - debug - footer - - - language/en-GB/en-GB.tpl_hathor.ini - language/en-GB/en-GB.tpl_hathor.sys.ini - - - -
          - - - - - - - - - - - - - - - - - - -
          -
          -
          -
          diff --git a/administrator/templates/hathor/template_preview.png b/administrator/templates/hathor/template_preview.png deleted file mode 100644 index be57da7cc5433..0000000000000 Binary files a/administrator/templates/hathor/template_preview.png and /dev/null differ diff --git a/administrator/templates/hathor/template_thumbnail.png b/administrator/templates/hathor/template_thumbnail.png deleted file mode 100644 index b9b2b49b88d51..0000000000000 Binary files a/administrator/templates/hathor/template_thumbnail.png and /dev/null differ diff --git a/administrator/templates/isis/component.php b/administrator/templates/isis/component.php deleted file mode 100644 index 863c9b2de8965..0000000000000 --- a/administrator/templates/isis/component.php +++ /dev/null @@ -1,59 +0,0 @@ -setHtml5(true); - -// Add JavaScript Frameworks -JHtml::_('bootstrap.framework'); - -// Add filter polyfill for IE8 -JHtml::_('behavior.polyfill', array('filter'), 'lte IE 9'); - -// Add template js -JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); - -// Add html5 shiv -JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); - -// Add Stylesheets -JHtml::_('stylesheet', 'template' . ($this->direction === 'rtl' ? '-rtl' : '') . '.css', array('version' => 'auto', 'relative' => true)); - -// Load optional RTL Bootstrap CSS -JHtml::_('bootstrap.loadCss', false, $this->direction); - -// Load specific language related CSS -JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); - -// Load custom.css -JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); - -// Link color -if ($this->params->get('linkColor')) -{ - $this->addStyleDeclaration('a { color: ' . $this->params->get('linkColor') . '; }'); -} -?> - - - - - - - - - - diff --git a/administrator/templates/isis/cpanel.php b/administrator/templates/isis/cpanel.php deleted file mode 100644 index 0560a23f67abe..0000000000000 --- a/administrator/templates/isis/cpanel.php +++ /dev/null @@ -1,12 +0,0 @@ - li, -ol.inline > li { - display: inline-block; - *display: inline; - *zoom: 1; - padding-left: 5px; - padding-right: 5px; -} -dl { - margin-bottom: 18px; -} -dt, -dd { - line-height: 18px; -} -dt { - font-weight: bold; -} -dd { - margin-left: 9px; -} -.dl-horizontal { - *zoom: 1; -} -.dl-horizontal:before, -.dl-horizontal:after { - display: table; - content: ""; - line-height: 0; -} -.dl-horizontal:after { - clear: both; -} -.dl-horizontal dt { - float: left; - width: 160px; - clear: left; - text-align: right; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.dl-horizontal dd { - margin-left: 180px; -} -hr { - margin: 18px 0; - border: 0; - border-top: 1px solid #eee; - border-bottom: 1px solid #fff; -} -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999; -} -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} -blockquote { - padding: 0 0 0 15px; - margin: 0 0 18px; - border-left: 5px solid #eee; -} -blockquote p { - margin-bottom: 0; - font-size: 16.25px; - font-weight: 300; - line-height: 1.25; -} -blockquote small { - display: block; - line-height: 18px; - color: #999; -} -blockquote small:before { - content: '\2014 \00A0'; -} -blockquote.pull-right { - float: right; - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eee; - border-left: 0; -} -blockquote.pull-right p, -blockquote.pull-right small { - text-align: right; -} -blockquote.pull-right small:before { - content: ''; -} -blockquote.pull-right small:after { - content: '\00A0 \2014'; -} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} -address { - display: block; - margin-bottom: 18px; - font-style: normal; - line-height: 18px; -} -code, -pre { - padding: 0 3px 2px; - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; - font-size: 11px; - color: #333; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -code { - padding: 2px 4px; - color: #d14; - background-color: #f7f7f9; - border: 1px solid #e1e1e8; - white-space: nowrap; -} -pre { - display: block; - padding: 8.5px; - margin: 0 0 9px; - font-size: 12px; - line-height: 18px; - word-break: break-all; - word-wrap: break-word; - white-space: pre; - white-space: pre-wrap; - background-color: #f5f5f5; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,0.15); - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -pre.prettyprint { - margin-bottom: 18px; -} -pre code { - padding: 0; - color: inherit; - white-space: pre; - white-space: pre-wrap; - background-color: transparent; - border: 0; -} -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} -form { - margin: 0 0 18px; -} -fieldset { - padding: 0; - margin: 0; - border: 0; -} -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 18px; - font-size: 19.5px; - line-height: 36px; - color: #333; - border: 0; - border-bottom: 1px solid #e5e5e5; -} -legend small { - font-size: 13.5px; - color: #999; -} -label, -input, -button, -select, -textarea { - font-size: 13px; - font-weight: normal; - line-height: 18px; -} -input, -button, -select, -textarea { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -} -label { - display: block; - margin-bottom: 5px; -} -select, -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - display: inline-block; - height: 18px; - padding: 4px 6px; - margin-bottom: 9px; - font-size: 13px; - line-height: 18px; - color: #555; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - vertical-align: middle; -} -input, -textarea, -.uneditable-input { - width: 206px; -} -textarea { - height: auto; -} -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - background-color: #fff; - border: 1px solid #ccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -webkit-transition: border linear .2s, box-shadow linear .2s; - -moz-transition: border linear .2s, box-shadow linear .2s; - -o-transition: border linear .2s, box-shadow linear .2s; - transition: border linear .2s, box-shadow linear .2s; -} -textarea:focus, -input[type="text"]:focus, -input[type="password"]:focus, -input[type="datetime"]:focus, -input[type="datetime-local"]:focus, -input[type="date"]:focus, -input[type="month"]:focus, -input[type="time"]:focus, -input[type="week"]:focus, -input[type="number"]:focus, -input[type="email"]:focus, -input[type="url"]:focus, -input[type="search"]:focus, -input[type="tel"]:focus, -input[type="color"]:focus, -.uneditable-input:focus { - border-color: rgba(82,168,236,0.8); - outline: 0; - outline: thin dotted \9; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); -} -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - *margin-top: 0; - margin-top: 1px \9; - line-height: normal; -} -input[type="file"], -input[type="image"], -input[type="submit"], -input[type="reset"], -input[type="button"], -input[type="radio"], -input[type="checkbox"] { - width: auto; -} -select, -input[type="file"] { - height: 28px; - *margin-top: 4px; - line-height: 28px; -} -select { - width: 220px; - border: 1px solid #ccc; - background-color: #fff; -} -select[multiple], -select[size] { - height: auto; -} -select:focus, -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.uneditable-input, -.uneditable-textarea { - color: #999; - background-color: #fcfcfc; - border-color: #ccc; - -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); - -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); - box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); - cursor: not-allowed; -} -.uneditable-input { - overflow: hidden; - white-space: nowrap; -} -.uneditable-textarea { - width: auto; - height: auto; -} -input:-moz-placeholder, -textarea:-moz-placeholder { - color: #999; -} -input:-ms-input-placeholder, -textarea:-ms-input-placeholder { - color: #999; -} -input::-webkit-input-placeholder, -textarea::-webkit-input-placeholder { - color: #999; -} -.radio, -.checkbox { - min-height: 18px; - padding-left: 20px; -} -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: left; - margin-left: -20px; -} -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 5px; -} -.radio.inline, -.checkbox.inline { - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} -.radio.inline + .radio.inline, -.checkbox.inline + .checkbox.inline { - margin-left: 10px; -} -.input-mini { - width: 60px; -} -.input-small { - width: 90px; -} -.input-medium { - width: 150px; -} -.input-large { - width: 210px; -} -.input-xlarge { - width: 270px; -} -.input-xxlarge { - width: 530px; -} -input[class*="span"], -select[class*="span"], -textarea[class*="span"], -.uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"] { - float: none; - margin-left: 0; -} -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} -input, -textarea, -.uneditable-input { - margin-left: 0; -} -.controls-row [class*="span"] + [class*="span"] { - margin-left: 20px; -} -input.span12, -textarea.span12, -.uneditable-input.span12 { - width: 926px; -} -input.span11, -textarea.span11, -.uneditable-input.span11 { - width: 846px; -} -input.span10, -textarea.span10, -.uneditable-input.span10 { - width: 766px; -} -input.span9, -textarea.span9, -.uneditable-input.span9 { - width: 686px; -} -input.span8, -textarea.span8, -.uneditable-input.span8 { - width: 606px; -} -input.span7, -textarea.span7, -.uneditable-input.span7 { - width: 526px; -} -input.span6, -textarea.span6, -.uneditable-input.span6 { - width: 446px; -} -input.span5, -textarea.span5, -.uneditable-input.span5 { - width: 366px; -} -input.span4, -textarea.span4, -.uneditable-input.span4 { - width: 286px; -} -input.span3, -textarea.span3, -.uneditable-input.span3 { - width: 206px; -} -input.span2, -textarea.span2, -.uneditable-input.span2 { - width: 126px; -} -input.span1, -textarea.span1, -.uneditable-input.span1 { - width: 46px; -} -.controls-row { - *zoom: 1; -} -.controls-row:before, -.controls-row:after { - display: table; - content: ""; - line-height: 0; -} -.controls-row:after { - clear: both; -} -.controls-row [class*="span"], -.row-fluid .controls-row [class*="span"] { - float: left; -} -.controls-row .checkbox[class*="span"], -.controls-row .radio[class*="span"] { - padding-top: 5px; -} -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - cursor: not-allowed; - background-color: #eee; -} -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"][readonly], -input[type="checkbox"][readonly] { - background-color: transparent; -} -.control-group.warning .control-label, -.control-group.warning .help-block, -.control-group.warning .help-inline { - color: #8a6d3b; -} -.control-group.warning .checkbox, -.control-group.warning .radio, -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - color: #8a6d3b; -} -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - border-color: #8a6d3b; -} -.control-group.warning input:focus, -.control-group.warning select:focus, -.control-group.warning textarea:focus { - border-color: #66512c; -} -.control-group.warning .input-prepend .add-on, -.control-group.warning .input-append .add-on { - color: #8a6d3b; - background-color: #fcf8e3; - border-color: #8a6d3b; -} -.control-group.error .control-label, -.control-group.error .help-block, -.control-group.error .help-inline { - color: #a94442; -} -.control-group.error .checkbox, -.control-group.error .radio, -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - color: #a94442; -} -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - border-color: #a94442; -} -.control-group.error input:focus, -.control-group.error select:focus, -.control-group.error textarea:focus { - border-color: #843534; -} -.control-group.error .input-prepend .add-on, -.control-group.error .input-append .add-on { - color: #a94442; - background-color: #f2dede; - border-color: #a94442; -} -.control-group.success .control-label, -.control-group.success .help-block, -.control-group.success .help-inline { - color: #3c763d; -} -.control-group.success .checkbox, -.control-group.success .radio, -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - color: #3c763d; -} -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - border-color: #3c763d; -} -.control-group.success input:focus, -.control-group.success select:focus, -.control-group.success textarea:focus { - border-color: #2b542c; -} -.control-group.success .input-prepend .add-on, -.control-group.success .input-append .add-on { - color: #3c763d; - background-color: #dff0d8; - border-color: #3c763d; -} -.control-group.info .control-label, -.control-group.info .help-block, -.control-group.info .help-inline { - color: #31708f; -} -.control-group.info .checkbox, -.control-group.info .radio, -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - color: #31708f; -} -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - border-color: #31708f; -} -.control-group.info input:focus, -.control-group.info select:focus, -.control-group.info textarea:focus { - border-color: #245269; -} -.control-group.info .input-prepend .add-on, -.control-group.info .input-append .add-on { - color: #31708f; - background-color: #d9edf7; - border-color: #31708f; -} -input:focus:invalid, -textarea:focus:invalid, -select:focus:invalid { - color: #b94a48; - border-color: #ee5f5b; -} -input:focus:invalid:focus, -textarea:focus:invalid:focus, -select:focus:invalid:focus { - border-color: #e9322d; - -webkit-box-shadow: 0 0 6px #f8b9b7; - -moz-box-shadow: 0 0 6px #f8b9b7; - box-shadow: 0 0 6px #f8b9b7; -} -.form-actions { - padding: 17px 20px 18px; - margin-top: 18px; - margin-bottom: 18px; - background-color: #F0F0F0; - border-top: 1px solid #e5e5e5; - *zoom: 1; -} -.form-actions:before, -.form-actions:after { - display: table; - content: ""; - line-height: 0; -} -.form-actions:after { - clear: both; -} -.help-block, -.help-inline { - color: #595959; -} -.help-block { - display: block; - margin-bottom: 9px; -} -.help-inline { - display: inline-block; - *display: inline; - *zoom: 1; - vertical-align: middle; - padding-left: 5px; -} -.input-append, -.input-prepend { - display: inline-block; - margin-bottom: 9px; - vertical-align: middle; - font-size: 0; - white-space: nowrap; -} -.input-append input, -.input-append select, -.input-append .uneditable-input, -.input-append .dropdown-menu, -.input-append .popover, -.input-prepend input, -.input-prepend select, -.input-prepend .uneditable-input, -.input-prepend .dropdown-menu, -.input-prepend .popover { - font-size: 13px; -} -.input-append input, -.input-append select, -.input-append .uneditable-input, -.input-prepend input, -.input-prepend select, -.input-prepend .uneditable-input { - position: relative; - margin-bottom: 0; - *margin-left: 0; - vertical-align: top; - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-append input:focus, -.input-append select:focus, -.input-append .uneditable-input:focus, -.input-prepend input:focus, -.input-prepend select:focus, -.input-prepend .uneditable-input:focus { - z-index: 2; -} -.input-append .add-on, -.input-prepend .add-on { - display: inline-block; - width: auto; - height: 18px; - min-width: 16px; - padding: 4px 5px; - font-size: 13px; - font-weight: normal; - line-height: 18px; - text-align: center; - text-shadow: 0 1px 0 #fff; - background-color: #eee; - border: 1px solid #ccc; -} -.input-append .add-on, -.input-append .btn, -.input-append .btn-group > .dropdown-toggle, -.input-prepend .add-on, -.input-prepend .btn, -.input-prepend .btn-group > .dropdown-toggle { - vertical-align: top; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.input-prepend .add-on, -.input-prepend .btn { - margin-right: -1px; -} -.input-prepend .add-on:first-child, -.input-prepend .btn:first-child { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-append input, -.input-append select, -.input-append .uneditable-input { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-append input + .btn-group .btn:last-child, -.input-append select + .btn-group .btn:last-child, -.input-append .uneditable-input + .btn-group .btn:last-child { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-append .add-on, -.input-append .btn, -.input-append .btn-group { - margin-left: -1px; -} -.input-append .add-on:last-child, -.input-append .btn:last-child, -.input-append .btn-group:last-child > .dropdown-toggle { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend.input-append input, -.input-prepend.input-append select, -.input-prepend.input-append .uneditable-input { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.input-prepend.input-append input + .btn-group .btn, -.input-prepend.input-append select + .btn-group .btn, -.input-prepend.input-append .uneditable-input + .btn-group .btn { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend.input-append .add-on:first-child, -.input-prepend.input-append .btn:first-child { - margin-right: -1px; - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-prepend.input-append .add-on:last-child, -.input-prepend.input-append .btn:last-child { - margin-left: -1px; - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend.input-append .btn-group:first-child { - margin-left: 0; -} -input.search-query { - padding-right: 14px; - padding-right: 4px \9; - padding-left: 14px; - padding-left: 4px \9; - margin-bottom: 0; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -.form-search .input-append .search-query, -.form-search .input-prepend .search-query { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.form-search .input-append .search-query { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} -.form-search .input-append .btn { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} -.form-search .input-prepend .search-query { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} -.form-search .input-prepend .btn { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} -.js-stools-field-filter .input-prepend, -.js-stools-field-filter .input-append { - margin-bottom: 0; -} -.form-search input, -.form-search textarea, -.form-search select, -.form-search .help-inline, -.form-search .uneditable-input, -.form-search .input-prepend, -.form-search .input-append, -.form-inline input, -.form-inline textarea, -.form-inline select, -.form-inline .help-inline, -.form-inline .uneditable-input, -.form-inline .input-prepend, -.form-inline .input-append, -.form-horizontal input, -.form-horizontal textarea, -.form-horizontal select, -.form-horizontal .help-inline, -.form-horizontal .uneditable-input, -.form-horizontal .input-prepend, -.form-horizontal .input-append { - display: inline-block; - *display: inline; - *zoom: 1; - margin-bottom: 0; - vertical-align: middle; -} -.form-search .hide, -.form-inline .hide, -.form-horizontal .hide { - display: none; -} -.form-search label, -.form-inline label, -.form-search .btn-group, -.form-inline .btn-group { - display: inline-block; -} -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - padding-left: 0; - margin-bottom: 0; - vertical-align: middle; -} -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: left; - margin-right: 3px; - margin-left: 0; -} -.control-group { - margin-bottom: 9px; -} -legend + .control-group { - margin-top: 18px; - -webkit-margin-top-collapse: separate; -} -.form-horizontal .control-group { - margin-bottom: 18px; - *zoom: 1; -} -.form-horizontal .control-group:before, -.form-horizontal .control-group:after { - display: table; - content: ""; - line-height: 0; -} -.form-horizontal .control-group:after { - clear: both; -} -.form-horizontal .control-label { - float: left; - width: 160px; - padding-top: 5px; - text-align: right; -} -.form-horizontal .controls { - *display: inline-block; - *padding-left: 20px; - margin-left: 180px; - *margin-left: 0; -} -.form-horizontal .controls:first-child { - *padding-left: 180px; -} -.form-horizontal .help-block { - margin-bottom: 0; -} -.form-horizontal input + .help-block, -.form-horizontal select + .help-block, -.form-horizontal textarea + .help-block, -.form-horizontal .uneditable-input + .help-block, -.form-horizontal .input-prepend + .help-block, -.form-horizontal .input-append + .help-block { - margin-top: 9px; -} -.form-horizontal .form-actions { - padding-left: 180px; -} -.control-label .hasPopover, -.control-label .hasTooltip { - display: inline-block; -} -.subform-repeatable-wrapper .btn-group>.btn.button { - min-width: 0; -} -.subform-repeatable-wrapper .ui-sortable-helper { - background: #fff; -} -.subform-repeatable-wrapper tr.ui-sortable-helper { - display: table; -} -@media (min-width: 980px) and (max-width: 1215px) { - .float-cols .control-label { - float: none; - } - .float-cols .controls { - margin-left: 0; - } -} -table { - max-width: 100%; - background-color: transparent; - border-collapse: collapse; - border-spacing: 0; -} -.table { - width: 100%; - margin-bottom: 18px; -} -.table th, -.table td { - padding: 8px; - line-height: 18px; - text-align: left; - vertical-align: top; - border-top: 1px solid #ddd; -} -.table th { - font-weight: bold; -} -.table thead th { - vertical-align: bottom; -} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; -} -.table tbody + tbody { - border-top: 2px solid #ddd; -} -.table .table { - background-color: #fff; -} -.table-condensed th, -.table-condensed td { - padding: 4px 5px; -} -.table-bordered { - border: 1px solid #ddd; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.table-bordered th, -.table-bordered td { - border-left: 1px solid #ddd; -} -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; -} -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; -} -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; -} -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; - border-bottom-left-radius: 0; -} -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; - border-bottom-right-radius: 0; -} -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; -} -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; -} -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: #f9f9f9; -} -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: #F0F0F0; -} -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; -} -.table td.span1, -.table th.span1 { - float: none; - width: 44px; - margin-left: 0; -} -.table td.span2, -.table th.span2 { - float: none; - width: 124px; - margin-left: 0; -} -.table td.span3, -.table th.span3 { - float: none; - width: 204px; - margin-left: 0; -} -.table td.span4, -.table th.span4 { - float: none; - width: 284px; - margin-left: 0; -} -.table td.span5, -.table th.span5 { - float: none; - width: 364px; - margin-left: 0; -} -.table td.span6, -.table th.span6 { - float: none; - width: 444px; - margin-left: 0; -} -.table td.span7, -.table th.span7 { - float: none; - width: 524px; - margin-left: 0; -} -.table td.span8, -.table th.span8 { - float: none; - width: 604px; - margin-left: 0; -} -.table td.span9, -.table th.span9 { - float: none; - width: 684px; - margin-left: 0; -} -.table td.span10, -.table th.span10 { - float: none; - width: 764px; - margin-left: 0; -} -.table td.span11, -.table th.span11 { - float: none; - width: 844px; - margin-left: 0; -} -.table td.span12, -.table th.span12 { - float: none; - width: 924px; - margin-left: 0; -} -.table tbody tr.success > td { - background-color: #dff0d8; -} -.table tbody tr.error > td { - background-color: #f2dede; -} -.table tbody tr.warning > td { - background-color: #fcf8e3; -} -.table tbody tr.info > td { - background-color: #d9edf7; -} -.table-hover tbody tr.success:hover > td { - background-color: #d0e9c6; -} -.table-hover tbody tr.error:hover > td { - background-color: #ebcccc; -} -.table-hover tbody tr.warning:hover > td { - background-color: #faf2cc; -} -.table-hover tbody tr.info:hover > td { - background-color: #c4e3f3; -} -.table-noheader { - border-collapse: collapse; -} -.table-noheader thead { - display: none; -} -.dropup, -.dropdown { - position: relative; -} -.dropdown-toggle { - *margin-bottom: -3px; -} -.dropdown-toggle:active, -.open .dropdown-toggle { - outline: 0; -} -.caret { - display: inline-block; - width: 0; - height: 0; - vertical-align: top; - border-top: 4px solid #000; - border-right: 4px solid transparent; - border-left: 4px solid transparent; - content: ""; -} -.dropdown .caret { - margin-top: 8px; - margin-left: 2px; -} -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,0.2); - *border-right-width: 2px; - *border-bottom-width: 2px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); - -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); - box-shadow: 0 5px 10px rgba(0,0,0,0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} -.dropdown-menu.pull-right { - right: 0; - left: auto; -} -.dropdown-menu .divider { - *width: 100%; - height: 1px; - margin: 8px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #F0F0F0; - border-bottom: 1px solid #fff; -} -.dropdown-menu .menuitem-group { - margin: 4px 1px; - overflow: hidden; - border-top: 1px solid #eee; - border-bottom: 1px solid #eee; - background-color: #eee; - color: #555; - text-transform: capitalize; - font-size: 95%; - padding: 3px 20px; -} -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 18px; - color: #333; - white-space: nowrap; -} -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-submenu:hover > a, -.dropdown-submenu:focus > a { - text-decoration: none; - color: #fff; - background-color: #2d6ca2; - background-image: -moz-linear-gradient(top,#3071a9,#2a6496); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#3071a9),to(#2a6496)); - background-image: -webkit-linear-gradient(top,#3071a9,#2a6496); - background-image: -o-linear-gradient(top,#3071a9,#2a6496); - background-image: linear-gradient(to bottom,#3071a9,#2a6496); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f70a9', endColorstr='#ff296395', GradientType=0); -} -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #333; - text-decoration: none; - outline: 0; - background-color: #2d6ca2; - background-image: -moz-linear-gradient(top,#3071a9,#2a6496); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#3071a9),to(#2a6496)); - background-image: -webkit-linear-gradient(top,#3071a9,#2a6496); - background-image: -o-linear-gradient(top,#3071a9,#2a6496); - background-image: linear-gradient(to bottom,#3071a9,#2a6496); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f70a9', endColorstr='#ff296395', GradientType=0); -} -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #999; -} -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - cursor: default; -} -.open { - *z-index: 1000; -} -.open > .dropdown-menu { - display: block; -} -.dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: 990; -} -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0; - border-bottom: 4px solid #000; - content: ""; -} -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; -} -.dropdown-submenu { - position: relative; -} -.dropdown-submenu > .dropdown-menu { - top: 0; - left: 100%; - margin-top: -6px; - margin-left: -1px; - -webkit-border-radius: 6px 6px 6px 6px; - -moz-border-radius: 6px 6px 6px 6px; - border-radius: 6px 6px 6px 6px; -} -.dropdown-submenu:hover > .dropdown-menu { - display: block; -} -.dropup .dropdown-submenu > .dropdown-menu { - top: auto; - bottom: 0; - margin-top: 0; - margin-bottom: -2px; - -webkit-border-radius: 5px 5px 5px 0; - -moz-border-radius: 5px 5px 5px 0; - border-radius: 5px 5px 5px 0; -} -.dropdown-submenu > a:after { - display: block; - content: " "; - float: right; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; - border-width: 5px 0 5px 5px; - border-left-color: #cccccc; - margin-top: 5px; - margin-right: -10px; -} -.dropdown-submenu:hover > a:after { - border-left-color: #fff; -} -.dropdown-submenu.pull-left { - float: none; -} -.dropdown-submenu.pull-left > .dropdown-menu { - left: -100%; - margin-left: 10px; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} -.dropdown .dropdown-menu .nav-header { - padding-left: 20px; - padding-right: 20px; -} -.typeahead { - z-index: 1051; - margin-top: 2px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #F0F0F0; - border: 1px solid #F0F0F0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.well blockquote { - border-color: #f0f0f0; - border-color: rgba(0,0,0,0.15); -} -.well-large { - padding: 24px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.well-small { - padding: 9px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.fade { - opacity: 0; - -webkit-transition: opacity .15s linear; - -moz-transition: opacity .15s linear; - -o-transition: opacity .15s linear; - transition: opacity .15s linear; -} -.fade.in { - opacity: 1; -} -.collapse { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition: height .35s ease; - -moz-transition: height .35s ease; - -o-transition: height .35s ease; - transition: height .35s ease; -} -.collapse.in { - height: auto; -} -.close { - float: right; - font-size: 20px; - font-weight: bold; - line-height: 18px; - color: #000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} -.close:hover, -.close:focus { - color: #000; - text-decoration: none; - cursor: pointer; - opacity: 0.4; - filter: alpha(opacity=40); -} -button.close { - padding: 3; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} -.alert-options { - float: right; - line-height: 18px; - color: #000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} -.alert-options:hover, -.alert-options:focus { - color: #000; - text-decoration: none; - cursor: pointer; - opacity: 0.4; - filter: alpha(opacity=40); -} -.btn { - display: inline-block; - *display: inline; - *zoom: 1; - padding: 4px 12px; - margin-bottom: 0; - font-size: 13px; - line-height: 18px; - text-align: center; - vertical-align: middle; - cursor: pointer; - background-color: #f3f3f3; - color: #333; - border: 1px solid #b3b3b3; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - box-shadow: 0 1px 2px rgba(0,0,0,0.05); -} -.btn:hover, -.btn:focus { - background-color: #e6e6e6; - text-decoration: none; - text-shadow: none; -} -.btn:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.btn.active, -.btn:active { - background-image: none; - outline: 0; -} -.btn.disabled, -.btn[disabled] { - cursor: default; - background-image: none; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.btn-large { - padding: 11px 19px; - font-size: 16.25px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.btn-large [class^="icon-"], -.btn-large [class*=" icon-"] { - margin-top: 4px; -} -.btn-small { - padding: 2px 10px; - font-size: 12px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.btn-small [class^="icon-"], -.btn-small [class*=" icon-"] { - margin-top: 0; -} -.btn-mini [class^="icon-"], -.btn-mini [class*=" icon-"] { - margin-top: -1px; -} -.btn-mini { - padding: 0 6px; - font-size: 9.75px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.btn-block { - display: block; - width: 100%; - padding-left: 0; - padding-right: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.btn-block + .btn-block { - margin-top: 5px; -} -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} -.btn-primary, -.btn-warning, -.btn-danger, -.btn-success, -.btn-info, -.btn-inverse { - box-shadow: 0 1px 2px rgba(0,0,0,0.05); -} -.btn-primary { - border: 1px solid #15497c; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #2384d3; -} -.btn-primary:hover, -.btn-primary:focus { - background-color: #185b91; - color: #fff; - text-decoration: none; -} -.btn-warning { - border: 1px solid #f89406; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #f89406; -} -.btn-warning:hover, -.btn-warning:focus { - background-color: #ad6704; - color: #fff; - text-decoration: none; - text-shadow: none; -} -.btn-danger { - border: 1px solid #bd362f; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #bd362f; -} -.btn-danger:hover, -.btn-danger:focus { - background-color: #802420; - color: #fff; - text-decoration: none; -} -.btn-success { - border: 1px solid #378137; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #46a546; -} -.btn-success:hover, -.btn-success:focus { - background-color: #2f6f2f; - color: #fff; - text-decoration: none; -} -.btn-info { - border: 1px solid #2f96b4; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #2f96b4; -} -.btn-info:hover, -.btn-info:focus { - background-color: #1f6377; - color: #fff; - text-decoration: none; -} -.btn-inverse { - border: 1px solid #444; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #444; -} -.btn-inverse:hover, -.btn-inverse:focus { - background-color: #1e1e1e; - color: #fff; - text-decoration: none; -} -button.btn, -input[type="submit"].btn { - *padding-top: 3px; - *padding-bottom: 3px; -} -button.btn::-moz-focus-inner, -input[type="submit"].btn::-moz-focus-inner { - padding: 0; - border: 0; -} -button.btn.btn-large, -input[type="submit"].btn.btn-large { - *padding-top: 7px; - *padding-bottom: 7px; -} -button.btn.btn-small, -input[type="submit"].btn.btn-small { - *padding-top: 3px; - *padding-bottom: 3px; -} -button.btn.btn-mini, -input[type="submit"].btn.btn-mini { - *padding-top: 1px; - *padding-bottom: 1px; -} -.btn-link, -.btn-link:active, -.btn-link[disabled] { - background-color: transparent; - background-image: none; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.btn-link { - border-color: transparent; - cursor: pointer; - color: #3071a9; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.btn-link:hover, -.btn-link:focus { - color: #1f496e; - text-decoration: underline; - background-color: transparent; -} -.btn-link[disabled]:hover, -.btn-link[disabled]:focus { - color: #333; - text-decoration: none; -} -.btn-group { - position: relative; - display: inline-block; - *display: inline; - *zoom: 1; - font-size: 0; - vertical-align: middle; - white-space: nowrap; - *margin-left: .3em; -} -.btn-group:first-child { - *margin-left: 0; -} -.btn-group .btn + .btn { - margin-left: -1px; -} -.btn-group + .btn-group { - margin-left: 5px; -} -.btn-toolbar { - font-size: 0; - margin-top: 9px; - margin-bottom: 9px; -} -.btn-toolbar > .btn + .btn, -.btn-toolbar > .btn-group + .btn, -.btn-toolbar > .btn + .btn-group { - margin-left: 5px; -} -.btn-group > .btn { - position: relative; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.btn-group > .btn-micro { - margin-left: -1px; -} -.btn-group > .btn, -.btn-group > .dropdown-menu, -.btn-group > .popover { - font-size: 13px; -} -.btn-group > .btn-mini { - font-size: 9.75px; -} -.btn-group > .btn-small { - font-size: 12px; -} -.btn-group > .btn-large { - font-size: 16.25px; -} -.btn-group > .btn:first-child { - margin-left: 0; - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.btn-group > .btn:last-child, -.btn-group > .dropdown-toggle { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.btn-group > .btn.large:first-child { - margin-left: 0; - -webkit-border-top-left-radius: 6px; - -moz-border-radius-topleft: 6px; - border-top-left-radius: 6px; - -webkit-border-bottom-left-radius: 6px; - -moz-border-radius-bottomleft: 6px; - border-bottom-left-radius: 6px; -} -.btn-group > .btn.large:last-child, -.btn-group > .large.dropdown-toggle { - -webkit-border-top-right-radius: 6px; - -moz-border-radius-topright: 6px; - border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - -moz-border-radius-bottomright: 6px; - border-bottom-right-radius: 6px; -} -.btn-group > .btn:hover, -.btn-group > .btn:focus, -.btn-group > .btn:active, -.btn-group > .btn.active { - z-index: 2; -} -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; - *padding-top: 5px; - *padding-bottom: 5px; -} -.btn-group > .btn-mini + .dropdown-toggle { - padding-left: 5px; - padding-right: 5px; - *padding-top: 2px; - *padding-bottom: 2px; -} -.btn-group > .btn-small + .dropdown-toggle { - *padding-top: 5px; - *padding-bottom: 4px; -} -.btn-group > .btn-large + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; - *padding-top: 7px; - *padding-bottom: 7px; -} -.btn-group.open .dropdown-toggle { - background-image: none; -} -.btn-group.open .btn.dropdown-toggle { - background-color: #e6e6e6; -} -.btn-group.open .btn-primary.dropdown-toggle { - background-color: #15497c; -} -.btn-group.open .btn-warning.dropdown-toggle { - background-color: #c67605; -} -.btn-group.open .btn-danger.dropdown-toggle { - background-color: #942a25; -} -.btn-group.open .btn-success.dropdown-toggle { - background-color: #378137; -} -.btn-group.open .btn-info.dropdown-toggle { - background-color: #24748c; -} -.btn-group.open .btn-inverse.dropdown-toggle { - background-color: #222; -} -.btn .caret { - margin-top: 8px; - margin-left: 0; -} -.btn-large .caret { - margin-top: 6px; -} -.btn-large .caret { - border-left-width: 5px; - border-right-width: 5px; - border-top-width: 5px; -} -.btn-mini .caret, -.btn-small .caret { - margin-top: 8px; -} -.dropup .btn-large .caret { - border-bottom-width: 5px; -} -.btn-primary .caret { - border-top-color: #1f496e; - border-bottom-color: #1f496e; -} -.btn-warning .caret, -.btn-danger .caret, -.btn-info .caret, -.btn-success .caret, -.btn-inverse .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.btn-group-vertical { - display: inline-block; - *display: inline; - *zoom: 1; -} -.btn-group-vertical > .btn { - display: block; - float: none; - max-width: 100%; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.btn-group-vertical > .btn + .btn { - margin-left: 0; - margin-top: -1px; -} -.btn-group-vertical > .btn:first-child { - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; -} -.btn-group-vertical > .btn:last-child { - -webkit-border-radius: 0 0 3px 3px; - -moz-border-radius: 0 0 3px 3px; - border-radius: 0 0 3px 3px; -} -.btn-group-vertical > .btn-large:first-child { - -webkit-border-radius: 6px 6px 0 0; - -moz-border-radius: 6px 6px 0 0; - border-radius: 6px 6px 0 0; -} -.btn-group-vertical > .btn-large:last-child { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} -.alert { - padding: 8px 35px 8px 14px; - margin-bottom: 18px; - text-shadow: 0 1px 0 rgba(255,255,255,0.5); - background-color: #fcf8e3; - border: 1px solid #faebcc; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.alert, -.alert h4 { - color: #8a6d3b; -} -.alert h4 { - margin: 0 0 .5em; -} -.alert .close { - position: relative; - top: -2px; - right: -21px; - line-height: 18px; - cursor: pointer; -} -.alert-success { - background-color: #dff0d8; - border-color: #d6e9c6; - color: #3c763d; -} -.alert-success h4 { - color: #3c763d; -} -.alert-danger, -.alert-error { - background-color: #f2dede; - border-color: #ebccd1; - color: #a94442; -} -.alert-danger h4, -.alert-error h4 { - color: #a94442; -} -.alert-info { - background-color: #d9edf7; - border-color: #bce8f1; - color: #31708f; -} -.alert-info h4 { - color: #31708f; -} -.alert-block { - padding-top: 14px; - padding-bottom: 14px; -} -.alert-block > p, -.alert-block > ul { - margin-bottom: 0; -} -.alert-block p + p { - margin-top: 5px; -} -.nav { - margin-left: 0; - margin-bottom: 18px; - list-style: none; -} -.nav > li > a { - display: block; -} -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #eee; -} -.nav > li > a > img { - max-width: none; -} -.nav > .pull-right { - float: right; -} -.nav-header { - display: block; - padding: 3px 15px; - font-size: 11px; - font-weight: bold; - line-height: 18px; - color: #999; - text-shadow: 0 1px 0 rgba(255,255,255,0.5); - text-transform: uppercase; -} -.nav li + .nav-header { - margin-top: 9px; -} -.nav-list { - padding-left: 15px; - padding-right: 15px; - margin-bottom: 0; -} -.nav-list > li > a, -.nav-list .nav-header { - margin-left: -15px; - margin-right: -15px; - text-shadow: 0 1px 0 rgba(255,255,255,0.5); -} -.nav-list > li > a { - padding: 3px 15px; -} -.nav-list > .active > a, -.nav-list > .active > a:hover, -.nav-list > .active > a:focus { - color: #fff; - text-shadow: 0 -1px 0 rgba(0,0,0,0.2); - background-color: #3071a9; -} -.nav-list [class^="icon-"], -.nav-list [class*=" icon-"] { - margin-right: 2px; -} -.nav-list .divider { - *width: 100%; - height: 1px; - margin: 8px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #e5e5e5; - border-bottom: 1px solid #fff; -} -.nav-tabs, -.nav-pills { - *zoom: 1; -} -.nav-tabs:before, -.nav-tabs:after, -.nav-pills:before, -.nav-pills:after { - display: table; - content: ""; - line-height: 0; -} -.nav-tabs:after, -.nav-pills:after { - clear: both; -} -.nav-tabs > li, -.nav-pills > li { - float: left; -} -.nav-tabs > li > a, -.nav-pills > li > a { - padding-right: 12px; - padding-left: 12px; - margin-right: 2px; - line-height: 14px; -} -.nav-tabs { - border-bottom: 1px solid #ddd; -} -.nav-tabs > li { - margin-bottom: -1px; -} -.nav-tabs > li > a { - padding-top: 8px; - padding-bottom: 8px; - line-height: 18px; - border: 1px solid transparent; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} -.nav-tabs > li > a:hover, -.nav-tabs > li > a:focus { - border-color: #eee #eee #ddd; -} -.nav-tabs > .active > a, -.nav-tabs > .active > a:hover, -.nav-tabs > .active > a:focus { - color: #555; - background-color: #fff; - border: 1px solid #ddd; - border-bottom-color: transparent; - cursor: default; -} -.nav-pills > li > a { - padding-top: 8px; - padding-bottom: 8px; - margin-top: 2px; - margin-bottom: 2px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.nav-pills > .active > a, -.nav-pills > .active > a:hover, -.nav-pills > .active > a:focus { - color: #fff; - background-color: #3071a9; -} -.nav-stacked > li { - float: none; -} -.nav-stacked > li > a { - margin-right: 0; -} -.nav-tabs.nav-stacked { - border-bottom: 0; -} -.nav-tabs.nav-stacked > li > a { - border: 1px solid #ddd; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.nav-tabs.nav-stacked > li:first-child > a { - -webkit-border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; - border-top-right-radius: 4px; - -webkit-border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; - border-top-left-radius: 4px; -} -.nav-tabs.nav-stacked > li:last-child > a { - -webkit-border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; - border-bottom-right-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - border-bottom-left-radius: 4px; -} -.nav-tabs.nav-stacked > li > a:hover, -.nav-tabs.nav-stacked > li > a:focus { - border-color: #ddd; - z-index: 2; -} -.nav-pills.nav-stacked > li > a { - margin-bottom: 3px; -} -.nav-pills.nav-stacked > li:last-child > a { - margin-bottom: 1px; -} -.nav-tabs .dropdown-menu { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} -.nav-pills .dropdown-menu { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.nav .dropdown-toggle .caret { - border-top-color: #3071a9; - border-bottom-color: #3071a9; - margin-top: 6px; -} -.nav .dropdown-toggle:hover .caret, -.nav .dropdown-toggle:focus .caret { - border-top-color: #1f496e; - border-bottom-color: #1f496e; -} -.nav-tabs .dropdown-toggle .caret { - margin-top: 8px; -} -.nav .active .dropdown-toggle .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.nav-tabs .active .dropdown-toggle .caret { - border-top-color: #555; - border-bottom-color: #555; -} -.nav > .dropdown.active > a:hover, -.nav > .dropdown.active > a:focus { - cursor: pointer; -} -.nav-tabs .open .dropdown-toggle, -.nav-pills .open .dropdown-toggle, -.nav > li.dropdown.open.active > a:hover, -.nav > li.dropdown.open.active > a:focus { - color: #fff; - background-color: #999; - border-color: #999; -} -.nav li.dropdown.open .caret, -.nav li.dropdown.open.active .caret, -.nav li.dropdown.open a:hover .caret, -.nav li.dropdown.open a:focus .caret { - border-top-color: #fff; - border-bottom-color: #fff; - opacity: 1; - filter: alpha(opacity=100); -} -.tabs-stacked .open > a:hover, -.tabs-stacked .open > a:focus { - border-color: #999; -} -.tabbable { - *zoom: 1; -} -.tabbable:before, -.tabbable:after { - display: table; - content: ""; - line-height: 0; -} -.tabbable:after { - clear: both; -} -.tab-content { - overflow: auto; -} -.tabs-below > .nav-tabs, -.tabs-right > .nav-tabs, -.tabs-left > .nav-tabs { - border-bottom: 0; -} -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} -.tab-content > .active, -.pill-content > .active { - display: block; -} -.tabs-below > .nav-tabs { - border-top: 1px solid #ddd; -} -.tabs-below > .nav-tabs > li { - margin-top: -1px; - margin-bottom: 0; -} -.tabs-below > .nav-tabs > li > a { - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} -.tabs-below > .nav-tabs > li > a:hover, -.tabs-below > .nav-tabs > li > a:focus { - border-bottom-color: transparent; - border-top-color: #ddd; -} -.tabs-below > .nav-tabs > .active > a, -.tabs-below > .nav-tabs > .active > a:hover, -.tabs-below > .nav-tabs > .active > a:focus { - border-color: transparent #ddd #ddd #ddd; -} -.tabs-left > .nav-tabs > li, -.tabs-right > .nav-tabs > li { - float: none; -} -.tabs-left > .nav-tabs > li > a, -.tabs-right > .nav-tabs > li > a { - min-width: 74px; - margin-right: 0; - margin-bottom: 3px; -} -.tabs-left > .nav-tabs { - float: left; - margin-right: 19px; - border-right: 1px solid #ddd; -} -.tabs-left > .nav-tabs > li > a { - margin-right: -1px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} -.tabs-left > .nav-tabs > li > a:hover, -.tabs-left > .nav-tabs > li > a:focus { - border-color: #eee #ddd #eee #eee; -} -.tabs-left > .nav-tabs .active > a, -.tabs-left > .nav-tabs .active > a:hover, -.tabs-left > .nav-tabs .active > a:focus { - border-color: #ddd transparent #ddd #ddd; - *border-right-color: #fff; -} -.tabs-right > .nav-tabs { - float: right; - margin-left: 19px; - border-left: 1px solid #ddd; -} -.tabs-right > .nav-tabs > li > a { - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} -.tabs-right > .nav-tabs > li > a:hover, -.tabs-right > .nav-tabs > li > a:focus { - border-color: #eee #eee #eee #ddd; -} -.tabs-right > .nav-tabs .active > a, -.tabs-right > .nav-tabs .active > a:hover, -.tabs-right > .nav-tabs .active > a:focus { - border-color: #ddd #ddd #ddd transparent; - *border-left-color: #fff; -} -.nav > .disabled > a { - color: #999; -} -.nav > .disabled > a:hover, -.nav > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - cursor: default; -} -.navbar { - overflow: visible; - margin-bottom: 18px; - *position: relative; - *z-index: 2; -} -.navbar-inner { - min-height: 40px; - padding-left: 20px; - padding-right: 20px; - background-color: #fafafa; - background-image: -moz-linear-gradient(top,#ffffff,#f2f2f2); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#ffffff),to(#f2f2f2)); - background-image: -webkit-linear-gradient(top,#ffffff,#f2f2f2); - background-image: -o-linear-gradient(top,#ffffff,#f2f2f2); - background-image: linear-gradient(to bottom,#ffffff,#f2f2f2); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); - border: 1px solid #d4d4d4; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 4px rgba(0,0,0,0.065); - -moz-box-shadow: 0 1px 4px rgba(0,0,0,0.065); - box-shadow: 0 1px 4px rgba(0,0,0,0.065); - *zoom: 1; -} -.navbar-inner:before, -.navbar-inner:after { - display: table; - content: ""; - line-height: 0; -} -.navbar-inner:after { - clear: both; -} -.navbar .container { - width: auto; -} -.nav-collapse.collapse { - height: auto; - overflow: visible; -} -.navbar .brand { - float: left; - display: block; - padding: 11px 20px 11px; - margin-left: -20px; - font-size: 20px; - font-weight: 200; - color: #555; - text-shadow: 0 1px 0 #ffffff; -} -.navbar .brand:hover, -.navbar .brand:focus { - text-decoration: none; -} -.navbar-text { - margin-bottom: 0; - line-height: 40px; - color: #555; -} -.navbar-link { - color: #555; -} -.navbar-link:hover, -.navbar-link:focus { - color: #333; -} -.navbar .divider-vertical { - height: 40px; - margin: 0 9px; - border-left: 1px solid #f2f2f2; - border-right: 1px solid #ffffff; -} -.navbar .btn, -.navbar .btn-group { - margin-top: 5px; -} -.navbar .btn-group .btn, -.navbar .input-prepend .btn, -.navbar .input-append .btn, -.navbar .input-prepend .btn-group, -.navbar .input-append .btn-group { - margin-top: 0; -} -.navbar-form { - margin-bottom: 0; - *zoom: 1; -} -.navbar-form:before, -.navbar-form:after { - display: table; - content: ""; - line-height: 0; -} -.navbar-form:after { - clear: both; -} -.navbar-form input, -.navbar-form select, -.navbar-form .radio, -.navbar-form .checkbox { - margin-top: 5px; -} -.navbar-form input, -.navbar-form select, -.navbar-form .btn { - display: inline-block; - margin-bottom: 0; -} -.navbar-form input[type="image"], -.navbar-form input[type="checkbox"], -.navbar-form input[type="radio"] { - margin-top: 3px; -} -.navbar-form .input-append, -.navbar-form .input-prepend { - margin-top: 5px; - white-space: nowrap; -} -.navbar-form .input-append input, -.navbar-form .input-prepend input { - margin-top: 0; -} -.navbar-search { - position: relative; - float: left; - margin-top: 5px; - margin-bottom: 0; -} -.navbar-search .search-query { - margin-bottom: 0; - padding: 4px 14px; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: normal; - line-height: 1; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -.navbar-static-top { - position: static; - margin-bottom: 0; -} -.navbar-static-top .navbar-inner { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1030; - margin-bottom: 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - border-width: 0 0 1px; -} -.navbar-fixed-bottom .navbar-inner { - border-width: 1px 0 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-fixed-bottom .navbar-inner { - padding-left: 0; - padding-right: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - width: 940px; -} -.navbar-fixed-top { - top: 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1); - -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1); - box-shadow: 0 1px 10px rgba(0,0,0,.1); -} -.navbar-fixed-bottom { - bottom: 0; -} -.navbar-fixed-bottom .navbar-inner { - -webkit-box-shadow: 0 -1px 10px rgba(0,0,0,.1); - -moz-box-shadow: 0 -1px 10px rgba(0,0,0,.1); - box-shadow: 0 -1px 10px rgba(0,0,0,.1); -} -.navbar .nav { - position: relative; - left: 0; - display: block; - float: left; - margin: 0 10px 0 0; -} -.navbar .nav.pull-right { - float: right; - margin-right: 0; -} -.navbar .nav > li { - float: left; -} -.navbar .nav > li > a { - float: none; - padding: 11px 15px 11px; - color: #555; - text-decoration: none; - text-shadow: 0 1px 0 #ffffff; -} -.navbar .nav .dropdown-toggle .caret { - margin-top: 8px; -} -.navbar .nav > li > a:focus, -.navbar .nav > li > a:hover { - background-color: transparent; - color: #333; - text-decoration: none; -} -.navbar .nav > li > a:focus { - outline: 2px solid #5e9ed6; -} -.navbar .nav > .active > a, -.navbar .nav > .active > a:hover, -.navbar .nav > .active > a:focus { - color: #555; - text-decoration: none; - background-color: #e6e6e6; - -webkit-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); - -moz-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); - box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); -} -.navbar .btn-navbar { - display: none; - float: right; - padding: 7px 10px; - margin-left: 5px; - margin-right: 5px; - background-color: #f2f2f2; - *background-color: #f2f2f2; - -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); - -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); - box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); -} -.navbar .btn-navbar:hover, -.navbar .btn-navbar:focus, -.navbar .btn-navbar:active, -.navbar .btn-navbar.active, -.navbar .btn-navbar.disabled, -.navbar .btn-navbar[disabled] { - color: #fff; - background-color: #d9d9d9; - *background-color: #d9d9d9; -} -.navbar .btn-navbar:active, -.navbar .btn-navbar.active { - background-color: #f2f2f2; -} -.navbar .btn-navbar .icon-bar { - display: block; - width: 18px; - height: 2px; - background-color: #f5f5f5; - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; - -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.25); - -moz-box-shadow: 0 1px 0 rgba(0,0,0,0.25); - box-shadow: 0 1px 0 rgba(0,0,0,0.25); -} -.btn-navbar .icon-bar + .icon-bar { - margin-top: 3px; -} -.navbar .nav > li > .dropdown-menu:before { - content: ''; - display: inline-block; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; - border-bottom-color: rgba(0,0,0,0.2); - position: absolute; - top: -7px; - left: 9px; -} -.navbar .nav > li > .dropdown-menu:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #fff; - position: absolute; - top: -6px; - left: 10px; -} -.navbar-fixed-bottom .nav > li > .dropdown-menu:before { - border-top: 7px solid #ccc; - border-top-color: rgba(0,0,0,0.2); - border-bottom: 0; - bottom: -7px; - top: auto; -} -.navbar-fixed-bottom .nav > li > .dropdown-menu:after { - border-top: 6px solid #fff; - border-bottom: 0; - bottom: -6px; - top: auto; -} -.navbar .nav li.dropdown > a:hover .caret, -.navbar .nav li.dropdown > a:focus .caret { - border-top-color: #333; - border-bottom-color: #333; -} -.navbar .nav li.dropdown.open > .dropdown-toggle, -.navbar .nav li.dropdown.active > .dropdown-toggle, -.navbar .nav li.dropdown.open.active > .dropdown-toggle { - background-color: #e6e6e6; - color: #555; -} -.navbar .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #555; - border-bottom-color: #555; -} -.navbar .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #555; - border-bottom-color: #555; -} -.navbar .pull-right > li > .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right { - left: auto; - right: 0; -} -.navbar .pull-right > li > .dropdown-menu:before, -.navbar .nav > li > .dropdown-menu.pull-right:before { - left: auto; - right: 12px; -} -.navbar .pull-right > li > .dropdown-menu:after, -.navbar .nav > li > .dropdown-menu.pull-right:after { - left: auto; - right: 13px; -} -.navbar .pull-right > li > .dropdown-menu .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { - left: auto; - right: 100%; - margin-left: 0; - margin-right: -1px; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} -.navbar-inverse .navbar-inner { - background-color: #13294a; - background-image: -moz-linear-gradient(top,#152d53,#10223e); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#152d53),to(#10223e)); - background-image: -webkit-linear-gradient(top,#152d53,#10223e); - background-image: -o-linear-gradient(top,#152d53,#10223e); - background-image: linear-gradient(to bottom,#152d53,#10223e); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff142c52', endColorstr='#ff0f213e', GradientType=0); - border-color: #0b172a; -} -.navbar-inverse .brand, -.navbar-inverse .nav > li > a { - color: #d9d9d9; - text-shadow: 0 -1px 0 rgba(0,0,0,0.25); -} -.navbar-inverse .brand:hover, -.navbar-inverse .brand:focus, -.navbar-inverse .nav > li > a:hover, -.navbar-inverse .nav > li > a:focus { - color: #fff; -} -.navbar-inverse .brand { - color: #d9d9d9; -} -.navbar-inverse .navbar-text { - color: #d9d9d9; -} -.navbar-inverse .nav > li > a:focus, -.navbar-inverse .nav > li > a:hover { - background-color: transparent; - color: #fff; -} -.navbar-inverse .nav .active > a, -.navbar-inverse .nav .active > a:hover, -.navbar-inverse .nav .active > a:focus { - color: #fff; - background-color: #10223e; -} -.navbar-inverse .navbar-link { - color: #d9d9d9; -} -.navbar-inverse .navbar-link:hover, -.navbar-inverse .navbar-link:focus { - color: #fff; -} -.navbar-inverse .divider-vertical { - border-left-color: #10223e; - border-right-color: #152d53; -} -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { - background-color: #10223e; - color: #fff; -} -.navbar-inverse .nav li.dropdown > a:hover .caret, -.navbar-inverse .nav li.dropdown > a:focus .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #d9d9d9; - border-bottom-color: #d9d9d9; -} -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.navbar-inverse .navbar-search .search-query { - color: #fff; - background-color: #2959a4; - border-color: #10223e; - -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); - -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); - box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); - -webkit-transition: none; - -moz-transition: none; - -o-transition: none; - transition: none; -} -.navbar-inverse .navbar-search .search-query:-moz-placeholder { - color: #ccc; -} -.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { - color: #ccc; -} -.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { - color: #ccc; -} -.navbar-inverse .navbar-search .search-query:focus, -.navbar-inverse .navbar-search .search-query.focused { - padding: 5px 15px; - color: #333; - text-shadow: 0 1px 0 #fff; - background-color: #fff; - border: 0; - -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.15); - -moz-box-shadow: 0 0 3px rgba(0,0,0,0.15); - box-shadow: 0 0 3px rgba(0,0,0,0.15); - outline: 0; -} -.navbar-inverse .btn-navbar { - background-color: #10223e; - *background-color: #10223e; -} -.navbar-inverse .btn-navbar:hover, -.navbar-inverse .btn-navbar:focus, -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active, -.navbar-inverse .btn-navbar.disabled, -.navbar-inverse .btn-navbar[disabled] { - color: #fff; - background-color: #050c16; - *background-color: #050c16; -} -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active { - background-color: #10223e; -} -.breadcrumb { - padding: 8px 15px; - margin: 0 0 18px; - list-style: none; - background-color: #f5f5f5; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.breadcrumb > li { - display: inline-block; - *display: inline; - *zoom: 1; - text-shadow: 0 1px 0 #fff; -} -.breadcrumb > li > .divider { - padding: 0 5px; - color: #ccc; -} -.breadcrumb > .active { - color: #999; -} -.pagination { - margin: 18px 0; -} -.pagination ul { - display: inline-block; - *display: inline; - *zoom: 1; - margin-left: 0; - margin-bottom: 0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.05); - -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.05); - box-shadow: 0 1px 2px rgba(0,0,0,0.05); -} -.pagination ul > li { - display: inline; -} -.pagination ul > li > a, -.pagination ul > li > span { - float: left; - padding: 4px 12px; - line-height: 18px; - text-decoration: none; - background-color: #fff; - border: 1px solid #ddd; - border-left-width: 0; -} -.pagination ul > li > a:hover, -.pagination ul > li > a:focus, -.pagination ul > .active > a, -.pagination ul > .active > span { - background-color: #F0F0F0; -} -.pagination ul > .active > a, -.pagination ul > .active > span { - color: #999; - cursor: default; -} -.pagination ul > .disabled > span, -.pagination ul > .disabled > a, -.pagination ul > .disabled > a:hover, -.pagination ul > .disabled > a:focus { - color: #999; - background-color: transparent; - cursor: default; -} -.pagination ul > li:first-child > a, -.pagination ul > li:first-child > span { - border-left-width: 1px; - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.pagination ul > li:last-child > a, -.pagination ul > li:last-child > span { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.pagination-centered { - text-align: center; -} -.pagination-right { - text-align: right; -} -.pagination-large ul > li > a, -.pagination-large ul > li > span { - padding: 11px 19px; - font-size: 16.25px; -} -.pagination-large ul > li:first-child > a, -.pagination-large ul > li:first-child > span { - -webkit-border-top-left-radius: 6px; - -moz-border-radius-topleft: 6px; - border-top-left-radius: 6px; - -webkit-border-bottom-left-radius: 6px; - -moz-border-radius-bottomleft: 6px; - border-bottom-left-radius: 6px; -} -.pagination-large ul > li:last-child > a, -.pagination-large ul > li:last-child > span { - -webkit-border-top-right-radius: 6px; - -moz-border-radius-topright: 6px; - border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - -moz-border-radius-bottomright: 6px; - border-bottom-right-radius: 6px; -} -.pagination-mini ul > li:first-child > a, -.pagination-mini ul > li:first-child > span, -.pagination-small ul > li:first-child > a, -.pagination-small ul > li:first-child > span { - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.pagination-mini ul > li:last-child > a, -.pagination-mini ul > li:last-child > span, -.pagination-small ul > li:last-child > a, -.pagination-small ul > li:last-child > span { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.pagination-small ul > li > a, -.pagination-small ul > li > span { - padding: 2px 10px; - font-size: 12px; -} -.pagination-mini ul > li > a, -.pagination-mini ul > li > span { - padding: 0 6px; - font-size: 9.75px; -} -.pager { - margin: 18px 0; - list-style: none; - text-align: center; - *zoom: 1; -} -.pager:before, -.pager:after { - display: table; - content: ""; - line-height: 0; -} -.pager:after { - clear: both; -} -.pager li { - display: inline; -} -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #fff; - border: 1px solid #ddd; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #f5f5f5; -} -.pager .next > a, -.pager .next > span { - float: right; -} -.pager .previous > a, -.pager .previous > span { - float: left; -} -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #999; - background-color: #fff; - cursor: default; -} -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000; -} -.modal-backdrop.fade { - opacity: 0; -} -.modal-backdrop, -.modal-backdrop.fade.in { - opacity: 0.8; - filter: alpha(opacity=80); -} -.modal-header { - padding: 9px 15px; - border-bottom: 1px solid #eee; -} -.modal-header .close { - margin-top: 2px; -} -.modal-header h3 { - margin: 0; - line-height: 30px; -} -.modal-body { - width: 98%; - position: relative; - max-height: 400px; - padding: 1%; -} -.modal-body iframe { - width: 100%; - max-height: none; - border: 0 !important; -} -.modal-form { - margin-bottom: 0; -} -.modal-footer { - padding: 14px 15px 15px; - margin-bottom: 0; - text-align: right; - background-color: #f5f5f5; - border-top: 1px solid #ddd; - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - -webkit-box-shadow: inset 0 1px 0 #fff; - -moz-box-shadow: inset 0 1px 0 #fff; - box-shadow: inset 0 1px 0 #fff; - *zoom: 1; -} -.modal-footer:before, -.modal-footer:after { - display: table; - content: ""; - line-height: 0; -} -.modal-footer:after { - clear: both; -} -.modal-footer .btn + .btn { - margin-left: 5px; - margin-bottom: 0; -} -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} -.tooltip { - position: absolute; - z-index: 1030; - display: block; - visibility: visible; - font-size: 11px; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); -} -.tooltip.in { - opacity: 0.8; - filter: alpha(opacity=80); -} -.tooltip.top { - margin-top: -3px; - padding: 5px 0; -} -.tooltip.right { - margin-left: 3px; - padding: 0 5px; -} -.tooltip.bottom { - margin-top: 3px; - padding: 5px 0; -} -.tooltip.left { - margin-left: -3px; - padding: 0 5px; -} -.tooltip-inner { - max-width: 200px; - padding: 8px; - color: #fff; - text-align: center; - text-decoration: none; - background-color: #000; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000; -} -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000; -} -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1060; - display: none; - max-width: 276px; - padding: 1px; - text-align: left; - background-color: #fff; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,0.2); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); - -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); - box-shadow: 0 5px 10px rgba(0,0,0,0.2); - white-space: normal; -} -.popover.top { - margin-top: -10px; -} -.popover.right { - margin-left: 10px; -} -.popover.bottom { - margin-top: 10px; -} -.popover.left { - margin-left: -10px; -} -.popover-title { - margin: 0; - padding: 8px 14px; - font-size: 14px; - font-weight: normal; - line-height: 18px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - -webkit-border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - border-radius: 5px 5px 0 0; -} -.popover-title:empty { - display: none; -} -.popover-content { - padding: 9px 14px; -} -.popover .arrow, -.popover .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.popover .arrow { - border-width: 11px; -} -.popover .arrow:after { - border-width: 10px; - content: ""; -} -.popover.top .arrow { - left: 50%; - margin-left: -11px; - border-bottom-width: 0; - border-top-color: #999; - border-top-color: rgba(0,0,0,0.25); - bottom: -11px; -} -.popover.top .arrow:after { - bottom: 1px; - margin-left: -10px; - border-bottom-width: 0; - border-top-color: #fff; -} -.popover.right .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-left-width: 0; - border-right-color: #999; - border-right-color: rgba(0,0,0,0.25); -} -.popover.right .arrow:after { - left: 1px; - bottom: -10px; - border-left-width: 0; - border-right-color: #fff; -} -.popover.bottom .arrow { - left: 50%; - margin-left: -11px; - border-top-width: 0; - border-bottom-color: #999; - border-bottom-color: rgba(0,0,0,0.25); - top: -11px; -} -.popover.bottom .arrow:after { - top: 1px; - margin-left: -10px; - border-top-width: 0; - border-bottom-color: #fff; -} -.popover.left .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-right-width: 0; - border-left-color: #999; - border-left-color: rgba(0,0,0,0.25); -} -.popover.left .arrow:after { - right: 1px; - border-right-width: 0; - border-left-color: #fff; - bottom: -10px; -} -.thumbnails { - margin-left: -20px; - list-style: none; - *zoom: 1; -} -.thumbnails:before, -.thumbnails:after { - display: table; - content: ""; - line-height: 0; -} -.thumbnails:after { - clear: both; -} -.row-fluid .thumbnails { - margin-left: 0; -} -.thumbnails > li { - float: left; - margin-bottom: 18px; - margin-left: 20px; -} -.thumbnail { - display: block; - padding: 4px; - line-height: 18px; - border: 1px solid #ddd; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.055); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.055); - box-shadow: 0 1px 3px rgba(0,0,0,0.055); - -webkit-transition: all .2s ease-in-out; - -moz-transition: all .2s ease-in-out; - -o-transition: all .2s ease-in-out; - transition: all .2s ease-in-out; -} -a.thumbnail:hover, -a.thumbnail:focus { - border-color: #3071a9; - -webkit-box-shadow: 0 1px 4px rgba(0,105,214,0.25); - -moz-box-shadow: 0 1px 4px rgba(0,105,214,0.25); - box-shadow: 0 1px 4px rgba(0,105,214,0.25); -} -.thumbnail > img { - display: block; - max-width: 100%; - margin-left: auto; - margin-right: auto; -} -.thumbnail .caption { - padding: 9px; - color: #555; -} -.media, -.media-body { - overflow: hidden; - *overflow: visible; - zoom: 1; -} -.media, -.media .media { - margin-top: 15px; -} -.media:first-child { - margin-top: 0; -} -.media-object { - display: block; -} -.media-heading { - margin: 0 0 5px; -} -.media > .pull-left { - margin-right: 10px; -} -.media > .pull-right { - margin-left: 10px; -} -.media-list { - margin-left: 0; - list-style: none; -} -.label, -.badge { - display: inline-block; - padding: 2px 4px; - font-size: 10.998px; - font-weight: bold; - line-height: 14px; - color: #fff; - vertical-align: baseline; - white-space: nowrap; - text-shadow: 0 -1px 0 rgba(0,0,0,0.25); - background-color: #999; -} -.label { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.badge { - padding-left: 9px; - padding-right: 9px; - -webkit-border-radius: 9px; - -moz-border-radius: 9px; - border-radius: 9px; -} -.label:empty, -.badge:empty { - display: none; -} -a.label:hover, -a.label:focus, -a.badge:hover, -a.badge:focus { - color: #fff; - text-decoration: none; - cursor: pointer; -} -.label-important, -.badge-important { - background-color: #a94442; -} -.label-important[href], -.badge-important[href] { - background-color: #843534; -} -.label-warning, -.badge-warning { - background-color: #f89406; -} -.label-warning[href], -.badge-warning[href] { - background-color: #c67605; -} -.label-success, -.badge-success { - background-color: #3c763d; -} -.label-success[href], -.badge-success[href] { - background-color: #2b542c; -} -.label-info, -.badge-info { - background-color: #31708f; -} -.label-info[href], -.badge-info[href] { - background-color: #245269; -} -.label-inverse, -.badge-inverse { - background-color: #333; -} -.label-inverse[href], -.badge-inverse[href] { - background-color: #1a1a1a; -} -.btn .label, -.btn .badge { - position: relative; - top: -1px; -} -.btn-mini .label, -.btn-mini .badge { - top: 0; -} -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-moz-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-ms-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-o-keyframes progress-bar-stripes { - from { - background-position: 0 0; - } - to { - background-position: 40px 0; - } -} -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -.progress { - overflow: hidden; - height: 18px; - margin-bottom: 18px; - background-color: #f7f7f7; - background-image: -moz-linear-gradient(top,#f5f5f5,#f9f9f9); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9)); - background-image: -webkit-linear-gradient(top,#f5f5f5,#f9f9f9); - background-image: -o-linear-gradient(top,#f5f5f5,#f9f9f9); - background-image: linear-gradient(to bottom,#f5f5f5,#f9f9f9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); - -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); - box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.progress .bar { - width: 0%; - height: 100%; - color: #fff; - float: left; - font-size: 12px; - text-align: center; - text-shadow: 0 -1px 0 rgba(0,0,0,0.25); - background-color: #0e90d2; - background-image: -moz-linear-gradient(top,#149bdf,#0480be); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be)); - background-image: -webkit-linear-gradient(top,#149bdf,#0480be); - background-image: -o-linear-gradient(top,#149bdf,#0480be); - background-image: linear-gradient(to bottom,#149bdf,#0480be); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); - -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); - -moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); - box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: width .6s ease; - -moz-transition: width .6s ease; - -o-transition: width .6s ease; - transition: width .6s ease; -} -.progress .bar + .bar { - -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); - -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); - box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); -} -.progress-striped .bar { - background-color: #149bdf; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - -webkit-background-size: 40px 40px; - -moz-background-size: 40px 40px; - -o-background-size: 40px 40px; - background-size: 40px 40px; -} -.progress.active .bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - -ms-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} -.progress-danger .bar, -.progress .bar-danger { - background-color: #dd514c; - background-image: -moz-linear-gradient(top,#ee5f5b,#c43c35); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35)); - background-image: -webkit-linear-gradient(top,#ee5f5b,#c43c35); - background-image: -o-linear-gradient(top,#ee5f5b,#c43c35); - background-image: linear-gradient(to bottom,#ee5f5b,#c43c35); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); -} -.progress-danger.progress-striped .bar, -.progress-striped .bar-danger { - background-color: #ee5f5b; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); -} -.progress-success .bar, -.progress .bar-success { - background-color: #5eb95e; - background-image: -moz-linear-gradient(top,#62c462,#57a957); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957)); - background-image: -webkit-linear-gradient(top,#62c462,#57a957); - background-image: -o-linear-gradient(top,#62c462,#57a957); - background-image: linear-gradient(to bottom,#62c462,#57a957); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); -} -.progress-success.progress-striped .bar, -.progress-striped .bar-success { - background-color: #62c462; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); -} -.progress-info .bar, -.progress .bar-info { - background-color: #4bb1cf; - background-image: -moz-linear-gradient(top,#5bc0de,#339bb9); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9)); - background-image: -webkit-linear-gradient(top,#5bc0de,#339bb9); - background-image: -o-linear-gradient(top,#5bc0de,#339bb9); - background-image: linear-gradient(to bottom,#5bc0de,#339bb9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); -} -.progress-info.progress-striped .bar, -.progress-striped .bar-info { - background-color: #5bc0de; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); -} -.progress-warning .bar, -.progress .bar-warning { - background-color: #faa732; - background-image: -moz-linear-gradient(top,#fbb450,#f89406); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406)); - background-image: -webkit-linear-gradient(top,#fbb450,#f89406); - background-image: -o-linear-gradient(top,#fbb450,#f89406); - background-image: linear-gradient(to bottom,#fbb450,#f89406); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffab44f', endColorstr='#fff89406', GradientType=0); -} -.progress-warning.progress-striped .bar, -.progress-striped .bar-warning { - background-color: #fbb450; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); -} -.accordion { - margin-bottom: 18px; -} -.accordion-group { - margin-bottom: 2px; - border: 1px solid #e5e5e5; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.accordion-heading { - border-bottom: 0; -} -.accordion-heading .accordion-toggle { - display: block; - padding: 8px 15px; -} -.accordion-toggle { - cursor: pointer; -} -.accordion-inner { - padding: 9px 15px; - border-top: 1px solid #e5e5e5; -} -.carousel { - position: relative; - margin-bottom: 18px; - line-height: 1; -} -.carousel-inner { - overflow: hidden; - width: 100%; - position: relative; -} -.carousel-inner > .item { - display: none; - position: relative; - -webkit-transition: .6s ease-in-out left; - -moz-transition: .6s ease-in-out left; - -o-transition: .6s ease-in-out left; - transition: .6s ease-in-out left; -} -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - line-height: 1; -} -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} -.carousel-inner > .active { - left: 0; -} -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} -.carousel-inner > .next { - left: 100%; -} -.carousel-inner > .prev { - left: -100%; -} -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} -.carousel-inner > .active.left { - left: -100%; -} -.carousel-inner > .active.right { - left: 100%; -} -.carousel-control { - position: absolute; - top: 40%; - left: 15px; - width: 40px; - height: 40px; - margin-top: -20px; - font-size: 60px; - font-weight: 100; - line-height: 30px; - color: #fff; - text-align: center; - background: #222; - border: 3px solid #fff; - -webkit-border-radius: 23px; - -moz-border-radius: 23px; - border-radius: 23px; - opacity: 0.5; - filter: alpha(opacity=50); -} -.carousel-control.right { - left: auto; - right: 15px; -} -.carousel-control:hover, -.carousel-control:focus { - color: #fff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} -.carousel-indicators { - position: absolute; - top: 15px; - right: 15px; - z-index: 5; - margin: 0; - list-style: none; -} -.carousel-indicators li { - display: block; - float: left; - width: 10px; - height: 10px; - margin-left: 5px; - text-indent: -999px; - background-color: #ccc; - background-color: rgba(255,255,255,0.25); - border-radius: 5px; -} -.carousel-indicators .active { - background-color: #fff; -} -.carousel-caption { - position: absolute; - left: 0; - right: 0; - bottom: 0; - padding: 15px; - background: #333; - background: rgba(0,0,0,0.75); -} -.carousel-caption h4, -.carousel-caption p { - color: #fff; - line-height: 18px; -} -.carousel-caption h4 { - margin: 0 0 5px; -} -.carousel-caption p { - margin-bottom: 0; -} -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 27px; - color: inherit; - background-color: #eee; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - color: inherit; - letter-spacing: -1px; -} -.hero-unit li { - line-height: 27px; -} -.pull-right { - float: right; -} -.pull-left { - float: left; -} -.hide { - display: none; -} -.show { - display: block; -} -.invisible { - visibility: hidden; -} -.affix { - position: fixed; -} -@-ms-viewport { - width: device-width; -} -.hidden { - display: none; - visibility: hidden; -} -.visible-phone { - display: none !important; -} -.visible-tablet { - display: none !important; -} -.hidden-desktop { - display: none !important; -} -.visible-desktop { - display: inherit !important; -} -@media (min-width: 768px) and (max-width: 979px) { - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important; - } - .visible-tablet { - display: inherit !important; - } - .hidden-tablet { - display: none !important; - } -} -@media (max-width: 767px) { - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important; - } - .visible-phone { - display: inherit !important; - } - .hidden-phone { - display: none !important; - } -} -.visible-print { - display: none !important; -} -@media print { - .visible-print { - display: inherit !important; - } - .hidden-print { - display: none !important; - } -} -@media (max-width: 767px) { - body { - padding-left: 20px; - padding-right: 20px; - } - .navbar-fixed-top, - .navbar-fixed-bottom, - .navbar-static-top { - margin-left: -20px; - margin-right: -20px; - } - .container-fluid { - padding: 0; - } - .dl-horizontal dt { - float: none; - clear: none; - width: auto; - text-align: left; - } - .dl-horizontal dd { - margin-left: 0; - } - .dropdown-menu .menuitem-group { - background-color: #10223e; - color: #eee; - } - .container { - width: auto; - } - .row-fluid { - width: 100%; - } - .row, - .thumbnails { - margin-left: 0; - } - .thumbnails > li { - float: none; - margin-left: 0; - } - [class*="span"], - .uneditable-input[class*="span"], - .row-fluid [class*="span"] { - float: none; - display: block; - width: 100%; - margin-left: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .span12, - .row-fluid .span12 { - width: 100%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="offset"]:first-child { - margin-left: 0; - } - .input-large, - .input-xlarge, - .input-xxlarge, - input[class*="span"], - select[class*="span"], - textarea[class*="span"], - .uneditable-input { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .input-prepend input, - .input-append input, - .input-prepend input[class*="span"], - .input-append input[class*="span"] { - display: inline-block; - width: auto; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 0; - } -} -@media (max-width: 480px) { - .nav-collapse { - -webkit-transform: translate3d(0,0,0); - } - .page-header h1 small { - display: block; - line-height: 18px; - } - input[type="checkbox"], - input[type="radio"] { - border: 1px solid #ccc; - } - .form-horizontal .control-label { - float: none; - width: auto; - padding-top: 0; - text-align: left; - } - .form-horizontal .controls { - margin-left: 0; - } - .form-horizontal .control-list { - padding-top: 0; - } - .form-horizontal .form-actions { - padding-left: 10px; - padding-right: 10px; - } - .tag-category input#filter-search, - .newsfeed-category input#filter-search { - width: auto; - margin-bottom: 9px; - } - .category-list input#filter-search { - width: auto; - } - .media .pull-left, - .media .pull-right { - float: none; - display: block; - margin-bottom: 10px; - } - .media-object { - margin-right: 0; - margin-left: 0; - } - .modal-header .close { - padding: 10px; - margin: -10px; - } - .carousel-caption { - position: static; - } -} -@media (min-width: 768px) and (max-width: 979px) { - .row { - margin-left: -20px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - content: ""; - line-height: 0; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - min-height: 1px; - margin-left: 20px; - } - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 724px; - } - .span12 { - width: 724px; - } - .span11 { - width: 662px; - } - .span10 { - width: 600px; - } - .span9 { - width: 538px; - } - .span8 { - width: 476px; - } - .span7 { - width: 414px; - } - .span6 { - width: 352px; - } - .span5 { - width: 290px; - } - .span4 { - width: 228px; - } - .span3 { - width: 166px; - } - .span2 { - width: 104px; - } - .span1 { - width: 42px; - } - .offset12 { - margin-left: 764px; - } - .offset11 { - margin-left: 702px; - } - .offset10 { - margin-left: 640px; - } - .offset9 { - margin-left: 578px; - } - .offset8 { - margin-left: 516px; - } - .offset7 { - margin-left: 454px; - } - .offset6 { - margin-left: 392px; - } - .offset5 { - margin-left: 330px; - } - .offset4 { - margin-left: 268px; - } - .offset3 { - margin-left: 206px; - } - .offset2 { - margin-left: 144px; - } - .offset1 { - margin-left: 82px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - content: ""; - line-height: 0; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - float: left; - margin-left: 2.76243094%; - *margin-left: 2.70923945%; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.76243094%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851%; - } - .row-fluid .span11 { - width: 91.43646409%; - *width: 91.3832726%; - } - .row-fluid .span10 { - width: 82.87292818%; - *width: 82.81973669%; - } - .row-fluid .span9 { - width: 74.30939227%; - *width: 74.25620078%; - } - .row-fluid .span8 { - width: 65.74585635%; - *width: 65.69266486%; - } - .row-fluid .span7 { - width: 57.18232044%; - *width: 57.12912895%; - } - .row-fluid .span6 { - width: 48.61878453%; - *width: 48.56559304%; - } - .row-fluid .span5 { - width: 40.05524862%; - *width: 40.00205713%; - } - .row-fluid .span4 { - width: 31.49171271%; - *width: 31.43852122%; - } - .row-fluid .span3 { - width: 22.9281768%; - *width: 22.87498531%; - } - .row-fluid .span2 { - width: 14.36464088%; - *width: 14.31144939%; - } - .row-fluid .span1 { - width: 5.80110497%; - *width: 5.74791348%; - } - .row-fluid .offset12 { - margin-left: 105.52486188%; - *margin-left: 105.4184789%; - } - .row-fluid .offset12:first-child { - margin-left: 102.76243094%; - *margin-left: 102.65604796%; - } - .row-fluid .offset11 { - margin-left: 96.96132597%; - *margin-left: 96.85494299%; - } - .row-fluid .offset11:first-child { - margin-left: 94.19889503%; - *margin-left: 94.09251205%; - } - .row-fluid .offset10 { - margin-left: 88.39779006%; - *margin-left: 88.29140708%; - } - .row-fluid .offset10:first-child { - margin-left: 85.63535912%; - *margin-left: 85.52897614%; - } - .row-fluid .offset9 { - margin-left: 79.83425414%; - *margin-left: 79.72787116%; - } - .row-fluid .offset9:first-child { - margin-left: 77.0718232%; - *margin-left: 76.96544023%; - } - .row-fluid .offset8 { - margin-left: 71.27071823%; - *margin-left: 71.16433525%; - } - .row-fluid .offset8:first-child { - margin-left: 68.50828729%; - *margin-left: 68.40190431%; - } - .row-fluid .offset7 { - margin-left: 62.70718232%; - *margin-left: 62.60079934%; - } - .row-fluid .offset7:first-child { - margin-left: 59.94475138%; - *margin-left: 59.8383684%; - } - .row-fluid .offset6 { - margin-left: 54.14364641%; - *margin-left: 54.03726343%; - } - .row-fluid .offset6:first-child { - margin-left: 51.38121547%; - *margin-left: 51.27483249%; - } - .row-fluid .offset5 { - margin-left: 45.5801105%; - *margin-left: 45.47372752%; - } - .row-fluid .offset5:first-child { - margin-left: 42.81767956%; - *margin-left: 42.71129658%; - } - .row-fluid .offset4 { - margin-left: 37.01657459%; - *margin-left: 36.91019161%; - } - .row-fluid .offset4:first-child { - margin-left: 34.25414365%; - *margin-left: 34.14776067%; - } - .row-fluid .offset3 { - margin-left: 28.45303867%; - *margin-left: 28.3466557%; - } - .row-fluid .offset3:first-child { - margin-left: 25.69060773%; - *margin-left: 25.58422476%; - } - .row-fluid .offset2 { - margin-left: 19.88950276%; - *margin-left: 19.78311978%; - } - .row-fluid .offset2:first-child { - margin-left: 17.12707182%; - *margin-left: 17.02068884%; - } - .row-fluid .offset1 { - margin-left: 11.32596685%; - *margin-left: 11.21958387%; - } - .row-fluid .offset1:first-child { - margin-left: 8.56353591%; - *margin-left: 8.45715293%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 20px; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 710px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 648px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 586px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 524px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 462px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 400px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 338px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 276px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 214px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 152px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 90px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 28px; - } -} -@media (min-width: 1200px) { - .row { - margin-left: -30px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - content: ""; - line-height: 0; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - min-height: 1px; - margin-left: 30px; - } - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 1170px; - } - .span12 { - width: 1170px; - } - .span11 { - width: 1070px; - } - .span10 { - width: 970px; - } - .span9 { - width: 870px; - } - .span8 { - width: 770px; - } - .span7 { - width: 670px; - } - .span6 { - width: 570px; - } - .span5 { - width: 470px; - } - .span4 { - width: 370px; - } - .span3 { - width: 270px; - } - .span2 { - width: 170px; - } - .span1 { - width: 70px; - } - .offset12 { - margin-left: 1230px; - } - .offset11 { - margin-left: 1130px; - } - .offset10 { - margin-left: 1030px; - } - .offset9 { - margin-left: 930px; - } - .offset8 { - margin-left: 830px; - } - .offset7 { - margin-left: 730px; - } - .offset6 { - margin-left: 630px; - } - .offset5 { - margin-left: 530px; - } - .offset4 { - margin-left: 430px; - } - .offset3 { - margin-left: 330px; - } - .offset2 { - margin-left: 230px; - } - .offset1 { - margin-left: 130px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - content: ""; - line-height: 0; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - float: left; - margin-left: 2.76243094%; - *margin-left: 2.70923945%; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.76243094%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851%; - } - .row-fluid .span11 { - width: 91.43646409%; - *width: 91.3832726%; - } - .row-fluid .span10 { - width: 82.87292818%; - *width: 82.81973669%; - } - .row-fluid .span9 { - width: 74.30939227%; - *width: 74.25620078%; - } - .row-fluid .span8 { - width: 65.74585635%; - *width: 65.69266486%; - } - .row-fluid .span7 { - width: 57.18232044%; - *width: 57.12912895%; - } - .row-fluid .span6 { - width: 48.61878453%; - *width: 48.56559304%; - } - .row-fluid .span5 { - width: 40.05524862%; - *width: 40.00205713%; - } - .row-fluid .span4 { - width: 31.49171271%; - *width: 31.43852122%; - } - .row-fluid .span3 { - width: 22.9281768%; - *width: 22.87498531%; - } - .row-fluid .span2 { - width: 14.36464088%; - *width: 14.31144939%; - } - .row-fluid .span1 { - width: 5.80110497%; - *width: 5.74791348%; - } - .row-fluid .offset12 { - margin-left: 105.52486188%; - *margin-left: 105.4184789%; - } - .row-fluid .offset12:first-child { - margin-left: 102.76243094%; - *margin-left: 102.65604796%; - } - .row-fluid .offset11 { - margin-left: 96.96132597%; - *margin-left: 96.85494299%; - } - .row-fluid .offset11:first-child { - margin-left: 94.19889503%; - *margin-left: 94.09251205%; - } - .row-fluid .offset10 { - margin-left: 88.39779006%; - *margin-left: 88.29140708%; - } - .row-fluid .offset10:first-child { - margin-left: 85.63535912%; - *margin-left: 85.52897614%; - } - .row-fluid .offset9 { - margin-left: 79.83425414%; - *margin-left: 79.72787116%; - } - .row-fluid .offset9:first-child { - margin-left: 77.0718232%; - *margin-left: 76.96544023%; - } - .row-fluid .offset8 { - margin-left: 71.27071823%; - *margin-left: 71.16433525%; - } - .row-fluid .offset8:first-child { - margin-left: 68.50828729%; - *margin-left: 68.40190431%; - } - .row-fluid .offset7 { - margin-left: 62.70718232%; - *margin-left: 62.60079934%; - } - .row-fluid .offset7:first-child { - margin-left: 59.94475138%; - *margin-left: 59.8383684%; - } - .row-fluid .offset6 { - margin-left: 54.14364641%; - *margin-left: 54.03726343%; - } - .row-fluid .offset6:first-child { - margin-left: 51.38121547%; - *margin-left: 51.27483249%; - } - .row-fluid .offset5 { - margin-left: 45.5801105%; - *margin-left: 45.47372752%; - } - .row-fluid .offset5:first-child { - margin-left: 42.81767956%; - *margin-left: 42.71129658%; - } - .row-fluid .offset4 { - margin-left: 37.01657459%; - *margin-left: 36.91019161%; - } - .row-fluid .offset4:first-child { - margin-left: 34.25414365%; - *margin-left: 34.14776067%; - } - .row-fluid .offset3 { - margin-left: 28.45303867%; - *margin-left: 28.3466557%; - } - .row-fluid .offset3:first-child { - margin-left: 25.69060773%; - *margin-left: 25.58422476%; - } - .row-fluid .offset2 { - margin-left: 19.88950276%; - *margin-left: 19.78311978%; - } - .row-fluid .offset2:first-child { - margin-left: 17.12707182%; - *margin-left: 17.02068884%; - } - .row-fluid .offset1 { - margin-left: 11.32596685%; - *margin-left: 11.21958387%; - } - .row-fluid .offset1:first-child { - margin-left: 8.56353591%; - *margin-left: 8.45715293%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 30px; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 1156px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 1056px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 956px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 856px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 756px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 656px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 556px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 456px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 356px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 256px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 156px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 56px; - } - .thumbnails { - margin-left: -30px; - } - .thumbnails > li { - margin-left: 30px; - } - .row-fluid .thumbnails { - margin-left: 0; - } -} -@media (max-width: 767px) { - body { - padding-top: 0; - } - .navbar-fixed-top, - .navbar-fixed-bottom { - position: static; - } - .navbar-fixed-top { - margin-bottom: 18px; - } - .navbar-fixed-bottom { - margin-top: 18px; - } - .navbar-fixed-top .navbar-inner, - .navbar-fixed-bottom .navbar-inner { - padding: 5px; - } - .navbar .container { - width: auto; - padding: 0; - } - .navbar .brand { - padding-left: 10px; - padding-right: 10px; - margin: 0 0 0 -5px; - } - .nav-collapse { - clear: both; - } - .nav-collapse .nav { - float: none; - margin: 0 0 9px; - } - .nav-collapse .nav > li { - float: none; - } - .nav-collapse .nav > li > a { - margin-bottom: 2px; - } - .nav-collapse .nav > .divider-vertical { - display: none; - } - .nav-collapse .nav .nav-header { - color: #555; - text-shadow: none; - } - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - padding: 9px 15px; - font-weight: bold; - color: #555; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - } - .nav-collapse .btn { - padding: 4px 10px 4px; - font-weight: normal; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - } - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 2px; - } - .nav-collapse .nav > li > a:hover, - .nav-collapse .nav > li > a:focus, - .nav-collapse .dropdown-menu a:hover, - .nav-collapse .dropdown-menu a:focus { - background-color: #f2f2f2; - } - .navbar-inverse .nav-collapse .nav > li > a, - .navbar-inverse .nav-collapse .dropdown-menu a { - color: #d9d9d9; - } - .navbar-inverse .nav-collapse .nav > li > a:hover, - .navbar-inverse .nav-collapse .nav > li > a:focus, - .navbar-inverse .nav-collapse .dropdown-menu a:hover, - .navbar-inverse .nav-collapse .dropdown-menu a:focus { - background-color: #10223e; - } - .nav-collapse.in .btn-group { - margin-top: 5px; - padding: 0; - } - .nav-collapse .dropdown-menu { - position: static; - top: auto; - left: auto; - float: none; - display: none; - max-width: none; - margin: 0 15px; - padding: 0; - background-color: transparent; - border: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } - .nav-collapse .open > .dropdown-menu { - display: block; - } - .nav-collapse .dropdown-menu:before, - .nav-collapse .dropdown-menu:after { - display: none; - } - .nav-collapse .dropdown-menu .divider { - display: none; - } - .nav-collapse .nav > li > .dropdown-menu:before, - .nav-collapse .nav > li > .dropdown-menu:after { - display: none; - } - .nav-collapse .navbar-form, - .nav-collapse .navbar-search { - float: none; - padding: 9px 15px; - margin: 9px 0; - border-top: 1px solid #f2f2f2; - border-bottom: 1px solid #f2f2f2; - -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - } - .navbar-inverse .nav-collapse .navbar-form, - .navbar-inverse .nav-collapse .navbar-search { - border-top-color: #10223e; - border-bottom-color: #10223e; - } - .navbar .nav-collapse .nav.pull-right { - float: none; - margin-left: 0; - } - .nav-collapse, - .nav-collapse.collapse { - overflow: hidden; - height: 0; - } - .navbar .btn-navbar { - display: block; - } - .navbar-static .navbar-inner { - padding-left: 10px; - padding-right: 10px; - } -} -@media (min-width: 768px) { - .nav-collapse.collapse { - height: auto !important; - overflow: visible !important; - } -} -.small { - font-size: 11px; -} -iframe, -svg { - max-width: 100%; -} -.nowrap { - white-space: nowrap; -} -.center, -.table td.center, -.table th.center { - text-align: center; -} -a.disabled, -a.disabled:hover { - color: #999999; - background-color: transparent; - cursor: default; - text-decoration: none; -} -.hero-unit { - text-align: center; -} -.hero-unit .lead { - margin-bottom: 18px; - font-size: 20px; - font-weight: 200; - line-height: 27px; -} -.btn .caret { - margin-bottom: 7px; -} -.btn.btn-micro .caret { - margin: 5px 0; -} -.blog-row-rule, -.blog-item-rule { - border: 0; -} -body.modal { - padding-top: 0; -} -.row-even, -.row-odd { - padding: 5px; - width: 99%; - border-bottom: 1px solid #ddd; -} -.row-odd { - background-color: transparent; -} -.row-even { - background-color: #f9f9f9; -} -.blog-row-rule, -.blog-item-rule { - border: 0; -} -.row-fluid .row-reveal { - visibility: hidden; -} -.row-fluid:hover .row-reveal { - visibility: visible; -} -.btn-wide { - width: 80%; -} -.nav-list > li.offset > a { - padding-left: 30px; - font-size: 12px; -} -.blog-row-rule, -.blog-item-rule { - border: 0; -} -.row-fluid .offset1 { - margin-left: 8.382978723%; -} -.row-fluid .offset2 { - margin-left: 16.89361702%; -} -.row-fluid .offset3 { - margin-left: 25.404255317%; -} -.row-fluid .offset4 { - margin-left: 33.914893614%; -} -.row-fluid .offset5 { - margin-left: 42.425531911%; -} -.row-fluid .offset6 { - margin-left: 50.93617020799999%; -} -.row-fluid .offset7 { - margin-left: 59.446808505%; -} -.row-fluid .offset8 { - margin-left: 67.95744680199999%; -} -.row-fluid .offset9 { - margin-left: 76.468085099%; -} -.row-fluid .offset10 { - margin-left: 84.97872339599999%; -} -.row-fluid .offset11 { - margin-left: 91.489361693%; -} -.navbar .nav > li > a.btn { - padding: 4px 10px; - line-height: 18px; -} -.nav-tabs.nav-dark { - border-bottom: 1px solid #333; - text-shadow: 1px 1px 1px #000; -} -.nav-tabs.nav-dark > li > a { - color: #F8F8F8; -} -.nav-tabs.nav-dark > li > a:hover { - border-color: #333 #333 #111; - background-color: #777777; -} -.nav-tabs.nav-dark > .active > a, -.nav-tabs.nav-dark > .active > a:hover { - color: #ffffff; - background-color: #555555; - border: 1px solid #222; - border-bottom-color: transparent; -} -.thumbnail.pull-left { - margin: 0 10px 10px 0; -} -.thumbnail.pull-right { - margin: 0 0 10px 10px; -} -.width-10 { - width: 10px; -} -.width-20 { - width: 20px; -} -.width-30 { - width: 30px; -} -.width-40 { - width: 40px; -} -.width-50 { - width: 50px; -} -.width-60 { - width: 60px; -} -.width-70 { - width: 70px; -} -.width-80 { - width: 80px; -} -.width-90 { - width: 90px; -} -.width-100 { - width: 100px; -} -.height-10 { - height: 10px; -} -.height-20 { - height: 20px; -} -.height-30 { - height: 30px; -} -.height-40 { - height: 40px; -} -.height-50 { - height: 50px; -} -.height-60 { - height: 60px; -} -.height-70 { - height: 70px; -} -.height-80 { - height: 80px; -} -.height-90 { - height: 90px; -} -.height-100 { - height: 100px; -} -hr.hr-condensed { - margin: 10px 0; -} -.list-striped, -.row-striped { - list-style: none; - line-height: 18px; - text-align: left; - vertical-align: middle; - border-top: 1px solid #ddd; - margin-left: 0; -} -.list-striped li, -.list-striped dd, -.row-striped .row, -.row-striped .row-fluid { - border-bottom: 1px solid #ddd; - padding: 8px; -} -.list-striped li:nth-child(odd), -.list-striped dd:nth-child(odd), -.row-striped .row:nth-child(odd), -.row-striped .row-fluid:nth-child(odd) { - background-color: #f9f9f9; -} -.list-striped li:hover, -.list-striped dd:hover, -.row-striped .row:hover, -.row-striped .row-fluid:hover { - background-color: #F0F0F0; -} -.row-striped .row-fluid { - width: 100%; - box-sizing: border-box; -} -.row-striped .row-fluid [class*="span"] { - min-height: 10px; -} -.row-striped .row-fluid [class*="span"] { - margin-left: 8px; -} -.row-striped .row-fluid [class*="span"]:first-child { - margin-left: 0; -} -.list-condensed li { - padding: 4px 5px; -} -.row-condensed .row, -.row-condensed .row-fluid { - padding: 4px 5px; -} -.list-bordered, -.row-bordered { - list-style: none; - line-height: 18px; - text-align: left; - vertical-align: middle; - margin-left: 0; - border: 1px solid #ddd; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -.radio.btn-group input[type=radio] { - display: none; -} -.radio.btn-group > label { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.radio.btn-group > label:first-of-type { - margin-left: 0; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - -moz-border-radius-topleft: 4px; -} -fieldset.radio.btn-group { - padding-left: 0; -} -.iframe-bordered { - border: 1px solid #ddd; -} -.tab-content { - overflow: visible; -} -.tabs-left .tab-content { - overflow: auto; -} -.nav-tabs > li > span { - display: block; - margin-right: 2px; - padding-right: 12px; - padding-left: 12px; - padding-top: 8px; - padding-bottom: 8px; - line-height: 18px; - border: 1px solid transparent; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} -.btn-micro { - padding: 1px 4px; - font-size: 10px; - line-height: 8px; -} -.btn-group > .btn-micro { - font-size: 10px; -} -.tip-wrap { - max-width: 200px; - padding: 3px 8px; - color: #fff; - text-align: center; - text-decoration: none; - background-color: #000; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - z-index: 100; -} -.page-header { - margin: 2px 0px 10px 0px; - padding-bottom: 5px; -} -.input-prepend > .add-on, -.input-append > .add-on { - vertical-align: top; -} -.input-prepend .chzn-container-single .chzn-single { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend .chzn-container-single .chzn-single-with-drop { - -webkit-border-radius: 0 3px 0 0; - -moz-border-radius: 0 3px 0 0; - border-radius: 0 3px 0 0; -} -.input-append .chzn-container-single .chzn-single { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-append .chzn-container-single .chzn-single-with-drop { - -webkit-border-radius: 3px 0 0 0; - -moz-border-radius: 3px 0 0 0; - border-radius: 3px 0 0 0; -} -.input-prepend.input-append .chzn-container-single .chzn-single, -.input-prepend.input-append .chzn-container-single .chzn-single-with-drop { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.element-invisible { - position: absolute; - padding: 0; - margin: 0; - border: 0; - height: 1px; - width: 1px; - overflow: hidden; -} -.element-invisible:focus { - width: auto; - height: auto; - overflow: auto; - background: #eee; - color: #000; - padding: 1em; -} -.form-vertical .control-label { - float: none; - width: auto; - padding-right: 0; - padding-top: 0; - text-align: left; -} -.form-vertical .controls { - margin-left: 0; -} -.width-auto { - width: auto; -} -.btn-group .chzn-results { - white-space: normal; -} -.accordion-body.in:hover { - overflow: visible; -} -.invalid { - color: #9d261d; - font-weight: bold; -} -input.invalid { - border: 1px solid #9d261d; - background: #f2dede; -} -select.chzn-done.invalid + .chzn-container.chzn-container-single > a.chzn-single, -select.chzn-done.invalid + .chzn-container.chzn-container-multi > ul.chzn-choices { - border-color: #9d261d; - color: #9d261d; -} -.tooltip { - max-width: 400px; -} -.tooltip-inner { - max-width: none; - text-align: left; - text-shadow: none; -} -th .tooltip-inner { - font-weight: normal; -} -.tooltip.hasimage { - opacity: 1; -} -.tip-text { - text-align: left; -} -.btn-group > .btn + .dropdown-backdrop + .btn { - margin-left: -1px; -} -.btn-group > .btn + .dropdown-backdrop + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; - -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - *padding-top: 5px; - *padding-bottom: 5px; -} -.btn-group > .btn-mini + .dropdown-backdrop + .dropdown-toggle { - padding-left: 5px; - padding-right: 5px; - *padding-top: 2px; - *padding-bottom: 2px; -} -.btn-group > .btn-small + .dropdown-backdrop + .dropdown-toggle { - *padding-top: 5px; - *padding-bottom: 4px; -} -.btn-group > .btn-large + .dropdown-backdrop + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; - *padding-top: 7px; - *padding-bottom: 7px; -} -.dropdown-menu { - text-align: left; -} -.alert-link { - font-weight: bold; -} -.alert .alert-link { - color: #66512c; -} -.alert-success .alert-link { - color: #2b542c; -} -.alert-danger .alert-link, -.alert-error .alert-link { - color: #843534; -} -.alert-info .alert-link { - color: #245269; -} -div.modal { - position: fixed; - top: 5%; - left: 50%; - z-index: 1050; - width: 80%; - margin-left: -40%; - background-color: #fff; - border: 1px solid #999; - border: 1px solid rgba(0,0,0,0.3); - *border: 1px solid #999; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 3px 7px rgba(0,0,0,0.3); - -moz-box-shadow: 0 3px 7px rgba(0,0,0,0.3); - box-shadow: 0 3px 7px rgba(0,0,0,0.3); - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; - outline: none; -} -div.modal.fade { - -webkit-transition: opacity .3s linear, top .3s ease-out; - -moz-transition: opacity .3s linear, top .3s ease-out; - -o-transition: opacity .3s linear, top .3s ease-out; - transition: opacity .3s linear, top .3s ease-out; - top: -25%; -} -div.modal.fade.in { - top: 5%; -} -.modal-batch { - overflow-y: visible; -} -.modal-body[class^="jviewport-height"], -.modal-body[class*="jviewport-height"] { - max-height: none; -} -.jviewport-height10 { - height: 10vh; -} -.jviewport-height20 { - height: 20vh; -} -.jviewport-height30 { - height: 30vh; -} -.jviewport-height40 { - height: 40vh; -} -.jviewport-height50 { - height: 50vh; -} -.jviewport-height60 { - height: 60vh; -} -.jviewport-height70 { - height: 70vh; -} -.jviewport-height80 { - height: 80vh; -} -.jviewport-height90 { - height: 90vh; -} -.jviewport-height100 { - height: 100vh; -} -div.modal.jviewport-width10 { - width: 10vw; - margin-left: -5vw; -} -div.modal.jviewport-width20 { - width: 20vw; - margin-left: -10vw; -} -div.modal.jviewport-width30 { - width: 30vw; - margin-left: -15vw; -} -div.modal.jviewport-width40 { - width: 40vw; - margin-left: -20vw; -} -div.modal.jviewport-width50 { - width: 50vw; - margin-left: -25vw; -} -div.modal.jviewport-width60 { - width: 60vw; - margin-left: -30vw; -} -div.modal.jviewport-width70 { - width: 70vw; - margin-left: -35vw; -} -div.modal.jviewport-width80 { - width: 80vw; - margin-left: -40vw; -} -div.modal.jviewport-width90 { - width: 90vw; - margin-left: -45vw; -} -div.modal.jviewport-width100 { - width: 100vw; - margin-left: -50vw; -} -@media (max-width: 767px) { - div.modal { - position: fixed; - top: 20px; - left: 20px; - right: 20px; - width: auto; - margin: 0; - } - div.modal.fade { - top: -100px; - } - div.modal.fade.in { - top: 20px; - } - div.modal[class*="jviewport-width"] { - width: auto; - margin: 0; - } -} -@media (max-width: 480px) { - div.modal { - top: 10px; - left: 10px; - right: 10px; - } -} -@font-face { - font-family: 'IcoMoon'; - src: url('../../../../media/jui/fonts/IcoMoon.eot'); - src: url('../../../../media/jui/fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), url('../../../../media/jui/fonts/IcoMoon.woff') format('woff'), url('../../../../media/jui/fonts/IcoMoon.ttf') format('truetype'), url('../../../../media/jui/fonts/IcoMoon.svg#IcoMoon') format('svg'); - font-weight: normal; - font-style: normal; -} -[data-icon]:before { - font-family: 'IcoMoon'; - content: attr(data-icon); - speak: none; -} -[class^="icon-"], -[class*=" icon-"] { - display: inline-block; - width: 14px; - height: 14px; - margin-right: .25em; - line-height: 14px; -} -[class^="icon-"]:before, -[class*=" icon-"]:before { - font-family: 'IcoMoon'; - font-style: normal; - speak: none; -} -[class^="icon-"].disabled, -[class*=" icon-"].disabled { - font-weight: normal; -} -.icon-joomla:before { - content: "\e200"; -} -.icon-chevron-up:before, -.icon-uparrow:before, -.icon-arrow-up:before { - content: "\e005"; -} -.icon-chevron-right:before, -.icon-rightarrow:before, -.icon-arrow-right:before { - content: "\e006"; -} -.icon-chevron-down:before, -.icon-downarrow:before, -.icon-arrow-down:before { - content: "\e007"; -} -.icon-chevron-left:before, -.icon-leftarrow:before, -.icon-arrow-left:before { - content: "\e008"; -} -.icon-arrow-first:before { - content: "\e003"; -} -.icon-arrow-last:before { - content: "\e004"; -} -.icon-arrow-up-2:before { - content: "\e009"; -} -.icon-arrow-right-2:before { - content: "\e00a"; -} -.icon-arrow-down-2:before { - content: "\e00b"; -} -.icon-arrow-left-2:before { - content: "\e00c"; -} -.icon-arrow-up-3:before { - content: "\e00f"; -} -.icon-arrow-right-3:before { - content: "\e010"; -} -.icon-arrow-down-3:before { - content: "\e011"; -} -.icon-arrow-left-3:before { - content: "\e012"; -} -.icon-menu-2:before { - content: "\e00e"; -} -.icon-arrow-up-4:before { - content: "\e201"; -} -.icon-arrow-right-4:before { - content: "\e202"; -} -.icon-arrow-down-4:before { - content: "\e203"; -} -.icon-arrow-left-4:before { - content: "\e204"; -} -.icon-share:before, -.icon-redo:before { - content: "\27"; -} -.icon-undo:before { - content: "\28"; -} -.icon-forward-2:before { - content: "\e205"; -} -.icon-backward-2:before, -.icon-reply:before { - content: "\e206"; -} -.icon-unblock:before, -.icon-refresh:before, -.icon-redo-2:before { - content: "\6c"; -} -.icon-undo-2:before { - content: "\e207"; -} -.icon-move:before { - content: "\7a"; -} -.icon-expand:before { - content: "\66"; -} -.icon-contract:before { - content: "\67"; -} -.icon-expand-2:before { - content: "\68"; -} -.icon-contract-2:before { - content: "\69"; -} -.icon-play:before { - content: "\e208"; -} -.icon-pause:before { - content: "\e209"; -} -.icon-stop:before { - content: "\e210"; -} -.icon-previous:before, -.icon-backward:before { - content: "\7c"; -} -.icon-next:before, -.icon-forward:before { - content: "\7b"; -} -.icon-first:before { - content: "\7d"; -} -.icon-last:before { - content: "\e000"; -} -.icon-play-circle:before { - content: "\e00d"; -} -.icon-pause-circle:before { - content: "\e211"; -} -.icon-stop-circle:before { - content: "\e212"; -} -.icon-backward-circle:before { - content: "\e213"; -} -.icon-forward-circle:before { - content: "\e214"; -} -.icon-loop:before { - content: "\e001"; -} -.icon-shuffle:before { - content: "\e002"; -} -.icon-search:before { - content: "\53"; -} -.icon-zoom-in:before { - content: "\64"; -} -.icon-zoom-out:before { - content: "\65"; -} -.icon-apply:before, -.icon-edit:before, -.icon-pencil:before { - content: "\2b"; -} -.icon-pencil-2:before { - content: "\2c"; -} -.icon-brush:before { - content: "\3b"; -} -.icon-save-new:before, -.icon-plus-2:before { - content: "\5d"; -} -.icon-minus-sign:before, -.icon-minus-2:before { - content: "\5e"; -} -.icon-delete:before, -.icon-remove:before, -.icon-cancel-2:before { - content: "\49"; -} -.icon-publish:before, -.icon-save:before, -.icon-ok:before, -.icon-checkmark:before { - content: "\47"; -} -.icon-new:before, -.icon-plus:before { - content: "\2a"; -} -.icon-plus-circle:before { - content: "\e215"; -} -.icon-minus:before, -.icon-not-ok:before { - content: "\4b"; -} -.icon-ban-circle:before, -.icon-minus-circle:before { - content: "\e216"; -} -.icon-unpublish:before, -.icon-cancel:before { - content: "\4a"; -} -.icon-cancel-circle:before { - content: "\e217"; -} -.icon-checkmark-2:before { - content: "\e218"; -} -.icon-checkmark-circle:before { - content: "\e219"; -} -.icon-info:before { - content: "\e220"; -} -.icon-info-2:before, -.icon-info-circle:before { - content: "\e221"; -} -.icon-question:before, -.icon-question-sign:before, -.icon-help:before { - content: "\45"; -} -.icon-question-2:before, -.icon-question-circle:before { - content: "\e222"; -} -.icon-notification:before { - content: "\e223"; -} -.icon-notification-2:before, -.icon-notification-circle:before { - content: "\e224"; -} -.icon-pending:before, -.icon-warning:before { - content: "\48"; -} -.icon-warning-2:before, -.icon-warning-circle:before { - content: "\e225"; -} -.icon-checkbox-unchecked:before { - content: "\3d"; -} -.icon-checkin:before, -.icon-checkbox:before, -.icon-checkbox-checked:before { - content: "\3e"; -} -.icon-checkbox-partial:before { - content: "\3f"; -} -.icon-square:before { - content: "\e226"; -} -.icon-radio-unchecked:before { - content: "\e227"; -} -.icon-radio-checked:before, -.icon-generic:before { - content: "\e228"; -} -.icon-circle:before { - content: "\e229"; -} -.icon-signup:before { - content: "\e230"; -} -.icon-grid:before, -.icon-grid-view:before { - content: "\58"; -} -.icon-grid-2:before, -.icon-grid-view-2:before { - content: "\59"; -} -.icon-menu:before { - content: "\5a"; -} -.icon-list:before, -.icon-list-view:before { - content: "\31"; -} -.icon-list-2:before { - content: "\e231"; -} -.icon-menu-3:before { - content: "\e232"; -} -.icon-folder-open:before, -.icon-folder:before { - content: "\2d"; -} -.icon-folder-close:before, -.icon-folder-2:before { - content: "\2e"; -} -.icon-folder-plus:before { - content: "\e234"; -} -.icon-folder-minus:before { - content: "\e235"; -} -.icon-folder-3:before { - content: "\e236"; -} -.icon-folder-plus-2:before { - content: "\e237"; -} -.icon-folder-remove:before { - content: "\e238"; -} -.icon-file:before { - content: "\e016"; -} -.icon-file-2:before { - content: "\e239"; -} -.icon-file-add:before, -.icon-file-plus:before { - content: "\29"; -} -.icon-file-minus:before { - content: "\e017"; -} -.icon-file-check:before { - content: "\e240"; -} -.icon-file-remove:before { - content: "\e241"; -} -.icon-save-copy:before, -.icon-copy:before { - content: "\e018"; -} -.icon-stack:before { - content: "\e242"; -} -.icon-tree:before { - content: "\e243"; -} -.icon-tree-2:before { - content: "\e244"; -} -.icon-paragraph-left:before { - content: "\e246"; -} -.icon-paragraph-center:before { - content: "\e247"; -} -.icon-paragraph-right:before { - content: "\e248"; -} -.icon-paragraph-justify:before { - content: "\e249"; -} -.icon-screen:before { - content: "\e01c"; -} -.icon-tablet:before { - content: "\e01d"; -} -.icon-mobile:before { - content: "\e01e"; -} -.icon-box-add:before { - content: "\51"; -} -.icon-box-remove:before { - content: "\52"; -} -.icon-download:before { - content: "\e021"; -} -.icon-upload:before { - content: "\e022"; -} -.icon-home:before { - content: "\21"; -} -.icon-home-2:before { - content: "\e250"; -} -.icon-out-2:before, -.icon-new-tab:before { - content: "\e024"; -} -.icon-out-3:before, -.icon-new-tab-2:before { - content: "\e251"; -} -.icon-link:before { - content: "\e252"; -} -.icon-picture:before, -.icon-image:before { - content: "\2f"; -} -.icon-pictures:before, -.icon-images:before { - content: "\30"; -} -.icon-palette:before, -.icon-color-palette:before { - content: "\e014"; -} -.icon-camera:before { - content: "\55"; -} -.icon-camera-2:before, -.icon-video:before { - content: "\e015"; -} -.icon-play-2:before, -.icon-video-2:before, -.icon-youtube:before { - content: "\56"; -} -.icon-music:before { - content: "\57"; -} -.icon-user:before { - content: "\22"; -} -.icon-users:before { - content: "\e01f"; -} -.icon-vcard:before { - content: "\6d"; -} -.icon-address:before { - content: "\70"; -} -.icon-share-alt:before, -.icon-out:before { - content: "\26"; -} -.icon-enter:before { - content: "\e257"; -} -.icon-exit:before { - content: "\e258"; -} -.icon-comment:before, -.icon-comments:before { - content: "\24"; -} -.icon-comments-2:before { - content: "\25"; -} -.icon-quote:before, -.icon-quotes-left:before { - content: "\60"; -} -.icon-quote-2:before, -.icon-quotes-right:before { - content: "\61"; -} -.icon-quote-3:before, -.icon-bubble-quote:before { - content: "\e259"; -} -.icon-phone:before { - content: "\e260"; -} -.icon-phone-2:before { - content: "\e261"; -} -.icon-envelope:before, -.icon-mail:before { - content: "\4d"; -} -.icon-envelope-opened:before, -.icon-mail-2:before { - content: "\4e"; -} -.icon-unarchive:before, -.icon-drawer:before { - content: "\4f"; -} -.icon-archive:before, -.icon-drawer-2:before { - content: "\50"; -} -.icon-briefcase:before { - content: "\e020"; -} -.icon-tag:before { - content: "\e262"; -} -.icon-tag-2:before { - content: "\e263"; -} -.icon-tags:before { - content: "\e264"; -} -.icon-tags-2:before { - content: "\e265"; -} -.icon-options:before, -.icon-cog:before { - content: "\38"; -} -.icon-cogs:before { - content: "\37"; -} -.icon-screwdriver:before, -.icon-tools:before { - content: "\36"; -} -.icon-wrench:before { - content: "\3a"; -} -.icon-equalizer:before { - content: "\39"; -} -.icon-dashboard:before { - content: "\78"; -} -.icon-switch:before { - content: "\e266"; -} -.icon-filter:before { - content: "\54"; -} -.icon-purge:before, -.icon-trash:before { - content: "\4c"; -} -.icon-checkedout:before, -.icon-lock:before, -.icon-locked:before { - content: "\23"; -} -.icon-unlock:before { - content: "\e267"; -} -.icon-key:before { - content: "\5f"; -} -.icon-support:before { - content: "\46"; -} -.icon-database:before { - content: "\62"; -} -.icon-scissors:before { - content: "\e268"; -} -.icon-health:before { - content: "\6a"; -} -.icon-wand:before { - content: "\6b"; -} -.icon-eye-open:before, -.icon-eye:before { - content: "\3c"; -} -.icon-eye-close:before, -.icon-eye-blocked:before, -.icon-eye-2:before { - content: "\e269"; -} -.icon-clock:before { - content: "\6e"; -} -.icon-compass:before { - content: "\6f"; -} -.icon-broadcast:before, -.icon-connection:before, -.icon-wifi:before { - content: "\e01b"; -} -.icon-book:before { - content: "\e271"; -} -.icon-lightning:before, -.icon-flash:before { - content: "\79"; -} -.icon-print:before, -.icon-printer:before { - content: "\e013"; -} -.icon-feed:before { - content: "\71"; -} -.icon-calendar:before { - content: "\43"; -} -.icon-calendar-2:before { - content: "\44"; -} -.icon-calendar-3:before { - content: "\e273"; -} -.icon-pie:before { - content: "\77"; -} -.icon-bars:before { - content: "\76"; -} -.icon-chart:before { - content: "\75"; -} -.icon-power-cord:before { - content: "\32"; -} -.icon-cube:before { - content: "\33"; -} -.icon-puzzle:before { - content: "\34"; -} -.icon-attachment:before, -.icon-paperclip:before, -.icon-flag-2:before { - content: "\72"; -} -.icon-lamp:before { - content: "\74"; -} -.icon-pin:before, -.icon-pushpin:before { - content: "\73"; -} -.icon-location:before { - content: "\63"; -} -.icon-shield:before { - content: "\e274"; -} -.icon-flag:before { - content: "\35"; -} -.icon-flag-3:before { - content: "\e275"; -} -.icon-bookmark:before { - content: "\e023"; -} -.icon-bookmark-2:before { - content: "\e276"; -} -.icon-heart:before { - content: "\e277"; -} -.icon-heart-2:before { - content: "\e278"; -} -.icon-thumbs-up:before { - content: "\5b"; -} -.icon-thumbs-down:before { - content: "\5c"; -} -.icon-unfeatured:before, -.icon-asterisk:before, -.icon-star-empty:before { - content: "\40"; -} -.icon-star-2:before { - content: "\41"; -} -.icon-featured:before, -.icon-default:before, -.icon-star:before { - content: "\42"; -} -.icon-smiley:before, -.icon-smiley-happy:before { - content: "\e279"; -} -.icon-smiley-2:before, -.icon-smiley-happy-2:before { - content: "\e280"; -} -.icon-smiley-sad:before { - content: "\e281"; -} -.icon-smiley-sad-2:before { - content: "\e282"; -} -.icon-smiley-neutral:before { - content: "\e283"; -} -.icon-smiley-neutral-2:before { - content: "\e284"; -} -.icon-cart:before { - content: "\e019"; -} -.icon-basket:before { - content: "\e01a"; -} -.icon-credit:before { - content: "\e286"; -} -.icon-credit-2:before { - content: "\e287"; -} -.icon-expired:before { - content: "\4b"; -} -.icon-edit:before { - color: #24748c; -} -.icon-publish:before, -.icon-save:before, -.icon-ok:before, -.icon-save-new:before, -.icon-save-copy:before, -.btn-toolbar .icon-copy:before { - color: #378137; -} -.icon-unpublish:before, -.icon-not-ok:before, -.icon-eye-close:before, -.icon-ban-circle:before, -.icon-minus-sign:before, -.btn-toolbar .icon-cancel:before { - color: #942a25; -} -.icon-featured:before, -.icon-default:before, -.icon-expired:before, -.icon-pending:before { - color: #c67605; -} -.icon-back:before { - content: "\e008"; -} -html { - height: 100%; -} -body { - height: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - box-sizing: border-box; -} -a:hover, -a:active, -a:focus { - outline: none; -} -.small { - font-size: 11px; -} -.row-even .small, -.row-odd .small, -.row-even .small a, -.row-odd .small a { - color: #888; -} -.content-title { - font-size: 24px; - font-weight: normal; - line-height: 26px; - margin-top: 0; -} -.well .page-header { - margin: -10px 0 18px 0; - padding-bottom: 5px; -} -.well .module-title.nav-header { - padding: 0 0 7px; - margin: 0; - font-size: 13px; -} -.well .row-even p, -.well .row-odd p { - margin-bottom: 0; -} -h1, -h2, -h3, -h4, -h5, -h6 { - margin: 12px 0; -} -h1 { - font-size: 26px; - line-height: 28px; -} -h2 { - font-size: 22px; - line-height: 24px; -} -h3 { - font-size: 18px; - line-height: 20px; -} -h4 { - font-size: 14px; - line-height: 16px; -} -h5 { - font-size: 13px; - line-height: 15px; -} -h6 { - font-size: 12px; - line-height: 14px; -} -.truncate { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.chzn-container .chzn-drop { - border-radius: 0 0 3px 3px; -} -.control-group .chzn-container { - max-width: 100%; -} -.control-group .chzn-container .chzn-choices li.search-field, -.control-group .chzn-container .chzn-choices li.search-field input { - width: 100% !important; -} -.chzn-container-single .chzn-single { - background-color: #fff; - background-clip: inherit; - background-image: none; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,0.2); - border-radius: 3px; - box-shadow: 0 1px 0 rgba(255,255,255,0.2) inset, 0 1px 2px rgba(0,0,0,0.05); - height: auto; - line-height: 26px; -} -.chzn-container-single .chzn-single div { - background-color: #f3f3f3; - border-left: 1px solid #ccc; - bottom: 0; - height: auto; - text-align: center; - width: 28px; -} -.chzn-container-single .chzn-single div b { - background-image: none; - display: inline-block; -} -.chzn-container-single .chzn-single div b:after { - content: '\E011'; - font-family: IcoMoon; -} -.chzn-container-single .chzn-single abbr { - background: none; - right: 36px; - top: 0; -} -.chzn-container-single .chzn-single abbr:before { - font-family: IcoMoon; - content: '\0049'; - font-size: 10px; - line-height: 26px; -} -.chzn-container-single .chzn-single abbr:hover { - color: #000; -} -.chzn-container-single .chzn-search:after { - content: '\0053'; - font-family: IcoMoon; - position: relative; - right: 20px; - top: 2px; -} -.chzn-container-single .chzn-search input[type="text"] { - background: none; - border-radius: 3px; - border: 1px solid #ccc; - box-shadow: none; - height: 25px; -} -.chzn-container-single .chzn-search input[type="text"]:focus { - border-color: #3071A9; -} -.chzn-container-single .chzn-drop { - background-clip: padding-box; - border-color: #3071A9; - border-radius: 0 0 3px 3px; -} -.chzn-container-active .chzn-single { - color: #3071A9; -} -.chzn-container-active.chzn-with-drop .chzn-single { - background-image: none; - border: 1px solid #3071A9; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} -.chzn-container-active.chzn-with-drop .chzn-single div { - background-color: #f3f3f3; - border-bottom: 1px solid #ccc; - border-bottom-left-radius: 3px; - border-left: 1px solid #ccc; -} -.chzn-container-active.chzn-with-drop .chzn-single div b:after { - content: '\E00F'; - font-family: IcoMoon; -} -.chzn-container-active.chzn-container-multi .chzn-choices { - border: 1px solid #3071A9; - box-shadow: none; -} -.chzn-container .chzn-results { - background-color: #fff; - border-radius: 0 0 3px 3px; - margin: 0; - padding: 0; -} -.chzn-container .chzn-results li.highlighted { - background-color: #3071A9; - background-image: none; -} -.chzn-color[rel="value_"] div { - background-color: #f3f3f3; - border-left: 1px solid #ccc; -} -.chzn-color-state.chzn-single div, -.chzn-color.chzn-single[rel="value_0"] div, -.chzn-color.chzn-single[rel="value_1"] div, -.chzn-color-state.chzn-single[rel="value_-1"] div, -.chzn-color-state.chzn-single[rel="value_-2"] div, -.chzn-color.chzn-single[rel="value_hide"] div, -.chzn-color.chzn-single[rel="value_show_no_link"] div, -.chzn-color.chzn-single[rel="value_show_with_link"] div { - background-color: transparent !important; - border: none !important; -} -.chzn-container-active .chzn-choices { - border: 1px solid #3071A9; -} -.chzn-container-multi .chzn-choices { - background-image: none; - border-radius: 3px; - border: 1px solid #ccc; -} -.chzn-container-multi .chzn-choices li.search-choice { - background-color: #3071A9; - background-image: none; - border: 0; - box-shadow: none; - color: #fff; - line-height: 20px; - padding: 0 7px; -} -.chzn-container-multi .chzn-choices li.search-choice .search-choice-close { - color: #f5f5f5; - display: inline-block; - margin-left: 5px; - position: relative; - top: 0; - left: 0; - background-image: none; - font-size: inherit; -} -.chzn-container-multi .chzn-choices li.search-choice .search-choice-close:hover { - text-decoration: none; -} -.chzn-container-multi .chzn-choices li.search-choice .search-choice-close:before { - font-family: IcoMoon; - content: '\004A'; - position: relative; - right: 1px; - top: 0; -} -.js-stools .js-stools-container-bar .js-stools-field-filter .chzn-container { - margin: 1px 0; - padding: 0 !important; -} -.chzn-color.chzn-single[rel="value_1"], -.chzn-color-reverse.chzn-single[rel="value_0"], -.chzn-color-state.chzn-single[rel="value_1"], -.chzn-color.chzn-single[rel="value_show_no_link"], -.chzn-color.chzn-single[rel="value_show_with_link"] { - background-color: #46a546; - *background-color: #46a546; - box-shadow: 0 1px 2px rgba(0,0,0,0.05); - color: #ffffff; -} -.chzn-color.chzn-single[rel="value_1"]:hover, -.chzn-color.chzn-single[rel="value_1"]:focus, -.chzn-color.chzn-single[rel="value_1"]:active, -.chzn-color.chzn-single[rel="value_1"].active, -.chzn-color.chzn-single[rel="value_1"].disabled, -.chzn-color.chzn-single[rel="value_1"][disabled], -.chzn-color-reverse.chzn-single[rel="value_0"]:hover, -.chzn-color-reverse.chzn-single[rel="value_0"]:focus, -.chzn-color-reverse.chzn-single[rel="value_0"]:active, -.chzn-color-reverse.chzn-single[rel="value_0"].active, -.chzn-color-reverse.chzn-single[rel="value_0"].disabled, -.chzn-color-reverse.chzn-single[rel="value_0"][disabled], -.chzn-color-state.chzn-single[rel="value_1"]:hover, -.chzn-color-state.chzn-single[rel="value_1"]:focus, -.chzn-color-state.chzn-single[rel="value_1"]:active, -.chzn-color-state.chzn-single[rel="value_1"].active, -.chzn-color-state.chzn-single[rel="value_1"].disabled, -.chzn-color-state.chzn-single[rel="value_1"][disabled], -.chzn-color.chzn-single[rel="value_show_no_link"]:hover, -.chzn-color.chzn-single[rel="value_show_no_link"]:focus, -.chzn-color.chzn-single[rel="value_show_no_link"]:active, -.chzn-color.chzn-single[rel="value_show_no_link"].active, -.chzn-color.chzn-single[rel="value_show_no_link"].disabled, -.chzn-color.chzn-single[rel="value_show_no_link"][disabled], -.chzn-color.chzn-single[rel="value_show_with_link"]:hover, -.chzn-color.chzn-single[rel="value_show_with_link"]:focus, -.chzn-color.chzn-single[rel="value_show_with_link"]:active, -.chzn-color.chzn-single[rel="value_show_with_link"].active, -.chzn-color.chzn-single[rel="value_show_with_link"].disabled, -.chzn-color.chzn-single[rel="value_show_with_link"][disabled] { - color: #fff; - background-color: #2f6f2f; - *background-color: #2f6f2f; -} -.chzn-color.chzn-single[rel="value_1"]:active, -.chzn-color.chzn-single[rel="value_1"].active, -.chzn-color-reverse.chzn-single[rel="value_0"]:active, -.chzn-color-reverse.chzn-single[rel="value_0"].active, -.chzn-color-state.chzn-single[rel="value_1"]:active, -.chzn-color-state.chzn-single[rel="value_1"].active, -.chzn-color.chzn-single[rel="value_show_no_link"]:active, -.chzn-color.chzn-single[rel="value_show_no_link"].active, -.chzn-color.chzn-single[rel="value_show_with_link"]:active, -.chzn-color.chzn-single[rel="value_show_with_link"].active { - background-color: #46a546; -} -.chzn-color-state.chzn-single[rel="value_0"], -.chzn-color-state.chzn-single[rel="value_-2"] { - background-color: #bd362f; - *background-color: #bd362f; - box-shadow: 0 1px 2px rgba(0,0,0,0.05); - color: #ffffff; -} -.chzn-color-state.chzn-single[rel="value_0"]:hover, -.chzn-color-state.chzn-single[rel="value_0"]:focus, -.chzn-color-state.chzn-single[rel="value_0"]:active, -.chzn-color-state.chzn-single[rel="value_0"].active, -.chzn-color-state.chzn-single[rel="value_0"].disabled, -.chzn-color-state.chzn-single[rel="value_0"][disabled], -.chzn-color-state.chzn-single[rel="value_-2"]:hover, -.chzn-color-state.chzn-single[rel="value_-2"]:focus, -.chzn-color-state.chzn-single[rel="value_-2"]:active, -.chzn-color-state.chzn-single[rel="value_-2"].active, -.chzn-color-state.chzn-single[rel="value_-2"].disabled, -.chzn-color-state.chzn-single[rel="value_-2"][disabled] { - color: #fff; - background-color: #802420; - *background-color: #802420; -} -.chzn-color-state.chzn-single[rel="value_0"]:active, -.chzn-color-state.chzn-single[rel="value_0"].active, -.chzn-color-state.chzn-single[rel="value_-2"]:active, -.chzn-color-state.chzn-single[rel="value_-2"].active { - background-color: #bd362f; -} -.CodeMirror { - height: calc(100vh - 400px); - min-height: 400px; - max-height: 800px; -} -.form-horizontal .control-label { - padding-right: 5px; - text-align: left; -} -.form-horizontal .control-label .spacer hr { - width: 380px; -} -@media (max-width: 420px) { - .form-horizontal .control-label .spacer hr { - width: 220px; - } -} -.form-horizontal .field-spacer>.control-label { - width: auto; -} -.form-horizontal #jform_catid_chzn { - vertical-align: middle; -} -.form-vertical .control-label > label { - display: inline-block; - *display: inline; - *zoom: 1; -} -.form-vertical .controls { - margin-left: 0; -} -@media (max-width: 979px) { - .form-horizontal-desktop .control-label { - float: none; - width: auto; - padding-right: 0; - padding-top: 0; - text-align: left; - } - .form-horizontal-desktop .control-label > label { - display: inline-block; - *display: inline; - *zoom: 1; - } - .form-horizontal-desktop .controls { - margin-left: 0; - } -} -@media (max-width: 1199px) { - .row-fluid .row-fluid .form-horizontal-desktop .control-label { - float: none; - width: auto; - padding-right: 0; - padding-top: 0; - text-align: left; - } - .row-fluid .row-fluid .form-horizontal-desktop .control-label > label { - display: inline-block; - *display: inline; - *zoom: 1; - } - .row-fluid .row-fluid .form-horizontal-desktop .controls { - margin-left: 0; - } -} -.form-inline-header { - margin: 5px 0; -} -.form-inline-header .control-group, -.form-inline-header .control-label, -.form-inline-header .controls { - display: inline-block; - *display: inline; - *zoom: 1; -} -.form-inline-header .control-label { - width: auto; - padding-right: 10px; -} -.form-inline-header .controls { - padding-right: 20px; -} -fieldset[class^="form-"] { - min-width: 100%; -} -@-moz-document url-prefix() { - fieldset[class^="form-"] { - display: table-cell; - } -} -fieldset.checkboxes input { - float: left; -} -fieldset.checkboxes li { - list-style: none; -} -.control-group, -.controls, -.controls input[type="text"], -.controls input[type="number"], -.controls input[type="email"], -.controls select, -.controls textarea { - max-width: 100%; -} -.controls .btn-group > .btn { - min-width: 50px; - margin-left: -1px; -} -.controls .btn-group.btn-group-yesno { - width: 220px; - max-width: 100%; -} -.controls .btn-group.btn-group-yesno > .btn { - width: 50%; - min-width: 40px; - padding: 2px 0; -} -input.input-large-text { - font-size: 18px; - line-height: 22px; - height: auto; -} -textarea { - resize: both; -} -textarea.vert { - resize: vertical; -} -textarea.noResize { - resize: none; -} -.subform-repeatable { - padding-right: 10px; -} -.subform-repeatable > .btn-toolbar { - margin: 0; -} -.subform-repeatable > .btn-toolbar .group-add { - line-height: 26px; - width: 56px; - font-size: 13px; - margin-left: 28px; -} -.subform-repeatable-group { - margin-top: 20px; - margin-left: 28px; - border: 1px solid #ccc; - padding: 8px 25px 15px; - position: relative; - border-radius: 3px; -} -.subform-repeatable-group > .btn-toolbar { - margin: 0; -} -.subform-repeatable-group > .btn-toolbar .btn-group { - margin-right: 0px; - margin-top: -1px; - position: static; -} -.subform-repeatable-group > .btn-toolbar .btn { - font-size: 13px; - line-height: 26px; - background-color: #F3F3F3; - position: absolute; -} -.subform-repeatable-group > .btn-toolbar .btn span { - vertical-align: middle; - line-height: 11px; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-success { - color: #378137; - bottom: 0; - right: 0; - border-radius: 3px 0 0 0; - border-width: 1px 0 0 1px; - padding-top: 1px; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-success .icon-plus:before { - content: "]"; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-danger { - color: #942a25; - top: 0; - right: 0; - border-radius: 0 0 0 3px; - border-width: 0 0 1px 1px; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-danger .icon-minus:before { - content: "I"; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-primary { - color: #24748c; - color: #333; - right: 100%; - top: 50%; - margin-top: -27px; - margin-right: 1px; - border-radius: 3px 0 0 3px; - border-width: 1px 0 1px 1px; - line-height: 52px; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-primary .icon-move:before { - content: "Z"; -} -.subform-repeatable-group > .btn-toolbar .btn [class^="icon-"], -.subform-repeatable-group > .btn-toolbar .btn [class*=" icon-"] { - margin: 0; -} -.subform-repeatable-group > .btn-toolbar .btn:hover { - background-color: #E6E6E6; -} -.subform-repeatable-group .control-group:last-of-type { - margin-bottom: 10px; -} -@media (max-width: 979px) { - .subform-repeatable-group > .btn-toolbar .btn-group { - margin-bottom: 10px; - } -} -.subform-table-layout .control-group, -.subform-table-layout .control-group:last-of-type { - margin-bottom: 0; -} -.subform-table-layout .controls { - padding-right: 20px; -} -.subform-table-layout input { - width: 100%; - max-width: 206px; -} -.subform-table-layout table .btn-group { - margin: 0 7px; -} -@media (max-width: 1024px) { - .subform-table-layout .subform-repeatable { - padding-right: 0; - } - .subform-table-layout .subform-repeatable tbody td:last-of-type { - text-align: right; - padding-bottom: 15px; - } - .subform-table-layout table, - .subform-table-layout thead, - .subform-table-layout tbody, - .subform-table-layout th, - .subform-table-layout td, - .subform-table-layout tr { - display: block; - } - .subform-table-layout table { - border: 1px solid #ddd; - } - .subform-table-layout thead th { - position: absolute; - top: -9999px; - left: -9999px; - } - .subform-table-layout thead th:last-of-type { - position: static; - width: 100% !important; - text-align: right; - box-sizing: border-box; - border-left: 0; - } - .subform-table-layout tr { - margin: 0; - padding: 0; - border: 0; - } - .subform-table-layout td { - border: none; - position: relative; - padding-left: 50%; - } - .subform-table-layout tbody td:first-of-type { - padding-top: 15px; - border-top: 1px solid #ddd; - } - .subform-table-layout tbody td:first-of-type:before { - top: 18px; - } - .subform-table-layout td:before { - content: attr(data-column); - position: absolute; - top: 13px; - left: 10px; - padding-right: 10px; - } -} -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 0; -} -.form-horizontal .controls > .radio:first-child, -.form-horizontal .controls > .checkbox:first-child { - padding-top: 5px; -} -.form-horizontal .controls > .radio.btn-group:first-child { - padding-top: 0; -} -.form-horizontal .controls > .radio.btn-group-yesno:first-child { - padding-top: 2px; -} -.header { - background-color: #1a3867; - border-top: 1px solid rgba(255,255,255,0.2); - padding: 8px 25px; -} -@media (max-width: 767px) { - .header { - padding: 4px 18px; - margin-left: -20px; - margin-right: -20px; - } -} -.header .navbar-search { - margin-top: 0; -} -@media (max-width: 979px) { - .header .navbar-search { - border-top: 0; - border-bottom: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } -} -.container-logo { - float: right; - text-align: right; -} -.logo { - width: auto; - max-width: 100%; - max-height: 36px; - height: auto; -} -.page-title { - color: white; - font-weight: normal; - font-size: 20px; - line-height: 36px; - margin: 0; -} -.page-title [class^="icon-"], -.page-title [class*=" icon-"] { - margin-right: 16px; -} -@media (max-width: 767px) { - .container-logo { - display: none; - } - .page-title { - font-size: 18px; - line-height: 28px; - } - .page-title [class^="icon-"], - .page-title [class*=" icon-"] { - margin-right: 10px; - } -} -.view-login { - background-color: #17568c; - padding-top: 0; -} -.view-login .container { - width: 300px; - position: absolute; - top: 50%; - left: 50%; - margin-top: -206px; - margin-left: -150px; -} -.view-login .navbar-fixed-bottom { - padding-left: 20px; - padding-right: 20px; - text-align: center; -} -.view-login .navbar-fixed-bottom, -.view-login .navbar-fixed-bottom a { - color: #FCFCFC; -} -.view-login .navbar-inverse.navbar-fixed-bottom, -.view-login .navbar-inverse.navbar-fixed-bottom a { - color: #555; -} -.view-login .well { - padding-bottom: 0; -} -.view-login .login-joomla { - position: absolute; - left: 50%; - height: 24px; - width: 24px; - margin-left: -12px; - font-size: 22px; -} -.view-login .navbar-fixed-bottom { - position: absolute; -} -.view-login .input-medium { - width: 176px; -} -.view-login #lang_chzn { - width: 233px !important; - max-width: none; -} -.view-login #lang_chzn .chzn-single div { - width: 43px; -} -.view-login .input-prepend .add-on, -.view-login .controls .btn-group > .btn { - margin-left: 0; -} -.navbar-inverse { - color: #333; -} -.login .btn-large { - margin-top: 15px; -} -.login .form-inline .btn-group { - display: block; -} -@media (max-width: 479px) { - .login .chzn-single { - width: 222px !important; - } - .login .chzn-container, - .login .chzn-drop { - width: 230px !important; - } -} -@media (max-width: 319px) { - .view-login .navbar-fixed-bottom { - display: none; - } -} -ul.manager .height-50 .icon-folder-2 { - height: 35px; - width: 35px; - line-height: 35px; - font-size: 30px; -} -#imageForm { - margin: -25px 0 0; -} -#imageForm .well { - margin-bottom: 5px; -} -.thumbnails-media { - margin-left: 0; -} -.thumbnails-media .thumbnail { - background-color: #f4f4f4; - border-radius: 3px; - border: 0; - box-shadow: 0 0 0 1px rgba(0,0,0,0.05) inset; - padding: 0px; - height: 100px; - width: 100px; - margin: 8px 16px; - margin-left: 0 !important; - position: relative; - text-align: center; - overflow: hidden; -} -.thumbnails-media .thumbnail .close { - background-color: #ccc; - border-left: 1px solid rgba(0,0,0,0.1); - height: 22px; - line-height: 22px; - opacity: 0.3; - text-align: center; - width: 22px; - top: 0; - right: 0; -} -.thumbnails-media .thumbnail .close:hover { - background-color: #bbb; -} -.thumbnails-media .thumbnail *, -.thumbnails-media .thumbnail *:before { - -webkit-transition: all 0.2s ease; - transition: all 0.2s ease; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.thumbnails-media .thumbnail input[type="radio"], -.thumbnails-media .thumbnail input[type="checkbox"] { - margin: 0; - opacity: 0.55; - position: absolute; - top: 5px; - left: 5px; -} -.thumbnails-media .thumbnail .controls, -.thumbnails-media .thumbnail .imginfoBorder { - display: none; -} -.thumbnails-media .imgThumb { - position: relative; - z-index: 1; - width: 100%; - display: inline-block; -} -.thumbnails-media .imgThumb input { - display: none; -} -.thumbnails-media .imgThumb label, -.thumbnails-media .imgThumb .imgThumbInside { - display: block; - line-height: 100px; - position: relative; - width: 100%; - border-radius: 3px; - overflow: hidden; -} -.thumbnails-media .imgThumb label:before, -.thumbnails-media .imgThumb .imgThumbInside:before { - font-family: "IcoMoon"; - font-style: normal; - content: 'G'; - position: absolute; - top: 0; - right: 0; - background-color: #46a546; - color: #fff; - line-height: 26px; - width: 26px; - -webkit-transform: scale(0.5); - transform: scale(0.5); - opacity: 0; - border-color: rgba(0,0,0,0.2); - box-shadow: 0 1px 2px rgba(0,0,0,0.05); - border-radius: 0 3px; -} -.thumbnails-media .imgThumb img { - width: auto; -} -.thumbnails-media .selected :checked + label, -.thumbnails-media .selected .imgThumbInside, -.thumbnails-media .imgInput :checked + label, -.thumbnails-media .imgInput .imgThumbInside { - background-color: #ddd; -} -.thumbnails-media .selected :checked + label:before, -.thumbnails-media .selected .imgThumbInside:before, -.thumbnails-media .imgInput :checked + label:before, -.thumbnails-media .imgInput .imgThumbInside:before { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 1; -} -.thumbnails-media .selected :checked + label:after, -.thumbnails-media .selected .imgThumbInside:after, -.thumbnails-media .imgInput :checked + label:after, -.thumbnails-media .imgInput .imgThumbInside:after { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - content: ''; - border: 3px solid #46a546; - border-radius: 5px; -} -.thumbnails-media .imgDelete a.close, -.thumbnails-media .imgPreview a { - padding: 0; - position: absolute; - left: 0; - z-index: 1; - height: 26px; - width: 26px; -} -.thumbnails-media .imgPreview a { - width: 100%; -} -.thumbnails-media .imgDelete a.close { - background-color: #bd362f; - border-color: #bd362f rgba(0,0,0,0.2) rgba(0,0,0,0.2) #bd362f; - top: 0; - line-height: 28px; - font-size: 12px; - padding-left: 1px; - color: #fff; - border-bottom-right-radius: 3px; - border-top-left-radius: 3px; - z-index: 10; - opacity: 0; - -webkit-transform: scale(0.5); - transform: scale(0.5); -} -.thumbnails-media .imgDelete a.close:hover { - background-color: #802420; -} -.thumbnails-media .thumbnail:hover .imgDelete a.close { - opacity: 1; - -webkit-transform: scale(1); - transform: scale(1); -} -.thumbnails-media .imgPreview a, -.thumbnails-media .imgDetails { - position: absolute; - left: 0; - text-align: left; - background-color: #fff; - border-color: rgba(0,0,0,0.2); - bottom: 0; - line-height: 26px; - border: 1px solid rgba(0,0,0,0.1); - border-width: 1px; - border-radius: 0 3px 0 0; - z-index: 1; -} -.thumbnails-media .imgPreview a:hover, -.thumbnails-media .imgDetails:hover { - background-color: #eee; -} -.thumbnails-media .imgDetails { - padding: 0 5px; - line-height: 20px; - color: #555; -} -.thumbnails-media .imgFolder span { - line-height: 90px; - font-size: 38px; - margin: 0; - width: auto; -} -.thumbnails-media .imgFolder + .imgDetails { - color: inherit; -} -.com_media .media a + a { - margin-left: -1px; -} -.com_media .tree-holder { - padding: 0 15px; -} -#folderframe.thumbnail { - border: 0; - box-shadow: none; - padding: 0; -} -#mediamanager-form { - margin: 0 -10px; -} -#mediamanager-form > .muted { - padding: 0px; -} -#mediamanager-form .checkbox { - padding-left: 30px; - margin-bottom: 15px; -} -#mediamanager-form .checkbox input { - margin-top: 3px; -} -#mediamanager-form .thumbnails .thumbnail { - height: 120px; - width: 120px; - margin: 0 18px 18px 0; -} -#mediamanager-form .thumbnails .imgThumb label, -#mediamanager-form .thumbnails .imgTotal { - line-height: 120px; -} -#mediamanager-form .icon-search::before { - padding-right: 5px; - padding-left: 1px; -} -#mediamanager-form .height-50 { - background-color: #fafafa; - height: 77px; - position: relative; - z-index: 1; - width: 100%; - display: inline-block; -} -#mediamanager-form .height-50 a, -#mediamanager-form .height-50 .icon-folder-2 { - display: inline-block; - line-height: 75px; - margin-top: -1px; -} -#mediamanager-form .height-50 a:after { - bottom: 0; - box-shadow: 0 0 0 1px rgba(0,0,0,0.08) inset; - content: ""; - display: block; - left: 0; - overflow: hidden; - position: absolute; - right: 0; - top: 0; -} -#mediamanager-form .height-50 .icon-folder-2 { - font-size: 40px; -} -.uploadform { - margin-top: 20px; -} -body.modal-open { - -ms-overflow-style: none; -} -.modal-header { - padding: 0 20px; - text-align: left; -} -.modal-header h3 { - font-weight: normal; - line-height: 50px; -} -.modal-header .close { - width: 50px; - margin-top: 0; - margin-right: -15px; - font-size: 2rem; - line-height: 50px; - border-left: 1px solid #ccc; -} -.modal-body { - padding: 0; - width: 100%; - height: auto; -} -.modal-body .container-fluid { - padding-top: 15px; - padding-bottom: 15px; -} -.modal-footer { - clear: both; -} -.contentpane { - padding: 10px; - height: auto; -} -@media (min-width: 768px) { - .row-fluid .modal-batch [class*="span"] { - margin-left: 0; - } -} -.container-popup { - padding: 28px 10px 10px 10px; -} -body .navbar, -body .navbar-fixed-top { - margin-bottom: 0; -} -.navbar-inner { - min-height: 0; - background: #f2f2f2; - background-image: none; - filter: none; -} -.navbar-inner .container-fluid { - padding-left: 10px; - padding-right: 10px; - font-size: 15px; -} -.navbar-inverse .navbar-inner { - background: #10223e; - background-image: none; - filter: none; -} -.navbar .navbar-text { - line-height: 30px; -} -.navbar .admin-logo { - float: left; - padding: 7px 12px 0px 15px; - font-size: 16px; - color: #555; -} -.navbar .admin-logo:hover { - color: #333; -} -.navbar-inverse.navbar .admin-logo { - color: #d9d9d9; -} -.navbar-inverse.navbar .admin-logo:hover { - color: #ffffff; -} -.navbar .brand { - float: right; - display: block; - padding: 6px 10px; - margin-left: -20px; - font-size: inherit; - font-weight: normal; -} -.navbar .brand:hover, -.navbar .brand:focus { - text-decoration: none; -} -.navbar .nav > li > a { - padding: 6px 10px; -} -.navbar .nav > li > a:hover { - color: white; -} -.navbar .nav > li > a:hover span.carot { - border-bottom-color: #fff; - border-top-color: #fff; -} -.navbar .dropdown-menu, -.navbar .nav-user { - font-size: 13px; -} -.navbar .nav-user .dropdown-menu li span { - padding-left: 10px; -} -.navbar .nav > li ul { - overflow-y: auto; - overflow-x: hidden; - -webkit-overflow-scrolling: touch; - -moz-overflow-scrolling: touch; - -ms-overflow-scrolling: touch; - -o-overflow-scrolling: touch; - overflow-scrolling: touch; - height: auto; - max-height: 500px; - margin: 0; -} -.navbar .nav > li ul::-webkit-scrollbar { - -webkit-appearance: none; - width: 7px; -} -.navbar .nav > li ul::-webkit-scrollbar-thumb { - border-radius: 4px; - background-color: rgba(0,0,0,0.5); - -webkit-box-shadow: 0 0 1px rgba(255,255,255,0.5); -} -.navbar .nav > li > .dropdown-menu:after { - display: none; -} -.navbar .nav > .dropdown.open:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #fff; - position: absolute; - top: 25px; - left: 10px; - z-index: 1001; -} -.navbar .empty-nav { - display: none; -} -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-submenu:hover > a, -.dropdown-submenu:focus > a { - background-image: none; -} -.navbar-fixed-bottom { - bottom: 0; -} -.navbar-fixed-bottom .navbar-inner { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.navbar .btn-navbar { - background: #17568c; - border: 1px solid #0D2242; - margin-bottom: 2px; -} -@media (max-width: 767px) { - .navbar .admin-logo { - margin-left: 10px; - padding: 9px 9px 0 9px; - } -} -.navbar-search .search-query { - background: rgba(255,255,255,0.3); -} -@media (max-width: 979px) { - .navbar .nav { - font-size: 13px; - margin: 0 2px 0 0; - } - .navbar .nav > li > a { - padding: 6px; - } -} -@media (max-width: 767px) { - .navbar-search.pull-right { - float: none; - text-align: center; - } -} -@media (max-width: 738px) { - .navbar .brand { - font-size: 16px; - } -} -.nav-collapse .nav li a, -.dropdown-menu a { - background-image: none; -} -.nav-collapse .dropdown-menu > li img { - max-width: none; -} -@media (max-width: 767px) { - .navbar-fixed-top .navbar-inner, - .navbar-fixed-top .navbar-inner .container-fluid { - padding: 0; - } - .navbar .brand { - margin-top: 2px; - float: none; - text-align: center; - } - .navbar .btn-navbar { - margin-top: 3px; - margin-right: 3px; - margin-bottom: 3px; - } - .nav-collapse .nav .nav-header { - color: #fff; - } - .nav-collapse .nav, - .navbar .nav-collapse .nav.pull-right { - margin: 0; - } - .nav-collapse .dropdown-menu { - margin: 0; - } - .nav-collapse .dropdown-menu > li > span { - display: block; - padding: 4px 15px; - } - .navbar-inverse .nav-collapse .dropdown-menu > li > span { - color: #d9d9d9; - } - .nav-collapse .nav > li > a.dropdown-toggle { - background-color: rgba(255,255,255,0.07); - font-size: 12px; - font-weight: bold; - color: #eee; - text-transform: uppercase; - padding-left: 15px; - } - .nav-collapse .nav li a { - margin-bottom: 0; - border-top: 1px solid rgba(255,255,255,0.25); - border-bottom: 1px solid rgba(0,0,0,0.5); - } - .nav-collapse .nav li ul li ul.dropdown-menu, - .nav-collapse .nav li ul li:hover ul.dropdown-menu, - .nav-collapse .caret { - display: none !important; - } - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - font-size: 15px; - font-weight: normal; - color: #fff; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - } - .navbar .nav-collapse .nav > li > .dropdown-menu::before, - .navbar .nav-collapse .nav > li > .dropdown-menu::after, - .navbar .nav-collapse .dropdown-submenu > a::after { - display: none; - } - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 0; - } -} -.quick-icons { - font-size: 14px; - margin-bottom: 20px; -} -.quick-icons .nav-header { - margin: 12px 0 5px; - font-size: 13px; -} -.quick-icons .nav-header:first-child { - margin: 0 0 5px; -} -.quick-icons [class^="icon-"], -.quick-icons [class*=" icon-"] { - margin-right: 9px; -} -.quick-icons [class^="icon-"]:before, -.quick-icons [class*=" icon-"]:before { - font-size: 16px; - margin-bottom: 20px; - line-height: 18px; -} -html[dir=rtl] .quick-icons .nav-list [class^="icon-"], -html[dir=rtl] .quick-icons .nav-list [class*=" icon-"] { - margin-left: 9px; - margin-right: 0; -} -.sidebar-nav .nav-list { - padding-left: 25px; - padding-right: 25px; -} -.sidebar-nav .nav-list > li > a { - color: #555; - padding: 3px 25px; - margin-left: -26px; - margin-right: -26px; -} -.sidebar-nav .nav-list > li.active > a { - color: #fff; - margin-right: -26px; -} -.sidebar-nav .nav-list > li > a:focus, -.sidebar-nav .nav-list > li > a:hover { - text-decoration: none; - color: #fff; - background-color: #2d6ca2; - text-shadow: none; -} -.j-sidebar-container { - position: absolute; - display: block; - left: -16.5%; - width: 16.5%; - margin: -18px 0 0 -1px; - padding-top: 28px; - padding-bottom: 40px; - clear: both; - background-color: #F0F0F0; - border-bottom: 1px solid #dedede; - border-right: 1px solid #dedede; - -webkit-border-radius: 0 0 3px 0; - -moz-border-radius: 0 0 3px 0; - border-radius: 0 0 3px 0; -} -.j-sidebar-container.j-sidebar-hidden { - left: -16.5%; -} -.j-sidebar-container.j-sidebar-visible { - left: 0; -} -.j-sidebar-container .filter-select { - padding: 0 14px; -} -.j-toggle-sidebar-header h3 { - font-weight: normal; - padding: 0 15px; -} -.j-toggle-button-wrapper { - position: absolute; - display: block; - top: 7px; - padding: 0; -} -.j-toggle-button-wrapper.j-toggle-hidden { - right: -24px; -} -.j-toggle-button-wrapper.j-toggle-visible { - right: 7px; -} -.j-toggle-sidebar-button { - font-size: 16px; - color: #3071a9; - text-decoration: none; - cursor: pointer; -} -.j-toggle-sidebar-button:hover { - color: #1f496e; -} -#system-message-container, -#j-main-container { - padding: 0 0 0 5px; - min-height: 0; -} -#system-message-container.j-toggle-main, -#j-main-container.j-toggle-main, -#system-debug.j-toggle-main { - float: right; -} -@media (min-width: 768px) { - .j-toggle-transition { - -webkit-transition: all 0.3s ease; - -moz-transition: all 0.3s ease; - -o-transition: all 0.3s ease; - transition: all 0.3s ease; - } -} -@media (max-width: 979px) { - .j-toggle-button-wrapper.j-toggle-hidden { - right: -20px; - } -} -@media (max-width: 767px) { - .j-sidebar-container { - position: relative; - width: 100%; - margin: 0 0 20px 0; - padding: 0; - background: transparent; - border-right: 0; - border-bottom: 0; - } - .j-sidebar-container.j-sidebar-hidden { - margin-left: 16.5%; - } - .j-sidebar-container.j-sidebar-visible { - margin-left: 0; - } - .j-toggle-sidebar-header, - .j-toggle-button-wrapper { - display: none; - } - .view-login select { - width: 232px; - } -} -@media (max-width: 420px) { - .j-sidebar-container { - margin: 0; - } - .view-login .input-medium { - width: 180px; - } - .view-login select { - width: 232px; - } -} -#status { - background: #ebebeb; - border-top: 1px solid #dedede; - padding: 4px 10px; - -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); - -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); - box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); - color: #626262; -} -#status .btn-group { - margin: 0; -} -#status .btn-group.separator:after { - content: ' '; - display: block; - float: left; - background: #ADADAD; - margin: 0 10px; - height: 15px; - width: 1px; -} -#status .btn-toolbar, -#status p { - margin: 0px; -} -#status .btn-toolbar, -#status .btn-group { - font-size: 12px; -} -#status a { - color: #626262; -} -#status .badge { - margin-right: .25em; -} -#status.status-top { - background: #1a3867; - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); - border-top: 0; - color: #d9d9d9; - padding: 2px 20px 6px 20px; -} -#status.status-top a { - color: #d9d9d9; -} -@media (max-width: 479px) { - .pagination a { - padding: 5px; - } - .btn-group.divider, - .header .row-fluid .span3, - .header .row-fluid .span7 { - display: none; - } - .navbar .btn { - margin: 0; - } - .btn-subhead { - display: block; - margin: 10px 0; - } - .subhead-collapse.collapse { - height: 0; - overflow: hidden; - } - .btn-toolbar .btn-wrapper { - display: block; - margin: 0px 10px 5px 10px; - } - .btn-toolbar .btn-wrapper .btn { - width: 100% !important; - } - .subhead { - background: none repeat scroll 0 0 transparent; - border-bottom: 0 solid #dedede; - } - .btn-group + .btn-group { - margin-left: 10px; - } - .login .chzn-single { - width: 222px !important; - } - .login .chzn-container, - .login .chzn-drop { - width: 230px !important; - } - #toolbar [class^="icon-"], - #toolbar [class*=" icon-"] { - background-color: transparent; - border-right: medium none; - width: 10px; - } -} -table label { - margin: 0; -} -td.has-context { - height: 23px; -} -td.nowrap.has-context { - width: 45%; -} -.subhead { - background: #F0F0F0; - border-bottom: 1px solid #dedede; - color: #0C192E; - text-shadow: 0 1px 0 #FFF; - margin-bottom: 10px; - min-height: 51px; -} -.subhead-collapse { - margin-bottom: 19px; -} -.subhead-collapse.collapse { - height: auto; - overflow: visible; -} -.btn-toolbar { - margin-bottom: 5px; -} -.btn-toolbar .btn-wrapper { - display: inline-block; - margin: 0 0 8px 5px; -} -.subhead-fixed { - position: fixed; - width: 100%; - top: 30px; - z-index: 100; -} -@media (max-width: 767px) { - body { - -webkit-overflow-scrolling: touch; - } - .subhead { - margin-left: -20px; - margin-right: -20px; - padding-left: 10px; - padding-right: 10px; - } -} -.subhead h1 { - font-size: 17px; - font-weight: normal; - margin-left: 10px; - margin-top: 6px; -} -#toolbar { - margin-bottom: 2px; - margin-top: 12px; -} -#toolbar .btn { - line-height: 24px; - margin-right: 4px; - padding: 0 10px; -} -#toolbar .btn-success { - min-width: 148px; -} -#toolbar .btn-primary [class^="icon-"], -#toolbar .btn-primary [class*=" icon-"], -#toolbar .btn-warning [class^="icon-"], -#toolbar .btn-warning [class*=" icon-"], -#toolbar .btn-danger [class^="icon-"], -#toolbar .btn-danger [class*=" icon-"], -#toolbar .btn-success [class^="icon-"], -#toolbar .btn-success [class*=" icon-"], -#toolbar .btn-info [class^="icon-"], -#toolbar .btn-info [class*=" icon-"], -#toolbar .btn-inverse [class^="icon-"], -#toolbar .btn-inverse [class*=" icon-"] { - background-color: transparent; - border-right: 0; - border-left: 0; - width: 16px; - margin-left: 0; - margin-right: 0; -} -#toolbar #toolbar-options, -#toolbar #toolbar-help { - float: right; -} -#toolbar [class^="icon-"], -#toolbar [class*=" icon-"] { - background-color: #e6e6e6; - border-radius: 3px 0 0 3px; - border-right: 1px solid #b3b3b3; - height: auto; - line-height: inherit; - margin: 0 6px 0 -10px; - opacity: 1; - text-shadow: none; - width: 28px; - z-index: -1; -} -#toolbar iframe .btn-group .btn { - margin-left: -1px !important; -} -html[dir=rtl] #toolbar #toolbar-options, -html[dir=rtl] #toolbar #toolbar-help { - float: left; -} -@media (max-width: 767px) { - .subhead-fixed { - position: static; - width: auto; - } -} -.btn-subhead { - display: none; -} -@media (min-width: 480px) { - #filter-bar { - height: 29px; - } -} -@media (max-width: 479px) { - .navbar .btn { - margin: 0; - } - .btn-subhead { - display: block; - margin: 10px 0; - } - .subhead-collapse.collapse { - height: 0; - overflow: hidden; - } - .btn-toolbar .btn-wrapper { - display: block; - margin: 0px 10px 5px 10px; - } - .btn-toolbar .btn-wrapper .btn { - width: 100% !important; - } - .subhead { - background: none repeat scroll 0 0 transparent; - border-bottom: 0 solid #dedede; - } - #toolbar [class^="icon-"], - #toolbar [class*=" icon-"] { - background-color: transparent; - border-right: medium none; - width: 10px; - } -} -@media (max-width: 319px) { - .view-login .navbar-fixed-bottom { - display: none; - } -} -ul.treeselect, -ul.treeselect li { - margin: 0; - padding: 0; -} -ul.treeselect { - margin-top: 8px; -} -ul.treeselect li { - padding: 2px 10px 2px; - list-style: none; -} -ul.treeselect i.treeselect-toggle { - line-height: 18px; -} -ul.treeselect label { - font-size: 1em; - margin-left: 8px; -} -ul.treeselect label.nav-header { - padding: 0; -} -ul.treeselect input { - margin: 2px 0 0 8px; -} -ul.treeselect .treeselect-menu { - margin: 0 6px; -} -ul.treeselect ul.dropdown-menu { - margin: 0; -} -ul.treeselect ul.dropdown-menu li { - padding: 0 5px; - border: none; -} -.tree-holder .folder-url, -.tree-holder .file { - position: relative; - background-color: #fefefe; - margin-bottom: 4px; - padding: 0 10px; - line-height: 32px; - border: 1px solid rgba(0,0,0,0.08); -} -.tree-holder .folder-url, -.tree-holder .folder-url:hover, -.tree-holder .folder-url:focus { - font-weight: bold; - background-color: #f5f5f5; - color: #3071a9; -} -.tree-holder .active { - background-color: #3071a9; - color: #fff; - box-shadow: -3px 0 0 #36a2ff !important; -} -.tree-holder .active.folder-url { - background-color: #f5f5f5; - color: #3071a9; -} -.tree-holder .active.file:hover { - background-color: #3071a9; -} -.tree-holder ul ul { - box-shadow: -3px 0 0 rgba(0,0,0,0.08); - padding-right: 0; -} -.tree-holder ul ul .folder-url, -.tree-holder ul ul .file { - box-shadow: -3px 0 0 #3071a9; - border-left: 0; -} -.break-word { - word-break: break-all; - word-wrap: break-word; -} -.disabled { - cursor: default; - background-image: none; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.j-links-separator { - margin: 20px 0px; - width: 100%; - height: 0px; - border-top: 2px solid #DDDDDD; -} -.container-main, -#system-debug { - padding-bottom: 50px; -} -.pagination-toolbar { - margin: 0; -} -.pagination-toolbar a { - line-height: 26px; -} -.pull-right > .dropdown-menu { - left: auto; - right: 0; -} -.nav-filters hr { - margin: 5px 0; -} -#assignment.tab-pane { - min-height: 500px; -} -@media (max-width: 979px) { - .container-fluid { - padding-left: 10px; - padding-right: 10px; - } -} -@media (min-width: 768px) { - body { - padding-top: 30px; - } - .nav-collapse.collapse.in { - height: auto !important; - } -} -@media (max-width: 767px) { - .container-fluid { - padding-left: 0; - padding-right: 0; - } -} -@media (max-width: 479px) { - .pagination a { - padding: 5px; - } - .btn-group.divider, - .header .row-fluid .span3, - .header .row-fluid .span7 { - display: none; - } - .btn-group + .btn-group { - margin-left: 10px; - } -} -.info-labels { - margin-top: -5px; - margin-bottom: 10px; -} -.sortable-handler.inactive { - opacity: 0.3; - filter: alpha(opacity=30); -} -.alert-joomlaupdate { - text-align: center; -} -.alert-joomlaupdate button { - vertical-align: baseline; -} -.j-jed-message { - line-height: 2em; - color: #333333; -} -.upload-queue > li > span, -.upload-queue > li > a { - margin: 0 2px; -} -.upload-queue .file-remove { - float: right; -} -.moor-box { - z-index: 3; -} -.admin .chzn-container .chzn-drop { - z-index: 1060; -} -.item-associations { - margin: 0; -} -.item-associations li { - list-style: none; - display: inline-block; - margin: 0 0 3px 0; -} -.item-associations li a { - color: #ffffff; -} -#flag img { - padding-top: 6px; - vertical-align: top; -} -.tooltip { - max-width: 400px; -} -.tooltip-inner { - max-width: none; - text-align: left; - text-shadow: none; -} -th .tooltip-inner { - font-weight: normal; -} -.tooltip.hasimage { - opacity: 1; -} -#permissions-sliders .chzn-container { - margin-top: -5px; - position: absolute; -} -#permissions-sliders .table td { - padding: 8px 8px 9px; -} -.img-preview > img { - max-height: 100%; -} -#helpsite-refresh { - padding: 4px 12px; - vertical-align: top; -} -.alert-no-items { - margin-top: 20px; -} -@media (max-width: 767px) { - html[dir=rtl] #toolbar #toolbar-options, - html[dir=rtl] #toolbar #toolbar-help, - #toolbar #toolbar-options, - #toolbar #toolbar-help { - float: none; - } -} -#permissions-sliders .input-small { - width: 120px; -} -.editor { - overflow: hidden; - position: relative; -} -.editor textarea.mce_editable { - box-sizing: border-box; -} -a.grid_false { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/publish_r.png'); -} -a.grid_true { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/icon-16-allow.png'); -} -textarea, -input, -.uneditable-input { - box-shadow: none !important; -} -textarea:focus, -input:focus, -.uneditable-input:focus { - box-shadow: none; - border: 1px solid #3071A9; -} -.js-pstats-data-details dd { - margin-left: 240px; -} -.js-pstats-data-details dt { - width: 220px; -} -#permissions table td, -#page-permissions table td { - vertical-align: middle; -} -#permissions table select, -#page-permissions table select { - margin-bottom: 0; -} -.js-stools-container-bar .btn-primary .caret { - border-bottom: 4px solid #fff; -} -.input-append .add-on, -.input-append .btn, -.input-append .btn-group > .dropdown-toggle, -.input-prepend .add-on, -.input-prepend .btn, -.input-prepend .btn-group > .dropdown-toggle { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.alert, -.alert-options, -.badge, -.breadcrumb > li, -.close, -.input-append .add-on, -.input-prepend .add-on, -.label, -.nav-header, -.nav-list .nav-header, -.nav-list > .active > a, -.nav-list > .active > a:focus, -.nav-list > .active > a:hover, -.nav-list > li > a, -.nav-tabs.nav-dark, -.navbar .brand, -.navbar .nav > li > a, -.navbar-inverse .brand, -.navbar-inverse .nav > li > a, -.navbar-inverse .navbar-search .search-query.focused, -.navbar-inverse .navbar-search .search-query:focus, -.progress .bar, -.subhead { - text-shadow: none; -} -.popover-content { - min-height: 33px; -} -.lead, -.navbar .brand, -.hero-unit, -.hero-unit .lead { - font-weight: 400; -} -.com_cpanel .well { - padding: 8px 14px; - border: 1px solid rgba(0,0,0,0.05); -} -.com_cpanel .well .module-title.nav-header { - color: #555; -} -.com_cpanel .well > .row-striped, -.com_cpanel .well > .list-striped { - margin: 0 -14px; -} -.com_cpanel .well > .row-striped > .row-fluid, -.com_cpanel .well > .list-striped > .row-fluid { - padding: 8px 14px; -} -.com_cpanel .well > .row-striped > .row-fluid [class*="span"], -.com_cpanel .well > .list-striped > .row-fluid [class*="span"] { - margin-left: 0; -} -.com_cpanel .well > .row-striped > li, -.com_cpanel .well > .list-striped > li { - padding-left: 15px; - padding-right: 15px; -} -.com_postinstall fieldset { - background-color: #fafafa; - border: 1px solid #ccc; - border-radius: 5px; - margin: 0 0 18px; - padding: 4px 18px 18px; -} -.com_postinstall fieldset .btn { - margin-top: 10px; -} -.com_postinstall legend { - border: 0 none; - display: inline-block; - padding: 0 5px; - margin-bottom: 0; - width: auto; -} -#menu-assignment { - position: relative; -} -#menu-assignment .menu-links { - margin-top: 15px; - margin-left: 0; - -webkit-column-count: 3; - -moz-column-count: 3; - column-count: 3; - -moz-column-gap: 15px; - -webkit-column-gap: 15px; - column-gap: 15px; -} -#menu-assignment .menu-links > li { - display: inline-block; - vertical-align: top; - margin-bottom: 15px; - width: 100%; - list-style: none; - -webkit-column-break-inside: avoid; - -webkit-backface-visibility: hidden; -} -#menu-assignment .menu-links-block { - background-color: #fafafa; - border: 1px solid #ddd; - border-radius: 3px; - padding: 15px; -} -@media (max-width: 767px) { - #menu-assignment .menu-links { - -webkit-column-count: auto; - -moz-column-count: auto; - column-count: auto; - } -} -.pull-right { - float: left; -} -.pull-left { - float: right; -} -.table th, -.table td { - text-align: right; -} -.navbar .brand { - float: right; - padding: 8px 20px 8px 12px; - margin-right: -20px; - margin-left: 0; -} -.navbar .nav, -.navbar .nav > li { - float: left; -} -.navbar .nav.pull-right { - margin-right: 10px; - margin-left: 0px; -} -.pull-right > .dropdown-menu { - left: 0; - right: auto; -} -[class*="span"] { - float: right; - margin-right: 20px; - margin-left: 0px; -} -.row-fluid [class*="span"] { - float: right; - margin-right: 2.127659574%; - *margin-right: 2.0744680846382977%; - margin-left: 0px !important; - *margin-left: 0px !important; -} -.row-fluid [class*="span"]:first-child { - margin-right: 0; -} -.form-horizontal .control-label { - float: right; - width: auto; - padding-left: 5px; - padding-right: 0; - text-align: right; -} -.form-horizontal .controls { - *display: inline-block; - *padding-right: 20px; - margin-right: 160px; - *margin-right: 0; - margin-left: 0; - text-align: right; - margin-top: 6px; -} -.form-horizontal .controls:first-child { - *padding-right: 160px; -} -.form-vertical .controls { - *display: inline-block; - *padding-right: 20px; - margin-right: 0; - *margin-right: 0; - margin-left: 0; - text-align: right; - margin-top: 6px; -} -.form-vertical .control-label { - float: none; - padding-right: 0; - padding-top: 0; - text-align: right; - width: auto; -} -.chzn-container-single-nosearch .chzn-search input { - position: absolute; - left: -9000px; - display: none; -} -.nav-tabs > li, -.nav-pills > li { - float: right; -} -.nav-stacked > li { - float: none; -} -.btn-group > .btn { - float: right; - margin-right: -1px; - margin-left: 0; -} -.btn-group > .btn:first-child { - margin-right: 0; -} -.btn-group > .btn:first-child, -.radio.btn-group > label:first-of-type { - margin-left: 0; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - -moz-border-radius-topleft: 4px; - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-bottomright: 4px; - -moz-border-radius-topright: 4px; -} -.btn-group > .btn:last-child, -.btn-group > .dropdown-toggle { - -webkit-border-top-right-radius: 0px; - border-top-right-radius: 0px; - -webkit-border-bottom-right-radius: 0px; - border-bottom-right-radius: 0px; - -moz-border-radius-topright: 0px; - -moz-border-radius-bottomright: 0px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-topleft: 4px; - -moz-border-radius-bottomleft: 4px; -} -.btn-group > .btn.large:first-child { - -webkit-border-bottom-left-radius: 0px; - border-bottom-left-radius: 0px; - -webkit-border-top-left-radius: 0px; - border-top-left-radius: 0px; - -moz-border-radius-bottomleft: 0px; - -moz-border-radius-topleft: 0px; - margin-right: 0; - -webkit-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - -webkit-border-top-right-radius: 6px; - border-top-right-radius: 6px; - -moz-border-radius-bottomright: 6px; - -moz-border-radius-topright: 6px; -} -.btn-group > .btn.large:last-child, -.btn-group > .large.dropdown-toggle { - -webkit-border-top-right-radius: 0px; - border-top-right-radius: 0px; - -webkit-border-bottom-right-radius: 0px; - border-bottom-right-radius: 0px; - -moz-border-radius-topright: 0px; - -moz-border-radius-bottomright: 0px; - -webkit-border-top-left-radius: 6px; - border-top-left-radius: 6px; - -webkit-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-topleft: 6px; - -moz-border-radius-bottomleft: 6px; -} -.btn-group > .btn:first-child:last-child { - margin-left: 0; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-topleft: 4px; - -moz-border-radius-bottomleft: 4px; - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-bottomright: 4px; - -moz-border-radius-topright: 4px; -} -.input-prepend .add-on { - float: right; -} -.input-append .add-on { - float: none; -} -.input-prepend .add-on, -.input-prepend .btn { - margin-left: -1px; - margin-right: 0; -} -.input-prepend .add-on:first-child, -.input-prepend .btn:first-child { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-append input, -.input-append select, -.input-append .uneditable-input { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-append .uneditable-input { - border-left-color: #ccc; - border-right-color: #eee; -} -.input-append .add-on:last-child, -.input-append .btn:last-child { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-prepend.input-append input, -.input-prepend.input-append select, -.input-prepend.input-append .uneditable-input { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.input-prepend.input-append .add-on:first-child, -.input-prepend.input-append .btn:first-child { - margin-left: -1px; - margin-right: 0px; - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; - float: right; -} -.input-prepend.input-append .add-on:last-child, -.input-prepend.input-append .btn:last-child { - margin-right: -1px; - margin-left: 0px; - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-prepend input, -.input-prepend select, -.input-prepend .uneditable-input { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -body { - direction: rtl; -} -.pager .next a { - float: left; -} -.pager .previous a { - float: right; -} -.btn-group > .btn:first-child, -.radio.btn-group > label:first-of-type { - margin-left: 0; - -webkit-border-bottom-left-radius: 0px; - border-bottom-left-radius: 0px; - -webkit-border-top-left-radius: 0px; - border-top-left-radius: 0px; - -moz-border-radius-bottomleft: 0px; - -moz-border-radius-topleft: 0px; - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-bottomright: 4px; - -moz-border-radius-topright: 4px; -} -.icon-arrow-right { - background-position: -241px -94px; - float: left; - padding-right: 3px; -} -.icon-arrow-left { - background-position: -264px -95px; -} -.icon-refresh { - background-position: -240px -23px; -} -#refresh-status { - background-position: right center; - padding-left: 0; - padding-right: 25px; -} -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: right; - margin-right: 2px; - margin-left: 5px; -} -.list-striped, -.row-striped { - list-style: none; - line-height: 18px; - text-align: right; -} -.btn-group + .btn-group { - margin-right: 5px; - margin-left: 0px; -} -.tabs-left > .nav-tabs { - float: right; - margin-left: 19px; - border-left: 1px solid #DDD; - margin-right: 0px; - border-right: 0px; -} -.tabs-left > .nav-tabs .active > a, -.tabs-left > .nav-tabs .active > a:hover { - border-color: #DDD #DDD #DDD transparent; -} -.tabs-left > .nav-tabs > li > a { - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; - margin-right: 0px; -} -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 0px; -} -.btn-toolbar { - margin-top: 14px; - margin-bottom: 3px; -} -.navbar .nav > li { - float: right; -} -.icon-folder-2 { - line-height: 25px; - padding-left: 5px; -} -.navbar .nav > li > a { - padding: 8px 10px; - color: #FFFFFF; -} -.navigation .nav li li .nav-child { - left: auto; - right: 100%; -} -.navigation .nav li li .nav-child:before { - left: auto; - right: -7px; - border-left: 7px solid rgba(0,0,0,0.2); - border-right-width: 0; -} -.navigation .nav li li .nav-child:after { - left: auto; - right: -6px; - border-left: 6px solid #ffffff; - border-right-width: 0; -} -.container-logo { - padding-top: 6px; - float: left; - text-align: left; -} -.modal-header .close { - float: left; -} -.pagination a { - float: right; -} -.pagination ul { - display: inline-block; - *display: inline; - *zoom: 1; - margin-right: 0; - margin-bottom: 0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.05); - -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.05); - box-shadow: 0 1px 2px rgba(0,0,0,0.05); -} -.pagination a { - float: right; - padding: 0 14px; - line-height: 34px; - text-decoration: none; - border: 1px solid #ddd; - border-right-width: 0; -} -.pagination li:first-child a { - border-right-width: 1px; - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.pagination li:last-child a { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.pagination-centered { - text-align: center; -} -.pagination-right { - text-align: right; -} -.icon-first:before { - content: "\e000"; -} -.icon-previous:before { - content: "\7d"; -} -.icon-last:before { - content: "\7b"; -} -.icon-next:before { - content: "\7c"; -} -.dl-horizontal dt { - float: right; - text-align: left; - clear: right; -} -.dl-horizontal dd { - margin-left: 0; - margin-right: 180px; -} -.dl-horizontal dt, -.profile> ul { - margin: 9px 25px 0 0; -} -.dropdown-submenu > a:after { - float: left; - border-width: 5px 5px 5px 0; - margin-left: -10px; - border-left-color: transparent; - border-right-color: #CCC; -} -.badge { - margin-left: 10px; -} -.tip-text { - text-align: right; -} -.icon-file-add:before { - content: "("; -} -.icon-eye-open:before, -.icon-eye:before { - content: ">"; -} -.icon-checkin:before, -.icon-checkbox:before { - content: "<"; -} -.icon-save-new:before, -.icon-plus-2:before { - content: "["; -} -.btn-toolbar .btn + .btn, -.btn-toolbar .btn-group + .btn, -.btn-toolbar .btn + .btn-group { - margin-left: 0; - margin-right: 5px; -} -.btn-toolbar .btn-wrapper { - display: inline-block; - margin: 0 5px 5px 0; -} -.btn-group > .btn + .btn { - margin-left: 0; - margin-right: -1px; -} -.input-append .add-on, -.input-append .btn, -.input-prepend .add-on, -.input-prepend .btn { - margin-left: 0; - margin-right: -1px; -} -.table-bordered { - border-right-width: 0; - border-left-width: 1px; - border-right-style: none; - border-left-style: solid; - border-right-color: -moz-use-text-color; - border-left-color: #DDDDDD; -} -.chzn-container-single .chzn-single { - padding-right: 8px; - padding-left: 0; -} -.chzn-container-single .chzn-single span { - margin-left: 26px; - margin-right: 0; -} -.chzn-container-single .chzn-single abbr { - left: 26px; - right: auto; -} -.chzn-container-single .chzn-single div { - left: 0; - right: auto; -} -.chzn-container-multi .chzn-choices li { - float: right; -} -.chzn-container-multi .chzn-choices .search-choice { - margin-right: 5px; - margin-left: 0; - padding-right: 5px; - padding-left: 20px; -} -.chzn-container-multi .chzn-choices .search-choice .search-choice-close { - left: 3px; - right: auto; -} -.chzn-container.chzn-with-drop .chzn-drop { - right: 0; - left: auto; -} -.chzn-container-single.chzn-container-single-nosearch .chzn-search { - position: absolute; - right: -9999px; - left: auto; -} -.chzn-container .chzn-drop { - right: -9999px; - left: auto; -} -.alert { - padding-right: 14px; - padding-left: 35px; -} -.alert .close { - left: -21px; - right: auto; -} -.close { - float: left; -} -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - margin-bottom: 9px; -} -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: right; - margin-left: 3px; - margin-right: 0; -} -.com_media .container-main .media { - display: inline-block; -} -.thumbnails > li { - float: right; - margin-bottom: 18px; - margin-right: 20px; -} -#mediamanager-form .description, -#mediamanager-form .filesize, -#mediamanager-form .dimensions { - direction: ltr; -} -.popover, -.tooltip-inner { - text-align: right; -} -.popover.top .arrow, -.popover.bottom .arrow { - margin-right: -11px; -} -.popover.top .arrow:after, -.popover.bottom .arrow:after { - margin-right: -10px; -} -@media (max-width: 480px) { - .btn-toolbar .btn-wrapper { - display: block; - margin: 0 0 5px 0; - } - .btn-toolbar .btn-wrapper .btn { - margin-left: 0px; - margin-right: 10px; - } -} -#pop-print { - float: left; - margin: 10px; -} -#install_url, -#install_directory, -#jform_customurl, -#jform_link, -#jform_params_url, -input[type="url"] { - text-align: left; - direction: ltr; -} -#aside .nav .nav-child { - border-left: 0; - border-right: 2px solid #ddd; - padding-left: 0; - padding-right: 5px; -} -.dropdown-menu { - text-align: right; -} -[class^="icon-"], -[class*=" icon-"] { - margin-left: .25em; -} -.navbar .admin-logo { - float: right; - padding: 7px 15px 0px 12px; -} -.navbar .brand { - float: left; - padding: 6px 10px; -} -.navbar .nav { - margin: 0 0 0 10px; -} -.navbar .nav > li > a { - padding: 6px 10px; -} -.navbar .nav > li ul { - overflow-y: auto; - overflow-x: hidden; - -webkit-overflow-scrolling: touch; - -moz-overflow-scrolling: touch; - -ms-overflow-scrolling: touch; - -o-overflow-scrolling: touch; - overflow-scrolling: touch; - height: auto; - max-height: 500px; - margin: 0; -} -.navbar .nav > li ul::-webkit-scrollbar { - -webkit-appearance: none; - width: 7px; -} -.navbar .nav > li ul::-webkit-scrollbar-thumb { - border-radius: 4px; - background-color: rgba(0,0,0,0.5); - -webkit-box-shadow: 0 0 1px rgba(255,255,255,0.5); -} -.navbar .nav-user .dropdown-menu li span { - padding-left: 0; - padding-right: 10px; -} -.navbar .nav > .dropdown.open:after { - right: 10px; - width: 0; -} -.navbar .empty-nav { - display: none; -} -#toolbar .btn { - padding: 0 10px; -} -#toolbar [class^="icon-"], -#toolbar [class*=" icon-"] { - border-radius: 0 3px 3px 0; - border-right: 0; - border-left: 1px solid #b3b3b3; - margin: 0 -10px 0 6px; -} -.chzn-container-single .chzn-single { - padding-left: 8px; -} -.chzn-container-single .chzn-single div { - border-left: 0; - border-right: 1px solid #cccccc; -} -.chzn-container-single .chzn-single abbr { - left: 36px; -} -.chzn-container-active.chzn-with-drop .chzn-single div { - background-color: #f3f3f3; - border-bottom: 1px solid #cccccc; - border-bottom-left-radius: 0px; - border-bottom-right-radius: 3px; - border-left: 1px solid #cccccc; -} -.chzn-container-multi .chzn-choices .search-choice { - padding-left: 7px; -} -.chzn-container-multi .chzn-choices .search-choice .search-choice-close { - margin-left: 0; - margin-right: 3px; -} -.chzn-container .chzn-single.chzn-color[rel="value_0"] div, -.chzn-container .chzn-single.chzn-color[rel="value_1"] div { - border-right: none; -} -.chzn-container-single .chzn-search::after { - left: 20px; - right: auto; -} -.container-logo { - padding-top: 0; - float: left; - text-align: left; -} -.page-title [class^="icon-"], -.page-title [class*=" icon-"] { - margin-right: 0; - margin-left: 16px; -} -@media (max-width: 767px) { - .navbar .admin-logo { - margin-right: 10px; - padding: 9px 9px 0 9px; - } - .navbar .btn-navbar { - float: left; - margin-right: 5px; - margin-left: 3px; - } - .navbar .nav-collapse .nav.pull-left { - float: none; - margin-left: 0; - margin-right: 0; - } - .nav-collapse .nav > li { - float: none; - } - .page-title [class^="icon-"], - .page-title [class*=" icon-"] { - margin-left: 10px; - } -} -#status { - padding: 4px 10px; -} -#status .btn-group { - margin: 0; -} -#status .btn-group.separator:after { - content: ' '; - display: block; - float: left; - background: #ADADAD; - margin: 0 10px; - height: 15px; - width: 1px; -} -#status .badge { - margin-left: .25em; - margin-right: 0; -} -.dropdown-menu > li > a { - text-align: right; -} -.btn-group.btn-group-yesno > .btn, -.btn-group > .btn, -.btn-group > .btn + .dropdown-toggle { - float: none; -} -a.grid_false { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/publish_r.png'); -} -a.grid_true { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/icon-16-allow.png'); -} -.view-login .login-joomla { - position: absolute; - right: 50%; - height: 24px; - width: 24px; - margin-right: -12px; - font-size: 22px; -} -.view-login .input-medium { - width: 169px; -} -.login .chzn-single { - width: 219px !important; -} -.login .chzn-container, -.login .chzn-drop { - width: 227px !important; - max-width: 227px !important; -} -.login .input-prepend .chzn-container-single .chzn-single { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; - border-right: 0px; -} -.j-sidebar-container { - position: absolute; - display: block; - left: auto; - right: -16.5%; - padding-top: 28px; - padding-bottom: 40px; - clear: both; - margin: -10px -1px 0 0; - border-right: 0; - border-left: 1px solid #d3d3d3; -} -.j-sidebar-container.j-sidebar-hidden { - left: auto; - right: -16.5%; -} -.j-sidebar-container.j-sidebar-visible { - left: auto; - right: 0; -} -.j-toggle-sidebar-header { - padding: 10px 19px 10px 0; -} -.sidebar { - padding: 3px 4px 3px 3px; -} -.j-toggle-button-wrapper.j-toggle-hidden { - right: auto; - left: -24px; -} -.j-toggle-button-wrapper.j-toggle-visible { - right: auto; - left: 10px; -} -.j-sidebar-container .icon-folder-2 { - line-height: 15px; - padding-left: 0; -} -#system-message-container, -#j-main-container { - padding: 0 5px 0 0; -} -#system-message-container.j-toggle-main, -#j-main-container.j-toggle-main, -#system-debug.j-toggle-main { - float: left; -} -@media (max-width: 979px) { - .j-toggle-button-wrapper.j-toggle-hidden { - right: auto; - left: -20px; - } -} -@media (max-width: 767px) { - .j-sidebar-container { - position: relative; - padding: 0; - border-right: 0; - border-left: 0; - } - .j-sidebar-container.j-sidebar-hidden { - margin-left: auto; - margin-right: 16.5%; - } - .j-sidebar-container.j-sidebar-visible { - margin-left: auto; - margin-right: 0; - } - .view-login select { - width: 229px; - } -} -#j-main-container.expanded { - margin-right: 0; -} -@media (min-width: 768px) { - .row-fluid [class*="span"] { - margin-right: 15px; - margin-left: 0; - } - .row-fluid .modal-batch [class*="span"] { - margin-right: 0; - } -} -.row-fluid .modal-batch [class*="span"] { - margin-right: 0; -} -@media (max-width: 479px) { - .btn-toolbar .btn-wrapper .btn { - width: 100% !important; - margin-right: 0px; - } - .btn-toolbar .btn-wrapper { - margin: 0 10px 5px 10px; - } -} -@media (max-width: 420px) { - .j-sidebar-container { - margin: 0; - } - .view-login .input-medium { - width: 173px; - } - .view-login select { - width: 229px; - } -} -.js-pstats-data-details dd { - margin-right: 240px; -} -.modal-footer button { - float: left; -} -.modal-header { - text-align: right; -} -#mediamanager-form .thumbnails-media .thumbnail { - margin-left: 18px !important; - margin-right: 0; - direction: ltr; - text-align: center; -} -.thumbnails-media .imgThumb label::before, -.thumbnails-media .imgThumb .imgThumbInside::before { - left: 0; - right: auto; - border-radius: 3px 0; -} -.thumbnails-media .thumbnail input[type="radio"], -.thumbnails-media .thumbnail input[type="checkbox"] { - left: auto; - right: 5px; -} -.thumbnails-media .imgDelete a.close { - border-radius: 0 3px; -} -.thumbnails-media .imgPreview a, -.thumbnails-media .imgDetails { - border-radius: 3px 0; - border-width: 1px; - left: 0; - right: 0; - text-align: left; - direction: ltr; -} -.thumbnails-media .imgPreview a { - width: 100%; -} -.subform-table-layout td { - padding-left: 10px; -} -.subform-table-layout td::before { - content: attr(data-column); - left: auto; - right: 10px; - padding-left: 10px; - padding-right: 0; -} -.subform-table-layout .subform-repeatable tbody td:last-of-type { - text-align: left; -} -.subform-table-layout .form-horizontal .controls { - margin-top: 0; -} -.tree-holder ul ul { - padding-right: 15px; - box-shadow: 3px 0 0 rgba(0,0,0,0.08); - padding-left: 0; -} -.tree-holder ul ul .folder-url, -.tree-holder ul ul .file { - box-shadow: 3px 0 0 #3071a9; - border-right: 0; - border-left: 1px solid rgba(0,0,0,0.08); -} diff --git a/administrator/templates/isis/css/template.css b/administrator/templates/isis/css/template.css deleted file mode 100644 index c7ae130221745..0000000000000 --- a/administrator/templates/isis/css/template.css +++ /dev/null @@ -1,9106 +0,0 @@ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section { - display: block; -} -audio, -canvas, -video { - display: inline-block; - *display: inline; - *zoom: 1; -} -audio:not([controls]) { - display: none; -} -html { - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} -a:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -a:hover, -a:active { - outline: 0; -} -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} -sup { - top: -0.5em; -} -sub { - bottom: -0.25em; -} -img { - max-width: 100%; - width: auto \9; - height: auto; - vertical-align: middle; - border: 0; - -ms-interpolation-mode: bicubic; -} -#map_canvas img, -.google-maps img, -.gm-style img { - max-width: none; -} -button, -input, -select, -textarea { - margin: 0; - font-size: 100%; - vertical-align: middle; -} -button, -input { - *overflow: visible; - line-height: normal; -} -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0; -} -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; - cursor: pointer; -} -label, -select, -button, -input[type="button"], -input[type="reset"], -input[type="submit"], -input[type="radio"], -input[type="checkbox"] { - cursor: pointer; -} -input[type="search"] { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; -} -input[type="search"]::-webkit-search-decoration, -input[type="search"]::-webkit-search-cancel-button { - -webkit-appearance: none; -} -textarea { - overflow: auto; - vertical-align: top; -} -@media print { - * { - text-shadow: none !important; - color: #000 !important; - background: transparent !important; - box-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - @page { - margin: 0.5cm; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } -} -.clearfix { - *zoom: 1; -} -.clearfix:before, -.clearfix:after { - display: table; - content: ""; - line-height: 0; -} -.clearfix:after { - clear: both; -} -.hide-text { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} -.input-block-level { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -body { - margin: 0; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - line-height: 18px; - color: #333; - background-color: #fff; -} -a { - color: #3071a9; - text-decoration: none; -} -a:hover, -a:focus { - color: #1f496e; - text-decoration: underline; -} -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.img-polaroid { - padding: 4px; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,0.2); - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.1); - box-shadow: 0 1px 3px rgba(0,0,0,0.1); -} -.img-circle { - -webkit-border-radius: 500px; - -moz-border-radius: 500px; - border-radius: 500px; -} -.row { - margin-left: -20px; - *zoom: 1; -} -.row:before, -.row:after { - display: table; - content: ""; - line-height: 0; -} -.row:after { - clear: both; -} -[class*="span"] { - float: left; - min-height: 1px; - margin-left: 20px; -} -.container, -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - width: 940px; -} -.span12 { - width: 940px; -} -.span11 { - width: 860px; -} -.span10 { - width: 780px; -} -.span9 { - width: 700px; -} -.span8 { - width: 620px; -} -.span7 { - width: 540px; -} -.span6 { - width: 460px; -} -.span5 { - width: 380px; -} -.span4 { - width: 300px; -} -.span3 { - width: 220px; -} -.span2 { - width: 140px; -} -.span1 { - width: 60px; -} -.offset12 { - margin-left: 980px; -} -.offset11 { - margin-left: 900px; -} -.offset10 { - margin-left: 820px; -} -.offset9 { - margin-left: 740px; -} -.offset8 { - margin-left: 660px; -} -.offset7 { - margin-left: 580px; -} -.offset6 { - margin-left: 500px; -} -.offset5 { - margin-left: 420px; -} -.offset4 { - margin-left: 340px; -} -.offset3 { - margin-left: 260px; -} -.offset2 { - margin-left: 180px; -} -.offset1 { - margin-left: 100px; -} -.row-fluid { - width: 100%; - *zoom: 1; -} -.row-fluid:before, -.row-fluid:after { - display: table; - content: ""; - line-height: 0; -} -.row-fluid:after { - clear: both; -} -.row-fluid [class*="span"] { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - float: left; - margin-left: 2.1276595744681%; - *margin-left: 2.0744680851064%; -} -.row-fluid [class*="span"]:first-child { - margin-left: 0; -} -.row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.1276595744681%; -} -.row-fluid .span12 { - width: 100%; - *width: 99.946808510638%; -} -.row-fluid .span11 { - width: 91.489361702128%; - *width: 91.436170212766%; -} -.row-fluid .span10 { - width: 82.978723404255%; - *width: 82.925531914894%; -} -.row-fluid .span9 { - width: 74.468085106383%; - *width: 74.414893617021%; -} -.row-fluid .span8 { - width: 65.957446808511%; - *width: 65.904255319149%; -} -.row-fluid .span7 { - width: 57.446808510638%; - *width: 57.393617021277%; -} -.row-fluid .span6 { - width: 48.936170212766%; - *width: 48.882978723404%; -} -.row-fluid .span5 { - width: 40.425531914894%; - *width: 40.372340425532%; -} -.row-fluid .span4 { - width: 31.914893617021%; - *width: 31.86170212766%; -} -.row-fluid .span3 { - width: 23.404255319149%; - *width: 23.351063829787%; -} -.row-fluid .span2 { - width: 14.893617021277%; - *width: 14.840425531915%; -} -.row-fluid .span1 { - width: 6.3829787234043%; - *width: 6.3297872340426%; -} -.row-fluid .offset12 { - margin-left: 104.25531914894%; - *margin-left: 104.14893617021%; -} -.row-fluid .offset12:first-child { - margin-left: 102.12765957447%; - *margin-left: 102.02127659574%; -} -.row-fluid .offset11 { - margin-left: 95.744680851064%; - *margin-left: 95.63829787234%; -} -.row-fluid .offset11:first-child { - margin-left: 93.617021276596%; - *margin-left: 93.510638297872%; -} -.row-fluid .offset10 { - margin-left: 87.234042553191%; - *margin-left: 87.127659574468%; -} -.row-fluid .offset10:first-child { - margin-left: 85.106382978723%; - *margin-left: 85%; -} -.row-fluid .offset9 { - margin-left: 78.723404255319%; - *margin-left: 78.617021276596%; -} -.row-fluid .offset9:first-child { - margin-left: 76.595744680851%; - *margin-left: 76.489361702128%; -} -.row-fluid .offset8 { - margin-left: 70.212765957447%; - *margin-left: 70.106382978723%; -} -.row-fluid .offset8:first-child { - margin-left: 68.085106382979%; - *margin-left: 67.978723404255%; -} -.row-fluid .offset7 { - margin-left: 61.702127659574%; - *margin-left: 61.595744680851%; -} -.row-fluid .offset7:first-child { - margin-left: 59.574468085106%; - *margin-left: 59.468085106383%; -} -.row-fluid .offset6 { - margin-left: 53.191489361702%; - *margin-left: 53.085106382979%; -} -.row-fluid .offset6:first-child { - margin-left: 51.063829787234%; - *margin-left: 50.957446808511%; -} -.row-fluid .offset5 { - margin-left: 44.68085106383%; - *margin-left: 44.574468085106%; -} -.row-fluid .offset5:first-child { - margin-left: 42.553191489362%; - *margin-left: 42.446808510638%; -} -.row-fluid .offset4 { - margin-left: 36.170212765957%; - *margin-left: 36.063829787234%; -} -.row-fluid .offset4:first-child { - margin-left: 34.042553191489%; - *margin-left: 33.936170212766%; -} -.row-fluid .offset3 { - margin-left: 27.659574468085%; - *margin-left: 27.553191489362%; -} -.row-fluid .offset3:first-child { - margin-left: 25.531914893617%; - *margin-left: 25.425531914894%; -} -.row-fluid .offset2 { - margin-left: 19.148936170213%; - *margin-left: 19.042553191489%; -} -.row-fluid .offset2:first-child { - margin-left: 17.021276595745%; - *margin-left: 16.914893617021%; -} -.row-fluid .offset1 { - margin-left: 10.63829787234%; - *margin-left: 10.531914893617%; -} -.row-fluid .offset1:first-child { - margin-left: 8.5106382978723%; - *margin-left: 8.4042553191489%; -} -[class*="span"].hide, -.row-fluid [class*="span"].hide { - display: none; -} -[class*="span"].pull-right, -.row-fluid [class*="span"].pull-right { - float: right; -} -.container { - margin-right: auto; - margin-left: auto; - *zoom: 1; -} -.container:before, -.container:after { - display: table; - content: ""; - line-height: 0; -} -.container:after { - clear: both; -} -.container-fluid { - padding-right: 20px; - padding-left: 20px; - *zoom: 1; -} -.container-fluid:before, -.container-fluid:after { - display: table; - content: ""; - line-height: 0; -} -.container-fluid:after { - clear: both; -} -p { - margin: 0 0 9px; -} -.lead { - margin-bottom: 18px; - font-size: 19.5px; - font-weight: 200; - line-height: 27px; -} -small { - font-size: 85%; -} -strong { - font-weight: bold; -} -em { - font-style: italic; -} -cite { - font-style: normal; -} -.muted { - color: #999; -} -a.muted:hover, -a.muted:focus { - color: #808080; -} -.text-warning { - color: #8a6d3b; -} -a.text-warning:hover, -a.text-warning:focus { - color: #66512c; -} -.text-error { - color: #a94442; -} -a.text-error:hover, -a.text-error:focus { - color: #843534; -} -.text-info { - color: #31708f; -} -a.text-info:hover, -a.text-info:focus { - color: #245269; -} -.text-success { - color: #3c763d; -} -a.text-success:hover, -a.text-success:focus { - color: #2b542c; -} -.text-left { - text-align: left; -} -.text-right { - text-align: right; -} -.text-center { - text-align: center; -} -h1, -h2, -h3, -h4, -h5, -h6 { - margin: 9px 0; - font-family: inherit; - font-weight: bold; - line-height: 18px; - color: inherit; - text-rendering: optimizelegibility; -} -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6 small { - font-weight: normal; - line-height: 1; - color: #999; -} -h1, -h2, -h3 { - line-height: 36px; -} -h1 { - font-size: 35.75px; -} -h2 { - font-size: 29.25px; -} -h3 { - font-size: 22.75px; -} -h4 { - font-size: 16.25px; -} -h5 { - font-size: 13px; -} -h6 { - font-size: 11.05px; -} -h1 small { - font-size: 22.75px; -} -h2 small { - font-size: 16.25px; -} -h3 small { - font-size: 13px; -} -h4 small { - font-size: 13px; -} -.page-header { - padding-bottom: 8px; - margin: 18px 0 27px; - border-bottom: 1px solid #eee; -} -ul, -ol { - padding: 0; - margin: 0 0 9px 25px; -} -ul ul, -ul ol, -ol ol, -ol ul { - margin-bottom: 0; -} -li { - line-height: 18px; -} -ul.unstyled, -ol.unstyled { - margin-left: 0; - list-style: none; -} -ul.inline, -ol.inline { - margin-left: 0; - list-style: none; -} -ul.inline > li, -ol.inline > li { - display: inline-block; - *display: inline; - *zoom: 1; - padding-left: 5px; - padding-right: 5px; -} -dl { - margin-bottom: 18px; -} -dt, -dd { - line-height: 18px; -} -dt { - font-weight: bold; -} -dd { - margin-left: 9px; -} -.dl-horizontal { - *zoom: 1; -} -.dl-horizontal:before, -.dl-horizontal:after { - display: table; - content: ""; - line-height: 0; -} -.dl-horizontal:after { - clear: both; -} -.dl-horizontal dt { - float: left; - width: 160px; - clear: left; - text-align: right; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.dl-horizontal dd { - margin-left: 180px; -} -hr { - margin: 18px 0; - border: 0; - border-top: 1px solid #eee; - border-bottom: 1px solid #fff; -} -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999; -} -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} -blockquote { - padding: 0 0 0 15px; - margin: 0 0 18px; - border-left: 5px solid #eee; -} -blockquote p { - margin-bottom: 0; - font-size: 16.25px; - font-weight: 300; - line-height: 1.25; -} -blockquote small { - display: block; - line-height: 18px; - color: #999; -} -blockquote small:before { - content: '\2014 \00A0'; -} -blockquote.pull-right { - float: right; - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eee; - border-left: 0; -} -blockquote.pull-right p, -blockquote.pull-right small { - text-align: right; -} -blockquote.pull-right small:before { - content: ''; -} -blockquote.pull-right small:after { - content: '\00A0 \2014'; -} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} -address { - display: block; - margin-bottom: 18px; - font-style: normal; - line-height: 18px; -} -code, -pre { - padding: 0 3px 2px; - font-family: Monaco, Menlo, Consolas, "Courier New", monospace; - font-size: 11px; - color: #333; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -code { - padding: 2px 4px; - color: #d14; - background-color: #f7f7f9; - border: 1px solid #e1e1e8; - white-space: nowrap; -} -pre { - display: block; - padding: 8.5px; - margin: 0 0 9px; - font-size: 12px; - line-height: 18px; - word-break: break-all; - word-wrap: break-word; - white-space: pre; - white-space: pre-wrap; - background-color: #f5f5f5; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,0.15); - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -pre.prettyprint { - margin-bottom: 18px; -} -pre code { - padding: 0; - color: inherit; - white-space: pre; - white-space: pre-wrap; - background-color: transparent; - border: 0; -} -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} -form { - margin: 0 0 18px; -} -fieldset { - padding: 0; - margin: 0; - border: 0; -} -legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 18px; - font-size: 19.5px; - line-height: 36px; - color: #333; - border: 0; - border-bottom: 1px solid #e5e5e5; -} -legend small { - font-size: 13.5px; - color: #999; -} -label, -input, -button, -select, -textarea { - font-size: 13px; - font-weight: normal; - line-height: 18px; -} -input, -button, -select, -textarea { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -} -label { - display: block; - margin-bottom: 5px; -} -select, -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - display: inline-block; - height: 18px; - padding: 4px 6px; - margin-bottom: 9px; - font-size: 13px; - line-height: 18px; - color: #555; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - vertical-align: middle; -} -input, -textarea, -.uneditable-input { - width: 206px; -} -textarea { - height: auto; -} -textarea, -input[type="text"], -input[type="password"], -input[type="datetime"], -input[type="datetime-local"], -input[type="date"], -input[type="month"], -input[type="time"], -input[type="week"], -input[type="number"], -input[type="email"], -input[type="url"], -input[type="search"], -input[type="tel"], -input[type="color"], -.uneditable-input { - background-color: #fff; - border: 1px solid #ccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); - -webkit-transition: border linear .2s, box-shadow linear .2s; - -moz-transition: border linear .2s, box-shadow linear .2s; - -o-transition: border linear .2s, box-shadow linear .2s; - transition: border linear .2s, box-shadow linear .2s; -} -textarea:focus, -input[type="text"]:focus, -input[type="password"]:focus, -input[type="datetime"]:focus, -input[type="datetime-local"]:focus, -input[type="date"]:focus, -input[type="month"]:focus, -input[type="time"]:focus, -input[type="week"]:focus, -input[type="number"]:focus, -input[type="email"]:focus, -input[type="url"]:focus, -input[type="search"]:focus, -input[type="tel"]:focus, -input[type="color"]:focus, -.uneditable-input:focus { - border-color: rgba(82,168,236,0.8); - outline: 0; - outline: thin dotted \9; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); -} -input[type="radio"], -input[type="checkbox"] { - margin: 4px 0 0; - *margin-top: 0; - margin-top: 1px \9; - line-height: normal; -} -input[type="file"], -input[type="image"], -input[type="submit"], -input[type="reset"], -input[type="button"], -input[type="radio"], -input[type="checkbox"] { - width: auto; -} -select, -input[type="file"] { - height: 28px; - *margin-top: 4px; - line-height: 28px; -} -select { - width: 220px; - border: 1px solid #ccc; - background-color: #fff; -} -select[multiple], -select[size] { - height: auto; -} -select:focus, -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.uneditable-input, -.uneditable-textarea { - color: #999; - background-color: #fcfcfc; - border-color: #ccc; - -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); - -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); - box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); - cursor: not-allowed; -} -.uneditable-input { - overflow: hidden; - white-space: nowrap; -} -.uneditable-textarea { - width: auto; - height: auto; -} -input:-moz-placeholder, -textarea:-moz-placeholder { - color: #999; -} -input:-ms-input-placeholder, -textarea:-ms-input-placeholder { - color: #999; -} -input::-webkit-input-placeholder, -textarea::-webkit-input-placeholder { - color: #999; -} -.radio, -.checkbox { - min-height: 18px; - padding-left: 20px; -} -.radio input[type="radio"], -.checkbox input[type="checkbox"] { - float: left; - margin-left: -20px; -} -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 5px; -} -.radio.inline, -.checkbox.inline { - display: inline-block; - padding-top: 5px; - margin-bottom: 0; - vertical-align: middle; -} -.radio.inline + .radio.inline, -.checkbox.inline + .checkbox.inline { - margin-left: 10px; -} -.input-mini { - width: 60px; -} -.input-small { - width: 90px; -} -.input-medium { - width: 150px; -} -.input-large { - width: 210px; -} -.input-xlarge { - width: 270px; -} -.input-xxlarge { - width: 530px; -} -input[class*="span"], -select[class*="span"], -textarea[class*="span"], -.uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"] { - float: none; - margin-left: 0; -} -.input-append input[class*="span"], -.input-append .uneditable-input[class*="span"], -.input-prepend input[class*="span"], -.input-prepend .uneditable-input[class*="span"], -.row-fluid input[class*="span"], -.row-fluid select[class*="span"], -.row-fluid textarea[class*="span"], -.row-fluid .uneditable-input[class*="span"], -.row-fluid .input-prepend [class*="span"], -.row-fluid .input-append [class*="span"] { - display: inline-block; -} -input, -textarea, -.uneditable-input { - margin-left: 0; -} -.controls-row [class*="span"] + [class*="span"] { - margin-left: 20px; -} -input.span12, -textarea.span12, -.uneditable-input.span12 { - width: 926px; -} -input.span11, -textarea.span11, -.uneditable-input.span11 { - width: 846px; -} -input.span10, -textarea.span10, -.uneditable-input.span10 { - width: 766px; -} -input.span9, -textarea.span9, -.uneditable-input.span9 { - width: 686px; -} -input.span8, -textarea.span8, -.uneditable-input.span8 { - width: 606px; -} -input.span7, -textarea.span7, -.uneditable-input.span7 { - width: 526px; -} -input.span6, -textarea.span6, -.uneditable-input.span6 { - width: 446px; -} -input.span5, -textarea.span5, -.uneditable-input.span5 { - width: 366px; -} -input.span4, -textarea.span4, -.uneditable-input.span4 { - width: 286px; -} -input.span3, -textarea.span3, -.uneditable-input.span3 { - width: 206px; -} -input.span2, -textarea.span2, -.uneditable-input.span2 { - width: 126px; -} -input.span1, -textarea.span1, -.uneditable-input.span1 { - width: 46px; -} -.controls-row { - *zoom: 1; -} -.controls-row:before, -.controls-row:after { - display: table; - content: ""; - line-height: 0; -} -.controls-row:after { - clear: both; -} -.controls-row [class*="span"], -.row-fluid .controls-row [class*="span"] { - float: left; -} -.controls-row .checkbox[class*="span"], -.controls-row .radio[class*="span"] { - padding-top: 5px; -} -input[disabled], -select[disabled], -textarea[disabled], -input[readonly], -select[readonly], -textarea[readonly] { - cursor: not-allowed; - background-color: #eee; -} -input[type="radio"][disabled], -input[type="checkbox"][disabled], -input[type="radio"][readonly], -input[type="checkbox"][readonly] { - background-color: transparent; -} -.control-group.warning .control-label, -.control-group.warning .help-block, -.control-group.warning .help-inline { - color: #8a6d3b; -} -.control-group.warning .checkbox, -.control-group.warning .radio, -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - color: #8a6d3b; -} -.control-group.warning input, -.control-group.warning select, -.control-group.warning textarea { - border-color: #8a6d3b; -} -.control-group.warning input:focus, -.control-group.warning select:focus, -.control-group.warning textarea:focus { - border-color: #66512c; -} -.control-group.warning .input-prepend .add-on, -.control-group.warning .input-append .add-on { - color: #8a6d3b; - background-color: #fcf8e3; - border-color: #8a6d3b; -} -.control-group.error .control-label, -.control-group.error .help-block, -.control-group.error .help-inline { - color: #a94442; -} -.control-group.error .checkbox, -.control-group.error .radio, -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - color: #a94442; -} -.control-group.error input, -.control-group.error select, -.control-group.error textarea { - border-color: #a94442; -} -.control-group.error input:focus, -.control-group.error select:focus, -.control-group.error textarea:focus { - border-color: #843534; -} -.control-group.error .input-prepend .add-on, -.control-group.error .input-append .add-on { - color: #a94442; - background-color: #f2dede; - border-color: #a94442; -} -.control-group.success .control-label, -.control-group.success .help-block, -.control-group.success .help-inline { - color: #3c763d; -} -.control-group.success .checkbox, -.control-group.success .radio, -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - color: #3c763d; -} -.control-group.success input, -.control-group.success select, -.control-group.success textarea { - border-color: #3c763d; -} -.control-group.success input:focus, -.control-group.success select:focus, -.control-group.success textarea:focus { - border-color: #2b542c; -} -.control-group.success .input-prepend .add-on, -.control-group.success .input-append .add-on { - color: #3c763d; - background-color: #dff0d8; - border-color: #3c763d; -} -.control-group.info .control-label, -.control-group.info .help-block, -.control-group.info .help-inline { - color: #31708f; -} -.control-group.info .checkbox, -.control-group.info .radio, -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - color: #31708f; -} -.control-group.info input, -.control-group.info select, -.control-group.info textarea { - border-color: #31708f; -} -.control-group.info input:focus, -.control-group.info select:focus, -.control-group.info textarea:focus { - border-color: #245269; -} -.control-group.info .input-prepend .add-on, -.control-group.info .input-append .add-on { - color: #31708f; - background-color: #d9edf7; - border-color: #31708f; -} -input:focus:invalid, -textarea:focus:invalid, -select:focus:invalid { - color: #b94a48; - border-color: #ee5f5b; -} -input:focus:invalid:focus, -textarea:focus:invalid:focus, -select:focus:invalid:focus { - border-color: #e9322d; - -webkit-box-shadow: 0 0 6px #f8b9b7; - -moz-box-shadow: 0 0 6px #f8b9b7; - box-shadow: 0 0 6px #f8b9b7; -} -.form-actions { - padding: 17px 20px 18px; - margin-top: 18px; - margin-bottom: 18px; - background-color: #F0F0F0; - border-top: 1px solid #e5e5e5; - *zoom: 1; -} -.form-actions:before, -.form-actions:after { - display: table; - content: ""; - line-height: 0; -} -.form-actions:after { - clear: both; -} -.help-block, -.help-inline { - color: #595959; -} -.help-block { - display: block; - margin-bottom: 9px; -} -.help-inline { - display: inline-block; - *display: inline; - *zoom: 1; - vertical-align: middle; - padding-left: 5px; -} -.input-append, -.input-prepend { - display: inline-block; - margin-bottom: 9px; - vertical-align: middle; - font-size: 0; - white-space: nowrap; -} -.input-append input, -.input-append select, -.input-append .uneditable-input, -.input-append .dropdown-menu, -.input-append .popover, -.input-prepend input, -.input-prepend select, -.input-prepend .uneditable-input, -.input-prepend .dropdown-menu, -.input-prepend .popover { - font-size: 13px; -} -.input-append input, -.input-append select, -.input-append .uneditable-input, -.input-prepend input, -.input-prepend select, -.input-prepend .uneditable-input { - position: relative; - margin-bottom: 0; - *margin-left: 0; - vertical-align: top; - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-append input:focus, -.input-append select:focus, -.input-append .uneditable-input:focus, -.input-prepend input:focus, -.input-prepend select:focus, -.input-prepend .uneditable-input:focus { - z-index: 2; -} -.input-append .add-on, -.input-prepend .add-on { - display: inline-block; - width: auto; - height: 18px; - min-width: 16px; - padding: 4px 5px; - font-size: 13px; - font-weight: normal; - line-height: 18px; - text-align: center; - text-shadow: 0 1px 0 #fff; - background-color: #eee; - border: 1px solid #ccc; -} -.input-append .add-on, -.input-append .btn, -.input-append .btn-group > .dropdown-toggle, -.input-prepend .add-on, -.input-prepend .btn, -.input-prepend .btn-group > .dropdown-toggle { - vertical-align: top; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.input-prepend .add-on, -.input-prepend .btn { - margin-right: -1px; -} -.input-prepend .add-on:first-child, -.input-prepend .btn:first-child { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-append input, -.input-append select, -.input-append .uneditable-input { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-append input + .btn-group .btn:last-child, -.input-append select + .btn-group .btn:last-child, -.input-append .uneditable-input + .btn-group .btn:last-child { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-append .add-on, -.input-append .btn, -.input-append .btn-group { - margin-left: -1px; -} -.input-append .add-on:last-child, -.input-append .btn:last-child, -.input-append .btn-group:last-child > .dropdown-toggle { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend.input-append input, -.input-prepend.input-append select, -.input-prepend.input-append .uneditable-input { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.input-prepend.input-append input + .btn-group .btn, -.input-prepend.input-append select + .btn-group .btn, -.input-prepend.input-append .uneditable-input + .btn-group .btn { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend.input-append .add-on:first-child, -.input-prepend.input-append .btn:first-child { - margin-right: -1px; - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-prepend.input-append .add-on:last-child, -.input-prepend.input-append .btn:last-child { - margin-left: -1px; - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend.input-append .btn-group:first-child { - margin-left: 0; -} -input.search-query { - padding-right: 14px; - padding-right: 4px \9; - padding-left: 14px; - padding-left: 4px \9; - margin-bottom: 0; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -.form-search .input-append .search-query, -.form-search .input-prepend .search-query { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.form-search .input-append .search-query { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} -.form-search .input-append .btn { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} -.form-search .input-prepend .search-query { - -webkit-border-radius: 0 14px 14px 0; - -moz-border-radius: 0 14px 14px 0; - border-radius: 0 14px 14px 0; -} -.form-search .input-prepend .btn { - -webkit-border-radius: 14px 0 0 14px; - -moz-border-radius: 14px 0 0 14px; - border-radius: 14px 0 0 14px; -} -.js-stools-field-filter .input-prepend, -.js-stools-field-filter .input-append { - margin-bottom: 0; -} -.form-search input, -.form-search textarea, -.form-search select, -.form-search .help-inline, -.form-search .uneditable-input, -.form-search .input-prepend, -.form-search .input-append, -.form-inline input, -.form-inline textarea, -.form-inline select, -.form-inline .help-inline, -.form-inline .uneditable-input, -.form-inline .input-prepend, -.form-inline .input-append, -.form-horizontal input, -.form-horizontal textarea, -.form-horizontal select, -.form-horizontal .help-inline, -.form-horizontal .uneditable-input, -.form-horizontal .input-prepend, -.form-horizontal .input-append { - display: inline-block; - *display: inline; - *zoom: 1; - margin-bottom: 0; - vertical-align: middle; -} -.form-search .hide, -.form-inline .hide, -.form-horizontal .hide { - display: none; -} -.form-search label, -.form-inline label, -.form-search .btn-group, -.form-inline .btn-group { - display: inline-block; -} -.form-search .input-append, -.form-inline .input-append, -.form-search .input-prepend, -.form-inline .input-prepend { - margin-bottom: 0; -} -.form-search .radio, -.form-search .checkbox, -.form-inline .radio, -.form-inline .checkbox { - padding-left: 0; - margin-bottom: 0; - vertical-align: middle; -} -.form-search .radio input[type="radio"], -.form-search .checkbox input[type="checkbox"], -.form-inline .radio input[type="radio"], -.form-inline .checkbox input[type="checkbox"] { - float: left; - margin-right: 3px; - margin-left: 0; -} -.control-group { - margin-bottom: 9px; -} -legend + .control-group { - margin-top: 18px; - -webkit-margin-top-collapse: separate; -} -.form-horizontal .control-group { - margin-bottom: 18px; - *zoom: 1; -} -.form-horizontal .control-group:before, -.form-horizontal .control-group:after { - display: table; - content: ""; - line-height: 0; -} -.form-horizontal .control-group:after { - clear: both; -} -.form-horizontal .control-label { - float: left; - width: 160px; - padding-top: 5px; - text-align: right; -} -.form-horizontal .controls { - *display: inline-block; - *padding-left: 20px; - margin-left: 180px; - *margin-left: 0; -} -.form-horizontal .controls:first-child { - *padding-left: 180px; -} -.form-horizontal .help-block { - margin-bottom: 0; -} -.form-horizontal input + .help-block, -.form-horizontal select + .help-block, -.form-horizontal textarea + .help-block, -.form-horizontal .uneditable-input + .help-block, -.form-horizontal .input-prepend + .help-block, -.form-horizontal .input-append + .help-block { - margin-top: 9px; -} -.form-horizontal .form-actions { - padding-left: 180px; -} -.control-label .hasPopover, -.control-label .hasTooltip { - display: inline-block; -} -.subform-repeatable-wrapper .btn-group>.btn.button { - min-width: 0; -} -.subform-repeatable-wrapper .ui-sortable-helper { - background: #fff; -} -.subform-repeatable-wrapper tr.ui-sortable-helper { - display: table; -} -@media (min-width: 980px) and (max-width: 1215px) { - .float-cols .control-label { - float: none; - } - .float-cols .controls { - margin-left: 0; - } -} -table { - max-width: 100%; - background-color: transparent; - border-collapse: collapse; - border-spacing: 0; -} -.table { - width: 100%; - margin-bottom: 18px; -} -.table th, -.table td { - padding: 8px; - line-height: 18px; - text-align: left; - vertical-align: top; - border-top: 1px solid #ddd; -} -.table th { - font-weight: bold; -} -.table thead th { - vertical-align: bottom; -} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; -} -.table tbody + tbody { - border-top: 2px solid #ddd; -} -.table .table { - background-color: #fff; -} -.table-condensed th, -.table-condensed td { - padding: 4px 5px; -} -.table-bordered { - border: 1px solid #ddd; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.table-bordered th, -.table-bordered td { - border-left: 1px solid #ddd; -} -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; -} -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; -} -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; -} -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; - border-bottom-left-radius: 0; -} -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; - border-bottom-right-radius: 0; -} -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; -} -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; -} -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: #f9f9f9; -} -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: #F0F0F0; -} -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; -} -.table td.span1, -.table th.span1 { - float: none; - width: 44px; - margin-left: 0; -} -.table td.span2, -.table th.span2 { - float: none; - width: 124px; - margin-left: 0; -} -.table td.span3, -.table th.span3 { - float: none; - width: 204px; - margin-left: 0; -} -.table td.span4, -.table th.span4 { - float: none; - width: 284px; - margin-left: 0; -} -.table td.span5, -.table th.span5 { - float: none; - width: 364px; - margin-left: 0; -} -.table td.span6, -.table th.span6 { - float: none; - width: 444px; - margin-left: 0; -} -.table td.span7, -.table th.span7 { - float: none; - width: 524px; - margin-left: 0; -} -.table td.span8, -.table th.span8 { - float: none; - width: 604px; - margin-left: 0; -} -.table td.span9, -.table th.span9 { - float: none; - width: 684px; - margin-left: 0; -} -.table td.span10, -.table th.span10 { - float: none; - width: 764px; - margin-left: 0; -} -.table td.span11, -.table th.span11 { - float: none; - width: 844px; - margin-left: 0; -} -.table td.span12, -.table th.span12 { - float: none; - width: 924px; - margin-left: 0; -} -.table tbody tr.success > td { - background-color: #dff0d8; -} -.table tbody tr.error > td { - background-color: #f2dede; -} -.table tbody tr.warning > td { - background-color: #fcf8e3; -} -.table tbody tr.info > td { - background-color: #d9edf7; -} -.table-hover tbody tr.success:hover > td { - background-color: #d0e9c6; -} -.table-hover tbody tr.error:hover > td { - background-color: #ebcccc; -} -.table-hover tbody tr.warning:hover > td { - background-color: #faf2cc; -} -.table-hover tbody tr.info:hover > td { - background-color: #c4e3f3; -} -.table-noheader { - border-collapse: collapse; -} -.table-noheader thead { - display: none; -} -.dropup, -.dropdown { - position: relative; -} -.dropdown-toggle { - *margin-bottom: -3px; -} -.dropdown-toggle:active, -.open .dropdown-toggle { - outline: 0; -} -.caret { - display: inline-block; - width: 0; - height: 0; - vertical-align: top; - border-top: 4px solid #000; - border-right: 4px solid transparent; - border-left: 4px solid transparent; - content: ""; -} -.dropdown .caret { - margin-top: 8px; - margin-left: 2px; -} -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,0.2); - *border-right-width: 2px; - *border-bottom-width: 2px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); - -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); - box-shadow: 0 5px 10px rgba(0,0,0,0.2); - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} -.dropdown-menu.pull-right { - right: 0; - left: auto; -} -.dropdown-menu .divider { - *width: 100%; - height: 1px; - margin: 8px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #F0F0F0; - border-bottom: 1px solid #fff; -} -.dropdown-menu .menuitem-group { - margin: 4px 1px; - overflow: hidden; - border-top: 1px solid #eee; - border-bottom: 1px solid #eee; - background-color: #eee; - color: #555; - text-transform: capitalize; - font-size: 95%; - padding: 3px 20px; -} -.dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 18px; - color: #333; - white-space: nowrap; -} -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-submenu:hover > a, -.dropdown-submenu:focus > a { - text-decoration: none; - color: #fff; - background-color: #2d6ca2; - background-image: -moz-linear-gradient(top,#3071a9,#2a6496); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#3071a9),to(#2a6496)); - background-image: -webkit-linear-gradient(top,#3071a9,#2a6496); - background-image: -o-linear-gradient(top,#3071a9,#2a6496); - background-image: linear-gradient(to bottom,#3071a9,#2a6496); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f70a9', endColorstr='#ff296395', GradientType=0); -} -.dropdown-menu > .active > a, -.dropdown-menu > .active > a:hover, -.dropdown-menu > .active > a:focus { - color: #333; - text-decoration: none; - outline: 0; - background-color: #2d6ca2; - background-image: -moz-linear-gradient(top,#3071a9,#2a6496); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#3071a9),to(#2a6496)); - background-image: -webkit-linear-gradient(top,#3071a9,#2a6496); - background-image: -o-linear-gradient(top,#3071a9,#2a6496); - background-image: linear-gradient(to bottom,#3071a9,#2a6496); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f70a9', endColorstr='#ff296395', GradientType=0); -} -.dropdown-menu > .disabled > a, -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - color: #999; -} -.dropdown-menu > .disabled > a:hover, -.dropdown-menu > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - cursor: default; -} -.open { - *z-index: 1000; -} -.open > .dropdown-menu { - display: block; -} -.dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: 990; -} -.pull-right > .dropdown-menu { - right: 0; - left: auto; -} -.dropup .caret, -.navbar-fixed-bottom .dropdown .caret { - border-top: 0; - border-bottom: 4px solid #000; - content: ""; -} -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 1px; -} -.dropdown-submenu { - position: relative; -} -.dropdown-submenu > .dropdown-menu { - top: 0; - left: 100%; - margin-top: -6px; - margin-left: -1px; - -webkit-border-radius: 6px 6px 6px 6px; - -moz-border-radius: 6px 6px 6px 6px; - border-radius: 6px 6px 6px 6px; -} -.dropdown-submenu:hover > .dropdown-menu { - display: block; -} -.dropup .dropdown-submenu > .dropdown-menu { - top: auto; - bottom: 0; - margin-top: 0; - margin-bottom: -2px; - -webkit-border-radius: 5px 5px 5px 0; - -moz-border-radius: 5px 5px 5px 0; - border-radius: 5px 5px 5px 0; -} -.dropdown-submenu > a:after { - display: block; - content: " "; - float: right; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; - border-width: 5px 0 5px 5px; - border-left-color: #cccccc; - margin-top: 5px; - margin-right: -10px; -} -.dropdown-submenu:hover > a:after { - border-left-color: #fff; -} -.dropdown-submenu.pull-left { - float: none; -} -.dropdown-submenu.pull-left > .dropdown-menu { - left: -100%; - margin-left: 10px; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} -.dropdown .dropdown-menu .nav-header { - padding-left: 20px; - padding-right: 20px; -} -.typeahead { - z-index: 1051; - margin-top: 2px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #F0F0F0; - border: 1px solid #F0F0F0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.well blockquote { - border-color: #f0f0f0; - border-color: rgba(0,0,0,0.15); -} -.well-large { - padding: 24px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.well-small { - padding: 9px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.fade { - opacity: 0; - -webkit-transition: opacity .15s linear; - -moz-transition: opacity .15s linear; - -o-transition: opacity .15s linear; - transition: opacity .15s linear; -} -.fade.in { - opacity: 1; -} -.collapse { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition: height .35s ease; - -moz-transition: height .35s ease; - -o-transition: height .35s ease; - transition: height .35s ease; -} -.collapse.in { - height: auto; -} -.close { - float: right; - font-size: 20px; - font-weight: bold; - line-height: 18px; - color: #000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} -.close:hover, -.close:focus { - color: #000; - text-decoration: none; - cursor: pointer; - opacity: 0.4; - filter: alpha(opacity=40); -} -button.close { - padding: 3; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} -.alert-options { - float: right; - line-height: 18px; - color: #000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} -.alert-options:hover, -.alert-options:focus { - color: #000; - text-decoration: none; - cursor: pointer; - opacity: 0.4; - filter: alpha(opacity=40); -} -.btn { - display: inline-block; - *display: inline; - *zoom: 1; - padding: 4px 12px; - margin-bottom: 0; - font-size: 13px; - line-height: 18px; - text-align: center; - vertical-align: middle; - cursor: pointer; - background-color: #f3f3f3; - color: #333; - border: 1px solid #b3b3b3; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - box-shadow: 0 1px 2px rgba(0,0,0,0.05); -} -.btn:hover, -.btn:focus { - background-color: #e6e6e6; - text-decoration: none; - text-shadow: none; -} -.btn:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.btn.active, -.btn:active { - background-image: none; - outline: 0; -} -.btn.disabled, -.btn[disabled] { - cursor: default; - background-image: none; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.btn-large { - padding: 11px 19px; - font-size: 16.25px; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.btn-large [class^="icon-"], -.btn-large [class*=" icon-"] { - margin-top: 4px; -} -.btn-small { - padding: 2px 10px; - font-size: 12px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.btn-small [class^="icon-"], -.btn-small [class*=" icon-"] { - margin-top: 0; -} -.btn-mini [class^="icon-"], -.btn-mini [class*=" icon-"] { - margin-top: -1px; -} -.btn-mini { - padding: 0 6px; - font-size: 9.75px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.btn-block { - display: block; - width: 100%; - padding-left: 0; - padding-right: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.btn-block + .btn-block { - margin-top: 5px; -} -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} -.btn-primary, -.btn-warning, -.btn-danger, -.btn-success, -.btn-info, -.btn-inverse { - box-shadow: 0 1px 2px rgba(0,0,0,0.05); -} -.btn-primary { - border: 1px solid #15497c; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #2384d3; -} -.btn-primary:hover, -.btn-primary:focus { - background-color: #185b91; - color: #fff; - text-decoration: none; -} -.btn-warning { - border: 1px solid #f89406; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #f89406; -} -.btn-warning:hover, -.btn-warning:focus { - background-color: #ad6704; - color: #fff; - text-decoration: none; - text-shadow: none; -} -.btn-danger { - border: 1px solid #bd362f; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #bd362f; -} -.btn-danger:hover, -.btn-danger:focus { - background-color: #802420; - color: #fff; - text-decoration: none; -} -.btn-success { - border: 1px solid #378137; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #46a546; -} -.btn-success:hover, -.btn-success:focus { - background-color: #2f6f2f; - color: #fff; - text-decoration: none; -} -.btn-info { - border: 1px solid #2f96b4; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #2f96b4; -} -.btn-info:hover, -.btn-info:focus { - background-color: #1f6377; - color: #fff; - text-decoration: none; -} -.btn-inverse { - border: 1px solid #444; - border: 1px solid rgba(0,0,0,0.2); - color: #fff; - background-color: #444; -} -.btn-inverse:hover, -.btn-inverse:focus { - background-color: #1e1e1e; - color: #fff; - text-decoration: none; -} -button.btn, -input[type="submit"].btn { - *padding-top: 3px; - *padding-bottom: 3px; -} -button.btn::-moz-focus-inner, -input[type="submit"].btn::-moz-focus-inner { - padding: 0; - border: 0; -} -button.btn.btn-large, -input[type="submit"].btn.btn-large { - *padding-top: 7px; - *padding-bottom: 7px; -} -button.btn.btn-small, -input[type="submit"].btn.btn-small { - *padding-top: 3px; - *padding-bottom: 3px; -} -button.btn.btn-mini, -input[type="submit"].btn.btn-mini { - *padding-top: 1px; - *padding-bottom: 1px; -} -.btn-link, -.btn-link:active, -.btn-link[disabled] { - background-color: transparent; - background-image: none; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.btn-link { - border-color: transparent; - cursor: pointer; - color: #3071a9; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.btn-link:hover, -.btn-link:focus { - color: #1f496e; - text-decoration: underline; - background-color: transparent; -} -.btn-link[disabled]:hover, -.btn-link[disabled]:focus { - color: #333; - text-decoration: none; -} -.btn-group { - position: relative; - display: inline-block; - *display: inline; - *zoom: 1; - font-size: 0; - vertical-align: middle; - white-space: nowrap; - *margin-left: .3em; -} -.btn-group:first-child { - *margin-left: 0; -} -.btn-group .btn + .btn { - margin-left: -1px; -} -.btn-group + .btn-group { - margin-left: 5px; -} -.btn-toolbar { - font-size: 0; - margin-top: 9px; - margin-bottom: 9px; -} -.btn-toolbar > .btn + .btn, -.btn-toolbar > .btn-group + .btn, -.btn-toolbar > .btn + .btn-group { - margin-left: 5px; -} -.btn-group > .btn { - position: relative; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.btn-group > .btn-micro { - margin-left: -1px; -} -.btn-group > .btn, -.btn-group > .dropdown-menu, -.btn-group > .popover { - font-size: 13px; -} -.btn-group > .btn-mini { - font-size: 9.75px; -} -.btn-group > .btn-small { - font-size: 12px; -} -.btn-group > .btn-large { - font-size: 16.25px; -} -.btn-group > .btn:first-child { - margin-left: 0; - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.btn-group > .btn:last-child, -.btn-group > .dropdown-toggle { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.btn-group > .btn.large:first-child { - margin-left: 0; - -webkit-border-top-left-radius: 6px; - -moz-border-radius-topleft: 6px; - border-top-left-radius: 6px; - -webkit-border-bottom-left-radius: 6px; - -moz-border-radius-bottomleft: 6px; - border-bottom-left-radius: 6px; -} -.btn-group > .btn.large:last-child, -.btn-group > .large.dropdown-toggle { - -webkit-border-top-right-radius: 6px; - -moz-border-radius-topright: 6px; - border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - -moz-border-radius-bottomright: 6px; - border-bottom-right-radius: 6px; -} -.btn-group > .btn:hover, -.btn-group > .btn:focus, -.btn-group > .btn:active, -.btn-group > .btn.active { - z-index: 2; -} -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; - *padding-top: 5px; - *padding-bottom: 5px; -} -.btn-group > .btn-mini + .dropdown-toggle { - padding-left: 5px; - padding-right: 5px; - *padding-top: 2px; - *padding-bottom: 2px; -} -.btn-group > .btn-small + .dropdown-toggle { - *padding-top: 5px; - *padding-bottom: 4px; -} -.btn-group > .btn-large + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; - *padding-top: 7px; - *padding-bottom: 7px; -} -.btn-group.open .dropdown-toggle { - background-image: none; -} -.btn-group.open .btn.dropdown-toggle { - background-color: #e6e6e6; -} -.btn-group.open .btn-primary.dropdown-toggle { - background-color: #15497c; -} -.btn-group.open .btn-warning.dropdown-toggle { - background-color: #c67605; -} -.btn-group.open .btn-danger.dropdown-toggle { - background-color: #942a25; -} -.btn-group.open .btn-success.dropdown-toggle { - background-color: #378137; -} -.btn-group.open .btn-info.dropdown-toggle { - background-color: #24748c; -} -.btn-group.open .btn-inverse.dropdown-toggle { - background-color: #222; -} -.btn .caret { - margin-top: 8px; - margin-left: 0; -} -.btn-large .caret { - margin-top: 6px; -} -.btn-large .caret { - border-left-width: 5px; - border-right-width: 5px; - border-top-width: 5px; -} -.btn-mini .caret, -.btn-small .caret { - margin-top: 8px; -} -.dropup .btn-large .caret { - border-bottom-width: 5px; -} -.btn-primary .caret { - border-top-color: #1f496e; - border-bottom-color: #1f496e; -} -.btn-warning .caret, -.btn-danger .caret, -.btn-info .caret, -.btn-success .caret, -.btn-inverse .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.btn-group-vertical { - display: inline-block; - *display: inline; - *zoom: 1; -} -.btn-group-vertical > .btn { - display: block; - float: none; - max-width: 100%; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.btn-group-vertical > .btn + .btn { - margin-left: 0; - margin-top: -1px; -} -.btn-group-vertical > .btn:first-child { - -webkit-border-radius: 3px 3px 0 0; - -moz-border-radius: 3px 3px 0 0; - border-radius: 3px 3px 0 0; -} -.btn-group-vertical > .btn:last-child { - -webkit-border-radius: 0 0 3px 3px; - -moz-border-radius: 0 0 3px 3px; - border-radius: 0 0 3px 3px; -} -.btn-group-vertical > .btn-large:first-child { - -webkit-border-radius: 6px 6px 0 0; - -moz-border-radius: 6px 6px 0 0; - border-radius: 6px 6px 0 0; -} -.btn-group-vertical > .btn-large:last-child { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} -.alert { - padding: 8px 35px 8px 14px; - margin-bottom: 18px; - text-shadow: 0 1px 0 rgba(255,255,255,0.5); - background-color: #fcf8e3; - border: 1px solid #faebcc; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.alert, -.alert h4 { - color: #8a6d3b; -} -.alert h4 { - margin: 0 0 .5em; -} -.alert .close { - position: relative; - top: -2px; - right: -21px; - line-height: 18px; - cursor: pointer; -} -.alert-success { - background-color: #dff0d8; - border-color: #d6e9c6; - color: #3c763d; -} -.alert-success h4 { - color: #3c763d; -} -.alert-danger, -.alert-error { - background-color: #f2dede; - border-color: #ebccd1; - color: #a94442; -} -.alert-danger h4, -.alert-error h4 { - color: #a94442; -} -.alert-info { - background-color: #d9edf7; - border-color: #bce8f1; - color: #31708f; -} -.alert-info h4 { - color: #31708f; -} -.alert-block { - padding-top: 14px; - padding-bottom: 14px; -} -.alert-block > p, -.alert-block > ul { - margin-bottom: 0; -} -.alert-block p + p { - margin-top: 5px; -} -.nav { - margin-left: 0; - margin-bottom: 18px; - list-style: none; -} -.nav > li > a { - display: block; -} -.nav > li > a:hover, -.nav > li > a:focus { - text-decoration: none; - background-color: #eee; -} -.nav > li > a > img { - max-width: none; -} -.nav > .pull-right { - float: right; -} -.nav-header { - display: block; - padding: 3px 15px; - font-size: 11px; - font-weight: bold; - line-height: 18px; - color: #999; - text-shadow: 0 1px 0 rgba(255,255,255,0.5); - text-transform: uppercase; -} -.nav li + .nav-header { - margin-top: 9px; -} -.nav-list { - padding-left: 15px; - padding-right: 15px; - margin-bottom: 0; -} -.nav-list > li > a, -.nav-list .nav-header { - margin-left: -15px; - margin-right: -15px; - text-shadow: 0 1px 0 rgba(255,255,255,0.5); -} -.nav-list > li > a { - padding: 3px 15px; -} -.nav-list > .active > a, -.nav-list > .active > a:hover, -.nav-list > .active > a:focus { - color: #fff; - text-shadow: 0 -1px 0 rgba(0,0,0,0.2); - background-color: #3071a9; -} -.nav-list [class^="icon-"], -.nav-list [class*=" icon-"] { - margin-right: 2px; -} -.nav-list .divider { - *width: 100%; - height: 1px; - margin: 8px 1px; - *margin: -5px 0 5px; - overflow: hidden; - background-color: #e5e5e5; - border-bottom: 1px solid #fff; -} -.nav-tabs, -.nav-pills { - *zoom: 1; -} -.nav-tabs:before, -.nav-tabs:after, -.nav-pills:before, -.nav-pills:after { - display: table; - content: ""; - line-height: 0; -} -.nav-tabs:after, -.nav-pills:after { - clear: both; -} -.nav-tabs > li, -.nav-pills > li { - float: left; -} -.nav-tabs > li > a, -.nav-pills > li > a { - padding-right: 12px; - padding-left: 12px; - margin-right: 2px; - line-height: 14px; -} -.nav-tabs { - border-bottom: 1px solid #ddd; -} -.nav-tabs > li { - margin-bottom: -1px; -} -.nav-tabs > li > a { - padding-top: 8px; - padding-bottom: 8px; - line-height: 18px; - border: 1px solid transparent; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} -.nav-tabs > li > a:hover, -.nav-tabs > li > a:focus { - border-color: #eee #eee #ddd; -} -.nav-tabs > .active > a, -.nav-tabs > .active > a:hover, -.nav-tabs > .active > a:focus { - color: #555; - background-color: #fff; - border: 1px solid #ddd; - border-bottom-color: transparent; - cursor: default; -} -.nav-pills > li > a { - padding-top: 8px; - padding-bottom: 8px; - margin-top: 2px; - margin-bottom: 2px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.nav-pills > .active > a, -.nav-pills > .active > a:hover, -.nav-pills > .active > a:focus { - color: #fff; - background-color: #3071a9; -} -.nav-stacked > li { - float: none; -} -.nav-stacked > li > a { - margin-right: 0; -} -.nav-tabs.nav-stacked { - border-bottom: 0; -} -.nav-tabs.nav-stacked > li > a { - border: 1px solid #ddd; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.nav-tabs.nav-stacked > li:first-child > a { - -webkit-border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; - border-top-right-radius: 4px; - -webkit-border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; - border-top-left-radius: 4px; -} -.nav-tabs.nav-stacked > li:last-child > a { - -webkit-border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; - border-bottom-right-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - border-bottom-left-radius: 4px; -} -.nav-tabs.nav-stacked > li > a:hover, -.nav-tabs.nav-stacked > li > a:focus { - border-color: #ddd; - z-index: 2; -} -.nav-pills.nav-stacked > li > a { - margin-bottom: 3px; -} -.nav-pills.nav-stacked > li:last-child > a { - margin-bottom: 1px; -} -.nav-tabs .dropdown-menu { - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; -} -.nav-pills .dropdown-menu { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.nav .dropdown-toggle .caret { - border-top-color: #3071a9; - border-bottom-color: #3071a9; - margin-top: 6px; -} -.nav .dropdown-toggle:hover .caret, -.nav .dropdown-toggle:focus .caret { - border-top-color: #1f496e; - border-bottom-color: #1f496e; -} -.nav-tabs .dropdown-toggle .caret { - margin-top: 8px; -} -.nav .active .dropdown-toggle .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.nav-tabs .active .dropdown-toggle .caret { - border-top-color: #555; - border-bottom-color: #555; -} -.nav > .dropdown.active > a:hover, -.nav > .dropdown.active > a:focus { - cursor: pointer; -} -.nav-tabs .open .dropdown-toggle, -.nav-pills .open .dropdown-toggle, -.nav > li.dropdown.open.active > a:hover, -.nav > li.dropdown.open.active > a:focus { - color: #fff; - background-color: #999; - border-color: #999; -} -.nav li.dropdown.open .caret, -.nav li.dropdown.open.active .caret, -.nav li.dropdown.open a:hover .caret, -.nav li.dropdown.open a:focus .caret { - border-top-color: #fff; - border-bottom-color: #fff; - opacity: 1; - filter: alpha(opacity=100); -} -.tabs-stacked .open > a:hover, -.tabs-stacked .open > a:focus { - border-color: #999; -} -.tabbable { - *zoom: 1; -} -.tabbable:before, -.tabbable:after { - display: table; - content: ""; - line-height: 0; -} -.tabbable:after { - clear: both; -} -.tab-content { - overflow: auto; -} -.tabs-below > .nav-tabs, -.tabs-right > .nav-tabs, -.tabs-left > .nav-tabs { - border-bottom: 0; -} -.tab-content > .tab-pane, -.pill-content > .pill-pane { - display: none; -} -.tab-content > .active, -.pill-content > .active { - display: block; -} -.tabs-below > .nav-tabs { - border-top: 1px solid #ddd; -} -.tabs-below > .nav-tabs > li { - margin-top: -1px; - margin-bottom: 0; -} -.tabs-below > .nav-tabs > li > a { - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} -.tabs-below > .nav-tabs > li > a:hover, -.tabs-below > .nav-tabs > li > a:focus { - border-bottom-color: transparent; - border-top-color: #ddd; -} -.tabs-below > .nav-tabs > .active > a, -.tabs-below > .nav-tabs > .active > a:hover, -.tabs-below > .nav-tabs > .active > a:focus { - border-color: transparent #ddd #ddd #ddd; -} -.tabs-left > .nav-tabs > li, -.tabs-right > .nav-tabs > li { - float: none; -} -.tabs-left > .nav-tabs > li > a, -.tabs-right > .nav-tabs > li > a { - min-width: 74px; - margin-right: 0; - margin-bottom: 3px; -} -.tabs-left > .nav-tabs { - float: left; - margin-right: 19px; - border-right: 1px solid #ddd; -} -.tabs-left > .nav-tabs > li > a { - margin-right: -1px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} -.tabs-left > .nav-tabs > li > a:hover, -.tabs-left > .nav-tabs > li > a:focus { - border-color: #eee #ddd #eee #eee; -} -.tabs-left > .nav-tabs .active > a, -.tabs-left > .nav-tabs .active > a:hover, -.tabs-left > .nav-tabs .active > a:focus { - border-color: #ddd transparent #ddd #ddd; - *border-right-color: #fff; -} -.tabs-right > .nav-tabs { - float: right; - margin-left: 19px; - border-left: 1px solid #ddd; -} -.tabs-right > .nav-tabs > li > a { - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} -.tabs-right > .nav-tabs > li > a:hover, -.tabs-right > .nav-tabs > li > a:focus { - border-color: #eee #eee #eee #ddd; -} -.tabs-right > .nav-tabs .active > a, -.tabs-right > .nav-tabs .active > a:hover, -.tabs-right > .nav-tabs .active > a:focus { - border-color: #ddd #ddd #ddd transparent; - *border-left-color: #fff; -} -.nav > .disabled > a { - color: #999; -} -.nav > .disabled > a:hover, -.nav > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - cursor: default; -} -.navbar { - overflow: visible; - margin-bottom: 18px; - *position: relative; - *z-index: 2; -} -.navbar-inner { - min-height: 40px; - padding-left: 20px; - padding-right: 20px; - background-color: #fafafa; - background-image: -moz-linear-gradient(top,#ffffff,#f2f2f2); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#ffffff),to(#f2f2f2)); - background-image: -webkit-linear-gradient(top,#ffffff,#f2f2f2); - background-image: -o-linear-gradient(top,#ffffff,#f2f2f2); - background-image: linear-gradient(to bottom,#ffffff,#f2f2f2); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); - border: 1px solid #d4d4d4; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 4px rgba(0,0,0,0.065); - -moz-box-shadow: 0 1px 4px rgba(0,0,0,0.065); - box-shadow: 0 1px 4px rgba(0,0,0,0.065); - *zoom: 1; -} -.navbar-inner:before, -.navbar-inner:after { - display: table; - content: ""; - line-height: 0; -} -.navbar-inner:after { - clear: both; -} -.navbar .container { - width: auto; -} -.nav-collapse.collapse { - height: auto; - overflow: visible; -} -.navbar .brand { - float: left; - display: block; - padding: 11px 20px 11px; - margin-left: -20px; - font-size: 20px; - font-weight: 200; - color: #555; - text-shadow: 0 1px 0 #ffffff; -} -.navbar .brand:hover, -.navbar .brand:focus { - text-decoration: none; -} -.navbar-text { - margin-bottom: 0; - line-height: 40px; - color: #555; -} -.navbar-link { - color: #555; -} -.navbar-link:hover, -.navbar-link:focus { - color: #333; -} -.navbar .divider-vertical { - height: 40px; - margin: 0 9px; - border-left: 1px solid #f2f2f2; - border-right: 1px solid #ffffff; -} -.navbar .btn, -.navbar .btn-group { - margin-top: 5px; -} -.navbar .btn-group .btn, -.navbar .input-prepend .btn, -.navbar .input-append .btn, -.navbar .input-prepend .btn-group, -.navbar .input-append .btn-group { - margin-top: 0; -} -.navbar-form { - margin-bottom: 0; - *zoom: 1; -} -.navbar-form:before, -.navbar-form:after { - display: table; - content: ""; - line-height: 0; -} -.navbar-form:after { - clear: both; -} -.navbar-form input, -.navbar-form select, -.navbar-form .radio, -.navbar-form .checkbox { - margin-top: 5px; -} -.navbar-form input, -.navbar-form select, -.navbar-form .btn { - display: inline-block; - margin-bottom: 0; -} -.navbar-form input[type="image"], -.navbar-form input[type="checkbox"], -.navbar-form input[type="radio"] { - margin-top: 3px; -} -.navbar-form .input-append, -.navbar-form .input-prepend { - margin-top: 5px; - white-space: nowrap; -} -.navbar-form .input-append input, -.navbar-form .input-prepend input { - margin-top: 0; -} -.navbar-search { - position: relative; - float: left; - margin-top: 5px; - margin-bottom: 0; -} -.navbar-search .search-query { - margin-bottom: 0; - padding: 4px 14px; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: normal; - line-height: 1; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -.navbar-static-top { - position: static; - margin-bottom: 0; -} -.navbar-static-top .navbar-inner { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.navbar-fixed-top, -.navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1030; - margin-bottom: 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - border-width: 0 0 1px; -} -.navbar-fixed-bottom .navbar-inner { - border-width: 1px 0 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-fixed-bottom .navbar-inner { - padding-left: 0; - padding-right: 0; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.navbar-static-top .container, -.navbar-fixed-top .container, -.navbar-fixed-bottom .container { - width: 940px; -} -.navbar-fixed-top { - top: 0; -} -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - -webkit-box-shadow: 0 1px 10px rgba(0,0,0,.1); - -moz-box-shadow: 0 1px 10px rgba(0,0,0,.1); - box-shadow: 0 1px 10px rgba(0,0,0,.1); -} -.navbar-fixed-bottom { - bottom: 0; -} -.navbar-fixed-bottom .navbar-inner { - -webkit-box-shadow: 0 -1px 10px rgba(0,0,0,.1); - -moz-box-shadow: 0 -1px 10px rgba(0,0,0,.1); - box-shadow: 0 -1px 10px rgba(0,0,0,.1); -} -.navbar .nav { - position: relative; - left: 0; - display: block; - float: left; - margin: 0 10px 0 0; -} -.navbar .nav.pull-right { - float: right; - margin-right: 0; -} -.navbar .nav > li { - float: left; -} -.navbar .nav > li > a { - float: none; - padding: 11px 15px 11px; - color: #555; - text-decoration: none; - text-shadow: 0 1px 0 #ffffff; -} -.navbar .nav .dropdown-toggle .caret { - margin-top: 8px; -} -.navbar .nav > li > a:focus, -.navbar .nav > li > a:hover { - background-color: transparent; - color: #333; - text-decoration: none; -} -.navbar .nav > li > a:focus { - outline: 2px solid #5e9ed6; -} -.navbar .nav > .active > a, -.navbar .nav > .active > a:hover, -.navbar .nav > .active > a:focus { - color: #555; - text-decoration: none; - background-color: #e6e6e6; - -webkit-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); - -moz-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); - box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); -} -.navbar .btn-navbar { - display: none; - float: right; - padding: 7px 10px; - margin-left: 5px; - margin-right: 5px; - background-color: #f2f2f2; - *background-color: #f2f2f2; - -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); - -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); - box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); -} -.navbar .btn-navbar:hover, -.navbar .btn-navbar:focus, -.navbar .btn-navbar:active, -.navbar .btn-navbar.active, -.navbar .btn-navbar.disabled, -.navbar .btn-navbar[disabled] { - color: #fff; - background-color: #d9d9d9; - *background-color: #d9d9d9; -} -.navbar .btn-navbar:active, -.navbar .btn-navbar.active { - background-color: #f2f2f2; -} -.navbar .btn-navbar .icon-bar { - display: block; - width: 18px; - height: 2px; - background-color: #f5f5f5; - -webkit-border-radius: 1px; - -moz-border-radius: 1px; - border-radius: 1px; - -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.25); - -moz-box-shadow: 0 1px 0 rgba(0,0,0,0.25); - box-shadow: 0 1px 0 rgba(0,0,0,0.25); -} -.btn-navbar .icon-bar + .icon-bar { - margin-top: 3px; -} -.navbar .nav > li > .dropdown-menu:before { - content: ''; - display: inline-block; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #ccc; - border-bottom-color: rgba(0,0,0,0.2); - position: absolute; - top: -7px; - left: 9px; -} -.navbar .nav > li > .dropdown-menu:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #fff; - position: absolute; - top: -6px; - left: 10px; -} -.navbar-fixed-bottom .nav > li > .dropdown-menu:before { - border-top: 7px solid #ccc; - border-top-color: rgba(0,0,0,0.2); - border-bottom: 0; - bottom: -7px; - top: auto; -} -.navbar-fixed-bottom .nav > li > .dropdown-menu:after { - border-top: 6px solid #fff; - border-bottom: 0; - bottom: -6px; - top: auto; -} -.navbar .nav li.dropdown > a:hover .caret, -.navbar .nav li.dropdown > a:focus .caret { - border-top-color: #333; - border-bottom-color: #333; -} -.navbar .nav li.dropdown.open > .dropdown-toggle, -.navbar .nav li.dropdown.active > .dropdown-toggle, -.navbar .nav li.dropdown.open.active > .dropdown-toggle { - background-color: #e6e6e6; - color: #555; -} -.navbar .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #555; - border-bottom-color: #555; -} -.navbar .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #555; - border-bottom-color: #555; -} -.navbar .pull-right > li > .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right { - left: auto; - right: 0; -} -.navbar .pull-right > li > .dropdown-menu:before, -.navbar .nav > li > .dropdown-menu.pull-right:before { - left: auto; - right: 12px; -} -.navbar .pull-right > li > .dropdown-menu:after, -.navbar .nav > li > .dropdown-menu.pull-right:after { - left: auto; - right: 13px; -} -.navbar .pull-right > li > .dropdown-menu .dropdown-menu, -.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { - left: auto; - right: 100%; - margin-left: 0; - margin-right: -1px; - -webkit-border-radius: 6px 0 6px 6px; - -moz-border-radius: 6px 0 6px 6px; - border-radius: 6px 0 6px 6px; -} -.navbar-inverse .navbar-inner { - background-color: #13294a; - background-image: -moz-linear-gradient(top,#152d53,#10223e); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#152d53),to(#10223e)); - background-image: -webkit-linear-gradient(top,#152d53,#10223e); - background-image: -o-linear-gradient(top,#152d53,#10223e); - background-image: linear-gradient(to bottom,#152d53,#10223e); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff142c52', endColorstr='#ff0f213e', GradientType=0); - border-color: #0b172a; -} -.navbar-inverse .brand, -.navbar-inverse .nav > li > a { - color: #d9d9d9; - text-shadow: 0 -1px 0 rgba(0,0,0,0.25); -} -.navbar-inverse .brand:hover, -.navbar-inverse .brand:focus, -.navbar-inverse .nav > li > a:hover, -.navbar-inverse .nav > li > a:focus { - color: #fff; -} -.navbar-inverse .brand { - color: #d9d9d9; -} -.navbar-inverse .navbar-text { - color: #d9d9d9; -} -.navbar-inverse .nav > li > a:focus, -.navbar-inverse .nav > li > a:hover { - background-color: transparent; - color: #fff; -} -.navbar-inverse .nav .active > a, -.navbar-inverse .nav .active > a:hover, -.navbar-inverse .nav .active > a:focus { - color: #fff; - background-color: #10223e; -} -.navbar-inverse .navbar-link { - color: #d9d9d9; -} -.navbar-inverse .navbar-link:hover, -.navbar-inverse .navbar-link:focus { - color: #fff; -} -.navbar-inverse .divider-vertical { - border-left-color: #10223e; - border-right-color: #152d53; -} -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { - background-color: #10223e; - color: #fff; -} -.navbar-inverse .nav li.dropdown > a:hover .caret, -.navbar-inverse .nav li.dropdown > a:focus .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { - border-top-color: #d9d9d9; - border-bottom-color: #d9d9d9; -} -.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, -.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { - border-top-color: #fff; - border-bottom-color: #fff; -} -.navbar-inverse .navbar-search .search-query { - color: #fff; - background-color: #2959a4; - border-color: #10223e; - -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); - -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); - box-shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15); - -webkit-transition: none; - -moz-transition: none; - -o-transition: none; - transition: none; -} -.navbar-inverse .navbar-search .search-query:-moz-placeholder { - color: #ccc; -} -.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { - color: #ccc; -} -.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { - color: #ccc; -} -.navbar-inverse .navbar-search .search-query:focus, -.navbar-inverse .navbar-search .search-query.focused { - padding: 5px 15px; - color: #333; - text-shadow: 0 1px 0 #fff; - background-color: #fff; - border: 0; - -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.15); - -moz-box-shadow: 0 0 3px rgba(0,0,0,0.15); - box-shadow: 0 0 3px rgba(0,0,0,0.15); - outline: 0; -} -.navbar-inverse .btn-navbar { - background-color: #10223e; - *background-color: #10223e; -} -.navbar-inverse .btn-navbar:hover, -.navbar-inverse .btn-navbar:focus, -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active, -.navbar-inverse .btn-navbar.disabled, -.navbar-inverse .btn-navbar[disabled] { - color: #fff; - background-color: #050c16; - *background-color: #050c16; -} -.navbar-inverse .btn-navbar:active, -.navbar-inverse .btn-navbar.active { - background-color: #10223e; -} -.breadcrumb { - padding: 8px 15px; - margin: 0 0 18px; - list-style: none; - background-color: #f5f5f5; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.breadcrumb > li { - display: inline-block; - *display: inline; - *zoom: 1; - text-shadow: 0 1px 0 #fff; -} -.breadcrumb > li > .divider { - padding: 0 5px; - color: #ccc; -} -.breadcrumb > .active { - color: #999; -} -.pagination { - margin: 18px 0; -} -.pagination ul { - display: inline-block; - *display: inline; - *zoom: 1; - margin-left: 0; - margin-bottom: 0; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.05); - -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.05); - box-shadow: 0 1px 2px rgba(0,0,0,0.05); -} -.pagination ul > li { - display: inline; -} -.pagination ul > li > a, -.pagination ul > li > span { - float: left; - padding: 4px 12px; - line-height: 18px; - text-decoration: none; - background-color: #fff; - border: 1px solid #ddd; - border-left-width: 0; -} -.pagination ul > li > a:hover, -.pagination ul > li > a:focus, -.pagination ul > .active > a, -.pagination ul > .active > span { - background-color: #F0F0F0; -} -.pagination ul > .active > a, -.pagination ul > .active > span { - color: #999; - cursor: default; -} -.pagination ul > .disabled > span, -.pagination ul > .disabled > a, -.pagination ul > .disabled > a:hover, -.pagination ul > .disabled > a:focus { - color: #999; - background-color: transparent; - cursor: default; -} -.pagination ul > li:first-child > a, -.pagination ul > li:first-child > span { - border-left-width: 1px; - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.pagination ul > li:last-child > a, -.pagination ul > li:last-child > span { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.pagination-centered { - text-align: center; -} -.pagination-right { - text-align: right; -} -.pagination-large ul > li > a, -.pagination-large ul > li > span { - padding: 11px 19px; - font-size: 16.25px; -} -.pagination-large ul > li:first-child > a, -.pagination-large ul > li:first-child > span { - -webkit-border-top-left-radius: 6px; - -moz-border-radius-topleft: 6px; - border-top-left-radius: 6px; - -webkit-border-bottom-left-radius: 6px; - -moz-border-radius-bottomleft: 6px; - border-bottom-left-radius: 6px; -} -.pagination-large ul > li:last-child > a, -.pagination-large ul > li:last-child > span { - -webkit-border-top-right-radius: 6px; - -moz-border-radius-topright: 6px; - border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - -moz-border-radius-bottomright: 6px; - border-bottom-right-radius: 6px; -} -.pagination-mini ul > li:first-child > a, -.pagination-mini ul > li:first-child > span, -.pagination-small ul > li:first-child > a, -.pagination-small ul > li:first-child > span { - -webkit-border-top-left-radius: 3px; - -moz-border-radius-topleft: 3px; - border-top-left-radius: 3px; - -webkit-border-bottom-left-radius: 3px; - -moz-border-radius-bottomleft: 3px; - border-bottom-left-radius: 3px; -} -.pagination-mini ul > li:last-child > a, -.pagination-mini ul > li:last-child > span, -.pagination-small ul > li:last-child > a, -.pagination-small ul > li:last-child > span { - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topright: 3px; - border-top-right-radius: 3px; - -webkit-border-bottom-right-radius: 3px; - -moz-border-radius-bottomright: 3px; - border-bottom-right-radius: 3px; -} -.pagination-small ul > li > a, -.pagination-small ul > li > span { - padding: 2px 10px; - font-size: 12px; -} -.pagination-mini ul > li > a, -.pagination-mini ul > li > span { - padding: 0 6px; - font-size: 9.75px; -} -.pager { - margin: 18px 0; - list-style: none; - text-align: center; - *zoom: 1; -} -.pager:before, -.pager:after { - display: table; - content: ""; - line-height: 0; -} -.pager:after { - clear: both; -} -.pager li { - display: inline; -} -.pager li > a, -.pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #fff; - border: 1px solid #ddd; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - border-radius: 15px; -} -.pager li > a:hover, -.pager li > a:focus { - text-decoration: none; - background-color: #f5f5f5; -} -.pager .next > a, -.pager .next > span { - float: right; -} -.pager .previous > a, -.pager .previous > span { - float: left; -} -.pager .disabled > a, -.pager .disabled > a:hover, -.pager .disabled > a:focus, -.pager .disabled > span { - color: #999; - background-color: #fff; - cursor: default; -} -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000; -} -.modal-backdrop.fade { - opacity: 0; -} -.modal-backdrop, -.modal-backdrop.fade.in { - opacity: 0.8; - filter: alpha(opacity=80); -} -.modal-header { - padding: 9px 15px; - border-bottom: 1px solid #eee; -} -.modal-header .close { - margin-top: 2px; -} -.modal-header h3 { - margin: 0; - line-height: 30px; -} -.modal-body { - width: 98%; - position: relative; - max-height: 400px; - padding: 1%; -} -.modal-body iframe { - width: 100%; - max-height: none; - border: 0 !important; -} -.modal-form { - margin-bottom: 0; -} -.modal-footer { - padding: 14px 15px 15px; - margin-bottom: 0; - text-align: right; - background-color: #f5f5f5; - border-top: 1px solid #ddd; - -webkit-border-radius: 0 0 6px 6px; - -moz-border-radius: 0 0 6px 6px; - border-radius: 0 0 6px 6px; - -webkit-box-shadow: inset 0 1px 0 #fff; - -moz-box-shadow: inset 0 1px 0 #fff; - box-shadow: inset 0 1px 0 #fff; - *zoom: 1; -} -.modal-footer:before, -.modal-footer:after { - display: table; - content: ""; - line-height: 0; -} -.modal-footer:after { - clear: both; -} -.modal-footer .btn + .btn { - margin-left: 5px; - margin-bottom: 0; -} -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} -.tooltip { - position: absolute; - z-index: 1030; - display: block; - visibility: visible; - font-size: 11px; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); -} -.tooltip.in { - opacity: 0.8; - filter: alpha(opacity=80); -} -.tooltip.top { - margin-top: -3px; - padding: 5px 0; -} -.tooltip.right { - margin-left: 3px; - padding: 0 5px; -} -.tooltip.bottom { - margin-top: 3px; - padding: 5px 0; -} -.tooltip.left { - margin-left: -3px; - padding: 0 5px; -} -.tooltip-inner { - max-width: 200px; - padding: 8px; - color: #fff; - text-align: center; - text-decoration: none; - background-color: #000; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000; -} -.tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000; -} -.tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000; -} -.tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; -} -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1060; - display: none; - max-width: 276px; - padding: 1px; - text-align: left; - background-color: #fff; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,0.2); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); - -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); - box-shadow: 0 5px 10px rgba(0,0,0,0.2); - white-space: normal; -} -.popover.top { - margin-top: -10px; -} -.popover.right { - margin-left: 10px; -} -.popover.bottom { - margin-top: 10px; -} -.popover.left { - margin-left: -10px; -} -.popover-title { - margin: 0; - padding: 8px 14px; - font-size: 14px; - font-weight: normal; - line-height: 18px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - -webkit-border-radius: 5px 5px 0 0; - -moz-border-radius: 5px 5px 0 0; - border-radius: 5px 5px 0 0; -} -.popover-title:empty { - display: none; -} -.popover-content { - padding: 9px 14px; -} -.popover .arrow, -.popover .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.popover .arrow { - border-width: 11px; -} -.popover .arrow:after { - border-width: 10px; - content: ""; -} -.popover.top .arrow { - left: 50%; - margin-left: -11px; - border-bottom-width: 0; - border-top-color: #999; - border-top-color: rgba(0,0,0,0.25); - bottom: -11px; -} -.popover.top .arrow:after { - bottom: 1px; - margin-left: -10px; - border-bottom-width: 0; - border-top-color: #fff; -} -.popover.right .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-left-width: 0; - border-right-color: #999; - border-right-color: rgba(0,0,0,0.25); -} -.popover.right .arrow:after { - left: 1px; - bottom: -10px; - border-left-width: 0; - border-right-color: #fff; -} -.popover.bottom .arrow { - left: 50%; - margin-left: -11px; - border-top-width: 0; - border-bottom-color: #999; - border-bottom-color: rgba(0,0,0,0.25); - top: -11px; -} -.popover.bottom .arrow:after { - top: 1px; - margin-left: -10px; - border-top-width: 0; - border-bottom-color: #fff; -} -.popover.left .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-right-width: 0; - border-left-color: #999; - border-left-color: rgba(0,0,0,0.25); -} -.popover.left .arrow:after { - right: 1px; - border-right-width: 0; - border-left-color: #fff; - bottom: -10px; -} -.thumbnails { - margin-left: -20px; - list-style: none; - *zoom: 1; -} -.thumbnails:before, -.thumbnails:after { - display: table; - content: ""; - line-height: 0; -} -.thumbnails:after { - clear: both; -} -.row-fluid .thumbnails { - margin-left: 0; -} -.thumbnails > li { - float: left; - margin-bottom: 18px; - margin-left: 20px; -} -.thumbnail { - display: block; - padding: 4px; - line-height: 18px; - border: 1px solid #ddd; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.055); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.055); - box-shadow: 0 1px 3px rgba(0,0,0,0.055); - -webkit-transition: all .2s ease-in-out; - -moz-transition: all .2s ease-in-out; - -o-transition: all .2s ease-in-out; - transition: all .2s ease-in-out; -} -a.thumbnail:hover, -a.thumbnail:focus { - border-color: #3071a9; - -webkit-box-shadow: 0 1px 4px rgba(0,105,214,0.25); - -moz-box-shadow: 0 1px 4px rgba(0,105,214,0.25); - box-shadow: 0 1px 4px rgba(0,105,214,0.25); -} -.thumbnail > img { - display: block; - max-width: 100%; - margin-left: auto; - margin-right: auto; -} -.thumbnail .caption { - padding: 9px; - color: #555; -} -.media, -.media-body { - overflow: hidden; - *overflow: visible; - zoom: 1; -} -.media, -.media .media { - margin-top: 15px; -} -.media:first-child { - margin-top: 0; -} -.media-object { - display: block; -} -.media-heading { - margin: 0 0 5px; -} -.media > .pull-left { - margin-right: 10px; -} -.media > .pull-right { - margin-left: 10px; -} -.media-list { - margin-left: 0; - list-style: none; -} -.label, -.badge { - display: inline-block; - padding: 2px 4px; - font-size: 10.998px; - font-weight: bold; - line-height: 14px; - color: #fff; - vertical-align: baseline; - white-space: nowrap; - text-shadow: 0 -1px 0 rgba(0,0,0,0.25); - background-color: #999; -} -.label { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.badge { - padding-left: 9px; - padding-right: 9px; - -webkit-border-radius: 9px; - -moz-border-radius: 9px; - border-radius: 9px; -} -.label:empty, -.badge:empty { - display: none; -} -a.label:hover, -a.label:focus, -a.badge:hover, -a.badge:focus { - color: #fff; - text-decoration: none; - cursor: pointer; -} -.label-important, -.badge-important { - background-color: #a94442; -} -.label-important[href], -.badge-important[href] { - background-color: #843534; -} -.label-warning, -.badge-warning { - background-color: #f89406; -} -.label-warning[href], -.badge-warning[href] { - background-color: #c67605; -} -.label-success, -.badge-success { - background-color: #3c763d; -} -.label-success[href], -.badge-success[href] { - background-color: #2b542c; -} -.label-info, -.badge-info { - background-color: #31708f; -} -.label-info[href], -.badge-info[href] { - background-color: #245269; -} -.label-inverse, -.badge-inverse { - background-color: #333; -} -.label-inverse[href], -.badge-inverse[href] { - background-color: #1a1a1a; -} -.btn .label, -.btn .badge { - position: relative; - top: -1px; -} -.btn-mini .label, -.btn-mini .badge { - top: 0; -} -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-moz-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-ms-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -@-o-keyframes progress-bar-stripes { - from { - background-position: 0 0; - } - to { - background-position: 40px 0; - } -} -@keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } -} -.progress { - overflow: hidden; - height: 18px; - margin-bottom: 18px; - background-color: #f7f7f7; - background-image: -moz-linear-gradient(top,#f5f5f5,#f9f9f9); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9)); - background-image: -webkit-linear-gradient(top,#f5f5f5,#f9f9f9); - background-image: -o-linear-gradient(top,#f5f5f5,#f9f9f9); - background-image: linear-gradient(to bottom,#f5f5f5,#f9f9f9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); - -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); - box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.progress .bar { - width: 0%; - height: 100%; - color: #fff; - float: left; - font-size: 12px; - text-align: center; - text-shadow: 0 -1px 0 rgba(0,0,0,0.25); - background-color: #0e90d2; - background-image: -moz-linear-gradient(top,#149bdf,#0480be); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be)); - background-image: -webkit-linear-gradient(top,#149bdf,#0480be); - background-image: -o-linear-gradient(top,#149bdf,#0480be); - background-image: linear-gradient(to bottom,#149bdf,#0480be); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); - -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); - -moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); - box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: width .6s ease; - -moz-transition: width .6s ease; - -o-transition: width .6s ease; - transition: width .6s ease; -} -.progress .bar + .bar { - -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); - -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); - box-shadow: inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15); -} -.progress-striped .bar { - background-color: #149bdf; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - -webkit-background-size: 40px 40px; - -moz-background-size: 40px 40px; - -o-background-size: 40px 40px; - background-size: 40px 40px; -} -.progress.active .bar { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -moz-animation: progress-bar-stripes 2s linear infinite; - -ms-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; -} -.progress-danger .bar, -.progress .bar-danger { - background-color: #dd514c; - background-image: -moz-linear-gradient(top,#ee5f5b,#c43c35); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35)); - background-image: -webkit-linear-gradient(top,#ee5f5b,#c43c35); - background-image: -o-linear-gradient(top,#ee5f5b,#c43c35); - background-image: linear-gradient(to bottom,#ee5f5b,#c43c35); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); -} -.progress-danger.progress-striped .bar, -.progress-striped .bar-danger { - background-color: #ee5f5b; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); -} -.progress-success .bar, -.progress .bar-success { - background-color: #5eb95e; - background-image: -moz-linear-gradient(top,#62c462,#57a957); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957)); - background-image: -webkit-linear-gradient(top,#62c462,#57a957); - background-image: -o-linear-gradient(top,#62c462,#57a957); - background-image: linear-gradient(to bottom,#62c462,#57a957); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); -} -.progress-success.progress-striped .bar, -.progress-striped .bar-success { - background-color: #62c462; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); -} -.progress-info .bar, -.progress .bar-info { - background-color: #4bb1cf; - background-image: -moz-linear-gradient(top,#5bc0de,#339bb9); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9)); - background-image: -webkit-linear-gradient(top,#5bc0de,#339bb9); - background-image: -o-linear-gradient(top,#5bc0de,#339bb9); - background-image: linear-gradient(to bottom,#5bc0de,#339bb9); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); -} -.progress-info.progress-striped .bar, -.progress-striped .bar-info { - background-color: #5bc0de; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); -} -.progress-warning .bar, -.progress .bar-warning { - background-color: #faa732; - background-image: -moz-linear-gradient(top,#fbb450,#f89406); - background-image: -webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406)); - background-image: -webkit-linear-gradient(top,#fbb450,#f89406); - background-image: -o-linear-gradient(top,#fbb450,#f89406); - background-image: linear-gradient(to bottom,#fbb450,#f89406); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffab44f', endColorstr='#fff89406', GradientType=0); -} -.progress-warning.progress-striped .bar, -.progress-striped .bar-warning { - background-color: #fbb450; - background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(.25,rgba(255,255,255,0.15)),color-stop(.25,transparent),color-stop(.5,transparent),color-stop(.5,rgba(255,255,255,0.15)),color-stop(.75,rgba(255,255,255,0.15)),color-stop(.75,transparent),to(transparent)); - background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); - background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); -} -.accordion { - margin-bottom: 18px; -} -.accordion-group { - margin-bottom: 2px; - border: 1px solid #e5e5e5; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.accordion-heading { - border-bottom: 0; -} -.accordion-heading .accordion-toggle { - display: block; - padding: 8px 15px; -} -.accordion-toggle { - cursor: pointer; -} -.accordion-inner { - padding: 9px 15px; - border-top: 1px solid #e5e5e5; -} -.carousel { - position: relative; - margin-bottom: 18px; - line-height: 1; -} -.carousel-inner { - overflow: hidden; - width: 100%; - position: relative; -} -.carousel-inner > .item { - display: none; - position: relative; - -webkit-transition: .6s ease-in-out left; - -moz-transition: .6s ease-in-out left; - -o-transition: .6s ease-in-out left; - transition: .6s ease-in-out left; -} -.carousel-inner > .item > img, -.carousel-inner > .item > a > img { - display: block; - line-height: 1; -} -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - display: block; -} -.carousel-inner > .active { - left: 0; -} -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} -.carousel-inner > .next { - left: 100%; -} -.carousel-inner > .prev { - left: -100%; -} -.carousel-inner > .next.left, -.carousel-inner > .prev.right { - left: 0; -} -.carousel-inner > .active.left { - left: -100%; -} -.carousel-inner > .active.right { - left: 100%; -} -.carousel-control { - position: absolute; - top: 40%; - left: 15px; - width: 40px; - height: 40px; - margin-top: -20px; - font-size: 60px; - font-weight: 100; - line-height: 30px; - color: #fff; - text-align: center; - background: #222; - border: 3px solid #fff; - -webkit-border-radius: 23px; - -moz-border-radius: 23px; - border-radius: 23px; - opacity: 0.5; - filter: alpha(opacity=50); -} -.carousel-control.right { - left: auto; - right: 15px; -} -.carousel-control:hover, -.carousel-control:focus { - color: #fff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); -} -.carousel-indicators { - position: absolute; - top: 15px; - right: 15px; - z-index: 5; - margin: 0; - list-style: none; -} -.carousel-indicators li { - display: block; - float: left; - width: 10px; - height: 10px; - margin-left: 5px; - text-indent: -999px; - background-color: #ccc; - background-color: rgba(255,255,255,0.25); - border-radius: 5px; -} -.carousel-indicators .active { - background-color: #fff; -} -.carousel-caption { - position: absolute; - left: 0; - right: 0; - bottom: 0; - padding: 15px; - background: #333; - background: rgba(0,0,0,0.75); -} -.carousel-caption h4, -.carousel-caption p { - color: #fff; - line-height: 18px; -} -.carousel-caption h4 { - margin: 0 0 5px; -} -.carousel-caption p { - margin-bottom: 0; -} -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 27px; - color: inherit; - background-color: #eee; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; -} -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - color: inherit; - letter-spacing: -1px; -} -.hero-unit li { - line-height: 27px; -} -.pull-right { - float: right; -} -.pull-left { - float: left; -} -.hide { - display: none; -} -.show { - display: block; -} -.invisible { - visibility: hidden; -} -.affix { - position: fixed; -} -@-ms-viewport { - width: device-width; -} -.hidden { - display: none; - visibility: hidden; -} -.visible-phone { - display: none !important; -} -.visible-tablet { - display: none !important; -} -.hidden-desktop { - display: none !important; -} -.visible-desktop { - display: inherit !important; -} -@media (min-width: 768px) and (max-width: 979px) { - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important; - } - .visible-tablet { - display: inherit !important; - } - .hidden-tablet { - display: none !important; - } -} -@media (max-width: 767px) { - .hidden-desktop { - display: inherit !important; - } - .visible-desktop { - display: none !important; - } - .visible-phone { - display: inherit !important; - } - .hidden-phone { - display: none !important; - } -} -.visible-print { - display: none !important; -} -@media print { - .visible-print { - display: inherit !important; - } - .hidden-print { - display: none !important; - } -} -@media (max-width: 767px) { - body { - padding-left: 20px; - padding-right: 20px; - } - .navbar-fixed-top, - .navbar-fixed-bottom, - .navbar-static-top { - margin-left: -20px; - margin-right: -20px; - } - .container-fluid { - padding: 0; - } - .dl-horizontal dt { - float: none; - clear: none; - width: auto; - text-align: left; - } - .dl-horizontal dd { - margin-left: 0; - } - .dropdown-menu .menuitem-group { - background-color: #10223e; - color: #eee; - } - .container { - width: auto; - } - .row-fluid { - width: 100%; - } - .row, - .thumbnails { - margin-left: 0; - } - .thumbnails > li { - float: none; - margin-left: 0; - } - [class*="span"], - .uneditable-input[class*="span"], - .row-fluid [class*="span"] { - float: none; - display: block; - width: 100%; - margin-left: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .span12, - .row-fluid .span12 { - width: 100%; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .row-fluid [class*="offset"]:first-child { - margin-left: 0; - } - .input-large, - .input-xlarge, - .input-xxlarge, - input[class*="span"], - select[class*="span"], - textarea[class*="span"], - .uneditable-input { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .input-prepend input, - .input-append input, - .input-prepend input[class*="span"], - .input-append input[class*="span"] { - display: inline-block; - width: auto; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 0; - } -} -@media (max-width: 480px) { - .nav-collapse { - -webkit-transform: translate3d(0,0,0); - } - .page-header h1 small { - display: block; - line-height: 18px; - } - input[type="checkbox"], - input[type="radio"] { - border: 1px solid #ccc; - } - .form-horizontal .control-label { - float: none; - width: auto; - padding-top: 0; - text-align: left; - } - .form-horizontal .controls { - margin-left: 0; - } - .form-horizontal .control-list { - padding-top: 0; - } - .form-horizontal .form-actions { - padding-left: 10px; - padding-right: 10px; - } - .tag-category input#filter-search, - .newsfeed-category input#filter-search { - width: auto; - margin-bottom: 9px; - } - .category-list input#filter-search { - width: auto; - } - .media .pull-left, - .media .pull-right { - float: none; - display: block; - margin-bottom: 10px; - } - .media-object { - margin-right: 0; - margin-left: 0; - } - .modal-header .close { - padding: 10px; - margin: -10px; - } - .carousel-caption { - position: static; - } -} -@media (min-width: 768px) and (max-width: 979px) { - .row { - margin-left: -20px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - content: ""; - line-height: 0; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - min-height: 1px; - margin-left: 20px; - } - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 724px; - } - .span12 { - width: 724px; - } - .span11 { - width: 662px; - } - .span10 { - width: 600px; - } - .span9 { - width: 538px; - } - .span8 { - width: 476px; - } - .span7 { - width: 414px; - } - .span6 { - width: 352px; - } - .span5 { - width: 290px; - } - .span4 { - width: 228px; - } - .span3 { - width: 166px; - } - .span2 { - width: 104px; - } - .span1 { - width: 42px; - } - .offset12 { - margin-left: 764px; - } - .offset11 { - margin-left: 702px; - } - .offset10 { - margin-left: 640px; - } - .offset9 { - margin-left: 578px; - } - .offset8 { - margin-left: 516px; - } - .offset7 { - margin-left: 454px; - } - .offset6 { - margin-left: 392px; - } - .offset5 { - margin-left: 330px; - } - .offset4 { - margin-left: 268px; - } - .offset3 { - margin-left: 206px; - } - .offset2 { - margin-left: 144px; - } - .offset1 { - margin-left: 82px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - content: ""; - line-height: 0; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - float: left; - margin-left: 2.76243094%; - *margin-left: 2.70923945%; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.76243094%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851%; - } - .row-fluid .span11 { - width: 91.43646409%; - *width: 91.3832726%; - } - .row-fluid .span10 { - width: 82.87292818%; - *width: 82.81973669%; - } - .row-fluid .span9 { - width: 74.30939227%; - *width: 74.25620078%; - } - .row-fluid .span8 { - width: 65.74585635%; - *width: 65.69266486%; - } - .row-fluid .span7 { - width: 57.18232044%; - *width: 57.12912895%; - } - .row-fluid .span6 { - width: 48.61878453%; - *width: 48.56559304%; - } - .row-fluid .span5 { - width: 40.05524862%; - *width: 40.00205713%; - } - .row-fluid .span4 { - width: 31.49171271%; - *width: 31.43852122%; - } - .row-fluid .span3 { - width: 22.9281768%; - *width: 22.87498531%; - } - .row-fluid .span2 { - width: 14.36464088%; - *width: 14.31144939%; - } - .row-fluid .span1 { - width: 5.80110497%; - *width: 5.74791348%; - } - .row-fluid .offset12 { - margin-left: 105.52486188%; - *margin-left: 105.4184789%; - } - .row-fluid .offset12:first-child { - margin-left: 102.76243094%; - *margin-left: 102.65604796%; - } - .row-fluid .offset11 { - margin-left: 96.96132597%; - *margin-left: 96.85494299%; - } - .row-fluid .offset11:first-child { - margin-left: 94.19889503%; - *margin-left: 94.09251205%; - } - .row-fluid .offset10 { - margin-left: 88.39779006%; - *margin-left: 88.29140708%; - } - .row-fluid .offset10:first-child { - margin-left: 85.63535912%; - *margin-left: 85.52897614%; - } - .row-fluid .offset9 { - margin-left: 79.83425414%; - *margin-left: 79.72787116%; - } - .row-fluid .offset9:first-child { - margin-left: 77.0718232%; - *margin-left: 76.96544023%; - } - .row-fluid .offset8 { - margin-left: 71.27071823%; - *margin-left: 71.16433525%; - } - .row-fluid .offset8:first-child { - margin-left: 68.50828729%; - *margin-left: 68.40190431%; - } - .row-fluid .offset7 { - margin-left: 62.70718232%; - *margin-left: 62.60079934%; - } - .row-fluid .offset7:first-child { - margin-left: 59.94475138%; - *margin-left: 59.8383684%; - } - .row-fluid .offset6 { - margin-left: 54.14364641%; - *margin-left: 54.03726343%; - } - .row-fluid .offset6:first-child { - margin-left: 51.38121547%; - *margin-left: 51.27483249%; - } - .row-fluid .offset5 { - margin-left: 45.5801105%; - *margin-left: 45.47372752%; - } - .row-fluid .offset5:first-child { - margin-left: 42.81767956%; - *margin-left: 42.71129658%; - } - .row-fluid .offset4 { - margin-left: 37.01657459%; - *margin-left: 36.91019161%; - } - .row-fluid .offset4:first-child { - margin-left: 34.25414365%; - *margin-left: 34.14776067%; - } - .row-fluid .offset3 { - margin-left: 28.45303867%; - *margin-left: 28.3466557%; - } - .row-fluid .offset3:first-child { - margin-left: 25.69060773%; - *margin-left: 25.58422476%; - } - .row-fluid .offset2 { - margin-left: 19.88950276%; - *margin-left: 19.78311978%; - } - .row-fluid .offset2:first-child { - margin-left: 17.12707182%; - *margin-left: 17.02068884%; - } - .row-fluid .offset1 { - margin-left: 11.32596685%; - *margin-left: 11.21958387%; - } - .row-fluid .offset1:first-child { - margin-left: 8.56353591%; - *margin-left: 8.45715293%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 20px; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 710px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 648px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 586px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 524px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 462px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 400px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 338px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 276px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 214px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 152px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 90px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 28px; - } -} -@media (min-width: 1200px) { - .row { - margin-left: -30px; - *zoom: 1; - } - .row:before, - .row:after { - display: table; - content: ""; - line-height: 0; - } - .row:after { - clear: both; - } - [class*="span"] { - float: left; - min-height: 1px; - margin-left: 30px; - } - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { - width: 1170px; - } - .span12 { - width: 1170px; - } - .span11 { - width: 1070px; - } - .span10 { - width: 970px; - } - .span9 { - width: 870px; - } - .span8 { - width: 770px; - } - .span7 { - width: 670px; - } - .span6 { - width: 570px; - } - .span5 { - width: 470px; - } - .span4 { - width: 370px; - } - .span3 { - width: 270px; - } - .span2 { - width: 170px; - } - .span1 { - width: 70px; - } - .offset12 { - margin-left: 1230px; - } - .offset11 { - margin-left: 1130px; - } - .offset10 { - margin-left: 1030px; - } - .offset9 { - margin-left: 930px; - } - .offset8 { - margin-left: 830px; - } - .offset7 { - margin-left: 730px; - } - .offset6 { - margin-left: 630px; - } - .offset5 { - margin-left: 530px; - } - .offset4 { - margin-left: 430px; - } - .offset3 { - margin-left: 330px; - } - .offset2 { - margin-left: 230px; - } - .offset1 { - margin-left: 130px; - } - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - content: ""; - line-height: 0; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - float: left; - margin-left: 2.76243094%; - *margin-left: 2.70923945%; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.76243094%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851%; - } - .row-fluid .span11 { - width: 91.43646409%; - *width: 91.3832726%; - } - .row-fluid .span10 { - width: 82.87292818%; - *width: 82.81973669%; - } - .row-fluid .span9 { - width: 74.30939227%; - *width: 74.25620078%; - } - .row-fluid .span8 { - width: 65.74585635%; - *width: 65.69266486%; - } - .row-fluid .span7 { - width: 57.18232044%; - *width: 57.12912895%; - } - .row-fluid .span6 { - width: 48.61878453%; - *width: 48.56559304%; - } - .row-fluid .span5 { - width: 40.05524862%; - *width: 40.00205713%; - } - .row-fluid .span4 { - width: 31.49171271%; - *width: 31.43852122%; - } - .row-fluid .span3 { - width: 22.9281768%; - *width: 22.87498531%; - } - .row-fluid .span2 { - width: 14.36464088%; - *width: 14.31144939%; - } - .row-fluid .span1 { - width: 5.80110497%; - *width: 5.74791348%; - } - .row-fluid .offset12 { - margin-left: 105.52486188%; - *margin-left: 105.4184789%; - } - .row-fluid .offset12:first-child { - margin-left: 102.76243094%; - *margin-left: 102.65604796%; - } - .row-fluid .offset11 { - margin-left: 96.96132597%; - *margin-left: 96.85494299%; - } - .row-fluid .offset11:first-child { - margin-left: 94.19889503%; - *margin-left: 94.09251205%; - } - .row-fluid .offset10 { - margin-left: 88.39779006%; - *margin-left: 88.29140708%; - } - .row-fluid .offset10:first-child { - margin-left: 85.63535912%; - *margin-left: 85.52897614%; - } - .row-fluid .offset9 { - margin-left: 79.83425414%; - *margin-left: 79.72787116%; - } - .row-fluid .offset9:first-child { - margin-left: 77.0718232%; - *margin-left: 76.96544023%; - } - .row-fluid .offset8 { - margin-left: 71.27071823%; - *margin-left: 71.16433525%; - } - .row-fluid .offset8:first-child { - margin-left: 68.50828729%; - *margin-left: 68.40190431%; - } - .row-fluid .offset7 { - margin-left: 62.70718232%; - *margin-left: 62.60079934%; - } - .row-fluid .offset7:first-child { - margin-left: 59.94475138%; - *margin-left: 59.8383684%; - } - .row-fluid .offset6 { - margin-left: 54.14364641%; - *margin-left: 54.03726343%; - } - .row-fluid .offset6:first-child { - margin-left: 51.38121547%; - *margin-left: 51.27483249%; - } - .row-fluid .offset5 { - margin-left: 45.5801105%; - *margin-left: 45.47372752%; - } - .row-fluid .offset5:first-child { - margin-left: 42.81767956%; - *margin-left: 42.71129658%; - } - .row-fluid .offset4 { - margin-left: 37.01657459%; - *margin-left: 36.91019161%; - } - .row-fluid .offset4:first-child { - margin-left: 34.25414365%; - *margin-left: 34.14776067%; - } - .row-fluid .offset3 { - margin-left: 28.45303867%; - *margin-left: 28.3466557%; - } - .row-fluid .offset3:first-child { - margin-left: 25.69060773%; - *margin-left: 25.58422476%; - } - .row-fluid .offset2 { - margin-left: 19.88950276%; - *margin-left: 19.78311978%; - } - .row-fluid .offset2:first-child { - margin-left: 17.12707182%; - *margin-left: 17.02068884%; - } - .row-fluid .offset1 { - margin-left: 11.32596685%; - *margin-left: 11.21958387%; - } - .row-fluid .offset1:first-child { - margin-left: 8.56353591%; - *margin-left: 8.45715293%; - } - input, - textarea, - .uneditable-input { - margin-left: 0; - } - .controls-row [class*="span"] + [class*="span"] { - margin-left: 30px; - } - input.span12, - textarea.span12, - .uneditable-input.span12 { - width: 1156px; - } - input.span11, - textarea.span11, - .uneditable-input.span11 { - width: 1056px; - } - input.span10, - textarea.span10, - .uneditable-input.span10 { - width: 956px; - } - input.span9, - textarea.span9, - .uneditable-input.span9 { - width: 856px; - } - input.span8, - textarea.span8, - .uneditable-input.span8 { - width: 756px; - } - input.span7, - textarea.span7, - .uneditable-input.span7 { - width: 656px; - } - input.span6, - textarea.span6, - .uneditable-input.span6 { - width: 556px; - } - input.span5, - textarea.span5, - .uneditable-input.span5 { - width: 456px; - } - input.span4, - textarea.span4, - .uneditable-input.span4 { - width: 356px; - } - input.span3, - textarea.span3, - .uneditable-input.span3 { - width: 256px; - } - input.span2, - textarea.span2, - .uneditable-input.span2 { - width: 156px; - } - input.span1, - textarea.span1, - .uneditable-input.span1 { - width: 56px; - } - .thumbnails { - margin-left: -30px; - } - .thumbnails > li { - margin-left: 30px; - } - .row-fluid .thumbnails { - margin-left: 0; - } -} -@media (max-width: 767px) { - body { - padding-top: 0; - } - .navbar-fixed-top, - .navbar-fixed-bottom { - position: static; - } - .navbar-fixed-top { - margin-bottom: 18px; - } - .navbar-fixed-bottom { - margin-top: 18px; - } - .navbar-fixed-top .navbar-inner, - .navbar-fixed-bottom .navbar-inner { - padding: 5px; - } - .navbar .container { - width: auto; - padding: 0; - } - .navbar .brand { - padding-left: 10px; - padding-right: 10px; - margin: 0 0 0 -5px; - } - .nav-collapse { - clear: both; - } - .nav-collapse .nav { - float: none; - margin: 0 0 9px; - } - .nav-collapse .nav > li { - float: none; - } - .nav-collapse .nav > li > a { - margin-bottom: 2px; - } - .nav-collapse .nav > .divider-vertical { - display: none; - } - .nav-collapse .nav .nav-header { - color: #555; - text-shadow: none; - } - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - padding: 9px 15px; - font-weight: bold; - color: #555; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - } - .nav-collapse .btn { - padding: 4px 10px 4px; - font-weight: normal; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - } - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 2px; - } - .nav-collapse .nav > li > a:hover, - .nav-collapse .nav > li > a:focus, - .nav-collapse .dropdown-menu a:hover, - .nav-collapse .dropdown-menu a:focus { - background-color: #f2f2f2; - } - .navbar-inverse .nav-collapse .nav > li > a, - .navbar-inverse .nav-collapse .dropdown-menu a { - color: #d9d9d9; - } - .navbar-inverse .nav-collapse .nav > li > a:hover, - .navbar-inverse .nav-collapse .nav > li > a:focus, - .navbar-inverse .nav-collapse .dropdown-menu a:hover, - .navbar-inverse .nav-collapse .dropdown-menu a:focus { - background-color: #10223e; - } - .nav-collapse.in .btn-group { - margin-top: 5px; - padding: 0; - } - .nav-collapse .dropdown-menu { - position: static; - top: auto; - left: auto; - float: none; - display: none; - max-width: none; - margin: 0 15px; - padding: 0; - background-color: transparent; - border: none; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } - .nav-collapse .open > .dropdown-menu { - display: block; - } - .nav-collapse .dropdown-menu:before, - .nav-collapse .dropdown-menu:after { - display: none; - } - .nav-collapse .dropdown-menu .divider { - display: none; - } - .nav-collapse .nav > li > .dropdown-menu:before, - .nav-collapse .nav > li > .dropdown-menu:after { - display: none; - } - .nav-collapse .navbar-form, - .nav-collapse .navbar-search { - float: none; - padding: 9px 15px; - margin: 9px 0; - border-top: 1px solid #f2f2f2; - border-bottom: 1px solid #f2f2f2; - -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); - } - .navbar-inverse .nav-collapse .navbar-form, - .navbar-inverse .nav-collapse .navbar-search { - border-top-color: #10223e; - border-bottom-color: #10223e; - } - .navbar .nav-collapse .nav.pull-right { - float: none; - margin-left: 0; - } - .nav-collapse, - .nav-collapse.collapse { - overflow: hidden; - height: 0; - } - .navbar .btn-navbar { - display: block; - } - .navbar-static .navbar-inner { - padding-left: 10px; - padding-right: 10px; - } -} -@media (min-width: 768px) { - .nav-collapse.collapse { - height: auto !important; - overflow: visible !important; - } -} -.small { - font-size: 11px; -} -iframe, -svg { - max-width: 100%; -} -.nowrap { - white-space: nowrap; -} -.center, -.table td.center, -.table th.center { - text-align: center; -} -a.disabled, -a.disabled:hover { - color: #999999; - background-color: transparent; - cursor: default; - text-decoration: none; -} -.hero-unit { - text-align: center; -} -.hero-unit .lead { - margin-bottom: 18px; - font-size: 20px; - font-weight: 200; - line-height: 27px; -} -.btn .caret { - margin-bottom: 7px; -} -.btn.btn-micro .caret { - margin: 5px 0; -} -.blog-row-rule, -.blog-item-rule { - border: 0; -} -body.modal { - padding-top: 0; -} -.row-even, -.row-odd { - padding: 5px; - width: 99%; - border-bottom: 1px solid #ddd; -} -.row-odd { - background-color: transparent; -} -.row-even { - background-color: #f9f9f9; -} -.blog-row-rule, -.blog-item-rule { - border: 0; -} -.row-fluid .row-reveal { - visibility: hidden; -} -.row-fluid:hover .row-reveal { - visibility: visible; -} -.btn-wide { - width: 80%; -} -.nav-list > li.offset > a { - padding-left: 30px; - font-size: 12px; -} -.blog-row-rule, -.blog-item-rule { - border: 0; -} -.row-fluid .offset1 { - margin-left: 8.382978723%; -} -.row-fluid .offset2 { - margin-left: 16.89361702%; -} -.row-fluid .offset3 { - margin-left: 25.404255317%; -} -.row-fluid .offset4 { - margin-left: 33.914893614%; -} -.row-fluid .offset5 { - margin-left: 42.425531911%; -} -.row-fluid .offset6 { - margin-left: 50.93617020799999%; -} -.row-fluid .offset7 { - margin-left: 59.446808505%; -} -.row-fluid .offset8 { - margin-left: 67.95744680199999%; -} -.row-fluid .offset9 { - margin-left: 76.468085099%; -} -.row-fluid .offset10 { - margin-left: 84.97872339599999%; -} -.row-fluid .offset11 { - margin-left: 91.489361693%; -} -.navbar .nav > li > a.btn { - padding: 4px 10px; - line-height: 18px; -} -.nav-tabs.nav-dark { - border-bottom: 1px solid #333; - text-shadow: 1px 1px 1px #000; -} -.nav-tabs.nav-dark > li > a { - color: #F8F8F8; -} -.nav-tabs.nav-dark > li > a:hover { - border-color: #333 #333 #111; - background-color: #777777; -} -.nav-tabs.nav-dark > .active > a, -.nav-tabs.nav-dark > .active > a:hover { - color: #ffffff; - background-color: #555555; - border: 1px solid #222; - border-bottom-color: transparent; -} -.thumbnail.pull-left { - margin: 0 10px 10px 0; -} -.thumbnail.pull-right { - margin: 0 0 10px 10px; -} -.width-10 { - width: 10px; -} -.width-20 { - width: 20px; -} -.width-30 { - width: 30px; -} -.width-40 { - width: 40px; -} -.width-50 { - width: 50px; -} -.width-60 { - width: 60px; -} -.width-70 { - width: 70px; -} -.width-80 { - width: 80px; -} -.width-90 { - width: 90px; -} -.width-100 { - width: 100px; -} -.height-10 { - height: 10px; -} -.height-20 { - height: 20px; -} -.height-30 { - height: 30px; -} -.height-40 { - height: 40px; -} -.height-50 { - height: 50px; -} -.height-60 { - height: 60px; -} -.height-70 { - height: 70px; -} -.height-80 { - height: 80px; -} -.height-90 { - height: 90px; -} -.height-100 { - height: 100px; -} -hr.hr-condensed { - margin: 10px 0; -} -.list-striped, -.row-striped { - list-style: none; - line-height: 18px; - text-align: left; - vertical-align: middle; - border-top: 1px solid #ddd; - margin-left: 0; -} -.list-striped li, -.list-striped dd, -.row-striped .row, -.row-striped .row-fluid { - border-bottom: 1px solid #ddd; - padding: 8px; -} -.list-striped li:nth-child(odd), -.list-striped dd:nth-child(odd), -.row-striped .row:nth-child(odd), -.row-striped .row-fluid:nth-child(odd) { - background-color: #f9f9f9; -} -.list-striped li:hover, -.list-striped dd:hover, -.row-striped .row:hover, -.row-striped .row-fluid:hover { - background-color: #F0F0F0; -} -.row-striped .row-fluid { - width: 100%; - box-sizing: border-box; -} -.row-striped .row-fluid [class*="span"] { - min-height: 10px; -} -.row-striped .row-fluid [class*="span"] { - margin-left: 8px; -} -.row-striped .row-fluid [class*="span"]:first-child { - margin-left: 0; -} -.list-condensed li { - padding: 4px 5px; -} -.row-condensed .row, -.row-condensed .row-fluid { - padding: 4px 5px; -} -.list-bordered, -.row-bordered { - list-style: none; - line-height: 18px; - text-align: left; - vertical-align: middle; - margin-left: 0; - border: 1px solid #ddd; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -.radio.btn-group input[type=radio] { - display: none; -} -.radio.btn-group > label { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.radio.btn-group > label:first-of-type { - margin-left: 0; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - -moz-border-radius-topleft: 4px; -} -fieldset.radio.btn-group { - padding-left: 0; -} -.iframe-bordered { - border: 1px solid #ddd; -} -.tab-content { - overflow: visible; -} -.tabs-left .tab-content { - overflow: auto; -} -.nav-tabs > li > span { - display: block; - margin-right: 2px; - padding-right: 12px; - padding-left: 12px; - padding-top: 8px; - padding-bottom: 8px; - line-height: 18px; - border: 1px solid transparent; - -webkit-border-radius: 4px 4px 0 0; - -moz-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} -.btn-micro { - padding: 1px 4px; - font-size: 10px; - line-height: 8px; -} -.btn-group > .btn-micro { - font-size: 10px; -} -.tip-wrap { - max-width: 200px; - padding: 3px 8px; - color: #fff; - text-align: center; - text-decoration: none; - background-color: #000; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - z-index: 100; -} -.page-header { - margin: 2px 0px 10px 0px; - padding-bottom: 5px; -} -.input-prepend > .add-on, -.input-append > .add-on { - vertical-align: top; -} -.input-prepend .chzn-container-single .chzn-single { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.input-prepend .chzn-container-single .chzn-single-with-drop { - -webkit-border-radius: 0 3px 0 0; - -moz-border-radius: 0 3px 0 0; - border-radius: 0 3px 0 0; -} -.input-append .chzn-container-single .chzn-single { - -webkit-border-radius: 3px 0 0 3px; - -moz-border-radius: 3px 0 0 3px; - border-radius: 3px 0 0 3px; -} -.input-append .chzn-container-single .chzn-single-with-drop { - -webkit-border-radius: 3px 0 0 0; - -moz-border-radius: 3px 0 0 0; - border-radius: 3px 0 0 0; -} -.input-prepend.input-append .chzn-container-single .chzn-single, -.input-prepend.input-append .chzn-container-single .chzn-single-with-drop { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; -} -.element-invisible { - position: absolute; - padding: 0; - margin: 0; - border: 0; - height: 1px; - width: 1px; - overflow: hidden; -} -.element-invisible:focus { - width: auto; - height: auto; - overflow: auto; - background: #eee; - color: #000; - padding: 1em; -} -.form-vertical .control-label { - float: none; - width: auto; - padding-right: 0; - padding-top: 0; - text-align: left; -} -.form-vertical .controls { - margin-left: 0; -} -.width-auto { - width: auto; -} -.btn-group .chzn-results { - white-space: normal; -} -.accordion-body.in:hover { - overflow: visible; -} -.invalid { - color: #9d261d; - font-weight: bold; -} -input.invalid { - border: 1px solid #9d261d; - background: #f2dede; -} -select.chzn-done.invalid + .chzn-container.chzn-container-single > a.chzn-single, -select.chzn-done.invalid + .chzn-container.chzn-container-multi > ul.chzn-choices { - border-color: #9d261d; - color: #9d261d; -} -.tooltip { - max-width: 400px; -} -.tooltip-inner { - max-width: none; - text-align: left; - text-shadow: none; -} -th .tooltip-inner { - font-weight: normal; -} -.tooltip.hasimage { - opacity: 1; -} -.tip-text { - text-align: left; -} -.btn-group > .btn + .dropdown-backdrop + .btn { - margin-left: -1px; -} -.btn-group > .btn + .dropdown-backdrop + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; - -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - box-shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); - *padding-top: 5px; - *padding-bottom: 5px; -} -.btn-group > .btn-mini + .dropdown-backdrop + .dropdown-toggle { - padding-left: 5px; - padding-right: 5px; - *padding-top: 2px; - *padding-bottom: 2px; -} -.btn-group > .btn-small + .dropdown-backdrop + .dropdown-toggle { - *padding-top: 5px; - *padding-bottom: 4px; -} -.btn-group > .btn-large + .dropdown-backdrop + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; - *padding-top: 7px; - *padding-bottom: 7px; -} -.dropdown-menu { - text-align: left; -} -.alert-link { - font-weight: bold; -} -.alert .alert-link { - color: #66512c; -} -.alert-success .alert-link { - color: #2b542c; -} -.alert-danger .alert-link, -.alert-error .alert-link { - color: #843534; -} -.alert-info .alert-link { - color: #245269; -} -div.modal { - position: fixed; - top: 5%; - left: 50%; - z-index: 1050; - width: 80%; - margin-left: -40%; - background-color: #fff; - border: 1px solid #999; - border: 1px solid rgba(0,0,0,0.3); - *border: 1px solid #999; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - -webkit-box-shadow: 0 3px 7px rgba(0,0,0,0.3); - -moz-box-shadow: 0 3px 7px rgba(0,0,0,0.3); - box-shadow: 0 3px 7px rgba(0,0,0,0.3); - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; - outline: none; -} -div.modal.fade { - -webkit-transition: opacity .3s linear, top .3s ease-out; - -moz-transition: opacity .3s linear, top .3s ease-out; - -o-transition: opacity .3s linear, top .3s ease-out; - transition: opacity .3s linear, top .3s ease-out; - top: -25%; -} -div.modal.fade.in { - top: 5%; -} -.modal-batch { - overflow-y: visible; -} -.modal-body[class^="jviewport-height"], -.modal-body[class*="jviewport-height"] { - max-height: none; -} -.jviewport-height10 { - height: 10vh; -} -.jviewport-height20 { - height: 20vh; -} -.jviewport-height30 { - height: 30vh; -} -.jviewport-height40 { - height: 40vh; -} -.jviewport-height50 { - height: 50vh; -} -.jviewport-height60 { - height: 60vh; -} -.jviewport-height70 { - height: 70vh; -} -.jviewport-height80 { - height: 80vh; -} -.jviewport-height90 { - height: 90vh; -} -.jviewport-height100 { - height: 100vh; -} -div.modal.jviewport-width10 { - width: 10vw; - margin-left: -5vw; -} -div.modal.jviewport-width20 { - width: 20vw; - margin-left: -10vw; -} -div.modal.jviewport-width30 { - width: 30vw; - margin-left: -15vw; -} -div.modal.jviewport-width40 { - width: 40vw; - margin-left: -20vw; -} -div.modal.jviewport-width50 { - width: 50vw; - margin-left: -25vw; -} -div.modal.jviewport-width60 { - width: 60vw; - margin-left: -30vw; -} -div.modal.jviewport-width70 { - width: 70vw; - margin-left: -35vw; -} -div.modal.jviewport-width80 { - width: 80vw; - margin-left: -40vw; -} -div.modal.jviewport-width90 { - width: 90vw; - margin-left: -45vw; -} -div.modal.jviewport-width100 { - width: 100vw; - margin-left: -50vw; -} -@media (max-width: 767px) { - div.modal { - position: fixed; - top: 20px; - left: 20px; - right: 20px; - width: auto; - margin: 0; - } - div.modal.fade { - top: -100px; - } - div.modal.fade.in { - top: 20px; - } - div.modal[class*="jviewport-width"] { - width: auto; - margin: 0; - } -} -@media (max-width: 480px) { - div.modal { - top: 10px; - left: 10px; - right: 10px; - } -} -@font-face { - font-family: 'IcoMoon'; - src: url('../../../../media/jui/fonts/IcoMoon.eot'); - src: url('../../../../media/jui/fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), url('../../../../media/jui/fonts/IcoMoon.woff') format('woff'), url('../../../../media/jui/fonts/IcoMoon.ttf') format('truetype'), url('../../../../media/jui/fonts/IcoMoon.svg#IcoMoon') format('svg'); - font-weight: normal; - font-style: normal; -} -[data-icon]:before { - font-family: 'IcoMoon'; - content: attr(data-icon); - speak: none; -} -[class^="icon-"], -[class*=" icon-"] { - display: inline-block; - width: 14px; - height: 14px; - margin-right: .25em; - line-height: 14px; -} -[class^="icon-"]:before, -[class*=" icon-"]:before { - font-family: 'IcoMoon'; - font-style: normal; - speak: none; -} -[class^="icon-"].disabled, -[class*=" icon-"].disabled { - font-weight: normal; -} -.icon-joomla:before { - content: "\e200"; -} -.icon-chevron-up:before, -.icon-uparrow:before, -.icon-arrow-up:before { - content: "\e005"; -} -.icon-chevron-right:before, -.icon-rightarrow:before, -.icon-arrow-right:before { - content: "\e006"; -} -.icon-chevron-down:before, -.icon-downarrow:before, -.icon-arrow-down:before { - content: "\e007"; -} -.icon-chevron-left:before, -.icon-leftarrow:before, -.icon-arrow-left:before { - content: "\e008"; -} -.icon-arrow-first:before { - content: "\e003"; -} -.icon-arrow-last:before { - content: "\e004"; -} -.icon-arrow-up-2:before { - content: "\e009"; -} -.icon-arrow-right-2:before { - content: "\e00a"; -} -.icon-arrow-down-2:before { - content: "\e00b"; -} -.icon-arrow-left-2:before { - content: "\e00c"; -} -.icon-arrow-up-3:before { - content: "\e00f"; -} -.icon-arrow-right-3:before { - content: "\e010"; -} -.icon-arrow-down-3:before { - content: "\e011"; -} -.icon-arrow-left-3:before { - content: "\e012"; -} -.icon-menu-2:before { - content: "\e00e"; -} -.icon-arrow-up-4:before { - content: "\e201"; -} -.icon-arrow-right-4:before { - content: "\e202"; -} -.icon-arrow-down-4:before { - content: "\e203"; -} -.icon-arrow-left-4:before { - content: "\e204"; -} -.icon-share:before, -.icon-redo:before { - content: "\27"; -} -.icon-undo:before { - content: "\28"; -} -.icon-forward-2:before { - content: "\e205"; -} -.icon-backward-2:before, -.icon-reply:before { - content: "\e206"; -} -.icon-unblock:before, -.icon-refresh:before, -.icon-redo-2:before { - content: "\6c"; -} -.icon-undo-2:before { - content: "\e207"; -} -.icon-move:before { - content: "\7a"; -} -.icon-expand:before { - content: "\66"; -} -.icon-contract:before { - content: "\67"; -} -.icon-expand-2:before { - content: "\68"; -} -.icon-contract-2:before { - content: "\69"; -} -.icon-play:before { - content: "\e208"; -} -.icon-pause:before { - content: "\e209"; -} -.icon-stop:before { - content: "\e210"; -} -.icon-previous:before, -.icon-backward:before { - content: "\7c"; -} -.icon-next:before, -.icon-forward:before { - content: "\7b"; -} -.icon-first:before { - content: "\7d"; -} -.icon-last:before { - content: "\e000"; -} -.icon-play-circle:before { - content: "\e00d"; -} -.icon-pause-circle:before { - content: "\e211"; -} -.icon-stop-circle:before { - content: "\e212"; -} -.icon-backward-circle:before { - content: "\e213"; -} -.icon-forward-circle:before { - content: "\e214"; -} -.icon-loop:before { - content: "\e001"; -} -.icon-shuffle:before { - content: "\e002"; -} -.icon-search:before { - content: "\53"; -} -.icon-zoom-in:before { - content: "\64"; -} -.icon-zoom-out:before { - content: "\65"; -} -.icon-apply:before, -.icon-edit:before, -.icon-pencil:before { - content: "\2b"; -} -.icon-pencil-2:before { - content: "\2c"; -} -.icon-brush:before { - content: "\3b"; -} -.icon-save-new:before, -.icon-plus-2:before { - content: "\5d"; -} -.icon-minus-sign:before, -.icon-minus-2:before { - content: "\5e"; -} -.icon-delete:before, -.icon-remove:before, -.icon-cancel-2:before { - content: "\49"; -} -.icon-publish:before, -.icon-save:before, -.icon-ok:before, -.icon-checkmark:before { - content: "\47"; -} -.icon-new:before, -.icon-plus:before { - content: "\2a"; -} -.icon-plus-circle:before { - content: "\e215"; -} -.icon-minus:before, -.icon-not-ok:before { - content: "\4b"; -} -.icon-ban-circle:before, -.icon-minus-circle:before { - content: "\e216"; -} -.icon-unpublish:before, -.icon-cancel:before { - content: "\4a"; -} -.icon-cancel-circle:before { - content: "\e217"; -} -.icon-checkmark-2:before { - content: "\e218"; -} -.icon-checkmark-circle:before { - content: "\e219"; -} -.icon-info:before { - content: "\e220"; -} -.icon-info-2:before, -.icon-info-circle:before { - content: "\e221"; -} -.icon-question:before, -.icon-question-sign:before, -.icon-help:before { - content: "\45"; -} -.icon-question-2:before, -.icon-question-circle:before { - content: "\e222"; -} -.icon-notification:before { - content: "\e223"; -} -.icon-notification-2:before, -.icon-notification-circle:before { - content: "\e224"; -} -.icon-pending:before, -.icon-warning:before { - content: "\48"; -} -.icon-warning-2:before, -.icon-warning-circle:before { - content: "\e225"; -} -.icon-checkbox-unchecked:before { - content: "\3d"; -} -.icon-checkin:before, -.icon-checkbox:before, -.icon-checkbox-checked:before { - content: "\3e"; -} -.icon-checkbox-partial:before { - content: "\3f"; -} -.icon-square:before { - content: "\e226"; -} -.icon-radio-unchecked:before { - content: "\e227"; -} -.icon-radio-checked:before, -.icon-generic:before { - content: "\e228"; -} -.icon-circle:before { - content: "\e229"; -} -.icon-signup:before { - content: "\e230"; -} -.icon-grid:before, -.icon-grid-view:before { - content: "\58"; -} -.icon-grid-2:before, -.icon-grid-view-2:before { - content: "\59"; -} -.icon-menu:before { - content: "\5a"; -} -.icon-list:before, -.icon-list-view:before { - content: "\31"; -} -.icon-list-2:before { - content: "\e231"; -} -.icon-menu-3:before { - content: "\e232"; -} -.icon-folder-open:before, -.icon-folder:before { - content: "\2d"; -} -.icon-folder-close:before, -.icon-folder-2:before { - content: "\2e"; -} -.icon-folder-plus:before { - content: "\e234"; -} -.icon-folder-minus:before { - content: "\e235"; -} -.icon-folder-3:before { - content: "\e236"; -} -.icon-folder-plus-2:before { - content: "\e237"; -} -.icon-folder-remove:before { - content: "\e238"; -} -.icon-file:before { - content: "\e016"; -} -.icon-file-2:before { - content: "\e239"; -} -.icon-file-add:before, -.icon-file-plus:before { - content: "\29"; -} -.icon-file-minus:before { - content: "\e017"; -} -.icon-file-check:before { - content: "\e240"; -} -.icon-file-remove:before { - content: "\e241"; -} -.icon-save-copy:before, -.icon-copy:before { - content: "\e018"; -} -.icon-stack:before { - content: "\e242"; -} -.icon-tree:before { - content: "\e243"; -} -.icon-tree-2:before { - content: "\e244"; -} -.icon-paragraph-left:before { - content: "\e246"; -} -.icon-paragraph-center:before { - content: "\e247"; -} -.icon-paragraph-right:before { - content: "\e248"; -} -.icon-paragraph-justify:before { - content: "\e249"; -} -.icon-screen:before { - content: "\e01c"; -} -.icon-tablet:before { - content: "\e01d"; -} -.icon-mobile:before { - content: "\e01e"; -} -.icon-box-add:before { - content: "\51"; -} -.icon-box-remove:before { - content: "\52"; -} -.icon-download:before { - content: "\e021"; -} -.icon-upload:before { - content: "\e022"; -} -.icon-home:before { - content: "\21"; -} -.icon-home-2:before { - content: "\e250"; -} -.icon-out-2:before, -.icon-new-tab:before { - content: "\e024"; -} -.icon-out-3:before, -.icon-new-tab-2:before { - content: "\e251"; -} -.icon-link:before { - content: "\e252"; -} -.icon-picture:before, -.icon-image:before { - content: "\2f"; -} -.icon-pictures:before, -.icon-images:before { - content: "\30"; -} -.icon-palette:before, -.icon-color-palette:before { - content: "\e014"; -} -.icon-camera:before { - content: "\55"; -} -.icon-camera-2:before, -.icon-video:before { - content: "\e015"; -} -.icon-play-2:before, -.icon-video-2:before, -.icon-youtube:before { - content: "\56"; -} -.icon-music:before { - content: "\57"; -} -.icon-user:before { - content: "\22"; -} -.icon-users:before { - content: "\e01f"; -} -.icon-vcard:before { - content: "\6d"; -} -.icon-address:before { - content: "\70"; -} -.icon-share-alt:before, -.icon-out:before { - content: "\26"; -} -.icon-enter:before { - content: "\e257"; -} -.icon-exit:before { - content: "\e258"; -} -.icon-comment:before, -.icon-comments:before { - content: "\24"; -} -.icon-comments-2:before { - content: "\25"; -} -.icon-quote:before, -.icon-quotes-left:before { - content: "\60"; -} -.icon-quote-2:before, -.icon-quotes-right:before { - content: "\61"; -} -.icon-quote-3:before, -.icon-bubble-quote:before { - content: "\e259"; -} -.icon-phone:before { - content: "\e260"; -} -.icon-phone-2:before { - content: "\e261"; -} -.icon-envelope:before, -.icon-mail:before { - content: "\4d"; -} -.icon-envelope-opened:before, -.icon-mail-2:before { - content: "\4e"; -} -.icon-unarchive:before, -.icon-drawer:before { - content: "\4f"; -} -.icon-archive:before, -.icon-drawer-2:before { - content: "\50"; -} -.icon-briefcase:before { - content: "\e020"; -} -.icon-tag:before { - content: "\e262"; -} -.icon-tag-2:before { - content: "\e263"; -} -.icon-tags:before { - content: "\e264"; -} -.icon-tags-2:before { - content: "\e265"; -} -.icon-options:before, -.icon-cog:before { - content: "\38"; -} -.icon-cogs:before { - content: "\37"; -} -.icon-screwdriver:before, -.icon-tools:before { - content: "\36"; -} -.icon-wrench:before { - content: "\3a"; -} -.icon-equalizer:before { - content: "\39"; -} -.icon-dashboard:before { - content: "\78"; -} -.icon-switch:before { - content: "\e266"; -} -.icon-filter:before { - content: "\54"; -} -.icon-purge:before, -.icon-trash:before { - content: "\4c"; -} -.icon-checkedout:before, -.icon-lock:before, -.icon-locked:before { - content: "\23"; -} -.icon-unlock:before { - content: "\e267"; -} -.icon-key:before { - content: "\5f"; -} -.icon-support:before { - content: "\46"; -} -.icon-database:before { - content: "\62"; -} -.icon-scissors:before { - content: "\e268"; -} -.icon-health:before { - content: "\6a"; -} -.icon-wand:before { - content: "\6b"; -} -.icon-eye-open:before, -.icon-eye:before { - content: "\3c"; -} -.icon-eye-close:before, -.icon-eye-blocked:before, -.icon-eye-2:before { - content: "\e269"; -} -.icon-clock:before { - content: "\6e"; -} -.icon-compass:before { - content: "\6f"; -} -.icon-broadcast:before, -.icon-connection:before, -.icon-wifi:before { - content: "\e01b"; -} -.icon-book:before { - content: "\e271"; -} -.icon-lightning:before, -.icon-flash:before { - content: "\79"; -} -.icon-print:before, -.icon-printer:before { - content: "\e013"; -} -.icon-feed:before { - content: "\71"; -} -.icon-calendar:before { - content: "\43"; -} -.icon-calendar-2:before { - content: "\44"; -} -.icon-calendar-3:before { - content: "\e273"; -} -.icon-pie:before { - content: "\77"; -} -.icon-bars:before { - content: "\76"; -} -.icon-chart:before { - content: "\75"; -} -.icon-power-cord:before { - content: "\32"; -} -.icon-cube:before { - content: "\33"; -} -.icon-puzzle:before { - content: "\34"; -} -.icon-attachment:before, -.icon-paperclip:before, -.icon-flag-2:before { - content: "\72"; -} -.icon-lamp:before { - content: "\74"; -} -.icon-pin:before, -.icon-pushpin:before { - content: "\73"; -} -.icon-location:before { - content: "\63"; -} -.icon-shield:before { - content: "\e274"; -} -.icon-flag:before { - content: "\35"; -} -.icon-flag-3:before { - content: "\e275"; -} -.icon-bookmark:before { - content: "\e023"; -} -.icon-bookmark-2:before { - content: "\e276"; -} -.icon-heart:before { - content: "\e277"; -} -.icon-heart-2:before { - content: "\e278"; -} -.icon-thumbs-up:before { - content: "\5b"; -} -.icon-thumbs-down:before { - content: "\5c"; -} -.icon-unfeatured:before, -.icon-asterisk:before, -.icon-star-empty:before { - content: "\40"; -} -.icon-star-2:before { - content: "\41"; -} -.icon-featured:before, -.icon-default:before, -.icon-star:before { - content: "\42"; -} -.icon-smiley:before, -.icon-smiley-happy:before { - content: "\e279"; -} -.icon-smiley-2:before, -.icon-smiley-happy-2:before { - content: "\e280"; -} -.icon-smiley-sad:before { - content: "\e281"; -} -.icon-smiley-sad-2:before { - content: "\e282"; -} -.icon-smiley-neutral:before { - content: "\e283"; -} -.icon-smiley-neutral-2:before { - content: "\e284"; -} -.icon-cart:before { - content: "\e019"; -} -.icon-basket:before { - content: "\e01a"; -} -.icon-credit:before { - content: "\e286"; -} -.icon-credit-2:before { - content: "\e287"; -} -.icon-expired:before { - content: "\4b"; -} -.icon-edit:before { - color: #24748c; -} -.icon-publish:before, -.icon-save:before, -.icon-ok:before, -.icon-save-new:before, -.icon-save-copy:before, -.btn-toolbar .icon-copy:before { - color: #378137; -} -.icon-unpublish:before, -.icon-not-ok:before, -.icon-eye-close:before, -.icon-ban-circle:before, -.icon-minus-sign:before, -.btn-toolbar .icon-cancel:before { - color: #942a25; -} -.icon-featured:before, -.icon-default:before, -.icon-expired:before, -.icon-pending:before { - color: #c67605; -} -.icon-back:before { - content: "\e008"; -} -html { - height: 100%; -} -body { - height: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - box-sizing: border-box; -} -a:hover, -a:active, -a:focus { - outline: none; -} -.small { - font-size: 11px; -} -.row-even .small, -.row-odd .small, -.row-even .small a, -.row-odd .small a { - color: #888; -} -.content-title { - font-size: 24px; - font-weight: normal; - line-height: 26px; - margin-top: 0; -} -.well .page-header { - margin: -10px 0 18px 0; - padding-bottom: 5px; -} -.well .module-title.nav-header { - padding: 0 0 7px; - margin: 0; - font-size: 13px; -} -.well .row-even p, -.well .row-odd p { - margin-bottom: 0; -} -h1, -h2, -h3, -h4, -h5, -h6 { - margin: 12px 0; -} -h1 { - font-size: 26px; - line-height: 28px; -} -h2 { - font-size: 22px; - line-height: 24px; -} -h3 { - font-size: 18px; - line-height: 20px; -} -h4 { - font-size: 14px; - line-height: 16px; -} -h5 { - font-size: 13px; - line-height: 15px; -} -h6 { - font-size: 12px; - line-height: 14px; -} -.truncate { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.chzn-container .chzn-drop { - border-radius: 0 0 3px 3px; -} -.control-group .chzn-container { - max-width: 100%; -} -.control-group .chzn-container .chzn-choices li.search-field, -.control-group .chzn-container .chzn-choices li.search-field input { - width: 100% !important; -} -.chzn-container-single .chzn-single { - background-color: #fff; - background-clip: inherit; - background-image: none; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,0.2); - border-radius: 3px; - box-shadow: 0 1px 0 rgba(255,255,255,0.2) inset, 0 1px 2px rgba(0,0,0,0.05); - height: auto; - line-height: 26px; -} -.chzn-container-single .chzn-single div { - background-color: #f3f3f3; - border-left: 1px solid #ccc; - bottom: 0; - height: auto; - text-align: center; - width: 28px; -} -.chzn-container-single .chzn-single div b { - background-image: none; - display: inline-block; -} -.chzn-container-single .chzn-single div b:after { - content: '\E011'; - font-family: IcoMoon; -} -.chzn-container-single .chzn-single abbr { - background: none; - right: 36px; - top: 0; -} -.chzn-container-single .chzn-single abbr:before { - font-family: IcoMoon; - content: '\0049'; - font-size: 10px; - line-height: 26px; -} -.chzn-container-single .chzn-single abbr:hover { - color: #000; -} -.chzn-container-single .chzn-search:after { - content: '\0053'; - font-family: IcoMoon; - position: relative; - right: 20px; - top: 2px; -} -.chzn-container-single .chzn-search input[type="text"] { - background: none; - border-radius: 3px; - border: 1px solid #ccc; - box-shadow: none; - height: 25px; -} -.chzn-container-single .chzn-search input[type="text"]:focus { - border-color: #3071A9; -} -.chzn-container-single .chzn-drop { - background-clip: padding-box; - border-color: #3071A9; - border-radius: 0 0 3px 3px; -} -.chzn-container-active .chzn-single { - color: #3071A9; -} -.chzn-container-active.chzn-with-drop .chzn-single { - background-image: none; - border: 1px solid #3071A9; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} -.chzn-container-active.chzn-with-drop .chzn-single div { - background-color: #f3f3f3; - border-bottom: 1px solid #ccc; - border-bottom-left-radius: 3px; - border-left: 1px solid #ccc; -} -.chzn-container-active.chzn-with-drop .chzn-single div b:after { - content: '\E00F'; - font-family: IcoMoon; -} -.chzn-container-active.chzn-container-multi .chzn-choices { - border: 1px solid #3071A9; - box-shadow: none; -} -.chzn-container .chzn-results { - background-color: #fff; - border-radius: 0 0 3px 3px; - margin: 0; - padding: 0; -} -.chzn-container .chzn-results li.highlighted { - background-color: #3071A9; - background-image: none; -} -.chzn-color[rel="value_"] div { - background-color: #f3f3f3; - border-left: 1px solid #ccc; -} -.chzn-color-state.chzn-single div, -.chzn-color.chzn-single[rel="value_0"] div, -.chzn-color.chzn-single[rel="value_1"] div, -.chzn-color-state.chzn-single[rel="value_-1"] div, -.chzn-color-state.chzn-single[rel="value_-2"] div, -.chzn-color.chzn-single[rel="value_hide"] div, -.chzn-color.chzn-single[rel="value_show_no_link"] div, -.chzn-color.chzn-single[rel="value_show_with_link"] div { - background-color: transparent !important; - border: none !important; -} -.chzn-container-active .chzn-choices { - border: 1px solid #3071A9; -} -.chzn-container-multi .chzn-choices { - background-image: none; - border-radius: 3px; - border: 1px solid #ccc; -} -.chzn-container-multi .chzn-choices li.search-choice { - background-color: #3071A9; - background-image: none; - border: 0; - box-shadow: none; - color: #fff; - line-height: 20px; - padding: 0 7px; -} -.chzn-container-multi .chzn-choices li.search-choice .search-choice-close { - color: #f5f5f5; - display: inline-block; - margin-left: 5px; - position: relative; - top: 0; - left: 0; - background-image: none; - font-size: inherit; -} -.chzn-container-multi .chzn-choices li.search-choice .search-choice-close:hover { - text-decoration: none; -} -.chzn-container-multi .chzn-choices li.search-choice .search-choice-close:before { - font-family: IcoMoon; - content: '\004A'; - position: relative; - right: 1px; - top: 0; -} -.js-stools .js-stools-container-bar .js-stools-field-filter .chzn-container { - margin: 1px 0; - padding: 0 !important; -} -.chzn-color.chzn-single[rel="value_1"], -.chzn-color-reverse.chzn-single[rel="value_0"], -.chzn-color-state.chzn-single[rel="value_1"], -.chzn-color.chzn-single[rel="value_show_no_link"], -.chzn-color.chzn-single[rel="value_show_with_link"] { - background-color: #46a546; - *background-color: #46a546; - box-shadow: 0 1px 2px rgba(0,0,0,0.05); - color: #ffffff; -} -.chzn-color.chzn-single[rel="value_1"]:hover, -.chzn-color.chzn-single[rel="value_1"]:focus, -.chzn-color.chzn-single[rel="value_1"]:active, -.chzn-color.chzn-single[rel="value_1"].active, -.chzn-color.chzn-single[rel="value_1"].disabled, -.chzn-color.chzn-single[rel="value_1"][disabled], -.chzn-color-reverse.chzn-single[rel="value_0"]:hover, -.chzn-color-reverse.chzn-single[rel="value_0"]:focus, -.chzn-color-reverse.chzn-single[rel="value_0"]:active, -.chzn-color-reverse.chzn-single[rel="value_0"].active, -.chzn-color-reverse.chzn-single[rel="value_0"].disabled, -.chzn-color-reverse.chzn-single[rel="value_0"][disabled], -.chzn-color-state.chzn-single[rel="value_1"]:hover, -.chzn-color-state.chzn-single[rel="value_1"]:focus, -.chzn-color-state.chzn-single[rel="value_1"]:active, -.chzn-color-state.chzn-single[rel="value_1"].active, -.chzn-color-state.chzn-single[rel="value_1"].disabled, -.chzn-color-state.chzn-single[rel="value_1"][disabled], -.chzn-color.chzn-single[rel="value_show_no_link"]:hover, -.chzn-color.chzn-single[rel="value_show_no_link"]:focus, -.chzn-color.chzn-single[rel="value_show_no_link"]:active, -.chzn-color.chzn-single[rel="value_show_no_link"].active, -.chzn-color.chzn-single[rel="value_show_no_link"].disabled, -.chzn-color.chzn-single[rel="value_show_no_link"][disabled], -.chzn-color.chzn-single[rel="value_show_with_link"]:hover, -.chzn-color.chzn-single[rel="value_show_with_link"]:focus, -.chzn-color.chzn-single[rel="value_show_with_link"]:active, -.chzn-color.chzn-single[rel="value_show_with_link"].active, -.chzn-color.chzn-single[rel="value_show_with_link"].disabled, -.chzn-color.chzn-single[rel="value_show_with_link"][disabled] { - color: #fff; - background-color: #2f6f2f; - *background-color: #2f6f2f; -} -.chzn-color.chzn-single[rel="value_1"]:active, -.chzn-color.chzn-single[rel="value_1"].active, -.chzn-color-reverse.chzn-single[rel="value_0"]:active, -.chzn-color-reverse.chzn-single[rel="value_0"].active, -.chzn-color-state.chzn-single[rel="value_1"]:active, -.chzn-color-state.chzn-single[rel="value_1"].active, -.chzn-color.chzn-single[rel="value_show_no_link"]:active, -.chzn-color.chzn-single[rel="value_show_no_link"].active, -.chzn-color.chzn-single[rel="value_show_with_link"]:active, -.chzn-color.chzn-single[rel="value_show_with_link"].active { - background-color: #46a546; -} -.chzn-color-state.chzn-single[rel="value_0"], -.chzn-color-state.chzn-single[rel="value_-2"] { - background-color: #bd362f; - *background-color: #bd362f; - box-shadow: 0 1px 2px rgba(0,0,0,0.05); - color: #ffffff; -} -.chzn-color-state.chzn-single[rel="value_0"]:hover, -.chzn-color-state.chzn-single[rel="value_0"]:focus, -.chzn-color-state.chzn-single[rel="value_0"]:active, -.chzn-color-state.chzn-single[rel="value_0"].active, -.chzn-color-state.chzn-single[rel="value_0"].disabled, -.chzn-color-state.chzn-single[rel="value_0"][disabled], -.chzn-color-state.chzn-single[rel="value_-2"]:hover, -.chzn-color-state.chzn-single[rel="value_-2"]:focus, -.chzn-color-state.chzn-single[rel="value_-2"]:active, -.chzn-color-state.chzn-single[rel="value_-2"].active, -.chzn-color-state.chzn-single[rel="value_-2"].disabled, -.chzn-color-state.chzn-single[rel="value_-2"][disabled] { - color: #fff; - background-color: #802420; - *background-color: #802420; -} -.chzn-color-state.chzn-single[rel="value_0"]:active, -.chzn-color-state.chzn-single[rel="value_0"].active, -.chzn-color-state.chzn-single[rel="value_-2"]:active, -.chzn-color-state.chzn-single[rel="value_-2"].active { - background-color: #bd362f; -} -.CodeMirror { - height: calc(100vh - 400px); - min-height: 400px; - max-height: 800px; -} -.form-horizontal .control-label { - padding-right: 5px; - text-align: left; -} -.form-horizontal .control-label .spacer hr { - width: 380px; -} -@media (max-width: 420px) { - .form-horizontal .control-label .spacer hr { - width: 220px; - } -} -.form-horizontal .field-spacer>.control-label { - width: auto; -} -.form-horizontal #jform_catid_chzn { - vertical-align: middle; -} -.form-vertical .control-label > label { - display: inline-block; - *display: inline; - *zoom: 1; -} -.form-vertical .controls { - margin-left: 0; -} -@media (max-width: 979px) { - .form-horizontal-desktop .control-label { - float: none; - width: auto; - padding-right: 0; - padding-top: 0; - text-align: left; - } - .form-horizontal-desktop .control-label > label { - display: inline-block; - *display: inline; - *zoom: 1; - } - .form-horizontal-desktop .controls { - margin-left: 0; - } -} -@media (max-width: 1199px) { - .row-fluid .row-fluid .form-horizontal-desktop .control-label { - float: none; - width: auto; - padding-right: 0; - padding-top: 0; - text-align: left; - } - .row-fluid .row-fluid .form-horizontal-desktop .control-label > label { - display: inline-block; - *display: inline; - *zoom: 1; - } - .row-fluid .row-fluid .form-horizontal-desktop .controls { - margin-left: 0; - } -} -.form-inline-header { - margin: 5px 0; -} -.form-inline-header .control-group, -.form-inline-header .control-label, -.form-inline-header .controls { - display: inline-block; - *display: inline; - *zoom: 1; -} -.form-inline-header .control-label { - width: auto; - padding-right: 10px; -} -.form-inline-header .controls { - padding-right: 20px; -} -fieldset[class^="form-"] { - min-width: 100%; -} -@-moz-document url-prefix() { - fieldset[class^="form-"] { - display: table-cell; - } -} -fieldset.checkboxes input { - float: left; -} -fieldset.checkboxes li { - list-style: none; -} -.control-group, -.controls, -.controls input[type="text"], -.controls input[type="number"], -.controls input[type="email"], -.controls select, -.controls textarea { - max-width: 100%; -} -.controls .btn-group > .btn { - min-width: 50px; - margin-left: -1px; -} -.controls .btn-group.btn-group-yesno { - width: 220px; - max-width: 100%; -} -.controls .btn-group.btn-group-yesno > .btn { - width: 50%; - min-width: 40px; - padding: 2px 0; -} -input.input-large-text { - font-size: 18px; - line-height: 22px; - height: auto; -} -textarea { - resize: both; -} -textarea.vert { - resize: vertical; -} -textarea.noResize { - resize: none; -} -.subform-repeatable { - padding-right: 10px; -} -.subform-repeatable > .btn-toolbar { - margin: 0; -} -.subform-repeatable > .btn-toolbar .group-add { - line-height: 26px; - width: 56px; - font-size: 13px; - margin-left: 28px; -} -.subform-repeatable-group { - margin-top: 20px; - margin-left: 28px; - border: 1px solid #ccc; - padding: 8px 25px 15px; - position: relative; - border-radius: 3px; -} -.subform-repeatable-group > .btn-toolbar { - margin: 0; -} -.subform-repeatable-group > .btn-toolbar .btn-group { - margin-right: 0px; - margin-top: -1px; - position: static; -} -.subform-repeatable-group > .btn-toolbar .btn { - font-size: 13px; - line-height: 26px; - background-color: #F3F3F3; - position: absolute; -} -.subform-repeatable-group > .btn-toolbar .btn span { - vertical-align: middle; - line-height: 11px; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-success { - color: #378137; - bottom: 0; - right: 0; - border-radius: 3px 0 0 0; - border-width: 1px 0 0 1px; - padding-top: 1px; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-success .icon-plus:before { - content: "]"; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-danger { - color: #942a25; - top: 0; - right: 0; - border-radius: 0 0 0 3px; - border-width: 0 0 1px 1px; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-danger .icon-minus:before { - content: "I"; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-primary { - color: #24748c; - color: #333; - right: 100%; - top: 50%; - margin-top: -27px; - margin-right: 1px; - border-radius: 3px 0 0 3px; - border-width: 1px 0 1px 1px; - line-height: 52px; -} -.subform-repeatable-group > .btn-toolbar .btn.btn-primary .icon-move:before { - content: "Z"; -} -.subform-repeatable-group > .btn-toolbar .btn [class^="icon-"], -.subform-repeatable-group > .btn-toolbar .btn [class*=" icon-"] { - margin: 0; -} -.subform-repeatable-group > .btn-toolbar .btn:hover { - background-color: #E6E6E6; -} -.subform-repeatable-group .control-group:last-of-type { - margin-bottom: 10px; -} -@media (max-width: 979px) { - .subform-repeatable-group > .btn-toolbar .btn-group { - margin-bottom: 10px; - } -} -.subform-table-layout .control-group, -.subform-table-layout .control-group:last-of-type { - margin-bottom: 0; -} -.subform-table-layout .controls { - padding-right: 20px; -} -.subform-table-layout input { - width: 100%; - max-width: 206px; -} -.subform-table-layout table .btn-group { - margin: 0 7px; -} -@media (max-width: 1024px) { - .subform-table-layout .subform-repeatable { - padding-right: 0; - } - .subform-table-layout .subform-repeatable tbody td:last-of-type { - text-align: right; - padding-bottom: 15px; - } - .subform-table-layout table, - .subform-table-layout thead, - .subform-table-layout tbody, - .subform-table-layout th, - .subform-table-layout td, - .subform-table-layout tr { - display: block; - } - .subform-table-layout table { - border: 1px solid #ddd; - } - .subform-table-layout thead th { - position: absolute; - top: -9999px; - left: -9999px; - } - .subform-table-layout thead th:last-of-type { - position: static; - width: 100% !important; - text-align: right; - box-sizing: border-box; - border-left: 0; - } - .subform-table-layout tr { - margin: 0; - padding: 0; - border: 0; - } - .subform-table-layout td { - border: none; - position: relative; - padding-left: 50%; - } - .subform-table-layout tbody td:first-of-type { - padding-top: 15px; - border-top: 1px solid #ddd; - } - .subform-table-layout tbody td:first-of-type:before { - top: 18px; - } - .subform-table-layout td:before { - content: attr(data-column); - position: absolute; - top: 13px; - left: 10px; - padding-right: 10px; - } -} -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 0; -} -.form-horizontal .controls > .radio:first-child, -.form-horizontal .controls > .checkbox:first-child { - padding-top: 5px; -} -.form-horizontal .controls > .radio.btn-group:first-child { - padding-top: 0; -} -.form-horizontal .controls > .radio.btn-group-yesno:first-child { - padding-top: 2px; -} -.header { - background-color: #1a3867; - border-top: 1px solid rgba(255,255,255,0.2); - padding: 8px 25px; -} -@media (max-width: 767px) { - .header { - padding: 4px 18px; - margin-left: -20px; - margin-right: -20px; - } -} -.header .navbar-search { - margin-top: 0; -} -@media (max-width: 979px) { - .header .navbar-search { - border-top: 0; - border-bottom: 0; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - } -} -.container-logo { - float: right; - text-align: right; -} -.logo { - width: auto; - max-width: 100%; - max-height: 36px; - height: auto; -} -.page-title { - color: white; - font-weight: normal; - font-size: 20px; - line-height: 36px; - margin: 0; -} -.page-title [class^="icon-"], -.page-title [class*=" icon-"] { - margin-right: 16px; -} -@media (max-width: 767px) { - .container-logo { - display: none; - } - .page-title { - font-size: 18px; - line-height: 28px; - } - .page-title [class^="icon-"], - .page-title [class*=" icon-"] { - margin-right: 10px; - } -} -.view-login { - background-color: #17568c; - padding-top: 0; -} -.view-login .container { - width: 300px; - position: absolute; - top: 50%; - left: 50%; - margin-top: -206px; - margin-left: -150px; -} -.view-login .navbar-fixed-bottom { - padding-left: 20px; - padding-right: 20px; - text-align: center; -} -.view-login .navbar-fixed-bottom, -.view-login .navbar-fixed-bottom a { - color: #FCFCFC; -} -.view-login .navbar-inverse.navbar-fixed-bottom, -.view-login .navbar-inverse.navbar-fixed-bottom a { - color: #555; -} -.view-login .well { - padding-bottom: 0; -} -.view-login .login-joomla { - position: absolute; - left: 50%; - height: 24px; - width: 24px; - margin-left: -12px; - font-size: 22px; -} -.view-login .navbar-fixed-bottom { - position: absolute; -} -.view-login .input-medium { - width: 176px; -} -.view-login #lang_chzn { - width: 233px !important; - max-width: none; -} -.view-login #lang_chzn .chzn-single div { - width: 43px; -} -.view-login .input-prepend .add-on, -.view-login .controls .btn-group > .btn { - margin-left: 0; -} -.navbar-inverse { - color: #333; -} -.login .btn-large { - margin-top: 15px; -} -.login .form-inline .btn-group { - display: block; -} -@media (max-width: 479px) { - .login .chzn-single { - width: 222px !important; - } - .login .chzn-container, - .login .chzn-drop { - width: 230px !important; - } -} -@media (max-width: 319px) { - .view-login .navbar-fixed-bottom { - display: none; - } -} -ul.manager .height-50 .icon-folder-2 { - height: 35px; - width: 35px; - line-height: 35px; - font-size: 30px; -} -#imageForm { - margin: -25px 0 0; -} -#imageForm .well { - margin-bottom: 5px; -} -.thumbnails-media { - margin-left: 0; -} -.thumbnails-media .thumbnail { - background-color: #f4f4f4; - border-radius: 3px; - border: 0; - box-shadow: 0 0 0 1px rgba(0,0,0,0.05) inset; - padding: 0px; - height: 100px; - width: 100px; - margin: 8px 16px; - margin-left: 0 !important; - position: relative; - text-align: center; - overflow: hidden; -} -.thumbnails-media .thumbnail .close { - background-color: #ccc; - border-left: 1px solid rgba(0,0,0,0.1); - height: 22px; - line-height: 22px; - opacity: 0.3; - text-align: center; - width: 22px; - top: 0; - right: 0; -} -.thumbnails-media .thumbnail .close:hover { - background-color: #bbb; -} -.thumbnails-media .thumbnail *, -.thumbnails-media .thumbnail *:before { - -webkit-transition: all 0.2s ease; - transition: all 0.2s ease; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.thumbnails-media .thumbnail input[type="radio"], -.thumbnails-media .thumbnail input[type="checkbox"] { - margin: 0; - opacity: 0.55; - position: absolute; - top: 5px; - left: 5px; -} -.thumbnails-media .thumbnail .controls, -.thumbnails-media .thumbnail .imginfoBorder { - display: none; -} -.thumbnails-media .imgThumb { - position: relative; - z-index: 1; - width: 100%; - display: inline-block; -} -.thumbnails-media .imgThumb input { - display: none; -} -.thumbnails-media .imgThumb label, -.thumbnails-media .imgThumb .imgThumbInside { - display: block; - line-height: 100px; - position: relative; - width: 100%; - border-radius: 3px; - overflow: hidden; -} -.thumbnails-media .imgThumb label:before, -.thumbnails-media .imgThumb .imgThumbInside:before { - font-family: "IcoMoon"; - font-style: normal; - content: 'G'; - position: absolute; - top: 0; - right: 0; - background-color: #46a546; - color: #fff; - line-height: 26px; - width: 26px; - -webkit-transform: scale(0.5); - transform: scale(0.5); - opacity: 0; - border-color: rgba(0,0,0,0.2); - box-shadow: 0 1px 2px rgba(0,0,0,0.05); - border-radius: 0 3px; -} -.thumbnails-media .imgThumb img { - width: auto; -} -.thumbnails-media .selected :checked + label, -.thumbnails-media .selected .imgThumbInside, -.thumbnails-media .imgInput :checked + label, -.thumbnails-media .imgInput .imgThumbInside { - background-color: #ddd; -} -.thumbnails-media .selected :checked + label:before, -.thumbnails-media .selected .imgThumbInside:before, -.thumbnails-media .imgInput :checked + label:before, -.thumbnails-media .imgInput .imgThumbInside:before { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 1; -} -.thumbnails-media .selected :checked + label:after, -.thumbnails-media .selected .imgThumbInside:after, -.thumbnails-media .imgInput :checked + label:after, -.thumbnails-media .imgInput .imgThumbInside:after { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - content: ''; - border: 3px solid #46a546; - border-radius: 5px; -} -.thumbnails-media .imgDelete a.close, -.thumbnails-media .imgPreview a { - padding: 0; - position: absolute; - left: 0; - z-index: 1; - height: 26px; - width: 26px; -} -.thumbnails-media .imgPreview a { - width: 100%; -} -.thumbnails-media .imgDelete a.close { - background-color: #bd362f; - border-color: #bd362f rgba(0,0,0,0.2) rgba(0,0,0,0.2) #bd362f; - top: 0; - line-height: 28px; - font-size: 12px; - padding-left: 1px; - color: #fff; - border-bottom-right-radius: 3px; - border-top-left-radius: 3px; - z-index: 10; - opacity: 0; - -webkit-transform: scale(0.5); - transform: scale(0.5); -} -.thumbnails-media .imgDelete a.close:hover { - background-color: #802420; -} -.thumbnails-media .thumbnail:hover .imgDelete a.close { - opacity: 1; - -webkit-transform: scale(1); - transform: scale(1); -} -.thumbnails-media .imgPreview a, -.thumbnails-media .imgDetails { - position: absolute; - left: 0; - text-align: left; - background-color: #fff; - border-color: rgba(0,0,0,0.2); - bottom: 0; - line-height: 26px; - border: 1px solid rgba(0,0,0,0.1); - border-width: 1px; - border-radius: 0 3px 0 0; - z-index: 1; -} -.thumbnails-media .imgPreview a:hover, -.thumbnails-media .imgDetails:hover { - background-color: #eee; -} -.thumbnails-media .imgDetails { - padding: 0 5px; - line-height: 20px; - color: #555; -} -.thumbnails-media .imgFolder span { - line-height: 90px; - font-size: 38px; - margin: 0; - width: auto; -} -.thumbnails-media .imgFolder + .imgDetails { - color: inherit; -} -.com_media .media a + a { - margin-left: -1px; -} -.com_media .tree-holder { - padding: 0 15px; -} -#folderframe.thumbnail { - border: 0; - box-shadow: none; - padding: 0; -} -#mediamanager-form { - margin: 0 -10px; -} -#mediamanager-form > .muted { - padding: 0px; -} -#mediamanager-form .checkbox { - padding-left: 30px; - margin-bottom: 15px; -} -#mediamanager-form .checkbox input { - margin-top: 3px; -} -#mediamanager-form .thumbnails .thumbnail { - height: 120px; - width: 120px; - margin: 0 18px 18px 0; -} -#mediamanager-form .thumbnails .imgThumb label, -#mediamanager-form .thumbnails .imgTotal { - line-height: 120px; -} -#mediamanager-form .icon-search::before { - padding-right: 5px; - padding-left: 1px; -} -#mediamanager-form .height-50 { - background-color: #fafafa; - height: 77px; - position: relative; - z-index: 1; - width: 100%; - display: inline-block; -} -#mediamanager-form .height-50 a, -#mediamanager-form .height-50 .icon-folder-2 { - display: inline-block; - line-height: 75px; - margin-top: -1px; -} -#mediamanager-form .height-50 a:after { - bottom: 0; - box-shadow: 0 0 0 1px rgba(0,0,0,0.08) inset; - content: ""; - display: block; - left: 0; - overflow: hidden; - position: absolute; - right: 0; - top: 0; -} -#mediamanager-form .height-50 .icon-folder-2 { - font-size: 40px; -} -.uploadform { - margin-top: 20px; -} -body.modal-open { - -ms-overflow-style: none; -} -.modal-header { - padding: 0 20px; - text-align: left; -} -.modal-header h3 { - font-weight: normal; - line-height: 50px; -} -.modal-header .close { - width: 50px; - margin-top: 0; - margin-right: -15px; - font-size: 2rem; - line-height: 50px; - border-left: 1px solid #ccc; -} -.modal-body { - padding: 0; - width: 100%; - height: auto; -} -.modal-body .container-fluid { - padding-top: 15px; - padding-bottom: 15px; -} -.modal-footer { - clear: both; -} -.contentpane { - padding: 10px; - height: auto; -} -@media (min-width: 768px) { - .row-fluid .modal-batch [class*="span"] { - margin-left: 0; - } -} -.container-popup { - padding: 28px 10px 10px 10px; -} -body .navbar, -body .navbar-fixed-top { - margin-bottom: 0; -} -.navbar-inner { - min-height: 0; - background: #f2f2f2; - background-image: none; - filter: none; -} -.navbar-inner .container-fluid { - padding-left: 10px; - padding-right: 10px; - font-size: 15px; -} -.navbar-inverse .navbar-inner { - background: #10223e; - background-image: none; - filter: none; -} -.navbar .navbar-text { - line-height: 30px; -} -.navbar .admin-logo { - float: left; - padding: 7px 12px 0px 15px; - font-size: 16px; - color: #555; -} -.navbar .admin-logo:hover { - color: #333; -} -.navbar-inverse.navbar .admin-logo { - color: #d9d9d9; -} -.navbar-inverse.navbar .admin-logo:hover { - color: #ffffff; -} -.navbar .brand { - float: right; - display: block; - padding: 6px 10px; - margin-left: -20px; - font-size: inherit; - font-weight: normal; -} -.navbar .brand:hover, -.navbar .brand:focus { - text-decoration: none; -} -.navbar .nav > li > a { - padding: 6px 10px; -} -.navbar .nav > li > a:hover { - color: white; -} -.navbar .nav > li > a:hover span.carot { - border-bottom-color: #fff; - border-top-color: #fff; -} -.navbar .dropdown-menu, -.navbar .nav-user { - font-size: 13px; -} -.navbar .nav-user .dropdown-menu li span { - padding-left: 10px; -} -.navbar .nav > li ul { - overflow-y: auto; - overflow-x: hidden; - -webkit-overflow-scrolling: touch; - -moz-overflow-scrolling: touch; - -ms-overflow-scrolling: touch; - -o-overflow-scrolling: touch; - overflow-scrolling: touch; - height: auto; - max-height: 500px; - margin: 0; -} -.navbar .nav > li ul::-webkit-scrollbar { - -webkit-appearance: none; - width: 7px; -} -.navbar .nav > li ul::-webkit-scrollbar-thumb { - border-radius: 4px; - background-color: rgba(0,0,0,0.5); - -webkit-box-shadow: 0 0 1px rgba(255,255,255,0.5); -} -.navbar .nav > li > .dropdown-menu:after { - display: none; -} -.navbar .nav > .dropdown.open:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #fff; - position: absolute; - top: 25px; - left: 10px; - z-index: 1001; -} -.navbar .empty-nav { - display: none; -} -.navbar-fixed-top .navbar-inner, -.navbar-static-top .navbar-inner { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus, -.dropdown-submenu:hover > a, -.dropdown-submenu:focus > a { - background-image: none; -} -.navbar-fixed-bottom { - bottom: 0; -} -.navbar-fixed-bottom .navbar-inner { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.navbar .btn-navbar { - background: #17568c; - border: 1px solid #0D2242; - margin-bottom: 2px; -} -@media (max-width: 767px) { - .navbar .admin-logo { - margin-left: 10px; - padding: 9px 9px 0 9px; - } -} -.navbar-search .search-query { - background: rgba(255,255,255,0.3); -} -@media (max-width: 979px) { - .navbar .nav { - font-size: 13px; - margin: 0 2px 0 0; - } - .navbar .nav > li > a { - padding: 6px; - } -} -@media (max-width: 767px) { - .navbar-search.pull-right { - float: none; - text-align: center; - } -} -@media (max-width: 738px) { - .navbar .brand { - font-size: 16px; - } -} -.nav-collapse .nav li a, -.dropdown-menu a { - background-image: none; -} -.nav-collapse .dropdown-menu > li img { - max-width: none; -} -@media (max-width: 767px) { - .navbar-fixed-top .navbar-inner, - .navbar-fixed-top .navbar-inner .container-fluid { - padding: 0; - } - .navbar .brand { - margin-top: 2px; - float: none; - text-align: center; - } - .navbar .btn-navbar { - margin-top: 3px; - margin-right: 3px; - margin-bottom: 3px; - } - .nav-collapse .nav .nav-header { - color: #fff; - } - .nav-collapse .nav, - .navbar .nav-collapse .nav.pull-right { - margin: 0; - } - .nav-collapse .dropdown-menu { - margin: 0; - } - .nav-collapse .dropdown-menu > li > span { - display: block; - padding: 4px 15px; - } - .navbar-inverse .nav-collapse .dropdown-menu > li > span { - color: #d9d9d9; - } - .nav-collapse .nav > li > a.dropdown-toggle { - background-color: rgba(255,255,255,0.07); - font-size: 12px; - font-weight: bold; - color: #eee; - text-transform: uppercase; - padding-left: 15px; - } - .nav-collapse .nav li a { - margin-bottom: 0; - border-top: 1px solid rgba(255,255,255,0.25); - border-bottom: 1px solid rgba(0,0,0,0.5); - } - .nav-collapse .nav li ul li ul.dropdown-menu, - .nav-collapse .nav li ul li:hover ul.dropdown-menu, - .nav-collapse .caret { - display: none !important; - } - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - font-size: 15px; - font-weight: normal; - color: #fff; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - } - .navbar .nav-collapse .nav > li > .dropdown-menu::before, - .navbar .nav-collapse .nav > li > .dropdown-menu::after, - .navbar .nav-collapse .dropdown-submenu > a::after { - display: none; - } - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 0; - } -} -.quick-icons { - font-size: 14px; - margin-bottom: 20px; -} -.quick-icons .nav-header { - margin: 12px 0 5px; - font-size: 13px; -} -.quick-icons .nav-header:first-child { - margin: 0 0 5px; -} -.quick-icons [class^="icon-"], -.quick-icons [class*=" icon-"] { - margin-right: 9px; -} -.quick-icons [class^="icon-"]:before, -.quick-icons [class*=" icon-"]:before { - font-size: 16px; - margin-bottom: 20px; - line-height: 18px; -} -html[dir=rtl] .quick-icons .nav-list [class^="icon-"], -html[dir=rtl] .quick-icons .nav-list [class*=" icon-"] { - margin-left: 9px; - margin-right: 0; -} -.sidebar-nav .nav-list { - padding-left: 25px; - padding-right: 25px; -} -.sidebar-nav .nav-list > li > a { - color: #555; - padding: 3px 25px; - margin-left: -26px; - margin-right: -26px; -} -.sidebar-nav .nav-list > li.active > a { - color: #fff; - margin-right: -26px; -} -.sidebar-nav .nav-list > li > a:focus, -.sidebar-nav .nav-list > li > a:hover { - text-decoration: none; - color: #fff; - background-color: #2d6ca2; - text-shadow: none; -} -.j-sidebar-container { - position: absolute; - display: block; - left: -16.5%; - width: 16.5%; - margin: -18px 0 0 -1px; - padding-top: 28px; - padding-bottom: 40px; - clear: both; - background-color: #F0F0F0; - border-bottom: 1px solid #dedede; - border-right: 1px solid #dedede; - -webkit-border-radius: 0 0 3px 0; - -moz-border-radius: 0 0 3px 0; - border-radius: 0 0 3px 0; -} -.j-sidebar-container.j-sidebar-hidden { - left: -16.5%; -} -.j-sidebar-container.j-sidebar-visible { - left: 0; -} -.j-sidebar-container .filter-select { - padding: 0 14px; -} -.j-toggle-sidebar-header h3 { - font-weight: normal; - padding: 0 15px; -} -.j-toggle-button-wrapper { - position: absolute; - display: block; - top: 7px; - padding: 0; -} -.j-toggle-button-wrapper.j-toggle-hidden { - right: -24px; -} -.j-toggle-button-wrapper.j-toggle-visible { - right: 7px; -} -.j-toggle-sidebar-button { - font-size: 16px; - color: #3071a9; - text-decoration: none; - cursor: pointer; -} -.j-toggle-sidebar-button:hover { - color: #1f496e; -} -#system-message-container, -#j-main-container { - padding: 0 0 0 5px; - min-height: 0; -} -#system-message-container.j-toggle-main, -#j-main-container.j-toggle-main, -#system-debug.j-toggle-main { - float: right; -} -@media (min-width: 768px) { - .j-toggle-transition { - -webkit-transition: all 0.3s ease; - -moz-transition: all 0.3s ease; - -o-transition: all 0.3s ease; - transition: all 0.3s ease; - } -} -@media (max-width: 979px) { - .j-toggle-button-wrapper.j-toggle-hidden { - right: -20px; - } -} -@media (max-width: 767px) { - .j-sidebar-container { - position: relative; - width: 100%; - margin: 0 0 20px 0; - padding: 0; - background: transparent; - border-right: 0; - border-bottom: 0; - } - .j-sidebar-container.j-sidebar-hidden { - margin-left: 16.5%; - } - .j-sidebar-container.j-sidebar-visible { - margin-left: 0; - } - .j-toggle-sidebar-header, - .j-toggle-button-wrapper { - display: none; - } - .view-login select { - width: 232px; - } -} -@media (max-width: 420px) { - .j-sidebar-container { - margin: 0; - } - .view-login .input-medium { - width: 180px; - } - .view-login select { - width: 232px; - } -} -#status { - background: #ebebeb; - border-top: 1px solid #dedede; - padding: 4px 10px; - -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); - -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); - box-shadow: 0 0 3px rgba(0, 0, 0, 0.08); - color: #626262; -} -#status .btn-group { - margin: 0; -} -#status .btn-group.separator:after { - content: ' '; - display: block; - float: left; - background: #ADADAD; - margin: 0 10px; - height: 15px; - width: 1px; -} -#status .btn-toolbar, -#status p { - margin: 0px; -} -#status .btn-toolbar, -#status .btn-group { - font-size: 12px; -} -#status a { - color: #626262; -} -#status .badge { - margin-right: .25em; -} -#status.status-top { - background: #1a3867; - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3); - border-top: 0; - color: #d9d9d9; - padding: 2px 20px 6px 20px; -} -#status.status-top a { - color: #d9d9d9; -} -@media (max-width: 479px) { - .pagination a { - padding: 5px; - } - .btn-group.divider, - .header .row-fluid .span3, - .header .row-fluid .span7 { - display: none; - } - .navbar .btn { - margin: 0; - } - .btn-subhead { - display: block; - margin: 10px 0; - } - .subhead-collapse.collapse { - height: 0; - overflow: hidden; - } - .btn-toolbar .btn-wrapper { - display: block; - margin: 0px 10px 5px 10px; - } - .btn-toolbar .btn-wrapper .btn { - width: 100% !important; - } - .subhead { - background: none repeat scroll 0 0 transparent; - border-bottom: 0 solid #dedede; - } - .btn-group + .btn-group { - margin-left: 10px; - } - .login .chzn-single { - width: 222px !important; - } - .login .chzn-container, - .login .chzn-drop { - width: 230px !important; - } - #toolbar [class^="icon-"], - #toolbar [class*=" icon-"] { - background-color: transparent; - border-right: medium none; - width: 10px; - } -} -table label { - margin: 0; -} -td.has-context { - height: 23px; -} -td.nowrap.has-context { - width: 45%; -} -.subhead { - background: #F0F0F0; - border-bottom: 1px solid #dedede; - color: #0C192E; - text-shadow: 0 1px 0 #FFF; - margin-bottom: 10px; - min-height: 51px; -} -.subhead-collapse { - margin-bottom: 19px; -} -.subhead-collapse.collapse { - height: auto; - overflow: visible; -} -.btn-toolbar { - margin-bottom: 5px; -} -.btn-toolbar .btn-wrapper { - display: inline-block; - margin: 0 0 8px 5px; -} -.subhead-fixed { - position: fixed; - width: 100%; - top: 30px; - z-index: 100; -} -@media (max-width: 767px) { - body { - -webkit-overflow-scrolling: touch; - } - .subhead { - margin-left: -20px; - margin-right: -20px; - padding-left: 10px; - padding-right: 10px; - } -} -.subhead h1 { - font-size: 17px; - font-weight: normal; - margin-left: 10px; - margin-top: 6px; -} -#toolbar { - margin-bottom: 2px; - margin-top: 12px; -} -#toolbar .btn { - line-height: 24px; - margin-right: 4px; - padding: 0 10px; -} -#toolbar .btn-success { - min-width: 148px; -} -#toolbar .btn-primary [class^="icon-"], -#toolbar .btn-primary [class*=" icon-"], -#toolbar .btn-warning [class^="icon-"], -#toolbar .btn-warning [class*=" icon-"], -#toolbar .btn-danger [class^="icon-"], -#toolbar .btn-danger [class*=" icon-"], -#toolbar .btn-success [class^="icon-"], -#toolbar .btn-success [class*=" icon-"], -#toolbar .btn-info [class^="icon-"], -#toolbar .btn-info [class*=" icon-"], -#toolbar .btn-inverse [class^="icon-"], -#toolbar .btn-inverse [class*=" icon-"] { - background-color: transparent; - border-right: 0; - border-left: 0; - width: 16px; - margin-left: 0; - margin-right: 0; -} -#toolbar #toolbar-options, -#toolbar #toolbar-help { - float: right; -} -#toolbar [class^="icon-"], -#toolbar [class*=" icon-"] { - background-color: #e6e6e6; - border-radius: 3px 0 0 3px; - border-right: 1px solid #b3b3b3; - height: auto; - line-height: inherit; - margin: 0 6px 0 -10px; - opacity: 1; - text-shadow: none; - width: 28px; - z-index: -1; -} -#toolbar iframe .btn-group .btn { - margin-left: -1px !important; -} -html[dir=rtl] #toolbar #toolbar-options, -html[dir=rtl] #toolbar #toolbar-help { - float: left; -} -@media (max-width: 767px) { - .subhead-fixed { - position: static; - width: auto; - } -} -.btn-subhead { - display: none; -} -@media (min-width: 480px) { - #filter-bar { - height: 29px; - } -} -@media (max-width: 479px) { - .navbar .btn { - margin: 0; - } - .btn-subhead { - display: block; - margin: 10px 0; - } - .subhead-collapse.collapse { - height: 0; - overflow: hidden; - } - .btn-toolbar .btn-wrapper { - display: block; - margin: 0px 10px 5px 10px; - } - .btn-toolbar .btn-wrapper .btn { - width: 100% !important; - } - .subhead { - background: none repeat scroll 0 0 transparent; - border-bottom: 0 solid #dedede; - } - #toolbar [class^="icon-"], - #toolbar [class*=" icon-"] { - background-color: transparent; - border-right: medium none; - width: 10px; - } -} -@media (max-width: 319px) { - .view-login .navbar-fixed-bottom { - display: none; - } -} -ul.treeselect, -ul.treeselect li { - margin: 0; - padding: 0; -} -ul.treeselect { - margin-top: 8px; -} -ul.treeselect li { - padding: 2px 10px 2px; - list-style: none; -} -ul.treeselect i.treeselect-toggle { - line-height: 18px; -} -ul.treeselect label { - font-size: 1em; - margin-left: 8px; -} -ul.treeselect label.nav-header { - padding: 0; -} -ul.treeselect input { - margin: 2px 0 0 8px; -} -ul.treeselect .treeselect-menu { - margin: 0 6px; -} -ul.treeselect ul.dropdown-menu { - margin: 0; -} -ul.treeselect ul.dropdown-menu li { - padding: 0 5px; - border: none; -} -.tree-holder .folder-url, -.tree-holder .file { - position: relative; - background-color: #fefefe; - margin-bottom: 4px; - padding: 0 10px; - line-height: 32px; - border: 1px solid rgba(0,0,0,0.08); -} -.tree-holder .folder-url, -.tree-holder .folder-url:hover, -.tree-holder .folder-url:focus { - font-weight: bold; - background-color: #f5f5f5; - color: #3071a9; -} -.tree-holder .active { - background-color: #3071a9; - color: #fff; - box-shadow: -3px 0 0 #36a2ff !important; -} -.tree-holder .active.folder-url { - background-color: #f5f5f5; - color: #3071a9; -} -.tree-holder .active.file:hover { - background-color: #3071a9; -} -.tree-holder ul ul { - box-shadow: -3px 0 0 rgba(0,0,0,0.08); - padding-right: 0; -} -.tree-holder ul ul .folder-url, -.tree-holder ul ul .file { - box-shadow: -3px 0 0 #3071a9; - border-left: 0; -} -.break-word { - word-break: break-all; - word-wrap: break-word; -} -.disabled { - cursor: default; - background-image: none; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.j-links-separator { - margin: 20px 0px; - width: 100%; - height: 0px; - border-top: 2px solid #DDDDDD; -} -.container-main, -#system-debug { - padding-bottom: 50px; -} -.pagination-toolbar { - margin: 0; -} -.pagination-toolbar a { - line-height: 26px; -} -.pull-right > .dropdown-menu { - left: auto; - right: 0; -} -.nav-filters hr { - margin: 5px 0; -} -#assignment.tab-pane { - min-height: 500px; -} -@media (max-width: 979px) { - .container-fluid { - padding-left: 10px; - padding-right: 10px; - } -} -@media (min-width: 768px) { - body { - padding-top: 30px; - } - .nav-collapse.collapse.in { - height: auto !important; - } -} -@media (max-width: 767px) { - .container-fluid { - padding-left: 0; - padding-right: 0; - } -} -@media (max-width: 479px) { - .pagination a { - padding: 5px; - } - .btn-group.divider, - .header .row-fluid .span3, - .header .row-fluid .span7 { - display: none; - } - .btn-group + .btn-group { - margin-left: 10px; - } -} -.info-labels { - margin-top: -5px; - margin-bottom: 10px; -} -.sortable-handler.inactive { - opacity: 0.3; - filter: alpha(opacity=30); -} -.alert-joomlaupdate { - text-align: center; -} -.alert-joomlaupdate button { - vertical-align: baseline; -} -.j-jed-message { - line-height: 2em; - color: #333333; -} -.upload-queue > li > span, -.upload-queue > li > a { - margin: 0 2px; -} -.upload-queue .file-remove { - float: right; -} -.moor-box { - z-index: 3; -} -.admin .chzn-container .chzn-drop { - z-index: 1060; -} -.item-associations { - margin: 0; -} -.item-associations li { - list-style: none; - display: inline-block; - margin: 0 0 3px 0; -} -.item-associations li a { - color: #ffffff; -} -#flag img { - padding-top: 6px; - vertical-align: top; -} -.tooltip { - max-width: 400px; -} -.tooltip-inner { - max-width: none; - text-align: left; - text-shadow: none; -} -th .tooltip-inner { - font-weight: normal; -} -.tooltip.hasimage { - opacity: 1; -} -#permissions-sliders .chzn-container { - margin-top: -5px; - position: absolute; -} -#permissions-sliders .table td { - padding: 8px 8px 9px; -} -.img-preview > img { - max-height: 100%; -} -#helpsite-refresh { - padding: 4px 12px; - vertical-align: top; -} -.alert-no-items { - margin-top: 20px; -} -@media (max-width: 767px) { - html[dir=rtl] #toolbar #toolbar-options, - html[dir=rtl] #toolbar #toolbar-help, - #toolbar #toolbar-options, - #toolbar #toolbar-help { - float: none; - } -} -#permissions-sliders .input-small { - width: 120px; -} -.editor { - overflow: hidden; - position: relative; -} -.editor textarea.mce_editable { - box-sizing: border-box; -} -a.grid_false { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/publish_r.png'); -} -a.grid_true { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/icon-16-allow.png'); -} -textarea, -input, -.uneditable-input { - box-shadow: none !important; -} -textarea:focus, -input:focus, -.uneditable-input:focus { - box-shadow: none; - border: 1px solid #3071A9; -} -.js-pstats-data-details dd { - margin-left: 240px; -} -.js-pstats-data-details dt { - width: 220px; -} -#permissions table td, -#page-permissions table td { - vertical-align: middle; -} -#permissions table select, -#page-permissions table select { - margin-bottom: 0; -} -.js-stools-container-bar .btn-primary .caret { - border-bottom: 4px solid #fff; -} -.input-append .add-on, -.input-append .btn, -.input-append .btn-group > .dropdown-toggle, -.input-prepend .add-on, -.input-prepend .btn, -.input-prepend .btn-group > .dropdown-toggle { - -webkit-border-radius: 0 3px 3px 0; - -moz-border-radius: 0 3px 3px 0; - border-radius: 0 3px 3px 0; -} -.alert, -.alert-options, -.badge, -.breadcrumb > li, -.close, -.input-append .add-on, -.input-prepend .add-on, -.label, -.nav-header, -.nav-list .nav-header, -.nav-list > .active > a, -.nav-list > .active > a:focus, -.nav-list > .active > a:hover, -.nav-list > li > a, -.nav-tabs.nav-dark, -.navbar .brand, -.navbar .nav > li > a, -.navbar-inverse .brand, -.navbar-inverse .nav > li > a, -.navbar-inverse .navbar-search .search-query.focused, -.navbar-inverse .navbar-search .search-query:focus, -.progress .bar, -.subhead { - text-shadow: none; -} -.popover-content { - min-height: 33px; -} -.lead, -.navbar .brand, -.hero-unit, -.hero-unit .lead { - font-weight: 400; -} -.com_cpanel .well { - padding: 8px 14px; - border: 1px solid rgba(0,0,0,0.05); -} -.com_cpanel .well .module-title.nav-header { - color: #555; -} -.com_cpanel .well > .row-striped, -.com_cpanel .well > .list-striped { - margin: 0 -14px; -} -.com_cpanel .well > .row-striped > .row-fluid, -.com_cpanel .well > .list-striped > .row-fluid { - padding: 8px 14px; -} -.com_cpanel .well > .row-striped > .row-fluid [class*="span"], -.com_cpanel .well > .list-striped > .row-fluid [class*="span"] { - margin-left: 0; -} -.com_cpanel .well > .row-striped > li, -.com_cpanel .well > .list-striped > li { - padding-left: 15px; - padding-right: 15px; -} -.com_postinstall fieldset { - background-color: #fafafa; - border: 1px solid #ccc; - border-radius: 5px; - margin: 0 0 18px; - padding: 4px 18px 18px; -} -.com_postinstall fieldset .btn { - margin-top: 10px; -} -.com_postinstall legend { - border: 0 none; - display: inline-block; - padding: 0 5px; - margin-bottom: 0; - width: auto; -} -#menu-assignment { - position: relative; -} -#menu-assignment .menu-links { - margin-top: 15px; - margin-left: 0; - -webkit-column-count: 3; - -moz-column-count: 3; - column-count: 3; - -moz-column-gap: 15px; - -webkit-column-gap: 15px; - column-gap: 15px; -} -#menu-assignment .menu-links > li { - display: inline-block; - vertical-align: top; - margin-bottom: 15px; - width: 100%; - list-style: none; - -webkit-column-break-inside: avoid; - -webkit-backface-visibility: hidden; -} -#menu-assignment .menu-links-block { - background-color: #fafafa; - border: 1px solid #ddd; - border-radius: 3px; - padding: 15px; -} -@media (max-width: 767px) { - #menu-assignment .menu-links { - -webkit-column-count: auto; - -moz-column-count: auto; - column-count: auto; - } -} diff --git a/administrator/templates/isis/error.php b/administrator/templates/isis/error.php deleted file mode 100644 index 9c3a0cb1afbbd..0000000000000 --- a/administrator/templates/isis/error.php +++ /dev/null @@ -1,296 +0,0 @@ -getTemplate(true)->params; - -$app = JFactory::getApplication(); -$lang = JFactory::getLanguage(); -$input = $app->input; -$user = JFactory::getUser(); - -// Gets the FrontEnd Main page Uri -$frontEndUri = JUri::getInstance(JUri::root()); -$frontEndUri->setScheme(((int) $app->get('force_ssl', 0) === 2) ? 'https' : 'http'); -$mainPageUri = $frontEndUri->toString(); - -// Detecting Active Variables -$option = $input->get('option', ''); -$view = $input->get('view', ''); -$layout = $input->get('layout', ''); -$task = $input->get('task', ''); -$itemid = $input->get('Itemid', 0, 'int'); -$sitename = $app->get('sitename'); - -$cpanel = ($option === 'com_cpanel'); - -$showSubmenu = false; -$this->submenumodules = JModuleHelper::getModules('submenu'); -foreach ($this->submenumodules as $submenumodule) -{ - $output = JModuleHelper::renderModule($submenumodule); - if ($output !== '') - { - $showSubmenu = true; - break; - } -} - -// Logo file -if ($params->get('logoFile')) -{ - $logo = JUri::root() . $params->get('logoFile'); -} -else -{ - $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo.png'; -} - -// Template Parameters -$displayHeader = $params->get('displayHeader', '1'); -$statusFixed = $params->get('statusFixed', '1'); -$stickyToolbar = $params->get('stickyToolbar', '1'); -?> - - - - - - - <?php echo $this->title; ?> <?php echo htmlspecialchars($this->error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> - get('debug_lang', '0') == '1' || $app->get('debug', '0') == '1') : ?> - - - - - direction == 'rtl') : ?> - - - - getTag() . '/' . $lang->getTag() . '.css'; ?> - - - - - - - get('templateColor')) : ?> - - - - get('headerColor')) : ?> - - - - get('sidebarColor')) : ?> - - - - - - - - - - - - -
          - - - -
          -

          -
          -
          - getInstance()->countModules('status')) : ?> - - - - -
          - -
          -
          - -
          -
          - -

          -
          - error->getCode(); ?> error->getMessage(), ENT_QUOTES, 'UTF-8');?> - debug) : ?> -
          error->getFile(), ENT_QUOTES, 'UTF-8');?>:error->getLine(); ?> - -
          - debug) : ?> -
          - renderBacktrace(); ?> - - error->getPrevious()) : ?> - - _error here and in the loop as setError() assigns errors to this property and we need this for the backtrace to work correctly ?> - - setError($this->_error->getPrevious()); ?> - -

          -

          - _error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> -
          _error->getFile(), ENT_QUOTES, 'UTF-8');?>:_error->getLine(); ?> -

          - renderBacktrace(); ?> - setError($this->_error->getPrevious()); ?> - - - setError($this->error); ?> - -
          - -

          - -
          -
          - -
          -
          -
          - - - diff --git a/administrator/templates/isis/html/com_media/imageslist/default_folder.php b/administrator/templates/isis/html/com_media/imageslist/default_folder.php deleted file mode 100644 index 6fd2b12f53dd1..0000000000000 --- a/administrator/templates/isis/html/com_media/imageslist/default_folder.php +++ /dev/null @@ -1,23 +0,0 @@ -input; -?> -
        • - -
          - -
          -
          - _tmp_folder->name, 10, false); ?> -
          -
          -
        • diff --git a/administrator/templates/isis/html/com_media/imageslist/default_image.php b/administrator/templates/isis/html/com_media/imageslist/default_image.php deleted file mode 100644 index 6a5eea836df14..0000000000000 --- a/administrator/templates/isis/html/com_media/imageslist/default_image.php +++ /dev/null @@ -1,32 +0,0 @@ -trigger('onContentBeforeDisplay', array('com_media.file', &$this->_tmp_img, &$params)); -?> - -
        • - -
          -
          - 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)); ?> -
          -
          -
          - _tmp_img->name, 10, false); ?> -
          -
          -
        • -trigger('onContentAfterDisplay', array('com_media.file', &$this->_tmp_img, &$params)); diff --git a/administrator/templates/isis/html/com_media/medialist/thumbs_folders.php b/administrator/templates/isis/html/com_media/medialist/thumbs_folders.php deleted file mode 100644 index 2a62670982838..0000000000000 --- a/administrator/templates/isis/html/com_media/medialist/thumbs_folders.php +++ /dev/null @@ -1,35 +0,0 @@ - -folders as $i => $folder) : ?> -
        • - canDelete):?> - × -
          - name, false, 'rm', 'cb-folder'); ?> -
          -
          - - -
          - - - -
          - - -
        • - diff --git a/administrator/templates/isis/html/com_media/medialist/thumbs_imgs.php b/administrator/templates/isis/html/com_media/medialist/thumbs_imgs.php deleted file mode 100644 index ae1afdcc39ea2..0000000000000 --- a/administrator/templates/isis/html/com_media/medialist/thumbs_imgs.php +++ /dev/null @@ -1,46 +0,0 @@ - - -images as $i => $img) : ?> - trigger('onContentBeforeDisplay', array('com_media.file', &$img, &$params)); ?> -
        • - - canDelete):?> -
          - -
          - - -
          - canDelete):?> - name, false, 'rm', 'cb-image'); ?> - - -
          - - -
        • - trigger('onContentAfterDisplay', array('com_media.file', &$img, &$params)); ?> - diff --git a/administrator/templates/isis/html/layouts/joomla/form/field/media.php b/administrator/templates/isis/html/layouts/joomla/form/field/media.php deleted file mode 100644 index 50e38e19bab6b..0000000000000 --- a/administrator/templates/isis/html/layouts/joomla/form/field/media.php +++ /dev/null @@ -1,140 +0,0 @@ - -
          - JText::_('JLIB_FORM_CHANGE_IMAGE'), - 'closeButton' => true, - 'footer' => '' . JText::_('JCANCEL') . '', - ) - ); - - JHtml::_('script', 'media/mediafield.min.js', array('version' => 'auto', 'relative' => true)); - ?> - -
          - - - - -
          - - /> - - - - -
          - -
          - -
          diff --git a/administrator/templates/isis/html/layouts/joomla/form/field/user.php b/administrator/templates/isis/html/layouts/joomla/form/field/user.php deleted file mode 100644 index 7a33b47058749..0000000000000 --- a/administrator/templates/isis/html/layouts/joomla/form/field/user.php +++ /dev/null @@ -1,127 +0,0 @@ - section in form XML. - * @var boolean $hidden Is this field hidden in the form? - * @var string $hint Placeholder for the field. - * @var string $id DOM id of the field. - * @var string $label Label of the field. - * @var string $labelclass Classes to apply to the label. - * @var boolean $multiple Does this field support multiple values? - * @var string $name Name of the input field. - * @var string $onchange Onchange attribute for the field. - * @var string $onclick Onclick attribute for the field. - * @var string $pattern Pattern (Reg Ex) of value of the form field. - * @var boolean $readonly Is this field read only? - * @var boolean $repeat Allows extensions to duplicate elements. - * @var boolean $required Is this field required? - * @var integer $size Size attribute of the input. - * @var boolean $spellcheck Spellcheck state for the form field. - * @var string $validate Validation rules to apply. - * @var string $value Value attribute of the field. - * - * @var string $userName The user name - * @var mixed $groups The filtering groups (null means no filtering) - * @var mixed $excluded The users to exclude from the list of users - */ - -if (!$readonly) -{ - JHtml::_('script', 'jui/fielduser.min.js', array('version' => 'auto', 'relative' => true)); -} - -$uri = new JUri('index.php?option=com_users&view=users&layout=modal&tmpl=component&required=0&field={field-user-id}&ismoo=0'); - -if ($required) -{ - $uri->setVar('required', 1); -} - -if (!empty($groups)) -{ - $uri->setVar('groups', base64_encode(json_encode($groups))); -} - -if (!empty($excluded)) -{ - $uri->setVar('excluded', base64_encode(json_encode($excluded))); -} - -// Invalidate the input value if no user selected -if ($this->escape($userName) === JText::_('JLIB_FORM_SELECT_USER')) -{ - $userName = ''; -} - -$inputAttributes = array( - 'type' => 'text', 'id' => $id, 'class' => 'field-user-input-name', 'value' => $this->escape($userName) -); - -if ($class) -{ - $inputAttributes['class'] .= ' ' . $class; -} - -if ($size) -{ - $inputAttributes['size'] = (int) $size; -} - -if ($required) -{ - $inputAttributes['required'] = 'required'; -} - -if (!$readonly) -{ - $inputAttributes['placeholder'] = JText::_('JLIB_FORM_SELECT_USER'); -} - -?> -
          -
          - readonly /> - - - JText::_('JLIB_FORM_CHANGE_USER'), - 'closeButton' => true, - 'footer' => '' . JText::_('JCANCEL') . '', - ) - ); ?> - -
          - - - -
          diff --git a/administrator/templates/isis/html/layouts/joomla/pagination/link.php b/administrator/templates/isis/html/layouts/joomla/pagination/link.php deleted file mode 100644 index 5c7b861a2ab69..0000000000000 --- a/administrator/templates/isis/html/layouts/joomla/pagination/link.php +++ /dev/null @@ -1,113 +0,0 @@ -get('liClass', ''); - $addText = $options->get('addText', ''); -} -else -{ - $liClass = $addText = ''; -} - -$display = $item->text; - -switch ((string) $item->text) -{ - // Check for "Start" item - case JText::_('JLIB_HTML_START') : - $icon = 'icon-backward icon-first'; - $aria = JText::sprintf('JLIB_HTML_GOTO_POSITION', strtolower($item->text)); - break; - - // Check for "Prev" item - case JText::_('JPREV') : - $item->text = JText::_('JPREVIOUS'); - $icon = 'icon-step-backward icon-previous'; - $aria = JText::sprintf('JLIB_HTML_GOTO_POSITION', strtolower($item->text)); - break; - - // Check for "Next" item - case JText::_('JNEXT') : - $icon = 'icon-step-forward icon-next'; - $aria = JText::sprintf('JLIB_HTML_GOTO_POSITION', strtolower($item->text)); - break; - - // Check for "End" item - case JText::_('JLIB_HTML_END') : - $icon = 'icon-forward icon-last'; - $aria = JText::sprintf('JLIB_HTML_GOTO_POSITION', strtolower($item->text)); - break; - - default: - $icon = null; - $aria = JText::sprintf('JLIB_HTML_GOTO_PAGE', $item->text); - break; -} - -$item->text .= $addText ?: ''; - -if ($icon !== null) -{ - $display = ''; -} - -if ($displayData['active']) -{ - if ($item->base > 0) - { - $limit = 'limitstart.value=' . $item->base; - } - else - { - $limit = 'limitstart.value=0'; - } - - $cssClasses = array(); - - $title = ''; - - if (!is_numeric($item->text)) - { - JHtml::_('bootstrap.tooltip'); - $cssClasses[] = 'hasTooltip'; - $title = ' title="' . $item->text . '" '; - } - - $onClick = 'document.adminForm.' . $item->prefix . 'limitstart.value=' . ($item->base > 0 ? $item->base : '0') . '; Joomla.submitform();return false;'; -} -else -{ - $class = (property_exists($item, 'active') && $item->active) ? 'active' : 'disabled'; - if ($class != 'active') - { - $class .= $liClass ? ($class ? ' ' : '') . $liClass : ''; - } -} -?> - - > - href="#" onclick=""> - - - - -
        • - > - - -
        • -get('showLimitBox', 0); -$showPagesLinks = $options->get('showPagesLinks', true); -$showLimitStart = $options->get('showLimitStart', true); -?> - - diff --git a/administrator/templates/isis/html/layouts/joomla/system/message.php b/administrator/templates/isis/html/layouts/joomla/system/message.php deleted file mode 100644 index aa5c91fb34bb3..0000000000000 --- a/administrator/templates/isis/html/layouts/joomla/system/message.php +++ /dev/null @@ -1,30 +0,0 @@ - 'alert-error', 'warning' => '', 'notice' => 'alert-info', 'message' => 'alert-success'); -?> -
          - - $msgs) : ?> -
          - - -

          - -
          - - -
          - - -
          diff --git a/administrator/templates/isis/html/layouts/joomla/toolbar/versions.php b/administrator/templates/isis/html/layouts/joomla/toolbar/versions.php deleted file mode 100644 index a00f330fcce41..0000000000000 --- a/administrator/templates/isis/html/layouts/joomla/toolbar/versions.php +++ /dev/null @@ -1,43 +0,0 @@ - $link, - 'title' => JText::_('COM_CONTENTHISTORY_MODAL_TITLE'), - 'height' => '300px', - 'width' => '800px', - 'footer' => '' - ) -); -?> - - diff --git a/administrator/templates/isis/html/mod_version/default.php b/administrator/templates/isis/html/mod_version/default.php deleted file mode 100644 index b9faf4f17a2bb..0000000000000 --- a/administrator/templates/isis/html/mod_version/default.php +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/administrator/templates/isis/html/modules.php b/administrator/templates/isis/html/modules.php deleted file mode 100644 index efe75c238c0e0..0000000000000 --- a/administrator/templates/isis/html/modules.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * This gives template designers ultimate control over how modules are rendered. - * - * NOTICE: All chrome wrapping methods should be named: modChrome_{STYLE} and take the same - * two arguments. - */ - -/* - * Module chrome for rendering the module in a submenu - */ -function modChrome_title($module, &$params, &$attribs) -{ - if ($module->content) - { - echo '
          ' . $module->title . '
          '; - echo $module->content; - } -} - -function modChrome_no($module, &$params, &$attribs) -{ - if ($module->content) - { - echo $module->content; - } -} - -function modChrome_well($module, &$params, &$attribs) -{ - if ($module->content) - { - $moduleTag = $params->get('module_tag', 'div'); - $bootstrapSize = (int) $params->get('bootstrap_size'); - $moduleClass = $bootstrapSize ? ' span' . $bootstrapSize : ''; - $headerTag = htmlspecialchars($params->get('header_tag', 'h2'), ENT_COMPAT, 'UTF-8'); - - // Temporarily store header class in variable - $headerClass = $params->get('header_class'); - $headerClass = $headerClass ? ' ' . htmlspecialchars($headerClass, ENT_COMPAT, 'UTF-8') : ''; - - echo '<' . $moduleTag . ' class="well well-small' . $moduleClass . '">'; - - if ($module->showtitle) - { - echo '<' . $headerTag . ' class="module-title nav-header' . $headerClass . '">' . $module->title . ''; - } - - echo $module->content; - echo ''; - } -} diff --git a/administrator/templates/isis/html/pagination.php b/administrator/templates/isis/html/pagination.php deleted file mode 100644 index dbf4a2035d68e..0000000000000 --- a/administrator/templates/isis/html/pagination.php +++ /dev/null @@ -1,220 +0,0 @@ -base : integer - * $item->link : string - * $item->text : string - * - * pagination_item_inactive - * Input variable $item is an object with fields: - * $item->base : integer - * $item->link : string - * $item->text : string - * - * This gives template designers ultimate control over how pagination is rendered. - * - * NOTE: If you override pagination_item_active OR pagination_item_inactive you MUST override them both - */ - - -/** - * Renders the pagination list - * - * @param array $list Array containing pagination information - * - * @return string HTML markup for the full pagination object - * - * @since 3.0 - */ -function pagination_list_render($list) -{ - // Calculate to display range of pages - $currentPage = 1; - $range = 1; - $step = 5; - foreach ($list['pages'] as $k => $page) - { - if (!$page['active']) - { - $currentPage = $k; - } - } - if ($currentPage >= $step) - { - if ($currentPage % $step == 0) - { - $range = ceil($currentPage / $step) + 1; - } - else - { - $range = ceil($currentPage / $step); - } - } - - $html = '
            '; - $html .= $list['start']['data']; - $html .= $list['previous']['data']; - - foreach ($list['pages'] as $k => $page) - { - $html .= $page['data']; - } - - $html .= $list['next']['data']; - $html .= $list['end']['data']; - - $html .= '
          '; - return $html; -} - -/** - * Renders an active item in the pagination block - * - * @param JPaginationObject $item The current pagination object - * - * @return string HTML markup for active item - * - * @since 3.0 - */ -function pagination_item_active(&$item) -{ - $class = ''; - - // Check for "Start" item - if ($item->text == JText::_('JLIB_HTML_START')) - { - $display = ''; - } - - // Check for "Prev" item - if ($item->text == JText::_('JPREV')) - { - $item->text = JText::_('JPREVIOUS'); - $display = ''; - } - - // Check for "Next" item - if ($item->text == JText::_('JNEXT')) - { - $display = ''; - } - - // Check for "End" item - if ($item->text == JText::_('JLIB_HTML_END')) - { - $display = ''; - } - - // If the display object isn't set already, just render the item with its text - if (!isset($display)) - { - $display = $item->text; - $class = ' class="hidden-phone"'; - } - - if ($item->base > 0) - { - $limit = 'limitstart.value=' . $item->base; - } - else - { - $limit = 'limitstart.value=0'; - } - - $title = ''; - if (!is_numeric($item->text)) - { - JHtml::_('bootstrap.tooltip'); - $title = ' class="hasTooltip" title="' . $item->text . '"'; - } - - return '' . $display . ''; -} - -/** - * Renders an inactive item in the pagination block - * - * @param JPaginationObject $item The current pagination object - * - * @return string HTML markup for inactive item - * - * @since 3.0 - */ -function pagination_item_inactive(&$item) -{ - // Check for "Start" item - if ($item->text == JText::_('JLIB_HTML_START')) - { - return '
        • '; - } - - // Check for "Prev" item - if ($item->text == JText::_('JPREV')) - { - return '
        • '; - } - - // Check for "Next" item - if ($item->text == JText::_('JNEXT')) - { - return '
        • '; - } - - // Check for "End" item - if ($item->text == JText::_('JLIB_HTML_END')) - { - return '
        • '; - } - - // Check if the item is the active page - if (isset($item->active) && $item->active) - { - return '
        • ' . $item->text . '
        • '; - } - - // Doesn't match any other condition, render a normal item - return '
        • ' . $item->text . '
        • '; -} diff --git a/administrator/templates/isis/images/admin/blank.png b/administrator/templates/isis/images/admin/blank.png deleted file mode 100644 index 1797bf909a764..0000000000000 Binary files a/administrator/templates/isis/images/admin/blank.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/checked_out.png b/administrator/templates/isis/images/admin/checked_out.png deleted file mode 100644 index 6ad8f25ac9b91..0000000000000 Binary files a/administrator/templates/isis/images/admin/checked_out.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/collapseall.png b/administrator/templates/isis/images/admin/collapseall.png deleted file mode 100644 index a986d3b4fbfc5..0000000000000 Binary files a/administrator/templates/isis/images/admin/collapseall.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/disabled.png b/administrator/templates/isis/images/admin/disabled.png deleted file mode 100644 index 4c1f7c3b218f5..0000000000000 Binary files a/administrator/templates/isis/images/admin/disabled.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/downarrow-1.png b/administrator/templates/isis/images/admin/downarrow-1.png deleted file mode 100644 index c94074e5963e8..0000000000000 Binary files a/administrator/templates/isis/images/admin/downarrow-1.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/downarrow.png b/administrator/templates/isis/images/admin/downarrow.png deleted file mode 100644 index 69950e19d656c..0000000000000 Binary files a/administrator/templates/isis/images/admin/downarrow.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/downarrow0.png b/administrator/templates/isis/images/admin/downarrow0.png deleted file mode 100644 index 69950e19d656c..0000000000000 Binary files a/administrator/templates/isis/images/admin/downarrow0.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/expandall.png b/administrator/templates/isis/images/admin/expandall.png deleted file mode 100644 index 64b8c4b56915c..0000000000000 Binary files a/administrator/templates/isis/images/admin/expandall.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/featured.png b/administrator/templates/isis/images/admin/featured.png deleted file mode 100644 index e03064c7cf33e..0000000000000 Binary files a/administrator/templates/isis/images/admin/featured.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/filesave.png b/administrator/templates/isis/images/admin/filesave.png deleted file mode 100644 index 65a45b551ed04..0000000000000 Binary files a/administrator/templates/isis/images/admin/filesave.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/filter_16.png b/administrator/templates/isis/images/admin/filter_16.png deleted file mode 100644 index cbc62b7d30f78..0000000000000 Binary files a/administrator/templates/isis/images/admin/filter_16.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/icon-16-add.png b/administrator/templates/isis/images/admin/icon-16-add.png deleted file mode 100644 index 6e7aa02ab332c..0000000000000 Binary files a/administrator/templates/isis/images/admin/icon-16-add.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/icon-16-allow.png b/administrator/templates/isis/images/admin/icon-16-allow.png deleted file mode 100644 index d28a18b2f21e3..0000000000000 Binary files a/administrator/templates/isis/images/admin/icon-16-allow.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/icon-16-allowinactive.png b/administrator/templates/isis/images/admin/icon-16-allowinactive.png deleted file mode 100644 index d20e059da06b9..0000000000000 Binary files a/administrator/templates/isis/images/admin/icon-16-allowinactive.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/icon-16-deny.png b/administrator/templates/isis/images/admin/icon-16-deny.png deleted file mode 100644 index ebeb69cdf1c9a..0000000000000 Binary files a/administrator/templates/isis/images/admin/icon-16-deny.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/icon-16-denyinactive.png b/administrator/templates/isis/images/admin/icon-16-denyinactive.png deleted file mode 100644 index 0dc1b43e0fa08..0000000000000 Binary files a/administrator/templates/isis/images/admin/icon-16-denyinactive.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/icon-16-links.png b/administrator/templates/isis/images/admin/icon-16-links.png deleted file mode 100644 index 52b4cb434eb81..0000000000000 Binary files a/administrator/templates/isis/images/admin/icon-16-links.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/icon-16-notice-note.png b/administrator/templates/isis/images/admin/icon-16-notice-note.png deleted file mode 100644 index a207d70ae835c..0000000000000 Binary files a/administrator/templates/isis/images/admin/icon-16-notice-note.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/icon-16-protected.png b/administrator/templates/isis/images/admin/icon-16-protected.png deleted file mode 100644 index b72ad93568e40..0000000000000 Binary files a/administrator/templates/isis/images/admin/icon-16-protected.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/menu_divider.png b/administrator/templates/isis/images/admin/menu_divider.png deleted file mode 100644 index b4706b18b39f9..0000000000000 Binary files a/administrator/templates/isis/images/admin/menu_divider.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/note_add_16.png b/administrator/templates/isis/images/admin/note_add_16.png deleted file mode 100644 index 0acd4a592806b..0000000000000 Binary files a/administrator/templates/isis/images/admin/note_add_16.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/publish_g.png b/administrator/templates/isis/images/admin/publish_g.png deleted file mode 100644 index d3794988476dd..0000000000000 Binary files a/administrator/templates/isis/images/admin/publish_g.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/publish_r.png b/administrator/templates/isis/images/admin/publish_r.png deleted file mode 100644 index 1405a7900f5ee..0000000000000 Binary files a/administrator/templates/isis/images/admin/publish_r.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/publish_x.png b/administrator/templates/isis/images/admin/publish_x.png deleted file mode 100644 index 8719043981ae1..0000000000000 Binary files a/administrator/templates/isis/images/admin/publish_x.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/publish_y.png b/administrator/templates/isis/images/admin/publish_y.png deleted file mode 100644 index 75b0ddf9d75bb..0000000000000 Binary files a/administrator/templates/isis/images/admin/publish_y.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/sort_asc.png b/administrator/templates/isis/images/admin/sort_asc.png deleted file mode 100644 index 1204f31f50f22..0000000000000 Binary files a/administrator/templates/isis/images/admin/sort_asc.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/sort_desc.png b/administrator/templates/isis/images/admin/sort_desc.png deleted file mode 100644 index c0ca72e6c8f39..0000000000000 Binary files a/administrator/templates/isis/images/admin/sort_desc.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/tick.png b/administrator/templates/isis/images/admin/tick.png deleted file mode 100644 index 7cf3ad3ab29db..0000000000000 Binary files a/administrator/templates/isis/images/admin/tick.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/trash.png b/administrator/templates/isis/images/admin/trash.png deleted file mode 100644 index 9c100938a6604..0000000000000 Binary files a/administrator/templates/isis/images/admin/trash.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/uparrow-1.png b/administrator/templates/isis/images/admin/uparrow-1.png deleted file mode 100644 index 20175936c331c..0000000000000 Binary files a/administrator/templates/isis/images/admin/uparrow-1.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/uparrow.png b/administrator/templates/isis/images/admin/uparrow.png deleted file mode 100644 index b5b5beddd63b1..0000000000000 Binary files a/administrator/templates/isis/images/admin/uparrow.png and /dev/null differ diff --git a/administrator/templates/isis/images/admin/uparrow0.png b/administrator/templates/isis/images/admin/uparrow0.png deleted file mode 100644 index b5b5beddd63b1..0000000000000 Binary files a/administrator/templates/isis/images/admin/uparrow0.png and /dev/null differ diff --git a/administrator/templates/isis/images/emailButton.png b/administrator/templates/isis/images/emailButton.png deleted file mode 100644 index cd7ff64b8ac67..0000000000000 Binary files a/administrator/templates/isis/images/emailButton.png and /dev/null differ diff --git a/administrator/templates/isis/images/joomla.png b/administrator/templates/isis/images/joomla.png deleted file mode 100644 index 239f577864f24..0000000000000 Binary files a/administrator/templates/isis/images/joomla.png and /dev/null differ diff --git a/administrator/templates/isis/images/login-joomla-inverse.png b/administrator/templates/isis/images/login-joomla-inverse.png deleted file mode 100644 index 04050ad37e237..0000000000000 Binary files a/administrator/templates/isis/images/login-joomla-inverse.png and /dev/null differ diff --git a/administrator/templates/isis/images/login-joomla.png b/administrator/templates/isis/images/login-joomla.png deleted file mode 100644 index edd17ca9f7e40..0000000000000 Binary files a/administrator/templates/isis/images/login-joomla.png and /dev/null differ diff --git a/administrator/templates/isis/images/logo-inverse.png b/administrator/templates/isis/images/logo-inverse.png deleted file mode 100644 index 4e60f8676d2f3..0000000000000 Binary files a/administrator/templates/isis/images/logo-inverse.png and /dev/null differ diff --git a/administrator/templates/isis/images/logo.png b/administrator/templates/isis/images/logo.png deleted file mode 100644 index 8c1c265a194ab..0000000000000 Binary files a/administrator/templates/isis/images/logo.png and /dev/null differ diff --git a/administrator/templates/isis/images/pdf_button.png b/administrator/templates/isis/images/pdf_button.png deleted file mode 100644 index c4a1d044e2f1d..0000000000000 Binary files a/administrator/templates/isis/images/pdf_button.png and /dev/null differ diff --git a/administrator/templates/isis/images/printButton.png b/administrator/templates/isis/images/printButton.png deleted file mode 100644 index e56670c172f96..0000000000000 Binary files a/administrator/templates/isis/images/printButton.png and /dev/null differ diff --git a/administrator/templates/isis/img/glyphicons-halflings-white.png b/administrator/templates/isis/img/glyphicons-halflings-white.png deleted file mode 100644 index c1ab58151c472..0000000000000 Binary files a/administrator/templates/isis/img/glyphicons-halflings-white.png and /dev/null differ diff --git a/administrator/templates/isis/img/glyphicons-halflings.png b/administrator/templates/isis/img/glyphicons-halflings.png deleted file mode 100644 index f241c76f9adb7..0000000000000 Binary files a/administrator/templates/isis/img/glyphicons-halflings.png and /dev/null differ diff --git a/administrator/templates/isis/index.php b/administrator/templates/isis/index.php deleted file mode 100644 index a5f4f18a0e265..0000000000000 --- a/administrator/templates/isis/index.php +++ /dev/null @@ -1,338 +0,0 @@ -input; -$user = JFactory::getUser(); - -// Output as HTML5 -$this->setHtml5(true); - -// Gets the FrontEnd Main page Uri -$frontEndUri = JUri::getInstance(JUri::root()); -$frontEndUri->setScheme(((int) $app->get('force_ssl', 0) === 2) ? 'https' : 'http'); -$mainPageUri = $frontEndUri->toString(); - -// Add JavaScript Frameworks -JHtml::_('bootstrap.framework'); - -// Add filter polyfill for IE8 -JHtml::_('behavior.polyfill', array('filter'), 'lte IE 9'); - -// Add template js -JHtml::_('script', 'template.js', array('version' => 'auto', 'relative' => true)); - -// Add html5 shiv -JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); - -// Add Stylesheets -JHtml::_('stylesheet', 'template' . ($this->direction === 'rtl' ? '-rtl' : '') . '.css', array('version' => 'auto', 'relative' => true)); - -// Load specific language related CSS -JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); - -// Load custom.css -JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); - -JHtml::_('stylesheet', 'responsive.css', array('version' => 'auto', 'relative' => true)); - - -// Detecting Active Variables -$option = $input->get('option', ''); -$view = $input->get('view', ''); -$layout = $input->get('layout', ''); -$task = $input->get('task', ''); -$itemid = $input->get('Itemid', 0, 'int'); -$sitename = htmlspecialchars($app->get('sitename', ''), ENT_QUOTES, 'UTF-8'); -$cpanel = $option === 'com_cpanel'; - -$hidden = $app->input->get('hidemainmenu'); - -$showSubmenu = false; -$this->submenumodules = JModuleHelper::getModules('submenu'); - -foreach ($this->submenumodules as $submenumodule) -{ - $output = JModuleHelper::renderModule($submenumodule); - - if ($output !== '') - { - $showSubmenu = true; - break; - } -} - -// Template Parameters -$displayHeader = $this->params->get('displayHeader', '1'); -$statusFixed = $this->params->get('statusFixed', '1'); -$stickyToolbar = $this->params->get('stickyToolbar', '1'); - -// Header classes -$navbar_color = $this->params->get('templateColor') ?: ''; -$header_color = $displayHeader && $this->params->get('headerColor') ? $this->params->get('headerColor') : ''; -$navbar_is_light = $navbar_color && colorIsLight($navbar_color); -$header_is_light = $header_color && colorIsLight($header_color); - -if ($displayHeader) -{ - // Logo file - if ($this->params->get('logoFile')) - { - $logo = JUri::root() . $this->params->get('logoFile'); - } - else - { - $logo = $this->baseurl . '/templates/' . $this->template . '/images/logo' . ($header_is_light ? '-inverse' : '') . '.png'; - } -} - -function colorIsLight($color) -{ - $r = hexdec(substr($color, 1, 2)); - $g = hexdec(substr($color, 3, 2)); - $b = hexdec(substr($color, 5, 2)); - - $yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000; - - return $yiq >= 200; -} - -// Pass some values to javascript -$offset = 20; - -if ($displayHeader || !$statusFixed) -{ - $offset = 30; -} - -$stickyBar = 0; - -if ($stickyToolbar) -{ - $stickyBar = 'true'; -} - -// Template color -if ($navbar_color) -{ - $this->addStyleDeclaration(' - .navbar-inner, - .navbar-inverse .navbar-inner, - .dropdown-menu li > a:hover, - .dropdown-menu .active > a, - .dropdown-menu .active > a:hover, - .navbar-inverse .nav li.dropdown.open > .dropdown-toggle, - .navbar-inverse .nav li.dropdown.active > .dropdown-toggle, - .navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle, - #status.status-top { - background: ' . $navbar_color . '; - }'); -} - -// Template header color -if ($header_color) -{ - $this->addStyleDeclaration(' - .header { - background: ' . $header_color . '; - }'); -} - -// Sidebar background color -if ($this->params->get('sidebarColor')) -{ - $this->addStyleDeclaration(' - .nav-list > .active > a, - .nav-list > .active > a:hover { - background: ' . $this->params->get('sidebarColor') . '; - }'); -} - -// Link color -if ($this->params->get('linkColor')) -{ - $this->addStyleDeclaration(' - a, - .j-toggle-sidebar-button { - color: ' . $this->params->get('linkColor') . '; - }'); -} -?> - - - - - - - - - -
          - - - -
          - -
          - -
          -
          - -countModules('status')) : ?> - - - - - - - - -
          -
          -
          -
          -
          -
          - - - -
          -
          -
          -
          -
          - -
          - - -
          - - -
          -
          - - -
          - -
          - -
          -
          - -
          - - - -
          -
          - countModules('bottom')) : ?> - - - -
          - - countModules('status') || (!$statusFixed && $this->countModules('status'))) : ?> -
          -

          - - ©

          -
          - -
          -countModules('status')) : ?> - - - - - - - diff --git a/administrator/templates/isis/js/application.js b/administrator/templates/isis/js/application.js deleted file mode 100644 index 783c73edaf5b1..0000000000000 --- a/administrator/templates/isis/js/application.js +++ /dev/null @@ -1,7 +0,0 @@ -$('.dropdown-toggle').dropdown() -$('.collapse').collapse('show') -$('#myModal').modal('hide') -$('.typeahead').typeahead() -$('.tabs').button() -$('.tip').tooltip() -$(".alert-message").alert() \ No newline at end of file diff --git a/administrator/templates/isis/js/classes.js b/administrator/templates/isis/js/classes.js deleted file mode 100644 index 2f4677300e62b..0000000000000 --- a/administrator/templates/isis/js/classes.js +++ /dev/null @@ -1,45 +0,0 @@ -// Add classes - -window.onload=function() { -var input = document.getElementsByTagName("input"); -for (var i = 0; i < input.length; i++) { - if (input[i].className == 'button') { - input[i].className = 'btn btn-primary'; - } -} - -var button = document.getElementsByTagName("button"); -for (var i = 0; i < input.length; i++) { - if (button[i].className == 'button') { - button[i].className = 'btn btn-primary'; - } -} - -var p = document.getElementsByTagName("p"); -for (var i = 0; i < p.length; i++) { - if (p[i].className == 'readmore') { - p[i].className = 'btn'; - } -} - -var table = document.getElementsByTagName("table"); -for (var i = 0; i < table.length; i++) { - if (table[i].className == 'category') { - table[i].className = 'table table-striped'; - } -} - -var ul = document.getElementsByTagName("ul"); -for (var i = 0; i < ul.length; i++) { - if (ul[i].className == 'actions') { - ul[i].className = 'nav nav-pills'; - } -} - -var ul = document.getElementsByTagName("ul"); -for (var i = 0; i < ul.length; i++) { - if (ul[i].className == 'pagenav') { - ul[i].className = 'pagination'; - } -} -} \ No newline at end of file diff --git a/administrator/templates/isis/js/template.js b/administrator/templates/isis/js/template.js deleted file mode 100644 index 8a61f1a126269..0000000000000 --- a/administrator/templates/isis/js/template.js +++ /dev/null @@ -1,409 +0,0 @@ -/** - * @package Joomla.Administrator - * @subpackage Templates.isis - * @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. - * @license GNU General Public License version 2 or later; see LICENSE.txt - * @since 3.0 - */ - -(function($) -{ - $(document).ready(function() - { - var $w = $(window); - - $('*[rel=tooltip]').tooltip(); - - // Turn radios into btn-group - $('.radio.btn-group label').addClass('btn'); - - $('.btn-group label:not(.active)').click(function() - { - var label = $(this); - var input = $('#' + label.attr('for')); - - if (!input.prop('checked')) - { - label.closest('.btn-group').find('label').removeClass('active btn-success btn-danger btn-primary'); - - if (label.closest('.btn-group').hasClass('btn-group-reversed')) - { - if (input.val() == '') - { - label.addClass('active btn-primary'); - } - else if (input.val() == 0) - { - label.addClass('active btn-success'); - } - else - { - label.addClass('active btn-danger'); - } - } - else - { - if (input.val() == '') - { - label.addClass('active btn-primary'); - } - else if (input.val() == 0) - { - label.addClass('active btn-danger'); - } - else - { - label.addClass('active btn-success'); - } - - } - input.prop('checked', true); - input.trigger('change'); - } - }); - $('.btn-group input[checked=checked]').each(function() - { - var $self = $(this); - var attrId = $self.attr('id'); - - if ($self.parent().hasClass('btn-group-reversed')) - { - if ($self.val() == '') - { - $('label[for=' + attrId + ']').addClass('active btn-primary'); - } - else if ($self.val() == 0) - { - $('label[for=' + attrId + ']').addClass('active btn-success'); - } - else - { - $('label[for=' + attrId + ']').addClass('active btn-danger'); - } - } - else - { - if ($self.val() == '') - { - $('label[for=' + attrId + ']').addClass('active btn-primary'); - } - else if ($self.val() == 0) - { - $('label[for=' + attrId + ']').addClass('active btn-danger'); - } - else - { - $('label[for=' + attrId + ']').addClass('active btn-success'); - } - } - }); - // add color classes to chosen field based on value - $('select[class^="chzn-color"], select[class*=" chzn-color"]').on('liszt:ready', function(){ - var select = $(this); - var cls = this.className.replace(/^.(chzn-color[a-z0-9-_]*)$.*/, '\1'); - var container = select.next('.chzn-container').find('.chzn-single'); - container.addClass(cls).attr('rel', 'value_' + select.val()); - select.on('change click', function() - { - container.attr('rel', 'value_' + select.val()); - }); - - }); - - /** - * Append submenu items to empty UL on hover allowing a scrollable dropdown - */ - if ($w.width() > 767) - { - var menuScroll = $('#menu > li > ul'), - emptyMenu = $('#nav-empty'); - - $('#menu > li').on('click mouseenter', function() { - - // Set max-height (and width if scroll) for dropdown menu, depending of window height - var $dropdownMenu = $(this).children('ul'), - windowHeight = $w.height(), - linkHeight = $(this).outerHeight(true), - statusHeight = $('#status').outerHeight(true), - menuHeight = $dropdownMenu.height(), - menuOuterHeight = $dropdownMenu.outerHeight(true), - scrollMenuWidth = $dropdownMenu.width() + 15, - maxHeight = windowHeight - (linkHeight + statusHeight + (menuOuterHeight - menuHeight) + 20); - - if (maxHeight < menuHeight) - { - $dropdownMenu.css('width', scrollMenuWidth); - } - else if (maxHeight > menuHeight) - { - $dropdownMenu.css('width', 'auto'); - } - - $dropdownMenu.css('max-height', maxHeight); - - // Get the submenu position - linkWidth = $(this).outerWidth(true); - menuWidth = $dropdownMenu.width(); - linkPaddingLeft = $(this).children('a').css('padding-left'); - offsetLeft = Math.round($(this).offset().left) - parseInt(linkPaddingLeft); - - emptyMenu.empty().hide(); - - }); - - menuScroll.find('.dropdown-submenu > a').on('mouseover', function() { - - var $self = $(this), - dropdown = $self.next('ul'), - submenuWidth = dropdown.outerWidth(), - offsetTop = $self.offset().top, - linkPaddingTop = parseInt(dropdown.css('padding-top')) + parseInt($(this).css('padding-top')), - scroll = $w.scrollTop() + linkPaddingTop; - - // Set the submenu position - if ($('html').attr('dir') == 'rtl') - { - emptyMenu.css({ - top : offsetTop - scroll, - left: offsetLeft - (menuWidth - linkWidth) - submenuWidth - }); - } - else - { - emptyMenu.css({ - top : offsetTop - scroll, - left: offsetLeft + menuWidth - }); - } - - // Append items to empty
            and show it - dropdown.hide(); - emptyMenu.show().html(dropdown.html()); - - // Check if the full element is visible. If not, adjust the position - if (emptyMenu.Jvisible() !== true) - { - emptyMenu.css({ - top : ($w.height() - emptyMenu.outerHeight()) - $('#status').height() - }); - } - - }); - - menuScroll.find('a.no-dropdown').on('mouseenter', function() { - - emptyMenu.empty().hide(); - - }); - - // obtain a reference to the original handler - var _clearMenus = $._data(document, 'events').click.filter(function (el) { - return el.namespace === 'data-api.dropdown' && el.selector === undefined - })[0].handler; - - // disable the old listener - $(document) - .off('click.data-api.dropdown', _clearMenus) - .on('click.data-api.dropdown', function(e) { - e.button === 2 || _clearMenus(); - - if (!$('#menu').find('> li').hasClass('open')) - { - emptyMenu.empty().hide(); - } - }); - - $.fn.Jvisible = function(partial,hidden) - { - if (this.length < 1) - { - return; - } - - var $t = this.length > 1 ? this.eq(0) : this, - t = $t.get(0) - - var viewTop = $w.scrollTop(), - viewBottom = (viewTop + $w.height()) - $('#status').height(), - offset = $t.offset(), - _top = offset.top, - _bottom = _top + $t.height(), - compareTop = partial === true ? _bottom : _top, - compareBottom = partial === true ? _top : _bottom; - - return !!t.offsetWidth * t.offsetHeight && ((compareBottom <= viewBottom) && (compareTop >= viewTop)); - }; - - } - - - /** - * USED IN: All views with toolbar and sticky bar enabled - */ - var navTop; - var isFixed = false; - - - if (document.getElementById('isisJsData') && document.getElementById('isisJsData').getAttribute('data-tmpl-sticky') == "true") { - processScrollInit(); - processScroll(); - - $(window).on('resize', processScrollInit); - $(window).on('scroll', processScroll); - } - - function processScrollInit() { - if ($('.subhead').length) { - navTop = $('.subhead').length && $('.subhead').offset().top - parseInt(document.getElementById('isisJsData').getAttribute('data-tmpl-offset')); - - // Fix the container top - $(".container-main").css("top", $('.subhead').height() + $('nav.navbar').height()); - - // Only apply the scrollspy when the toolbar is not collapsed - if (document.body.clientWidth > 480) { - $('.subhead-collapse').height($('.subhead').height()); - $('.subhead').scrollspy({offset: {top: $('.subhead').offset().top - $('nav.navbar').height()}}); - } - } - } - - function processScroll() { - if ($('.subhead').length) { - var scrollTop = $(window).scrollTop(); - if (scrollTop >= navTop && !isFixed) { - isFixed = true; - $('.subhead').addClass('subhead-fixed'); - - // Fix the container top - $(".container-main").css("top", $('.subhead').height() + $('nav.navbar').height()); - } else if (scrollTop <= navTop && isFixed) { - isFixed = false; - $('.subhead').removeClass('subhead-fixed'); - } - } - } - - /** - * USED IN: All list views to hide/show the sidebar - */ - window.toggleSidebar = function(force) - { - var context = 'jsidebar'; - - var $sidebar = $('#j-sidebar-container'), - $main = $('#j-main-container'), - $message = $('#system-message-container'), - $debug = $('#system-debug'), - $toggleSidebarIcon = $('#j-toggle-sidebar-icon'), - $toggleButtonWrapper = $('#j-toggle-button-wrapper'), - $toggleButton = $('#j-toggle-sidebar-button'), - $sidebarToggle = $('#j-toggle-sidebar'); - - var openIcon = 'icon-arrow-left-2', - closedIcon = 'icon-arrow-right-2'; - - var $visible = $sidebarToggle.is(":visible"); - - if (jQuery(document.querySelector("html")).attr('dir') == 'rtl') - { - openIcon = 'icon-arrow-right-2'; - closedIcon = 'icon-arrow-left-2'; - } - - var isComponent = $('body').hasClass('component'); - - $sidebar.removeClass('span2').addClass('j-sidebar-container'); - $message.addClass('j-toggle-main'); - $main.addClass('j-toggle-main'); - if (!isComponent) { - $debug.addClass('j-toggle-main'); - } - - var mainHeight = $main.outerHeight()+30, - sidebarHeight = $sidebar.outerHeight(), - bodyWidth = $('body').outerWidth(), - sidebarWidth = $sidebar.outerWidth(), - contentWidth = $('#content').outerWidth(), - contentWidthRelative = contentWidth / bodyWidth * 100, - mainWidthRelative = (contentWidth - sidebarWidth) / bodyWidth * 100; - - if (force) - { - // Load the value from localStorage - if (typeof(Storage) !== "undefined") - { - $visible = localStorage.getItem(context); - } - - // Need to convert the value to a boolean - $visible = ($visible == 'true'); - } - else - { - $message.addClass('j-toggle-transition'); - $sidebar.addClass('j-toggle-transition'); - $toggleButtonWrapper.addClass('j-toggle-transition'); - $main.addClass('j-toggle-transition'); - if (!isComponent) { - $debug.addClass('j-toggle-transition'); - } - } - - if ($visible) - { - $sidebarToggle.hide(); - $sidebar.removeClass('j-sidebar-visible').addClass('j-sidebar-hidden'); - $toggleButtonWrapper.removeClass('j-toggle-visible').addClass('j-toggle-hidden'); - $toggleSidebarIcon.removeClass('j-toggle-visible').addClass('j-toggle-hidden'); - $message.removeClass('span10').addClass('span12'); - $main.removeClass('span10').addClass('span12 expanded'); - $toggleSidebarIcon.removeClass(openIcon).addClass(closedIcon); - $toggleButton.attr( 'data-original-title', Joomla.JText._('JTOGGLE_SHOW_SIDEBAR') ); - $toggleButton.attr( 'aria-label', Joomla.JText._('JTOGGLE_SHOW_SIDEBAR') ); - $sidebar.attr('aria-hidden', true); - $sidebar.find('a').attr('tabindex', '-1'); - $sidebar.find(':input').attr('tabindex', '-1'); - - if (!isComponent) { - $debug.css( 'width', contentWidthRelative + '%' ); - } - - if (typeof(Storage) !== "undefined") - { - // Set the last selection in localStorage - localStorage.setItem(context, true); - } - } - else - { - $sidebarToggle.show(); - $sidebar.removeClass('j-sidebar-hidden').addClass('j-sidebar-visible'); - $toggleButtonWrapper.removeClass('j-toggle-hidden').addClass('j-toggle-visible'); - $toggleSidebarIcon.removeClass('j-toggle-hidden').addClass('j-toggle-visible'); - $message.removeClass('span12').addClass('span10'); - $main.removeClass('span12 expanded').addClass('span10'); - $toggleSidebarIcon.removeClass(closedIcon).addClass(openIcon); - $toggleButton.attr( 'data-original-title', Joomla.JText._('JTOGGLE_HIDE_SIDEBAR') ); - $toggleButton.attr( 'aria-label', Joomla.JText._('JTOGGLE_HIDE_SIDEBAR') ); - $sidebar.removeAttr('aria-hidden'); - $sidebar.find('a').removeAttr('tabindex'); - $sidebar.find(':input').removeAttr('tabindex'); - - if (!isComponent && bodyWidth > 768 && mainHeight < sidebarHeight) - { - $debug.css( 'width', mainWidthRelative + '%' ); - } - else if (!isComponent) - { - $debug.css( 'width', contentWidthRelative + '%' ); - } - - if (typeof(Storage) !== "undefined") - { - // Set the last selection in localStorage - localStorage.setItem( context, false ); - } - } - } - }); -})(jQuery); diff --git a/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.ini b/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.ini deleted file mode 100644 index b41aba55b2f7e..0000000000000 --- a/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.ini +++ /dev/null @@ -1,43 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -ISIS="Isis Administrator template" -TPL_ISIS_CLEAR_CACHE="Clear Cache" -TPL_ISIS_COLOR_DESC="Choose a colour for the navigation bar." -TPL_ISIS_COLOR_HEADER_DESC="Choose a colour for the header." -TPL_ISIS_COLOR_HEADER_LABEL="Header Colour" -TPL_ISIS_COLOR_LABEL="Nav Bar Colour" -TPL_ISIS_COLOR_LOGIN_BACKGROUND_DESC="Choose a colour for the background of the login screen." -TPL_ISIS_COLOR_LOGIN_BACKGROUND_LABEL="Login Background Colour" -TPL_ISIS_COLOR_SIDEBAR_DESC="Choose a colour for the Sidebar Background." -TPL_ISIS_COLOR_SIDEBAR_LABEL="Sidebar Colour" -TPL_ISIS_COLOR_LINK_DESC="Choose a colour for the Link." -TPL_ISIS_COLOR_LINK_LABEL="Link Colour" -TPL_ISIS_CONTROL_PANEL="Control Panel" -TPL_ISIS_EDIT_ACCOUNT="Edit Account" -TPL_ISIS_FIELD_ADMIN_MENUS_DESC="If you intend to use Joomla Administrator on a monitor, set this to 'No'. It will prevent the collapse of the Administrator menus when reducing the width of the window. Default is 'Yes'." -TPL_ISIS_FIELD_ADMIN_MENUS_LABEL="Collapse Administrator Menu" -TPL_ISIS_HEADER_DESC="Optional display of header." -TPL_ISIS_HEADER_LABEL="Display Header" -TPL_ISIS_INSTALLER="Installer" -TPL_ISIS_ISFREESOFTWARE="Joomla is free software released under the GNU General Public License." -TPL_ISIS_LOGIN_LOGO_DESC="Select or upload a custom logo for the login area of administrator template." -TPL_ISIS_LOGIN_LOGO_LABEL="Login Logo" -TPL_ISIS_LOGO_DESC="Upload a custom logo for the administrator template." -TPL_ISIS_LOGO_LABEL="Logo" -TPL_ISIS_LOGOUT="Logout" -TPL_ISIS_PREVIEW="Preview %s" -TPL_ISIS_SKIP_TO_MAIN_CONTENT="Skip to Main Content" -TPL_ISIS_SKIP_TO_MAIN_CONTENT_HERE="Main content begins here" -TPL_ISIS_STATUS_BOTTOM="Fixed bottom" -TPL_ISIS_STATUS_DESC="Choose the location of the status module." -TPL_ISIS_STATUS_LABEL="Status Module Position" -TPL_ISIS_STATUS_TOP="Top" -TPL_ISIS_STICKY_DESC="Optionally set the toolbar to a fixed (pinned) location." -TPL_ISIS_STICKY_LABEL="Pinned Toolbar" -TPL_ISIS_TOGGLE_MENU="Toggle Navigation" -TPL_ISIS_TOOLBAR="Toolbar" -TPL_ISIS_USERMENU="User Menu" -TPL_ISIS_XML_DESCRIPTION="Continuing the Egyptian god/goddess theme (Khepri from 1.5 and Hathor from 1.6), Isis is the Joomla 3 administrator template based on Bootstrap and the launch of the Joomla User Interface library (JUI)." diff --git a/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.sys.ini b/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.sys.ini deleted file mode 100644 index fdc72b89c4aab..0000000000000 --- a/administrator/templates/isis/language/en-GB/en-GB.tpl_isis.sys.ini +++ /dev/null @@ -1,20 +0,0 @@ -; Joomla! Project -; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. -; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php -; Note : All ini files need to be saved as UTF-8 - -ISIS="Isis Administrator template" -TPL_ISIS_POSITION_BOTTOM="Bottom" -TPL_ISIS_POSITION_CPANEL="Cpanel" -TPL_ISIS_POSITION_CP_SHELL="Unused" -TPL_ISIS_POSITION_DEBUG="Debug" -TPL_ISIS_POSITION_FOOTER="Footer" -TPL_ISIS_POSITION_ICON="Quick Icons" -TPL_ISIS_POSITION_LOGIN="Login" -TPL_ISIS_POSITION_MENU="Menu" -TPL_ISIS_POSITION_POSTINSTALL="Postinstall" -TPL_ISIS_POSITION_STATUS="Status" -TPL_ISIS_POSITION_SUBMENU="Submenu" -TPL_ISIS_POSITION_TITLE="Title" -TPL_ISIS_POSITION_TOOLBAR="Toolbar" -TPL_ISIS_XML_DESCRIPTION="Continuing the Egyptian god/goddess theme (Khepri from 1.5 and Hathor from 1.6), Isis is the Joomla 3 administrator template based on Bootstrap and the launch of the Joomla User Interface library (JUI)." diff --git a/administrator/templates/isis/less/blocks/_chzn-override.less b/administrator/templates/isis/less/blocks/_chzn-override.less deleted file mode 100644 index 485771e94f026..0000000000000 --- a/administrator/templates/isis/less/blocks/_chzn-override.less +++ /dev/null @@ -1,201 +0,0 @@ -.chzn-container { - .chzn-drop { - border-radius: 0 0 3px 3px; - } -} - -// Fluid width -.control-group .chzn-container { - max-width: 100%; - .chzn-choices li.search-field, - .chzn-choices li.search-field input { // Fix for #13594 - width: 100% !important; - } -} - -.chzn-container-single { - .chzn-single { - background-color: @white; - background-clip: inherit; - background-image: none; - border: 1px solid @inputBorder; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 3px; - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 1px 2px rgba(0, 0, 0, 0.05); - height: auto; - line-height: 26px; - div { - background-color: @btnBackground; - border-left: 1px solid @inputBorder; - bottom: 0; - height: auto; - text-align: center; - width: 28px; - b { - background-image: none; - display: inline-block; - &:after { - content: '\E011'; - font-family: IcoMoon; - } - } - } - abbr { - background: none; - right: 36px; - top: 0; - &:before { - font-family: IcoMoon; - content: '\0049'; - font-size: 10px; - line-height: 26px; - } - &:hover { - color: #000; - } - } - } - .chzn-search { - &:after { - content: '\0053'; - font-family: IcoMoon; - position: relative; - right: 20px; - top: 2px; - } - input[type="text"] { - background: none; - border-radius: @inputBorderRadius; - border: 1px solid @inputBorder; - box-shadow: none; - height: 25px; - &:focus { - border-color: @inputBorderHighlight; - } - } - } - .chzn-drop { - background-clip: padding-box; - border-color: @inputBorderHighlight; - border-radius: 0 0 3px 3px; - } -} -.chzn-container-active { - .chzn-single { - color: @inputBorderHighlight; - } - &.chzn-with-drop { - .chzn-single { - background-image: none; - border: 1px solid @inputBorderHighlight; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - div { - background-color: @btnBackground; - border-bottom: 1px solid @inputBorder; - border-bottom-left-radius: @inputBorderRadius; - border-left: 1px solid @inputBorder; - b { - &:after { - content: '\E00F'; - font-family: IcoMoon; - } - } - } - } - } - &.chzn-container-multi { - .chzn-choices { - border: 1px solid @inputBorderHighlight; - box-shadow: none; - } - } -} -.chzn-container .chzn-results { - background-color: @white; - border-radius: 0 0 @inputBorderRadius @inputBorderRadius; - margin: 0; - padding: 0; - li.highlighted { - background-color: @inputBorderHighlight; - background-image: none; - } -} -.chzn-color[rel="value_"] div { - background-color: @btnBackground; - border-left: 1px solid @inputBorder; -} -.chzn-color-state.chzn-single, -.chzn-color.chzn-single[rel="value_0"], -.chzn-color.chzn-single[rel="value_1"], -.chzn-color-state.chzn-single[rel="value_-1"], -.chzn-color-state.chzn-single[rel="value_-2"], -.chzn-color.chzn-single[rel="value_hide"], -.chzn-color.chzn-single[rel="value_show_no_link"], -.chzn-color.chzn-single[rel="value_show_with_link"] { - div { - background-color: transparent !important; - border: none !important; - } -} -.chzn-container-active .chzn-choices { - border: 1px solid @inputBorderHighlight; -} -.chzn-container-multi { - .chzn-choices { - background-image: none; - border-radius: @inputBorderRadius; - border: 1px solid @inputBorder; - li.search-choice { - background-color: @inputBorderHighlight; - background-image: none; - border: 0; - box-shadow: none; - color: #fff; - line-height: 20px; - padding: 0 7px; - .search-choice-close { - color: #f5f5f5; - display: inline-block; - margin-left: 5px; - position: relative; - top: 0; - left: 0; - background-image: none; - font-size: inherit; - &:hover { - text-decoration: none; - } - &:before { - font-family: IcoMoon; - content: '\004A'; - position: relative; - right: 1px; - top: 0; - } - } - } - } -} -.js-stools .js-stools-container-bar .js-stools-field-filter .chzn-container { - margin: 1px 0; - padding: 0 !important; -} - -/* Chosen color styles */ -.chzn-color.chzn-single[rel="value_1"], -.chzn-color-reverse.chzn-single[rel="value_0"], -.chzn-color-state.chzn-single[rel="value_1"], -.chzn-color.chzn-single[rel="value_show_no_link"], -.chzn-color.chzn-single[rel="value_show_with_link"] { - .buttonBackground(@btnSuccessBackground, @btnSuccessBackgroundHighlight); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - color: #ffffff; -} - -.chzn-color-state.chzn-single[rel="value_0"], -.chzn-color-state.chzn-single[rel="value_-2"] { - .buttonBackground(@btnDangerBackground, @btnDangerBackgroundHighlight); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - color: #ffffff; -} diff --git a/administrator/templates/isis/less/blocks/_custom.less b/administrator/templates/isis/less/blocks/_custom.less deleted file mode 100644 index 3b0a369d3bae8..0000000000000 --- a/administrator/templates/isis/less/blocks/_custom.less +++ /dev/null @@ -1,294 +0,0 @@ -// Custom - -/* Links */ -.j-links-separator { - margin: 20px 0px; - width: 100%; - height: 0px; - border-top: 2px solid #DDDDDD; -} -/* Main Container & System Debug Padding */ -.container-main, -#system-debug { - padding-bottom: 50px; -} - -/* Pagination in toolbar */ -.pagination-toolbar { - margin: 0; -} - -.pagination-toolbar a { - line-height: 26px; -} -/* Toolbar dropdown */ -.pull-right > .dropdown-menu { - left: auto; - right: 0; -} - -/* Nav list filters */ -.nav-filters hr { - margin: 5px 0; -} -/* Module Assignment Tab */ -#assignment.tab-pane { - min-height: 500px; -} - -@media (max-width: @lg-max) { - .container-fluid { - padding-left: 10px; - padding-right: 10px; - } -} - -@media (min-width: @md) { - body { - padding-top: 30px; - } - - .nav-collapse.collapse.in { - height: auto !important; - } -} - -@media (max-width: @md-max) { - .container-fluid { - padding-left: 0; - padding-right: 0; - } -} - -@media (max-width: @sm-max) { - - .pagination a { - padding: 5px; - } - - .btn-group.divider, - .header .row-fluid .span3, - .header .row-fluid .span7 { - display: none; - } - - .btn-group + .btn-group { - margin-left: 10px; - } -} - -/* Extension type labels */ -.info-labels { - margin-top: -5px; - margin-bottom: 10px; -} - -/* Sortable list*/ -.sortable-handler.inactive { - opacity: 0.3; - filter: alpha(opacity=30); -} -/* Joomla and Extension update message */ -.alert-joomlaupdate { - text-align: center; - button { - vertical-align: baseline; - } -} -.j-jed-message { - line-height: 2em; - color:#333333; -} - -/* Flash uploader */ -.upload-queue > li > span, -.upload-queue > li > a { - margin: 0 2px; -} - -.upload-queue .file-remove { - float: right; -} -/* z-index issues */ -.moor-box { - z-index: 3; -} - -.admin .chzn-container .chzn-drop { - z-index: 1060; -} - -/* Item associations */ -.item-associations { - margin: 0; -} - -.item-associations li { - list-style: none; - display: inline-block; - margin: 0 0 3px 0; -} - -.item-associations li a { - color: #ffffff; -} - -/* Content Languages flag */ -#flag img { - padding-top: 6px; - vertical-align: top; -} -/* Tweaking of tooltips */ -.tooltip { - max-width: 400px; -} - -.tooltip-inner { - max-width: none; - text-align: left; - text-shadow: none; -} - -th .tooltip-inner { - font-weight: normal; -} - -.tooltip.hasimage { - opacity: 1; -} - -/* Permissions dropdown display */ -#permissions-sliders { - .chzn-container { - margin-top: -5px; - position: absolute; - } - .table td { - padding: 8px 8px 9px; - } -} - -.img-preview > img { - max-height: 100%; -} - -/* Help site refresh button*/ -#helpsite-refresh { - padding: 4px 12px; - vertical-align: top; -} -.alert-no-items { - margin-top: 20px; -} -@media (max-width: @md-max) { - html[dir=rtl] #toolbar #toolbar-options, - html[dir=rtl] #toolbar #toolbar-help, - #toolbar #toolbar-options, - #toolbar #toolbar-help { - float: none; - } -} - -/* Widen the drop downs for the Permissions Field */ -#permissions-sliders .input-small { - width: 120px; -} -.editor { - overflow: hidden; - position: relative -} - -.editor textarea.mce_editable { - box-sizing: border-box; -} -/* For grid.boolean */ -a.grid_false { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/publish_r.png'); -} - -a.grid_true { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/icon-16-allow.png'); -} - -/* Box-shadow from focused fields */ -textarea, input, .uneditable-input { - box-shadow: none !important; -} -textarea:focus, input:focus, .uneditable-input:focus { - box-shadow: none; - border: 1px solid @inputBorderHighlight; -} - -/* Stats plugin */ -.js-pstats-data-details dd { - margin-left: 240px; -} -.js-pstats-data-details dt { - width: 220px; -} - -/* ACL Permission page */ -#permissions, -#page-permissions { - table { - td { - vertical-align: middle; - } - select { - margin-bottom: 0; - } - } -} - -.js-stools-container-bar .btn-primary .caret { - border-bottom: 4px solid @white; -} - -.input-append .add-on, .input-append .btn, .input-append .btn-group > .dropdown-toggle, .input-prepend .add-on, .input-prepend .btn, .input-prepend .btn-group > .dropdown-toggle { - -webkit-border-radius: 0 @inputBorderRadius @inputBorderRadius 0; - -moz-border-radius: 0 @inputBorderRadius @inputBorderRadius 0; - border-radius: 0 @inputBorderRadius @inputBorderRadius 0; -} - -/* Removes Text Shadows */ -.alert, -.alert-options, -.badge, -.breadcrumb > li, -.close, -.input-append .add-on, -.input-prepend .add-on, -.label, -.nav-header, -.nav-list .nav-header, -.nav-list > .active > a, -.nav-list > .active > a:focus, -.nav-list > .active > a:hover, -.nav-list > li > a, -.nav-tabs.nav-dark, -.navbar .brand, -.navbar .nav > li > a, -.navbar-inverse .brand, -.navbar-inverse .nav > li > a, -.navbar-inverse .navbar-search .search-query.focused, -.navbar-inverse .navbar-search .search-query:focus, -.progress .bar, -.subhead { - text-shadow: none; -} - -/* Popover minimum height - overwrite bootstrap default */ -.popover-content { - min-height: 33px; -} - -/* Overrid font-weight 200 */ -.lead, .navbar .brand, .hero-unit, .hero-unit .lead { - font-weight: 400; -} \ No newline at end of file diff --git a/administrator/templates/isis/less/blocks/_editors.less b/administrator/templates/isis/less/blocks/_editors.less deleted file mode 100644 index 12877e145550d..0000000000000 --- a/administrator/templates/isis/less/blocks/_editors.less +++ /dev/null @@ -1,7 +0,0 @@ -// Editors - -.CodeMirror { - height: calc(~"100vh - 400px"); - min-height: 400px; - max-height: 800px; -} diff --git a/administrator/templates/isis/less/blocks/_forms.less b/administrator/templates/isis/less/blocks/_forms.less deleted file mode 100644 index 3a10120d0c102..0000000000000 --- a/administrator/templates/isis/less/blocks/_forms.less +++ /dev/null @@ -1,349 +0,0 @@ -// Forms - - -// Normalize LTR Label (JBS request) -// -------------------------- - -.form-horizontal { - // Float the labels left - .control-label { - padding-right: 5px; - text-align: left; - // Set a width for the spacer hr so it shows - .spacer hr { - width: 380px; - @media (max-width: 420px) { - width: 220px; - } - } - } - .field-spacer>.control-label{ - width: auto; - } - #jform_catid_chzn { - vertical-align: middle; - } -} - -.form-vertical { - .control-label { - > label { - display: inline-block; - .ie7-inline-block(); - } - } - .controls { - margin-left: 0; - } -} -@media (max-width: @lg-max) { - .form-horizontal-desktop { - .control-label { - float: none; - width: auto; - padding-right: 0; - padding-top: 0; - text-align: left; - > label { - display: inline-block; - .ie7-inline-block(); - } - } - .controls { - margin-left: 0; - } - } -} - -@media (max-width: @xl-max) { - .row-fluid .row-fluid .form-horizontal-desktop { - .control-label { - float: none; - width: auto; - padding-right: 0; - padding-top: 0; - text-align: left; - > label { - display: inline-block; - .ie7-inline-block(); - } - } - .controls { - margin-left: 0; - } - } -} - -.form-inline-header { - margin: 5px 0; - .control-group, - .control-label, - .controls { - display: inline-block; - .ie7-inline-block(); - } - .control-label { - width: auto; - padding-right: 10px; - } - .controls { - padding-right: 20px; - } -} -/* Make fieldsets responsive */ -fieldset[class^="form-"] { - min-width: 100%; -} -/* Make fieldsets responsive in Firefox. See http://getbootstrap.com/css/#tables-responsive */ -@-moz-document url-prefix() { - fieldset[class^="form-"] { display: table-cell; } -} - -/* Display checkboxes without bullets in list */ -fieldset.checkboxes input { - float: left; -} - -fieldset.checkboxes li { - list-style: none; -} - -/* Make form elements responsive */ -.control-group, -.controls, -.controls input[type="text"], -.controls input[type="number"], -.controls input[type="email"], -.controls select, -.controls textarea -{ - max-width: 100%; -} - -/* Min-width on buttons */ -.controls .btn-group > .btn { - min-width: 50px; - margin-left: -1px; -} - -.controls .btn-group.btn-group-yesno { - width: 220px; - max-width: 100%; - > .btn { - width: 50%; - min-width: 40px; - padding: 2px 0; - } -} - -/* Title field */ -input.input-large-text { - font-size: 18px; - line-height: 22px; - height: auto; -} - -/* Customize Textarea Resizing */ -textarea { - resize: both; -} - -textarea.vert { - resize: vertical; -} - -textarea.noResize { - resize: none; -} - -/* Repeatable SubForm */ -.subform-repeatable { - padding-right: 10px; - > .btn-toolbar { - margin: 0; - .group-add { - line-height: 26px; - width: 56px; - font-size: 13px; - margin-left: 28px; - } - } -} -.subform-repeatable-group { - margin-top: 20px; - margin-left: 28px; - border: 1px solid @inputBorder; - padding: 8px 25px 15px; - position: relative; - border-radius: @inputBorderRadius; - > .btn-toolbar { - margin: 0; - .btn-group { - margin-right: 0px; - margin-top: -1px; - position: static; - } - .btn { - font-size: 13px; - line-height: 26px; - background-color: #F3F3F3; - position: absolute; - span { - vertical-align: middle; - line-height: 11px; - } - &.btn-success { - color: #378137; - bottom: 0; - right: 0; - border-radius: @inputBorderRadius 0 0 0; - border-width: 1px 0 0 1px; - padding-top: 1px; - .icon-plus:before { - content: "]"; - } - } - &.btn-danger { - color: #942a25; - top: 0; - right: 0; - border-radius: 0 0 0 @inputBorderRadius; - border-width: 0 0 1px 1px; - .icon-minus:before { - content: "I"; - - } - } - &.btn-primary { - color: #24748c; - color: #333; - right: 100%; - top: 50%; - margin-top: -27px; - margin-right: 1px; - border-radius: @inputBorderRadius 0 0 @inputBorderRadius; - border-width: 1px 0 1px 1px; - line-height: 52px; - .icon-move:before { - content: "Z"; - } - } - [class^="icon-"], [class*=" icon-"] { - margin: 0; - } - &:hover { - background-color: #E6E6E6; - } - } - } - &:nth-child(odd) { - } - &:nth-child(even) { - } - &:last-of-type { - } - .control-group:last-of-type { - margin-bottom: 10px; - } -} -@media (max-width: @lg-max) { - .subform-repeatable-group > .btn-toolbar .btn-group { - margin-bottom: 10px; - } -} - -.subform-table-layout { - .control-group, .control-group:last-of-type { - margin-bottom: 0; - } - .controls { - padding-right: 20px; - } - .btn-group { - - } - input { - width: 100%; - max-width: 206px; - } - table .btn-group { - margin: 0 7px; - } -} -@media (max-width: 1024px) { - .subform-table-layout { - .subform-repeatable { - padding-right: 0; - tbody td:last-of-type { - text-align: right; - padding-bottom: 15px; - } - } - table, thead, tbody, th, td, tr { - display: block; - } - table { - border: 1px solid #ddd; - } - thead { - - th { - position: absolute; - top: -9999px; - left: -9999px; - &:last-of-type { - position: static; - width: 100% !important; - text-align: right; - box-sizing: border-box; - border-left: 0; - } - } - } - tr { - margin: 0; - padding: 0; - border: 0; - } - td { - border: none; - position: relative; - padding-left: 50%; - } - tbody { - td:first-of-type { - padding-top: 15px; - border-top: 1px solid #ddd; - &:before {top:18px;} - } - } - - td:before { - content: attr(data-column); - position: absolute; - top: 13px; - left: 10px; - padding-right: 10px; - } - } -} - -/* Remove unneeded space between label and field in vertical forms */ -.controls > .radio:first-child, -.controls > .checkbox:first-child { - padding-top: 0; - - .form-horizontal & { - padding-top: 5px; - } -} - -/* Align btn-group to label */ -.form-horizontal .controls > .radio.btn-group:first-child { - padding-top: 0; -} - -/* Align btn-group-yesno to label */ -.form-horizontal .controls > .radio.btn-group-yesno:first-child { - padding-top: 2px; -} diff --git a/administrator/templates/isis/less/blocks/_global.less b/administrator/templates/isis/less/blocks/_global.less deleted file mode 100644 index 614f734b2d3af..0000000000000 --- a/administrator/templates/isis/less/blocks/_global.less +++ /dev/null @@ -1,98 +0,0 @@ -// Global - -/* Body */ -html { - height: 100%; -} - -body { - height: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - box-sizing: border-box; -} - -a:hover, -a:active, -a:focus { - outline: none; -} - -/* Typography */ -.small { - font-size: 11px; -} - -.row-even .small, -.row-odd .small, -.row-even .small a, -.row-odd .small a { - color: #888; -} - -/* Page Title in Content */ -.content-title { - font-size: 24px; - font-weight: normal; - line-height: 26px; - margin-top: 0; -} - -/* Content */ -.well .page-header { - margin: -10px 0 18px 0; - padding-bottom: 5px; -} - -.well .module-title.nav-header { - padding: 0 0 7px; - margin: 0; - font-size: 13px; -} - -.well .row-even p, -.well .row-odd p { - margin-bottom: 0; -} - -/* Headings */ - -h1, h2, h3, h4, h5, h6 { - margin: (@baseLineHeight / 1.5) 0; -} - -h1 { - font-size: 26px; - line-height: 28px; -} - -h2 { - font-size: 22px; - line-height: 24px; -} - -h3 { - font-size: 18px; - line-height: 20px; -} - -h4 { - font-size: 14px; - line-height: 16px; -} - -h5 { - font-size: 13px; - line-height: 15px; -} - -h6 { - font-size: 12px; - line-height: 14px; -} - -.truncate { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} diff --git a/administrator/templates/isis/less/blocks/_header.less b/administrator/templates/isis/less/blocks/_header.less deleted file mode 100644 index 6d604a1ae88cf..0000000000000 --- a/administrator/templates/isis/less/blocks/_header.less +++ /dev/null @@ -1,68 +0,0 @@ -// header - -.header { - background-color: @headerBackground; - border-top: 1px solid rgba(255, 255, 255, 0.2); - padding: 8px 25px; -} - -@media (max-width: @md-max) { - .header { - padding: 4px 18px; - margin-left: -20px; - margin-right: -20px; - } -} - -.header .navbar-search { - margin-top: 0; -} - -@media (max-width: @lg-max) { - .header .navbar-search { - border-top: 0; - border-bottom: 0; - .box-shadow(none); - } -} - -/* Logo */ -.container-logo { - float: right; - text-align: right; -} - -.logo { - width: auto; - max-width: 100%; - max-height: 36px; - height: auto; -} - -/* Page Title */ -.page-title { - color: white; - font-weight: normal; - font-size: 20px; - line-height: 36px; - margin: 0; - [class^="icon-"], - [class*=" icon-"] { - margin-right: 16px; - } -} - -@media (max-width: @md-max) { - .container-logo { - display: none; - } - - .page-title { - font-size: 18px; - line-height: 28px; - [class^="icon-"], - [class*=" icon-"] { - margin-right: 10px; - } - } -} diff --git a/administrator/templates/isis/less/blocks/_login.less b/administrator/templates/isis/less/blocks/_login.less deleted file mode 100644 index 7f0c02aa8c857..0000000000000 --- a/administrator/templates/isis/less/blocks/_login.less +++ /dev/null @@ -1,87 +0,0 @@ -// Login - -.view-login { - background-color: @loginBackground; - padding-top: 0; - - .container { - width: 300px; - position: absolute; - top: 50%; - left: 50%; - margin-top: -206px; - margin-left: -150px; - } - .navbar-fixed-bottom { - padding-left: 20px; - padding-right: 20px; - text-align: center; - } - .navbar-fixed-bottom, - .navbar-fixed-bottom a { - color: #FCFCFC; - } - .navbar-inverse.navbar-fixed-bottom, - .navbar-inverse.navbar-fixed-bottom a { - color: @gray; - } - .well { - padding-bottom: 0; - } - .login-joomla { - position: absolute; - left: 50%; - height: 24px; - width: 24px; - margin-left: -12px; - font-size: 22px; - } - .navbar-fixed-bottom { - position: absolute; - } - .input-medium { - width: 176px; - } - #lang_chzn { - width: 233px !important; - max-width: none; - .chzn-single div { - width:43px; - } - } - .input-prepend .add-on, .controls .btn-group > .btn { - margin-left:0; - } -} - -.navbar-inverse { - color: @textColor; -} - -.login { - .btn-large { - margin-top: 15px; - } - .form-inline .btn-group { - display:block; - } -} - -@media (max-width: @sm-max) { - .login .chzn-single { - width: 222px !important; - } - - .login .chzn-container, - .login .chzn-drop { - width: 230px !important; - } -} - - -@media (max-width: @xs-max) { - .view-login .navbar-fixed-bottom { - display: none; - } - -} \ No newline at end of file diff --git a/administrator/templates/isis/less/blocks/_media.less b/administrator/templates/isis/less/blocks/_media.less deleted file mode 100644 index 8154a7c527117..0000000000000 --- a/administrator/templates/isis/less/blocks/_media.less +++ /dev/null @@ -1,263 +0,0 @@ -// Media - -/* Media Manager folder icon override */ -ul.manager .height-50 .icon-folder-2 { - height: 35px; - width: 35px; - line-height: 35px; - font-size: 30px; -} - -#imageForm { - margin: -25px 0 0; - .well { - margin-bottom: 5px; - } -} -.thumbnails-media { - @thumbSize:100px; - margin-left: 0; - .thumbnail { - background-color: #f4f4f4; - border-radius: @inputBorderRadius; - border: 0; - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05) inset; - padding: 0px; - height: @thumbSize; - width: @thumbSize; - margin: 8px 16px; - margin-left: 0 !important; - position: relative; - text-align: center; - overflow: hidden; - .close { - background-color: #ccc; - border-left: 1px solid rgba(0, 0, 0, 0.1); - height: 22px; - line-height: 22px; - opacity: 0.3; - text-align: center; - width: 22px; - top: 0; - right: 0; - &:hover { - background-color: #bbb; - } - } - *, *:before { - -webkit-transition: all 0.2s ease; - transition: all 0.2s ease; - -webkit-box-sizing: border-box; - box-sizing: border-box; - } - input[type="radio"], input[type="checkbox"] { - margin: 0; - opacity: 0.55; - position: absolute; - top: 5px; - left: 5px; - } - .controls, .imginfoBorder { - display: none; - } - } - .imgThumb { - position: relative; - z-index: 1; - width:100%; - display: inline-block; - input { - display: none; - } - label, .imgThumbInside { - display: block; - line-height: @thumbSize; - position: relative; - width: 100%; - border-radius: @inputBorderRadius; - overflow: hidden; - &:before { - font-family: "IcoMoon"; - font-style: normal; - content: 'G'; - position: absolute; - top: 0; - right: 0; - background-color: @btnSuccessBackground; - color: #fff; - line-height: 26px; - width: 26px; - -webkit-transform: scale(0.5); - transform: scale(0.5); - opacity: 0; - border-color: rgba(0, 0, 0, 0.2); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - border-radius: 0 @inputBorderRadius; - } - } - img { - width: auto; - } - } - .selected, .imgInput { - :checked + label, .imgThumbInside { - background-color: #ddd; - &:before { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 1; - } - &:after { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - content: ''; - border: 3px solid @btnSuccessBackground; - border-radius: 5px; - } - } - } - .imgDelete a.close, .imgPreview a { - padding: 0; - position: absolute; - left: 0; - z-index: 1; - height: 26px; - width: 26px; - } - .imgPreview a { - width: 100%; - } - .imgDelete a.close { - background-color: @btnDangerBackground; - border-color: @btnDangerBackground rgba(0, 0, 0, 0.2) rgba(0, 0, 0, 0.2) @btnDangerBackground; - top: 0; - line-height: 28px; - font-size: 12px; - padding-left: 1px; - color: #fff; - border-bottom-right-radius: @inputBorderRadius; - border-top-left-radius: @inputBorderRadius; - z-index: 10; - opacity: 0; - -webkit-transform: scale(0.5); - transform: scale(0.5); - &:hover { - background-color: darken(@btnDangerBackground, 15%); - } - } - .thumbnail:hover .imgDelete a.close { - opacity: 1; - -webkit-transform: scale(1); - transform: scale(1); - } - .imgPreview a, .imgDetails { - position: absolute; - left:0; - text-align: left; - background-color: #fff; - border-color: rgba(0, 0, 0, 0.2); - bottom: 0; - line-height: 26px; - border: 1px solid rgba(0, 0, 0, 0.1); - border-width: 1px; - border-radius: 0 @inputBorderRadius 0 0; - z-index: 1; - &:hover { - background-color: #eee; - } - } - .imgDetails { - padding: 0 5px; - line-height: 20px; - color: #555; - } - .imgFolder { - span { - line-height: 90px; - font-size: 38px; - margin: 0; - width: auto; - } - } - .imgFolder + .imgDetails { - color: inherit; - } -} - -// Media Manager -.com_media { - .media a + a { - margin-left: -1px; - } - .tree-holder { - padding: 0 15px; - } -} -#folderframe.thumbnail { - border: 0; - box-shadow: none; - padding: 0; -} -#mediamanager-form { - margin: 0 -10px; - > .muted { - padding: 0px; - } - .checkbox { - padding-left: 30px; - margin-bottom: 15px; - input { - margin-top: 3px; - } - } - .thumbnails { - .thumbnail { - height: 120px; - width: 120px; - margin: 0 18px 18px 0; - } - .imgThumb label, .imgTotal { - line-height: 120px; - } - } - .icon-search::before { - padding-right: 5px; - padding-left: 1px; - } - .height-50 { - background-color: #fafafa; - height: 77px; - position: relative; - z-index: 1; - width:100%; - display: inline-block; - a, .icon-folder-2 { - display: inline-block; - line-height: 75px; - margin-top: -1px; - } - a { - &:after { - bottom: 0; - box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08) inset; - content: ""; - display: block; - left: 0; - overflow: hidden; - position: absolute; - right: 0; - top: 0; - } - } - .icon-folder-2 { - font-size: 40px; - } - } -} - -.uploadform { - margin-top: 20px; -} diff --git a/administrator/templates/isis/less/blocks/_modals.less b/administrator/templates/isis/less/blocks/_modals.less deleted file mode 100644 index 18c3e3ea24395..0000000000000 --- a/administrator/templates/isis/less/blocks/_modals.less +++ /dev/null @@ -1,52 +0,0 @@ -// Modals - -body.modal-open { - -ms-overflow-style: none; -} - -.modal-header { - padding: 0 20px; - text-align: left; - h3 { - font-weight: normal; - line-height: 50px; - } - .close { - width: 50px; - margin-top: 0; - margin-right: -15px; - font-size: 2rem; - line-height: 50px; - border-left: 1px solid #ccc; - } -} - -.modal-body { - padding: 0; - width: 100%; - height: auto; - .container-fluid { - padding-top: 15px; - padding-bottom: 15px; - } -} - -.modal-footer { - clear: both; -} - -.contentpane { - padding: 10px; - height: auto -} - -@media (min-width: @md) { - .row-fluid .modal-batch [class*="span"] { - margin-left: 0; - } -} - -/* Component pop-up */ -.container-popup { - padding: 28px 10px 10px 10px; -} \ No newline at end of file diff --git a/administrator/templates/isis/less/blocks/_navbar.less b/administrator/templates/isis/less/blocks/_navbar.less deleted file mode 100644 index e6eece66a91e3..0000000000000 --- a/administrator/templates/isis/less/blocks/_navbar.less +++ /dev/null @@ -1,272 +0,0 @@ -// Navbar - -body .navbar, -body .navbar-fixed-top { - margin-bottom: 0; -} - -.navbar-inner { - min-height: 0; - background: @navbarBackground; - background-image: none; - filter: none; - .container-fluid { - padding-left: 10px; - padding-right: 10px; - font-size: 15px; - } -} - -.navbar-inverse { - .navbar-inner { - background: @navbarInverseBackground; - background-image: none; - filter: none; - } -} - -.navbar { - .navbar-text { - line-height: 30px; - } - .admin-logo { - float: left; - padding: 7px 12px 0px 15px; - font-size: 16px; - color: @gray; - &:hover { - color: @grayDark; - } - .navbar-inverse& { - color: #d9d9d9; - &:hover { - color: #ffffff; - } - } - } - .brand { - float: right; - display: block; - padding: 6px 10px; - margin-left: -20px; - font-size: inherit; - font-weight: normal; - &:hover, - &:focus { - text-decoration: none; - } - } - .nav > li > a { - padding: 6px 10px; - &:hover { - color: white; - } - &:hover span.carot { - border-bottom-color: #fff; - border-top-color: #fff; - } - } - .dropdown-menu, - .nav-user { - font-size: 13px; - } - .nav-user .dropdown-menu li span { - padding-left: 10px; - } - .nav > li ul { - overflow-y: auto; - overflow-x: hidden; - -webkit-overflow-scrolling: touch; - -moz-overflow-scrolling: touch; - -ms-overflow-scrolling: touch; - -o-overflow-scrolling: touch; - overflow-scrolling: touch; - height: auto; - max-height: 500px; - margin: 0; - &::-webkit-scrollbar { - -webkit-appearance: none; - width: 7px; - } - &::-webkit-scrollbar-thumb { - border-radius: 4px; - background-color: rgba(0,0,0,.5); - -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); - } - } - .nav > li > .dropdown-menu:after { - display: none; - } - .nav > .dropdown.open:after { - content: ''; - display: inline-block; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #fff; - position: absolute; - top: 25px; - left: 10px; - z-index: 1001; - } - .empty-nav { - display: none; - } -} - -.navbar-fixed-top, -.navbar-static-top { - .navbar-inner { - .box-shadow(none); - } -} -.dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus, .dropdown-submenu:hover > a, .dropdown-submenu:focus > a { - background-image: none; -} - -// Fixed to bottom -.navbar-fixed-bottom { - bottom: 0; - .navbar-inner { - .box-shadow(none); - } -} - -.navbar .btn-navbar { - background: #17568c; - border: 1px solid #0D2242; - margin-bottom: 2px; -} - -@media (max-width: @md-max) { - .navbar .admin-logo { - margin-left: 10px; - padding: 9px 9px 0 9px; - } -} - -/* Search Module */ -.navbar-search .search-query { - background: rgba(255, 255, 255, 0.3); -} - -@media (max-width: @lg-max) { - .navbar { - .nav { - font-size: 13px; - margin: 0 2px 0 0; - > li { - > a { - padding: 6px; - } - } - } - } -} - -@media (max-width: @md-max) { - .navbar-search.pull-right { - float: none; - text-align: center; - } -} - -@media (max-width: 738px) { - .navbar { - .brand { - font-size: 16px; - - } - } -} - -// Navbar -.nav-collapse .nav li a, -.dropdown-menu a { - background-image: none; -} - -.nav-collapse .dropdown-menu > li { - img { - max-width: none; - } -} - -@media (max-width: @navbarCollapseWidth) { - .navbar-fixed-top .navbar-inner, - .navbar-fixed-top .navbar-inner .container-fluid { - padding: 0; - } - - .navbar .brand { - margin-top: 2px; - float: none; - text-align: center; - } - - .navbar .btn-navbar { - margin-top: 3px; - margin-right: 3px; - margin-bottom: 3px; - } - - .nav-collapse .nav .nav-header { - color: @white; - } - - .nav-collapse .nav, - .navbar .nav-collapse .nav.pull-right { - margin: 0; - } - - .nav-collapse .dropdown-menu { - margin: 0; - } - - .nav-collapse .dropdown-menu > li > span { - display: block; - padding: 4px 15px; - } - - .navbar-inverse .nav-collapse .dropdown-menu > li > span { - color: @navbarInverseLinkColor; - } - - .nav-collapse .nav > li > a.dropdown-toggle { - background-color: rgba(255, 255, 255, 0.07); - font-size: 12px; - font-weight: bold; - color: @grayLighter; - text-transform: uppercase; - padding-left: 15px; - } - - .nav-collapse .nav li a { - margin-bottom: 0; - border-top: 1px solid rgba(255, 255, 255, 0.25); - border-bottom: 1px solid rgba(0, 0, 0, 0.5); - } - - .nav-collapse .nav li ul li ul.dropdown-menu, - .nav-collapse .nav li ul li:hover ul.dropdown-menu, - .nav-collapse .caret { - display: none !important; - } - - .nav-collapse .nav > li > a, - .nav-collapse .dropdown-menu a { - font-size: 15px; - font-weight: normal; - color: @white; - .border-radius(0); - } - - .navbar .nav-collapse .nav > li > .dropdown-menu::before, - .navbar .nav-collapse .nav > li > .dropdown-menu::after, - .navbar .nav-collapse .dropdown-submenu > a::after { - display: none; - } - - .nav-collapse .dropdown-menu li + li a { - margin-bottom: 0; - } -} \ No newline at end of file diff --git a/administrator/templates/isis/less/blocks/_quickicons.less b/administrator/templates/isis/less/blocks/_quickicons.less deleted file mode 100644 index 9843de842a1f0..0000000000000 --- a/administrator/templates/isis/less/blocks/_quickicons.less +++ /dev/null @@ -1,27 +0,0 @@ -// Quick-icons - -.quick-icons { - font-size: 14px; - margin-bottom: 20px; - .nav-header { - margin: 12px 0 5px; - font-size: 13px; - &:first-child { - margin: 0 0 5px; - } - } - [class^="icon-"], - [class*=" icon-"] { - margin-right: 9px; - &:before { - font-size: 16px; - margin-bottom: 20px; - line-height: 18px; - } - } -} - -html[dir=rtl] .quick-icons .nav-list [class^="icon-"], html[dir=rtl] .quick-icons .nav-list [class*=" icon-"] { - margin-left: 9px; - margin-right: 0; -} diff --git a/administrator/templates/isis/less/blocks/_sidebar.less b/administrator/templates/isis/less/blocks/_sidebar.less deleted file mode 100644 index d5fc72dee2a96..0000000000000 --- a/administrator/templates/isis/less/blocks/_sidebar.less +++ /dev/null @@ -1,150 +0,0 @@ -// Sidebar - -.sidebar-nav .nav-list { - padding-left: 25px; - padding-right: 25px; -} - -.sidebar-nav .nav-list > li > a { - color: #555; - padding: 3px 25px; - margin-left: -26px; - margin-right: -26px; -} - -.sidebar-nav .nav-list > li.active > a { - color: #fff; - margin-right: -26px; -} -.sidebar-nav .nav-list > li > a:focus, -.sidebar-nav .nav-list > li > a:hover { - text-decoration: none; - color: #fff; - background-color: #2d6ca2; - text-shadow: none; -} - -/* For collapsible sidebar */ -.j-sidebar-container { - position: absolute; - display: block; - left: -16.5%; - width: 16.5%; - margin: -18px 0 0 -1px; - padding-top: 28px; - padding-bottom: 40px; - clear: both; - background-color: @wellBackground; - border-bottom: 1px solid darken(@wellBackground, 7%); - border-right: 1px solid darken(@wellBackground, 7%); - .border-radius(0 0 @baseBorderRadius 0); - &.j-sidebar-hidden { - left: -16.5%; - } - &.j-sidebar-visible { - left: 0; - } - .filter-select { - padding: 0 14px; - } -} - -.j-toggle-sidebar-header { - h3 { - font-weight: normal; - padding: 0 15px; - } -} - -.j-toggle-button-wrapper { - position: absolute; - display: block; - top: 7px; - padding: 0; - &.j-toggle-hidden { - right: -24px; - } - &.j-toggle-visible { - right: 7px; - } -} - -.j-toggle-sidebar-button { - font-size: 16px; - color: @linkColor; - text-decoration: none; - cursor: pointer; - &:hover { - color: @linkColorHover; - } -} - -#system-message-container, -#j-main-container { - padding: 0 0 0 5px; - min-height: 0; -} - -#system-message-container.j-toggle-main, -#j-main-container.j-toggle-main, -#system-debug.j-toggle-main { - float: right; -} - -@media (min-width: @md) { - .j-toggle-transition { - .transition(all 0.3s ease); - } -} - -@media (max-width: @lg-max) { - .j-toggle-button-wrapper.j-toggle-hidden { - right: -20px; - } -} - -@media (max-width: @md-max) { - .j-sidebar-container { - position: relative; - width: 100%; - margin: 0 0 20px 0; - padding: 0; - background: transparent; - border-right: 0; - border-bottom: 0; - } - - .j-sidebar-container.j-sidebar-hidden { - margin-left: 16.5%; - } - - .j-sidebar-container.j-sidebar-visible { - margin-left: 0; - } - - .j-toggle-sidebar-header, - .j-toggle-button-wrapper { - display: none; - } - - .view-login { - select { - width: 232px; - } - } -} - -@media (max-width: 420px) { - .j-sidebar-container { - margin: 0; - } - - .view-login { - .input-medium { - width: 180px; - } - select { - width: 232px - } - } -} \ No newline at end of file diff --git a/administrator/templates/isis/less/blocks/_status.less b/administrator/templates/isis/less/blocks/_status.less deleted file mode 100644 index 11945092c300b..0000000000000 --- a/administrator/templates/isis/less/blocks/_status.less +++ /dev/null @@ -1,46 +0,0 @@ -// Status - -#status { - background: #ebebeb; - border-top: 1px solid #dedede; - padding: 4px 10px; - .box-shadow(~"0 0 3px rgba(0, 0, 0, 0.08)"); - color: #626262; - - .btn-group { - margin: 0; - } - .btn-group.separator:after { - content: ' '; - display: block; - float: left; - background: #ADADAD; - margin: 0 10px; - height: 15px; - width: 1px; - } - .btn-toolbar, p { - margin: 0px; - } - .btn-toolbar, .btn-group { - font-size: 12px; - } - a { - color: #626262; - } - .badge { - margin-right: .25em; - } -} -/* Status Module in top position */ -#status.status-top { - background: @headerBackground; - .box-shadow(~"0px 1px 0px rgba(255, 255, 255, 0.2) inset, 0px -1px 0px rgba(0, 0, 0, 0.3) inset, 0px -1px 0px rgba(0, 0, 0, 0.3)"); - border-top: 0; - color: @navbarInverseText; - padding: 2px 20px 6px 20px; - - a { - color: @navbarInverseLinkColor; - } -} \ No newline at end of file diff --git a/administrator/templates/isis/less/blocks/_tables.less b/administrator/templates/isis/less/blocks/_tables.less deleted file mode 100644 index 7ca893a5704b8..0000000000000 --- a/administrator/templates/isis/less/blocks/_tables.less +++ /dev/null @@ -1,74 +0,0 @@ -// Tables - -@media (max-width: @sm-max) { - - .pagination a { - padding: 5px; - } - - .btn-group.divider, - .header .row-fluid .span3, - .header .row-fluid .span7 { - display: none; - } - - .navbar .btn { - margin: 0; - } - - .btn-subhead { - display: block; - margin: 10px 0; - } - - .subhead-collapse.collapse { - height: 0; - overflow: hidden; - } - - .btn-toolbar .btn-wrapper { - display: block; - margin:0px 10px 5px 10px; - } - - .btn-toolbar .btn-wrapper .btn { - width: 100% !important; - } - - .subhead { - background: none repeat scroll 0 0 transparent; - border-bottom: 0 solid darken(@wellBackground, 7%); - } - - .btn-group + .btn-group { - margin-left: 10px; - } - - .login .chzn-single { - width: 222px !important; - } - - .login .chzn-container, - .login .chzn-drop { - width: 230px !important; - } - #toolbar [class^="icon-"], #toolbar [class*=" icon-"] { - background-color: transparent; - border-right: medium none; - width: 10px; - } -} - -/* Tables */ -table label { - margin: 0; -} - -td.has-context { - // Fixes difference in height between normal and hover on cell with context - height: 23px; -} - -td.nowrap.has-context { - width: 45%; -} \ No newline at end of file diff --git a/administrator/templates/isis/less/blocks/_toolbar.less b/administrator/templates/isis/less/blocks/_toolbar.less deleted file mode 100644 index 8d1f36170b118..0000000000000 --- a/administrator/templates/isis/less/blocks/_toolbar.less +++ /dev/null @@ -1,165 +0,0 @@ -// Toolbar - -/* Subhead */ -.subhead { - background: @wellBackground; - border-bottom: 1px solid darken(@wellBackground, 7%); - color: #0C192E; - text-shadow: 0 1px 0 #FFF; - margin-bottom: 10px; - min-height: 51px; -} - -.subhead-collapse { - margin-bottom: 19px; -} - -.subhead-collapse.collapse { - height: auto; - overflow: visible; -} - -.btn-toolbar { - margin-bottom: 5px; - .btn-wrapper { - display: inline-block; - margin: 0 0 8px 5px; - } -} - -.subhead-fixed { - position: fixed; - width: 100%; - top: 30px; - z-index: 100; -} -@media (max-width: @md-max) { - /* Fix ios scrolling inside bootstrap modals */ - body { - -webkit-overflow-scrolling: touch; - } - .subhead { - margin-left: -20px; - margin-right: -20px; - padding-left: 10px; - padding-right: 10px; - } -} - -.subhead h1 { - font-size: 17px; - font-weight: normal; - margin-left: 10px; - margin-top: 6px; -} - -/* Toolbar */ -#toolbar { - margin-bottom: 2px; - margin-top: 12px; - .btn { - line-height: 24px; - margin-right: 4px; - padding: 0 10px; - } - .btn-success { - min-width: 148px; - } - .btn-primary, - .btn-warning, - .btn-danger, - .btn-success, - .btn-info, - .btn-inverse { - [class^="icon-"], [class*=" icon-"] { - background-color: transparent; - border-right: 0; - border-left: 0; - width: 16px; - margin-left: 0; - margin-right: 0; - } - } - #toolbar-options, #toolbar-help { - float: right; - } - [class^="icon-"], [class*=" icon-"] { - background-color: @btnBackgroundHighlight; - border-radius: 3px 0 0 3px; - border-right: 1px solid @btnBorder; - height: auto; - line-height: inherit; - margin: 0 6px 0 -10px; - opacity: 1; - text-shadow: none; - width: 28px; - z-index: -1; - } - iframe .btn-group .btn { - margin-left: -1px !important; - } -} -html[dir=rtl] #toolbar #toolbar-options, -html[dir=rtl] #toolbar #toolbar-help { - float: left; -} - -@media (max-width: @md-max) { - .subhead-fixed { - position: static; - width: auto; - } -} - -/* Subhead (toolbar) Collapse Button */ -.btn-subhead { - display: none; -} -@media (min-width: @sm) { - #filter-bar { - // Fix for Firefox - height: 29px; - } -} - -@media (max-width: @sm-max) { - .navbar .btn { - margin: 0; - } - - .btn-subhead { - display: block; - margin: 10px 0; - } - - .subhead-collapse.collapse { - height: 0; - overflow: hidden; - } - - .btn-toolbar .btn-wrapper { - display: block; - margin:0px 10px 5px 10px; - } - - .btn-toolbar .btn-wrapper .btn { - width: 100% !important; - } - - .subhead { - background: none repeat scroll 0 0 transparent; - border-bottom: 0 solid darken(@wellBackground, 7%); - } - - #toolbar [class^="icon-"], #toolbar [class*=" icon-"] { - background-color: transparent; - border-right: medium none; - width: 10px; - } -} - -@media (max-width: @xs-max) { - .view-login .navbar-fixed-bottom { - display: none; - } -} diff --git a/administrator/templates/isis/less/blocks/_treeselect.less b/administrator/templates/isis/less/blocks/_treeselect.less deleted file mode 100644 index c3ee4b3617809..0000000000000 --- a/administrator/templates/isis/less/blocks/_treeselect.less +++ /dev/null @@ -1,85 +0,0 @@ -// Tree Select - -ul.treeselect, -ul.treeselect li { - margin: 0; - padding: 0; -} - -ul.treeselect { - margin-top: 8px; -} - -ul.treeselect li { - padding: 2px 10px 2px; - list-style: none; -} - -ul.treeselect i.treeselect-toggle { - line-height: 18px; -} - -ul.treeselect label { - font-size: 1em; - margin-left: 8px; -} - -ul.treeselect label.nav-header { - padding: 0; -} - -ul.treeselect input { - margin: 2px 0 0 8px; -} - -ul.treeselect .treeselect-menu { - margin: 0 6px; -} - -ul.treeselect ul.dropdown-menu { - margin: 0; -} - -ul.treeselect ul.dropdown-menu li { - padding: 0 5px; - border: none; -} - -.tree-holder { - .folder-url, .file { - position: relative; - background-color: #fefefe; - margin-bottom: 4px; - padding: 0 10px; - line-height: 32px; - border: 1px solid rgba(0, 0, 0, 0.08); - - } - .folder-url, .folder-url:hover, .folder-url:focus { - font-weight: bold; - background-color: #f5f5f5; - color: @linkColor; - } - .active { - background-color: @linkColor; - color: #fff; - box-shadow: -3px 0 0 #36a2ff !important; - &.folder-url { - background-color: #f5f5f5; - color: @linkColor; - } - &.file:hover { - background-color: #3071a9; - } - } - ul { - ul { - box-shadow: -3px 0 0 rgba(0, 0, 0, 0.08); - padding-right: 0; - .folder-url, .file { - box-shadow: -3px 0 0 @linkColor; - border-left: 0; - } - } - } -} diff --git a/administrator/templates/isis/less/blocks/_utility-classes.less b/administrator/templates/isis/less/blocks/_utility-classes.less deleted file mode 100644 index 72eb5dffcdad4..0000000000000 --- a/administrator/templates/isis/less/blocks/_utility-classes.less +++ /dev/null @@ -1,13 +0,0 @@ -// Utility Classes - -.break-word { - word-break: break-all; - word-wrap: break-word; -} - -.disabled { - cursor: default; - background-image: none; - .opacity(65); - .box-shadow(none); -} diff --git a/administrator/templates/isis/less/bootstrap/button-groups.less b/administrator/templates/isis/less/bootstrap/button-groups.less deleted file mode 100644 index c861628cddbdf..0000000000000 --- a/administrator/templates/isis/less/bootstrap/button-groups.less +++ /dev/null @@ -1,239 +0,0 @@ -// -// Button groups -// -------------------------------------------------- - - -// Make the div behave like a button -.btn-group { - position: relative; - display: inline-block; - .ie7-inline-block(); - font-size: 0; // remove as part 1 of font-size inline-block hack - vertical-align: middle; // match .btn alignment given font-size hack above - white-space: nowrap; // prevent buttons from wrapping when in tight spaces (e.g., the table on the tests page) - .ie7-restore-left-whitespace(); - .btn + .btn { - margin-left: -1px; - } -} - -// Space out series of button groups -.btn-group + .btn-group { - margin-left: 5px; -} - -// Optional: Group multiple button groups together for a toolbar -.btn-toolbar { - font-size: 0; // Hack to remove whitespace that results from using inline-block - margin-top: @baseLineHeight / 2; - margin-bottom: @baseLineHeight / 2; - > .btn + .btn, - > .btn-group + .btn, - > .btn + .btn-group { - margin-left: 5px; - } -} - -// Float them, remove border radius, then re-add to first and last elements -.btn-group > .btn { - position: relative; - .border-radius(0); -} -.btn-group > .btn + .btn { - // margin-left: -1px; -} -.btn-group > .btn-micro { - margin-left: -1px; -} -.btn-group > .btn, -.btn-group > .dropdown-menu, -.btn-group > .popover { - font-size: @baseFontSize; // redeclare as part 2 of font-size inline-block hack -} - -// Reset fonts for other sizes -.btn-group > .btn-mini { - font-size: @fontSizeMini; -} -.btn-group > .btn-small { - font-size: @fontSizeSmall; -} -.btn-group > .btn-large { - font-size: @fontSizeLarge; -} - -// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match -.btn-group > .btn:first-child { - margin-left: 0; - .border-top-left-radius(@baseBorderRadius); - .border-bottom-left-radius(@baseBorderRadius); -} -// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it -.btn-group > .btn:last-child, -.btn-group > .dropdown-toggle { - .border-top-right-radius(@baseBorderRadius); - .border-bottom-right-radius(@baseBorderRadius); -} -// Reset corners for large buttons -.btn-group > .btn.large:first-child { - margin-left: 0; - .border-top-left-radius(@borderRadiusLarge); - .border-bottom-left-radius(@borderRadiusLarge); -} -.btn-group > .btn.large:last-child, -.btn-group > .large.dropdown-toggle { - .border-top-right-radius(@borderRadiusLarge); - .border-bottom-right-radius(@borderRadiusLarge); -} - -// On hover/focus/active, bring the proper btn to front -.btn-group > .btn:hover, -.btn-group > .btn:focus, -.btn-group > .btn:active, -.btn-group > .btn.active { - z-index: 2; -} - -// On active and open, don't show outline -.btn-group .dropdown-toggle:active, -.btn-group.open .dropdown-toggle { - outline: 0; -} - - - -// Split button dropdowns -// ---------------------- - -// Give the line between buttons some depth -.btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; - *padding-top: 5px; - *padding-bottom: 5px; -} -.btn-group > .btn-mini + .dropdown-toggle { - padding-left: 5px; - padding-right: 5px; - *padding-top: 2px; - *padding-bottom: 2px; -} -.btn-group > .btn-small + .dropdown-toggle { - *padding-top: 5px; - *padding-bottom: 4px; -} -.btn-group > .btn-large + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; - *padding-top: 7px; - *padding-bottom: 7px; -} - -.btn-group.open { - - // The clickable button for toggling the menu - // Remove the gradient and set the same inset shadow as the :active state - .dropdown-toggle { - background-image: none; - } - - // Keep the hover's background when dropdown is open - .btn.dropdown-toggle { - background-color: @btnBackgroundHighlight; - } - .btn-primary.dropdown-toggle { - background-color: @btnPrimaryBackgroundHighlight; - } - .btn-warning.dropdown-toggle { - background-color: @btnWarningBackgroundHighlight; - } - .btn-danger.dropdown-toggle { - background-color: @btnDangerBackgroundHighlight; - } - .btn-success.dropdown-toggle { - background-color: @btnSuccessBackgroundHighlight; - } - .btn-info.dropdown-toggle { - background-color: @btnInfoBackgroundHighlight; - } - .btn-inverse.dropdown-toggle { - background-color: @btnInverseBackgroundHighlight; - } -} - - -// Reposition the caret -.btn .caret { - margin-top: 8px; - margin-left: 0; -} -// Carets in other button sizes -.btn-large .caret { - margin-top: 6px; -} -.btn-large .caret { - border-left-width: 5px; - border-right-width: 5px; - border-top-width: 5px; -} -.btn-mini .caret, -.btn-small .caret { - margin-top: 8px; -} -// Upside down carets for .dropup -.dropup .btn-large .caret { - border-bottom-width: 5px; -} - - - -// Account for other colors -.btn-primary { - .caret { - border-top-color: @linkColorHover; - border-bottom-color: @linkColorHover; - } -} -.btn-warning, -.btn-danger, -.btn-info, -.btn-success, -.btn-inverse { - .caret { - border-top-color: @white; - border-bottom-color: @white; - } -} - - - -// Vertical button groups -// ---------------------- - -.btn-group-vertical { - display: inline-block; // makes buttons only take up the width they need - .ie7-inline-block(); -} -.btn-group-vertical > .btn { - display: block; - float: none; - max-width: 100%; - .border-radius(0); -} -.btn-group-vertical > .btn + .btn { - margin-left: 0; - margin-top: -1px; -} -.btn-group-vertical > .btn:first-child { - .border-radius(@baseBorderRadius @baseBorderRadius 0 0); -} -.btn-group-vertical > .btn:last-child { - .border-radius(0 0 @baseBorderRadius @baseBorderRadius); -} -.btn-group-vertical > .btn-large:first-child { - .border-radius(@borderRadiusLarge @borderRadiusLarge 0 0); -} -.btn-group-vertical > .btn-large:last-child { - .border-radius(0 0 @borderRadiusLarge @borderRadiusLarge); -} - diff --git a/administrator/templates/isis/less/bootstrap/buttons.less b/administrator/templates/isis/less/bootstrap/buttons.less deleted file mode 100644 index 6ee0c6db06016..0000000000000 --- a/administrator/templates/isis/less/bootstrap/buttons.less +++ /dev/null @@ -1,285 +0,0 @@ -// -// Buttons -// -------------------------------------------------- - - -// Base styles -// -------------------------------------------------- - -// Core -.btn { - display: inline-block; - .ie7-inline-block(); - padding: 4px 12px; - margin-bottom: 0; // For input.btn - font-size: @baseFontSize; - line-height: @baseLineHeight; - text-align: center; - vertical-align: middle; - cursor: pointer; - background-color: @btnBackground; - color: #333; - // .buttonBackground(@btnBackground, @btnBackgroundHighlight, @grayDark, 0 1px 1px rgba(255,255,255,.75)); - border: 1px solid @btnBorder; - .border-radius(@baseBorderRadius); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); - &:hover, - &:focus { - background-color: @btnBackgroundHighlight; - text-decoration: none; - text-shadow: none; - } - - // Focus state for keyboard and accessibility - &:focus { - .tab-focus(); - } - - // Active state - &.active, - &:active { - background-image: none; - outline: 0; - // .box-shadow(~"inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05)"); - } - - // Disabled state - &.disabled, - &[disabled] { - cursor: default; - background-image: none; - .opacity(65); - .box-shadow(none); - } - -} - - - -// Button Sizes -// -------------------------------------------------- - -// Large -.btn-large { - padding: @paddingLarge; - font-size: @fontSizeLarge; - .border-radius(@borderRadiusLarge); -} -.btn-large [class^="icon-"], -.btn-large [class*=" icon-"] { - margin-top: 4px; -} - -// Small -.btn-small { - padding: @paddingSmall; - font-size: @fontSizeSmall; - .border-radius(@borderRadiusSmall); -} -.btn-small [class^="icon-"], -.btn-small [class*=" icon-"] { - margin-top: 0; -} -.btn-mini [class^="icon-"], -.btn-mini [class*=" icon-"] { - margin-top: -1px; -} - -// Mini -.btn-mini { - padding: @paddingMini; - font-size: @fontSizeMini; - .border-radius(@borderRadiusSmall); -} - - -// Block button -// ------------------------- - -.btn-block { - display: block; - width: 100%; - padding-left: 0; - padding-right: 0; - .box-sizing(border-box); -} - -// Vertically space out multiple block buttons -.btn-block + .btn-block { - margin-top: 5px; -} - -// Specificity overrides -input[type="submit"], -input[type="reset"], -input[type="button"] { - &.btn-block { - width: 100%; - } -} - - - -// Alternate buttons -// -------------------------------------------------- - -.btn-primary, -.btn-warning, -.btn-danger, -.btn-success, -.btn-info, -.btn-inverse { - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); -} - -// Provide *some* extra contrast for those who can get it -.btn-primary.active, -.btn-warning.active, -.btn-danger.active, -.btn-success.active, -.btn-info.active, -.btn-inverse.active { - // color: rgba(255,255,255,.75); -} - -// Set the backgrounds -// ------------------------- -.btn-primary { - border: 1px solid @btnPrimaryBackgroundHighlight; - border: 1px solid rgba(0, 0, 0, 0.2); - color: #fff; - background-color: @btnPrimaryBackground; - &:hover, - &:focus { - background-color: darken(@btnPrimaryBackground, 15%); - color: #fff; - text-decoration: none; - } -} -// Warning appears are orange -.btn-warning { - border: 1px solid @btnWarningBackground; - border: 1px solid rgba(0, 0, 0, 0.2); - color: #fff; - background-color: @btnWarningBackground; - &:hover, - &:focus { - background-color: darken(@btnWarningBackground, 15%); - color: #fff; - text-decoration: none; - text-shadow: none; - } -} -// Danger and error appear as red -.btn-danger { - border: 1px solid @btnDangerBackground; - border: 1px solid rgba(0, 0, 0, 0.2); - color: #fff; - background-color: @btnDangerBackground; - &:hover, - &:focus { - background-color: darken(@btnDangerBackground, 15%); - color: #fff; - text-decoration: none; - } -} -// Success appears as green -.btn-success { - border: 1px solid @btnSuccessBackgroundHighlight; - border: 1px solid rgba(0, 0, 0, 0.2); - color: #fff; - background-color: @btnSuccessBackground; - &:hover, - &:focus { - background-color: darken(@btnSuccessBackground, 15%); - color: #fff; - text-decoration: none; - } -} -// Info appears as a neutral blue -.btn-info { - border: 1px solid @btnInfoBackground; - border: 1px solid rgba(0, 0, 0, 0.2); - color: #fff; - background-color: @btnInfoBackground; - &:hover, - &:focus { - background-color: darken(@btnInfoBackground, 15%); - color: #fff; - text-decoration: none; - } -} -// Inverse appears as dark gray -.btn-inverse { - border: 1px solid @btnInverseBackground; - border: 1px solid rgba(0, 0, 0, 0.2); - color: #fff; - background-color: @btnInverseBackground; - &:hover, - &:focus { - background-color: darken(@btnInverseBackground, 15%); - color: #fff; - text-decoration: none; - } -} - - -// Cross-browser Jank -// -------------------------------------------------- - -button.btn, -input[type="submit"].btn { - - // Firefox 3.6 only I believe - &::-moz-focus-inner { - padding: 0; - border: 0; - } - - // IE7 has some default padding on button controls - *padding-top: 3px; - *padding-bottom: 3px; - - &.btn-large { - *padding-top: 7px; - *padding-bottom: 7px; - } - &.btn-small { - *padding-top: 3px; - *padding-bottom: 3px; - } - &.btn-mini { - *padding-top: 1px; - *padding-bottom: 1px; - } -} - - -// Link buttons -// -------------------------------------------------- - -// Make a button look and behave like a link -.btn-link, -.btn-link:active, -.btn-link[disabled] { - background-color: transparent; - background-image: none; - .box-shadow(none); -} -.btn-link { - border-color: transparent; - cursor: pointer; - color: @linkColor; - .border-radius(0); -} -.btn-link:hover, -.btn-link:focus { - color: @linkColorHover; - text-decoration: underline; - background-color: transparent; -} -.btn-link[disabled]:hover, -.btn-link[disabled]:focus { - color: @grayDark; - text-decoration: none; -} diff --git a/administrator/templates/isis/less/bootstrap/mixins.less b/administrator/templates/isis/less/bootstrap/mixins.less deleted file mode 100644 index 5ecf2cea980b7..0000000000000 --- a/administrator/templates/isis/less/bootstrap/mixins.less +++ /dev/null @@ -1,708 +0,0 @@ -// -// Mixins -// -------------------------------------------------- - - -// UTILITY MIXINS -// -------------------------------------------------- - -// Clearfix -// -------- -// For clearing floats like a boss h5bp.com/q -.clearfix { - *zoom: 1; - &:before, - &:after { - display: table; - content: ""; - // Fixes Opera/contenteditable bug: - // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952 - line-height: 0; - } - &:after { - clear: both; - } -} - -// Webkit-style focus -// ------------------ -.tab-focus() { - // Default - outline: thin dotted #333; - // Webkit - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} - -// Center-align a block level element -// ---------------------------------- -.center-block() { - display: block; - margin-left: auto; - margin-right: auto; -} - -// IE7 inline-block -// ---------------- -.ie7-inline-block() { - *display: inline; /* IE7 inline-block hack */ - *zoom: 1; -} - -// IE7 likes to collapse whitespace on either side of the inline-block elements. -// Ems because we're attempting to match the width of a space character. Left -// version is for form buttons, which typically come after other elements, and -// right version is for icons, which come before. Applying both is ok, but it will -// mean that space between those elements will be .6em (~2 space characters) in IE7, -// instead of the 1 space in other browsers. -.ie7-restore-left-whitespace() { - *margin-left: .3em; - - &:first-child { - *margin-left: 0; - } -} - -.ie7-restore-right-whitespace() { - *margin-right: .3em; -} - -// Sizing shortcuts -// ------------------------- -.size(@height, @width) { - width: @width; - height: @height; -} -.square(@size) { - .size(@size, @size); -} - -// Placeholder text -// ------------------------- -.placeholder(@color: @placeholderText) { - &:-moz-placeholder { - color: @color; - } - &:-ms-input-placeholder { - color: @color; - } - &::-webkit-input-placeholder { - color: @color; - } -} - -// Text overflow -// ------------------------- -// Requires inline-block or block for proper styling -.text-overflow() { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -// CSS image replacement -// ------------------------- -// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 -.hide-text { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - - -// FONTS -// -------------------------------------------------- - -#font { - #family { - .serif() { - font-family: @serifFontFamily; - } - .sans-serif() { - font-family: @sansFontFamily; - } - .monospace() { - font-family: @monoFontFamily; - } - } - .shorthand(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { - font-size: @size; - font-weight: @weight; - line-height: @lineHeight; - } - .serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { - #font > #family > .serif; - #font > .shorthand(@size, @weight, @lineHeight); - } - .sans-serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { - #font > #family > .sans-serif; - #font > .shorthand(@size, @weight, @lineHeight); - } - .monospace(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { - #font > #family > .monospace; - #font > .shorthand(@size, @weight, @lineHeight); - } -} - - -// FORMS -// -------------------------------------------------- - -// Block level inputs -.input-block-level { - display: block; - width: 100%; - min-height: @inputHeight; // Make inputs at least the height of their button counterpart (base line-height + padding + border) - .box-sizing(border-box); // Makes inputs behave like true block-level elements -} - - - -// Mixin for form field states -.formFieldState(@textColor: #555, @borderColor: #ccc, @backgroundColor: #f5f5f5) { - // Set the text color - .control-label, - .help-block, - .help-inline { - color: @textColor; - } - // Style inputs accordingly - .checkbox, - .radio, - input, - select, - textarea { - color: @textColor; - } - input, - select, - textarea { - border-color: @borderColor; - //.box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work - &:focus { - border-color: darken(@borderColor, 10%); - @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@borderColor, 20%); - //.box-shadow(@shadow); - } - } - // Give a small background color for input-prepend/-append - .input-prepend .add-on, - .input-append .add-on { - color: @textColor; - background-color: @backgroundColor; - border-color: @textColor; - } -} - - - -// CSS3 PROPERTIES -// -------------------------------------------------- - -// Border Radius -.border-radius(@radius) { - -webkit-border-radius: @radius; - -moz-border-radius: @radius; - border-radius: @radius; -} - -// Single Corner Border Radius -.border-top-left-radius(@radius) { - -webkit-border-top-left-radius: @radius; - -moz-border-radius-topleft: @radius; - border-top-left-radius: @radius; -} -.border-top-right-radius(@radius) { - -webkit-border-top-right-radius: @radius; - -moz-border-radius-topright: @radius; - border-top-right-radius: @radius; -} -.border-bottom-right-radius(@radius) { - -webkit-border-bottom-right-radius: @radius; - -moz-border-radius-bottomright: @radius; - border-bottom-right-radius: @radius; -} -.border-bottom-left-radius(@radius) { - -webkit-border-bottom-left-radius: @radius; - -moz-border-radius-bottomleft: @radius; - border-bottom-left-radius: @radius; -} - -// Single Side Border Radius -.border-top-radius(@radius) { - .border-top-right-radius(@radius); - .border-top-left-radius(@radius); -} -.border-right-radius(@radius) { - .border-top-right-radius(@radius); - .border-bottom-right-radius(@radius); -} -.border-bottom-radius(@radius) { - .border-bottom-right-radius(@radius); - .border-bottom-left-radius(@radius); -} -.border-left-radius(@radius) { - .border-top-left-radius(@radius); - .border-bottom-left-radius(@radius); -} - -// Drop shadows -.box-shadow(@shadow) { - -webkit-box-shadow: @shadow; - -moz-box-shadow: @shadow; - box-shadow: @shadow; -} - -// Transitions -.transition(@transition) { - -webkit-transition: @transition; - -moz-transition: @transition; - -o-transition: @transition; - transition: @transition; -} -.transition-delay(@transition-delay) { - -webkit-transition-delay: @transition-delay; - -moz-transition-delay: @transition-delay; - -o-transition-delay: @transition-delay; - transition-delay: @transition-delay; -} -.transition-duration(@transition-duration) { - -webkit-transition-duration: @transition-duration; - -moz-transition-duration: @transition-duration; - -o-transition-duration: @transition-duration; - transition-duration: @transition-duration; -} - -// Transformations -.rotate(@degrees) { - -webkit-transform: rotate(@degrees); - -moz-transform: rotate(@degrees); - -ms-transform: rotate(@degrees); - -o-transform: rotate(@degrees); - transform: rotate(@degrees); -} -.scale(@ratio) { - -webkit-transform: scale(@ratio); - -moz-transform: scale(@ratio); - -ms-transform: scale(@ratio); - -o-transform: scale(@ratio); - transform: scale(@ratio); -} -.translate(@x, @y) { - -webkit-transform: translate(@x, @y); - -moz-transform: translate(@x, @y); - -ms-transform: translate(@x, @y); - -o-transform: translate(@x, @y); - transform: translate(@x, @y); -} -.skew(@x, @y) { - -webkit-transform: skew(@x, @y); - -moz-transform: skew(@x, @y); - -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twitter/bootstrap/issues/4885 - -o-transform: skew(@x, @y); - transform: skew(@x, @y); - -webkit-backface-visibility: hidden; // See https://github.com/twitter/bootstrap/issues/5319 -} -.translate3d(@x, @y, @z) { - -webkit-transform: translate3d(@x, @y, @z); - -moz-transform: translate3d(@x, @y, @z); - -o-transform: translate3d(@x, @y, @z); - transform: translate3d(@x, @y, @z); -} - -// Backface visibility -// Prevent browsers from flickering when using CSS 3D transforms. -// Default value is `visible`, but can be changed to `hidden -// See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples -.backface-visibility(@visibility){ - -webkit-backface-visibility: @visibility; - -moz-backface-visibility: @visibility; - backface-visibility: @visibility; -} - -// Background clipping -// Heads up: FF 3.6 and under need "padding" instead of "padding-box" -.background-clip(@clip) { - -webkit-background-clip: @clip; - -moz-background-clip: @clip; - background-clip: @clip; -} - -// Background sizing -.background-size(@size) { - -webkit-background-size: @size; - -moz-background-size: @size; - -o-background-size: @size; - background-size: @size; -} - - -// Box sizing -.box-sizing(@boxmodel) { - -webkit-box-sizing: @boxmodel; - -moz-box-sizing: @boxmodel; - box-sizing: @boxmodel; -} - -// User select -// For selecting text on the page -.user-select(@select) { - -webkit-user-select: @select; - -moz-user-select: @select; - -ms-user-select: @select; - -o-user-select: @select; - user-select: @select; -} - -// Resize anything -.resizable(@direction) { - resize: @direction; // Options: horizontal, vertical, both - overflow: auto; // Safari fix -} - -// CSS3 Content Columns -.content-columns(@columnCount, @columnGap: @gridGutterWidth) { - -webkit-column-count: @columnCount; - -moz-column-count: @columnCount; - column-count: @columnCount; - -webkit-column-gap: @columnGap; - -moz-column-gap: @columnGap; - column-gap: @columnGap; -} - -// Optional hyphenation -.hyphens(@mode: auto) { - word-wrap: break-word; - -webkit-hyphens: @mode; - -moz-hyphens: @mode; - -ms-hyphens: @mode; - -o-hyphens: @mode; - hyphens: @mode; -} - -// Opacity -.opacity(@opacity) { - opacity: @opacity / 100; - filter: ~"alpha(opacity=@{opacity})"; -} - - - -// BACKGROUNDS -// -------------------------------------------------- - -// Add an alphatransparency value to any background or border color (via Elyse Holladay) -#translucent { - .background(@color: @white, @alpha: 1) { - background-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha); - } - .border(@color: @white, @alpha: 1) { - border-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha); - .background-clip(padding-box); - } -} - -// Gradient Bar Colors for buttons and alerts -.gradientBar(@primaryColor, @secondaryColor, @textColor: #fff, @textShadow: 0 -1px 0 rgba(0,0,0,.25)) { - color: @textColor; - text-shadow: @textShadow; - #gradient > .vertical(@primaryColor, @secondaryColor); - border-color: @secondaryColor @secondaryColor darken(@secondaryColor, 15%); - // No idea why this is here, as it makes the border grey instead of the given colors - // border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%); -} - -// Gradients -#gradient { - .horizontal(@startColor: #555, @endColor: #333) { - background-color: @endColor; - background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 100% 0, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(left, @startColor, @endColor); // Opera 11.10 - background-image: linear-gradient(to right, @startColor, @endColor); // Standard, IE10 - background-repeat: repeat-x; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@startColor),argb(@endColor))); // IE9 and down - } - .vertical(@startColor: #555, @endColor: #333) { - background-color: mix(@startColor, @endColor, 60%); - background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10 - background-image: linear-gradient(to bottom, @startColor, @endColor); // Standard, IE10 - background-repeat: repeat-x; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down - } - .directional(@startColor: #555, @endColor: #333, @deg: 45deg) { - background-color: @endColor; - background-repeat: repeat-x; - background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+ - background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(@deg, @startColor, @endColor); // Opera 11.10 - background-image: linear-gradient(@deg, @startColor, @endColor); // Standard, IE10 - } - .horizontal-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) { - background-color: mix(@midColor, @endColor, 80%); - background-image: -webkit-gradient(left, linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor)); - background-image: -webkit-linear-gradient(left, @startColor, @midColor @colorStop, @endColor); - background-image: -moz-linear-gradient(left, @startColor, @midColor @colorStop, @endColor); - background-image: -o-linear-gradient(left, @startColor, @midColor @colorStop, @endColor); - background-image: linear-gradient(to right, @startColor, @midColor @colorStop, @endColor); - background-repeat: no-repeat; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down, gets no color-stop at all for proper fallback - } - - .vertical-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) { - background-color: mix(@midColor, @endColor, 80%); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor)); - background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor); - background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor); - background-image: -o-linear-gradient(@startColor, @midColor @colorStop, @endColor); - background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor); - background-repeat: no-repeat; - filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down, gets no color-stop at all for proper fallback - } - .radial(@innerColor: #555, @outerColor: #333) { - background-color: @outerColor; - background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@innerColor), to(@outerColor)); - background-image: -webkit-radial-gradient(circle, @innerColor, @outerColor); - background-image: -moz-radial-gradient(circle, @innerColor, @outerColor); - background-image: -o-radial-gradient(circle, @innerColor, @outerColor); - // > Joomla JUI - /* Joomla JUI NOTE: makes radial gradient IE 10+, also confirmed in Bootstrap, https://github.com/twbs/bootstrap/issues/7462 */ - background-image: radial-gradient(circle, @innerColor, @outerColor); - // < Joomla JUI - background-repeat: no-repeat; - } - .striped(@color: #555, @angle: 45deg) { - background-color: @color; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - } -} -// Reset filters for IE -.reset-filter() { - filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)")); -} - - - -// COMPONENT MIXINS -// -------------------------------------------------- - -// Horizontal dividers -// ------------------------- -// Dividers (basically an hr) within dropdowns and nav lists -.nav-divider(@top: #e5e5e5, @bottom: @white) { - // IE7 needs a set width since we gave a height. Restricting just - // to IE7 to keep the 1px left/right space in other browsers. - // It is unclear where IE is getting the extra space that we need - // to negative-margin away, but so it goes. - *width: 100%; - height: 1px; - margin: ((@baseLineHeight / 2) - 1) 1px; // 8px 1px - *margin: -5px 0 5px; - overflow: hidden; - background-color: @top; - border-bottom: 1px solid @bottom; -} - -// Button backgrounds -// ------------------ -.buttonBackground(@startColor, @endColor, @textColor: #fff, @textShadow: 0 -1px 0 rgba(0,0,0,.25)) { - // gradientBar will set the background to a pleasing blend of these, to support IE<=9 - //.gradientBar(@startColor, @endColor, @textColor, @textShadow); - background-color: @startColor; - *background-color: @startColor; /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - //.reset-filter(); - - // in these cases the gradient won't cover the background, so we override - &:hover, &:focus, &:active, &.active, &.disabled, &[disabled] { - color: @textColor; - background-color: darken(@endColor, 5%); - *background-color: darken(@endColor, 5%); - } - - // IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves - &:active, - &.active { - background-color: @startColor; - } -} - -// Navbar vertical align -// ------------------------- -// Vertically center elements in the navbar. -// Example: an element has a height of 30px, so write out `.navbarVerticalAlign(30px);` to calculate the appropriate top margin. -.navbarVerticalAlign(@elementHeight) { - margin-top: (@navbarHeight - @elementHeight) / 2; -} - - - -// Grid System -// ----------- - -// Centered container element -.container-fixed() { - margin-right: auto; - margin-left: auto; - .clearfix(); -} - -// Table columns -.tableColumns(@columnSpan: 1) { - float: none; // undo default grid column styles - width: ((@gridColumnWidth) * @columnSpan) + (@gridGutterWidth * (@columnSpan - 1)) - 16; // 16 is total padding on left and right of table cells - margin-left: 0; // undo default grid column styles -} - -// Make a Grid -// Use .makeRow and .makeColumn to assign semantic layouts grid system behavior -.makeRow() { - margin-left: @gridGutterWidth * -1; - .clearfix(); -} -.makeColumn(@columns: 1, @offset: 0) { - float: left; - margin-left: (@gridColumnWidth * @offset) + (@gridGutterWidth * (@offset - 1)) + (@gridGutterWidth * 2); - width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)); -} - -// The Grid -#grid { - - .core (@gridColumnWidth, @gridGutterWidth) { - - .spanX (@index) when (@index > 0) { - .span@{index} { .span(@index); } - .spanX(@index - 1); - } - .spanX (0) {} - - .offsetX (@index) when (@index > 0) { - .offset@{index} { .offset(@index); } - .offsetX(@index - 1); - } - .offsetX (0) {} - - .offset (@columns) { - margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns + 1)); - } - - .span (@columns) { - width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)); - } - - .row { - margin-left: @gridGutterWidth * -1; - .clearfix(); - } - - [class*="span"] { - float: left; - min-height: 1px; // prevent collapsing columns - margin-left: @gridGutterWidth; - } - - // Set the container width, and override it for fixed navbars in media queries - .container, - .navbar-static-top .container, - .navbar-fixed-top .container, - .navbar-fixed-bottom .container { .span(@gridColumns); } - - // generate .spanX and .offsetX - .spanX (@gridColumns); - .offsetX (@gridColumns); - - } - - .fluid (@fluidGridColumnWidth, @fluidGridGutterWidth) { - - .spanX (@index) when (@index > 0) { - .span@{index} { .span(@index); } - .spanX(@index - 1); - } - .spanX (0) {} - - .offsetX (@index) when (@index > 0) { - .offset@{index} { .offset(@index); } - .offset@{index}:first-child { .offsetFirstChild(@index); } - .offsetX(@index - 1); - } - .offsetX (0) {} - - .offset (@columns) { - margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth*2); - *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + (@fluidGridGutterWidth*2) - (.5 / @gridRowWidth * 100 * 1%); - } - - .offsetFirstChild (@columns) { - margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth); - *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%); - } - - .span (@columns) { - width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)); - *width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%); - } - - .row-fluid { - width: 100%; - .clearfix(); - [class*="span"] { - .input-block-level(); - float: left; - margin-left: @fluidGridGutterWidth; - *margin-left: @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%); - } - [class*="span"]:first-child { - margin-left: 0; - } - - // Space grid-sized controls properly if multiple per line - .controls-row [class*="span"] + [class*="span"] { - margin-left: @fluidGridGutterWidth; - } - - // generate .spanX and .offsetX - .spanX (@gridColumns); - .offsetX (@gridColumns); - } - - } - - .input(@gridColumnWidth, @gridGutterWidth) { - - .spanX (@index) when (@index > 0) { - input.span@{index}, textarea.span@{index}, .uneditable-input.span@{index} { .span(@index); } - .spanX(@index - 1); - } - .spanX (0) {} - - .span(@columns) { - width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 14; - } - - input, - textarea, - .uneditable-input { - margin-left: 0; // override margin-left from core grid system - } - - // Space grid-sized controls properly if multiple per line - .controls-row [class*="span"] + [class*="span"] { - margin-left: @gridGutterWidth; - } - - // generate .spanX - .spanX (@gridColumns); - - } -} diff --git a/administrator/templates/isis/less/bootstrap/responsive-1200px-min.less b/administrator/templates/isis/less/bootstrap/responsive-1200px-min.less deleted file mode 100644 index cd7d2812277a2..0000000000000 --- a/administrator/templates/isis/less/bootstrap/responsive-1200px-min.less +++ /dev/null @@ -1,201 +0,0 @@ -// -// Responsive: Large desktop and up -// -------------------------------------------------- - - -@media (min-width: 1200px) { - - // Fixed grid - #grid > .core(@gridColumnWidth1200, @gridGutterWidth1200); - - // Fluid grid - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - content: ""; - line-height: 0; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - float: left; - margin-left: 2.76243094%; - *margin-left: 2.70923945%; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.76243094%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851%; - } - .row-fluid .span11 { - width: 91.43646409%; - *width: 91.3832726%; - } - .row-fluid .span10 { - width: 82.87292818%; - *width: 82.81973669%; - } - .row-fluid .span9 { - width: 74.30939227%; - *width: 74.25620078%; - } - .row-fluid .span8 { - width: 65.74585635%; - *width: 65.69266486%; - } - .row-fluid .span7 { - width: 57.18232044%; - *width: 57.12912895%; - } - .row-fluid .span6 { - width: 48.61878453%; - *width: 48.56559304%; - } - .row-fluid .span5 { - width: 40.05524862%; - *width: 40.00205713%; - } - .row-fluid .span4 { - width: 31.49171271%; - *width: 31.43852122%; - } - .row-fluid .span3 { - width: 22.9281768%; - *width: 22.87498531%; - } - .row-fluid .span2 { - width: 14.36464088%; - *width: 14.31144939%; - } - .row-fluid .span1 { - width: 5.80110497%; - *width: 5.74791348%; - } - .row-fluid .offset12 { - margin-left: 105.52486188%; - *margin-left: 105.4184789%; - } - .row-fluid .offset12:first-child { - margin-left: 102.76243094%; - *margin-left: 102.65604796%; - } - .row-fluid .offset11 { - margin-left: 96.96132597%; - *margin-left: 96.85494299%; - } - .row-fluid .offset11:first-child { - margin-left: 94.19889503%; - *margin-left: 94.09251205%; - } - .row-fluid .offset10 { - margin-left: 88.39779006%; - *margin-left: 88.29140708%; - } - .row-fluid .offset10:first-child { - margin-left: 85.63535912%; - *margin-left: 85.52897614%; - } - .row-fluid .offset9 { - margin-left: 79.83425414%; - *margin-left: 79.72787116%; - } - .row-fluid .offset9:first-child { - margin-left: 77.0718232%; - *margin-left: 76.96544023%; - } - .row-fluid .offset8 { - margin-left: 71.27071823%; - *margin-left: 71.16433525%; - } - .row-fluid .offset8:first-child { - margin-left: 68.50828729%; - *margin-left: 68.40190431%; - } - .row-fluid .offset7 { - margin-left: 62.70718232%; - *margin-left: 62.60079934%; - } - .row-fluid .offset7:first-child { - margin-left: 59.94475138%; - *margin-left: 59.8383684%; - } - .row-fluid .offset6 { - margin-left: 54.14364641%; - *margin-left: 54.03726343%; - } - .row-fluid .offset6:first-child { - margin-left: 51.38121547%; - *margin-left: 51.27483249%; - } - .row-fluid .offset5 { - margin-left: 45.5801105%; - *margin-left: 45.47372752%; - } - .row-fluid .offset5:first-child { - margin-left: 42.81767956%; - *margin-left: 42.71129658%; - } - .row-fluid .offset4 { - margin-left: 37.01657459%; - *margin-left: 36.91019161%; - } - .row-fluid .offset4:first-child { - margin-left: 34.25414365%; - *margin-left: 34.14776067%; - } - .row-fluid .offset3 { - margin-left: 28.45303867%; - *margin-left: 28.3466557%; - } - .row-fluid .offset3:first-child { - margin-left: 25.69060773%; - *margin-left: 25.58422476%; - } - .row-fluid .offset2 { - margin-left: 19.88950276%; - *margin-left: 19.78311978%; - } - .row-fluid .offset2:first-child { - margin-left: 17.12707182%; - *margin-left: 17.02068884%; - } - .row-fluid .offset1 { - margin-left: 11.32596685%; - *margin-left: 11.21958387%; - } - .row-fluid .offset1:first-child { - margin-left: 8.56353591%; - *margin-left: 8.45715293%; - } - - // Input grid - #grid > .input(@gridColumnWidth1200, @gridGutterWidth1200); - - // Thumbnails - .thumbnails { - margin-left: -@gridGutterWidth1200; - } - .thumbnails > li { - margin-left: @gridGutterWidth1200; - } - .row-fluid .thumbnails { - margin-left: 0; - } - -} diff --git a/administrator/templates/isis/less/bootstrap/responsive-768px-979px.less b/administrator/templates/isis/less/bootstrap/responsive-768px-979px.less deleted file mode 100644 index 805e65a4b235f..0000000000000 --- a/administrator/templates/isis/less/bootstrap/responsive-768px-979px.less +++ /dev/null @@ -1,192 +0,0 @@ -// -// Responsive: Tablet to desktop -// -------------------------------------------------- - - -@media (min-width: 768px) and (max-width: 979px) { - - // Fixed grid - #grid > .core(@gridColumnWidth768, @gridGutterWidth768); - - // Fluid grid - .row-fluid { - width: 100%; - *zoom: 1; - } - .row-fluid:before, - .row-fluid:after { - display: table; - content: ""; - line-height: 0; - } - .row-fluid:after { - clear: both; - } - .row-fluid [class*="span"] { - display: block; - width: 100%; - min-height: 28px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - float: left; - margin-left: 2.76243094%; - *margin-left: 2.70923945%; - } - .row-fluid [class*="span"]:first-child { - margin-left: 0; - } - .row-fluid .controls-row [class*="span"] + [class*="span"] { - margin-left: 2.76243094%; - } - .row-fluid .span12 { - width: 100%; - *width: 99.94680851%; - } - .row-fluid .span11 { - width: 91.43646409%; - *width: 91.3832726%; - } - .row-fluid .span10 { - width: 82.87292818%; - *width: 82.81973669%; - } - .row-fluid .span9 { - width: 74.30939227%; - *width: 74.25620078%; - } - .row-fluid .span8 { - width: 65.74585635%; - *width: 65.69266486%; - } - .row-fluid .span7 { - width: 57.18232044%; - *width: 57.12912895%; - } - .row-fluid .span6 { - width: 48.61878453%; - *width: 48.56559304%; - } - .row-fluid .span5 { - width: 40.05524862%; - *width: 40.00205713%; - } - .row-fluid .span4 { - width: 31.49171271%; - *width: 31.43852122%; - } - .row-fluid .span3 { - width: 22.9281768%; - *width: 22.87498531%; - } - .row-fluid .span2 { - width: 14.36464088%; - *width: 14.31144939%; - } - .row-fluid .span1 { - width: 5.80110497%; - *width: 5.74791348%; - } - .row-fluid .offset12 { - margin-left: 105.52486188%; - *margin-left: 105.4184789%; - } - .row-fluid .offset12:first-child { - margin-left: 102.76243094%; - *margin-left: 102.65604796%; - } - .row-fluid .offset11 { - margin-left: 96.96132597%; - *margin-left: 96.85494299%; - } - .row-fluid .offset11:first-child { - margin-left: 94.19889503%; - *margin-left: 94.09251205%; - } - .row-fluid .offset10 { - margin-left: 88.39779006%; - *margin-left: 88.29140708%; - } - .row-fluid .offset10:first-child { - margin-left: 85.63535912%; - *margin-left: 85.52897614%; - } - .row-fluid .offset9 { - margin-left: 79.83425414%; - *margin-left: 79.72787116%; - } - .row-fluid .offset9:first-child { - margin-left: 77.0718232%; - *margin-left: 76.96544023%; - } - .row-fluid .offset8 { - margin-left: 71.27071823%; - *margin-left: 71.16433525%; - } - .row-fluid .offset8:first-child { - margin-left: 68.50828729%; - *margin-left: 68.40190431%; - } - .row-fluid .offset7 { - margin-left: 62.70718232%; - *margin-left: 62.60079934%; - } - .row-fluid .offset7:first-child { - margin-left: 59.94475138%; - *margin-left: 59.8383684%; - } - .row-fluid .offset6 { - margin-left: 54.14364641%; - *margin-left: 54.03726343%; - } - .row-fluid .offset6:first-child { - margin-left: 51.38121547%; - *margin-left: 51.27483249%; - } - .row-fluid .offset5 { - margin-left: 45.5801105%; - *margin-left: 45.47372752%; - } - .row-fluid .offset5:first-child { - margin-left: 42.81767956%; - *margin-left: 42.71129658%; - } - .row-fluid .offset4 { - margin-left: 37.01657459%; - *margin-left: 36.91019161%; - } - .row-fluid .offset4:first-child { - margin-left: 34.25414365%; - *margin-left: 34.14776067%; - } - .row-fluid .offset3 { - margin-left: 28.45303867%; - *margin-left: 28.3466557%; - } - .row-fluid .offset3:first-child { - margin-left: 25.69060773%; - *margin-left: 25.58422476%; - } - .row-fluid .offset2 { - margin-left: 19.88950276%; - *margin-left: 19.78311978%; - } - .row-fluid .offset2:first-child { - margin-left: 17.12707182%; - *margin-left: 17.02068884%; - } - .row-fluid .offset1 { - margin-left: 11.32596685%; - *margin-left: 11.21958387%; - } - .row-fluid .offset1:first-child { - margin-left: 8.56353591%; - *margin-left: 8.45715293%; - } - - // Input grid - #grid > .input(@gridColumnWidth768, @gridGutterWidth768); - - // No need to reset .thumbnails here since it's the same @gridGutterWidth - -} diff --git a/administrator/templates/isis/less/bootstrap/wells.less b/administrator/templates/isis/less/bootstrap/wells.less deleted file mode 100644 index 41aea38030da7..0000000000000 --- a/administrator/templates/isis/less/bootstrap/wells.less +++ /dev/null @@ -1,29 +0,0 @@ -// -// Wells -// -------------------------------------------------- - - -// Base class -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: @wellBackground; - border: 1px solid @wellBackground; - .border-radius(@baseBorderRadius); - //.box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); - blockquote { - border-color: #f0f0f0; - border-color: rgba(0,0,0,.15); - } -} - -// Sizes -.well-large { - padding: 24px; - .border-radius(@borderRadiusLarge); -} -.well-small { - padding: 9px; - .border-radius(@borderRadiusSmall); -} diff --git a/administrator/templates/isis/less/icomoon.less b/administrator/templates/isis/less/icomoon.less deleted file mode 100644 index 46f801b4214b3..0000000000000 --- a/administrator/templates/isis/less/icomoon.less +++ /dev/null @@ -1,39 +0,0 @@ -@font-face { - font-family: 'IcoMoon'; - src: url('../../../../media/jui/fonts/IcoMoon.eot'); - src: url('../../../../media/jui/fonts/IcoMoon.eot?#iefix') format('embedded-opentype'), - url('../../../../media/jui/fonts/IcoMoon.woff') format('woff'), - url('../../../../media/jui/fonts/IcoMoon.ttf') format('truetype'), - url('../../../../media/jui/fonts/IcoMoon.svg#IcoMoon') format('svg'); - font-weight: normal; - font-style: normal; -} -@import "../../../../media/jui/less/icomoon.less"; -.icon-edit:before { - color: @btnInfoBackgroundHighlight; -} -.icon-publish:before, -.icon-save:before, -.icon-ok:before, -.icon-save-new:before, -.icon-save-copy:before, -.btn-toolbar .icon-copy:before { - color: @btnSuccessBackgroundHighlight; -} -.icon-unpublish:before, -.icon-not-ok:before, -.icon-eye-close:before, -.icon-ban-circle:before, -.icon-minus-sign:before, -.btn-toolbar .icon-cancel:before { - color: @btnDangerBackgroundHighlight; -} -.icon-featured:before, -.icon-default:before, -.icon-expired:before, -.icon-pending:before { - color: @btnWarningBackgroundHighlight; -} -.icon-back:before { - content: "\e008"; -} \ No newline at end of file diff --git a/administrator/templates/isis/less/pages/_com_cpanel.less b/administrator/templates/isis/less/pages/_com_cpanel.less deleted file mode 100644 index 18d8a44cd19ce..0000000000000 --- a/administrator/templates/isis/less/pages/_com_cpanel.less +++ /dev/null @@ -1,24 +0,0 @@ -// com_cpanel - -.com_cpanel { - .well { - padding: 8px 14px; - border: 1px solid rgba(0,0,0,0.05); - .module-title.nav-header { - color: #555; - } - > .row-striped, > .list-striped { - margin: 0 -14px; - > .row-fluid { - padding: 8px 14px; - [class*="span"] { - margin-left: 0; - } - } - > li { - padding-left: 15px; - padding-right: 15px; - } - } - } -} \ No newline at end of file diff --git a/administrator/templates/isis/less/pages/_com_postinstall.less b/administrator/templates/isis/less/pages/_com_postinstall.less deleted file mode 100644 index 2c80f6f5222e4..0000000000000 --- a/administrator/templates/isis/less/pages/_com_postinstall.less +++ /dev/null @@ -1,21 +0,0 @@ -// com_postinstall - -.com_postinstall { - fieldset { - background-color: #fafafa; - border: 1px solid #ccc; - border-radius: 5px; - margin: 0 0 18px; - padding: 4px 18px 18px; - .btn { - margin-top: 10px; - } - } - legend { - border: 0 none; - display: inline-block; - padding: 0 5px; - margin-bottom: 0; - width: auto; - } -} diff --git a/administrator/templates/isis/less/pages/_com_templates.less b/administrator/templates/isis/less/pages/_com_templates.less deleted file mode 100644 index 69d17fc920a14..0000000000000 --- a/administrator/templates/isis/less/pages/_com_templates.less +++ /dev/null @@ -1,37 +0,0 @@ -// Template Menu Assignment - -#menu-assignment { - position: relative; - .menu-links { - margin-top: 15px; - margin-left: 0; - -webkit-column-count: 3; - -moz-column-count: 3; - column-count: 3; - -moz-column-gap: 15px; - -webkit-column-gap: 15px; - column-gap: 15px; - > li { - display: inline-block; - vertical-align: top; - margin-bottom: 15px; - width: 100%; - list-style: none; - -webkit-column-break-inside: avoid; - -webkit-backface-visibility: hidden; - } - } - .menu-links-block { - background-color: #fafafa; - border: 1px solid #ddd; - border-radius: 3px; - padding: 15px; - } -} -@media (max-width: @md-max) { - #menu-assignment .menu-links { - -webkit-column-count: auto; - -moz-column-count: auto; - column-count: auto; - } -} diff --git a/administrator/templates/isis/less/template-rtl.less b/administrator/templates/isis/less/template-rtl.less deleted file mode 100644 index 3ca5205be3e5e..0000000000000 --- a/administrator/templates/isis/less/template-rtl.less +++ /dev/null @@ -1,436 +0,0 @@ -@import "template.less"; -@import "../../../../media/jui/less/bootstrap-rtl.less"; - -.navbar { - .admin-logo { - float: right; - padding: 7px 15px 0px 12px; - } - .brand { - float: left; - padding: 6px 10px; - } - .nav { - margin: 0 0 0 10px; - > li > a { - padding: 6px 10px; - } - > li ul { - overflow-y: auto; - overflow-x: hidden; - -webkit-overflow-scrolling: touch; - -moz-overflow-scrolling: touch; - -ms-overflow-scrolling: touch; - -o-overflow-scrolling: touch; - overflow-scrolling: touch; - height: auto; - max-height: 500px; - margin: 0; - &::-webkit-scrollbar { - -webkit-appearance: none; - width: 7px; - } - &::-webkit-scrollbar-thumb { - border-radius: 4px; - background-color: rgba(0,0,0,.5); - -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); - } - } - } - .nav-user .dropdown-menu li span { - padding-left: 0; - padding-right: 10px; - } - .nav > .dropdown.open:after { - right: 10px; - width: 0; - } - .empty-nav { - display: none; - } -} - -#toolbar { - .btn { - padding: 0 10px; - } - [class^="icon-"], [class*=" icon-"] { - border-radius: 0 3px 3px 0; - border-right: 0; - border-left: 1px solid #b3b3b3; - margin: 0 -10px 0 6px; - } -} -.chzn-container-single .chzn-single { - padding-left: 8px; - div { - border-left: 0; - border-right: 1px solid #cccccc; - } - abbr { - left: 36px; - } -} -.chzn-container-active.chzn-with-drop .chzn-single div { - background-color: #f3f3f3; - border-bottom: 1px solid #cccccc; - border-bottom-left-radius: 0px; - border-bottom-right-radius: 3px; - border-left: 1px solid #cccccc; -} -.chzn-container-multi .chzn-choices .search-choice { - padding-left: 7px; - .search-choice-close { - margin-left: 0; - margin-right: 3px; - } -} -.chzn-container .chzn-single.chzn-color[rel="value_0"] div, -.chzn-container .chzn-single.chzn-color[rel="value_1"] div { - border-right: none; -} -.chzn-container-single .chzn-search::after { - left: 20px; - right: auto; -} - -.container-logo { - padding-top: 0; - float: left; - text-align: left; -} - -.page-title { - [class^="icon-"], - [class*=" icon-"] { - margin-right: 0; - margin-left: 16px; - } -} - -@media (max-width: @md-max) { - .navbar { - .admin-logo { - margin-right: 10px; - padding: 9px 9px 0 9px; - } - .btn-navbar { - float: left; - margin-right: 5px; - margin-left: 3px; - } - .nav-collapse .nav.pull-left { - float: none; - margin-left: 0; - margin-right: 0; - } - } - - .nav-collapse .nav > li { - float: none; - } - - .page-title { - [class^="icon-"], - [class*=" icon-"] { - margin-left: 10px; - } - } -} - -/* Status module */ -#status { - padding: 4px 10px; - - .btn-group { - margin: 0; - } - .btn-group.separator:after { - content: ' '; - display: block; - float: left; - background: #ADADAD; - margin: 0 10px; - height: 15px; - width: 1px; - } - .badge { - margin-left: .25em; - margin-right: 0; - } -} - -/* Menus */ -.dropdown-menu > li > a { - text-align: right; -} - -/* btn-group */ -.btn-group.btn-group-yesno > .btn, .btn-group > .btn, .btn-group > .btn + .dropdown-toggle { - float: none; -} - -/* For grid.boolean */ -a.grid_false { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/publish_r.png'); -} - -a.grid_true { - display: inline-block; - height: 16px; - width: 16px; - background-image: url('../images/admin/icon-16-allow.png'); -} - -/* Login */ -.view-login { - .login-joomla { - position: absolute; - right: 50%; - height: 24px; - width: 24px; - margin-right: -12px; - font-size: 22px; - } - .input-medium { - width: 169px; - } -} -.login { - .chzn-single { - width: 219px !important; - } - .chzn-container, - .chzn-drop { - width: 227px !important; - max-width: 227px !important; - } - .input-prepend .chzn-container-single .chzn-single { - .border-radius(3px 0 0 3px); - border-right:0px; - } -} - -/* For collapsible sidebar */ -.j-sidebar-container { - position: absolute; - display: block; - left: auto; - right: -16.5%; - padding-top: 28px; - padding-bottom: 40px; - clear: both; - margin: -10px -1px 0 0; - border-right: 0; - border-left: 1px solid #d3d3d3; -} - -.j-sidebar-container.j-sidebar-hidden { - left: auto; - right: -16.5%; -} - -.j-sidebar-container.j-sidebar-visible { - left: auto; - right: 0; -} - -.j-toggle-sidebar-header { - padding: 10px 19px 10px 0; -} - -.sidebar { - padding: 3px 4px 3px 3px; -} - -.j-toggle-button-wrapper { - &.j-toggle-hidden { - right: auto; - left: -24px; - } - &.j-toggle-visible { - right: auto; - left: 10px; - } -} - -.j-sidebar-container .icon-folder-2 { - line-height: 15px; - padding-left: 0; -} - -#system-message-container, -#j-main-container { - padding: 0 5px 0 0; -} - -#system-message-container.j-toggle-main, -#j-main-container.j-toggle-main, -#system-debug.j-toggle-main { - float: left; -} - -@media (max-width: @lg-max) { - .j-toggle-button-wrapper.j-toggle-hidden { - right: auto; - left: -20px; - } -} - -@media (max-width: @md-max) { - .j-sidebar-container { - position: relative; - padding: 0; - border-right: 0; - border-left: 0; - } - - .j-sidebar-container.j-sidebar-hidden { - margin-left: auto; - margin-right: 16.5%; - } - - .j-sidebar-container.j-sidebar-visible { - margin-left: auto; - margin-right: 0; - } - - /* login */ - .view-login { - select { - width: 229px - } - } -} - -#j-main-container.expanded { - margin-right: 0; -} - -/* Modal batch */ -@media (min-width: @md) { - .row-fluid [class*="span"] { - margin-right: 15px; - margin-left: 0; - } - - .row-fluid .modal-batch [class*="span"] { - margin-right: 0; - } -} - -.row-fluid .modal-batch [class*="span"] { - margin-right: 0; -} - -/* Extended Responsive Styles */ -@media (max-width: @sm-max) { - .btn-toolbar .btn-wrapper .btn { - width: 100% !important; - margin-right:0px; - } - .btn-toolbar .btn-wrapper { - margin:0 10px 5px 10px; - } -} - -@media (max-width: 420px) { - .j-sidebar-container { - margin: 0; - } - /* login */ - .view-login { - .input-medium { - width: 173px; - } - select { - width: 229px - } - } -} - -/* Stats plugin */ -.js-pstats-data-details dd { - margin-right: 240px; -} - -/* Modal footer */ -.modal-footer button { - float: left; -} - -/* Modal Header text align right even if parent container centered */ -.modal-header { - text-align: right; -} - - -/* Media Manager */ -#mediamanager-form .thumbnails-media .thumbnail { - margin-left: 18px !important; - margin-right: 0; - direction: ltr; - text-align: center; -} -.thumbnails-media .imgThumb label::before, .thumbnails-media .imgThumb .imgThumbInside::before { - left: 0; - right: auto; - border-radius: 3px 0; -} -.thumbnails-media .thumbnail input[type="radio"], .thumbnails-media .thumbnail input[type="checkbox"] { - left: auto; - right: 5px; -} -.thumbnails-media .imgDelete a.close { - border-radius: 0 3px; -} -.thumbnails-media .imgPreview a, .thumbnails-media .imgDetails { - border-radius: 3px 0; - border-width: 1px; - left: 0; - right: 0; - text-align: left; - direction: ltr; -} -.thumbnails-media .imgPreview a { - width: 100%; -} - -/* SubForms (Table) */ -.subform-table-layout { - td { - padding-left: 10px; - &::before { - content: attr(data-column); - left: auto; - right: 10px; - padding-left: 10px; - padding-right: 0; - } - } - .subform-repeatable tbody td:last-of-type { - text-align: left; - } - .form-horizontal .controls { - margin-top: 0; - } -} - -/* com_templates */ -.tree-holder { - ul { - ul { - padding-right: 15px; - box-shadow: 3px 0 0 rgba(0, 0, 0, 0.08); - padding-left: 0; - .folder-url, .file { - box-shadow: 3px 0 0 @linkColor; - border-right: 0; - border-left: 1px solid rgba(0, 0, 0, 0.08); - } - } - } -} \ No newline at end of file diff --git a/administrator/templates/isis/less/template.less b/administrator/templates/isis/less/template.less deleted file mode 100644 index ce927e392c1ce..0000000000000 --- a/administrator/templates/isis/less/template.less +++ /dev/null @@ -1,93 +0,0 @@ -// CSS Reset -@import "../../../../media/jui/less/reset.less"; -// Core variables and mixins -@import "variables.less"; -// Custom for this template -@import "bootstrap/mixins.less"; -// Grid system and page structure -@import "../../../../media/jui/less/scaffolding.less"; -@import "../../../../media/jui/less/grid.less"; -@import "../../../../media/jui/less/layouts.less"; -// Base CSS -@import "../../../../media/jui/less/type.less"; -@import "../../../../media/jui/less/code.less"; -@import "../../../../media/jui/less/forms.less"; -@import "../../../../media/jui/less/tables.less"; -// Components: common -// @import "../../../../media/jui/less/sprites.less"; -@import "../../../../media/jui/less/dropdowns.less"; -@import "bootstrap/wells.less"; -@import "../../../../media/jui/less/component-animations.less"; -@import "../../../../media/jui/less/close.less"; -// Components: Buttons & Alerts -@import "bootstrap/buttons.less"; -@import "bootstrap/button-groups.less"; -@import "../../../../media/jui/less/alerts.less"; -// Note: alerts share common CSS with buttons and thus have styles in buttons.less -// Components: Nav -@import "../../../../media/jui/less/navs.less"; -@import "../../../../media/jui/less/navbar.less"; -@import "../../../../media/jui/less/breadcrumbs.less"; -@import "../../../../media/jui/less/pagination.less"; -@import "../../../../media/jui/less/pager.less"; -// Components: Popovers -@import "../../../../media/jui/less/modals.less"; -@import "../../../../media/jui/less/tooltip.less"; -@import "../../../../media/jui/less/popovers.less"; -// Components: Misc -@import "../../../../media/jui/less/thumbnails.less"; -@import "../../../../media/jui/less/media.less"; -@import "../../../../media/jui/less/labels-badges.less"; -@import "../../../../media/jui/less/progress-bars.less"; -@import "../../../../media/jui/less/accordion.less"; -@import "../../../../media/jui/less/carousel.less"; -@import "../../../../media/jui/less/hero-unit.less"; -// Utility classes -@import "../../../../media/jui/less/utilities.less"; -// RESPONSIVE CLASSES -// ------------------ -@import "../../../../media/jui/less/responsive-utilities.less"; -// MEDIA QUERIES -// ------------------ -// Phones to portrait tablets and narrow desktops -@import "../../../../media/jui/less/responsive-767px-max.less"; -// Tablets to regular desktops -@import "bootstrap/responsive-768px-979px.less"; -// Large desktops -@import "bootstrap/responsive-1200px-min.less"; -// RESPONSIVE NAVBAR -// ------------------ -// From 979px and below, show a button to toggle navbar contents -@import "../../../../media/jui/less/responsive-navbar.less"; -// Extended for JUI -@import "../../../../media/jui/less/bootstrap-extended.less"; -// Has to be last to override when necessary -// div.modal (instead of .modal) -@import "../../../../media/jui/less/modals.joomla.less"; -@import "../../../../media/jui/less/responsive-767px-max.joomla.less"; -// Icon Font -@import "icomoon.less"; - -// Blocks -@import "blocks/_global.less"; -@import "blocks/_chzn-override.less"; -@import "blocks/_editors.less"; -@import "blocks/_forms.less"; -@import "blocks/_header.less"; -@import "blocks/_login.less"; -@import "blocks/_media.less"; -@import "blocks/_modals.less"; -@import "blocks/_navbar.less"; -@import "blocks/_quickicons.less"; -@import "blocks/_sidebar.less"; -@import "blocks/_status.less"; -@import "blocks/_tables.less"; -@import "blocks/_toolbar.less"; -@import "blocks/_treeselect.less"; -@import "blocks/_utility-classes.less"; -@import "blocks/_custom.less"; - -// Pages -@import "pages/_com_cpanel.less"; -@import "pages/_com_postinstall.less"; -@import "pages/_com_templates.less"; diff --git a/administrator/templates/isis/less/variables.less b/administrator/templates/isis/less/variables.less deleted file mode 100644 index 6d6a804f2c5fc..0000000000000 --- a/administrator/templates/isis/less/variables.less +++ /dev/null @@ -1,340 +0,0 @@ -// -// Variables -// -------------------------------------------------- - -// > Joomla JUI -// Responsive Breakpoints -// ------------------------- -@xs: 320px; -@sm: 480px; -@md: 768px; -@lg: 980px; -@xl: 1200px; - -@xs-max: @xs - 1; -@sm-max: @sm - 1; -@md-max: @md - 1; -@lg-max: @lg - 1; -@xl-max: @xl - 1; -// < Joomla JUI - -// Global values -// -------------------------------------------------- - - -// Grays -// ------------------------- -@black: #000; -@grayDarker: #222; -@grayDark: #333; -@gray: #555; -@grayLight: #999; -@grayLighter: #eee; -@white: #fff; - - -// Accent colors -// ------------------------- -@blue: #049cdb; -@blueDark: #0064cd; -@green: #46a546; -@red: #9d261d; -@yellow: #ffc40d; -@orange: #f89406; -@pink: #c3325f; -@purple: #7a43b6; - - -// Scaffolding -// ------------------------- -@bodyBackground: @white; -@textColor: @grayDark; - - -// Links -// ------------------------- -@linkColor: darken(#428bca, 10%); -@linkColorHover: darken(@linkColor, 15%); - - -// Typography -// ------------------------- -@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; -@serifFontFamily: Georgia, "Times New Roman", Times, serif; -@monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace; -// > Joomla JUI -@baseFontSize: 13px; -// < Joomla JUI -@baseFontFamily: @sansFontFamily; -// > Joomla JUI -@baseLineHeight: 18px; -// < Joomla JUI -@altFontFamily: @serifFontFamily; - -@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily -@headingsFontWeight: bold; // instead of browser default, bold -@headingsColor: inherit; // empty to use BS default, @textColor - - -// Component sizing -// ------------------------- -// Based on 14px font-size and 20px line-height - -@fontSizeLarge: @baseFontSize * 1.25; // ~18px -// > Joomla JUI -@fontSizeSmall: ceil(@baseFontSize * 0.85); // ~12px -// < Joomla JUI -@fontSizeMini: @baseFontSize * 0.75; // ~11px - -@paddingLarge: 11px 19px; // 44px -@paddingSmall: 2px 10px; // 26px -@paddingMini: 0 6px; // 22px - -@baseBorderRadius: 3px; -@borderRadiusLarge: 6px; -@borderRadiusSmall: 3px; - - -// Tables -// ------------------------- -@tableBackground: transparent; // overall background-color -@tableBackgroundAccent: #f9f9f9; // for striping -@tableBackgroundHover: #F0F0F0; // for hover -@tableBorder: #ddd; // table and cell border - -// Buttons -// ------------------------- -@btnBackground: #f3f3f3; -@btnBackgroundHighlight: darken(@grayLighter, 3%); -@btnBorder: lighten(@grayLight, 10%); - -// > Joomla JUI -@btnPrimaryBackground: #2384d3; -@btnPrimaryBackgroundHighlight: #15497c; -// < Joomla JUI - -@btnInfoBackground: #2f96b4; -@btnInfoBackgroundHighlight: darken(@btnInfoBackground, 10%); - -@btnSuccessBackground: #46a546; -@btnSuccessBackgroundHighlight: darken(@btnSuccessBackground, 10%); - -@btnWarningBackground: @orange; -@btnWarningBackgroundHighlight: darken(@btnWarningBackground, 10%); - -@btnDangerBackground: #bd362f; -@btnDangerBackgroundHighlight: darken(@btnDangerBackground, 10%); - -@btnInverseBackground: #444; -@btnInverseBackgroundHighlight: @grayDarker; - - -// Forms -// ------------------------- -@inputBackground: @white; -@inputBorder: #ccc; -@inputBorderHighlight: #3071A9; -@inputBorderRadius: 3px; -@inputDisabledBackground: @grayLighter; -@formActionsBackground: #F0F0F0; -@inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border - - -// Dropdowns -// ------------------------- -@dropdownBackground: @white; -@dropdownBorder: rgba(0,0,0,.2); -@dropdownDividerTop: #F0F0F0; -@dropdownDividerBottom: @white; - -@dropdownLinkColor: @grayDark; -@dropdownLinkColorHover: @white; -@dropdownLinkColorActive: @dropdownLinkColor; - -@dropdownLinkBackgroundHover: @dropdownLinkBackgroundActive; -@dropdownLinkBackgroundActive: @linkColor; - - - -// COMPONENT VARIABLES -// -------------------------------------------------- - - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -@zindexDropdown: 1000; -@zindexTooltip: 1030; -@zindexFixedNavbar: 1030; -@zindexModalBackdrop: 1040; -@zindexModal: 1050; -@zindexPopover: 1060; - - -// Sprite icons path -// ------------------------- -@iconSpritePath: "../img/glyphicons-halflings.png"; -@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; - - -// Input placeholder text color -// ------------------------- -@placeholderText: @grayLight; - - -// Hr border color -// ------------------------- -@hrBorder: @grayLighter; - - -// Horizontal forms & lists -// ------------------------- -@horizontalComponentOffset: 180px; - - -// Wells -// ------------------------- -@wellBackground: #F0F0F0; - - -// Navbar -// ------------------------- -// > Joomla JUI -@navbarCollapseWidth: @md-max; -// < Joomla JUI -@navbarCollapseDesktopWidth: (@navbarCollapseWidth + 1); - -@navbarHeight: 40px; -@navbarBackgroundHighlight: #ffffff; -@navbarBackground: darken(@navbarBackgroundHighlight, 5%); -@navbarBorder: darken(@navbarBackground, 12%); - -@navbarText: @gray; -@navbarLinkColor: @gray; -@navbarLinkColorHover: @grayDark; -@navbarLinkColorActive: @gray; -@navbarLinkBackgroundHover: transparent; -@navbarLinkBackgroundActive: darken(@navbarBackground, 5%); - -@navbarBrandColor: @navbarLinkColor; - -// Inverted navbar -// > Joomla JUI -@navbarInverseBackground: darken(@headerBackground, 10%); -@navbarInverseBackgroundHighlight: darken(@headerBackground, 5%); -@navbarInverseBorder: darken(@headerBackground, 15%); - -@navbarInverseText: lighten(@grayLight, 25%); -@navbarInverseLinkColor: lighten(@grayLight, 25%); -// < Joomla JUI -@navbarInverseLinkColorHover: @white; -@navbarInverseLinkColorActive: @navbarInverseLinkColorHover; -@navbarInverseLinkBackgroundHover: transparent; -@navbarInverseLinkBackgroundActive: @navbarInverseBackground; - -@navbarInverseSearchBackground: lighten(@navbarInverseBackground, 25%); -@navbarInverseSearchBackgroundFocus: @white; -@navbarInverseSearchBorder: @navbarInverseBackground; -@navbarInverseSearchPlaceholderColor: #ccc; - -@navbarInverseBrandColor: @navbarInverseLinkColor; - - -// Pagination -// ------------------------- -@paginationBackground: #fff; -@paginationBorder: #ddd; -@paginationActiveBackground: #F0F0F0; - - -// Hero unit -// ------------------------- -@heroUnitBackground: @grayLighter; -@heroUnitHeadingColor: inherit; -@heroUnitLeadColor: inherit; - - -// Form states and alerts -// ------------------------- -@warningText: #8a6d3b; -@warningBackground: #fcf8e3; -@warningBorder: darken(spin(@warningBackground, -10), 5%); - -@errorText: #a94442; -@errorBackground: #f2dede; -@errorBorder: darken(spin(@errorBackground, -10), 5%); - -@successText: #3c763d; -@successBackground: #dff0d8; -@successBorder: darken(spin(@successBackground, -10), 5%); - -@infoText: #31708f; -@infoBackground: #d9edf7; -@infoBorder: darken(spin(@infoBackground, -10), 7%); - - -// Tooltips and popovers -// ------------------------- -@tooltipColor: #fff; -@tooltipBackground: #000; -@tooltipArrowWidth: 5px; -@tooltipArrowColor: @tooltipBackground; - -@popoverBackground: #fff; -@popoverArrowWidth: 10px; -@popoverArrowColor: #fff; -@popoverTitleBackground: darken(@popoverBackground, 3%); - -// Special enhancement for popovers -@popoverArrowOuterWidth: @popoverArrowWidth + 1; -@popoverArrowOuterColor: rgba(0,0,0,.25); - - - -// GRID -// -------------------------------------------------- - - -// Default 940px grid -// ------------------------- -@gridColumns: 12; -@gridColumnWidth: 60px; -@gridGutterWidth: 20px; -@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); - -// 1200px min -@gridColumnWidth1200: 70px; -@gridGutterWidth1200: 30px; -@gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1)); - -// 768px-979px -@gridColumnWidth768: 42px; -@gridGutterWidth768: 20px; -@gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1)); - - -// Fluid grid -// ------------------------- -@fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth); -@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth); - -// 1200px min -@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200); -@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200); - -// 768px-979px -@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768); -@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768); - - -// > Joomla JUI -// Login -// ------------------------- -@loginBackground: #17568c; - -// Header -// ------------------------- -@headerBackground: #1a3867; -@headerBackgroundHighlight: #17568c; -// < Joomla JUI \ No newline at end of file diff --git a/administrator/templates/isis/login.php b/administrator/templates/isis/login.php deleted file mode 100644 index 4b7d39bc0e9bd..0000000000000 --- a/administrator/templates/isis/login.php +++ /dev/null @@ -1,139 +0,0 @@ -setHtml5(true); - -// Gets the FrontEnd Main page Uri -$frontEndUri = JUri::getInstance(JUri::root()); -$frontEndUri->setScheme(((int) $app->get('force_ssl', 0) === 2) ? 'https' : 'http'); - -// Color Params -$background_color = $this->params->get('loginBackgroundColor') ?: ''; -$color_is_light = $background_color && colorIsLight($background_color); - -// Add JavaScript Frameworks -JHtml::_('bootstrap.framework'); -JHtml::_('bootstrap.tooltip'); - -// Add html5 shiv -JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); - -// Add Stylesheets -JHtml::_('stylesheet', 'template' . ($this->direction === 'rtl' ? '-rtl' : '') . '.css', array('version' => 'auto', 'relative' => true)); - -// Load optional RTL Bootstrap CSS -JHtml::_('bootstrap.loadCss', false, $this->direction); - -// Load specific language related CSS -JHtml::_('stylesheet', 'administrator/language/' . $lang->getTag() . '/' . $lang->getTag() . '.css', array('version' => 'auto')); - -// Load custom.css -JHtml::_('stylesheet', 'custom.css', array('version' => 'auto', 'relative' => true)); - -// Detecting Active Variables -$option = $app->input->getCmd('option', ''); -$view = $app->input->getCmd('view', ''); -$layout = $app->input->getCmd('layout', ''); -$task = $app->input->getCmd('task', ''); -$itemid = $app->input->getCmd('Itemid', ''); -$sitename = htmlspecialchars($app->get('sitename', ''), ENT_QUOTES, 'UTF-8'); - -function colorIsLight($color) -{ - $r = hexdec(substr($color, 1, 2)); - $g = hexdec(substr($color, 3, 2)); - $b = hexdec(substr($color, 5, 2)); - - $yiq = (($r * 299) + ($g * 587) + ($b * 114)) / 1000; - - return $yiq >= 200; -} - -// Background color -if ($background_color) -{ - $this->addStyleDeclaration(' - .view-login { - background-color: ' . $background_color . '; - }'); -} - -// Responsive Styles -$this->addStyleDeclaration(' - @media (max-width: 480px) { - .view-login .container { - margin-top: -170px; - } - .btn { - font-size: 13px; - padding: 4px 10px 4px; - } - }'); - -// Check if debug is on -if (JPluginHelper::isEnabled('system', 'debug') && ($app->get('debug_lang', 0) || $app->get('debug', 0))) -{ - $this->addStyleDeclaration(' - .view-login .container { - position: static; - margin-top: 20px; - margin-left: auto; - margin-right: auto; - } - .view-login .navbar-fixed-bottom { - position: relative; - }'); -} -?> - - - - - - - - - -
            -
            - - - - -
            -
            - - - - diff --git a/administrator/templates/isis/templateDetails.xml b/administrator/templates/isis/templateDetails.xml deleted file mode 100644 index e7c0ba65dd33c..0000000000000 --- a/administrator/templates/isis/templateDetails.xml +++ /dev/null @@ -1,172 +0,0 @@ - - - - isis - 1.0 - 3/30/2012 - Kyle Ledbetter - admin@joomla.org - Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved. - TPL_ISIS_XML_DESCRIPTION - - component.php - cpanel.php - favicon.ico - index.php - login.php - templateDetails.xml - template_preview.png - template_thumbnail.png - css - html - images - img - js - language - less - - - menu - submenu - toolbar - title - status - icon - cp_shell - cpanel - bottom - footer - login - debug - - - en-GB/en-GB.tpl_isis.ini - en-GB/en-GB.tpl_isis.sys.ini - - - -
            - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            -
            -
            -
            diff --git a/administrator/templates/system/component.php b/administrator/templates/system/component.php index 26fa7caeca3ca..9b093962541ac 100644 --- a/administrator/templates/system/component.php +++ b/administrator/templates/system/component.php @@ -10,12 +10,6 @@ defined('_JEXEC') or die; /** @var JDocumentHtml $this */ - -// Output as HTML5 -$this->setHtml5(true); - -// Add html5 shiv -JHtml::_('script', 'jui/html5.js', array('version' => 'auto', 'relative' => true, 'conditional' => 'lt IE 9')); ?> diff --git a/administrator/templates/system/css/error.css b/administrator/templates/system/css/error.css index 60fede382b548..34a9e2f7430a9 100644 --- a/administrator/templates/system/css/error.css +++ b/administrator/templates/system/css/error.css @@ -4,6 +4,8 @@ */ .outline { + margin: 0 auto; + width: 550px; border: 1px solid #cccccc; background: #ffffff; padding: 2px; @@ -50,4 +52,4 @@ td { color: #ffffff; font-weight: bold; padding: 3px; -} \ No newline at end of file +} diff --git a/administrator/templates/system/error.php b/administrator/templates/system/error.php index c97223059129b..2f419d03de42e 100644 --- a/administrator/templates/system/error.php +++ b/administrator/templates/system/error.php @@ -9,22 +9,30 @@ defined('_JEXEC') or die; +use Joomla\CMS\HTML\HTMLHelper; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Router\Route; + /** @var JDocumentError $this */ +// Load template CSS file +HTMLHelper::_('stylesheet', 'error.css', ['version' => 'auto', 'relative' => true]); + +// Set page title +$this->setTitle($this->error->getCode() . ' - ' . htmlspecialchars($this->error->getMessage(), ENT_QUOTES, 'UTF-8')); ?> - - <?php echo $this->error->getCode(); ?> - <?php echo htmlspecialchars($this->error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> - - + + + - +
            @@ -32,10 +40,10 @@

            error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> debug) : ?> -
            error->getFile(), ENT_QUOTES, 'UTF-8');?>:error->getLine(); ?> +
            error->getFile(), ENT_QUOTES, 'UTF-8');?>:error->getLine(); ?>

            -

            +

            debug) : ?>
            renderBacktrace(); ?> @@ -46,10 +54,10 @@ setError($this->_error->getPrevious()); ?> -

            +

            _error->getMessage(), ENT_QUOTES, 'UTF-8'); ?> -
            _error->getFile(), ENT_QUOTES, 'UTF-8');?>:_error->getLine(); ?> +
            _error->getFile(), ENT_QUOTES, 'UTF-8');?>:_error->getLine(); ?>

            renderBacktrace(); ?> setError($this->_error->getPrevious()); ?> @@ -62,5 +70,7 @@
            -

            error->getCode() ?> -

            +

            error->getCode() ?> -

            + + diff --git a/administrator/templates/system/html/modules.php b/administrator/templates/system/html/modules.php index d88c9b9caeb0c..297c8888591d5 100644 --- a/administrator/templates/system/html/modules.php +++ b/administrator/templates/system/html/modules.php @@ -9,6 +9,8 @@ defined('_JEXEC') or die; +use Joomla\CMS\HTML\HTMLHelper; + /* * none (output raw module content) */ @@ -81,7 +83,7 @@ function modChrome_sliders($module, &$params, &$attribs) if (!empty($content)) { - echo JHtml::_('sliders.panel', $module->title, 'module' . $module->id); + echo HTMLHelper::_('sliders.panel', $module->title, 'module' . $module->id); echo $content; } } @@ -95,7 +97,7 @@ function modChrome_tabs($module, &$params, &$attribs) if (!empty($content)) { - echo JHtml::_('tabs.panel', $module->title, 'module' . $module->id); + echo HTMLHelper::_('tabs.panel', $module->title, 'module' . $module->id); echo $content; } } diff --git a/appveyor-phpunit.xml b/appveyor-phpunit.xml index 8044272900d57..0cfebafd21668 100644 --- a/appveyor-phpunit.xml +++ b/appveyor-phpunit.xml @@ -1,7 +1,6 @@ - @@ -19,9 +18,6 @@ tests/unit/suites/libraries/legacy - - tests/unit/suites/database - tests/unit/suites/administrator diff --git a/bin/keychain.php b/bin/keychain.php deleted file mode 100644 index 3398ab15347cf..0000000000000 --- a/bin/keychain.php +++ /dev/null @@ -1,415 +0,0 @@ -#!/usr/bin/env php -input->args)) - { - // Check if they passed --help in otherwise display short usage summary - if ($this->input->get('help', false) === false) - { - $this->out("usage: {$this->input->executable} [options] [command] []"); - exit(1); - } - else - { - $this->displayHelp(); - exit(0); - } - } - - // For all tasks but help and init we use the keychain - if (!in_array($this->input->args[0], array('help', 'init'))) - { - $this->loadKeychain(); - } - - switch ($this->input->args[0]) - { - case 'init': - $this->initPassphraseFile(); - break; - case 'list': - $this->listEntries(); - break; - case 'create': - $this->create(); - break; - case 'change': - $this->change(); - break; - case 'delete': - $this->delete(); - break; - case 'read': - $this->read(); - break; - case 'help': - $this->displayHelp(); - break; - default: - $this->out('Invalid command.'); - break; - } - - if ($this->updated) - { - $this->saveKeychain(); - } - - exit(0); - } - - /** - * Load the keychain from a file. - * - * @return void - * - * @since 12.3 - */ - protected function loadKeychain() - { - $keychain = $this->input->get('keychain', '', 'raw'); - $publicKeyFile = $this->input->get('public-key', '', 'raw'); - $passphraseFile = $this->input->get('passphrase', '', 'raw'); - - $this->keychain = new JKeychain; - - if (file_exists($keychain)) - { - if (file_exists($publicKeyFile)) - { - $this->keychain->loadKeychain($keychain, $passphraseFile, $publicKeyFile); - } - else - { - $this->out('Public key not specified or missing!'); - exit(1); - } - } - } - - /** - * Save this keychain to a file. - * - * @return void - * - * @since 12.3 - */ - protected function saveKeychain() - { - $keychain = $this->input->get('keychain', '', 'raw'); - $publicKeyFile = $this->input->get('public-key', '', 'raw'); - $passphraseFile = $this->input->get('passphrase', '', 'raw'); - - if (!file_exists($publicKeyFile)) - { - $this->out("Public key file specified doesn't exist: $publicKeyFile"); - exit(1); - } - - $this->keychain->saveKeychain($keychain, $passphraseFile, $publicKeyFile); - } - - /** - * Initialise a new passphrase file. - * - * @return void - * - * @since 12.3 - */ - protected function initPassphraseFile() - { - $keychain = new JKeychain; - - $passphraseFile = $this->input->get('passphrase', '', 'raw'); - $privateKeyFile = $this->input->get('private-key', '', 'raw'); - - if (!strlen($passphraseFile)) - { - $this->out('A passphrase file must be specified with --passphrase'); - exit(1); - } - - if (!file_exists($privateKeyFile)) - { - $this->out("protected key file specified doesn't exist: $privateKeyFile"); - exit(1); - } - - $this->out('Please enter the new passphrase:'); - $passphrase = $this->in(); - - $this->out('Please enter the passphrase for the protected key:'); - $privateKeyPassphrase = $this->in(); - - $keychain->createPassphraseFile($passphrase, $passphraseFile, $privateKeyFile, $privateKeyPassphrase); - } - - /** - * Create a new entry - * - * @return void - * - * @since 12.3 - */ - protected function create() - { - if (count($this->input->args) != 3) - { - $this->out("usage: {$this->input->executable} [options] create entry_name entry_value"); - exit(1); - } - - if ($this->keychain->exists($this->input->args[1])) - { - $this->out('error: entry already exists. To change this entry, use "change"'); - exit(1); - } - - $this->change(); - } - - /** - * Change an existing entry to a new value or create an entry if missing. - * - * @return void - * - * @since 12.3 - */ - protected function change() - { - if (count($this->input->args) != 3) - { - $this->out("usage: {$this->input->executable} [options] change entry_name entry_value"); - exit(1); - } - - $this->updated = true; - $this->keychain->setValue($this->input->args[1], $this->input->args[2]); - } - - /** - * Read an entry from the keychain - * - * @return void - * - * @since 12.3 - */ - protected function read() - { - if (count($this->input->args) != 2) - { - $this->out("usage: {$this->input->executable} [options] read entry_name"); - exit(1); - } - - $key = $this->input->args[1]; - $this->out($key . ': ' . $this->dumpVar($this->keychain->get($key))); - } - - /** - * Get the string from var_dump - * - * @param mixed $var The variable you want to have dumped. - * - * @return string The result of var_dump - * - * @since 12.3 - */ - private function dumpVar($var) - { - ob_start(); - var_dump($var); - $result = trim(ob_get_contents()); - ob_end_clean(); - - return $result; - } - - /** - * Delete an entry from the keychain - * - * @return void - * - * @since 12.3 - */ - protected function delete() - { - if (count($this->input->args) != 2) - { - $this->out("usage: {$this->input->executable} [options] delete entry_name"); - exit(1); - } - - $this->updated = true; - $this->keychain->deleteValue($this->input->args[1]); - } - - /** - * List entries in the keychain - * - * @return void - * - * @since 12.3 - */ - protected function listEntries() - { - foreach ($this->keychain->toArray() as $key => $value) - { - $line = $key; - - if ($this->input->get('print-values')) - { - $line .= ': ' . $this->dumpVar($value); - } - - $this->out($line); - } - } - - /** - * Display the help information - * - * @return void - * - * @since 12.3 - */ - protected function displayHelp() - { -/* -COMMANDS - - - list - - create entry_name entry_value - - change entry_name entry_value - - delete entry_name - - read entry_name -*/ - - $help = <<input->executable} [--keychain=/path/to/keychain] - [--passphrase=/path/to/passphrase.dat] [--public-key=/path/to/public.pem] - [command] [] - -OPTIONS - - --keychain=/path/to/keychain - Path to a keychain file to manipulate. - - --passphrase=/path/to/passphrase.dat - Path to a passphrase file containing the encryption/decryption key. - - --public-key=/path/to/public.pem - Path to a public key file to decrypt the passphrase file. - - -COMMANDS - - list: - Usage: list [--print-values] - Lists all entries in the keychain. Optionally pass --print-values to print the values as well. - - create: - Usage: create entry_name entry_value - Creates a new entry in the keychain called "entry_name" with the plaintext value "entry_value". - NOTE: This is an alias for change. - - change: - Usage: change entry_name entry_value - Updates the keychain entry called "entry_name" with the value "entry_value". - - delete: - Usage: delete entry_name - Removes an entry called "entry_name" from the keychain. - - read: - Usage: read entry_name - Outputs the plaintext value of "entry_name" from the keychain. - - init: - Usage: init - Creates a new passphrase file and prompts for a new passphrase. - -HELP; - $this->out($help); - } -} - -try -{ - JApplicationCli::getInstance('KeychainManager')->execute(); -} -catch (Exception $e) -{ - echo $e->getMessage() . "\n"; - exit(1); -} diff --git a/build.js b/build.js new file mode 100644 index 0000000000000..2e35f4e0f7edd --- /dev/null +++ b/build.js @@ -0,0 +1,106 @@ +/** + * Command line helper + * + * To get the complete functional media folder please run + * + * npm install + * + * For dedicated tasks, please run: + * node build.js --buildcheck === will create the error page (for incomplete repo build) + * node build.js --installer === will create the error page (for unsupported PHP version) + * node build.js --copy-assets === will clean the media/vendor folder and then will populate the folder from node_modules + * node build.js --compile-js === will transpile ES6 files and also uglify the ES6,ES5 files + * node build.js --compile-ce === will compile all the given CE or WC with their relative css files + * node build.js --compile-css === will compile all the scss defined files and also create a minified version of the css + * + */ + +// eslint-disable-next-line import/no-extraneous-dependencies +const Program = require('commander'); +// eslint-disable-next-line import/no-extraneous-dependencies + +// Joomla Build modules +const buildCheck = require('./build/build-modules-js/build-check'); +const copyAssets = require('./build/build-modules-js/update'); +const compileCSS = require('./build/build-modules-js/compilescss'); +const compileJS = require('./build/build-modules-js/compilejs'); +const compileWebComponents = require('./build/build-modules-js/compilecejs'); +const minifyVendor = require('./build/build-modules-js/minify-vendor'); + +// The settings +const options = require('./package.json'); +const settings = require('./build/build-modules-js/settings.json'); + +// Merge Joomla's specific settings to the main package.json object +if ('settings' in settings) { + options.settings = settings.settings; +} + +// Initialize the CLI +Program + .version(options.version) + .option('--copy-assets', 'Moving files from node_modules to media folder') + .option('--compile-js, --compile-js path', 'Compiles ES6 to ES5 scripts') + .option('--compile-css, --compile-css path', 'Compiles all the scss files to css') + .option('--compile-ce, --compile-ce path', 'Compiles/traspiles all the custom elements files') + .option('--watch, --watch path', 'Watch file changes and re-compile (Only work for compile-css and compile-js now).') + .option('--build-check', 'Creates the error pages for unsupported PHP version & incomplete environment') + .on('--help', () => { + // eslint-disable-next-line no-console + console.log(`Version: ${options.version}`); + process.exit(0); + }) + .parse(process.argv); + + +// Show help by default +if (!process.argv.slice(2).length) { + Program.outputHelp(); + process.exit(1); +} + +// Update the vendor folder +if (Program.copyAssets) { + Promise.resolve() + .then(copyAssets.copyAssets(options)) + .then(minifyVendor.compile(options)) + + // Exit with success + .then(() => process.exit(0)) + + // Handle errors + .catch((err) => { + // eslint-disable-next-line no-console + console.error(err); + process.exit(-1); + }); +} + + +// Creates the error pages for unsupported PHP version & incomplete environment +if (Program.buildCheck) { + buildCheck.buildCheck(options); +} + +// Convert scss to css +if (Program.compileCss) { + if (Program.watch) { + compileCSS.watch(options, null, true); + } else { + compileCSS.compileCSS(options, Program.args[0]); + } +} + +// Compress/transpile the javascript files +if (Program.compileJs) { + if (Program.watch) { + compileJS.watch(options, null, false); + } else { + compileJS.compileJS(options, Program.args[0]); + } +} + +// Compress/transpile the Custom Elements files +if (Program.compileCe) { + compileWebComponents.compile(options, Program.args[0]); +} diff --git a/build.xml b/build.xml index 4fd02118e473f..34f3e2859eb7d 100644 --- a/build.xml +++ b/build.xml @@ -37,6 +37,7 @@ + @@ -84,7 +85,7 @@ - + diff --git a/build/.gitignore b/build/.gitignore index 84868e9fe3fc5..c8470ef2dca03 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -1,6 +1,7 @@ # Ignore test report folders so they do not push to the repo # /api /coverage +/coverage-js /logs /pdepend diff --git a/build/bootstrap/Makefile b/build/bootstrap/Makefile deleted file mode 100644 index 8c435f5e6a511..0000000000000 --- a/build/bootstrap/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# -# This makefile builds Bootstrap customized for Joomla. -# -# Step 1: make bootstrap-js -# Step 2: make bootstrap-css -# -# It generates new build/bootstrap/css and build/bootstrap/js directories -# with the generated files. -# -# References: -# https://github.com/joomla/joomla-cms/pull/1172 -# https://github.com/joomla/joomla-cms/pull/1166 -# - -BOOTSTRAP_LESS = ../../media/jui/less/bootstrap.less -BOOTSTRAP_RESPONSIVE_LESS = ../../media/jui/less/responsive.less -DATE=$(shell date +%I:%M%p) -CHECK=\033[32m✔\033[39m -HR=\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# - - -# -# JS COMPILE -# -bootstrap-js: bootstrap/js/*.js - -bootstrap/js/*.js: js/*.js - mkdir -p bootstrap/js - cat js/bootstrap-transition.js js/bootstrap-alert.js js/bootstrap-button.js js/bootstrap-carousel.js js/bootstrap-collapse-joomla.js js/bootstrap-dropdown-joomla.js js/bootstrap-modal.js js/bootstrap-tooltip-joomla.js js/bootstrap-popover.js js/bootstrap-scrollspy.js js/bootstrap-tab.js js/bootstrap-typeahead.js js/bootstrap-affix.js > bootstrap/js/bootstrap.js - ## uglifyjs -nc bootstrap/js/bootstrap.js > bootstrap/js/bootstrap.min.tmp.js -- no nc parameter? - uglifyjs bootstrap/js/bootstrap.js > bootstrap/js/bootstrap.min.tmp.js - echo "/*!\n* Bootstrap.js by @fat & @mdo\n* Copyright 2012 Twitter, Inc.\n* http://www.apache.org/licenses/LICENSE-2.0.txt\n*/" > bootstrap/js/copyright.js - cat bootstrap/js/copyright.js bootstrap/js/bootstrap.min.tmp.js > bootstrap/js/bootstrap.min.js - rm bootstrap/js/copyright.js bootstrap/js/bootstrap.min.tmp.js - cp bootstrap/js/*.js ../../media/jui/js/ - -# -# CSS COMPLILE -# - -bootstrap-css: bootstrap/css/*.css - -bootstrap/css/*.css: ../../media/jui/less/*.less - mkdir -p bootstrap/css - recess --compile ${BOOTSTRAP_LESS} > bootstrap/css/bootstrap.css - recess --compress ${BOOTSTRAP_LESS} > bootstrap/css/bootstrap.min.css - recess --compile ${BOOTSTRAP_RESPONSIVE_LESS} > bootstrap/css/bootstrap-responsive.css - recess --compress ${BOOTSTRAP_RESPONSIVE_LESS} > bootstrap/css/bootstrap-responsive.min.css - cp bootstrap/css/*.css ../../media/jui/css/ - - diff --git a/build/bootstrap/js/bootstrap-affix.js b/build/bootstrap/js/bootstrap-affix.js deleted file mode 100644 index 91c9ced13d00b..0000000000000 --- a/build/bootstrap/js/bootstrap-affix.js +++ /dev/null @@ -1,117 +0,0 @@ -/* ========================================================== - * bootstrap-affix.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#affix - * ========================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* AFFIX CLASS DEFINITION - * ====================== */ - - var Affix = function (element, options) { - this.options = $.extend({}, $.fn.affix.defaults, options) - this.$window = $(window) - .on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) - .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this)) - this.$element = $(element) - this.checkPosition() - } - - Affix.prototype.checkPosition = function () { - if (!this.$element.is(':visible')) return - - var scrollHeight = $(document).height() - , scrollTop = this.$window.scrollTop() - , position = this.$element.offset() - , offset = this.options.offset - , offsetBottom = offset.bottom - , offsetTop = offset.top - , reset = 'affix affix-top affix-bottom' - , affix - - if (typeof offset != 'object') offsetBottom = offsetTop = offset - if (typeof offsetTop == 'function') offsetTop = offset.top() - if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() - - affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? - false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? - 'bottom' : offsetTop != null && scrollTop <= offsetTop ? - 'top' : false - - if (this.affixed === affix) return - - this.affixed = affix - this.unpin = affix == 'bottom' ? position.top - scrollTop : null - - this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) - } - - - /* AFFIX PLUGIN DEFINITION - * ======================= */ - - var old = $.fn.affix - - $.fn.affix = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('affix') - , options = typeof option == 'object' && option - if (!data) $this.data('affix', (data = new Affix(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.affix.Constructor = Affix - - $.fn.affix.defaults = { - offset: 0 - } - - - /* AFFIX NO CONFLICT - * ================= */ - - $.fn.affix.noConflict = function () { - $.fn.affix = old - return this - } - - - /* AFFIX DATA-API - * ============== */ - - $(window).on('load', function () { - $('[data-spy="affix"]').each(function () { - var $spy = $(this) - , data = $spy.data() - - data.offset = data.offset || {} - - data.offsetBottom && (data.offset.bottom = data.offsetBottom) - data.offsetTop && (data.offset.top = data.offsetTop) - - $spy.affix(data) - }) - }) - - -}(window.jQuery); \ No newline at end of file diff --git a/build/bootstrap/js/bootstrap-alert.js b/build/bootstrap/js/bootstrap-alert.js deleted file mode 100644 index 0cefe5fc5ecd7..0000000000000 --- a/build/bootstrap/js/bootstrap-alert.js +++ /dev/null @@ -1,99 +0,0 @@ -/* ========================================================== - * bootstrap-alert.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#alerts - * ========================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* ALERT CLASS DEFINITION - * ====================== */ - - var dismiss = '[data-dismiss="alert"]' - , Alert = function (el) { - $(el).on('click', dismiss, this.close) - } - - Alert.prototype.close = function (e) { - var $this = $(this) - , selector = $this.attr('data-target') - , $parent - - if (!selector) { - selector = $this.attr('href') - selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 - } - - $parent = $(selector) - - e && e.preventDefault() - - $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) - - $parent.trigger(e = $.Event('close')) - - if (e.isDefaultPrevented()) return - - $parent.removeClass('in') - - function removeElement() { - $parent - .trigger('closed') - .remove() - } - - $.support.transition && $parent.hasClass('fade') ? - $parent.on($.support.transition.end, removeElement) : - removeElement() - } - - - /* ALERT PLUGIN DEFINITION - * ======================= */ - - var old = $.fn.alert - - $.fn.alert = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('alert') - if (!data) $this.data('alert', (data = new Alert(this))) - if (typeof option == 'string') data[option].call($this) - }) - } - - $.fn.alert.Constructor = Alert - - - /* ALERT NO CONFLICT - * ================= */ - - $.fn.alert.noConflict = function () { - $.fn.alert = old - return this - } - - - /* ALERT DATA-API - * ============== */ - - $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) - -}(window.jQuery); \ No newline at end of file diff --git a/build/bootstrap/js/bootstrap-button.js b/build/bootstrap/js/bootstrap-button.js deleted file mode 100644 index ce45991644b3d..0000000000000 --- a/build/bootstrap/js/bootstrap-button.js +++ /dev/null @@ -1,105 +0,0 @@ -/* ============================================================ - * bootstrap-button.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#buttons - * ============================================================ - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* BUTTON PUBLIC CLASS DEFINITION - * ============================== */ - - var Button = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, $.fn.button.defaults, options) - } - - Button.prototype.setState = function (state) { - var d = 'disabled' - , $el = this.$element - , data = $el.data() - , val = $el.is('input') ? 'val' : 'html' - - state = state + 'Text' - data.resetText || $el.data('resetText', $el[val]()) - - $el[val](data[state] || this.options[state]) - - // push to event loop to allow forms to submit - setTimeout(function () { - state == 'loadingText' ? - $el.addClass(d).attr(d, d) : - $el.removeClass(d).removeAttr(d) - }, 0) - } - - Button.prototype.toggle = function () { - var $parent = this.$element.closest('[data-toggle="buttons-radio"]') - - $parent && $parent - .find('.active') - .removeClass('active') - - this.$element.toggleClass('active') - } - - - /* BUTTON PLUGIN DEFINITION - * ======================== */ - - var old = $.fn.button - - $.fn.button = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('button') - , options = typeof option == 'object' && option - if (!data) $this.data('button', (data = new Button(this, options))) - if (option == 'toggle') data.toggle() - else if (option) data.setState(option) - }) - } - - $.fn.button.defaults = { - loadingText: 'loading...' - } - - $.fn.button.Constructor = Button - - - /* BUTTON NO CONFLICT - * ================== */ - - $.fn.button.noConflict = function () { - $.fn.button = old - return this - } - - - /* BUTTON DATA-API - * =============== */ - - $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') - $btn.button('toggle') - }) - -}(window.jQuery); \ No newline at end of file diff --git a/build/bootstrap/js/bootstrap-carousel.js b/build/bootstrap/js/bootstrap-carousel.js deleted file mode 100644 index 476494ad6ad1a..0000000000000 --- a/build/bootstrap/js/bootstrap-carousel.js +++ /dev/null @@ -1,207 +0,0 @@ -/* ========================================================== - * bootstrap-carousel.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#carousel - * ========================================================== - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* CAROUSEL CLASS DEFINITION - * ========================= */ - - var Carousel = function (element, options) { - this.$element = $(element) - this.$indicators = this.$element.find('.carousel-indicators') - this.options = options - this.options.pause == 'hover' && this.$element - .on('mouseenter', $.proxy(this.pause, this)) - .on('mouseleave', $.proxy(this.cycle, this)) - } - - Carousel.prototype = { - - cycle: function (e) { - if (!e) this.paused = false - if (this.interval) clearInterval(this.interval); - this.options.interval - && !this.paused - && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) - return this - } - - , getActiveIndex: function () { - this.$active = this.$element.find('.item.active') - this.$items = this.$active.parent().children() - return this.$items.index(this.$active) - } - - , to: function (pos) { - var activeIndex = this.getActiveIndex() - , that = this - - if (pos > (this.$items.length - 1) || pos < 0) return - - if (this.sliding) { - return this.$element.one('slid', function () { - that.to(pos) - }) - } - - if (activeIndex == pos) { - return this.pause().cycle() - } - - return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) - } - - , pause: function (e) { - if (!e) this.paused = true - if (this.$element.find('.next, .prev').length && $.support.transition.end) { - this.$element.trigger($.support.transition.end) - this.cycle(true) - } - clearInterval(this.interval) - this.interval = null - return this - } - - , next: function () { - if (this.sliding) return - return this.slide('next') - } - - , prev: function () { - if (this.sliding) return - return this.slide('prev') - } - - , slide: function (type, next) { - var $active = this.$element.find('.item.active') - , $next = next || $active[type]() - , isCycling = this.interval - , direction = type == 'next' ? 'left' : 'right' - , fallback = type == 'next' ? 'first' : 'last' - , that = this - , e - - this.sliding = true - - isCycling && this.pause() - - $next = $next.length ? $next : this.$element.find('.item')[fallback]() - - e = $.Event('slide', { - relatedTarget: $next[0] - , direction: direction - }) - - if ($next.hasClass('active')) return - - if (this.$indicators.length) { - this.$indicators.find('.active').removeClass('active') - this.$element.one('slid', function () { - var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) - $nextIndicator && $nextIndicator.addClass('active') - }) - } - - if ($.support.transition && this.$element.hasClass('slide')) { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $next.addClass(type) - $next[0].offsetWidth // force reflow - $active.addClass(direction) - $next.addClass(direction) - this.$element.one($.support.transition.end, function () { - $next.removeClass([type, direction].join(' ')).addClass('active') - $active.removeClass(['active', direction].join(' ')) - that.sliding = false - setTimeout(function () { that.$element.trigger('slid') }, 0) - }) - } else { - this.$element.trigger(e) - if (e.isDefaultPrevented()) return - $active.removeClass('active') - $next.addClass('active') - this.sliding = false - this.$element.trigger('slid') - } - - isCycling && this.cycle() - - return this - } - - } - - - /* CAROUSEL PLUGIN DEFINITION - * ========================== */ - - var old = $.fn.carousel - - $.fn.carousel = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('carousel') - , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) - , action = typeof option == 'string' ? option : options.slide - if (!data) $this.data('carousel', (data = new Carousel(this, options))) - if (typeof option == 'number') data.to(option) - else if (action) data[action]() - else if (options.interval) data.pause().cycle() - }) - } - - $.fn.carousel.defaults = { - interval: 5000 - , pause: 'hover' - } - - $.fn.carousel.Constructor = Carousel - - - /* CAROUSEL NO CONFLICT - * ==================== */ - - $.fn.carousel.noConflict = function () { - $.fn.carousel = old - return this - } - - /* CAROUSEL DATA-API - * ================= */ - - $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { - var $this = $(this), href - , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 - , options = $.extend({}, $target.data(), $this.data()) - , slideIndex - - $target.carousel(options) - - if (slideIndex = $this.attr('data-slide-to')) { - $target.data('carousel').pause().to(slideIndex).cycle() - } - - e.preventDefault() - }) - -}(window.jQuery); \ No newline at end of file diff --git a/build/bootstrap/js/bootstrap-collapse-joomla.js b/build/bootstrap/js/bootstrap-collapse-joomla.js deleted file mode 100644 index fa35a4c1ec52f..0000000000000 --- a/build/bootstrap/js/bootstrap-collapse-joomla.js +++ /dev/null @@ -1,173 +0,0 @@ -/* ============================================================= - * bootstrap-collapse.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#collapse - * ============================================================= - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* COLLAPSE PUBLIC CLASS DEFINITION - * ================================ */ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, $.fn.collapse.defaults, options) - - if (this.options.parent) { - this.$parent = $(this.options.parent) - } - - this.options.toggle && this.toggle() - } - - Collapse.prototype = { - - constructor: Collapse - - , dimension: function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - , show: function () { - var dimension - , scroll - , actives - , hasData - - if (this.transitioning || this.$element.hasClass('in')) return - - dimension = this.dimension() - scroll = $.camelCase(['scroll', dimension].join('-')) - actives = this.$parent && this.$parent.find('> .accordion-group > .in') - - if (actives && actives.length) { - hasData = actives.data('collapse') - if (hasData && hasData.transitioning) return - actives.collapse('hide') - hasData || actives.data('collapse', null) - } - - this.$element[dimension](0) - this.transition('addClass', $.Event('show'), 'shown') - $.support.transition && this.$element[dimension](this.$element[0][scroll]) - } - - , hide: function () { - var dimension - if (this.transitioning || !this.$element.hasClass('in')) return - dimension = this.dimension() - this.reset(this.$element[dimension]()) - // > Joomla JUI - /* ORIGINAL: - this.transition('removeClass', $.Event('hide'), 'hidden') - */ - this.transition('removeClass', $.Event('hideme'), 'hidden') - // < Joomla JUI - - this.$element[dimension](0) - } - - , reset: function (size) { - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - [dimension](size || 'auto') - [0].offsetWidth - - this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') - - return this - } - - , transition: function (method, startEvent, completeEvent) { - var that = this - , complete = function () { - if (startEvent.type == 'show') that.reset() - that.transitioning = 0 - that.$element.trigger(completeEvent) - } - - this.$element.trigger(startEvent) - - if (startEvent.isDefaultPrevented()) return - - this.transitioning = 1 - - this.$element[method]('in') - - $.support.transition && this.$element.hasClass('collapse') ? - this.$element.one($.support.transition.end, complete) : - complete() - } - - , toggle: function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - } - - - /* COLLAPSE PLUGIN DEFINITION - * ========================== */ - - var old = $.fn.collapse - - $.fn.collapse = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('collapse') - , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) - if (!data) $this.data('collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.collapse.defaults = { - toggle: true - } - - $.fn.collapse.Constructor = Collapse - - - /* COLLAPSE NO CONFLICT - * ==================== */ - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - /* COLLAPSE DATA-API - * ================= */ - - $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { - var $this = $(this), href - , target = $this.attr('data-target') - || e.preventDefault() - || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 - , option = $(target).data('collapse') ? 'toggle' : $this.data() - $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') - $(target).collapse(option) - }) - -}(window.jQuery); diff --git a/build/bootstrap/js/bootstrap-collapse.js b/build/bootstrap/js/bootstrap-collapse.js deleted file mode 100644 index 74a73a890a2fe..0000000000000 --- a/build/bootstrap/js/bootstrap-collapse.js +++ /dev/null @@ -1,167 +0,0 @@ -/* ============================================================= - * bootstrap-collapse.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#collapse - * ============================================================= - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* COLLAPSE PUBLIC CLASS DEFINITION - * ================================ */ - - var Collapse = function (element, options) { - this.$element = $(element) - this.options = $.extend({}, $.fn.collapse.defaults, options) - - if (this.options.parent) { - this.$parent = $(this.options.parent) - } - - this.options.toggle && this.toggle() - } - - Collapse.prototype = { - - constructor: Collapse - - , dimension: function () { - var hasWidth = this.$element.hasClass('width') - return hasWidth ? 'width' : 'height' - } - - , show: function () { - var dimension - , scroll - , actives - , hasData - - if (this.transitioning || this.$element.hasClass('in')) return - - dimension = this.dimension() - scroll = $.camelCase(['scroll', dimension].join('-')) - actives = this.$parent && this.$parent.find('> .accordion-group > .in') - - if (actives && actives.length) { - hasData = actives.data('collapse') - if (hasData && hasData.transitioning) return - actives.collapse('hide') - hasData || actives.data('collapse', null) - } - - this.$element[dimension](0) - this.transition('addClass', $.Event('show'), 'shown') - $.support.transition && this.$element[dimension](this.$element[0][scroll]) - } - - , hide: function () { - var dimension - if (this.transitioning || !this.$element.hasClass('in')) return - dimension = this.dimension() - this.reset(this.$element[dimension]()) - this.transition('removeClass', $.Event('hide'), 'hidden') - this.$element[dimension](0) - } - - , reset: function (size) { - var dimension = this.dimension() - - this.$element - .removeClass('collapse') - [dimension](size || 'auto') - [0].offsetWidth - - this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') - - return this - } - - , transition: function (method, startEvent, completeEvent) { - var that = this - , complete = function () { - if (startEvent.type == 'show') that.reset() - that.transitioning = 0 - that.$element.trigger(completeEvent) - } - - this.$element.trigger(startEvent) - - if (startEvent.isDefaultPrevented()) return - - this.transitioning = 1 - - this.$element[method]('in') - - $.support.transition && this.$element.hasClass('collapse') ? - this.$element.one($.support.transition.end, complete) : - complete() - } - - , toggle: function () { - this[this.$element.hasClass('in') ? 'hide' : 'show']() - } - - } - - - /* COLLAPSE PLUGIN DEFINITION - * ========================== */ - - var old = $.fn.collapse - - $.fn.collapse = function (option) { - return this.each(function () { - var $this = $(this) - , data = $this.data('collapse') - , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) - if (!data) $this.data('collapse', (data = new Collapse(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - $.fn.collapse.defaults = { - toggle: true - } - - $.fn.collapse.Constructor = Collapse - - - /* COLLAPSE NO CONFLICT - * ==================== */ - - $.fn.collapse.noConflict = function () { - $.fn.collapse = old - return this - } - - - /* COLLAPSE DATA-API - * ================= */ - - $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { - var $this = $(this), href - , target = $this.attr('data-target') - || e.preventDefault() - || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 - , option = $(target).data('collapse') ? 'toggle' : $this.data() - $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') - $(target).collapse(option) - }) - -}(window.jQuery); \ No newline at end of file diff --git a/build/bootstrap/js/bootstrap-dropdown-joomla.js b/build/bootstrap/js/bootstrap-dropdown-joomla.js deleted file mode 100644 index 2437469c86fcd..0000000000000 --- a/build/bootstrap/js/bootstrap-dropdown-joomla.js +++ /dev/null @@ -1,184 +0,0 @@ -/* ============================================================ - * bootstrap-dropdown.js v2.3.2 - * http://twitter.github.com/bootstrap/javascript.html#dropdowns - * ============================================================ - * Copyright 2012 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* DROPDOWN CLASS DEFINITION - * ========================= */ - - var toggle = '[data-toggle=dropdown]' - , Dropdown = function (element) { - var $el = $(element).on('click.dropdown.data-api', this.toggle) - $('html').on('click.dropdown.data-api', function () { - $el.parent().removeClass('open') - }) - } - - Dropdown.prototype = { - - constructor: Dropdown - - , toggle: function (e) { - // > Joomla JUI - /* ORIGINAL - var $this = $(this) - , $parent - , isActive - - */ - var $this = $(this) - , $parent - , isActive - , url - - url = $this.attr('href') - if ((url) && (url !== '#')) { - window.location = url - return - } - // < Joomla JUI - - if ($this.is('.disabled, :disabled')) return - - $parent = getParent($this) - - isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - if ('ontouchstart' in document.documentElement) { - // if mobile we we use a backdrop because click events don't delegate - $('